view backend/sqlalchemy/SqlAlchemyBackend.py @ 206:f74fe7cb5091

when updating feeds, only ever create new Feed objects for entries that are younger than the current expire date. This ensures that we do not see old, read, expired entries again
author dirk
date Sat, 02 Jun 2012 04:30:04 +0200
parents 7157bfd3f4d4
children bb3c851b18b1
line wrap: on
line source


from Feed import Feed
from FeedEntry import FeedEntry
from FeedUpdater import FeedUpdater
from Preferences import Preferences
from backend.AbstractBackend import AbstractBackend
from sqlalchemy.orm import joinedload
from sqlalchemy.sql import and_
import Database
import Mapping
import logging
import util

class SqlAlchemyBackend(AbstractBackend):
    '''
    Backend that uses sqlalchemy for persistence
    '''

    def __init__(self):
        AbstractBackend.__init__(self)
        self._initLogging()
        self.session = Database.createSession()
        self.prefs = Preferences(self.session)
        self.updater = None

    def _initLogging(self):
        logging.getLogger("sqlalchemy.orm").setLevel(logging.WARN)

        sqlalchemyLogLevel = logging.ERROR
        if util.databaseLoggingEnabled():
            sqlalchemyLogLevel = logging.INFO
        logging.getLogger("sqlalchemy").setLevel(sqlalchemyLogLevel)

    def preferences(self):
        return self.prefs

    def dispose(self):
        # save all uncommitted state, just in case
        self.session.commit()
        self.session.close()

    #
    # handling of feeds
    #

    def getFeeds(self):
        if self.preferences().showOnlyUnreadFeeds():
            self.feeds = self._getUnreadFeeds()
        else:
            self.feeds = Feed.all(self.session)
        return self.feeds

    def _getUnreadFeeds(self):
        query = self.session.query(FeedEntry).filter(FeedEntry.read == 0)
        queryWithOptions = query.options(joinedload("feed"))
        result = queryWithOptions.all()
        return self._collectFeeds(result)

    def _collectFeeds(self, feedEntries):
        feeds = [entry.feed for entry in feedEntries]
        uniqueFeeds = set(feeds)
        return list(uniqueFeeds)

    def _retrieveEntriesForSelectedFeed(self, hideReadEntries):
        return self.selectedFeed.entriesSortedByUpdateDate(hideReadEntries)

    def deleteSelectedFeed(self):
        self.session.delete(self.selectedFeed)
        self.session.commit()

    def createFeed(self, url):
        try:
            newFeed = Feed(url)
            self.session.add(newFeed)

            FeedUpdater(self.preferences(), self.session).update(newFeed)
            self.session.commit()
        except AttributeError as ae:
            self.session.rollback()
            raise ae

    def updateAllFeeds(self):
        FeedUpdater.updateAllFeeds(self.preferences(), self.session)
        self.session.commit()

    def updateFeed(self, feed, changes):
        feed.takeChangesFrom(changes)
        feed.incrementNextUpdateDate()
        self.session.commit()

    #
    # handling of the selected feed entry
    #

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

    def markFeedEntriesAsRead(self, indices):
        for index in indices:
            self.feedEntries[index].markRead()
        self.session.commit()

    def toggleSelectedFeedEntryRead(self):
        self.selectedFeedEntry.toggleRead()
        self.session.commit()

    def expireFeedEntries(self):
        logger = logging.getLogger("feedupdater")
        expireDate = self._calculateExpireDate()
        logger.info("expiring entries older than " + str(expireDate))
        feedEntry = Mapping.feedEntryTable
        deleteStatement = feedEntry.delete().where(
            and_(feedEntry.c.create_timestamp < expireDate, feedEntry.c.read == 1)
        )
        deleteStatement.execute()
        self.session.commit()