123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- #!/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
|