Created
April 23, 2017 14:22
-
-
Save onli/a002cfbc623a950df0e7cae643b0b317 to your computer and use it in GitHub Desktop.
izulu with KDE plasma detection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# izulu - Change the wallpaper according to the weather | |
# | |
# Copyright (C) 2009 Malte Paskuda | |
# | |
# This program is free software; you can redistribute it and/or modify it | |
# under the terms of the GNU General Public License as published by the | |
# Free Software Foundation; either version 3 of the License, or (at your | |
# option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, but | |
# WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
# General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, see <http://www.gnu.org/licenses/>. | |
# get current weather | |
# $1: city to look for, or latitude | |
# $2 longitude, not needed if $1 was a city | |
# return: current weather | |
getWeather() { | |
echo "$WEATHER_DATA" | jq -r '.currently.icon' # -r makes jq not put " around the string, which is important for the later ifs | |
} | |
# fill WEATHER_DATA with weather API result. NOTE: Always run this at top level, not in a subshell | |
# $1: city or latitude | |
# $2: longitude, not needed if $1 was a city | |
# return: Weather api data (currently JSON) | |
fillWeatherData() { | |
if [ -n "$LATITUDE" ];then | |
local url="http://izulu.onli-blogging.de/forecast/$LATITUDE/$LONGITUDE" | |
else | |
local url="http://izulu.onli-blogging.de/forecast/$CITY" | |
fi | |
WEATHER_DATA=$(wget -q -O - "$url") | |
} | |
# map forecast-code to one of the icons | |
chooseForecastIcon() { | |
forecast="$1" | |
case "$forecast" in | |
"cloudy") | |
echo "forecast_cloud" | |
;; | |
"partly-cloudy-day"|"partly-cloudy-night") | |
echo "forecast_sunnycloud" | |
;; | |
"rain") | |
echo "forecast_rain" | |
;; | |
"clear-day"|"clear-night") | |
echo "forecast_sun" | |
;; | |
"snow" | "sleet") | |
echo "forecast_snow" | |
;; | |
"thunderstorm") | |
echo "forecast_thunderstorm" | |
;; | |
"wind") | |
echo "forecast_wind" # TODO: Add forecast image icon | |
;; | |
"fog") | |
echo "forecast_fog" # TODO: Add forecast image icon | |
;; | |
esac | |
} | |
# set the wallpaper according to the weather | |
# $1: current weather | |
chooseWallpaper() { | |
local weather="$1" | |
case "$weather" in | |
# Sun: | |
"clear-day" | "clear-night") | |
setWallpaper "clear" "gen_sun" | |
;; | |
# Clouds: | |
"partly-cloudy-day" | "partly-cloudy-night") | |
setWallpaper "partly_cloudy" "gen_cloud" | |
;; | |
"cloudy") | |
setWallpaper "cloudy" "gen_cloud" | |
;; | |
# "Rain") | |
"rain") | |
setWallpaper "rain" "gen_rain" | |
;; | |
# "Hail") | |
"hail") | |
setWallpaper "hail" "gen_rain" | |
;; | |
# "Thunderstorm") | |
"thunderstorm") | |
setWallpaper "thunderstorm" "gen_thunder" | |
;; | |
# Snow: | |
"sleet") | |
setWallpaper "sleet" "gen_snow" | |
;; | |
"snow") | |
setWallpaper "snow" "gen_snow" | |
;; | |
# Wind: | |
"wind") | |
setWallpaper "windy" "gen_wind" | |
;; | |
"tornado") | |
setWallpaper "tornado" "gen_wind" | |
;; | |
# Misc: | |
"fog") | |
setWallpaper "fog" "gen_misc" | |
;; | |
*) | |
setWallpaper "cloudy" "gen_cloud" #TODO: set a placeholder image here | |
;; | |
esac | |
} | |
#Choose the wallpaper | |
#$1: the image for the specific state | |
#$2: the image for the generic state, fallback | |
#$3: If set to anything, random-mode will not be triggered | |
setWallpaper() { | |
local specific="$1" | |
local generic="$2" | |
local random_override="$3" | |
if [[ -n "$current" ]];then | |
if [ "$current" == "$specific" ];then | |
if [ ! "$TEMPERATURE" == "TRUE" ] && [ ! "$SWISS_RADAR" == "TRUE" ] && [ ! "$GERMAN_RADAR" == "TRUE" ] && [ ! "$RADAR" == "TRUE" ];then | |
#no dynamic features, so no change necessary | |
return | |
fi | |
fi | |
fi | |
current="$specific" | |
if [ "$RANDOMLY" == "TRUE" ] && [[ -z "$random_override" ]];then | |
random_image=$(cycleWallpaper "$specific" "$generic") | |
if [[ -n "$random_image" ]];then | |
setImage "$random_image" | |
return | |
fi | |
fi | |
if isNight;then | |
specific="$specific"_night | |
generic="$generic"_night | |
fi | |
if [[ -e "$HOME"/.izulu/"$specific" ]];then | |
setImage "$HOME"/.izulu/"$specific" | |
else | |
if [[ -e /usr/share/izulu/"$specific" ]];then | |
setImage /usr/share/izulu/"$specific" | |
else | |
if [[ -e "$HOME"/.izulu/"$generic" ]];then | |
setImage "$HOME"/.izulu/"$generic" | |
else | |
setImage /usr/share/izulu/"$generic" | |
fi | |
fi | |
fi | |
} | |
# set the Wallpaper | |
# $1 the wallpaperfile | |
setImage() { | |
local tmpimage=$(mktemp) | |
# store for later merge - and to be able to write | |
cp "$1" "$tmpimage" | |
if [ "$PREVIEW" == "TRUE" ];then | |
for i in {0..4};do | |
# merge preview-icons with background-image | |
local forecast=$(echo "$WEATHER_DATA" | jq -r '.daily.data['$i'].icon') | |
local icon=$(chooseForecastIcon "$forecast") | |
local tmpicon=$(mktemp) | |
cp "/usr/share/izulu/$icon" "$tmpicon" | |
local day=$(date -d @$(echo "$WEATHER_DATA" | jq -r '.daily.data['$i'].time') "+%A") | |
convert "$tmpicon" -gravity South -fill '#c0bfbd' -font DejaVu-Sans-Condensed -background '#0000' -pointsize 16 -splice 0x24 -annotate +0+2 "${day:0:3}" "$tmpicon" | |
# at least +20 y height to be above typical taskbar | |
convert -depth 8 -gravity SouthEast -geometry +$((330-(i+1)*64))+20 "$tmpimage" "$tmpicon" -composite "$tmpimage" | |
done | |
fi | |
if [ "$TEMPERATURE" == "TRUE" ];then | |
local temperature=$(echo "$WEATHER_DATA" | jq -r '.currently.temperature') | |
# yql is only giving us fahrenheit values, so we have to convert it into a sane unit | |
convert -gravity "$TEMPERATURE_GRAVITY" "$tmpimage" -font DejaVu-Sans-Condensed -pointsize 36 -fill '#c0bfbd' -background '#0000' -annotate "$TEMPERATURE_MARGIN" "${temperature%.*}°C" "$tmpimage" | |
fi | |
addRadar "$tmpimage" | |
cp "$tmpimage" "$HOME"/.izulu/izulucurrent | |
rm "$tmpimage" | |
${WPCOMMAND/PLACEHOLDER/"$HOME/.izulu/izulucurrent"} & | |
osdNotify "$(echo "$WEATHER_DATA" | jq -r '.currently.summary')" | |
} | |
addRadar() { | |
local tmpimage="$1" | |
if [ "$SWISS_RADAR" == "TRUE" ];then | |
addSwissImage "$tmpimage" warning radar | |
return | |
fi | |
if [ "$GERMAN_RADAR" == "TRUE" ];then | |
addGermanImage "$tmpimage" | |
return | |
fi | |
if [ "$RADAR" == "TRUE" ];then | |
if contains "${RADAROPTIONS[*]}" "germany";then | |
local country="DE" | |
elif contains "${RADAROPTIONS[*]}" "swiss";then | |
local country="CH" | |
else | |
local country=$(getCountry) | |
fi | |
if ! contains "${RADAROPTIONS[*]}" "radar" && ! contains "${RADAROPTIONS[*]}" "warning";then | |
local options=("warning" "radar") | |
else | |
local options=() | |
for image in ${RADAROPTIONS[*]};do | |
if [ "$image" == "radar" ] || [ "$image" == "warning" ];then | |
options[${#options[*]}]="$image" | |
fi | |
done | |
fi | |
if [ "$country" == "DE" ];then | |
addGermanImage "$tmpimage" ${options[*]} | |
elif [ "$country" == "CH" ];then | |
addSwissImage "$tmpimage" ${options[*]} | |
fi | |
fi | |
} | |
addGermanImage() { | |
local i=0 | |
local tmpimage="$1" | |
local radarimage=$(mktemp) | |
wget -O - -q ftp://ftp.dfd.dlr.de/put/wetterbilder/Central_Europe/image1.jpg > "$radarimage" | |
#grab germany from the image of europe: | |
convert "$radarimage" -crop 650x900+274+120 "$radarimage" | |
convert "$radarimage" -resize 178 "$radarimage" | |
composite -gravity SouthEast -geometry +2+128 "$radarimage" "$tmpimage" "$tmpimage" | |
rm "$radarimage" | |
} | |
addSwissImage() { | |
local i=0 | |
local tmpimage="$1" | |
for image in $*;do | |
let i++ | |
if [ "$image" == "warning" ];then | |
local wetteralarm=$(mktemp) | |
wget -O - -q http://www.wetteralarm.ch/uploads/tx_namicswawetterkarte/bilder/wetterkarten/all_klein.jpg > "$wetteralarm" | |
convert "$wetteralarm" -resize 178 "$wetteralarm" | |
if [[ $i -eq 2 ]];then | |
composite -gravity SouthEast -geometry +2+128 "$wetteralarm" "$tmpimage" "$tmpimage" | |
else | |
composite -gravity SouthEast -geometry +2+245 "$wetteralarm" "$tmpimage" "$tmpimage" | |
fi | |
rm "$wetteralarm" | |
fi | |
done | |
} | |
contains() { | |
list=("$1") | |
element="$2" | |
if [ "$(echo ${list[*]} | grep "$element")" == "" ];then | |
return 1 | |
else | |
return 0 | |
fi | |
} | |
# send onscreen-notfication if weather changed | |
# $1: message, new weather-state | |
osdNotify() { | |
if [ "$OSD" == "TRUE" ];then | |
if [[ -z "$last_state" ]] || [ "$last_state" != "$1" ];then | |
if command -v notify-send > /dev/null;then | |
notify-send "izulu" "$(gettext "$1")" | |
else | |
echo "notify-send not installed, but osd via -o requested." \ | |
"Install libnotify-bin to use the osd." | |
fi | |
fi | |
last_state="$1" | |
fi | |
} | |
#choose randomly a wallpaper | |
#$1: wallpaper-category | |
#return: wallpaper to set | |
cycleWallpaper() { | |
local specific="$1" | |
local generic="$2" | |
local randomdir="" | |
case "$generic" in | |
"gen_sun") | |
randomdir="$RANDOMSUNDIR" | |
;; | |
"gen_cloud") | |
randomdir="$RANDOMCLOUDDIR" | |
;; | |
"gen_rain") | |
randomdir="$RANDOMRAINDIR" | |
;; | |
"gen_snow") | |
randomdir="$RANDOMSNOWDIR" | |
;; | |
*) | |
randomdir="$RANDOMMISCDIR" | |
;; | |
esac | |
if [[ -z "$randomdir" ]];then | |
flickrimg=$(getFlickrImage "$generic") | |
if [[ -z "$flickrimg" ]];then | |
setWallpaper "$specific" "$generic" "TRUE" | |
return 1 | |
else | |
echo "$flickrimg" | |
return 0 | |
fi | |
fi | |
# The IFS set to \n enables files with spaces | |
OLD_IFS=$IFS | |
IFS=$'\n' | |
# this gets all image files in randomdir and subdirs. The ${} around $randomdir is necessary to evaluate variables like ~ | |
pictures=($(echo -e "$(find ${randomdir} -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' | sed s"#.*\($randomdir.*\):.*#\1#"g | sort)")) | |
IFS=$OLD_IFS | |
chosen=$(shuf -i1-${#pictures[@]} -n1) | |
echo "${pictures[$chosen]}" | |
} | |
getFlickrImage() { | |
local generic="$1" | |
# flickriver sorts the flickr groups images randomly for us | |
local riverurl="" | |
case "$generic" in | |
"gen_sun") | |
riverurl="http://www.flickriver.com/groups/982364@N21/pool/random/" | |
;; | |
"gen_cloud") | |
riverurl="http://www.flickriver.com/groups/clouds-mildness/pool/random/" | |
;; | |
"gen_rain") | |
riverurl="http://www.flickriver.com/groups/387174@N22/pool/random/" | |
;; | |
"gen_snow") | |
riverurl="http://www.flickriver.com/groups/snow_pictures/pool/random/" | |
;; | |
"gen_wind") | |
riverurl="http://www.flickriver.com/groups/1159117@N24/pool/random/" | |
;; | |
*) | |
# misc, mainly fog | |
riverurl="http://www.flickriver.com/groups/fabulousfog/pool/random/" | |
;; | |
esac | |
local flickrpage=$(wget -O - --quiet $(wget -O - "$riverurl" --quiet | grep "class=\"noborder\" target=\"_blank\".*http://www.flickr.com/photos" | sed 's#.*href=\"\([^\"]*\)\".*#\1#g' | uniq | shuf -n 1)) | |
local imagesizes=$(echo -e "$flickrpage" | grep modelExport: | tr "}" "\n") | |
for size in "k" "o" "h" "l";do | |
# not all flickr images provide every size, so we try to get the best one | |
# It is nicer to prefer a size with a specific width, that is why Original is not first | |
local imageurl=$(echo -e "$imagesizes" | grep "\"$size\"" | sed -e 's#.*\(c[0-9].staticflickr.com.*\).*"#https://\1#g' -e 's#\\##g' -e 's#\".*##') | |
if [[ -n "$imageurl" ]];then | |
break | |
fi | |
done | |
if [[ -z "$imageurl" ]];then | |
return 1 | |
fi | |
if [[ -z "$FLICKRTMP" ]];then | |
FLICKRTMP=$(mktemp) | |
fi | |
if wget -O "$FLICKRTMP" "$imageurl" --quiet;then | |
echo "$FLICKRTMP" | |
else | |
return 1 | |
fi | |
} | |
# Return true if we know it is night, and user did ctivate the night mode | |
# This will only work well if the local time is in the same timezone as the detected place | |
isNight() { | |
current_time=$(date "+%s") | |
sunrise=$(echo "$WEATHER_DATA" | jq -r '.daily.data[0].sunriseTime') | |
sunset=$(echo "$WEATHER_DATA" | jq -r '.daily.data[0].sunsetTime') | |
return $(echo "(! $current_time < $sunrise || $current_time > $sunset)" | bc -l) | |
} | |
#determine the city via the geoip-api | |
getCity() { | |
ipApiLookup=$(wget -O - -q "http://freegeoip.net/xml/") | |
local city=$(echo "$ipApiLookup" | xml_grep --text_only '/Response/City') | |
if command -v notify-send >/dev/null;then | |
notify-send -u low "izulu" "$city" | |
fi | |
echo $city | |
} | |
#determine the country via the geoip-api | |
getCountry() { | |
ipApiLookup=$(wget -O - -q "http://freegeoip.net/xml/") | |
local country=$(echo "$ipApiLookup" | xml_grep --text_only '/Response/CountryCode') | |
echo $country | |
} | |
#check in which environment we run to select a command to set a wallpaper | |
getWPCommand() { | |
#partly taken from xdg-open | |
if [ x"$DESKTOP_SESSION" = x"ubuntu" ] || [ x"$DESKTOP_SESSION" = x"ubuntu-2d" ];then | |
gsettings set org.gnome.desktop.background picture-options "stretched" | |
echo "gsettings set org.gnome.desktop.background picture-uri file://PLACEHOLDER" | |
elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ] || [ x"$DESKTOP_SESSION" = x"gnome" ];then | |
if command -v gnome-about > /dev/null; then | |
echo "gconftool --type string -s /desktop/gnome/background/picture_filename PLACEHOLDER" | |
else | |
gsettings set org.gnome.desktop.background picture-options "stretched" | |
echo "gsettings set org.gnome.desktop.background picture-uri file://PLACEHOLDER" | |
fi | |
elif [ x"$XDG_CURRENT_DESKTOP" = x"MATE" ];then | |
gsettings set org.mate.background picture-options "stretched" | |
echo "gsettings set org.mate.background picture-filename PLACEHOLDER" | |
elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then | |
echo "xfdesktop --reload PLACEHOLDER" | |
elif [ x"$XDG_CURRENT_DESKTOP" = x"KDE" ];then | |
echo "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript 'var allDesktops = desktops();print (allDesktops);for (i=0;i<allDesktops.length;i++) {d = allDesktops[i];d.wallpaperPlugin = "org.kde.image";d.currentConfigGroup = Array(\"Wallpaper\", \"org.kde.image\", \"General\");d.writeConfig(\"Image\", \"file:///file://PLACEHOLDER\")}'" | |
elif command -v Esetroot > /dev/null; then | |
echo "Esetroot -scale PLACEHOLDER" | |
elif command -v feh > /dev/null; then | |
echo "feh --bg-scale --no-fehbg PLACEHOLDER" | |
elif command -v display > /dev/null; then | |
echo "display -window root PLACEHOLDER" | |
else | |
echo "gconftool --type string -s /desktop/gnome/background/picture_filename PLACEHOLDER" | |
fi | |
} | |
checkConfig() { | |
if [[ ! -d "$HOME/.izulu/" ]];then | |
mkdir "$HOME/.izulu/" | |
fi | |
if [[ ! -e "$HOME/.izulu/config" ]];then | |
echo "WPCOMMAND=\"\" #command to set the wallpaper | |
CITY=\"\" | |
LATITUDE=\"\" | |
LONGITUDE=\"\" | |
WIND=\"\" | |
SWISS_RADAR=\"\" | |
RANDOMSUNDIR=\"\" #Directories with pictures to randomly pick one | |
RANDOMCLOUDDIR=\"\" | |
RANDOMRAINDIR=\"\" | |
RANDOMSNOWDIR=\"\" | |
RANDOMMISCDIR=\"\"" > "$HOME/.izulu/config" | |
fi | |
} | |
readConfig() { | |
source "$HOME"/.izulu/config | |
} | |
# set default variables | |
TEMPERATURE_GRAVITY="SouthWest" | |
TEMPERATURE_MARGIN="+10+20" | |
checkConfig | |
readConfig | |
#read arguments | |
while [[ $# -gt 0 ]] ; do | |
parm="$1" | |
shift | |
case "$parm" in | |
-c | --city) | |
CITY="$1" | |
;; | |
-l | --latitude) | |
LATITUDE="${1%:*}" | |
LONGITUDE="${1#*:}" | |
;; | |
-d | --daemon) | |
DAEMON=TRUE | |
;; | |
-i | --interval) | |
INTERVAL="$1" | |
if [[ "$INTERVAL" -lt 900 ]];then | |
INTERVAL=900 | |
fi | |
;; | |
-r | --random) | |
RANDOMLY=TRUE | |
;; | |
-n | --night) | |
NIGHT=TRUE | |
;; | |
-o | --osd) | |
OSD=TRUE | |
;; | |
-p | --preview) | |
PREVIEW=TRUE | |
;; | |
-t | --temperature) | |
TEMPERATURE=TRUE | |
;; | |
-w | --wind) | |
WIND=TRUE | |
;; | |
-tg | --temperature-gravity) | |
TEMPERATURE_GRAVITY="$1" | |
;; | |
-tm | --temperature-margin) | |
TEMPERATURE_MARGIN="$1" | |
;; | |
-co | --compat) | |
if [[ "$1" -eq "unity" ]];then | |
TEMPERATURE_GRAVITY="NorthEast" | |
TEMPERATURE_MARGIN="+10+40" | |
fi | |
;; | |
-gr | --german-radar) | |
GERMAN_RADAR=TRUE | |
;; | |
-sr | --swiss-radar) | |
SWISS_RADAR=TRUE | |
;; | |
-rd | --radar) | |
RADAR=TRUE | |
RADAROPTIONS=() | |
for option in $*;do | |
if [ "${option:0:1}" == "-" ];then | |
#this option doesn't belongs to the radarswitch anymore | |
break | |
else | |
RADAROPTIONS[${#RADAROPTIONS[*]}]="$option" | |
shift | |
fi | |
done | |
;; | |
--help) | |
echo "-c city, --city city: | |
Set the city with the relevant weather, e.g Berlin. | |
-l LAT:LON, --latitude LAT:LON: | |
Give the current position as latitude and longitude | |
-d, -daemon: | |
Enable daemon-mode, check the weather every 15 minutes. | |
-gr, --german-radar | |
Shortcut: All german rader images. | |
-i interval, --interval interval: | |
Specify a custom check-interval when in daemon-mode, e.g. 900 (seconds, also the minimun). | |
-n, --night: | |
Set another wallpaper at night. | |
-o, --osd: | |
Send a notification when weather changes. | |
-p, --preview | |
Add images showing the weather forecast. | |
-r, --random: | |
Choose the wallpaper randomly. If no directory is named in the config, it will try to get a fitting image from flickr. | |
-rd [warning|radar] [warning|radar] [germany|swiss], --radar [warning|radar] [warning|radar] [germany|swiss]: | |
Show a warning and/or a radarimage for a country. Wetteralarm (www.wetteralarm.ch) and Rain-Radar (meteoschweiz.admin.ch) for Switzerland, official warnings (http://www.dwd.de/) and a satellite-image (http://www.dlr.de/) for Germany. | |
-sr, --swiss-radar | |
Shortcut: All swiss rader images. | |
-t, --temperature | |
Show the temperature. | |
-tg gravity, --temperature-gravity gravity | |
Set the gravity anchor of the temperature display. Possible choices are NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast. See also http://www.imagemagick.org/script/command-line-options.php#gravity | |
-tm margin, --temperature-margin margin | |
Set the margin the temperature display shall have from the screen borders. The format for margin is +x+y, for example '+10+30'. | |
-co desktop, --compat desktop | |
Set several default parameters for compatibility with the defaults of a specific desktop environment. The sole possible value for desktop so far is 'unity', and it will move the temparature display to the upper right corner." | |
exit 0 | |
;; | |
--version) | |
echo "izulu 1.1" | |
exit 0 | |
;; | |
esac | |
done | |
TEXTDOMAIN="izulu" | |
TEXTDOMAINDIR="/usr/share/locale/" | |
export TEXTDOMAIN | |
export TEXTDOMAINDIR | |
if [ "$WPCOMMAND" == "" ];then | |
WPCOMMAND="$(getWPCommand)" | |
fi | |
if [ "$CITY" == "" -a -z "$LATITUDE" ];then | |
CITY="$(getCity)" | |
if [ "$CITY" == "" ];then | |
echo "Error: Your location is not discoverable. Please specify a city with 'izulu -c cityname' or with 'izulu -l LAT:LON'." >&2 | |
exit 1 | |
fi | |
fi | |
fillWeatherData | |
chooseWallpaper "$(getWeather)" | |
#daemon-mode | |
daemon() { | |
while true;do | |
if [[ -z "$INTERVAL" ]];then | |
INTERVAL=3600 | |
fi | |
sleep $INTERVAL | |
fillWeatherData | |
chooseWallpaper "$(getWeather)" | |
done | |
} | |
if [ "$DAEMON" == "TRUE" ];then | |
daemon | |
fi | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment