Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c3c7639
packaging
AlperSakarya May 1, 2016
580e031
renaming README
AlperSakarya May 1, 2016
e1283ab
modifying readme
AlperSakarya May 1, 2016
3019ee4
fixing download url
AlperSakarya May 2, 2016
9605f80
adding formatted readme back
AlperSakarya May 2, 2016
fbf4987
moving files
AlperSakarya May 2, 2016
be7d804
Fixed logo and data.json so indicator.py can be runing from any direc…
AlperSakarya May 6, 2016
e911241
Fixed logo,data.json and wallpaper save directories. Script can run f…
AlperSakarya May 7, 2016
6e867f1
Script now can run from any directory. Renamed folder name.
AlperSakarya May 7, 2016
f479117
Script now can run from any directory. Renamed folder name.
AlperSakarya May 7, 2016
26dfed0
Added notification timer to stop it in 2 seconds. It takes too long t…
AlperSakarya May 17, 2016
eb169dc
Changing name back to no spaces since original project does not accep…
AlperSakarya May 19, 2017
04dbad5
python3 error fixed
Sep 8, 2018
8fcee5d
parser.py urllib version, range function and beautiful soup version l…
Sep 8, 2018
8e24d8e
All the errors resolved, libraries updated for Ubuntu 18.04 & Python3
Sep 8, 2018
d2d852d
All the errors resolved, libraries updated for Ubuntu 18.04 & Python3
Sep 8, 2018
50c361a
checking for NoneType
AlperSakarya Nov 18, 2023
3de5d5f
updated for Ubuntu 22.04.1 and parallelized parser
AlperSakarya Sep 15, 2024
bd2554f
letting AI on the loose for this repo:
AlperSakarya May 18, 2025
6bdedca
Add Debian package support and improve installation process
AlperSakarya Aug 9, 2025
ccbde23
v2.0: multi-source wallpaper engine with live satellites, fly-over ro…
AlperSakarya Aug 7, 2026
37ef572
gitignore: exclude build artifacts, pycache, and generated files
AlperSakarya Aug 7, 2026
ce2b315
readme: use apt install for one-step package setup
AlperSakarya Aug 7, 2026
34736a3
fix: single-instance lock and fair source rotation across all providers
AlperSakarya Aug 9, 2026
0a0dfb2
fix: round-robin source cycling + 7-day dedup ensures no repeats
AlperSakarya Aug 12, 2026
71935a4
fix: location mode no longer collapses onto Earth View
AlperSakarya Aug 12, 2026
894ee2c
packaging: clean install/upgrade handling and policy compliance
AlperSakarya Aug 12, 2026
5bc43bc
readme: document clean upgrade behaviour, cache location, and dedup
AlperSakarya Aug 12, 2026
d80ab09
add logging; fix black desktop after upgrade
AlperSakarya Aug 12, 2026
f5332a7
replace icon with original artwork; drop AmazonQ.md
AlperSakarya Aug 12, 2026
8ed38b8
fix broken package; start app after install
AlperSakarya Aug 12, 2026
c86267d
add source lock: restrict changes to chosen sources
AlperSakarya Aug 14, 2026
58e3902
fix Unsplash serving unrelated photos including portraits
AlperSakarya Aug 17, 2026
cea160d
add Wikimedia Commons source; remove all hardcoded image IDs
AlperSakarya Aug 17, 2026
2f5638d
add notification on/off setting, silent while screen is off
AlperSakarya Aug 17, 2026
a1eb8e5
use Unsplash random endpoint, register downloads, update README
AlperSakarya Aug 17, 2026
7d6aace
readme: archive notice, project moved to earthview-wallpaper
AlperSakarya Aug 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
LICENSE.txt
output.txt
wallpaper-changer/wallpaper.jpg
__pycache__/
*.pyc
*.deb

