feed list treeview alpha 20-05-07
[straw.git] / src / lib / Feed.py
blobdad60e1ea126e5c4ecedd093c97c262ecc2ebfdc
1 """ Feed.py
3 Provides a module for managing feeds
4 """
5 __copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
6 __license__ = """
7 Straw is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 2 of the License, or (at your option) any later
10 version.
12 Straw is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 Place - Suite 330, Boston, MA 02111-1307, USA. """
21 import Event
22 import FeedItems
23 import FeedDataRouter
24 import Config
25 from error import log
27 class Feed(object, Event.SignalEmitter):
28 "A Feed object stores information set by user about a RSS feed."
30 DEFAULT = -1
31 STATUS_IDLE = 0
32 STATUS_POLLING = 1
34 __slots__ = ('_title', '_location', '_username', '_password', '_parsed',
35 '__save_fields', '_items', '_slots',
36 '_id', '_channel_description',
37 '_channel_title', '_channel_link', '_channel_copyright',
38 'channel_lbd', 'channel_editor', 'channel_webmaster',
39 'channel_creator','_error', '_process_status', 'router', 'sticky', '_parent',
40 '_items_stored', '_poll_freq', '_last_poll', '_n_items_unread')
42 __save_fields = (('_title', ""), ('_location', ""), ('_username', ""),
43 ('_password', ""), ('_id', ""),
44 ('_channel_description', ""), ('_channel_title', ""),
45 ('_channel_link', ""), ('_channel_copyright', ""),
46 ('channel_creator', ""), ('_error', None),
47 ('_items_stored', DEFAULT),
48 ('_poll_freq', DEFAULT),
49 ('_last_poll', 0),
50 ('_n_items_unread', 0))
53 # use one of the factory functions below instead of this directly
54 def __init__(self, title="", location="", username="", password=""):
55 Event.SignalEmitter.__init__(self)
56 self.initialize_slots(Event.FeedInfoUpdatedSignal,
57 #Event.FeedUnreadChangedSignal,
58 #Event.FeedNumOfItemsStoredChangedSignal,
59 #Event.FeedPollFrequencyChangedSignal,
60 Event.FeedLastPollChangedSignal,
61 Event.FeedStatusChangedSignal,
62 Event.FeedErrorStatusChangedSignal,
63 Event.FeedPolledSignal,
64 Event.NewItemsSignal,
65 Event.ItemsAddedSignal,
66 Event.ItemReadSignal,
67 Event.ItemStickySignal,
68 Event.ItemDeletedSignal,
69 Event.AllItemsReadSignal,
70 Event.RefreshFeedDisplaySignal)
72 self._title = title
73 self._channel_description = ""
74 self._channel_title = ""
75 self._channel_link = ""
76 self._channel_copyright = ""
77 self.channel_lbd = None
78 self.channel_editor = ""
79 self.channel_webmaster = ""
80 self.channel_creator = ""
81 self._location = location
82 self._username = username
83 self._password = password
84 self._parsed = None
85 self._items = FeedItems.FeedItems(self)
86 self._error = None
87 self._process_status = self.STATUS_IDLE
88 self.router = FeedDataRouter.FeedDataRouter(self)
89 self._parent = None
90 self._items_stored = Feed.DEFAULT
91 self._poll_freq = Feed.DEFAULT
92 self._last_poll = 0
93 self._n_items_unread = 0
94 return
96 def __str__(self):
97 return "Feed '%s' from %s" % (self._title, self._location)
99 @property
100 def id(self):
101 return self._id
103 @apply
104 def parsed():
105 doc = "A ParsedSummary object generated from the summary file"
106 def fget(self):
107 return self._parsed
108 def fset(self, parsed):
109 self._parsed = parsed
110 return property(**locals())
112 @apply
113 def title():
114 doc = "The title of this Feed (as defined by user)"
115 def fget(self):
116 text = ''
117 if self._title:
118 text = self._title
119 return text
120 def fset(self, title):
121 if self._title != title:
122 self._title = title
123 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
124 return property(**locals())
126 @apply
127 def access_info():
128 doc = "A tuple of location, username, password"
129 def fget(self):
130 return (self._location, self._username, self._password)
131 def fset(self, (location,username,password)):
132 self._location = location
133 self._username = username
134 self._password = password
135 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
136 return property(**locals())
138 @apply
139 def location():
140 doc = ""
141 def fget(self):
142 return self._location
143 def fset(self, location):
144 if self._location != location:
145 self._location = location
146 self.emit_signal(Event.FeedInfoUpdateSignal(self))
147 return property(**locals())
149 @apply
150 def channel_title():
151 doc = ""
152 def fget(self):
153 text = ''
154 if self._channel_title:
155 text = self._channel_title
156 return text
157 def fset(self, t):
158 changed = self._channel_title != t
159 self._channel_title = t
160 if changed:
161 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
162 return property(**locals())
164 @apply
165 def channel_description():
166 doc = ""
167 def fget(self):
168 text = ''
169 if self._channel_description:
170 text = self._channel_description
171 return text
172 def fset(self, t):
173 changed = self._channel_description != t
174 self._channel_description = t
175 if changed:
176 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
177 return property(**locals())
179 @apply
180 def channel_link():
181 doc = ""
182 def fget(self):
183 return self._channel_link
184 def fset(self, t):
185 changed = self._channel_link != t
186 self._channel_link = t
187 if changed:
188 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
189 return property(**locals())
191 @apply
192 def channel_copyright():
193 doc = ""
194 def fget(self):
195 return self._channel_copyright
196 def fset(self, t):
197 changed = self._channel_copyright != t
198 self._channel_copyright = t
199 if changed:
200 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
201 return property(**locals())
203 @apply
204 def number_of_items_stored():
205 doc = ""
206 def fget(self):
207 return self._items_stored
208 def fset(self, num=None):
209 if self._items_stored != num:
210 self._items_stored = num
211 self.emit_signal(Event.FeedNumOfItemsStoredChangedSignal(self))
212 return property(**locals())
214 @apply
215 def poll_frequency():
216 doc = ""
217 def fget(self):
218 return self._poll_freq
219 def fset(self, freq):
220 if self._poll_freq != freq:
221 self._poll_freq = freq
222 self.emit_signal(Event.FeedPollFrequencyChangedSignal(self))
223 return property(**locals())
225 @apply
226 def last_poll():
227 doc = ""
228 def fget(self):
229 return self._last_poll
230 def fset(self, time):
231 if self._last_poll != time:
232 self._last_poll = time
233 self.emit_signal(Event.FeedLastPollChangedSignal(self))
234 return property(**locals())
236 @apply
237 def n_items_unread():
238 doc = ""
239 def fget(self):
240 return self._n_items_unread
241 def fset(self, n):
242 if self._n_items_unread != n:
243 self._n_items_unread = n
244 self.emit_signal(Event.FeedUnreadChangedSignal(self))
245 return property(**locals())
247 @apply
248 def error():
249 doc = ""
250 def fget(self):
251 return self._error
252 def fset(self, error):
253 if self._error != error:
254 self._error = error
255 self.emit_signal(Event.FeedErrorStatusChangedSignal(self))
256 return property(**locals())
258 @apply
259 def process_status():
260 doc = ""
261 def fget(self):
262 return self._process_status
263 def fset(self, status):
264 if status != self._process_status:
265 self._process_status = status
266 self.emit_signal(Event.FeedStatusChangedSignal(self))
267 return property(**locals())
269 @apply
270 def parent():
271 doc = ""
272 def fget(self):
273 return self._parent
274 def fset(self, parent):
275 self._parent = parent
276 return property(**locals())
278 @property
279 def next_refresh(self):
280 """ return the feed's next refresh (time)"""
281 nr = None
282 if self._poll_freq == self.DEFAULT:
283 increment = Config.get_instance().poll_frequency
284 else:
285 increment = self._poll_freq
286 if increment > 0:
287 nr = self.last_poll + increment
288 return nr
290 def dump(self):
291 fl = {}
292 for f, default in self.__save_fields:
293 fl[f] = self.__getattribute__(f)
294 return fl
296 def undump(self, dict):
297 for f, default in self.__save_fields:
298 self.__setattr__(f, dict.get(f, default))
299 return
301 def poll_done(self):
302 self.emit_signal(Event.FeedPolledSignal(self))
304 def signal_new_items(self, items):
305 self.emit_signal(Event.NewItemsSignal(self, items))
307 def signal_added_items(self, items):
308 self.emit_signal(Event.ItemsAddedSignal(self, items))
310 def signal_deleted_item(self, item):
311 self.emit_signal(Event.ItemDeletedSignal(self, item))
313 def signal_refresh_display(self):
314 self.emit_signal(Event.RefreshFeedDisplaySignal(self))
316 def signal_all_items_read(self, items):
317 self.emit_signal(Event.AllItemsReadSignal(self, items))
319 def forward_signal(self, signal):
320 self.emit_signal(signal)
322 def add_items(self, items):
323 return self._items.add_items(items)
325 def restore_items(self, items):
326 return self._items.restore_items(items)
328 def delete_all_items(self):
329 self.signal_deleted_item(self.items)
331 def get_item_index(self, item):
332 return self._items.get_item_index(item)
334 @property
335 def items(self):
336 return self._items.get_items()
338 @property
339 def number_of_unread(self):
340 return self._n_items_unread
342 @property
343 def number_of_items(self):
344 return self._items.number_of_items
346 def mark_all_read(self):
347 return self._items.mark_all_read()
349 def load_contents(self):
350 return self._items.load()
352 def unload_contents(self):
353 self._items.unload()
355 @classmethod
356 def create_new_feed(klass, title, location="", username="", password=""):
357 f = klass()
358 f._title = title
359 f._location = location
360 f._id = Config.get_instance().next_feed_id_seq()
361 f._username = username
362 f._password = password
363 return f
365 @classmethod
366 def create_empty_feed(klass):
367 f = klass()
368 return f