view backend/sqlalchemy/SqlAlchemyBackend.py @ 189:e5d492595bdb

the view returns feed entries for a feed sorted by update date now, no need to do sorting in-memory
author dirk
date Wed, 14 Sep 2011 00:17:55 +0200
parents 3bcf39181f6e
children 7157bfd3f4d4
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 markSelectedFeedAsRead(self):
        self.selectedFeed.markAllEntriesRead()
        self.session.commit()

    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()