diff options
Diffstat (limited to 'krebs/3modules/realwallpaper.nix')
-rw-r--r-- | krebs/3modules/realwallpaper.nix | 185 |
1 files changed, 184 insertions, 1 deletions
diff --git a/krebs/3modules/realwallpaper.nix b/krebs/3modules/realwallpaper.nix index 044811c7d..cb940efef 100644 --- a/krebs/3modules/realwallpaper.nix +++ b/krebs/3modules/realwallpaper.nix @@ -77,7 +77,190 @@ let serviceConfig = { Type = "simple"; - ExecStart = "${pkgs.realwallpaper}/realwallpaper.sh"; + ExecStart = pkgs.writeDash "generate-wallpaper" '' + set -xeuf + + # usage: getimg FILENAME URL + fetch() { + echo "fetch $1" + curl -LsS -z "$1" -o "$1" "$2" + } + + # usage: check_type FILENAME TYPE + check_type() { + if ! file -ib "$1" | grep -q "^$2/"; then + echo "$1 is not of type $2" >&2 + rm "$1" + return 1 + fi + } + + # usage: image_size FILENAME + image_size() { + identify "$1" | awk '{print$3}' + } + + # usage: make_mask DST SRC MASK + make_layer() { + if needs_rebuild "$@"; then + echo "make $1 (apply mask)" >&2 + convert "$2" "$3" -alpha off -compose copy_opacity -composite "$1" + fi + } + + # usage: flatten DST HILAYER LOLAYER + flatten() { + if needs_rebuild "$@"; then + echo "make $1 (flatten)" >&2 + composite "$2" "$3" "$1" + fi + } + + # usage: needs_rebuild DST SRC... + needs_rebuild() { + a="$1" + shift + if ! test -e "$a"; then + #echo " $a does not exist" >&2 + result=0 + else + result=1 + for b; do + if test "$b" -nt "$a"; then + #echo " $b is newer than $a" >&2 + result=0 + fi + done + fi + #case $result in + # 0) echo "$a needs rebuild" >&2;; + #esac + return $result + } + + main() { + cd ${cfg.workingDir} + + # fetch source images in parallel + fetch nightmap-raw.jpg \ + ${cfg.nightmap} & + fetch daymap-raw.png \ + ${cfg.daymap} & + fetch clouds-raw.jpg \ + ${cfg.cloudmap} & + fetch marker.json \ + ${cfg.marker} & + wait + + check_type nightmap-raw.jpg image + check_type daymap-raw.png image + check_type clouds-raw.jpg image + + in_size=2048x1024 + xplanet_out_size=1466x1200 + out_geometry=1366x768+100+160 + + nightsnow_color='#0c1a49' # nightmap + + for raw in \ + nightmap-raw.jpg \ + daymap-raw.png \ + clouds-raw.jpg \ + ; + do + normal=''${raw%-raw.*}.png + if needs_rebuild $normal $raw; then + echo "make $normal; normalize $raw" >&2 + convert $raw -scale $in_size $normal + fi + done + + # create nightmap-fullsnow + if needs_rebuild nightmap-fullsnow.png; then + convert -size $in_size xc:$nightsnow_color nightmap-fullsnow.png + fi + + # extract daymap-snowmask from daymap-final + if needs_rebuild daymap-snowmask.png daymap.png; then + convert daymap.png -threshold 95% daymap-snowmask.png + fi + + # extract nightmap-lightmask from nightmap + if needs_rebuild nightmap-lightmask.png nightmap.png; then + convert nightmap.png -threshold 25% nightmap-lightmask.png + fi + + # create layers + make_layer nightmap-snowlayer.png nightmap-fullsnow.png daymap-snowmask.png + make_layer nightmap-lightlayer.png nightmap.png nightmap-lightmask.png + + # apply layers + flatten nightmap-lightsnowlayer.png \ + nightmap-lightlayer.png \ + nightmap-snowlayer.png + + flatten nightmap-final.png \ + nightmap-lightsnowlayer.png \ + nightmap.png + + # create marker file from json + if [ -s marker.json ]; then + jq -r 'to_entries[] | @json "\(.value.latitude) \(.value.longitude)"' marker.json > marker_file + fi + + # make all unmodified files as final + for normal in \ + daymap.png \ + clouds.png \ + ; + do + final=''${normal%.png}-final.png + needs_rebuild $final && + ln $normal $final + done + + # rebuild every time to update shadow + xplanet --num_times 1 --geometry $xplanet_out_size \ + --output xplanet-output.png --projection merc \ + -config ${pkgs.writeText "xplanet.config" '' + [earth] + "Earth" + map=daymap-final.png + night_map=nightmap-final.png + cloud_map=clouds-final.png + cloud_threshold=10 + shade=15 + ''} + + xplanet --num_times 1 --geometry $xplanet_out_size \ + --output xplanet-krebs-output.png --projection merc \ + -config ${pkgs.writeText "xplanet-krebs.config" '' + [earth] + "Earth" + map=daymap-final.png + night_map=nightmap-final.png + cloud_map=clouds-final.png + cloud_threshold=10 + marker_file=marker_file + shade=15 + ''} + + # trim xplanet output + if needs_rebuild realwallpaper.png xplanet-output.png; then + convert xplanet-output.png -crop $out_geometry \ + realwallpaper-tmp.png + mv realwallpaper-tmp.png realwallpaper.png + fi + + if needs_rebuild realwallpaper-krebs.png xplanet-krebs-output.png; then + convert xplanet-krebs-output.png -crop $out_geometry \ + realwallpaper-krebs-tmp.png + mv realwallpaper-krebs-tmp.png realwallpaper-krebs.png + fi + } + + main "$@" + ''; User = "realwallpaper"; }; }; |