From: Moritz Venn Date: Tue, 8 Sep 2009 12:24:40 +0000 (+0000) Subject: allow to fetch feeds from google reader X-Git-Url: http://code.vuplus.com/gitweb/?a=commitdiff_plain;h=d8afa71e2b260f14254f25ac95500d19d68ee912;p=vuplus_dvbapp-plugin allow to fetch feeds from google reader this is more of a proof of concept since you cannot really sync the feeds or edit them but having them is good enough for now :-) --- diff --git a/simplerss/src/GoogleReader.py b/simplerss/src/GoogleReader.py new file mode 100644 index 0000000..a4ee660 --- /dev/null +++ b/simplerss/src/GoogleReader.py @@ -0,0 +1,106 @@ +import urllib +from twisted.web.client import getPage +from RSSFeed import UniversalFeed +from twisted.internet.defer import Deferred +from xml.etree.cElementTree import fromstring as cet_fromstring + +class GoogleReader: + def __init__(self, username = None, password = None): + self.username = username + self.password = password + self.token = None + self.sid = None + + def sendRequest(self, url): + print "[GoogleReader] sendRequest:", url + cookies = { + 'Name': 'SID', + 'SID': self.sid, + 'Domain': '.google.com', + 'Path': '/', + 'Expires': '160000000000' + } + + return getPage(url, cookies = cookies) + + def login(self): + print "[GoogleReader] login" + if not self.username or not self.password: + return + + headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'} + data = { + 'service': 'reader', + 'Email': self.username, + 'Passwd': self.password, + 'source': 'enigma2-plugin-extensions-simplerss', + 'continue': 'http://www.google.com/', + } + + defer = Deferred() + getPage('https://www.google.com/accounts/ClientLogin', method = 'POST', headers = headers, postdata = urllib.urlencode(data)).addCallback(self.loginFinished, defer).addErrback(self.loginFailed, defer) + return defer + + def loginFinished(self, res = None, defer = None): + print "[GoogleReader] loginFinished:", res + pos_beg = res.find('SID=') + pos_end = res.find('\n',pos_beg) + self.sid = res[pos_beg+4:pos_end] + if defer: + defer.callback(self.sid) + + def loginFailed(self, res = None, defer = None): + print "[GoogleReader] loginFailed:", res + if defer: + # XXX: we might want to give some information here besides "we failed" + defer.errback() + + def getToken(self): + print "[GoogleReader] getToken" + if not self.sid: + return + + defer = Deferred() + self.sendRequest('http://www.google.com/reader/api/0/token').addCallback(self.gotToken, defer).addErrback(seld.errToken, defer) + return defer + + def gotToken(self, res = None, defer = None): + print "[GoogleReader] gotToken", res + self.token = res + if defer: + defer.callback(res) + + def errToken(self, res = None, defer = None): + print "[GoogleReader] errToken", res + self.token = None + if defer: + # XXX: we might want to give some information here besides "we failed" + defer.errback() + + def getSubscriptionList(self): + print "[GoogleReader] getSubscriptionList" + if not self.sid: + return + + defer = Deferred() + self.sendRequest('http://www.google.com/reader/api/0/subscription/list').addCallback(self.gotSubscriptionList, defer).addErrback(self.errSubscriptionList, defer) + return defer + + def gotSubscriptionList(self, res = None, defer = None): + print "[GoogleReader] gotSubscriptionList", res + l = [] + if res: + dom = cet_fromstring(res) + for item in dom.getiterator(): + if item.tag == 'string': + if item.get('name') == 'id': + l.append(UniversalFeed(item.text[5:], True, True)) + if defer: + defer.callback(l) + + def errSubscriptionList(self, res = None, defer = None): + print "[GoogleReader] errSubscriptionList", res + if defer: + # XXX: we might want to give some information here besides "we failed" + defer.errback() + diff --git a/simplerss/src/RSSFeed.py b/simplerss/src/RSSFeed.py index 4ccd55d..77587c0 100644 --- a/simplerss/src/RSSFeed.py +++ b/simplerss/src/RSSFeed.py @@ -132,11 +132,14 @@ class BaseFeed: class UniversalFeed(BaseFeed): """Feed which can handle rdf, rss and atom feeds utilizing abstraction wrappers.""" - def __init__(self, uri, autoupdate): + def __init__(self, uri, autoupdate, sync = False): BaseFeed.__init__(self, uri) # Set Autoupdate self.autoupdate = autoupdate + + # Is this a synced feed? + self.sync = sync # Initialize self.last_update = None diff --git a/simplerss/src/RSSPoller.py b/simplerss/src/RSSPoller.py index e50f142..d51d2f9 100644 --- a/simplerss/src/RSSPoller.py +++ b/simplerss/src/RSSPoller.py @@ -4,11 +4,16 @@ from . import _ from Components.config import config from enigma import eTimer +from Tools.Notifications import AddPopup +from Screens.MessageBox import MessageBox + from RSSFeed import BaseFeed, UniversalFeed from twisted.web.client import getPage from xml.etree.cElementTree import fromstring as cElementTree_fromstring +from GoogleReader import GoogleReader + NOTIFICATIONID = 'SimpleRSSUpdateNotification' update_callbacks = [] @@ -20,8 +25,7 @@ class RSSPoller: # Timer self.poll_timer = eTimer() self.poll_timer.callback.append(self.poll) - if poll: - self.poll_timer.start(0, 1) + self.do_poll = poll # Save Session, Initialize Var to identify triggered Reload self.session = session @@ -42,9 +46,48 @@ class RSSPoller: for x in config.plugins.simpleRSS.feed ] + if not config.plugins.simpleRSS.enable_google_reader.value: + if poll: + self.poll_timer.start(0, 1) + else: + self.googleReader = GoogleReader(config.plugins.simpleRSS.google_username.value, config.plugins.simpleRSS.google_password.value) + self.googleReader.login().addCallback(self.googleLoggedIn).addErrback(self.googleLoginFailed) + # Initialize Vars self.current_feed = 0 + def googleLoggedIn(self, sid = None): + self.googleReader.getSubscriptionList().addCallback(self.googleSubscriptionList).addErrback(self.googleSubscriptionFailed) + + def googleLoginFailed(self, res = None): + AddPopup( + _("Failed to login to GoogleReader."), + MessageBox.TYPE_ERROR, + 5, + ) + + self.reloading = False + if self.do_poll: + self.poll_timer.start(0, 1) + + def googleSubscriptionList(self, subscriptions = None): + self.feeds.extend(subscriptions) + + self.reloading = False + if self.do_poll: + self.poll_timer.start(0, 1) + + def googleSubscriptionFailed(self, res = None): + AddPopup( + _("Failed to get subscriptions from GoogleReader."), + MessageBox.TYPE_ERROR, + 5, + ) + + self.reloading = False + if self.do_poll: + self.poll_timer.start(0, 1) + def addCallback(self, callback): if callback not in update_callbacks: update_callbacks.append(callback) @@ -144,9 +187,6 @@ class RSSPoller: newItems = True ) elif update_notification_value == "notification": - from Tools.Notifications import AddPopup - from Screens.MessageBox import MessageBox - AddPopup( _("Received %d new news item(s).") % (len(self.newItemFeed.history)), MessageBox.TYPE_INFO, @@ -224,5 +264,9 @@ class RSSPoller: self.feeds = newfeeds - self.reloading = False + if config.plugins.simpleRSS.enable_google_reader.value: + self.googleReader = GoogleReader(config.plugins.simpleRSS.google_username.value, config.plugins.simpleRSS.google_password.value) + self.googleReader.login().addCallback(self.googleLoggedIn).addErrback(self.googleLoginFailed) + else: + self.reloading = False diff --git a/simplerss/src/RSSSetup.py b/simplerss/src/RSSSetup.py index b07dcb3..df32603 100644 --- a/simplerss/src/RSSSetup.py +++ b/simplerss/src/RSSSetup.py @@ -68,34 +68,14 @@ class RSSSetup(ConfigListScreen, Screen): def __init__(self, session, rssPoller = None): Screen.__init__(self, session) - self.rssPoller = rssPoller - simpleRSS = config.plugins.simpleRSS - - # Create List of all Feeds - list = [ - getConfigListEntry(_("Feed"), x.uri) - for x in simpleRSS.feed - ] - - # Attach notifier to autostart and append ConfigListEntry to List - simpleRSS.autostart.addNotifier(self.autostartChanged, initial_call = False) - list.append(getConfigListEntry(_("Start automatically with Enigma2"), simpleRSS.autostart)) - - # Save keep_running in instance as we want to dynamically add/remove it - self.keep_running = getConfigListEntry(_("Keep running in background"), simpleRSS.keep_running) - if not simpleRSS.autostart.value: - list.append(self.keep_running) - # Append Last two config Elements - list.extend(( - getConfigListEntry(_("Show new Messages as"), simpleRSS.update_notification), - getConfigListEntry(_("Update Interval (min)"), simpleRSS.interval) - )) + self.createSetup() + config.plugins.simpleRSS.autostart.addNotifier(self.elementChanged, initial_call = False) + config.plugins.simpleRSS.enable_google_reader.addNotifier(self.elementChanged, initial_call = False) # Initialize ConfigListScreen - self.list = list - ConfigListScreen.__init__(self, list, session) + ConfigListScreen.__init__(self, self.list, session) self["key_red"] = Button(_("Cancel")) self["key_green"] = Button(_("OK")) @@ -117,15 +97,39 @@ class RSSSetup(ConfigListScreen, Screen): def setCustomTitle(self): self.setTitle(_("Simple RSS Reader Setup")) - def autostartChanged(self, instance): - # Remove keep_running from list if autostart is active - if instance.value: - self.list.remove(self.keep_running) - # Otherwise add it at third position from behind - else: - self.list.insert(-2, self.keep_running) + def createSetup(self): + simpleRSS = config.plugins.simpleRSS + + # Create List of all Feeds + list = [ + getConfigListEntry(_("Feed"), x.uri) + for x in simpleRSS.feed + ] + + list.append(getConfigListEntry(_("Start automatically with Enigma2"), simpleRSS.autostart)) + + # Save keep_running in instance as we want to dynamically add/remove it + self.keep_running = getConfigListEntry(_("Keep running in background"), simpleRSS.keep_running) + if not simpleRSS.autostart.value: + list.append(self.keep_running) + + # Append Last two config Elements + list.extend(( + getConfigListEntry(_("Show new Messages as"), simpleRSS.update_notification), + getConfigListEntry(_("Update Interval (min)"), simpleRSS.interval), + getConfigListEntry(_("Fetch feed from Google Reader?"), simpleRSS.enable_google_reader), + )) + + if simpleRSS.enable_google_reader.value: + list.extend(( + getConfigListEntry(_("Google Username"), simpleRSS.google_username), + getConfigListEntry(_("Google Password"), simpleRSS.google_password), + )) + + self.list = list - # Assign new List to ConfigList + def elementChanged(self, instance): + self.createSetup() self["config"].setList(self.list) def delete(self): @@ -142,10 +146,9 @@ class RSSSetup(ConfigListScreen, Screen): id = self["config"].getCurrentIndex() del config.plugins.simpleRSS.feed[id] config.plugins.simpleRSS.feedcount.value -= 1 - self.list.pop(id) - # redraw list - self["config"].l.invalidate() + self.createSetup() + self["config"].setList(self.list) def ok(self): id = self["config"].getCurrentIndex() @@ -174,8 +177,9 @@ class RSSSetup(ConfigListScreen, Screen): if uri.value == "http://": del config.plugins.simpleRSS.feed[id] else: - self.list.insert(id, getConfigListEntry(_("Feed"), uri)) config.plugins.simpleRSS.feedcount.value = id+1 + self.createSetup() + self["config"].setList(self.list) def keySave(self): # Tell Poller to recreate List if present @@ -188,7 +192,8 @@ class RSSSetup(ConfigListScreen, Screen): simpleRSS = config.plugins.simpleRSS # Remove Notifier - simpleRSS.autostart.notifiers.remove(self.autostartChanged) + simpleRSS.autostart.notifiers.remove(self.elementChanged) + simpleRSS.enable_google_reader.notifiers.remove(self.elementChanged) # Keep feedcount sane simpleRSS.feedcount.value = len(simpleRSS.feed) diff --git a/simplerss/src/plugin.py b/simplerss/src/plugin.py index ff35553..d6fb9de 100644 --- a/simplerss/src/plugin.py +++ b/simplerss/src/plugin.py @@ -2,7 +2,8 @@ from . import _ from Components.config import config, ConfigSubsection, ConfigSubList, \ - ConfigEnableDisable, ConfigNumber, ConfigText, ConfigSelection + ConfigEnableDisable, ConfigNumber, ConfigText, ConfigSelection, \ + ConfigYesNo, ConfigPassword # Initialize Configuration config.plugins.simpleRSS = ConfigSubsection() @@ -22,10 +23,13 @@ simpleRSS.keep_running = ConfigEnableDisable(default=True) simpleRSS.feed = ConfigSubList() for i in range(0, simpleRSS.feedcount.value): s = ConfigSubsection() - s.uri = ConfigText(default="http://", fixed_size = False) + s.uri = ConfigText(default="http://", fixed_size=False) s.autoupdate = ConfigEnableDisable(default=True) simpleRSS.feed.append(s) del s +simpleRSS.enable_google_reader = ConfigYesNo(default=False) +simpleRSS.google_username = ConfigText(default="", fixed_size=False) +simpleRSS.google_password = ConfigPassword(default="") del simpleRSS