1 # for localized messages
4 from Components.config import config
5 from enigma import eTimer
7 from Tools.Notifications import AddPopup
8 from Screens.MessageBox import MessageBox
10 from RSSFeed import BaseFeed, UniversalFeed
12 from twisted.web.client import getPage
13 from xml.etree.cElementTree import fromstring as cElementTree_fromstring
15 from GoogleReader import GoogleReader
17 NOTIFICATIONID = 'SimpleRSSUpdateNotification'
22 """Keeps all Feed and takes care of (automatic) updates"""
24 def __init__(self, session, poll = True):
26 self.poll_timer = eTimer()
27 self.poll_timer.callback.append(self.poll)
30 # Save Session, Initialize Var to identify triggered Reload
31 self.session = session
32 self.reloading = False
34 self.newItemFeed = BaseFeed(
37 _("New Items since last Auto-Update"),
46 for x in config.plugins.simpleRSS.feed
49 if not config.plugins.simpleRSS.enable_google_reader.value:
51 self.poll_timer.start(0, 1)
53 self.googleReader = GoogleReader(config.plugins.simpleRSS.google_username.value, config.plugins.simpleRSS.google_password.value)
54 self.googleReader.login().addCallback(self.googleLoggedIn).addErrback(self.googleLoginFailed)
59 def googleLoggedIn(self, sid = None):
60 self.googleReader.getSubscriptionList().addCallback(self.googleSubscriptionList).addErrback(self.googleSubscriptionFailed)
62 def googleLoginFailed(self, res = None):
64 _("Failed to login to GoogleReader."),
65 MessageBox.TYPE_ERROR,
69 self.reloading = False
71 self.poll_timer.start(0, 1)
73 def googleSubscriptionList(self, subscriptions = None):
74 self.feeds.extend(subscriptions)
76 self.reloading = False
78 self.poll_timer.start(0, 1)
80 def googleSubscriptionFailed(self, res = None):
82 _("Failed to get subscriptions from GoogleReader."),
83 MessageBox.TYPE_ERROR,
87 self.reloading = False
89 self.poll_timer.start(0, 1)
91 def addCallback(self, callback):
92 if callback not in update_callbacks:
93 update_callbacks.append(callback)
95 def removeCallback(self, callback):
96 if callback in update_callbacks:
97 update_callbacks.remove(callback)
99 def doCallback(self, id = None):
100 for callback in update_callbacks:
106 def error(self, error = ""):
107 print "[SimpleRSS] failed to fetch feed:", error
109 # Assume its just a temporary failure and jump over to next feed
112 def _gotPage(self, data, id = None, callback = False, errorback = None):
113 # workaround: exceptions in gotPage-callback were ignored
115 self.gotPage(data, id)
118 except NotImplementedError, errmsg:
119 # Don't show this error when updating in background
121 from Screens.MessageBox import MessageBox
125 _("Sorry, this type of feed is unsupported:\n%s") % (str(errmsg)),
126 type = MessageBox.TYPE_INFO,
130 # We don't want to stop updating just because one feed is broken
133 import traceback, sys
134 traceback.print_exc(file=sys.stdout)
135 # Errorback given, call it (asumme we don't need do restart timer!)
136 if errorback is not None:
139 # Assume its just a temporary failure and jump over to next feed
142 def gotPage(self, data, id = None):
143 feed = cElementTree_fromstring(data)
147 self.feeds[id].gotFeed(feed)
148 print "[SimpleRSS] single feed parsed..."
151 new_items = self.feeds[self.current_feed].gotFeed(feed)
153 print "[SimpleRSS] feed parsed..."
155 # Append new items to locally bound ones
156 if new_items is not None:
157 self.newItemFeed.history.extend(new_items)
159 # Start Timer so we can either fetch next feed or show new_items
162 def singlePoll(self, id, callback = False, errorback = None):
163 getPage(self.feeds[id].uri).addCallback(self._gotPage, id, callback, errorback).addErrback(errorback)
166 # Reloading, reschedule
168 print "[SimpleRSS] timer triggered while reloading, rescheduling"
169 self.poll_timer.start(10000, 1)
171 elif len(self.feeds) <= self.current_feed:
173 if self.newItemFeed.history:
174 print "[SimpleRSS] got new items, calling back"
178 update_notification_value = config.plugins.simpleRSS.update_notification.value
179 if update_notification_value == "preview":
180 from RSSScreens import RSSFeedView
182 from Tools.Notifications import AddNotificationWithID, RemovePopup
184 RemovePopup(NOTIFICATIONID)
186 AddNotificationWithID(
192 elif update_notification_value == "notification":
194 _("Received %d new news item(s).") % (len(self.newItemFeed.history)),
195 MessageBox.TYPE_INFO,
201 print "[SimpleRSS] no new items"
203 self.current_feed = 0
204 self.poll_timer.startLongTimer(config.plugins.simpleRSS.interval.value*60)
207 # Assume we're cleaning history if current feed is 0
208 clearHistory = self.current_feed == 0
209 if config.plugins.simpleRSS.update_notification.value != "none":
210 from Tools.Notifications import current_notifications, notifications
211 for x in current_notifications:
212 if x[0] == NOTIFICATIONID:
213 print "[SimpleRSS] timer triggered while preview on screen, rescheduling"
214 self.poll_timer.start(10000, 1)
218 for x in notifications:
219 if x[4] and x[4] == NOTIFICATIONID:
220 print "[SimpleRSS] wont wipe history because it was never read"
225 del self.newItemFeed.history[:]
227 # Feed supposed to autoupdate
228 feed = self.feeds[self.current_feed]
231 getPage(feed.uri).addCallback(self._gotPage).addErrback(self.error)
234 print "[SimpleRSS] passing feed"
238 self.current_feed += 1
239 self.poll_timer.start(1000, 1)
242 self.poll_timer.callback.remove(self.poll)
243 self.poll_timer = None
245 def triggerReload(self):
246 self.reloading = True
249 oldfeeds = self.feeds
251 for x in config.plugins.simpleRSS.feed:
252 for feed in oldfeeds:
253 if x.uri.value == feed.uri:
254 # Update possibly different autoupdate value
255 feed.autoupdate = x.autoupdate.value
256 newfeeds.append(feed) # Append to new Feeds
257 oldfeeds.remove(feed) # Remove from old Feeds
268 self.feeds = newfeeds
270 if config.plugins.simpleRSS.enable_google_reader.value:
271 self.googleReader = GoogleReader(config.plugins.simpleRSS.google_username.value, config.plugins.simpleRSS.google_password.value)
272 self.googleReader.login().addCallback(self.googleLoggedIn).addErrback(self.googleLoginFailed)
274 self.reloading = False