# Never commit credentials. Keys live in ~/.config/earthview/config.json,
# outside the repo, but guard against a copy being dropped in here.
config.json
**/config.json
*.key
.env
secrets*
earthview-package/usr/share/earthview/*.py
earthview-package/usr/share/earthview/sources/
earthview-package/usr/share/earthview/wallpaper_collections/

# Generated at build time from pristine sources in packaging/
earthview-package/usr/share/doc/
earthview-package/usr/share/man/
earthview-package/usr/share/icons/
1,580 changes: 63 additions & 1,517 deletions README.md
100644 → 100755

Large diffs are not rendered by default.

201 changes: 201 additions & 0 deletions build-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#!/bin/bash
# Build script for the earthview-wallpaper .deb package.
#
# Stages the current source tree into the package layout, normalises
# ownership and permissions, then builds the archive.

set -euo pipefail

VERSION="2.4.0"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PKG_DIR="$SCRIPT_DIR/earthview-package"
SHARE_DIR="$PKG_DIR/usr/share/earthview"
SRC_DIR="$SCRIPT_DIR/wallpaper-changer"
OUTPUT="$SCRIPT_DIR/earthview-wallpaper_${VERSION}_all.deb"

echo "Building Earth View Wallpaper Engine v${VERSION} package..."

# Keep the declared version and the filename in sync.
CONTROL_VERSION="$(awk '/^Version:/ {print $2}' "$PKG_DIR/DEBIAN/control")"
if [ "$CONTROL_VERSION" != "$VERSION" ]; then
echo "ERROR: DEBIAN/control says $CONTROL_VERSION but this script builds $VERSION." >&2
exit 1
fi

# --- Stage payload -------------------------------------------------------
# Wipe generated content so removed modules never linger in the package.
rm -rf "$SHARE_DIR/sources" "$SHARE_DIR/wallpaper_collections"
find "$SHARE_DIR" -maxdepth 1 -name '*.py' -delete
find "$SHARE_DIR" -name '__pycache__' -type d -prune -exec rm -rf {} + 2>/dev/null || true
find "$SHARE_DIR" -name '*.pyc' -delete 2>/dev/null || true

install -d "$SHARE_DIR" "$SHARE_DIR/sources" "$SHARE_DIR/wallpaper_collections"

# Application modules. Copied by glob rather than an explicit list: a
# hardcoded list silently omits newly added modules, which ships a package
# that crashes on import.
for src in "$SRC_DIR"/*.py; do
name="$(basename "$src")"
install -m 644 "$src" "$SHARE_DIR/$name"
done
install -m 644 "$SRC_DIR/data.json" "$SHARE_DIR/data.json"
install -m 644 "$SRC_DIR/logo.png" "$SHARE_DIR/logo.png"

# Entry point is executable.
chmod 755 "$SHARE_DIR/indicator.py"

install -m 644 "$SRC_DIR/sources/"*.py "$SHARE_DIR/sources/"
install -m 644 "$SRC_DIR/wallpaper_collections/"*.py "$SHARE_DIR/wallpaper_collections/"
install -m 644 "$SRC_DIR/wallpaper_collections/"*.json "$SHARE_DIR/wallpaper_collections/"

# Launcher wrapper.
chmod 755 "$PKG_DIR/usr/bin/earthview-wallpaper"

# NOTE: no wallpaper.jpg is shipped. The downloaded wallpaper is per-user
# runtime data and is written to ~/.cache/earthview/ at runtime, which keeps
# /usr/share read-only and root-owned.

# --- Documentation -------------------------------------------------------
# Debian policy requires a changelog and copyright file, and expects the
# changelog and man pages to be gzip compressed. Pristine sources live in
# packaging/ and are staged here, so the build never destroys its own inputs
# and repeated runs are idempotent.
DOC_SRC="$SCRIPT_DIR/packaging"
DOC_DIR="$PKG_DIR/usr/share/doc/earthview-wallpaper"
MAN_DIR="$PKG_DIR/usr/share/man/man1"

for required in changelog copyright earthview-wallpaper.1; do
if [ ! -f "$DOC_SRC/$required" ]; then
echo "ERROR: missing packaging/$required" >&2
exit 1
fi
done

rm -rf "$DOC_DIR" "$MAN_DIR"
install -d "$DOC_DIR" "$MAN_DIR"

install -m 644 "$DOC_SRC/copyright" "$DOC_DIR/copyright"
gzip -9nc "$DOC_SRC/changelog" > "$DOC_DIR/changelog.gz"
gzip -9nc "$DOC_SRC/earthview-wallpaper.1" > "$MAN_DIR/earthview-wallpaper.1.gz"
chmod 644 "$DOC_DIR/changelog.gz" "$MAN_DIR/earthview-wallpaper.1.gz"

# The changelog's top version must match what we are building.
CHANGELOG_VERSION="$(head -1 "$DOC_SRC/changelog" | sed -E 's/.*\(([^)]+)\).*/\1/')"
if [ "$CHANGELOG_VERSION" != "$VERSION" ]; then
echo "ERROR: changelog top entry is $CHANGELOG_VERSION but building $VERSION." >&2
exit 1
fi

