Updated Arabic Translation by Djihed Afifi.
[straw.git] / src / lib / Feed.py
blob59f6b07991c4cbe64a1d16f84b0193dcb16341cc
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', '_previous_etag',
40 '_error', '_process_status', 'router', 'sticky', '_parent',
41 '_items_stored', '_poll_freq', '_last_poll', '_n_items_unrea')
43 __save_fields = (('_title', ""), ('_location', ""), ('_username', ""),
44 ('_password', ""), ('_id', ""),
45 ('_channel_description', ""), ('_channel_title', ""),
46 ('_channel_link', ""), ('_channel_copyright', ""),
47 ('channel_creator', ""),
48 ('_previous_etag', ""), ('_error', None),
49 ('_items_stored', DEFAULT),
50 ('_poll_freq', DEFAULT),
51 ('_last_poll', 0),
52 ('_n_items_unread', 0))
55 # use one of the factory functions below instead of this directly
56 def __init__(self, title="", location="", username="", password=""):
57 Event.SignalEmitter.__init__(self)
58 self.initialize_slots(Event.FeedInfoUpdatedSignal,
59 #Event.FeedUnreadChangedSignal,
60 #Event.FeedNumOfItemsStoredChangedSignal,
61 #Event.FeedPollFrequencyChangedSignal,
62 Event.FeedLastPollChangedSignal,
63 Event.FeedStatusChangedSignal,
64 Event.FeedErrorStatusChangedSignal,
65 Event.FeedPolledSignal,
66 Event.NewItemsSignal,
67 Event.ItemsAddedSignal,
68 Event.ItemReadSignal,
69 Event.ItemStickySignal,
70 Event.ItemDeletedSignal,
71 Event.AllItemsReadSignal,
72 Event.RefreshFeedDisplaySignal)
74 self._title = title
75 self._channel_description = ""
76 self._channel_title = ""
77 self._channel_link = ""
78 self._channel_copyright = ""
79 self.channel_lbd = None
80 self.channel_editor = ""
81 self.channel_webmaster = ""
82 self.channel_creator = ""
83 self._location = location
84 self._username = username
85 self._password = password
86 self._parsed = None
87 self._items = FeedItems.FeedItems(self)
88 self._previous_etag = None
89 self._error = None
90 self._process_status = self.STATUS_IDLE
91 self.router = FeedDataRouter.FeedDataRouter(self)
92 self._parent = None
93 self._items_stored = Feed.DEFAULT
94 self._poll_freq = Feed.DEFAULT
95 self._last_poll = 0
96 self._n_items_unread = 0
97 return
99 def __str__(self):
100 return "Feed '%s' from %s" % (self._title, self._location)
102 @property
103 def id(self):
104 return self._id
106 @apply
107 def parsed():
108 doc = "A ParsedSummary object generated from the summary file"
109 def fget(self):
110 return self._parsed
111 def fset(self, parsed):
112 self._parsed = parsed
113 return property(**locals())
115 @apply
116 def title():
117 doc = "The title of this Feed (as defined by user)"
118 def fget(self):
119 text = ''
120 if self._title:
121 text = self._title
122 return text
123 def fset(self, title):
124 if self._title != title:
125 self._title = title
126 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
127 return property(**locals())
129 @apply
130 def access_info():
131 doc = "A tuple of location, username, password"
132 def fget(self):
133 return (self._location, self._username, self._password)
134 def fset(self, (location,username,password)):
135 self._location = location
136 self._username = username
137 self._password = password
138 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
139 return property(**locals())
141 @apply
142 def location():
143 doc = ""
144 def fget(self):
145 return self._location
146 def fset(self, location):
147 if self._location != location:
148 self._location = location
149 self.emit_signal(Event.FeedInfoUpdateSignal(self))
150 return property(**locals())
152 @apply
153 def channel_title():
154 doc = ""
155 def fget(self):
156 text = ''
157 if self._channel_title:
158 text = self._channel_title
159 return text
160 def fset(self, t):
161 changed = self._channel_title != t
162 self._channel_title = t
163 if changed:
164 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
165 return property(**locals())
167 @apply
168 def channel_description():
169 doc = ""
170 def fget(self):
171 text = ''
172 if self._channel_description:
173 text = self._channel_description
174 return text
175 def fset(self, t):
176 changed = self._channel_description != t
177 self._channel_description = t
178 if changed:
179 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
180 return property(**locals())
182 @apply
183 def channel_link():
184 doc = ""
185 def fget(self):
186 return self._channel_link
187 def fset(self, t):
188 changed = self._channel_link != t
189 self._channel_link = t
190 if changed:
191 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
192 return property(**locals())
194 @apply
195 def channel_copyright():
196 doc = ""
197 def fget(self):
198 return self._channel_copyright
199 def fset(self, t):
200 changed = self._channel_copyright != t
201 self._channel_copyright = t
202 if changed:
203 self.emit_signal(Event.FeedInfoUpdatedSignal(self))
204 return property(**locals())
206 @apply
207 def number_of_items_stored():
208 doc = ""
209 def fget(self):
210 return self._items_stored
211 def fset(self, num=None):
212 if self._items_stored != num:
213 self._items_stored = num
214 self.emit_signal(Event.FeedNumOfItemsStoredChangedSignal(self))
215 return property(**locals())
217 @apply
218 def poll_frequency():
219 doc = ""
220 def fget(self):
221 return self._poll_freq
222 def fset(self, freq):
223 if self._poll_freq != freq:
224 self._poll_freq = freq
225 self.emit_signal(Event.FeedPollFrequencyChangedSignal(self))
226 return property(**locals())
228 @apply
229 def last_poll():
230 doc = ""
231 def fget(self):
232 return self._last_poll
233 def fset(self, time):
234 if self._last_poll != time:
235 self._last_poll = time
236 self.emit_signal(Event.FeedLastPollChangedSignal(self))
237 return property(**locals())
239 @apply
240 def n_items_unread():
241 doc = ""
242 def fget(self):
243 return self._n_items_unread
244 def fset(self, n):
245 if self._n_items_unread != n:
246 self._n_items_unread = n
247 self.emit_signal(Event.FeedUnreadChangedSignal(self))
248 return property(**locals())
250 @apply
251 def previous_etag():
252 doc = ""
253 def fget(self):
254 return self._previous_etag
255 def fset(self, etag):
256 self._previous_etag = etag
257 return property(**locals())
259 @apply
260 def error():
261 doc = ""
262 def fget(self):
263 return self._error
264 def fset(self, error):
265 if self._error != error:
266 self._error = error
267 self.emit_signal(Event.FeedErrorStatusChangedSignal(self))
268 return property(**locals())
270 @apply
271 def process_status():
272 doc = ""
273 def fget(self):
274 return self._process_status
275 def fset(self, status):
276 if status != self._process_status:
277 self._process_status = status
278 self.emit_signal(Event.FeedStatusChangedSignal(self))
279 return property(**locals())
281 @apply
282 def parent():
283 doc = ""
284 def fget(self):
285 return self._parent
286 def fset(self, parent):
287 self._parent = parent
288 return property(**locals())
290 @property
291 def next_refresh(self):
292 """ return the feed's next refresh (time)"""
293 nr = None
294 if self._poll_freq == self.DEFAULT:
295 increment = Config.get_instance().poll_frequency
296 else:
297 increment = self._poll_freq
298 if increment > 0:
299 nr = self.last_poll + increment
300 return nr
302 def dump(self):
303 fl = {}
304 for f, default in self.__save_fields:
305 fl[f] = self.__getattribute__(f)
306 return fl
308 def undump(self, dict):
309 for f, default in self.__save_fields:
310 self.__setattr__(f, dict.get(f, default))
311 return
313 def poll_done(self):
314 self.emit_signal(Event.FeedPolledSignal(self))
316 def signal_new_items(self, items):
317 self.emit_signal(Event.NewItemsSignal(self, items))
319 def signal_added_items(self, items):
320 self.emit_signal(Event.ItemsAddedSignal(self, items))
322 def signal_deleted_item(self, item):
323 self.emit_signal(Event.ItemDeletedSignal(self, item))
325 def signal_refresh_display(self):
326 self.emit_signal(Event.RefreshFeedDisplaySignal(self))
328 def signal_all_items_read(self, items):
329 self.emit_signal(Event.AllItemsReadSignal(self, items))
331 def forward_signal(self, signal):
332 self.emit_signal(signal)
334 def add_items(self, items):
335 return self._items.add_items(items)
337 def restore_items(self, items):
338 return self._items.restore_items(items)
340 def delete_all_items(self):
341 self.signal_deleted_item(self.items)
343 def get_item_index(self, item):
344 return self._items.get_item_index(item)
346 @property
347 def items(self):
348 return self._items.get_items()
350 @property
351 def number_of_unread(self):
352 return self._n_items_unread
354 @property
355 def number_of_items(self):
356 return self._items.number_of_items
358 def mark_all_read(self):
359 return self._items.mark_all_read()
361 def load_contents(self):
362 return self._items.load()
364 def unload_contents(self):
365 self._items.unload()
367 @classmethod
368 def create_new_feed(klass, title, location="", username="", password=""):
369 f = klass()
370 f._title = title
371 f._location = location
372 f._id = Config.get_instance().next_feed_id_seq()
373 f._username = username
374 f._password = password
375 return f
377 @classmethod
378 def create_empty_feed(klass):
379 f = klass()
380 return f