3#-------------------------------------------------------------------------------
4# A script to load up a blogger blog with entries from a feed on disk.
5# Basically allows you to move a feed to Blogger, if you have the complete
6# feed as an existing atom feed. Doesn't handle comments or anything, just
8#-------------------------------------------------------------------------------
13require 'rexml/document'
15#-------------------------------------------------------------------------------
16# POST something to a URL
17#-------------------------------------------------------------------------------
18def httpPostForm(url, formData)
20 formData.each_pair { |k,v| elementArray << "#{CGI.escape(k)}=#{CGI.escape(v)}"}
21 formData = elementArray.join "&"
24 http = Net::HTTP.new(url.host, url.port)
26 if (url.scheme == "https")
28 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
31 return http.post(url.path, formData)
34#-------------------------------------------------------------------------------
35# Get Google ClientAuth key
36#-------------------------------------------------------------------------------
37def getGoogleClientAuth(email, password)
41 "source" => "MuellerWare-feedBlogger-0",
42 "service" => "blogger"
45 response = httpPostForm("https://www.google.com/accounts/ClientLogin", formData)
46 unless ("200" == response.code)
47 puts "Error getting profile: #{response.code} #{response.message}"
51 re = /.\nAuth=(.*)(\n|$)/m
52 match = re.match(response.body)
54 return nil unless match
59#-------------------------------------------------------------------------------
60# Get the URL to post blog entries to
61#-------------------------------------------------------------------------------
62def getPostingURL(blogURL)
63 html = Net::HTTP.get(URI.parse(blogURL))
64 pattern = /<link.*?rel="service.post".*?href="(.*?)"/m
65 match = pattern.match(html)
66 return nil unless match
70#-------------------------------------------------------------------------------
72#-------------------------------------------------------------------------------
73def postBlogEntry(postingURL, googleAuth, entry)
75 "Authorization" => "GoogleLogin auth=#{googleAuth}",
76 "Content-Type" => "application/atom+xml"
79 url = URI.parse(postingURL)
80 http = Net::HTTP.new(url.host, url.port)
82 if (url.scheme == "https")
84 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
87 response = http.post(url.path, entry, headers)
89 return ["200","201"].include?(response.code)
92##-------------------------------------------------------------------------------
94#-------------------------------------------------------------------------------
98 puts "Expecting [blogURL] [email] [password] [feedFile]"
100 puts "Adds the entries in [feedFile] to the blog at [blogURL] with the specified"
101 puts "credentials. For blogger.com"
111# sanity check parameters
112unless File.exist?(feedFile)
113 puts "File not found: #{feedFile}"
117# get the posting url of the blog
118postingURL = getPostingURL(blogURL)
121xml = REXML::Document.new(File.open(feedFile))
124auth = getGoogleClientAuth(email, password)
127xml.elements.each("//entry") do | entry |
128 title = entry.get_text("title")
129 puts "Processing: #{title}"
131 entry.add_namespace("http://www.w3.org/2005/Atom")
132 result = postBlogEntry(postingURL, auth, entry.to_s)
134 puts "Error posting blog entry"