diff --git a/bin/.bin/bing-wallpaper.sh b/bin/.bin/bing-wallpaper.sh new file mode 100755 index 0000000..77c0b18 --- /dev/null +++ b/bin/.bin/bing-wallpaper.sh @@ -0,0 +1,352 @@ +#!/bin/sh +PATH=/usr/local/bin:/usr/local/sbin:~/bin:/usr/bin:/bin:/usr/sbin:/sbin + +readonly SCRIPT=$(basename "$0") +readonly VERSION='1.1.1' +RESOLUTIONS=(1920x1200 1920x1080 1024x768 1280x720 1366x768 UHD) +MONITOR="0" # 0 means all monitors +PLIST_FILE="$HOME/Library/LaunchAgents/com.bing-wallpaper-daily-mac-multimonitor" +AUTO_UPDATE_NAME="default" +ARGS=$@ + +usage() { +cat < Name of your auto update when enabling/disabling + Using custom name enables setting multiple automatic update configurations. + Eg. Set on monitor 1 todays wallpaper and on monitor 2 wallpaper from yesterday + -f --force Force download of picture. This will overwrite + the picture if the filename already exists. + -s --ssl Communicate with bing.com over SSL. + -q --quiet Do not display log messages. + -c --country Specify market country/region eg. en-US, cs-CZ + Pictures may be different for markets on some days. + See full list of countries on https://learn.microsoft.com/en-us/previous-versions/bing/search/dd251064(v=msdn.10) + -d --day Day for which you want to get the picture. + 0 is current day, 1 is yesterday etc. + Default is 0. + -n --filename The name of the downloaded picture. Defaults to + the upstream name. + -p --picturedir The full path to the picture download dir. + Will be created if it does not exist. + [default: $HOME/Pictures/bing-wallpapers/] + -r --resolution The resolution of the image to retrieve. + Supported resolutions: ${RESOLUTIONS[*]} + --resolutions The resolutions of the image try to retrieve. + eg.: --resolutions "1920x1200 1920x1080 UHD" + -m --monitor Set wallpaper only on certain monitor (1,2,3...) + --all-desktops-experimental Set wallpaper on all desktops + Fixing osascript bug when wallpaper is not set for Desktop 2. + Known issue: Minimized apps are removed from Dock. + If something goes wrong delete Library/Application Support/Dock/desktoppicture.db + and restart your Mac. + -h --help Show this screen. + --version Show version. +EOF +} + +create_plist_in_users_agents_folder() { + local SCRIPT_PATH=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/$(basename "${BASH_SOURCE:-$0}") + local REST_ARGS=$(echo "$ARGS" | sed -e "s/enable-auto-update//") + + if [ $RUN_USING_NPX ]; then + local COMMANDS="source ~/.bashrc && npx --yes bing-wallpaper-daily-mac-multimonitor@latest $REST_ARGS" + else + local COMMANDS="$SCRIPT_PATH $REST_ARGS" + fi + + cat > $PLIST_FILE <<- EOM + + + + + Label + com.bing-wallpaper-daily-mac-multimonitor.plist + OnDemand + + ProgramArguments + + /bin/sh + -c + $COMMANDS + + EnvironmentVariables + + PATH + /usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin + + StandardErrorPath + /tmp/bing-wallpaper-daily-mac-multimonitor-plist.err + StandardOutPath + /tmp/bing-wallpaper-daily-mac-multimonitor-plist.out + StartInterval + 1800 + RunAtLoad + + + +EOM + +launchctl unload -w $PLIST_FILE 2>/dev/null +launchctl load -w $PLIST_FILE +} + +remove_plist_in_users_agents_folder() { + launchctl unload -w "$PLIST_FILE" 2>/dev/null + rm "$PLIST_FILE" +} + +show_info_text() { + # Parse HPImageArchive API and acquire picture BASE URL +COPYRIGHT=$(cat "$PICTURE_DIR/info.xml" | \ + grep -Eo ".*<\/copyright>") +COPYRIGHT=$(echo "$COPYRIGHT" | sed -e "s///") +COPYRIGHT=$(echo "$COPYRIGHT" | sed -e "s/<\/copyright>//") +echo $COPYRIGHT +} + +print_message() { + if [ ! "$QUIET" ]; then + printf "%s\n" "$(date): ${1}" + fi +} + +download_image_curl () { + local RES=$1 + FILEURLWITHRES="${FILEURL}_${RES}.jpg" + echo $FILEURLWITHRES + FILENAME=${FILEURLWITHRES/\/th\?id=/} + FILENAME_LOCAL="${AUTO_UPDATE_NAME}-${FILENAME}" + FILEWHOLEURL="$PROTO://bing.com/$FILEURLWITHRES" + + if [ $FORCE ] || [ ! -f "$PICTURE_DIR/$FILENAME_LOCAL" ]; then + find $PICTURE_DIR -type f -iname $AUTO_UPDATE_NAME-\*.jpg -delete + print_message "Downloading: $FILENAME..." + curl --fail -Lo "$PICTURE_DIR/$FILENAME_LOCAL" "$FILEWHOLEURL" + curl --fail -Lo "$PICTURE_DIR/info.xml" "$BING_HP_IMAGE_ARCHIVE_URL" + if [ "$?" == "0" ]; then + FILEPATH="$PICTURE_DIR/$FILENAME_LOCAL" + return + fi + + FILEPATH="" + return + else + print_message "Skipping download: $FILENAME_LOCAL..." + FILEPATH="$PICTURE_DIR/$FILENAME_LOCAL" + DOWNLOAD_SKIPPED=true + return + fi +} + +set_wallpaper () { + local FILEPATH=$1 + local MONITOR=$2 + + if [ "$MONITOR" -ge 1 ] 2>/dev/null; then + print_message "Setting wallpaper for monitor: $MONITOR" + osascript - << EOF + set tlst to {} + tell application "System Events" + set tlst to a reference to every desktop + set picture of item $MONITOR of tlst to "$FILEPATH" + end tell +EOF + else + osascript -e 'tell application "System Events" to tell every desktop to set picture to "'$FILEPATH'"' + fi +} + +set_wallpaper_experimental () { + local db_file="Library/Application Support/Dock/desktoppicture.db" + local db_path="$HOME/$db_file" + + # Put the image path in the database + local sql="insert into data values(\"$FILEPATH\"); " + sqlite3 "$db_path" "$sql" + + # Get the index of the new entry + local sql="select max(rowid) from data;" + local new_entry=$(sqlite3 "$db_path" "$sql") + local new_entry=$(echo $new_entry|tr -d '\n') + + # Get all picture ids (monitor/space pairs) + local sql="select rowid from pictures;" + local pictures_string=$(sqlite3 "$db_path" "$sql") + + local IFS=$'\n' + local pictures=($pictures_string) + + # Clear all existing preferences + local sql="select max(rowid) from data; delete from preferences; " + + for pic in "${pictures[@]}" + do + if [ "$pic" ]; then + local sql+="insert into preferences (key, data_id, picture_id) " + local sql+="values(1, $new_entry, $pic); " + fi + done + + sqlite3 "$db_path" "$sql" + + killall "Dock" +} + +# Defaults +PICTURE_DIR="$HOME/Pictures/bing-wallpapers/" + +# Option parsing +while [[ $# -gt 0 ]]; do + key="$1" + + case $key in + enable-auto-update) + ENABLE_AUTOMATIC_UPDATE=true + ;; + disable-auto-update) + DISABLE_AUTOMATIC_UPDATE=true + ;; + info) + INFO=true + ;; + --auto-update-name) + AUTO_UPDATE_NAME="$2" + shift + ;; + -r|--resolution) + RESOLUTION="$2" + shift + ;; + -p|--picturedir) + PICTURE_DIR="$2" + shift + ;; + -c|--country) + COUNTRY="$2" + shift + ;; + -d|--day) + DAY="$2" + shift + ;; + -n|--filename) + FILENAME="$2" + shift + ;; + -m|--monitor) + MONITOR="$2" + shift + ;; + -f|--force) + FORCE=true + ;; + -s|--ssl) + SSL=true + ;; + -q|--quiet) + QUIET=true + ;; + -h|--help) + usage + exit 0 + ;; + --resolutions) + RESOLUTIONS="$2" + shift + ;; + --all-desktops-experimental) + EXPERIMENTAL=true + ;; + --version) + printf "%s\n" $VERSION + exit 0 + ;; + *) + (>&2 printf "Unknown parameter: %s\n" "$1") + usage + exit 1 + ;; + esac + shift +done + +# Set options +[ $QUIET ] && CURL_QUIET='-s' +[ $SSL ] && PROTO='https' || PROTO='http' +[ $DAY ] && IDX=$DAY || IDX='0' +BING_HP_IMAGE_ARCHIVE_URL="https://www.bing.com/HPImageArchive.aspx?format=xml&idx=${IDX}&n=1" +[ $COUNTRY ] && BING_HP_IMAGE_ARCHIVE_URL="${BING_HP_IMAGE_ARCHIVE_URL}&mkt=${COUNTRY}" +PLIST_FILE="${PLIST_FILE}-${AUTO_UPDATE_NAME}.plist" + +PARENT_COMMAND=$(ps -o comm= $PPID) +if [[ "$PARENT_COMMAND" == *"npm exec"* ]]; then + RUN_USING_NPX=true +fi + +if [ "$ENABLE_AUTOMATIC_UPDATE" ]; then +# enable update +create_plist_in_users_agents_folder +echo "Automatic wallpaper update enabled" +exit 1 +fi + +if [ "$DISABLE_AUTOMATIC_UPDATE" ]; then +# disable update +remove_plist_in_users_agents_folder +echo "Automatic wallpaper update disabled" +exit 1 +fi + +if [ "$INFO" ]; then +show_info_text +exit 1 +fi + +# Create picture directory if it doesn't already exist +mkdir -p "${PICTURE_DIR}" + +# Parse HPImageArchive API and acquire picture BASE URL +FILEURL=( $(curl -sL $BING_HP_IMAGE_ARCHIVE_URL | \ + grep -Eo ".*?") ) +FILEURL=$(echo "$FILEURL" | sed -e "s///") +FILEURL=$(echo "$FILEURL" | sed -e "s/<\/urlBase>//") + +if [ $RESOLUTION ]; then + download_image_curl $RESOLUTION + if [ "$FILEPATH" ]; then + if [ "$EXPERIMENTAL" ]; then + if [ ! "$DOWNLOAD_SKIPPED" ]; then + set_wallpaper_experimental $FILEPATH + fi + else + set_wallpaper $FILEPATH $MONITOR + fi + fi + exit 1 +fi + +for RESOLUTION in "${RESOLUTIONS[@]}" + do + download_image_curl $RESOLUTION + if [ "$FILEPATH" ]; then + if [ "$EXPERIMENTAL" ]; then + if [ ! "$DOWNLOAD_SKIPPED" ]; then + set_wallpaper_experimental $ + fi + else + set_wallpaper $FILEPATH $MONITOR + fi + exit 1 + fi + done