Auto Blogging with Rake & Rails

I have a long running blog that I struggle to keep current. The blog centers on mountain bike racing scene here in Northern California, so the content needs to stay timely as there are races every weekend all year long. Unfortunately, I don’t have a lot of free time to devote to it. Long story short, I wanted to automatically create a post every Thursday morning to let people know what races were being held that weekend. You can see an example of what I wanted at NorCal MTB Racing blog.

The basic idea was to create a cron job that pulls a list of races (with a link for details) from my rails application’s database, plot the events on map, add some text and then post it to my blog on Blogger. Most of this is pretty standard rails stuff, but I did need some help for the map and posting.

For the maps, I used Google Static Maps. This allows you to embed a Google Maps image on your webpage just like a normal image. All you need to do it feed it the right parameters. For example, this HTML code:

<img
alt="NorCal MTB Race Event Map"
src="https://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318&markers=color:red%7Clabel:C%7C40.718217,-73.998284"
/>

Produces this map:

https://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318&markers=color:red%7Clabel:C%7C40.718217,-73.998284

NorCal MTB Map

To post to Blogger, I used the blogger gem (installation instructions). There are other ruby gems out there that interface with Blogger, but this was by far the most straight forward. To use the gem, you need username, password and blog ID. I found my blog ID through an answer in the blogger support forum:

Got to your dashboard and click Settings for the blog you want the ID of. In the address bar you should then see something like this: http://www.blogger.com/blog-options-basic.g?blogID=9101099271220909428 The long number at the end of the URL is your blog’s ID number.

I decided that this would be best implemented as a rake task, so I could full access to all the rails application environment (especially the database connection). Here is the complete rake task:

 1namespace :blogger do
 2  desc "post weekend update to blogger"
 3  task :weekend_update  => :environment do
 4    require 'blogger'
 5
 6    # preferences for blogger login
 7    username = 'sample@gmail.com' # change this to your username
 8    password = 'xxx129304xxxx' # change this to your password
 9    blog_id = '123456' # change this to your blogid
10
11    # my entry preferences
12    days_ahead = 5 # how many days of events ?
13    blog_entry = "For those of you making your weekend plans,
14                  here is quick rundown of this weekend\'s MTB racing schedule
15                  for NorCal:\n\n"
16
17    # google static map preferences
18    base_url = "http://maps.google.com/maps/api/staticmap?"
19    map_params = ["size=400x400", "maptype=roadmap", "sensor=false"]
20
21    # find all events in the mtbcalendar.com db for this weekend
22    @events = Event.active.find_tagged_with(
23        "norcal",
24        :conditions => ["start_date >= CURRENT_DATE AND start_date < ?",
25                        days_ahead.days.from_now],
26        :order => "start_date asc")
27
28    # loop through events adding place markers to the google static map URL
29    x = 0
30    @events.each do |marker|
31      x += 1
32      map_params << "markers=color:blue|label:#{x}|#{marker.lat},#{marker.lng}"
33      blog_entry += "#{x}. [#{marker.name}](http://mtbcalendar.com/events/#{marker.id})
34                    (#{marker.start_date.to_s(:compact)})\n"
35    end # marker loop
36
37    # add the google static map to post body
38    map_pic_url = base_url + map_params.join('&')
39    blog_entry += "\n![NorCal MTB Race Event Map](" + map_pic_url + ")"
40
41    # create title for the post
42    blog_title = "NorCal MTB Racing This Weekend:
43                  #{Date.today.to_s(:short)} -
44                  #{days_ahead.days.from_now.to_date.to_s(:short)},
45                  #{Date.today.year}"
46
47    # login into blogger and post this draft
48    account     = Blogger::Account.new(username,password)
49    new_post    = Blogger::Post.new(:title      => blog_title,
50                                    :content    => blog_entry,
51                                    :formatter  => :rdiscount,
52                                    :draft      => true)
53    account.post(blog_id,new_post)
54
55  end # task    
56end # namespace

Although I did this with a rake task, you could also make it just a regular ruby script. However, then you would need to handle all of the database login and queries yourself.


See also