This is just a shell script to automate the process of downloading National Geographic Photo of the Day that works. The script saves the image of Photo of the Day in the same directory where the script itself resides.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash
# This script downloads National Geographic Photo of the Day
# Permission to copy, modify, and distribute is granted under GPLv3
# Last revised 23 Dec, 2018

# change directory to where the script resides.
BASEDIR=$(dirname $0)
cd $BASEDIR
#######################

echo "start connection..."

# get data
data=$(curl -s https://www.nationalgeographic.com/photography/photo-of-the-day/)
if [ -n "$data" ]
then
  # get img url
  imgurl=$(grep 'property="og:image"' <<< "$data")
  imgurl="$(cut -d"\"" -f4 <<< $imgurl)"

  # get image name from canonical link and date
  name=$(grep 'rel="canonical"' <<< "$data")
  name="$(cut -d"\"" -f4 <<< $name)"
  name="$(cut -d"/" -f8 <<< $name)"

  date=$(grep 'meta property="gsa_publish_date"' <<< "$data")
  date="$(cut -d"\"" -f4 <<< $date)"

  file="$date-$name.jpg"

  if [ -f "$file" ]
  then
    echo "file already exists"
  else
    echo "start downloading the image..."
    curl "$imgurl" > $file
    echo "image downloaded successfully and saved as $file"
  fi

else
  echo "connection failed"
fi

As this script is hard coded, please address your suggestions to improve it. Thanks 😉!

What’s more, we can use launchctl to run this script daily on Mac OSX. Just simply create a .plist file and save it under ~/Library/LaunchAgents/. For instance, com.frankindev.ngspider.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <!-- give a unique Label -->
  <key>Label</key>
  <string>com.frankindev.ngspider.plist</string>
  <!-- path to the script -->
  <key>ProgramArguments</key>
  <array>
    <string>~/Pictures/Wallpaper/ngspider.sh</string>
  </array>
  <!-- set the daily running time -->
  <key>StartCalendarInterval</key>
  <dict>
        <key>Minute</key>
        <integer>30</integer>
        <key>Hour</key>
        <integer>14</integer>
  </dict>
<!-- std output -->
<key>StandardOutPath</key>
<string>~/Pictures/Wallpaper/ngspider.log</string>
<!-- std err output -->
<key>StandardErrorPath</key>
<string>~/Pictures/Wallpaper/ngspider.err</string>
</dict>
</plist>

Then load this plist by running launchctl load -w com.frankindev.ngspider.plist. The -w flag will remove any invalid keys in your plist file.

Following is a list of useful commands with launchctl, details of launchctl usages can be found at Daemons and Services Programming Guide.

# load a task
$ launchctl load -w com.frankindev.ngspider.plist

# unload a task
$ launchctl unload -w com.frankindev.ngspider.plist

# start a task immediately
$ launchctl start com.frankindev.ngspider.plist

# stop a task
$ launchctl stop com.frankindev.ngspider.plist

If you need to midify the contents of your plist file, you should unload it first, then load it back.

In a similar manner, we can download Bing wallpapers using this script:

#!/bin/bash

# change directory to where the script resides.
BASEDIR=$(dirname $0)
cd $BASEDIR

bing="http://www.bing.com"

# the idx parameter determines where to start from. 0 is the current day,
xmlURL="http://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-WW"

# Valid options: "_1024x768" "_1280x720" "_1366x768" "_1920x1200" "_1920x1080"
picRes="_1920x1080"

# The file extension for the Bing pic
picExt=".jpg"

# the XML data retrieved from xmlURL, form the fully qualified
# URL for the pic of the day, and store it in $picURL
data=$(curl -s $xmlURL)

if [ -n "$data" ]
then
  picURL=$(cut -d '>' -f13 <<< "$data")
  picURL=$(cut -d '<' -f 1 <<< "$picURL")
  picURL=$bing$picURL$picRes$picExt

  date=$(cut -d '>' -f5 <<< "$data")
  date=$(cut -d '<' -f1 <<< "$date")

  name=$(cut -d '>' -f15 <<< "$data")
  name=$(cut -d '<' -f 1 <<< "$name")
  name=$(cut -d ',' -f 1 <<< "$name")
  
  file="$date - $name$picExt"

  if [ -f "$file" ]
  then
    echo "file already downloaded"
  else
    curl "$picURL" > "$file"
    echo "image saved as $file"
  fi

else
  echo "connection failed"
fi

exit