Info

Hi, I'm David Askew

I build things

Homepage

Contact Me

About

Open Source

Bing Pics

Problem

I like the Bing homepage pics. The picture changes every day and they are always amazing to look at. I wanted a way to download the images automatically so that I would not accidently miss one. After some quick internet searches, I found the following RSS feed. I could have just used a standard RSS reader and I do love Feedly, but where’s the challenge in that? I have been working to learn some ruby so I wrote a quick script to help me. Hopefully the folks at theironyard will be able to help me write more idiomatic and clean code when I join their codeschool next month. In the interim, the following solution outlined below should suffice.

Requirments

Note: If you are not using a Mac, you will need to comment out the terminal-notifier parts of the script for it to work.

Solution

 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/env ruby

require 'rss'
require 'open-uri'
require 'logger'
require 'logger/colors'      #gem install logger-colors
require 'terminal-notifier'  #gem install terminal-notifier

@log = Logger.new(STDOUT)

@log.level = Logger::DEBUG # DEBUG,INFO,WARN,ERROR,FATAL

env_vars = %w{BING_DIR}

not_defined = env_vars.find_all { |var| ENV[var] == nil }

unless not_defined.empty?
  @log.fatal "The following environment variables are missing and 
  should be defined: #{not_defined.join(', ')}"
  
  if (not_defined.include?('BING_DIR'))
    @log.info "BING_DIR should point to the directory used to store the images.  
    It must exist and be of the form '/directory/subdir/'"
  end
  exit 0
end


TerminalNotifier.notify("Bing: Refresh Started", 
  :activate => 'activate test', :title => "Bing Pic of the Day")

enclosures = []

downloads_dir = ENV["BING_DIR"] 
# should be set to something like "/Users/username/Pictures/"

if(!File.exists?(downloads_dir))
  @log.fatal "The folder specified in BING_DIR (#{ENV["BING_DIR"]}) does not exist! 
  Please create and rerun script."
  
  exit 0
end

@log.debug "RSS fetch and parse : START"

url = 'http://feeds.feedburner.com/bingimages'
open(url) do |rss|
  feed = RSS::Parser.parse(rss,do_validate=false)
  feed.items.each do |item|
    enclosures << item.enclosure.url
  end
end

@log.debug "RSS fetch and parse : END" 

new_pictures = false

enclosures.each do |file|
  fpart1 = file[0,file.index('%2f')+3]
  fname = file[file.index('%2f')+3,file.length]
  
  output_file = downloads_dir + fname
  
  if(!File.exists?(output_file))
  
    File.open(output_file, 'wb') do |fo|
      fo.write open(file).read
      @log.info "File Created : #{output_file}"
    end
    
    new_pictures = true
    
  else
    @log.info "File Exists : #{output_file}"
  end
end

if(new_pictures)
  TerminalNotifier.notify("Bing: New Pictures Available", 
  :activate => 'activate test', :title => "Bing Pic of the Day")
else
  TerminalNotifier.notify("Bing: No New Pictures", 
  :activate => 'activate test', :title => "Bing Pic of the Day")
end  

TerminalNotifier.notify("Bing: Refresh Complete", 
  :activate => 'activate test', :title => "Bing Pic of the Day")

If you are using rvm, you might execute the script like this from cron or another scheduler, remembering first to modify the example statements to fit your environment.

1
2
BING_DIR="/Users/username/pictures/bing_pics/" 
/Users/username/.rvm/wrappers/ruby-2.0.0-p451@bing/ruby /Users/username/code/bing_1.rb

You can get the most recent version from my github repository.

I hope this helps you.