2

Random wallpaper with just bash and systemd

 2 years ago
source link: https://randthoughts.github.io/random-wallpaper-with-just-bash-and-systemd/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Random thoughts

A few thoughts you're free to ignore

Random wallpaper with just bash and systemd

July 21, 2022

I’m a big fan of Variety1, probably the most popular wallpaper changer among Linux users. It’s been sitting in my GNOME desktop’s system tray for a long time. (Yes, I know GNOME doesn’t actually have a system tray, but I can’t live without it so I installed Ubuntu’s AppIndicator and KStatusNotifierItem Support extension).

Recently, Variety started having some hiccups, for the simple reason that the API key it uses for Unsplash is shared among all Variety’s users, thus incurring rate limiting2. Since I don’t use most of Variety’s features, and I have only Unsplash enabled as image source, I scratched an itch by writing my own little wallpaper changer. Truth be told, it’s nothing fancy, but it does the job.

Here’s the Bash script (be sure to chmod +x it before running):

#!/usr/bin/env bash

ACCESS_KEY="YOUR-UNSPLASH-ACCESS-KEY"
TOPIC="bo8jQKTaE0Y" # "Wallpapers"
WALLPAPER_DIR="${HOME}/.local/share/backgrounds"

if ! photo_path="$(mktemp -p "${WALLPAPER_DIR}" "unsplash.com.XXXXXXXXXX.jpg")"
then
  >&2 echo "Error: failed to create temporary file."
  exit 1
fi

if ! photo_url="$(curl --silent --show-error --header "Authorization: Client-ID ${ACCESS_KEY}" \
  "https://api.unsplash.com/photos/random?orientation=landscape&topic=${TOPIC}" \
  | grep --ignore-case --only-matching --perl-regexp '(?<=download":").*?(?=")')"
then
  >&2 echo "Error: failed to retrieve download URL."
  exit 1
fi

if ! curl --silent --show-error --location --header "Authorization: Client-ID ${ACCESS_KEY}" \
  --output "${photo_path}" "${photo_url}"
then
  >&2 echo "Error: failed to download photo."
  exit 1
fi

for setting_name in "background" "screensaver"; do
  if ! gsettings set "org.gnome.desktop.${setting_name}" "picture-uri" "file:///${photo_path}"
  then
    >&2 echo "Error: failed to set photo as ${setting_name}."
    exit 1
  fi
done

I told you nothing fancy. Indeed, it does nothing more than downloading a random picture from Unplash’s Wallpapers topic, saving it to the user’s default backgrounds directory, and setting it as GNOME wallpaper. Additionally, it sets the picture as screen saver, so that it is displayed in the lock screen as well. One thing that could be certainly be improved–while still adhering to the KISS principle–is preventing files from accumulating boundlessly, for example by deleting older images based on their modification time.

Of course, the above script assumes that you use GNOME as desktop environment, and that you have obtained an API key from Unsplash3. The default, free “demo” mode is capped at 50 requests per hour, which is more than enough for this use case… Right?

If you prefer other topic(s) to pull photos from, here are the respective IDs:

  • Current Events: BJJMtteDJA4
  • Wallpapers: bo8jQKTaE0Y
  • 3D Renders: CDwuwXJAbEw
  • Textures & Patterns: iUIsnVtjB0Y
  • Experimental: qPYsDzvJOYc
  • Architecture: rnSKDHwwYUk
  • Nature: 6sMVjTLSkeQ
  • Business & Work: aeu6rL-j6ew
  • Fashion: S4MKLAsBB74
  • Film: hmenvQhUmxM

Actually, you don’t even have to choose a topic. The ways in which the pool of photos can be narrowed down are explained in the API docs4.

Anyway, we’ve done only half of the job, as the script alone doesn’t automate wallpaper switching. The standard way of achieving that is a systemd service/timer combo. Since we’re only interested in running the script as regular, non-root user, unit files can be conveniently installed under ~/.config/systemd/user. Here is the service unit I use:

# ~/.config/systemd/user/wallchanger.service 
[Unit]
Description=Change GNOME wallpaper
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/path/to/wallchanger.sh

Of course, replace /path/to/wallchanger.sh with whatever the script’s path is. The unit depends on network-online.target, so that it’s started only when the system is connected to the Internet, which is indeed needed to fetch images from Unsplash. As mentioned, we also need a timer unit, which is responsible for the actual automation:

# ~/.config/systemd/user/wallchanger.timer
[Unit]
Description=Start wallchanger.service hourly

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target

Notice that for this to work, the two unit files must have the same name (except for the .timer/.service suffix). Additionally, you can change hourly to your preferred interval. For example, to switch wallpaper once a day, you can put daily. Systemd has its own way of specifying times and dates, so if you need something more complex, I encourage you to check systemd’s documentation5.

The Persistent=true line ensures that if, for example, the system is resumed from sleep after a long time, the wallpaper is changed immediately once to “catch up” with skipped runs.

Once everything is in place, we need to tell systemd to reload its configuration with:

systemctl --user daemon-reload

Now, it’s time to test the service unit with:

systemctl --user start wallchanger.service

If you don’t see any output, don’t despair, that’s the expected outcome! Actually, your desktop’s wallpaper should have already changed by now. If that’s not the case, you can inspect what’s going on with journalctl:

journalctl --user --unit wallchanger.service

It is also possible to monitor the unit’s log in realtime by adding the --follow option to journalctl.

Lastly, we need to enable and start the timer so that it works on every boot:

systemctl enable --now wallchanger.timer

That’s all folks!


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK