auroradb36078
waldl: pick wallpapers in remage
+104 −147
1 file changed
- M .local/bin/waldl +104 −147
| @@ -1,159 +1,116 @@ | |||
| 1 | 1 | #!/bin/sh | |
| 2 | − | ||
| 3 | − | # https://github.com/pystardust/waldl | |
| 4 | − | # script to find and download wallpapers from wallhaven | |
| 5 | − | version="0.0.1" | |
| 6 | − | ||
| 7 | − | # Usage: | |
| 8 | − | # waldl <query> | |
| 9 | − | # if query left empty then sh_menu will be used (dmenu by default) | |
| 10 | − | # after the thumbnails are cached, nsxiv would open up with the thumbnails | |
| 11 | − | # Select the wallpapers using `m` on the image. ( marking the image in nsxiv ) | |
| 12 | − | # press `q` to quit nsxiv, the marked images would start downloading | |
| 13 | − | ||
| 14 | − | #################### | |
| 15 | − | ## User variables ## | |
| 16 | − | #################### | |
| 17 | − | ||
| 18 | − | # the dir where wallpapers are stored | |
| 19 | − | walldir="$HOME/pix/wallhaven" | |
| 20 | − | # the dir used to cache thumbnails | |
| 21 | − | cachedir="$HOME/.cache/wallhaven" | |
| 22 | − | # nsxiv options | |
| 23 | − | nsxiv_otps=" -tfpo -z 200" # o is needed for selection | |
| 24 | − | # number of pages to show in search results | |
| 25 | − | # each page contains 24 results | |
| 26 | − | max_pages=4 | |
| 27 | − | # sorting : date_added, relevance, random, views, favorites, toplist | |
| 28 | − | sorting=relevance | |
| 29 | − | # quality : large original small | |
| 30 | − | quality=large | |
| 31 | − | # atleast : least res | |
| 32 | − | atleast=1920x1080 | |
| 33 | − | ||
| 34 | − | # the menu command used when no query is provided | |
| 35 | − | sh_menu () { | |
| 36 | − | # : | dmenu -p "search wallhaven: " | |
| 37 | − | aurora-run --lines=0 --dmenu -p "search wallhaven: " | |
| 38 | − | # ROFI: comment the previous line and uncomment the next line for rofi | |
| 39 | − | # rofi -dmenu -l 0 -p "search wallpapers" | |
| 2 | + | # waldl: search wallhaven.cc, pick wallpapers in remage, download them. | |
| 3 | + | # Based on https://github.com/pystardust/waldl | |
| 4 | + | # | |
| 5 | + | # waldl [-s SORT] [-n PAGES] [-r WxH] [-d DIR] [QUERY...] | |
| 6 | + | # | |
| 7 | + | # No query = ask with aurora-run (or on the terminal). The thumbnails open in remage's grid in result | |
| 8 | + | # order: mark with m (v = visual mark in the grid, M = invert), quit with q, the marked ones download | |
| 9 | + | # to DIR/QUERY and open in remage (`:` -> "Set as wallpaper" or `setwall -m` to use one). | |
| 10 | + | # WALLHAVEN_API_KEY (optional) is sent along, e.g. for your account's purity/blacklist settings. | |
| 11 | + | ||
| 12 | + | walldir="$HOME/pix/wallhaven" # downloads go to $walldir/<query>/ | |
| 13 | + | max_pages=4 # 24 results per page | |
| 14 | + | sorting=relevance # date_added relevance random views favorites toplist hot | |
| 15 | + | atleast=1920x1080 # smallest resolution | |
| 16 | + | quality=large # thumbnail size: small large original | |
| 17 | + | ||
| 18 | + | usage() { | |
| 19 | + | sed -n '2,10s/^# \{0,1\}//p' "$0" | |
| 20 | + | exit "${1:-0}" | |
| 40 | 21 | } | |
| 41 | 22 | ||
| 42 | − | ########################## | |
| 43 | − | ## getting search query ## | |
| 44 | − | ########################## | |
| 45 | − | ||
| 46 | − | [ -n "$*" ] && query="$*" || query=$( sh_menu ) | |
| 47 | − | [ -z "$query" ] && exit 1 | |
| 48 | − | query=$(printf '%s' "$query" | tr ' ' '+' ) | |
| 49 | − | ||
| 50 | − | ###################### | |
| 51 | − | ## start up commands # | |
| 52 | − | ###################### | |
| 53 | − | ||
| 54 | − | rm -rf "$cachedir" | |
| 55 | − | mkdir -p "$walldir" "$cachedir" | |
| 56 | − | ||
| 57 | − | # progress display command | |
| 58 | − | sh_info () { | |
| 59 | − | printf "%s\n" "$1" >&2 | |
| 60 | − | notify-send "wallhaven" "$1" | |
| 23 | + | while getopts s:n:r:d:h opt; do | |
| 24 | + | case $opt in | |
| 25 | + | s) sorting=$OPTARG ;; | |
| 26 | + | n) max_pages=$OPTARG ;; | |
| 27 | + | r) atleast=$OPTARG ;; | |
| 28 | + | d) walldir=$OPTARG ;; | |
| 29 | + | h) usage ;; | |
| 30 | + | *) usage 1 >&2 ;; | |
| 31 | + | esac | |
| 32 | + | done | |
| 33 | + | shift $((OPTIND - 1)) | |
| 34 | + | ||
| 35 | + | # progress: stderr + one notification that is updated in place | |
| 36 | + | nid="" | |
| 37 | + | sh_info() { | |
| 38 | + | printf 'waldl: %s\n' "$1" >&2 | |
| 39 | + | nid=$(notify-send -a waldl -p ${nid:+-r "$nid"} "wallhaven" "$1" 2>/dev/null) | |
| 61 | 40 | [ -n "$2" ] && exit "$2" | |
| 62 | 41 | } | |
| 63 | 42 | ||
| 64 | − | # dependency checking | |
| 65 | − | dep_ck () { | |
| 66 | − | for pr; do | |
| 67 | − | command -v $pr >/dev/null 2>&1 || sh_info "command $pr not found, install: $pr" 1 | |
| 68 | − | done | |
| 69 | − | } | |
| 70 | − | dep_ck "nsxiv" "curl" "jq" | |
| 71 | − | ||
| 72 | − | ||
| 73 | − | # clean up command that would be called when the program exits | |
| 74 | − | clean_up () { | |
| 75 | − | printf "%s\n" "cleaning up..." >&2 | |
| 76 | − | rm -rf "$datafile" "$cachedir" | |
| 77 | − | } | |
| 43 | + | for dep in remage curl jq; do | |
| 44 | + | command -v "$dep" >/dev/null 2>&1 || sh_info "$dep not found, install it" 1 | |
| 45 | + | done | |
| 78 | 46 | ||
| 79 | − | # data file to store the api information | |
| 80 | − | datafile="/tmp/wald.$$" | |
| 81 | − | ||
| 82 | − | # clean up if killed | |
| 83 | − | trap "exit" INT TERM | |
| 84 | − | trap "clean_up" EXIT | |
| 85 | − | ||
| 86 | − | ################## | |
| 87 | − | ## getting data ## | |
| 88 | − | ################## | |
| 89 | − | ||
| 90 | − | # request the search results for each page | |
| 91 | − | get_results () { | |
| 92 | − | for page_no in $(seq $max_pages) | |
| 93 | − | do | |
| 94 | − | { | |
| 95 | − | json=$(curl -s -G "https://wallhaven.cc/api/v1/search" \ | |
| 96 | − | -d "q=$1" \ | |
| 97 | − | -d "page=$page_no" \ | |
| 98 | − | -d "atleast=$atleast" \ | |
| 99 | − | -d "sorting=$sorting" | |
| 100 | − | ) | |
| 101 | − | printf "%s\n" "$json" >> "$datafile" | |
| 102 | − | } & | |
| 103 | − | sleep 0.001 | |
| 104 | − | done | |
| 105 | − | wait | |
| 106 | − | } | |
| 107 | − | ||
| 108 | − | # search wallpapers | |
| 109 | − | sh_info "getting data..." | |
| 110 | − | get_results "$query" | |
| 111 | − | ||
| 112 | − | # check if data file is empty, if so then exit | |
| 113 | − | [ -s "$datafile" ] || sh_info "no images found" 1 | |
| 114 | − | ||
| 115 | − | ############################ | |
| 116 | − | ## downloading thumbnails ## | |
| 117 | − | ############################ | |
| 118 | − | ||
| 119 | − | # get a list of thumnails from the data | |
| 120 | − | thumbnails=$( jq -r '.data[]?|.thumbs.'"$quality" < "$datafile") | |
| 121 | − | ||
| 122 | − | [ -z "$thumbnails" ] && sh_info "no-results found" 1 | |
| 123 | − | ||
| 124 | − | # download the thumbnails | |
| 125 | − | sh_info "caching thumbnails..." | |
| 126 | − | for url in $thumbnails | |
| 127 | − | do | |
| 128 | − | printf "url = %s\n" "$url" | |
| 129 | − | printf "output = %s\n" "$cachedir/${url##*/}" | |
| 130 | − | done | curl -Z -K - | |
| 131 | − | #sh_info "downloaded thumbnails..." | |
| 132 | − | ||
| 133 | − | ########################### | |
| 134 | − | ## user selection (nsxiv) ## | |
| 135 | − | ########################### | |
| 47 | + | query="$*" | |
| 48 | + | if [ -z "$query" ]; then | |
| 49 | + | query=$(aurora-run -d -l 0 -p "search wallhaven: " </dev/null) | |
| 50 | + | # aurora not running: ask on the terminal instead | |
| 51 | + | [ $? -eq 2 ] && [ -t 0 ] && printf 'search wallhaven: ' >&2 && read -r query | |
| 52 | + | fi | |
| 53 | + | [ -z "$query" ] && exit 1 | |
| 136 | 54 | ||
| 137 | − | # extract the id's out of the thumbnail name | |
| 138 | − | image_ids="$(nsxiv $sxiv_otps "$cachedir")" | |
| 139 | − | [ -z "$image_ids" ] && exit | |
| 55 | + | tmp=$(mktemp -d "${TMPDIR:-/tmp}/waldl.XXXXXX") || exit 1 | |
| 56 | + | trap 'rm -rf "$tmp"' EXIT | |
| 57 | + | trap 'exit 1' INT TERM HUP | |
| 58 | + | mkdir "$tmp/thumbs" | |
| 59 | + | ||
| 60 | + | ##################### | |
| 61 | + | ## search results ## | |
| 62 | + | ##################### | |
| 63 | + | ||
| 64 | + | sh_info "searching \"$query\"..." | |
| 65 | + | page=1 | |
| 66 | + | while [ "$page" -le "$max_pages" ]; do | |
| 67 | + | curl -sfG "https://wallhaven.cc/api/v1/search" \ | |
| 68 | + | --data-urlencode "q=$query" \ | |
| 69 | + | -d "page=$page" -d "atleast=$atleast" -d "sorting=$sorting" \ | |
| 70 | + | ${WALLHAVEN_API_KEY:+-H "X-API-Key: $WALLHAVEN_API_KEY"} \ | |
| 71 | + | -o "$tmp/page$page.json" & | |
| 72 | + | page=$((page + 1)) | |
| 73 | + | done | |
| 74 | + | wait | |
| 75 | + | ||
| 76 | + | # id, resolution, thumbnail url, full url; pages in order, without the repeats random sorting gives | |
| 77 | + | page=1 | |
| 78 | + | while [ "$page" -le "$max_pages" ]; do | |
| 79 | + | [ -s "$tmp/page$page.json" ] && | |
| 80 | + | jq -r --arg q "$quality" '.data[]? | [.id, .resolution, .thumbs[$q], .path] | @tsv' "$tmp/page$page.json" | |
| 81 | + | page=$((page + 1)) | |
| 82 | + | done | awk -F '\t' '!seen[$1]++' > "$tmp/results" | |
| 83 | + | ||
| 84 | + | [ -s "$tmp/results" ] || sh_info "nothing found for \"$query\"" 1 | |
| 85 | + | ||
| 86 | + | ######################## | |
| 87 | + | ## pick in remage ## | |
| 88 | + | ######################## | |
| 89 | + | ||
| 90 | + | sh_info "caching $(wc -l < "$tmp/results") thumbnails..." | |
| 91 | + | # named ID_WxH.ext so remage's status bar shows the real resolution, not the thumbnail's | |
| 92 | + | while IFS="$(printf '\t')" read -r id res thumb full; do | |
| 93 | + | printf 'url = "%s"\noutput = "%s/thumbs/%s_%s.%s"\n' "$thumb" "$tmp" "$id" "$res" "${thumb##*.}" | |
| 94 | + | done < "$tmp/results" | curl -sfZ --parallel-max 16 -K - | |
| 95 | + | ||
| 96 | + | # -i keeps the result order, -p keeps these temp files out of the shared thumbnail cache | |
| 97 | + | marked=$(awk -F '\t' -v d="$tmp/thumbs" '{ n = split($3, u, "."); print d "/" $1 "_" $2 "." u[n] }' "$tmp/results" | | |
| 98 | + | while read -r f; do [ -f "$f" ] && printf '%s\n' "$f"; done | | |
| 99 | + | remage -i -t -p -o --class waldl) | |
| 100 | + | [ -z "$marked" ] && exit 0 | |
| 140 | 101 | ||
| 141 | 102 | ######################### | |
| 142 | − | ## download wallpapers ## | |
| 103 | + | ## download ## | |
| 143 | 104 | ######################### | |
| 144 | 105 | ||
| 145 | − | # download the selected wall papers | |
| 146 | − | mkdir "$walldir/$query" | |
| 147 | − | cd "$walldir/$query" | |
| 148 | − | sh_info "downloading wallpapers..." | |
| 149 | − | for ids in $image_ids | |
| 150 | − | do | |
| 151 | − | ids="${ids##*/}" | |
| 152 | − | ids="${ids%.*}" | |
| 153 | − | url=$( jq -r '.data[]?|select( .id == "'$ids'" )|.path' < "$datafile" ) | |
| 154 | − | printf "url = %s\n" "$url" | |
| 155 | − | printf -- "-O\n" | |
| 156 | − | done | curl -K - | |
| 157 | − | ||
| 158 | − | sh_info "wallpapers downloaded in:- '$walldir/$query'" | |
| 159 | − | nsxiv $(ls -c) | |
| 106 | + | dest="$walldir/$query" | |
| 107 | + | mkdir -p "$dest" || sh_info "can't create $dest" 1 | |
| 108 | + | count=$(printf '%s\n' "$marked" | wc -l) | |
| 109 | + | sh_info "downloading $count wallpaper(s)..." | |
| 110 | + | printf '%s\n' "$marked" | while read -r f; do | |
| 111 | + | f=${f##*/} | |
| 112 | + | awk -F '\t' -v id="${f%%_*}" '$1 == id { printf "url = \"%s\"\nremote-name\n", $4 }' "$tmp/results" | |
| 113 | + | done | curl -sfZ --skip-existing --output-dir "$dest" -K - | |
| 114 | + | ||
| 115 | + | sh_info "$count wallpaper(s) in $dest" | |
| 116 | + | remage --sort mtime --reverse "$dest" | |