view backend/couchdb/CouchDbBackend.py @ 258:4ca1fac32dde

Pull the constant of days to keep feed entries into the abstract class
author Dirk Olmes <dirk@xanthippe.ping.de>
date Tue, 12 Mar 2019 02:39:18 +0100
parents f79be01821c4
children
line wrap: on
line source

# -*- coding: utf-8 -*-
import couchdb
import logging
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

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

    def __init__(self):
        super(CouchDbBackend, self).__init__()
        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 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 getAllFeeds(self):
        # make sure that the results are actually fetched into memory, otherwise we'll pass
        # a ViewResults instance around which is not what we want
        return list(Feed.all(self.database))

    def _retrieveEntriesForSelectedFeed(self, hideReadEntries):
        viewResults = FeedEntry.entriesForFeed(self.selectedFeed, self.database)
        if hideReadEntries:
            filterFunc = lambda feedEntry: feedEntry.read is False
            viewResults = filter(filterFunc, 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 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._retrieveEntriesForSelectedFeed(False)
        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():
                try:
                    FeedUpdater(self.database, self.preferences()).update(feed)
                except Exception as ex:
                    logging.getLogger("FeedUpdate").error("Exception during fetch: " + str(ex))

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