Wednesday, December 26, 2012

Background Changing Script

I wrote a fairly basic bash script to change the background image periodically. The script expects to find a configuration file in ~/.bgchanger/config, which needs to look something like:

# this gets sourced in the main script
# I didn't put in defaults, so don't delete any of these

# folder where the backgrounds are (or symlinks to the backgrounds)
BGFOLDER=${HOME}/.bgchanger/backgrounds

# delay between transitions, in seconds
# this IS NOT an argument to sleep, it MUST be in seconds
# get a calculator if you can't multiply by 60, or use 
# $((5*60)) or something
DELAY=300

# SORTCMD is the sorting command to use when building the file list
# when the program is started or when it receives the SIGUSR2 signal.
# RESORTCMD is the sorting command to use once all of the backgrounds 
# have been looped over.
# so, the thing works like this: find ... | (RE)SORTCMD
# cat: does nothing (however find spits out the files for SORTCMD)
# sort: alphabetize somehow (read man sort); I like sort -fV
# shuf: shuffle (sort -R probably does the same thing)
# 
# For alphabetized backgrounds, use sort and cat.
# For shuffled backgrounds, use shuf and cat.
# For random backgrounds, use shuf and shuf (guaranteed to 
#     run through all files before repeating).
SORTCMD="shuf"
SORTARG="" # I REALLY want to know how to put these two as one variable
RESORTCMD="cat"
RESORTARG=""

# this gets jammed in a regex, case-sensitive as-is
EXTENSIONS="jpg|png|JPG|PNG"

# program which sets the background
# BGSETCMD='gsettings set org.gnome.desktop.background picture-uri "file://"'
BGSETCMD=fbsetbg
BGSETARG=-a

gsettings seems to introduce a really annoying lag in Gnome 3.6, so I ended up using fluxbox's background setter. I guess xsetroot would work, too, but I don't really know how to use it.

The folder with the backgrounds can contain any folder structure, and should not have issues with spaces in filenames and stuff. I keep my backgrounds wherever I want and symlink the ones I want to use in $BGFOLDER.

killall -USR1 bgchanger skips to the next background
killall -USR2 bgchanger reloads the backgrounds (effectively like restarting the script).

The script itself is:
#!/bin/bash
if pidof -x $(basename $0) -o $$ > /dev/null; then
        echo "$0 is already running. Exiting."
        exit
fi

CONFIGFILE=${HOME}/.bgchanger/config
source $CONFIGFILE

interruptable_sleep()
{
        RUNNING=1;
        for (( i = 0; i < $1 && RUNNING == 1; i++ ))
        do
                sleep 1
        done
        [ $RUNNING == -1 ] && echo "Skipping to next background prematurely!"
}
trap 'RUNNING=-1' SIGUSR1

create_file_list()
{
        echo -n "(Re)Generating list of backgrounds... "
        IFS=$'\n' FILES=$(find "${BGFOLDER}" -regex '.*..['${EXTENSIONS}']' | $SORTCMD $SORTARG)

        # also store as a string without any weird shit
        ONESTRING=''
        for FILE in $FILES; do
                ONESTRING=${ONESTRING}${FILE}"\n"
        done
        ONESTRING=${ONESTRING%??}
        echo "DONE!"
}
trap 'RUNNING=-2; SHOULDSTOP=1; create_file_list' SIGUSR2

create_file_list

while :
do
        IFS=$'\n' FILES=$(echo -e $ONESTRING | $RESORTCMD $RESORTARG) # shuffles files
        echo 'Starting From the Beginning'
        SHOULDSTOP=-1
        for FILE in $FILES; do
                echo ${FILE}
                ${BGSETCMD} ${BGSETARG} ${FILE}
                interruptable_sleep $DELAY
                [ $SHOULDSTOP == 1 ] && break
        done
done

No comments:

Post a Comment