# --- Icons ---------------------------------------------------------------
# Staged from packaging/icons so the installed theme always matches the
# master artwork. Each PNG must match its directory name or lintian fails.
ICON_SRC="$SCRIPT_DIR/packaging/icons"
ICON_DIR="$PKG_DIR/usr/share/icons/hicolor"

if [ ! -f "$ICON_SRC/earthview-wallpaper.svg" ]; then
echo "ERROR: missing packaging/icons/earthview-wallpaper.svg" >&2
exit 1
fi

rm -rf "$ICON_DIR"
for size in 32 48 64 128 256 512; do
src="$ICON_SRC/earthview-wallpaper-${size}.png"
if [ ! -f "$src" ]; then
echo "ERROR: missing packaging/icons/earthview-wallpaper-${size}.png" >&2
exit 1
fi
install -Dm644 "$src" "$ICON_DIR/${size}x${size}/apps/earthview-wallpaper.png"
done
install -Dm644 "$ICON_SRC/earthview-wallpaper.svg" \
"$ICON_DIR/scalable/apps/earthview-wallpaper.svg"

# --- Normalise permissions ----------------------------------------------
# Directories 755 and data files 644 as policy requires; the build tree may
# carry group-writable bits from the working copy.
find "$PKG_DIR" -path "$PKG_DIR/DEBIAN" -prune -o -type d -exec chmod 755 {} +
find "$PKG_DIR/usr/share/icons" -type f -exec chmod 644 {} +
chmod 644 "$PKG_DIR/usr/share/applications/earthview-wallpaper.desktop"

# --- Maintainer scripts --------------------------------------------------
for script in postinst prerm postrm; do
if [ -f "$PKG_DIR/DEBIAN/$script" ]; then
chmod 755 "$PKG_DIR/DEBIAN/$script"
bash -n "$PKG_DIR/DEBIAN/$script" \
|| { echo "ERROR: syntax error in DEBIAN/$script" >&2; exit 1; }
fi
done
chmod 644 "$PKG_DIR/DEBIAN/control"

# --- Build ---------------------------------------------------------------
# --root-owner-group forces root:root ownership inside the archive without
# needing fakeroot. Without it, files inherit the build user and land in
# /usr/share owned by that user.
rm -f "$OUTPUT"
dpkg-deb --root-owner-group --build "$PKG_DIR" "$OUTPUT"

# --- Verify payload ------------------------------------------------------
# Confirm every source module is present in the built archive. A missing
# module produces a package that fails at import time, which is not visible
# from the build output alone.
CONTENTS="$(dpkg-deb -c "$OUTPUT")"
MISSING=0

check_present() {
if ! printf '%s' "$CONTENTS" | grep -q "$1"; then
echo "ERROR: $1 missing from package" >&2
MISSING=1
fi
}

