|
@@ -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 <<EOF
|
|
|
+Usage:
|
|
|
+ $SCRIPT [options]
|
|
|
+ $SCRIPT -h | --help
|
|
|
+ $SCRIPT --version
|
|
|
+
|
|
|
+Options:
|
|
|
+ enable-auto-update Enable automatic update of wallpapers every day
|
|
|
+ the picture if the filename already exists.
|
|
|
+ disable-auto-update Disable automatic update of wallpapers every day
|
|
|
+ the picture if the filename already exists.
|
|
|
+ info Show description of current wallpaper.
|
|
|
+ --auto-update-name <name> 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 <coutry-tag> 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 <number> Day for which you want to get the picture.
|
|
|
+ 0 is current day, 1 is yesterday etc.
|
|
|
+ Default is 0.
|
|
|
+ -n --filename <file name> The name of the downloaded picture. Defaults to
|
|
|
+ the upstream name.
|
|
|
+ -p --picturedir <picture dir> The full path to the picture download dir.
|
|
|
+ Will be created if it does not exist.
|
|
|
+ [default: $HOME/Pictures/bing-wallpapers/]
|
|
|
+ -r --resolution <resolution> The resolution of the image to retrieve.
|
|
|
+ Supported resolutions: ${RESOLUTIONS[*]}
|
|
|
+ --resolutions <resolutions> The resolutions of the image try to retrieve.
|
|
|
+ eg.: --resolutions "1920x1200 1920x1080 UHD"
|
|
|
+ -m --monitor <num> 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="<string>source ~/.bashrc && npx --yes bing-wallpaper-daily-mac-multimonitor@latest $REST_ARGS</string>"
|
|
|
+ else
|
|
|
+ local COMMANDS="<string>$SCRIPT_PATH $REST_ARGS</string>"
|
|
|
+ fi
|
|
|
+
|
|
|
+ cat > $PLIST_FILE <<- EOM
|
|
|
+<?xml version="1.0" encoding="UTF-8"?>
|
|
|
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
|
+<plist version="1.0">
|
|
|
+<dict>
|
|
|
+ <key>Label</key>
|
|
|
+ <string>com.bing-wallpaper-daily-mac-multimonitor.plist</string>
|
|
|
+ <key>OnDemand</key>
|
|
|
+ <true/>
|
|
|
+ <key>ProgramArguments</key>
|
|
|
+ <array>
|
|
|
+ <string>/bin/sh</string>
|
|
|
+ <string>-c</string>
|
|
|
+ $COMMANDS
|
|
|
+ </array>
|
|
|
+ <key>EnvironmentVariables</key>
|
|
|
+ <dict>
|
|
|
+ <key>PATH</key>
|
|
|
+ <string>/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
|
+ </dict>
|
|
|
+ <key>StandardErrorPath</key>
|
|
|
+ <string>/tmp/bing-wallpaper-daily-mac-multimonitor-plist.err</string>
|
|
|
+ <key>StandardOutPath</key>
|
|
|
+ <string>/tmp/bing-wallpaper-daily-mac-multimonitor-plist.out</string>
|
|
|
+ <key>StartInterval</key>
|
|
|
+ <integer>1800</integer>
|
|
|
+ <key>RunAtLoad</key>
|
|
|
+ <true/>
|
|
|
+</dict>
|
|
|
+</plist>
|
|
|
+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>")
|
|
|
+COPYRIGHT=$(echo "$COPYRIGHT" | sed -e "s/<copyright>//")
|
|
|
+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 "<urlBase>.*?</urlBase>") )
|
|
|
+FILEURL=$(echo "$FILEURL" | sed -e "s/<urlBase>//")
|
|
|
+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
|