comparison backend/AbstractFeedUpdater.py @ 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
children 74217db92993
comparison
equal deleted inserted replaced
140:e927c6910c38 141:6ea813cfac33
1
2 from datetime import datetime
3 import feedparser
4 import logging
5
6 STATUS_ERROR = 400
7 log = logging.getLogger("FeedUpdater")
8
9 class AbstractFeedUpdater(object):
10 '''
11 Abstract base class for FeedUpdater implementations - handles all the parsing of the feed.
12 Subclasses need to implement creating and storing the new feed entries.
13 '''
14
15 def __init__(self, feed):
16 self.feed = feed
17
18 def update(self):
19 log.info("updating " + self.feed.rss_url)
20 result = self._retrieveFeed()
21 for entry in result.entries:
22 self._normalize(entry)
23 self._processEntry(entry)
24 self.feed.incrementNextUpdateDate()
25
26 def _retrieveFeed(self):
27 result = feedparser.parse(self.feed.rss_url)
28 # bozo flags if a feed is well-formed.
29 # if result["bozo"] > 0:
30 # raise FeedUpdateException()
31 status = result["status"]
32 if status >= STATUS_ERROR:
33 raise FeedUpdateException("HTTP status " + str(status))
34 return result
35
36 def _normalize(self, entry):
37 if not hasattr(entry, "id"):
38 entry.id = entry.link
39 if not hasattr(entry, "updated_parsed"):
40 entry.updated_parsed = datetime.today()
41 else:
42 entry.updated_parsed = datetime(*entry.updated_parsed[:6])
43 if not hasattr(entry, "summary"):
44 if hasattr(entry, "content"):
45 entry.summary = entry.content[0].value
46 else:
47 entry.summary = ""
48
49 def _processEntry(self, entry):
50 raise Exception("_processEntry is abstract, subclasses must override")
51
52
53 class FeedUpdateException(Exception):
54 pass