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