for src in "$SRC_DIR"/*.py; do
check_present "/usr/share/earthview/$(basename "$src")"
done
for src in "$SRC_DIR"/sources/*.py; do
check_present "/usr/share/earthview/sources/$(basename "$src")"
done
for src in "$SRC_DIR"/wallpaper_collections/*.py; do
check_present "/usr/share/earthview/wallpaper_collections/$(basename "$src")"
done
check_present "/usr/bin/earthview-wallpaper"
check_present "/usr/share/doc/earthview-wallpaper/changelog.gz"
check_present "/usr/share/doc/earthview-wallpaper/copyright"
check_present "/usr/share/man/man1/earthview-wallpaper.1.gz"

if [ "$MISSING" -ne 0 ]; then
echo "Build failed verification." >&2
rm -f "$OUTPUT"
exit 1
fi

# Confirm the entry point can resolve all its imports from the staged tree.
# Catches a missing module even when the file list looks complete.
if ! ( cd "$SHARE_DIR" && python3 -c "
import ast, sys, pathlib
local = {p.stem for p in pathlib.Path('.').glob('*.py')}
local |= {'sources', 'wallpaper_collections'}
tree = ast.parse(pathlib.Path('indicator.py').read_text())
missing = []
for node in ast.walk(tree):
if isinstance(node, ast.ImportFrom) and node.level == 0 and node.module:
root = node.module.split('.')[0]
if root in local:
continue
try:
__import__(root)
except ImportError:
missing.append(root)
if missing:
print('unresolved imports: ' + ', '.join(sorted(set(missing))), file=sys.stderr)
sys.exit(1)
" ); then
echo "ERROR: staged tree has unresolved imports." >&2
rm -f "$OUTPUT"
exit 1
fi

echo
echo "Package built: $(basename "$OUTPUT")"
echo
echo "Install with:"
echo " sudo apt install $OUTPUT"
Binary file added earthview-package.deb
Binary file not shown.
15 changes: 15 additions & 0 deletions earthview-package/DEBIAN/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Package: earthview-wallpaper
Version: 2.4.0
Section: utils
Priority: optional
Architecture: all
Depends: python3 (>= 3.8), python3-gi, python3-gi-cairo, python3-cairo, python3-bs4, python3-lxml, python3-requests, gir1.2-gtk-3.0, gir1.2-ayatanaappindicator3-0.1, gir1.2-notify-0.7
Maintainer: Earth View Wallpaper <earthview@example.com>
Description: Multi-source desktop wallpaper engine
Earth View Wallpaper Engine pulls stunning imagery from multiple sources
including Google Earth View, NASA EPIC, Himawari-8, GOES satellites,
NASA APOD, and Unsplash.
.
Features include live satellite feeds, time-aware mode, fly-over routes,
themed collections, favorites, history, and configurable auto-change.
Homepage: https://github.com/yourusername/earthview
158 changes: 158 additions & 0 deletions earthview-package/DEBIAN/postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/bin/bash
# postinst - runs after the package is unpacked and configured.
#
# Ensures a clean install: removes stale bytecode from previous versions,
# refreshes desktop/icon caches, and launches the app.
#
# Launch behaviour differs by situation, using dpkg's second argument which
# holds the previously configured version (empty on a fresh install):
# fresh install - start for every user with an active graphical session
# upgrade - start only for users who had it running before, so that
# someone who deliberately quit is not relaunched
#
# dpkg invokes this as root, so starting a tray application means entering the
# target user's session explicitly via their session bus.

set -e

SHARE_DIR=/usr/share/earthview
STATE_FILE=/run/earthview-wallpaper.restart
PREVIOUS_VERSION="$2"

# Users with a real login shell and home under /home, one per line.
desktop_users() {
for home in /home/*; do
[ -d "$home" ] || continue
user="$(basename "$home")"
id "$user" >/dev/null 2>&1 || continue
printf '%s\n' "$user"
done
}

# Path to a user's session bus, or empty when they have no active session.
session_bus() {
local uid
uid="$(id -u "$1" 2>/dev/null)" || return 0
local bus="/run/user/$uid/bus"
[ -S "$bus" ] && printf '%s' "$bus"
}

# Best-effort discovery of the user's X/Wayland display, read from an existing
# session process. Falls back to :0, which covers the common single-seat case.
user_display() {
local user="$1" pid display=""

for pattern in gnome-shell plasmashell xfce4-session gnome-session Xorg; do
pid="$(pgrep -u "$user" -o "$pattern" 2>/dev/null)" || continue
[ -n "$pid" ] || continue
[ -r "/proc/$pid/environ" ] || continue
display="$(tr '\0' '\n' < "/proc/$pid/environ" \
| sed -n 's/^DISPLAY=//p' | head -1)"
[ -n "$display" ] && break
done

printf '%s' "${display:-:0}"
}

# Start the app for one user inside their session. Never fatal: a failure to
# launch must not leave the package unconfigured.
start_for_user() {
local user="$1"
local bus display

bus="$(session_bus "$user")"
[ -n "$bus" ] || return 0 # not logged in to a graphical session

# Already running for this user; the app's own lock would refuse anyway.
if pgrep -u "$user" -f "$SHARE_DIR/indicator.py" >/dev/null 2>&1; then
return 0
fi

display="$(user_display "$user")"

echo "Starting Earth View Wallpaper for $user..."
# setsid detaches from dpkg so the app is not killed when this script ends.
su -l "$user" -c \
"DISPLAY='$display' \
DBUS_SESSION_BUS_ADDRESS='unix:path=$bus' \
setsid nohup earthview-wallpaper >/dev/null 2>&1 < /dev/null &" \
>/dev/null 2>&1 || true
}

case "$1" in
configure)
# Remove bytecode compiled from previous versions. Python normally
# invalidates by mtime, but stale __pycache__ from an older layout can
# linger after modules are renamed or removed.
find "$SHARE_DIR" -name '__pycache__' -type d -prune \
-exec rm -rf {} + 2>/dev/null || true
find "$SHARE_DIR" -name '*.pyc' -delete 2>/dev/null || true

# The launcher must be executable.
chmod 755 "$SHARE_DIR/indicator.py" 2>/dev/null || true
chmod 755 /usr/bin/earthview-wallpaper 2>/dev/null || true

# Refresh icon cache.
if command -v gtk-update-icon-cache >/dev/null 2>&1; then
gtk-update-icon-cache -f /usr/share/icons/hicolor/ 2>/dev/null || true
fi

# Refresh desktop database.
if command -v update-desktop-database >/dev/null 2>&1; then
update-desktop-database /usr/share/applications/ 2>/dev/null || true
fi

# Refresh the man page index.
if command -v mandb >/dev/null 2>&1; then
mandb -q 2>/dev/null || true
fi

# Migration: versions up to 2.0.2 stored the wallpaper inside this
# directory, which is removed on upgrade. Any desktop still pointing
# at that path would render black. Clear those stale references so the
# app reapplies a valid wallpaper on next start.
for user in $(desktop_users); do
bus="$(session_bus "$user")"
[ -n "$bus" ] || continue

for key in picture-uri picture-uri-dark; do
current="$(su -l "$user" -c \
"DBUS_SESSION_BUS_ADDRESS='unix:path=$bus' \
gsettings get org.gnome.desktop.background $key" \
2>/dev/null || true)"
case "$current" in
*"/usr/share/earthview/wallpaper.jpg"*)
echo "Clearing stale wallpaper reference ($key) for $user..."
su -l "$user" -c \
"DBUS_SESSION_BUS_ADDRESS='unix:path=$bus' \
gsettings reset org.gnome.desktop.background $key" \
>/dev/null 2>&1 || true
;;
esac
done
done

if [ -z "$PREVIOUS_VERSION" ]; then
# Fresh install: start for anyone currently logged in.
for user in $(desktop_users); do
start_for_user "$user"
done
elif [ -s "$STATE_FILE" ]; then
# Upgrade: only restore users who had it running.
while read -r user; do
[ -n "$user" ] || continue
start_for_user "$user"
done < "$STATE_FILE"
fi
rm -f "$STATE_FILE" 2>/dev/null || true

echo "Earth View Wallpaper Engine installed successfully."
echo "Launch from the applications menu or run: earthview-wallpaper"
echo "Enable 'Start at login' from the tray menu to run it on boot."
;;

abort-upgrade|abort-remove|abort-deconfigure)
;;
esac

exit 0
Loading