#!/opt/csw/bin/python # google-reader-opml v1.2 - Back up Google Reader OPML # Copyright (c) 2006, John Morrissey # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. # This script is a bit of a hack; we more or less imitate a web browser and # scrape the result. It would be nice if Google Reader OPML could be # downloaded through some Google Reader API. GOOGLE_USERNAME = None GOOGLE_PASSWORD = None OPML_OUTPUT = None from getopt import gnu_getopt, GetoptError from os import stat from os.path import basename from sys import argv, exit from time import gmtime, strftime from urllib import urlencode import urllib2 from urllib2 import HTTPError, Request GOOGLE_AUTH_URL = "https://www.google.com/accounts/ServiceLoginAuth" GOOGLE_READER_OPML_URL = "https://www.google.com/reader/subscriptions/export" def usage(): print "google-reader-opml v1.2" print "Usage: " + basename(argv[0]) + " [OPTION] OUTPUT-FILE" print "" print " -h, --help display this help and exit" print " -u USER, --user=USER log in as USER" print " -p PASSWORD, --user=PASSWORD use password PASSWORD" exit(2) try: options = gnu_getopt(argv[1:], "hu:p:", ["help=", "user=", "password="]) except GetoptError, e: print basename(argv[0]) + ": " + str(e) usage() if len(options[1]) != 1: usage() OPML_OUTPUT = options[1][0] for option in options[0]: if option[0] == '-h' or option[0] == '--help': usage() elif option[0] == '-u' or option[0] == '--user': GOOGLE_USERNAME = option[1] elif option[0] == '-p' or option[0] == '--password': GOOGLE_PASSWORD = option[1] if GOOGLE_USERNAME == None or GOOGLE_PASSWORD == None or OPML_OUTPUT == None: usage() class GetLoginCookies(urllib2.HTTPRedirectHandler): def http_error_302(self, req, fp, code, msg, headers): # We don't need to follow this redirect; we just need its # cookies so we can include them in the request for the OPML. req.cookies = headers["Set-Cookie"] return req auth = Request(GOOGLE_AUTH_URL, urlencode((("Email", GOOGLE_USERNAME), ("Passwd", GOOGLE_PASSWORD))) ) auth.add_header("User-Agent", "google-reader-opml 1.2") opener = urllib2.build_opener(GetLoginCookies) opener.open(auth) opml = Request(GOOGLE_READER_OPML_URL) opml.add_header("Cookie", auth.cookies) lastmod = 0 try: lastmod = stat(OPML_OUTPUT)[-3] except OSError, e: pass # Google Reader doesn't seem to support If-Modified-Since yet, but we'll use # it to be nice. opml.add_header("If-Modified-Since", strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime(lastmod))) try: data = opener.open(opml) except HTTPError, e: if e.code == 304: exit() else: print "Couldn't fetch Google Reader OPML for " + GOOGLE_USERNAME + ": " + str(e) exit() out = open(OPML_OUTPUT, "w") out.writelines(data) out.close()