From 42c93bb63d65624d78bbed2b5ee4748604bb1749 Mon Sep 17 00:00:00 2001 From: jmalonzo Date: Tue, 24 Jul 2007 09:31:38 +0000 Subject: [PATCH] use a FifoCache with feed items, fix typo in ImageCache git-svn-id: svn+ssh://svn.gnome.org/svn/straw/trunk@312 141a2093-ea25-0410-9ad2-d44d734a8f13 --- src/lib/ImageCache.py | 2 +- src/lib/feeds.py | 120 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 77 insertions(+), 45 deletions(-) diff --git a/src/lib/ImageCache.py b/src/lib/ImageCache.py index 861b1cd..496aff3 100644 --- a/src/lib/ImageCache.py +++ b/src/lib/ImageCache.py @@ -127,7 +127,7 @@ class Cache(gobject.GObject): entry.decr_count() if entry.count == 0: del self.__cache[key] - self.emit('image-updated', url, None) + self.emit('image-updated', key, None) def image_updated(self, url, data): self.__cache[url].pollstopper = None diff --git a/src/lib/feeds.py b/src/lib/feeds.py index a0866ea..71c008a 100644 --- a/src/lib/feeds.py +++ b/src/lib/feeds.py @@ -1,4 +1,4 @@ -import locale +import locale, operator import gobject import FeedDataRouter import ItemStore @@ -226,7 +226,7 @@ class Feed(gobject.GObject): self._items_stored = Feed.DEFAULT self._poll_freq = Feed.DEFAULT self._last_poll = 0 - self._items = set() + self._items = FifoCache(num_entries=Feed.DEFAULT) self._items_loaded = False return @@ -434,67 +434,42 @@ class Feed(gobject.GObject): def poll_done(self): self.emit('poll-done') - # FeedItems stuff - def _sort(self, items): - """ - Sorts the given items according to the sort order - """ - items = sorted(items, cmp=self._cmp) - # XXX - #if self._items.sort_order: - # items.reverse() - return items - - def _cmp(self, a, b): - """ - Comparator method to compare items based on the item's pub_date attribute - - If an item doesn't have a pub_date, it uses title and prioritizes the - unread items - """ - try: - return cmp(a.pub_date, b.pub_date) - except AttributeError: - return locale.strcoll(a.title, b.title) and not a.seen or not b.seen - def add_items(self, items): + items = sorted(items, key=operator.attrgetter('pub_date')) config = Config.get_instance() cutpoint = self.number_of_items_stored if cutpoint == Feed.DEFAULT: cutpoint = config.number_of_items_stored - items = set(sorted(items, cmp=self._cmp)) + self._items.set_number_of_entries(cutpoint) maxid = 0 if self._items: maxid = reduce(max, [item.id for item in self._items]) + print "MAX ID IS ", maxid + newitems = [] for item in items: maxid += 1 item.id = maxid item.feed = self - items.add(item) - self._items = self._items.union(items) - self.restore_items(self._items) - self.emit('items-updated', items) + newitems.append(item) + self._items[item.id] = item + self.emit('items-updated', newitems) def restore_items(self, items): - olditems = [] - config = Config.get_instance() + items = sorted(items, key=operator.attrgetter('pub_date')) cutpoint = self.number_of_items_stored if cutpoint == Feed.DEFAULT: + config = Config.get_instance() cutpoint = config.number_of_items_stored - items = self._sort(items) + self._items.set_number_of_entries(cutpoint) + olditems = [] for idx, item in enumerate(items): - item.feed = self - if item.sticky or not item.seen or idx <= cutpoint: - item.connect('read', self.item_read_cb) - # forward sticky signal? XXX - self._items.add(item) - continue - else: + if not item.sticky and idx > cutpoint: item.clean_up() olditems.append(item) - #self.number_of_items_stored = len(self.items) - print "\told: ", len(olditems) - print "\tnew: ", len(items) + continue + item.feed = self + self._items[item.id] = item + print "\told: %s, new:%s" % (len(olditems),len(self._items)) if olditems: self.emit('items-deleted', olditems) return @@ -509,7 +484,7 @@ class Feed(gobject.GObject): def items(self): if not self._items_loaded: self.load_contents() - return self._items + return self._items.itervalues() def mark_all_items_as_read(self): def mark(item): item.seen = True @@ -555,3 +530,60 @@ class Feed(gobject.GObject): def create_empty_feed(klass): f = klass() return f + + +import UserDict +from collections import deque + +class FifoCache(object, UserDict.DictMixin): + ''' A mapping that remembers the last 'num_entries' items that were set ''' + + def __init__(self, num_entries, dct=()): + self.num_entries = num_entries + self.dct = dict(dct) + self.lst = deque() + + def __repr__(self): + return '%r(%r,%r)' % ( + self.__class__.__name__, self.num_entries, self.dct) + + def copy(self): + return self.__class__(self.num_entries, self.dct) + + def keys(self): + return list(self.lst) + + def __getitem__(self, key): + return self.dct[key] + + def __setitem__(self, key, value): + dct = self.dct + lst = self.lst + if key in dct: + self.remove_from_deque(lst, key) + dct[key] = value + lst.append(key) + if len(lst) > self.num_entries: + del dct[lst.popleft()] + + def __delitem__(self, key): + self.dct.pop(key) + self.remove_from_deque(self.lst, key) + + # a method explicitly defined only as an optimization + def __contains__(self, item): + return item in self.dct + + has_key = __contains__ + + def remove_from_deque(self, d, x): + for i, v in enumerate(d): + if v == x: + del d[i] + return + raise ValueError, '%r not in %r' % (x,d) + + def set_number_of_entries(self, num): + self.num_entries = num + while len(self.lst) > num: + del self.dct[self.lst.popleft()] -- 2.11.4.GIT