123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- #!/bin/bash
- me="${0##*/}"
- ### DEPENDENCIES ###
- # coreutils awk sed xset xssstate xplanet
- ### RECOMMENDS ###
- # cputool feh wget xdpyinfo
- # The script fetches a screensaver timeout via xset and might behave unpredictably if that fails.
- ###############################################################################
- # USER ADJUSTABLE VARIABLES
- xplanetdir="$HOME/.xplanet"
- imgdir="$xplanetdir/images"
- allfeh=1 # set to 1: Use feh for setting the background, not xplanet
- tmpfile=/tmp/welrjkht.png
- # EARTH MAP
- # needs to point to the directory structure created by my get_bluemarble script
- bluemarble="$xplanetdir/bluemarble"
- prefix="world.topo.bathy" # "world" "world.topo" - the available map variations
- suffix="8192x4096_less.png" # resolution and filetype - you probably don't need to change this.
- # in the end the image for this month of the year will be linked to $imgdir/earth.jpg, which is what xplanet defaults to
- # the scripts directory will be created by this script!
- scenes="$xplanetdir/scripts/scenes"
- # how ill the scene be chosen from the scene file?
- #~ choose_scene="random" # randomly
- #~ choose_scene="daily" # daily change the scene, going through $scenes
- #~ choose_scene=1 # where n is a positive integer for the nth scene in your scenes file
- choose_scene="$1"
- delay=60 # sleep between runs/checks
- limit=10 # don't let cpu usage go beyond this many percent - only works when cputool is installed
- # setting this to 1 makes the script check for a current cloud image and
- # download it to the path $cloudimg
- # the get_clouds subroutine relies on this repository: github.com/apollo-ng/cloudmap
- apollo_ng_clouds=0
- # the following options are relevant only when apollo_ng_clouds == 1
- # this should be present in your xplanet config:
- cloudimg="$imgdir/clouds_5400x2700.jpg"
- maxdiff="10800" # if our cloud image is older than that - 3 hours - check if there's a new one
- #~ options=( -num_times 1 -date_format %c -color 0x555555 -pango -fontsize 8 \
- #~ -font "xos4 terminus" -labelpos +20+50 -glare 0 \
- #~ -label_string "Looking at: %t - Origin: %o" )
- [[ $allfeh == 1 ]] && options=( -num_times 1 -glare 0 ) || options=( -num_times 1 -glare 0 -transparency )
- [[ $allfeh == 1 ]] && geometry="$(xdpyinfo | awk '/dimensions/{print $2}')"
- ##############################################################################
- # HERE BE LIONS
- # sleep as a builtin
- for file in /usr/lib*/bash/sleep; do
- [ -r "$file" ] && enable -f "$file" sleep && break
- done
- # Portable enough?
- get_clouds() {
- # CLOUD MAP for all - praise be:
- # apollo.open-resource.org/mission:log:2014:06:17:new-fresh-global-cloudmap-distribution-service-xplanet
- # using this function is configurable; set to anything but 1 equals false
- [[ "$apollo_ng_clouds" != 1 ]] && return
- #~ __msg__ "Checking for a cloud map newer than $cloudimg"
- local_age="$(stat -c%Y "$cloudimg")"
- now="$(date +%s)"
- __msg__ "Local cloudmap age $local_age; time now $now; difference $((now - local_age))s"
- if (( now - local_age > 10800 )); then
- __msg__ "It's been longer than ${maxdiff}s, time to check if there's a newer one..."
- # Get latest remote checksum
- originsha=$(wget https://raw.githubusercontent.com/apollo-ng/cloudmap/master/global.sha256 --no-cache -q -O -)
- originsha="${originsha%% *}"
- # Generate local checksum
- if [ -e "$cloudimg" ]; then
- localsha="$(sha256sum "$cloudimg")"
- localsha="${localsha%% *}"
- fi
- # Check if we're behind origin
- __msg__ "Checksum comparison says remote file is "
- if [ "${originsha}" != "${localsha}" ]; then
- __msg__ "not the same file as local file; getting it."
- newcloudimg="$imgdir/newcloudimg.jpg"
- # Download raw global.jpg from master
- wget https://raw.githubusercontent.com/apollo-ng/cloudmap/master/global.jpg?${originsha} --no-cache -q -O "$newcloudimg"
- # Generate checksum of downloaded file
- newsha="$(sha256sum "$newcloudimg")"
- newsha="${newsha%% *}"
- # Check if download's chksum corresponds to origin
- [ "$newsha" == "$originsha" ] && mv "$newcloudimg" "$cloudimg" || rm "$newcloudimg"
- else
- __msg__ "the same file as local file. Nothing to do."
- fi
- else
- __msg__ "That's not longer than ${maxdiff}s, nothing to do."
- fi
- __msg__ "Back to main loop."
- }
- set_bg() {
- # if -background is found in options (read from current scene) set it as root window background before xplanet even starts
- for ((i=1;i<=$#;i++)); do
- [[ "${!i}" == "-background" ]] && ((i++)) && background="${!i}" && break
- done
- __msg__ "Found background $background"
- if [ -r "$background" ]; then
- __msg__ feh --no-fehbg --bg-fill "$background"
- feh --no-fehbg --bg-fill "$background"
- elif [ -r "$imgdir/$background" ];then
- __msg__ feh --no-fehbg --bg-fill "$imgdir/$background"
- feh --no-fehbg --bg-fill "$imgdir/$background"
- fi
- }
- __msg__() {
- echo -e "${me}@${SECONDS}s: $@"
- }
- aftermath() {
- # things to do after root window update
- signal=SIGUSR2
- for pid in $(pidof root-tail); do
- echo "kill -s $signal $pid"
- kill -s $signal $pid
- done
- }
- allfehornot() {
- if [[ $allfeh == 1 ]]; then
- "$@" -output "$tmpfile" -geometry "$geometry"
- feh --no-fehbg --bg-tile "$tmpfile"
- rm "$tmpfile"
- else
- "$@"
- fi
- }
- ##############################################################################
- # MAIN
- sstime="$(xset q | awk '/timeout/ {print $2}')" # the screensaver delay time in s
- cputool="$(which cputool)"
- [ ! -x "$cputool" ] && cputool=0 && limit=100
- # EARTH MAP
- month="$(date +%m)"
- map_real="$bluemarble/$month/$prefix/$prefix.2004$month.3x$suffix"
- map_link="$imgdir/earth.jpg"
- if [ ! -a "$map_link" ] || [ -h "$map_link" ]]; then
- ln -sf "$map_real" "$map_link"
- else
- __msg__ "Not symlinking chosen earth map\n$map_real\nto $map_link\nbecause $map_link\nalready exists and is not a symbolic link."
- fi
- ##############################################################################
- # we need to sanitize the scenes file first (mostly because wc -l might return something wrong):
- tail -c1 "$scenes" | read -r _ || echo >> "$scenes" # if a trailing newline is missing, add one
- sed -i '/^$/d' "$scenes" # if there's empty lines, delete them
- allscenes="$(wc -l "$scenes")"
- allscenes="$(( ${allscenes%% *} / 2))"
- case "$choose_scene" in
- random) chosen=$((RANDOM%allscenes + 1));;
- daily) chosen=$(($(date +%-j)%allscenes + 1));;# %j: day of the year - so we change the scene once a day
- *) if [ "$choose_scene" -gt 0 ] && [ "$choose_scene" -le "$allscenes" ]; then
- chosen="$choose_scene"
- else
- __msg__ "Wrong value for choose_scene: $choose_scene. Exiting."
- exit 1
- fi;;
- esac
- __msg__ "Chosen scene #$chosen:"
- chosen=$((chosen*2))
- sed -n $((chosen - 1))p "$scenes"
- eval set -- "$(sed -n ${chosen}p "$scenes")"
- __msg__ "All options:\n${options[@]} $@\n"
- # if a background image is found in options, set it with feh
- set_bg "$@"
- aftermath
- killall xplanet >/dev/null 2>&1
- get_clouds
- __msg__ "First xplanet run without CPU throttling ..."
- runtime=$SECONDS
- ###########################
- xplanet "${options[@]}" "$@"
- ###########################
- aftermath
- runtime=$(( SECONDS - runtime)) # a very rough calculation of how long xplanet took without cpu throttling; this is used to determine
- # max. idle time before screensaver kicks in
- __msg__ "... That took $runtime seconds"
- (( runtime == 0 )) && runtime=1
- runtime=$(( runtime * (100/limit) ))
- __msg__ "Screensaver delay according to xset: ${sstime}s\nCalculated xplanet runtime with CPU usage limited to ${limit}%: ${runtime}s"
- # assume xplanet takes Xs to render things, so if the screensaver comes on in Xs, don't even start rendering
- (( sstime > runtime )) && sstime="$((sstime - runtime))" || sstime="$runtime"
- __msg__ "If idle for more than ${sstime}s do not start xplanet.\n"
- sstime="$((sstime * 1000))" # need it in ms
- while sleep "$delay"; do
- # X11 has been idle for too long?
- idle="$(xssstate -i)"
- __msg__ "Current idle time: $((idle / 1000))s"
- if (( idle > sstime )); then
- __msg__ "Not running xplanet because screensaver is going to activate soon."
- else
- if [[ "$cputool" != 0 ]] && ((limit<100)); then
- __msg__ "Starting throttled xplanet"
- allfehornot cputool -c $limit -- xplanet "${options[@]}" "$@"
- else
- __msg__ "Starting xplanet"
- allfehornot xplanet "${options[@]}" "$@"
- fi
- __msg__ "xplanet finished"
- aftermath
- fi
- get_clouds
- done
|