| 1 |
""" |
|---|
| 2 |
Update feeds for Django community page. Requires Mark Pilgrim's excellent |
|---|
| 3 |
Universal Feed Parser (http://feedparser.org) |
|---|
| 4 |
""" |
|---|
| 5 |
|
|---|
| 6 |
import os |
|---|
| 7 |
import sys |
|---|
| 8 |
import time |
|---|
| 9 |
import socket |
|---|
| 10 |
import optparse |
|---|
| 11 |
import datetime |
|---|
| 12 |
import feedparser |
|---|
| 13 |
|
|---|
| 14 |
LOCKFILE = "/tmp/update_feeds.lock" |
|---|
| 15 |
def update_feeds(verbose=False): |
|---|
| 16 |
from django_website.apps.aggregator.models import Feed, FeedItem |
|---|
| 17 |
for feed in Feed.objects.filter(is_defunct=False): |
|---|
| 18 |
if verbose: |
|---|
| 19 |
print feed |
|---|
| 20 |
parsed_feed = feedparser.parse(feed.feed_url) |
|---|
| 21 |
for entry in parsed_feed.entries: |
|---|
| 22 |
title = entry.title.encode(parsed_feed.encoding, "xmlcharrefreplace") |
|---|
| 23 |
guid = entry.get("id", entry.link).encode(parsed_feed.encoding, "xmlcharrefreplace") |
|---|
| 24 |
link = entry.link.encode(parsed_feed.encoding, "xmlcharrefreplace") |
|---|
| 25 |
|
|---|
| 26 |
if not guid: |
|---|
| 27 |
guid = link |
|---|
| 28 |
|
|---|
| 29 |
if hasattr(entry, "summary"): |
|---|
| 30 |
content = entry.summary |
|---|
| 31 |
elif hasattr(entry, "content"): |
|---|
| 32 |
content = entry.content[0].value |
|---|
| 33 |
elif hasattr(entry, "description"): |
|---|
| 34 |
content = entry.description |
|---|
| 35 |
else: |
|---|
| 36 |
content = u"" |
|---|
| 37 |
content = content.encode(parsed_feed.encoding, "xmlcharrefreplace") |
|---|
| 38 |
|
|---|
| 39 |
try: |
|---|
| 40 |
if entry.has_key('modified_parsed'): |
|---|
| 41 |
date_modified = datetime.datetime.fromtimestamp(time.mktime(entry.modified_parsed)) |
|---|
| 42 |
elif parsed_feed.feed.has_key('modified_parsed'): |
|---|
| 43 |
date_modified = datetime.datetime.fromtimestamp(time.mktime(parsed_feed.feed.modified_parsed)) |
|---|
| 44 |
elif parsed_feed.has_key('modified'): |
|---|
| 45 |
date_modified = datetime.datetime.fromtimestamp(time.mktime(parsed_feed.modified)) |
|---|
| 46 |
else: |
|---|
| 47 |
date_modified = datetime.datetime.now() |
|---|
| 48 |
except TypeError: |
|---|
| 49 |
date_modified = datetime.datetime.now() |
|---|
| 50 |
|
|---|
| 51 |
try: |
|---|
| 52 |
feed.feeditem_set.get(guid=guid) |
|---|
| 53 |
except FeedItem.DoesNotExist: |
|---|
| 54 |
feed.feeditem_set.create(title=title, link=link, summary=content, guid=guid, date_modified=date_modified) |
|---|
| 55 |
|
|---|
| 56 |
def main(argv): |
|---|
| 57 |
socket.setdefaulttimeout(15) |
|---|
| 58 |
parser = optparse.OptionParser() |
|---|
| 59 |
parser.add_option('--settings') |
|---|
| 60 |
parser.add_option('-v', '--verbose', action="store_true") |
|---|
| 61 |
options, args = parser.parse_args(argv) |
|---|
| 62 |
if options.settings: |
|---|
| 63 |
os.environ["DJANGO_SETTINGS_MODULE"] = options.settings |
|---|
| 64 |
update_feeds(options.verbose) |
|---|
| 65 |
|
|---|
| 66 |
if __name__ == '__main__': |
|---|
| 67 |
try: |
|---|
| 68 |
lockfile = os.open(LOCKFILE, os.O_CREAT | os.O_EXCL) |
|---|
| 69 |
except OSError: |
|---|
| 70 |
sys.exit(0) |
|---|
| 71 |
try: |
|---|
| 72 |
sys.exit(main(sys.argv)) |
|---|
| 73 |
finally: |
|---|
| 74 |
os.close(lockfile) |
|---|
| 75 |
os.unlink(LOCKFILE) |
|---|