deluge/plugins/FlexRSS/plugin.py
2007-07-22 06:16:17 +00:00

935 lines
26 KiB
Python

class plugin_FlexRSS_Config:
feeds_counter = 0
filters_counter = 0
feeds = None
filters = None
# def listFilters(self):
# if not self.filters:
# return
# print 'Filters:'
# for filter in self.filters:
# print '+ id: %d' % filter['id']
# print ' name: %s' % filter['name']
# print ' type: %s' % filter['type']
# print ' patterns:'
# for p in filter['patterns']:
# print ' + [%s]' % p[1]
# print ' %s' % p[0]
# def listFeeds(self):
# if not self.feeds:
# return
# print 'Feeds:'
# for feed in self.feeds:
# print '+ id: %d' % feed['id']
# print ' name: %s' % feed['name']
# print ' url: %s' % feed['url']
# print ' interval: %d' % feed['interval']
def getFilter(self, id):
if not self.filters:
return None
for filter in self.filters:
if filter['id'] == id:
return filter
return None
def setFilter(self, id, key, value):
filter = self.getFilter(id)
if not filter:
return False
else:
filter[key] = value
return True
def addFilter(self, name, type, patterns, feeds):
id = self.feeds_counter + 1
self.feeds_counter = id
if not self.filters:
self.filters = []
filter = { "id" : id,
"name" : name,
"type" : type,
"patterns" : patterns,
"feeds" : feeds,
"history" : {} }
self.filters.append(filter)
return id
def deleteFilter(self, id):
if not self.filters:
return False
i = 0
while i < len(self.filters):
if self.filters[i]['id'] == id:
del self.filters[i]
return True
i = i + 1
def checkHistory(self, id, type, data):
filter = self.getFilter(id)
if not filter:
return False
try:
if type == 'TV Show':
filter['history'][type][data['series']].index(data['episode'])
return True
elif type == 'TV Show (dated)':
filter['history'][type][data['year']][data['month']].index(data['day'])
return True
else:
filter['history'][type].index(data['url'])
return True
except:
return False
def addHistory(self, id, type, data):
filter = self.getFilter(id)
if not filter:
return False
if type == 'TV Show':
if not filter['history'].has_key(type):
filter['history'][type] = {}
if not filter['history'][type].has_key(data['series']):
filter['history'][type][data['series']] = []
filter['history'][type][data['series']].append(data['episode'])
elif type == 'TV Show (dated)':
if not filter['history'].has_key(type):
filter['history'][type] = {}
if not filter['history'][type].has_key(data['year']):
filter['history'][type][data['year']] = {}
if not filter['history'][type][data['year']].has_key(data['month']):
filter['history'][type][data['year']][data['month']] = []
filter['history'][type][data['year']][data['month']].append(data['day'])
else:
if not filter['history'].has_key(type):
filter['history'][type] = []
filter['history'][type].append(data['url'])
def getFeed(self, id):
if not self.feeds:
return None
for feed in self.feeds:
if feed['id'] == id:
return feed
return None
def setFeed(self, id, key, value):
feed = self.getFeed(id)
if not feed:
return False
else:
feed[key] = value
return True
def addFeed(self, name, url, interval):
# Uhhh... no ++? WTF is the increment operator?
id = self.feeds_counter + 1
self.feeds_counter = id
if not self.feeds:
self.feeds = []
self.feeds.append({ "id" : id,
"name" : name,
"url" : url,
"interval" : interval })
return id
def deleteFeed(self, id):
if not self.feeds:
return False
i = 0
while i < len(self.feeds):
if self.feeds[i]['id'] == id:
del self.feeds[i]
return True
i = i + 1
class plugin_FlexRSS:
config = None
glade = None
feeds = None
def load_config(self):
import deluge.common, os
file = deluge.common.CONFIG_DIR + "/flexrss.dat"
if os.path.isfile(file):
import pickle
fd = open(file, 'r')
self.config = pickle.load(fd)
fd.close()
else:
self.config = plugin_FlexRSS_Config()
def write_config(self):
import deluge.common, os, pickle
file = deluge.common.CONFIG_DIR + "/flexrss.dat"
fd = open(file, 'w')
pickle.dump(self.config, fd)
fd.close()
def configure_cb_closed(self, args):
self.glade = None
def configure_cb_feed_new(self, args):
feed = { "name" : 'Untitled',
"url" : 'http://',
"interval" : 900,
"id" : 0 }
feed["id"] = self.config.addFeed(feed["name"], feed["url"], feed["interval"])
view = self.glade.get_widget("FlexRSS_Feeds")
model = view.get_model()
view.get_selection().select_iter(model.append(None, (feed["id"], feed["name"], feed["url"])))
def configure_cb_feed_selected(self, selection):
model, iter = selection.get_selected()
if not iter:
return
parent = model.iter_parent(iter)
if parent: # Selected a filter
iter = parent
# We want to edit a feed.
feed = self.config.getFeed(model.get_value(iter, 0))
if not feed:
print 'Error: could not find feed #' + str(model.get_value(iter, 0))
return
self.glade.get_widget("FlexRSS_EditFeed_Name").set_text(feed["name"])
self.glade.get_widget("FlexRSS_EditFeed_URL").set_text(feed["url"])
self.glade.get_widget("FlexRSS_EditFeed_Interval").set_text(str(feed["interval"]))
self.glade.get_widget('FlexRSS_Feeds_Editor').show()
def configure_cb_feed_delete(self, arg, id=None):
if not id:
# Which feed is selected?
selection = self.glade.get_widget("FlexRSS_Feeds").get_selection()
model, iter = selection.get_selected()
if not iter:
return
id = model.get_value(iter, 0)
else:
model = self.glade.get_widget("FlexRSS_Feeds").get_model()
iter = model.get_iter_first()
while iter:
if model.get_value(iter, 0) == id:
break
iter = model.iter_next(iter)
if not iter:
print 'Couldn\'t find feed.'
return
# Remove from config
if not self.config.deleteFeed(id):
print 'Unable to delete feed #' + str(id)
return
# Remove from UI
model.remove(iter)
self.write_config()
# We are no longer editing a feed, so hide the editing widgets.
self.glade.get_widget('FlexRSS_Feeds_Editor').hide()
def configure_cb_feed_save(self, arg, id=None):
if not id:
# Which feed is selected?
selection = self.glade.get_widget("FlexRSS_Feeds").get_selection()
model, iter = selection.get_selected()
if not iter:
return
id = model.get_value(iter, 0)
else:
model = self.glade.get_widget("FlexRSS_Feeds").get_model()
iter = model.iter_first()
while iter:
if model.get_value(iter, 0) == id:
break
iter = iter.iter_next(iter)
if not iter:
print 'Couldn\'t find feed.'
return
# Update configuration
self.config.setFeed(id, "name", self.glade.get_widget("FlexRSS_EditFeed_Name").get_text())
self.config.setFeed(id, "url", self.glade.get_widget("FlexRSS_EditFeed_URL").get_text())
self.config.setFeed(id, "interval", int(self.glade.get_widget("FlexRSS_EditFeed_Interval").get_text()))
self.write_config()
# Update UI
feed = self.config.getFeed(id)
model.set_value(iter, 0, feed["id"])
model.set_value(iter, 1, feed["name"])
model.set_value(iter, 2, feed["url"])
if not self.feeds.has_key(id):
self.feeds[id] = { 'cfg' : feed,
'updated' : 0,
'data' : [] }
def configure_cb_filter_new(self, arg, test_pattern=None):
filter = { "name" : "Untitled",
"type" : "Generic",
"patterns" : [('', 'Title')],
"feeds" : [0],
"id" : 0 }
if test_pattern:
# Try to guess a good pattern
import re, string
trans_table = string.maketrans(' ', '.')
# TV Show
exp = re.compile('(.*).([0-9]+)x([0-9]+)', re.IGNORECASE)
match = exp.match(test_pattern)
if match:
pattern = match.group(1).lower().translate(trans_table) + '.%sx%e'
filter['patterns'][0] = (pattern, 'Title')
filter['name'] = match.group(1)
filter['type'] = 'TV Show'
if not match:
exp = re.compile('(.*).S([0-9]+)E([0-9]+)', re.IGNORECASE)
match = exp.match(test_pattern)
if match:
pattern = match.group(1).lower().translate(trans_table) + '.S%sE%e'
filter['patterns'][0] = (pattern, 'Title')
filter['name'] = match.group(1)
filter['type'] = 'TV Show'
if not match:
exp = re.compile('(.*).([0-9]{4}).([0-9]{1,2}).([0-9]{1,2})', re.IGNORECASE)
match = exp.match(test_pattern)
if match:
pattern = None
if ((int(match.group(3)) <= 12) and (int(match.group(4)) <= 31)):
pattern = match.group(1).lower().translate(trans_table) + '.%Y.%m.%d'
elif ((int(match.group(3)) <= 31) and (int(match.group(4)) <= 12)):
pattern = match.group(1).lower().translate(trans_table) + '.%Y.%d.%m'
if pattern:
filter['patterns'][0] = (pattern, 'Title')
filter['name'] = match.group(1)
filter['type'] = 'TV Show (dated)'
else:
match = None
if not match:
exp = re.compile('(.*).([0-9]+)', re.IGNORECASE)
match = exp.match(test_pattern)
if match:
pattern = match.group(1).lower().translate(trans_table) + '.%e'
filter['patterns'][0] = (pattern, 'Title')
filter['name'] = match.group(1)
filter['type'] = 'TV Show'
# Add to config
filter['id'] = self.config.addFilter(filter['name'], filter['type'], filter['patterns'], 'feeds')
# Add to UI
self.configure_ui_add_filter(self.config.getFilter(filter['id']), test_pattern)
def configure_cb_filter_selected(self, selection):
model, iter = selection.get_selected()
if not iter:
return
# We want to edit a filter.
filter = self.config.getFilter(model.get_value(iter, 0))
if not filter:
print 'Error: could not find filter #' + str(model.get_value(iter, 0))
return
self.glade.get_widget('FlexRSS_Filters_Name').set_text(filter['name'])
if filter['type'] == 'TV Show':
type_i = 1
elif filter['type'] == 'TV Show (dated)':
type_i = 2
else:
type_i = 0
self.glade.get_widget('FlexRSS_Filters_Type').set_active(type_i)
selection = self.glade.get_widget('FlexRSS_Filters_Feed').get_selection()
selection.unselect_all()
feed_model = self.glade.get_widget('FlexRSS_Filters_Feed').get_model()
for i in filter['feeds']:
if i == 0:
selection.select_all()
else:
iter = feed_model.get_iter_first()
while iter:
if feed_model.get_value(iter, 0) == i:
selection.select_iter(iter)
iter = feed_model.iter_next(iter)
filter_patterns = self.glade.get_widget('FlexRSS_Filter_Patterns_List')
for child in filter_patterns.get_children():
child.destroy()
for pattern in filter['patterns']:
self.configure_ui_add_pattern(pattern)
def configure_cb_filter_save(self, arg):
# Which feed is selected?
selection = self.glade.get_widget("FlexRSS_Filters_List").get_selection()
model, iter = selection.get_selected()
if not iter:
return
id = model.get_value(iter, 0)
name = self.glade.get_widget('FlexRSS_Filters_Name').get_text()
self.config.setFilter(id, 'name', name)
iter = model.get_iter_first()
while iter:
if model.get_value(iter, 0) == id:
model.set_value(iter, 1, name)
iter = model.iter_next(iter)
type = self.glade.get_widget('FlexRSS_Filters_Type').get_active()
if type == 1:
type_s = 'TV Show'
elif type == 2:
type_s = 'TV Show (dated)'
else:
type_s = 'Generic'
self.config.setFilter(id, 'type', type_s)
model, paths = self.glade.get_widget('FlexRSS_Filters_Feed').get_selection().get_selected_rows()
feeds = []
for path in paths:
feeds.append(model.get_value(model.get_iter(path), 0))
if len(feeds) == 0:
feeds.append(0)
self.config.setFilter(id, 'feeds', feeds)
patterns = []
filter_patterns = self.glade.get_widget('FlexRSS_Filter_Patterns_List')
for i in filter_patterns.get_children():
data = i.get_children()
pattern = data[0].get_text()
if data[2].get_active() == 1:
type = 'Link'
else:
type = 'Title'
patterns.append((pattern, type))
self.config.setFilter(id, 'patterns', patterns)
self.write_config()
def configure_cb_remove_pattern(self, arg):
arg.get_parent().destroy()
def configure_ui_add_pattern(self, pattern):
import gtk, gobject
filter_patterns = self.glade.get_widget('FlexRSS_Filter_Patterns_List')
hbox = gtk.HBox()
filter_patterns.pack_start(hbox)
input = gtk.Entry()
input.set_text(pattern[0])
input.connect("changed", self.configure_cb_test_filter)
on = gtk.Label()
on.set_text('On')
on.show()
combo = gtk.combo_box_new_text()
combo.append_text('Title')
combo.append_text('Link')
if pattern[1] == 'Link':
combo.set_active(1)
else:
combo.set_active(0)
remove = gtk.Button(stock=gtk.STOCK_REMOVE)
remove.connect("pressed", self.configure_cb_remove_pattern)
hbox.pack_start(input)
hbox.pack_start(on, expand=False)
hbox.pack_start(combo, expand=False)
hbox.pack_start(remove, expand=False)
hbox.show_all()
def configure_cb_add_pattern(self, args):
self.configure_ui_add_pattern(('', 'Title'))
def configure_ui_add_filter(self, filter, test_pattern=None):
if not filter:
print 'No filter to add'
return None
model = self.glade.get_widget("FlexRSS_Filters_List").get_model()
iter = model.append(None, (filter['id'], filter['name']))
if not iter:
return
view = self.glade.get_widget("FlexRSS_Filters_List")
model = view.get_model()
view.get_selection().select_iter(iter)
if test_pattern:
self.glade.get_widget('FlexRSS_Filters_Test_Pattern').set_text(test_pattern)
self.configure_cb_test_filter(None)
self.glade.get_widget('FlexRSS_MainNotebook').set_current_page(1)
def configure_ui_test_result(self, result):
if result:
self.glade.get_widget('FlexRSS_Filters_Test_Result').set_text('Match')
else:
self.glade.get_widget('FlexRSS_Filters_Test_Result').set_text('Doesn\'t match')
type = self.glade.get_widget('FlexRSS_Filters_Type').get_active()
if type == 0: # Generic
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow').hide()
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Dated').hide()
elif type == 1: # TV Show
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow').show()
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Dated').hide()
if result:
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Series').set_text(str(result['series']))
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Episode').set_text(str(result['episode']))
else:
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Series').set_text('0')
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Episode').set_text('0')
else: # TV Show (dated)
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow').hide()
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Dated').show()
if result:
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Dated_Year').set_text(str(result['year']))
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Dated_Month').set_text(str(result['month']))
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Dated_Day').set_text(str(result['day']))
else:
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Dated_Year').set_text('0')
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Dated_Month').set_text('0')
self.glade.get_widget('FlexRSS_Filters_Test_Results_TVShow_Dated_Day').set_text('0')
def configure_cb_test_filter(self, filter):
subject = self.glade.get_widget('FlexRSS_Filters_Test_Pattern').get_text()
if len(subject) > 1:
type = self.glade.get_widget('FlexRSS_Filters_Type').get_active()
if type == 1:
type_s = 'TV Show'
elif type == 2:
type_s = 'TV Show (dated)'
else:
type_s = 'Generic'
filter_patterns = self.glade.get_widget('FlexRSS_Filter_Patterns_List')
for i in filter_patterns.get_children():
data = i.get_children()
pattern = data[0].get_text()
if len(pattern):
result = self.test_pattern(type_s, subject, pattern)
if result:
self.configure_ui_test_result(result)
return
self.configure_ui_test_result(False)
def configure_cb_delete_filter(self, arg):
# Which filter is selected?
selection = self.glade.get_widget("FlexRSS_Filters_List").get_selection()
model, iter = selection.get_selected()
if not iter:
return
id = model.get_value(iter, 0)
# Remove from config
if not self.config.deleteFilter(id):
print 'Unable to delete filter #' + str(id)
return
self.write_config()
# Remove from UI
model.remove(iter)
# Fuck it--just leave the crap in the widgets. Todo: fix it so
# the save button will create a new filter if it must.
def configure_cb_feed_refresh(self, caller, id=None):
if not id:
selection = self.glade.get_widget("FlexRSS_Feeds").get_selection()
model, iter = selection.get_selected()
if not iter:
return
id = model.get_value(iter, 0)
if id:
self.parse_feed(id)
def configure_cb_feed_popup(self, view, event):
if event.button != 3:
return
model = view.get_model()
coords = event.get_coords()
path = view.get_path_at_pos(int(coords[0]), int(coords[1]))
if path:
iter = model.get_iter(path[0])
else:
iter = None
import gtk
popup = gtk.Menu()
if iter:
id = model.get_value(iter, 0)
if id: # Feed
item_refresh = gtk.MenuItem("Refresh")
item_refresh.connect("activate", self.configure_cb_feed_refresh, id)
popup.append(item_refresh)
item_delete = gtk.MenuItem("Delete")
item_delete.connect("activate", self.configure_cb_feed_delete, id)
popup.append(item_delete)
else: # Filter
item_filter = gtk.MenuItem("Create filter")
item_filter.connect("activate", self.configure_cb_filter_new, model.get_value(iter, 1))
popup.append(item_filter)
else: # Neither
item_new = gtk.MenuItem("New feed")
item_new.connect("activate", self.configure_cb_feed_new)
popup.append(item_new)
popup.popup(None, None, None, event.button, event.time)
popup.show_all()
def configure(self):
if self.glade: # Dialog already running
return
import gtk, gtk.glade, gobject
self.glade = gtk.glade.XML(self.path + "/FlexRSS.glade")
# Intialize feed lists
feeds_model = gtk.TreeStore(gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING)
feeds_view = self.glade.get_widget("FlexRSS_Feeds")
filters_feeds_view = self.glade.get_widget("FlexRSS_Filters_Feed")
feeds_view.set_model(feeds_model)
filters_feeds_view.set_model(feeds_model)
# Setup columns for feeds tab
renderer_name = gtk.CellRendererText()
column_name = gtk.TreeViewColumn("Name", renderer_name, text=1)
feeds_view.append_column(column_name)
renderer_url = gtk.CellRendererText()
column_url = gtk.TreeViewColumn("URL", renderer_url, text=2)
feeds_view.append_column(column_url)
# Set callback for when selection is changed in feeds tab
# I can't figure out how to do this in Glade
feeds_view.get_selection().connect("changed", self.configure_cb_feed_selected)
# Setup columns for feed list on filters tab
renderer_name = gtk.CellRendererText()
column_name = gtk.TreeViewColumn("Name", renderer_name, text=1)
filters_feeds_view.append_column(column_name)
# Allow multiple selections of feeds in filters tab
# I can't figure out how to do this in Glade
filters_feeds_view.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
# Populate feed lists
if self.config.feeds:
for feed in self.config.feeds:
this_feed = feeds_model.append(None, (feed['id'], feed['name'], feed['url']))
for item in self.feeds[feed['id']]['data']:
feeds_model.append(this_feed, (0, item['title'], item['link']))
# Initialize filters list
filters_model = gtk.TreeStore(gobject.TYPE_INT, gobject.TYPE_STRING)
filters_view = self.glade.get_widget("FlexRSS_Filters_List")
filters_view.set_model(filters_model)
# Setup columns for filters list
renderer_name = gtk.CellRendererText()
column_name = gtk.TreeViewColumn("Name", renderer_name, text=1)
filters_view.append_column(column_name)
# Set callback for when selection is changed in feeds tab
# I can't figure out how to do this in Glade
filters_view.get_selection().connect("changed", self.configure_cb_filter_selected)
# Populate filters list
if self.config.filters:
for filter in self.config.filters:
filters_model.append(None, (filter['id'], filter['name']))
# Callbacks for UI events
actions = { # Feeds tab
"on_FlexRSS_MainWindow_destroy" : self.configure_cb_closed,
"on_FlexRSS_Feeds_New_pressed" : self.configure_cb_feed_new,
"on_FlexRSS_Feeds_Save_pressed" : self.configure_cb_feed_save,
"on_FlexRSS_Feeds_Delete_pressed" : self.configure_cb_feed_delete,
"on_FlexRSS_Feeds_button_press_event" : self.configure_cb_feed_popup,
# Filters tab
"on_FlexRSS_Filters_Add_pressed" : self.configure_cb_filter_new,
"on_FlexRSS_Action_Save_pressed" : self.configure_cb_filter_save,
"on_FlexRSS_Filter_Patern_Add_pressed" : self.configure_cb_add_pattern,
"on_FlexRSS_Filters_Test_Pattern" : self.configure_cb_test_filter,
"on_FlexRSS_Filters_Delete_pressed" : self.configure_cb_delete_filter }
self.glade.signal_autoconnect(actions)
self.glade.get_widget("FlexRSS_MainWindow").show()
def cmp_history(a, b):
try:
if a.has_key('series'):
if a['series'] > b['series']:
return 1
elif a['series'] < b['series']:
return -1
else:
if a['episode'] > b['episode']:
return 1
elif a['episode'] < b['episode']:
return -1
else:
return 0
except:
return 0
def strptime2regex(self, input):
# Does'n exactly live up to its name yet. Currently just
# replaces %y,%Y,%m,%d with named patterns. In the future, it
# would be nice to allow escaping (e.g., %%Y means literal %Y)
# and expand it to support other formats.
patterns = [('%Y', '(?P<Y>[0-9]{4})'),
('%y', '(?P<y>[0-9]{2})'),
('%m', '(?P<m>[0-9]{1,2})'),
('%d', '(?P<d>[0-9]{1,2})')]
out = input
for p in patterns:
out = out.replace(p[0], p[1])
return out
def replace_tv_show_patterns(self, input):
patterns = [('%s', '(?P<series>[0-9]+)'),
('%e', '(?P<episode>[0-9]+)')]
out = input
for p in patterns:
out = out.replace(p[0], p[1])
return out
def test_pattern(self, type, subject, pattern):
import re, time
result = False
if type == 'TV Show (dated)':
pattern = self.strptime2regex(pattern)
elif type == 'TV Show':
pattern = self.replace_tv_show_patterns(pattern)
# Wow, so this is lame...
if pattern[0] != '^':
pattern = '.*' + pattern
try:
exp = re.compile(pattern, re.IGNORECASE)
except:
print 'Broken expression: ' + pattern
return False
match = exp.match(subject)
if match:
print 'Match: ' + subject
print ' ' + pattern
if type == 'TV Show':
try:
series = int(match.group('series'))
except:
try:
series = int(match.group('season'))
except:
series = 0
try:
episode = int(match.group('episode'))
except:
episode = 0
result = { 'series' : series,
'episode' : episode }
elif type == 'TV Show (dated)':
try:
year = int(match.group('Y'))
except:
try:
year = int(match.group('y'))
if year > 70:
year += 1900
else:
year += 2000
except:
year = 0
try:
month = int(match.group('m'))
except:
month = 0
try:
day = int(match.group('d'))
except:
day = 0
result = { 'year' : year,
'month' : month,
'day' : day }
else:
result = True
return result
def parse_feed(self, id):
import time, feedparser
feed = self.config.getFeed(id)
print 'Updating feed #' + str(id)
parsed = feedparser.parse(feed['url'])
if (not parsed) or (not parsed.entries):
print 'Unable to parse feed: ' + feed['url']
return
data = []
for entry in parsed.entries:
try:
data.append({ 'title' : entry['title'],
'link' : entry.links[0]['href'] })
except:
continue
if self.config.filters:
for filter in self.config.filters:
if not ((feed['id'] in filter['feeds']) or (0 in filter['feeds'])):
continue
for pattern in filter['patterns']:
# (setq python-indent 4
# tab-width 4)
# Okay, I dislike python substantially less now.
try:
if pattern[1] == 'Title':
subject = entry['title']
else:
subject = entry['links'][0]['href']
except:
print 'Unable to find subject.'
match = self.test_pattern(filter['type'], subject, pattern[0])
if match:
# Filter matched. Check history to see if
# we should download it.
if filter['type'] == 'Generic': # Dirty hack.
match = { 'url' : entry.links[0]['href'] }
if not self.config.checkHistory(filter['id'], filter['type'], match):
self.config.addHistory(filter['id'], filter['type'], match)
self.write_config()
print 'Downloading'
self.interface.interactive_add_torrent_url(entry.links[0]['href'])
else:
print 'Skipping (history)'
self.feeds[feed['id']]['data'] = data
if self.glade: # Update config window...
# Todo: Fix this. It was just easier to clear
# everything and rebuild from scratch
feeds_model = self.glade.get_widget("FlexRSS_Feeds").get_model()
feeds_model.clear()
for feed in self.config.feeds:
this_feed = feeds_model.append(None, (feed['id'], feed['name'], feed['url']))
for item in self.feeds[feed['id']]['data']:
feeds_model.append(this_feed, (0, item['title'], item['link']))
def update(self):
import time
current_time = time.time()
# I feel dirty for this. Oh, how I miss C.
for id in self.feeds:
if (current_time - self.feeds[id]['cfg']['interval']) > self.feeds[id]['updated']:
self.feeds[id]['updated'] = current_time
self.parse_feed(self.feeds[id]['cfg']['id'])
def __init__(self, path, core, interface):
self.path = path
self.core = core
self.interface = interface
self.load_config()
self.feeds = {}
if self.config.feeds:
for feed in self.config.feeds:
self.feeds[feed['id']] = { 'cfg' : feed,
'updated' : 0,
'data' : [] }
# Debugging stuff
# self.configure()
# self.config.listFilters()
# self.config.listFeeds()