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 :-)
--- /dev/null
+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()
+
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
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 = []
# 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
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)
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,
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
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"))
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):
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()
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
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)
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()
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