view backend/couchdb/CouchDbBackend.py @ 182:964661153b97

hide read feed entries if configured
author dirk
date Sat, 10 Sep 2011 09:15:25 +0200
parents 1ab48428e2f9
children ac1de0a467fd
line wrap: on
line source


from FeedUpdater import FeedUpdater
from Preferences import Preferences
from backend.AbstractBackend import AbstractBackend
from backend.couchdb import CouchDb
from backend.couchdb.Feed import Feed
from backend.couchdb.FeedEntry import FeedEntry
import couchdb
import logging

class CouchDbBackend(AbstractBackend):
    '''
    Backend that uses CouchDB for persistence
    '''

    def __init__(self):
        CouchDb.init()
        server = self._initServer()
        self.database = server[CouchDb.database]
        self.prefs = None

    def _initServer(self):
        if CouchDb.database_url is not None:
            return couchdb.Server(CouchDb.database_url)
        else:
            return couchdb.Server()

    def preferences(self):
        if self.prefs is None:
            self.prefs = Preferences(self.database)
        return self.prefs

    #
    # handling of feeds
    #

    def getFeeds(self):
        if self.preferences().showOnlyUnreadFeeds():
            self.feeds = self._getUnreadFeeds()
        else:
            # make sure that the results are actually fetched into memory, otherwise we'll pass
            # a ViewResults instance around which is not what we want
            self.feeds = list(Feed.all(self.database))
        return self.feeds

    def _getUnreadFeeds(self):
        viewResults = self.database.view(CouchDb.feedsWithUnreadEntries(), group=True)
        feedsWithUnreadEntries = []
        for row in viewResults:
            feed = Feed.load(self.database, row["key"])
            feedsWithUnreadEntries.append(feed)
        return feedsWithUnreadEntries

    def _retrieveEntriesForSelectedFeed(self, hideReadEntries):
        viewResults = FeedEntry.view(self.database, CouchDb.feedEntriesByFeed(),
            key=self.selectedFeed.id)
        viewResults = list(viewResults)
        # TODO update date is a string ... convert to a ListDateTimeField for better sort support
        viewResults.sort(FeedEntry.compareByUpdateDate, reverse=True)
        if hideReadEntries:
            viewResults = filter(lambda feedEntry: feedEntry.read == False, viewResults)
        return viewResults

    def markSelectedFeedAsRead(self):
        for feedEntry in self.entriesForSelectedFeed():
            feedEntry.markRead(self.database)

    #
    # handling of the selected feed entry
    #

    def _markSelectedFeedEntryRead(self):
        self.selectedFeedEntry.markRead(self.database)

    def toggleSelectedFeedEntryRead(self):
        self.selectedFeedEntry.toggleRead(self.database)


    def toggleRead(self, feedEntry):
        raise Exception("not yet implemented")

    def markAllEntriesRead(self, feed):
        raise Exception("not yet implemented")

    def createFeed(self, url):
        feed = Feed.create(url)
        feed.store(self.database)
        FeedUpdater(self.database, self.preferences()).update(feed)

    def updateFeed(self, feed, changes):
        for key in changes.keys():
            feed[key] = changes[key]
        feed.store(self.database)

    def deleteSelectedFeed(self):
        viewResults = self.database.view(CouchDb.feedEntriesByFeed(), key=self.selectedFeed.id)
        for row in viewResults:
            del self.database[row.id]
        del self.database[self.selectedFeed.id]

    def entriesForFeed(self, feed, hideReadEntries):
        viewName = CouchDb.feedEntriesByFeed()
        if hideReadEntries:
            viewName = CouchDb.unreadFeedEntriesByFeed()
        return list(FeedEntry.view(self.database, viewName))

    def markFeedEntriesAsRead(self, indices):
        for index in indices:
            feedEntry = self.entriesForSelectedFeed()[index]
            feedEntry.markRead(self.database)

    def updateAllFeeds(self):
        # TODO use a view instead of iterating all feeds
        allFeeds = Feed.all(self.database)
        for feed in allFeeds:
            if feed.needsUpdate():
                FeedUpdater(self.database, self.preferences()).update(feed)

    def expireFeedEntries(self):
        logger = logging.getLogger("expiry")
        expireDate = self._calculateExpireDate()
        logger.info("expiring entries older than " + str(expireDate))
        for entry in FeedEntry.getReadFeedEntriesOlderThan(expireDate, self.database):
            del self.database[entry.id]