| 1 |
#!/usr/bin/python |
| 2 |
|
| 3 |
#TODO: Flickr photos out to check to see if captions have been updated |
| 4 |
#TODO: MySQL warnings are just going to standard output right now |
| 5 |
#TODO: non-existent attributes are set to the empty string to simplify MySQL... |
| 6 |
#TODO: queries could be optimized by checking multiple entries for updates |
| 7 |
# simulatenously (SELECT all entries that need to be updated...) |
| 8 |
#TODO: check style |
| 9 |
#TODO: Move MySQL connection info to another file, not under svn |
| 10 |
|
| 11 |
from getopt import gnu_getopt |
| 12 |
from sys import argv |
| 13 |
from xml.dom.minidom import Document |
| 14 |
import MySQLdb |
| 15 |
import feed |
| 16 |
import os.path, sys |
| 17 |
|
| 18 |
|
| 19 |
#TODO: refactor this |
| 20 |
# Specifies whether or not to force updates |
| 21 |
force = False |
| 22 |
# Controls how much to output |
| 23 |
verbose = False |
| 24 |
options, args = gnu_getopt(argv[1:], 'vf', ['force', 'verbose']) |
| 25 |
for o, a in options: |
| 26 |
if o == '--force' or o == '-f': |
| 27 |
force = True |
| 28 |
elif o == '--verbose' or o == '-v': |
| 29 |
verbose = True |
| 30 |
|
| 31 |
|
| 32 |
"""Parse a list to feeds to check for updates and populate a central database |
| 33 |
for other applications to use. |
| 34 |
""" |
| 35 |
|
| 36 |
# Connect to database |
| 37 |
db_settings_path = os.path.dirname(__file__) + '/config.txt' |
| 38 |
if not os.path.isfile(db_settings_path): |
| 39 |
print 'ERROR: Please create config.txt for db settings' |
| 40 |
exit() |
| 41 |
|
| 42 |
db_settings = {} |
| 43 |
for line in open(db_settings_path): |
| 44 |
if not line.startswith(('#', '//')): |
| 45 |
setting = line.strip().split(' ',1) |
| 46 |
db_settings[setting[0]] = setting[1] |
| 47 |
|
| 48 |
db_host = db_settings['db_host'] |
| 49 |
db_name = db_settings['db_name'] |
| 50 |
db_user = db_settings['db_user'] |
| 51 |
db_passwd = db_settings['db_passwd'] |
| 52 |
|
| 53 |
conn = MySQLdb.Connection(host=db_host, db=db_name, user=db_user, |
| 54 |
passwd=db_passwd, charset='utf8') |
| 55 |
cursor = conn.cursor() |
| 56 |
|
| 57 |
# Minidom object |
| 58 |
doc = Document() |
| 59 |
|
| 60 |
# Import the feeds |
| 61 |
import_list = os.path.dirname(__file__) + '/feeds.list' |
| 62 |
if os.path.isfile(import_list): |
| 63 |
for line in open(import_list): |
| 64 |
# Only act on non-empty, non-comment lines |
| 65 |
if line.strip() and not line.startswith(('#', '//')): |
| 66 |
# Split line into feed and attributes |
| 67 |
f = line.split() |
| 68 |
|
| 69 |
# Check for requested subclass |
| 70 |
if len(f) > 1 and hasattr(feed, f[1]) \ |
| 71 |
and callable(getattr(feed, f[1])) \ |
| 72 |
and issubclass(getattr(feed, f[1]), feed.Feed): |
| 73 |
this_type = getattr(feed, f[1]) |
| 74 |
# Otherwise, use default object |
| 75 |
else: |
| 76 |
if verbose: |
| 77 |
print "Warning: class %s not found -- using standard Feed class" % (f[1]) |
| 78 |
this_type = feed.Feed |
| 79 |
|
| 80 |
if verbose: |
| 81 |
print "Checking %s (%s)..." % (f[0], this_type.__name__) |
| 82 |
else: |
| 83 |
print "Checking %s..." % this_type.__name__ |
| 84 |
this_feed = this_type(f[0]) |
| 85 |
if not this_feed.parse(): |
| 86 |
sys.stderr.write(this_type.__name__ + ' updated failed.\n') |
| 87 |
this_feed.db_check(cursor, verbose, force) |
| 88 |
else: |
| 89 |
print "No feeds to check." |