#!/bin/sh # waldl: search wallhaven.cc, pick wallpapers in remage, download them. # Based on https://github.com/pystardust/waldl # # waldl [-s SORT] [-n PAGES] [-r WxH] [-d DIR] [QUERY...] # # No query = ask with aurora-run (or on the terminal). The thumbnails open in remage's grid in result # order: mark with m (v = visual mark in the grid, M = invert), quit with q, the marked ones download # to DIR/QUERY and open in remage (`:` -> "Set as wallpaper" or `setwall -m` to use one). # WALLHAVEN_API_KEY (optional) is sent along, e.g. for your account's purity/blacklist settings. walldir="$HOME/pix/wallhaven" # downloads go to $walldir// max_pages=4 # 24 results per page sorting=relevance # date_added relevance random views favorites toplist hot atleast=1920x1080 # smallest resolution quality=large # thumbnail size: small large original usage() { sed -n '2,10s/^# \{0,1\}//p' "$0" exit "${1:-0}" } while getopts s:n:r:d:h opt; do case $opt in s) sorting=$OPTARG ;; n) max_pages=$OPTARG ;; r) atleast=$OPTARG ;; d) walldir=$OPTARG ;; h) usage ;; *) usage 1 >&2 ;; esac done shift $((OPTIND - 1)) # progress: stderr + one notification that is updated in place nid="" sh_info() { printf 'waldl: %s\n' "$1" >&2 nid=$(notify-send -a waldl -p ${nid:+-r "$nid"} "wallhaven" "$1" 2>/dev/null) [ -n "$2" ] && exit "$2" } for dep in remage curl jq; do command -v "$dep" >/dev/null 2>&1 || sh_info "$dep not found, install it" 1 done query="$*" if [ -z "$query" ]; then query=$(aurora-run -d -l 0 -p "search wallhaven: " &2 && read -r query fi [ -z "$query" ] && exit 1 tmp=$(mktemp -d "${TMPDIR:-/tmp}/waldl.XXXXXX") || exit 1 trap 'rm -rf "$tmp"' EXIT trap 'exit 1' INT TERM HUP mkdir "$tmp/thumbs" ##################### ## search results ## ##################### sh_info "searching \"$query\"..." page=1 while [ "$page" -le "$max_pages" ]; do curl -sfG "https://wallhaven.cc/api/v1/search" \ --data-urlencode "q=$query" \ -d "page=$page" -d "atleast=$atleast" -d "sorting=$sorting" \ ${WALLHAVEN_API_KEY:+-H "X-API-Key: $WALLHAVEN_API_KEY"} \ -o "$tmp/page$page.json" & page=$((page + 1)) done wait # id, resolution, thumbnail url, full url; pages in order, without the repeats random sorting gives page=1 while [ "$page" -le "$max_pages" ]; do [ -s "$tmp/page$page.json" ] && jq -r --arg q "$quality" '.data[]? | [.id, .resolution, .thumbs[$q], .path] | @tsv' "$tmp/page$page.json" page=$((page + 1)) done | awk -F '\t' '!seen[$1]++' > "$tmp/results" [ -s "$tmp/results" ] || sh_info "nothing found for \"$query\"" 1 ######################## ## pick in remage ## ######################## sh_info "caching $(wc -l < "$tmp/results") thumbnails..." # named ID_WxH.ext so remage's status bar shows the real resolution, not the thumbnail's while IFS="$(printf '\t')" read -r id res thumb full; do printf 'url = "%s"\noutput = "%s/thumbs/%s_%s.%s"\n' "$thumb" "$tmp" "$id" "$res" "${thumb##*.}" done < "$tmp/results" | curl -sfZ --parallel-max 16 -K - # -i keeps the result order, -p keeps these temp files out of the shared thumbnail cache marked=$(awk -F '\t' -v d="$tmp/thumbs" '{ n = split($3, u, "."); print d "/" $1 "_" $2 "." u[n] }' "$tmp/results" | while read -r f; do [ -f "$f" ] && printf '%s\n' "$f"; done | remage -i -t -p -o --class waldl) [ -z "$marked" ] && exit 0 ######################### ## download ## ######################### dest="$walldir/$query" mkdir -p "$dest" || sh_info "can't create $dest" 1 count=$(printf '%s\n' "$marked" | wc -l) sh_info "downloading $count wallpaper(s)..." printf '%s\n' "$marked" | while read -r f; do f=${f##*/} awk -F '\t' -v id="${f%%_*}" '$1 == id { printf "url = \"%s\"\nremote-name\n", $4 }' "$tmp/results" done | curl -sfZ --skip-existing --output-dir "$dest" -K - sh_info "$count wallpaper(s) in $dest" remage --sort mtime --reverse "$dest"