""" 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
syntax highlighted by Code2HTML, v. 0.9.1