changelog shortlog tags changeset files revisions annotate raw

feedBlogger.rb

changeset 1: 9e6a63167a01
parent:d9ec3e87a178
author: Patrick Mueller <pmuellr@muellerware.org>
date: Tue Nov 06 12:07:20 2007 -0500 (2 years ago)
permissions: -rwxr-xr-x
description: added a comment at top
1#!/usr/bin/env ruby
2
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
7# the feed data.
8#-------------------------------------------------------------------------------
9
10require 'cgi'
11require 'net/http'
12require 'net/https'
13require 'rexml/document'
14
15#-------------------------------------------------------------------------------
16# POST something to a URL
17#-------------------------------------------------------------------------------
18def httpPostForm(url, formData)
19 elementArray = []
20 formData.each_pair { |k,v| elementArray << "#{CGI.escape(k)}=#{CGI.escape(v)}"}
21 formData = elementArray.join "&"
22
23 url = URI.parse(url)
24 http = Net::HTTP.new(url.host, url.port)
25
26 if (url.scheme == "https")
27 http.use_ssl = true
28 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
29 end
30
31 return http.post(url.path, formData)
32end
33
34#-------------------------------------------------------------------------------
35# Get Google ClientAuth key
36#-------------------------------------------------------------------------------
37def getGoogleClientAuth(email, password)
38 formData = {
39 "Email" => email,
40 "Passwd" => password,
41 "source" => "MuellerWare-feedBlogger-0",
42 "service" => "blogger"
43 }
44
45 response = httpPostForm("https://www.google.com/accounts/ClientLogin", formData)
46 unless ("200" == response.code)
47 puts "Error getting profile: #{response.code} #{response.message}"
48 exit
49 end
50
51 re = /.\nAuth=(.*)(\n|$)/m
52 match = re.match(response.body)
53
54 return nil unless match
55
56 return match[1]
57end
58
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
67 return match[1]
68end
69
70#-------------------------------------------------------------------------------
71# Post a blog entry
72#-------------------------------------------------------------------------------
73def postBlogEntry(postingURL, googleAuth, entry)
74 headers = {
75 "Authorization" => "GoogleLogin auth=#{googleAuth}",
76 "Content-Type" => "application/atom+xml"
77 }
78
79 url = URI.parse(postingURL)
80 http = Net::HTTP.new(url.host, url.port)
81
82 if (url.scheme == "https")
83 http.use_ssl = true
84 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
85 end
86
87 response = http.post(url.path, entry, headers)
88
89 return ["200","201"].include?(response.code)
90end
91
92##-------------------------------------------------------------------------------
93# main program
94#-------------------------------------------------------------------------------
95
96# check parameters
97if (ARGV.length < 4)
98 puts "Expecting [blogURL] [email] [password] [feedFile]"
99 puts
100 puts "Adds the entries in [feedFile] to the blog at [blogURL] with the specified"
101 puts "credentials. For blogger.com"
102 exit
103end
104
105# set parameters
106blogURL = ARGV[0]
107email = ARGV[1]
108password = ARGV[2]
109feedFile = ARGV[3]
110
111# sanity check parameters
112unless File.exist?(feedFile)
113 puts "File not found: #{feedFile}"
114 exit
115end
116
117# get the posting url of the blog
118postingURL = getPostingURL(blogURL)
119
120# read the feed file
121xml = REXML::Document.new(File.open(feedFile))
122
123# authenticate
124auth = getGoogleClientAuth(email, password)
125
126# process the entries
127xml.elements.each("//entry") do | entry |
128 title = entry.get_text("title")
129 puts "Processing: #{title}"
130
131 entry.add_namespace("http://www.w3.org/2005/Atom")
132 result = postBlogEntry(postingURL, auth, entry.to_s)
133 unless result
134 puts "Error posting blog entry"
135 end
136end
137