Remove unneeded usage of boundFunction
[enigma2-plugins.git] / simplerss / src / RSSPoller.py
1 from Screens.MessageBox import MessageBox
2 from Components.config import config
3 from enigma import eTimer
4
5 from RSSScreens import RSSFeedView
6 from RSSFeed import UniversalFeed
7
8 from twisted.web.client import getPage
9 from xml.dom.minidom import parseString as minidom_parseString
10
11 class RSSPoller:
12         """Keeps all Feed and takes care of (automatic) updates"""
13         def __init__(self, session):
14                 # Timer
15                 self.poll_timer = eTimer()
16                 self.poll_timer.timeout.get().append(self.poll)
17                 self.poll_timer.start(0, 1)
18
19                 # Functions to call when updates happened
20                 self.update_callbacks = [ ]
21
22                 # Save Session, Initialize Var to identify triggered Reload
23                 self.session = session
24                 self.reloading = False
25
26                 # Generate Feeds
27                 self.feeds = [
28                         UniversalFeed(
29                                 config.plugins.simpleRSS.feed[i].uri.value,
30                                 config.plugins.simpleRSS.feed[i].autoupdate.value
31                         )
32                                 for i in range(0, config.plugins.simpleRSS.feedcount.value)
33                 ]
34
35                 # Initialize Vars
36                 self.new_items = [ ]
37                 self.current_feed = 0
38
39         def addCallback(self, callback):
40                 if callback not in self.update_callbacks:
41                         self.update_callbacks.append(callback)
42
43         def removeCallback(self, callback):
44                 if callback in self.update_callbacks:
45                         self.update_callbacks.remove(callback)
46
47         def doCallback(self, id = None):
48                 for callback in self.update_callbacks:
49                         try:
50                                 callback(id)
51                         except:
52                                 pass
53
54         def error(self, error = ""):
55                 if not self.session:
56                         print "[SimpleRSS] error polling"
57                 else:
58                         self.session.open(
59                                 MessageBox,
60                                 "Sorry, failed to fetch feed.\n" + error,
61                                 type = MessageBox.TYPE_INFO,
62                                 timeout = 5
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                         # TODO: Annoying with Multifeed?
75                         self.session.open(
76                                 MessageBox,
77                                 "Sorry, this type of feed is unsupported.\n"+ str(errmsg),
78                                 type = MessageBox.TYPE_INFO,
79                                 timeout = 5
80                         )
81                 except:
82                         import traceback, sys
83                         traceback.print_exc(file=sys.stdout)
84                         # Errorback given, call it (asumme we don't need do restart timer!)
85                         if errorback is not None:
86                                 errorback()
87                                 return
88                         # Assume its just a temporary failure and jump over to next feed                          
89                         self.next_feed()
90         
91         def gotPage(self, data, id = None):
92                 print "[SimpleRSS] parsing.."
93
94                 # sometimes activates spinner :-/
95                 dom = minidom_parseString(data)
96
97                 print "[SimpleRSS] xml parsed.."
98
99                 # For Single-Polling
100                 if id is not None:
101                         self.feeds[id].gotDom(dom)
102                         print "[SimpleRSS] single feed parsed.."
103                         return
104
105                 new_items = self.feeds[self.current_feed].gotDom(dom)
106
107                 print "[SimpleRSS] feed parsed.."
108
109                 # Append new items to locally bound ones
110                 self.new_items.extend(new_items)
111
112                 # Start Timer so we can either fetch next feed or show new_items
113                 self.next_feed()
114
115         def singlePoll(self, id, callback = False, errorback = None):
116                 getPage(self.feeds[id].uri).addCallback(self._gotPage, id, callback, errorback).addErrback(errorback)
117
118         def poll(self):
119                 # Reloading, reschedule
120                 if self.reloading:
121                         print "[SimpleRSS] timer triggered while reloading, rescheduling"
122                         self.poll_timer.start(10000, 1)
123                 # End of List
124                 elif len(self.feeds) <= self.current_feed:
125                         # New Items
126                         if len(self.new_items):
127                                 print "[SimpleRSS] got", len(self.new_items), "new items"
128                                 print "[SimpleRSS] calling back"
129                                 self.doCallback()
130                                 # Inform User
131                                 if config.plugins.simpleRSS.show_new.value:
132                                         self.session.open(RSSFeedView, self.new_items, newItems=True)
133                         # No new Items
134                         else:
135                                 print "[SimpleRSS] no new items"
136                         self.current_feed = 0
137                         self.poll_timer.startLongTimer(config.plugins.simpleRSS.interval.value*60)
138                 # It's updating-time
139                 else:
140                         # Id is 0 -> empty out new items
141                         if self.current_feed == 0:
142                                 self.new_items = [ ]
143                         # Feed supposed to autoupdate
144                         feed = self.feeds[self.current_feed]
145                         if feed.autoupdate:
146                                 getPage(feed.uri).addCallback(self._gotPage).addErrback(self.error)
147                         # Go to next feed
148                         else:
149                                 print "[SimpleRSS] passing feed"
150                                 self.next_feed()
151
152         def next_feed(self):
153                 self.current_feed += 1
154                 self.poll_timer.start(1000, 1)
155
156         def shutdown(self):
157                 self.poll_timer.timeout.get().remove(self.poll)
158                 self.poll_timer = None
159
160         def triggerReload(self):
161                 self.reloading = True
162
163                 newfeeds = []
164                 found = False
165                 for i in range(0, config.plugins.simpleRSS.feedcount.value):
166                         for feed in self.feeds:
167                                 if config.plugins.simpleRSS.feed[i].uri.value == feed.uri:
168                                         # Update possibly different autoupdate value
169                                         feed.autoupdate = config.plugins.simpleRSS.feed[i].autoupdate.value
170                                         newfeeds.append(feed) # Append to new Feeds
171                                         self.feeds.remove(feed) # Remove from old Feeds
172                                         found = True
173                                         break
174                         if not found:
175                                 newfeeds.append(
176                                         UniversalFeed(
177                                                 config.plugins.simpleRSS.feed[i].uri.value,
178                                                 config.plugins.simpleRSS.feed[i].autoupdate.value
179                                 ))
180                         found = False
181
182                 self.feeds = newfeeds
183
184                 self.reloading = False