Skip to content

Instantly share code, notes, and snippets.

@ghiden
Created April 27, 2012 13:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ghiden/2509075 to your computer and use it in GitHub Desktop.
Save ghiden/2509075 to your computer and use it in GitHub Desktop.
Open Google Reader's Starred items in browser
#!/usr/bin/env python
import sys
import gdata.service
import subprocess
import getpass
import urllib
import re
import os
import ConfigParser
from optparse import OptionParser
from gdata.service import BadAuthentication
URL = '/reader/atom/user/-/state/com.google/starred'
SERVICE = gdata.service.GDataService(account_type='GOOGLE',
service='reader',
server='www.google.com',
source='MyReader')
CONFIG_FILE = os.path.expanduser('~/.gstar-reader')
CONFIG = {'email':'', 'password':''}
def unstar(entry, token):
i = entry.id.text
s = entry.source.extension_attributes['{http://www.google.com/schemas/reader/atom/}stream-id']
ret = SERVICE.Post(urllib.urlencode({
'i':i,
'r':'user/-/state/com.google/starred',
's':s,
'T':token
}),
'/reader/api/0/edit-tag',
converter = lambda x:x,
extra_headers = {'Content-Type':'application/x-www-form-urlencoded'})
print "Unstar result: %s [id: %s]" % (ret, i)
if ret == "OK":
return 1
else:
return 0
def get_continuation(feed):
pattern = re.compile(r"""ns2:continuation>(.*)<¥/ns2:continuation""", re.M)
result = pattern.search(feed.ToString())
if result:
return result.group(1)
else:
return False
def init_config():
if not os.path.exists(CONFIG_FILE):
print """Config file not found
Please create a file ‾/.gstar-reader with the following contents
[base]
email:name@example.com
password:password"""
sys.exit()
parser = ConfigParser.SafeConfigParser()
parser.read(CONFIG_FILE)
CONFIG['email'] = parser.get('base', 'email')
CONFIG['password'] = parser.get('base', 'password')
def prompt():
CONFIG['email'] = raw_input('Enter your email for Google Reader: ')
CONFIG['password'] = getpass.getpass('Enter your password for Google Reader: ')
def open_in_browser(url):
# open in Chrome
result = subprocess.call(["open", "-a", "Google Chrome", url])
if result != 0:
print "Error opening the item"
return result
def login():
try:
SERVICE.ClientLogin(CONFIG['email'], CONFIG['password'])
except BadAuthentication:
print "Wrong password!"
sys.exit()
# authenticated token
return SERVICE.Get('/reader/api/0/token',converter=lambda x:x)
# collect starred items
def starred():
# n = number of items to read per query, default is 20
params = {}
entries = []
while True:
query = gdata.service.Query(feed=URL, params=params)
feed = SERVICE.Get(query.ToUri())
cont = get_continuation(feed)
entries.extend(feed.entry)
if cont:
params['c'] = cont
else:
break
print '*' * len(entries)
return entries
# process starred items
def process_starred(token, entries, options):
total = len(entries)
cleared = 0
for entry in entries:
url = entry.GetHtmlLink().href
print entry.title.text
print url
if options.b != True:
result = open_in_browser(url)
else:
# -b is set, always return 0
result = 0
if options.s != True and result == 0:
# now unstar it
cleared += unstar(entry, token)
print "==============================================================="
return (total, cleared)
def main(options):
if options.p:
prompt()
else:
init_config()
token = login()
entries = starred()
(total, cleared) = process_starred(token, entries, options)
print "%d starred item(s) found and %d cleared" % (total, cleared)
if __name__ == '__main__':
parser = OptionParser()
parser.add_option("-s", action="store_true", default=False,
help="not to clear stars")
parser.add_option("-b", action="store_true", default=False,
help="not to open in browser")
parser.add_option("-p", action="store_true", default=False,
help="prompt email and password")
(options, args) = parser.parse_args()
main(options)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment