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."