1 from __future__ import print_function
3 from Components.config import config
4 from enigma import eTimer
6 from Tools.Notifications import AddPopup
7 from Screens.MessageBox import MessageBox
9 from RSSFeed import BaseFeed, UniversalFeed
11 from twisted.web.client import getPage
12 from xml.etree.cElementTree import fromstring as cElementTree_fromstring
14 from GoogleReader import GoogleReader
16 NOTIFICATIONID = 'SimpleRSSUpdateNotification'
21 """Keeps all Feed and takes care of (automatic) updates"""
23 def __init__(self, poll = True):
25 self.poll_timer = eTimer()
26 self.poll_timer_conn = self.poll_timer.timeout.connect(self.poll)
29 # this indicates we're reloading the list of feeds
30 self.reloading = False
32 self.newItemFeed = BaseFeed(
35 _("New Items since last Auto-Update"),
44 for x in config.plugins.simpleRSS.feed
47 if not config.plugins.simpleRSS.enable_google_reader.value:
49 self.poll_timer.start(0, 1)
51 self.googleReader = GoogleReader(config.plugins.simpleRSS.google_username.value, config.plugins.simpleRSS.google_password.value)
52 self.googleReader.login().addCallback(self.googleLoggedIn).addErrback(self.googleLoginFailed)
57 def googleLoggedIn(self, sid = None):
58 self.googleReader.getSubscriptionList().addCallback(self.googleSubscriptionList).addErrback(self.googleSubscriptionFailed)
60 def googleLoginFailed(self, res = None):
62 _("Failed to login to Google Reader."),
63 MessageBox.TYPE_ERROR,
67 self.reloading = False
69 self.poll_timer.start(0, 1)
71 def googleSubscriptionList(self, subscriptions = None):
72 self.feeds.extend(subscriptions)
74 self.reloading = False
77 self.poll_timer.start(0, 1)
79 def googleSubscriptionFailed(self, res = None):
81 _("Failed to get subscriptions from Google Reader."),
82 MessageBox.TYPE_ERROR,
86 self.reloading = False
88 self.poll_timer.start(0, 1)
90 def addCallback(self, callback):
91 if callback not in update_callbacks:
92 update_callbacks.append(callback)
94 def removeCallback(self, callback):
95 if callback in update_callbacks:
96 update_callbacks.remove(callback)
98 def doCallback(self, id = None):
99 for callback in update_callbacks:
105 def error(self, error = ""):
106 print("[SimpleRSS] failed to fetch feed:", error)
108 # Assume its just a temporary failure and jump over to next feed
111 def _gotPage(self, data, id = None, callback = False, errorback = None):
112 # workaround: exceptions in gotPage-callback were ignored
114 self.gotPage(data, id)
117 except NotImplementedError as errmsg:
118 # Don't show this error when updating in background
121 _("Sorry, this type of feed is unsupported:\n%s") % (str(errmsg)),
122 MessageBox.TYPE_INFO,
126 # We don't want to stop updating just because one feed is broken
129 import traceback, sys
130 traceback.print_exc(file=sys.stdout)
131 # Errorback given, call it (asumme we don't need do restart timer!)
132 if errorback is not None:
135 # Assume its just a temporary failure and jump over to next feed
138 def gotPage(self, data, id = None):
139 feed = cElementTree_fromstring(data)
143 self.feeds[id].gotFeed(feed)
144 print("[SimpleRSS] single feed parsed...")
147 new_items = self.feeds[self.current_feed].gotFeed(feed)
149 print("[SimpleRSS] feed parsed...")
151 # Append new items to locally bound ones
152 if new_items is not None:
153 self.newItemFeed.history.extend(new_items)
155 # Start Timer so we can either fetch next feed or show new_items
158 def singlePoll(self, id, callback = False, errorback = None):
159 getPage(self.feeds[id].uri).addCallback(self._gotPage, id, callback, errorback).addErrback(errorback)
162 # Reloading, reschedule
164 print("[SimpleRSS] timer triggered while reloading, rescheduling")
165 self.poll_timer.start(10000, 1)
167 elif len(self.feeds) <= self.current_feed:
169 if self.newItemFeed.history:
170 print("[SimpleRSS] got new items, calling back")
174 update_notification_value = config.plugins.simpleRSS.update_notification.value
175 if update_notification_value == "preview":
176 from RSSScreens import RSSFeedView
178 from Tools.Notifications import AddNotificationWithID, RemovePopup
180 RemovePopup(NOTIFICATIONID)
182 AddNotificationWithID(
188 elif update_notification_value == "notification":
190 _("Received %d new news item(s).") % (len(self.newItemFeed.history)),
191 MessageBox.TYPE_INFO,
195 elif update_notification_value == "ticker":
196 from RSSTickerView import tickerView
198 print("[SimpleRSS] missing ticker instance, something with my code is wrong :-/")
200 tickerView.display(self.newItemFeed)
203 print("[SimpleRSS] no new items")
205 self.current_feed = 0
206 self.poll_timer.startLongTimer(config.plugins.simpleRSS.interval.value*60)
209 # Assume we're cleaning history if current feed is 0
210 clearHistory = self.current_feed == 0
211 if config.plugins.simpleRSS.update_notification.value != "none":
212 from Tools import Notifications
213 if hasattr(Notifications, 'notificationQueue'):
214 notifications = Notifications.notificationQueue.queue
215 current_notifications = Notifications.notificationQueue.current
216 handler = lambda note: (note.fnc, note.screen, note.args, note.kwargs, note.id)
217 handler_current = lambda note: (note[0].id,)
219 notifications = Notifications.notifications
220 current_notifications = Notifications.current_notifications
221 handler_current = handler = lambda note: note
223 for x in current_notifications:
224 if handler_current(x)[0] == NOTIFICATIONID:
225 print("[SimpleRSS] timer triggered while preview on screen, rescheduling")
226 self.poll_timer.start(10000, 1)
230 for x in notifications:
231 if handler(x)[4] == NOTIFICATIONID:
232 print("[SimpleRSS] wont wipe history because it was never read")
237 del self.newItemFeed.history[:]
239 # Feed supposed to autoupdate
240 feed = self.feeds[self.current_feed]
243 getPage(feed.uri).addCallback(self._gotPage).addErrback(self.error)
246 print("[SimpleRSS] passing feed")
250 self.current_feed += 1
251 self.poll_timer.start(1000, 1)
254 self.poll_timer_conn = None
255 self.poll_timer = None
258 def triggerReload(self):
259 self.reloading = True
262 oldfeeds = self.feeds
264 for x in config.plugins.simpleRSS.feed:
265 for feed in oldfeeds:
266 if x.uri.value == feed.uri:
267 # Update possibly different autoupdate value
268 feed.autoupdate = x.autoupdate.value
269 newfeeds.append(feed) # Append to new Feeds
270 oldfeeds.remove(feed) # Remove from old Feeds
281 self.feeds = newfeeds
283 if config.plugins.simpleRSS.enable_google_reader.value:
284 self.googleReader = GoogleReader(config.plugins.simpleRSS.google_username.value, config.plugins.simpleRSS.google_password.value)
285 self.googleReader.login().addCallback(self.googleLoggedIn).addErrback(self.googleLoginFailed)
287 self.reloading = False