allow custom localization in simplerss and add italian translation (thx spaeleus)
[enigma2-plugins.git] / simplerss / src / RSSPoller.py
1 # for localized messages
2 from . import _
3
4 from Components.config import config
5 from enigma import eTimer
6
7 from RSSFeed import BaseFeed, UniversalFeed
8
9 from twisted.web.client import getPage
10 from xml.etree.cElementTree import fromstring as cElementTree_fromstring
11
12 NOTIFICATIONID = 'SimpleRSSUpdateNotification'
13
14 class RSSPoller:
15         """Keeps all Feed and takes care of (automatic) updates"""
16
17         def __init__(self, session, poll = True):
18                 # Timer
19                 self.poll_timer = eTimer()
20                 self.poll_timer.callback.append(self.poll)
21                 if poll:
22                         self.poll_timer.start(0, 1)
23
24                 # Functions to call when updates happened
25                 self.update_callbacks = [ ]
26
27                 # Save Session, Initialize Var to identify triggered Reload
28                 self.session = session
29                 self.reloading = False
30
31                 self.newItemFeed = BaseFeed(
32                         "",
33                         _("New Items"),
34                         _("New Items since last Auto-Update"),
35                 )
36
37                 # Generate Feeds
38                 self.feeds = [
39                         UniversalFeed(
40                                 config.plugins.simpleRSS.feed[i].uri.value,
41                                 config.plugins.simpleRSS.feed[i].autoupdate.value
42                         )
43                                 for i in range(0, config.plugins.simpleRSS.feedcount.value)
44                 ]
45
46                 # Initialize Vars
47                 self.current_feed = 0
48
49         def addCallback(self, callback):
50                 if callback not in self.update_callbacks:
51                         self.update_callbacks.append(callback)
52
53         def removeCallback(self, callback):
54                 if callback in self.update_callbacks:
55                         self.update_callbacks.remove(callback)
56
57         def doCallback(self, id = None):
58                 for callback in self.update_callbacks:
59                         try:
60                                 callback(id)
61                         except:
62                                 pass
63
64         def error(self, error = ""):
65                 print "[SimpleRSS] failed to fetch feed:", error 
66
67                 # Assume its just a temporary failure and jump over to next feed                          
68                 self.next_feed()
69
70         def _gotPage(self, data, id = None, callback = False, errorback = None):
71                 # workaround: exceptions in gotPage-callback were ignored
72                 try:
73                         self.gotPage(data, id)
74                         if callback:
75                                 self.doCallback(id)
76                 except NotImplementedError, errmsg:
77                         # Don't show this error when updating in background
78                         if id is not None:
79                                 from Screens.MessageBox import MessageBox
80
81                                 self.session.open(
82                                         MessageBox,
83                                         _("Sorry, this type of feed is unsupported:\n%s") % (str(errmsg)),
84                                         type = MessageBox.TYPE_INFO,
85                                         timeout = 5
86                                 )
87                 except:
88                         import traceback, sys
89                         traceback.print_exc(file=sys.stdout)
90                         # Errorback given, call it (asumme we don't need do restart timer!)
91                         if errorback is not None:
92                                 errorback()
93                                 return
94                         # Assume its just a temporary failure and jump over to next feed                          
95                         self.next_feed()
96
97         def gotPage(self, data, id = None):
98                 feed = cElementTree_fromstring(data)
99
100                 # For Single-Polling
101                 if id is not None:
102                         self.feeds[id].gotFeed(feed)
103                         print "[SimpleRSS] single feed parsed..."
104                         return
105
106                 new_items = self.feeds[self.current_feed].gotFeed(feed)
107
108                 print "[SimpleRSS] feed parsed..."
109
110                 # Append new items to locally bound ones
111                 if new_items is not None:
112                         self.newItemFeed.history.extend(new_items)
113
114                 # Start Timer so we can either fetch next feed or show new_items
115                 self.next_feed()
116
117         def singlePoll(self, id, callback = False, errorback = None):
118                 getPage(self.feeds[id].uri).addCallback(self._gotPage, id, callback, errorback).addErrback(errorback)
119
120         def poll(self):
121                 # Reloading, reschedule
122                 if self.reloading:
123                         print "[SimpleRSS] timer triggered while reloading, rescheduling"
124                         self.poll_timer.start(10000, 1)
125                 # End of List
126                 elif len(self.feeds) <= self.current_feed:
127                         # New Items
128                         if len(self.newItemFeed.history):
129                                 print "[SimpleRSS] got new items, calling back"
130                                 self.doCallback()
131
132                                 # Inform User
133                                 if config.plugins.simpleRSS.update_notification.value == "preview":
134                                         from RSSScreens import RSSFeedView
135
136                                         from Tools.Notifications import AddNotificationWithID, RemovePopup
137
138                                         RemovePopup(NOTIFICATIONID)
139
140                                         AddNotificationWithID(
141                                                 NOTIFICATIONID,
142                                                 RSSFeedView,
143                                                 self.newItemFeed,
144                                                 newItems = True
145                                         )
146                                 elif config.plugins.simpleRSS.update_notification.value == "notification":
147                                         from Tools.Notifications import AddPopup
148                                         from Screens.MessageBox import MessageBox
149
150                                         AddPopup(
151                                                 _("Received %d new news item(s).") % (len(self.newItemFeed.history)),
152                                                 MessageBox.TYPE_INFO,
153                                                 5,
154                                                 NOTIFICATIONID
155                                         )
156                         # No new Items
157                         else:
158                                 print "[SimpleRSS] no new items"
159
160                         self.current_feed = 0
161                         self.poll_timer.startLongTimer(config.plugins.simpleRSS.interval.value*60)
162                 # It's updating-time
163                 else:
164                         # Assume we're cleaning history if current feed is 0
165                         clearHistory = self.current_feed == 0
166                         if config.plugins.simpleRSS.update_notification.value != "none":
167                                 from Tools.Notifications import current_notifications, notifications
168                                 for x in current_notifications:
169                                         if x[0] == NOTIFICATIONID:
170                                                 print "[SimpleRSS] timer triggered while preview on screen, rescheduling"
171                                                 self.poll_timer.start(10000, 1)
172                                                 return
173
174                                 if clearHistory:
175                                         for x in notifications:
176                                                 if x[4] and x[4] == NOTIFICATIONID:
177                                                         print "[SimpleRSS] wont wipe history because it was never read"
178                                                         clearHistory = False
179                                                         break
180
181                         if clearHistory:
182                                 del self.newItemFeed.history[:]
183
184                         # Feed supposed to autoupdate
185                         feed = self.feeds[self.current_feed]
186
187                         if feed.autoupdate:
188                                 getPage(feed.uri).addCallback(self._gotPage).addErrback(self.error)
189                         # Go to next feed
190                         else:
191                                 print "[SimpleRSS] passing feed"
192                                 self.next_feed()
193
194         def next_feed(self):
195                 self.current_feed += 1
196                 self.poll_timer.start(1000, 1)
197
198         def shutdown(self):
199                 self.poll_timer.callback.remove(self.poll)
200                 self.poll_timer = None
201
202         def triggerReload(self):
203                 self.reloading = True
204
205                 newfeeds = []
206                 found = False
207                 for i in range(0, config.plugins.simpleRSS.feedcount.value):
208                         for feed in self.feeds:
209                                 if config.plugins.simpleRSS.feed[i].uri.value == feed.uri:
210                                         # Update possibly different autoupdate value
211                                         feed.autoupdate = config.plugins.simpleRSS.feed[i].autoupdate.value
212                                         newfeeds.append(feed) # Append to new Feeds
213                                         self.feeds.remove(feed) # Remove from old Feeds
214                                         found = True
215                                         break
216                         if not found:
217                                 newfeeds.append(
218                                         UniversalFeed(
219                                                 config.plugins.simpleRSS.feed[i].uri.value,
220                                                 config.plugins.simpleRSS.feed[i].autoupdate.value
221                                 ))
222                         found = False
223
224                 self.feeds = newfeeds
225
226                 self.reloading = False