While working on my newest project
http://iblog.deathbyescalator.com/blog_import I hit a bit of a problem while posting to blogger. I did complete the project. It now uploads to blogger and wordpress but the google calendar import does not work.
Back to the problem at hand.. I found a few sites that looked promising. So I installed the GData-0.0.4 gem with no luck.
So after looking at the gdata gem and the blogger api I build a quick script to post a blog entry to blogger.
Full script at
http://svn.stephenbeckeriv.com/code/gdata/blogger/
But the good parts: Auth
module Net
class HTTPS < HTTP
def initialize(address, port = nil)
super(address, port)
self.use_ssl = true
end
end
end
GOOGLE_LOGIN_URL = URI.parse('https://www.google.com/accounts/ClientLogin')
def get_gdata_headers(email,pass,service = 'blogger',source = 'gdata-ruby' ,url = 'www.blogger.com')
headers = {}
response = Net::HTTPS.post_form(GOOGLE_LOGIN_URL,
{'Email' => email,
'Passwd' => pass,
'source' => source,
'service' => service })
raise "Not Authorized" unless response.kind_of? Net::HTTPSuccess
headers['Content-Type'] = 'application/atom+xml'
headers['Authorization'] = "GoogleLogin auth=#{response.body.split(/=/).last}"
headers
end
I got the HTTPS class from the GData lib. I like the idea. This call does nothing but authenticate with the blogger service and produce the needed header hash for calls later. This same method can be used for all the google apis.
Posting to the right blog
def find_blog_by_url_from_xml(blog_url,xml)
xml_of_blogs = REXML::Document.new(xml)
blogs = xml_of_blogs.each_element("/*/entry"){|z| z}
urls = blogs.map{|e|
e.each_element("link"){|mr| mr}[0].attributes["href"]
}
index = urls.index(urls.select{|u| u.include?(blog_url)}.first)
blogs[index]
end
I have many blogs but want to post to just one of them. This method takes the body from a Http call i will show later. That call returns xml with all of the blog info. Links, author data, ids and other goodies. I do not think this is the best way to find the xml data I want. It is just one way that works.
Sending the post:
def post_xml_to_blog(base_url, headers, blog_url,post_array)
conn = Net::HTTP.new(base_url, 80)
list_of_blogs = conn.get("/feeds/default/blogs",headers)
blog_xml = find_blog_by_url_from_xml(blog_url,list_of_blogs.body)
blog_links = blog_xml.each_element("link"){|mr| mr}
post_url = blog_links.select{|e| e.attributes["href"] =~ BLOGGER_FEED_REGEX }.first.attributes["href"]
post_path = post_url.match(BLOGGER_FEED_REGEX).to_s
response = Array.new
post_array.each{|entry|
response << conn.post(post_path, build_atom_entry_xml(entry).to_s, headers)
}
response
end
Simple enough. I send in an array that has the hash of entries to create. I build these methods for my needs. These can be easily adapted and changed. Hopefully a fully supported GData lib will raise from some where and save me from my
one off scripts.