diff --git a/bin/chbg b/bin/chbg index cf1e166..98f43d3 100755 --- a/bin/chbg +++ b/bin/chbg @@ -1,34 +1,137 @@ #!/bin/bash -# to change wallpapers both niri workspace and niri tab view -[ -z "$1" ] && { - echo "Usage: ${0##*/} " - exit 1 -} -fsize=$(magick identify -format "%w %h" -- "$1" 2>/dev/null) || { - echo "ERROR: unable to identify. is it an EXISTING ACCESSIBLE IMAGE file?" - exit 1 -} +set -euo pipefail +THIS_COMMAND=$(basename "$0") +IMG_MAGICK="magick" WP_DIR="${XDG_DATA_HOME:-$HOME/.local/share}" -finput=$1 -read -r fw fh <<< "$fsize" -(( fw > 3840 && fh > 2160 )) && { +usage() { + cat << EOF +Usage: $THIS_COMMAND [-d output_path] image1 image2 ... +Options: + -d, --dir OUTPUT_PATH Directory to store chosen image. (default: $WP_DIR) + -h, --help Show this help message and exit. +Notes: + - Images can be provided as arguments or via stdin. If both are used, they are combined. + - Web URLs are also supported (via 'curl' or 'wget' downloading). + - If multiple images are provided, one will be randomly picked each time the script is executed. +EOF + exit 1 +} + +# showing help shouldn't require any dependencies. +while [[ $# -gt 0 ]]; do + case "$1" in + -d|--dir) + if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi + WP_DIR="$2"; shift 2 ;; + -h|--help) + usage ;; + --) + shift; break ;; + -*) + echo "Unknown option: $1"; usage ;; + *) + break ;; + esac +done + +if ! command -v swww >/dev/null 2>&1; then + echo "!) 'swww' command not found. Unable to comply." >&2 + exit 2 +fi + +if command -v magick >/dev/null 2>&1; then + IMG_MAGICK="magick" +elif command -v convert >/dev/null 2>&1; then + IMG_MAGICK="convert" +else + echo "!) 'magick' or 'convert' command not found. Image processing unavailable." >&2 + exit 2 +fi + +set_wallpaper() { + fsize=$($IMG_MAGICK identify -format "%w %h" -- "$1" 2>/dev/null) || { + echo "Invalid image file." >&2 + exit 10 + } + finput=$1 + + read -r fw fh <<< "$fsize" + (( fw > 3840 && fh > 2160 )) && { finput=$(mktemp "${TMPDIR:-/tmp}/chbg.XXXXXXXX.webp") trap 'rm -f "$finput"' EXIT - echo "WARNING: image too large, resizing ..." + echo "-> image too large, resizing ..." # echo "DEBUG: resized image at $finput" - magick "$1" -resize "3840x2160^" \ - -quality 90 \ - -define webp:method=6 \ - -define webp:alpha-quality=100 "$finput" + $IMG_MAGICK "$1" -resize "3840x2160^" \ + -quality 90 \ + -define webp:method=6 \ + -define webp:alpha-quality=100 "$finput" + } + + echo -n "-> making blurred version of '${1##*/}' ... " + cp $finput $WP_DIR/.wallpaper + $IMG_MAGICK $WP_DIR/.wallpaper -filter Gaussian -blur 0x30 $WP_DIR/.wallpaper_blur + echo "Done." + + swww img $WP_DIR/.wallpaper + swww img $WP_DIR/.wallpaper_blur --namespace blur } -echo -n "making blurred version of ${1##*/} ... " -mkdir -p $WP_DIR -cp $finput $WP_DIR/.wallpaper -magick $WP_DIR/.wallpaper -filter Gaussian -blur 0x30 $WP_DIR/.wallpaper_blur -echo "Done." +imagepool=() +lastresult="" -swww img $WP_DIR/.wallpaper -swww img $WP_DIR/.wallpaper_blur --namespace blur +# Read from stdin if data is available +if [ ! -t 0 ]; then + while IFS= read -r line; do + imagepool+=("$line") + done +fi + +# Read from positional arguments +for arg in "$@"; do + imagepool+=("$arg") +done + +if [ ${#imagepool[@]} -eq 0 ]; then + echo "No images provided." >&2 + exit 1 +fi + +mkdir -p -- "$WP_DIR" "/tmp/$USER" + +if [ -f "/tmp/$USER/chbg.last-slide.log" ]; then + lastresult=$(cat "/tmp/$USER/chbg.last-slide.log") +fi + +# Select a random image from the pool and set it as wallpaper +while : ; do + randomimage="${imagepool[RANDOM % ${#imagepool[@]}]}" + if [[ "$randomimage" == "http://"* || "$randomimage" == "https://"* ]]; then + break + fi + + if [ "$randomimage" != "$lastresult" ] || [ ${#imagepool[@]} -eq 1 ]; then + echo "$randomimage" > "/tmp/$USER/chbg.last-slide.log" + break + fi +done + +echo "Selected: $randomimage" + +if [ -f "$randomimage" ]; then + set_wallpaper "$randomimage" + exit 0 +fi + +tmpfile=$(mktemp) +trap 'rm -f "$tmpfile"' EXIT +if command -v curl >/dev/null 2>&1; then + curl -sSL "$randomimage" -o "$tmpfile" +elif command -v wget >/dev/null 2>&1; then + wget -qO "$tmpfile" "$randomimage" +else + echo "!) Unable to fetch image without 'curl' or 'wget'." >&2 + exit 2 +fi +set_wallpaper "$tmpfile"