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