""" Feed.py Provides a module for managing feeds """ __copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc." __license__ = """ Straw is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Straw is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. """ import Event import FeedItems import FeedDataRouter import Config from error import log class Feed(object, Event.SignalEmitter): "A Feed object stores information set by user about a RSS feed." DEFAULT = -1 STATUS_IDLE = 0 STATUS_POLLING = 1 __slots__ = ('_title', '_location', '_username', '_password', '_parsed', '__save_fields', '_items', '_slots', '_id', '_channel_description', '_channel_title', '_channel_link', '_channel_copyright', 'channel_lbd', 'channel_editor', 'channel_webmaster', 'channel_creator', '_previous_etag', '_error', '_process_status', 'router', 'sticky', '_parent', '_items_stored', '_poll_freq', '_last_poll', '_n_items_unrea') __save_fields = (('_title', ""), ('_location', ""), ('_username', ""), ('_password', ""), ('_id', ""), ('_channel_description', ""), ('_channel_title', ""), ('_channel_link', ""), ('_channel_copyright', ""), ('channel_creator', ""), ('_previous_etag', ""), ('_error', None), ('_items_stored', DEFAULT), ('_poll_freq', DEFAULT), ('_last_poll', 0), ('_n_items_unread', 0)) # use one of the factory functions below instead of this directly def __init__(self, title="", location="", username="", password=""): Event.SignalEmitter.__init__(self) self.initialize_slots(Event.FeedInfoUpdatedSignal, #Event.FeedUnreadChangedSignal, #Event.FeedNumOfItemsStoredChangedSignal, #Event.FeedPollFrequencyChangedSignal, Event.FeedLastPollChangedSignal, Event.FeedStatusChangedSignal, Event.FeedErrorStatusChangedSignal, Event.FeedPolledSignal, Event.NewItemsSignal, Event.ItemsAddedSignal, Event.ItemReadSignal, Event.ItemStickySignal, Event.ItemDeletedSignal, Event.AllItemsReadSignal, Event.RefreshFeedDisplaySignal) self._title = title self._channel_description = "" self._channel_title = "" self._channel_link = "" self._channel_copyright = "" self.channel_lbd = None self.channel_editor = "" self.channel_webmaster = "" self.channel_creator = "" self._location = location self._username = username self._password = password self._parsed = None self._items = FeedItems.FeedItems(self) self._previous_etag = None self._error = None self._process_status = self.STATUS_IDLE self.router = FeedDataRouter.FeedDataRouter(self) self._parent = None self._items_stored = Feed.DEFAULT self._poll_freq = Feed.DEFAULT self._last_poll = 0 self._n_items_unread = 0 return def __str__(self): return "Feed '%s' from %s" % (self._title, self._location) @property def id(self): return self._id @apply def parsed(): doc = "A ParsedSummary object generated from the summary file" def fget(self): return self._parsed def fset(self, parsed): self._parsed = parsed return property(**locals()) @apply def title(): doc = "The title of this Feed (as defined by user)" def fget(self): text = '' if self._title: text = self._title return text def fset(self, title): if self._title != title: self._title = title self.emit_signal(Event.FeedInfoUpdatedSignal(self)) return property(**locals()) @apply def access_info(): doc = "A tuple of location, username, password" def fget(self): return (self._location, self._username, self._password) def fset(self, (location,username,password)): self._location = location self._username = username self._password = password self.emit_signal(Event.FeedInfoUpdatedSignal(self)) return property(**locals()) @apply def location(): doc = "" def fget(self): return self._location def fset(self, location): if self._location != location: self._location = location self.emit_signal(Event.FeedInfoUpdateSignal(self)) return property(**locals()) @apply def channel_title(): doc = "" def fget(self): text = '' if self._channel_title: text = self._channel_title return text def fset(self, t): changed = self._channel_title != t self._channel_title = t if changed: self.emit_signal(Event.FeedInfoUpdatedSignal(self)) return property(**locals()) @apply def channel_description(): doc = "" def fget(self): text = '' if self._channel_description: text = self._channel_description return text def fset(self, t): changed = self._channel_description != t self._channel_description = t if changed: self.emit_signal(Event.FeedInfoUpdatedSignal(self)) return property(**locals()) @apply def channel_link(): doc = "" def fget(self): return self._channel_link def fset(self, t): changed = self._channel_link != t self._channel_link = t if changed: self.emit_signal(Event.FeedInfoUpdatedSignal(self)) return property(**locals()) @apply def channel_copyright(): doc = "" def fget(self): return self._channel_copyright def fset(self, t): changed = self._channel_copyright != t self._channel_copyright = t if changed: self.emit_signal(Event.FeedInfoUpdatedSignal(self)) return property(**locals()) @apply def number_of_items_stored(): doc = "" def fget(self): return self._items_stored def fset(self, num=None): if self._items_stored != num: self._items_stored = num self.emit_signal(Event.FeedNumOfItemsStoredChangedSignal(self)) return property(**locals()) @apply def poll_frequency(): doc = "" def fget(self): return self._poll_freq def fset(self, freq): if self._poll_freq != freq: self._poll_freq = freq self.emit_signal(Event.FeedPollFrequencyChangedSignal(self)) return property(**locals()) @apply def last_poll(): doc = "" def fget(self): return self._last_poll def fset(self, time): if self._last_poll != time: self._last_poll = time self.emit_signal(Event.FeedLastPollChangedSignal(self)) return property(**locals()) @apply def n_items_unread(): doc = "" def fget(self): return self._n_items_unread def fset(self, n): if self._n_items_unread != n: self._n_items_unread = n self.emit_signal(Event.FeedUnreadChangedSignal(self)) return property(**locals()) @apply def previous_etag(): doc = "" def fget(self): return self._previous_etag def fset(self, etag): self._previous_etag = etag return property(**locals()) @apply def error(): doc = "" def fget(self): return self._error def fset(self, error): if self._error != error: self._error = error self.emit_signal(Event.FeedErrorStatusChangedSignal(self)) return property(**locals()) @apply def process_status(): doc = "" def fget(self): return self._process_status def fset(self, status): if status != self._process_status: self._process_status = status self.emit_signal(Event.FeedStatusChangedSignal(self)) return property(**locals()) @apply def parent(): doc = "" def fget(self): return self._parent def fset(self, parent): self._parent = parent return property(**locals()) @property def next_refresh(self): """ return the feed's next refresh (time)""" nr = None if self._poll_freq == self.DEFAULT: increment = Config.get_instance().poll_frequency else: increment = self._poll_freq if increment > 0: nr = self.last_poll + increment return nr def dump(self): fl = {} for f, default in self.__save_fields: fl[f] = self.__getattribute__(f) return fl def undump(self, dict): for f, default in self.__save_fields: self.__setattr__(f, dict.get(f, default)) return def poll_done(self): self.emit_signal(Event.FeedPolledSignal(self)) def signal_new_items(self, items): self.emit_signal(Event.NewItemsSignal(self, items)) def signal_added_items(self, items): self.emit_signal(Event.ItemsAddedSignal(self, items)) def signal_deleted_item(self, item): self.emit_signal(Event.ItemDeletedSignal(self, item)) def signal_refresh_display(self): self.emit_signal(Event.RefreshFeedDisplaySignal(self)) def signal_all_items_read(self, items): self.emit_signal(Event.AllItemsReadSignal(self, items)) def forward_signal(self, signal): self.emit_signal(signal) def add_items(self, items): return self._items.add_items(items) def restore_items(self, items): return self._items.restore_items(items) def delete_all_items(self): self.signal_deleted_item(self.items) def get_item_index(self, item): return self._items.get_item_index(item) @property def items(self): return self._items.get_items() @property def number_of_unread(self): return self._n_items_unread @property def number_of_items(self): return self._items.number_of_items def mark_all_read(self): return self._items.mark_all_read() def load_contents(self): return self._items.load() def unload_contents(self): self._items.unload() @classmethod def create_new_feed(klass, title, location="", username="", password=""): f = klass() f._title = title f._location = location f._id = Config.get_instance().next_feed_id_seq() f._username = username f._password = password return f @classmethod def create_empty_feed(klass): f = klass() return f