Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=Bluefin Dynamic Wallpaper
After=graphical-session.target
PartOf=graphical-session.target

[Service]
Type=oneshot
ExecStart=/usr/libexec/bluefin-dynamic-wallpaper

[Install]
WantedBy=graphical-session.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=Run Bluefin Dynamic Wallpaper daily
PartOf=graphical-session.target

[Timer]
OnBootSec=1min
OnUnitActiveSec=24h
Persistent=true

[Install]
WantedBy=graphical-session.target
68 changes: 68 additions & 0 deletions system_files/shared/usr/libexec/bluefin-dynamic-wallpaper
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
set -euo pipefail

# Set the appropriate wallpaper based on month and hemisphere
# This will be run at login and periodically to update the wallpaper

readonly WALLPAPER_BASE_PATH="/usr/share/backgrounds/bluefin"

# Don't clobber custom wallpaper
CURRENT_WALLPAPER="$(gsettings get org.gnome.desktop.background picture-uri)"
CURRENT_WALLPAPER="${CURRENT_WALLPAPER#\'file://}"
CURRENT_WALLPAPER="${CURRENT_WALLPAPER%\'}"

if [[ "$CURRENT_WALLPAPER" != "${WALLPAPER_BASE_PATH}"/*-bluefin.xml ]]; then
echo "User has a personal wallpaper set. Not changing it."
exit 0
fi


MONTH="$(date +%m)"
MONTH_NUM="${MONTH#0}" # Remove leading zero if present

LATITUDE="$(/usr/libexec/get-geoclue-latitude.py)"
LOCATION_EXIT=$?
if [[ $LOCATION_EXIT -eq 2 ]]; then
echo "Location services disabled or denied, not touching wallpaper"
exit 0
elif [[ $LOCATION_EXIT -ne 0 ]]; then
echo "Error getting location, not touching wallpaper"
exit 1
else
if ! [[ "$LATITUDE" =~ ^-?[0-9]+\.?[0-9]*$ ]]; then
echo "Invalid latitude format: $LATITUDE" >&2
exit 1
fi

# Determine hemisphere
if [[ "${LATITUDE:0:1}" == "-" ]]; then
HEMISPHERE="south"
# Add 6 months and wrap around if needed
MONTH_NUM=$(( (MONTH_NUM + 6 - 1) % 12 + 1 ))
else
HEMISPHERE="north"
fi
fi

# Format month with leading zero if needed
if [[ $MONTH_NUM -lt 10 ]]; then
MONTH_PADDED="0$MONTH_NUM"
else
MONTH_PADDED="$MONTH_NUM"
fi

WALLPAPER_PATH="${WALLPAPER_BASE_PATH}/${MONTH_PADDED}-bluefin.xml"

if [[ ! -f "$WALLPAPER_PATH" ]]; then
echo "Wallpaper file not found: $WALLPAPER_PATH" >&2
exit 1
fi

# Apply the wallpaper
if gsettings set org.gnome.desktop.background picture-uri "file://$WALLPAPER_PATH" && \
gsettings set org.gnome.desktop.background picture-uri-dark "file://$WALLPAPER_PATH"; then
echo "Successfully set wallpaper to $WALLPAPER_PATH (adjusted month: $MONTH_NUM, hemisphere: $HEMISPHERE)"
else
echo "Failed to set wallpaper" >&2
exit 1
fi
61 changes: 61 additions & 0 deletions system_files/shared/usr/libexec/get-geoclue-latitude.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python3

import time
import sys
from pydbus import SystemBus

LOCATION_TIMEOUT_SECONDS = 30
POLL_INTERVAL_SECONDS = 0.5

def get_geoclue_client():
bus = SystemBus()
manager = bus.get("org.freedesktop.GeoClue2", "/org/freedesktop/GeoClue2/Manager")
client_path = manager.CreateClient()
client = bus.get("org.freedesktop.GeoClue2", client_path)

# Set client properties
client.DesktopId = "bluefin-dynamic-wallpaper"
client.RequestedAccuracyLevel = 1
client.Start()

return bus, client

def wait_for_location(bus, client):
"""Wait for location data to become available."""
max_attempts = int(LOCATION_TIMEOUT_SECONDS / POLL_INTERVAL_SECONDS)

for attempt in range(max_attempts):

Check warning on line 27 in system_files/shared/usr/libexec/get-geoclue-latitude.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

system_files/shared/usr/libexec/get-geoclue-latitude.py#L27

Unused variable 'attempt'
try:
if hasattr(client, 'Location') and client.Location:
location_obj = bus.get("org.freedesktop.GeoClue2", client.Location)
if hasattr(location_obj, 'Latitude') and location_obj.Latitude is not None:
return location_obj.Latitude
except Exception as e:
# Ignore "object does not export any interfaces" errors during initialization
if "object does not export any interfaces" not in str(e):
print(f"Unexpected error while waiting for location: {e}", file=sys.stderr)
sys.exit(1)

time.sleep(POLL_INTERVAL_SECONDS)

# Timeout reached
print("error: location unavailable after timeout", file=sys.stderr)
sys.exit(1)

def main():
try:
bus, client = get_geoclue_client()
latitude = wait_for_location(bus, client)
print(latitude)
sys.exit(0)

except Exception as e:
if "org.freedesktop.DBus.Error.AccessDenied" in str(e):
print("Location services disabled or denied", file=sys.stderr)
sys.exit(2)
else:
print(f"error: {e}", file=sys.stderr)
sys.exit(1)

if __name__ == "__main__":

Check notice on line 60 in system_files/shared/usr/libexec/get-geoclue-latitude.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

system_files/shared/usr/libexec/get-geoclue-latitude.py#L60

expected 2 blank lines after class or function definition, found 1 (E305)
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[Desktop Entry]
Name=Bluefin Dynamic Wallpaper
Exec=/usr/libexec/bluefin-dynamic-wallpaper
Icon=preferences-desktop-wallpaper
Type=Application
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

source /usr/lib/ublue/setup-services/libsetup.sh

version-script dynamic-wallpaper user 1 || exit 0

set -euo pipefail

# Enable dynamic wallpaper service and timer
echo "Enabling dynamic wallpaper service and timer"
systemctl --user enable --now bluefin-dynamic-wallpaper.service
systemctl --user enable --now bluefin-dynamic-wallpaper.timer