changeset 141:6ea813cfac33

pull out common code for updating a feed into an abstract class, have the sqlalchemy backend use that class.
author Dirk Olmes <dirk@xanthippe.ping.de>
date Wed, 24 Aug 2011 10:53:46 +0200
parents e927c6910c38
children 1524e1cefd39
files backend/AbstractFeedUpdater.py backend/sqlalchemy/FeedUpdater.py
diffstat 2 files changed, 60 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/backend/AbstractFeedUpdater.py	Wed Aug 24 10:53:46 2011 +0200
@@ -0,0 +1,54 @@
+
+from datetime import datetime
+import feedparser
+import logging
+
+STATUS_ERROR = 400
+log = logging.getLogger("FeedUpdater")
+
+class AbstractFeedUpdater(object):
+    '''
+    Abstract base class for FeedUpdater implementations - handles all the parsing of the feed.
+    Subclasses need to implement creating and storing the new feed entries.
+    '''
+
+    def __init__(self, feed):
+        self.feed = feed
+
+    def update(self):
+        log.info("updating " + self.feed.rss_url)
+        result = self._retrieveFeed()
+        for entry in result.entries:
+            self._normalize(entry)
+            self._processEntry(entry)
+        self.feed.incrementNextUpdateDate()
+
+    def _retrieveFeed(self):
+        result = feedparser.parse(self.feed.rss_url)
+        # bozo flags if a feed is well-formed.
+#        if result["bozo"] > 0:
+#            raise FeedUpdateException()
+        status = result["status"]
+        if status >= STATUS_ERROR:
+            raise FeedUpdateException("HTTP status " + str(status))
+        return result
+
+    def _normalize(self, entry):
+        if not hasattr(entry, "id"):
+            entry.id = entry.link
+        if not hasattr(entry, "updated_parsed"):
+            entry.updated_parsed = datetime.today()
+        else:
+            entry.updated_parsed = datetime(*entry.updated_parsed[:6])
+        if not hasattr(entry, "summary"):
+            if hasattr(entry, "content"):
+                entry.summary = entry.content[0].value
+            else:
+                entry.summary = ""
+
+    def _processEntry(self, entry):
+        raise Exception("_processEntry is abstract, subclasses must override")
+
+
+class FeedUpdateException(Exception):
+    pass
--- a/backend/sqlalchemy/FeedUpdater.py	Wed Aug 24 09:39:10 2011 +0200
+++ b/backend/sqlalchemy/FeedUpdater.py	Wed Aug 24 10:53:46 2011 +0200
@@ -1,4 +1,5 @@
 
+from backend.AbstractFeedUpdater import AbstractFeedUpdater, FeedUpdateException
 from datetime import datetime
 from Feed import Feed
 from FeedEntry import FeedEntry
@@ -46,39 +47,18 @@
     FeedUpdater(session, newFeed).update()
 
 
-class FeedUpdater(object):
+class FeedUpdater(AbstractFeedUpdater):
     def __init__(self, session, feed):
+        AbstractFeedUpdater.__init__(self, feed)
         self.session = session
-        self.feed = feed
-
-    def update(self):
-        log.info("updating " + self.feed.rss_url)
-        result = self.getFeed()
-        for entry in result.entries:
-            self.processEntry(entry)
-        self.feed.incrementNextUpdateDate()
 
-    def getFeed(self):
-        result = feedparser.parse(self.feed.rss_url)
-        # bozo flags if a feed is well-formed.
-#        if result["bozo"] > 0:
-#            raise FeedUpdateException()
-        status = result["status"]
-        if status >= STATUS_ERROR:
-            raise FeedUpdateException("HTTP status " + str(status))
-        return result
-
-    def processEntry(self, entry):
-        normalize(entry)
+    def _processEntry(self, entry):
         feedEntry = FeedEntry.findById(entry.id, self.session)
         if feedEntry is None:
-            self.createFeedEntry(entry)
+            self._createFeedEntry(entry)
 
-    def createFeedEntry(self, entry):
+    def _createFeedEntry(self, entry):
         new = FeedEntry.create(entry)
         new.feed = self.feed
         self.session.add(new)
         log.info("new feed entry: " + entry.title)
-
-class FeedUpdateException(Exception):
-    pass