Apply patch from David Mohr to make core.py more 1.2 compatible

This commit is contained in:
Andrew Resch 2009-09-02 22:36:34 +00:00
parent a6ab62f7ce
commit 4e3f4128fa

View File

@ -1,11 +1,12 @@
# #
# core.py # core.py
# #
# Copyright (C) 2009 David Mohr <david@mcbf.net>
# Copyright (C) 2008 Fredrik Eriksson <feeder@winterbird.org> # Copyright (C) 2008 Fredrik Eriksson <feeder@winterbird.org>
# #
# Basic plugin template created by: # Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007, 2008 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # Deluge is free software.
# #
@ -33,25 +34,32 @@
# exception, you may extend this exception to your version of the file(s), # exception, you may extend this exception to your version of the file(s),
# but you are not obligated to do so. If you do not wish to do so, delete # but you are not obligated to do so. If you do not wish to do so, delete
# this exception statement from your version. If you delete this exception # this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#
import feedparser # for parsing rss feeds import feedparser # for parsing rss feeds
import gobject # for the update timer
import threading # for threaded updates import threading # for threaded updates
import re # for regular expressions import re # for regular expressions
import deluge
import string
from deluge.log import LOG as log from deluge.log import LOG as log
from deluge.plugins.corepluginbase import CorePluginBase from deluge.plugins.pluginbase import CorePluginBase
from deluge import component import deluge.component as component
from deluge.plugins.coreclient import client #1.1 and later only import deluge.configmanager
#client: see http://dev.deluge-torrent.org/wiki/Development/UiClient#Remoteapi from deluge.core.rpcserver import export
DEFAULT_PREFS = {
"feeds": {},
"filters": {},
"updatetime": 15,
"history": []
}
# Helper classes
"""Help classes"""
class Feed: class Feed:
"Class for the Feed object (containging feed configurations)" """
Class for the Feed object (containging feed configurations)
"""
def __init__(self): def __init__(self):
self.url = "" self.url = ""
self.updatetime = 15 self.updatetime = 15
@ -63,8 +71,11 @@ class Feed:
self.url = config['url'] self.url = config['url']
self.updatetime = config['updatetime'] self.updatetime = config['updatetime']
class Filter: class Filter:
"Class for the Filter object (containing filter configurations)" """
Class for the Filter object (containing filter configurations)
"""
def __init__(self): def __init__(self):
self.regex = "" self.regex = ""
@ -74,7 +85,7 @@ class Filter:
# by default, set the configuration to match # by default, set the configuration to match
# the per-torrent settings in deluge # the per-torrent settings in deluge
def_conf = client.get_config() def_conf = component.get("Core").get_config()
self.max_download_speed = def_conf['max_download_speed_per_torrent'] self.max_download_speed = def_conf['max_download_speed_per_torrent']
self.max_upload_speed = def_conf['max_upload_speed_per_torrent'] self.max_upload_speed = def_conf['max_upload_speed_per_torrent']
self.max_connections = def_conf['max_connections_per_torrent'] self.max_connections = def_conf['max_connections_per_torrent']
@ -88,7 +99,7 @@ class Filter:
self.remove_at_ratio = def_conf['remove_seed_at_ratio'] self.remove_at_ratio = def_conf['remove_seed_at_ratio']
def get_config(self): def get_config(self):
def_conf = client.get_config() def_conf = component.get("Core").get_config()
try: try:
tmp = self.active tmp = self.active
@ -141,50 +152,208 @@ class Filter:
self.stop_at_ratio = conf['stop_at_ratio'] self.stop_at_ratio = conf['stop_at_ratio']
DEFAULT_PREFS = { class Timer:
"feeds": {}, def Timer(self, curr_time, timeout, callback, data):
"filters": {}, self.timeout = curr_time + timeout
"updatetime": 15, """Timeout is specified in seconds, since it is used by the update() method"""
"history": [] self.callback = callback
} self.data = data
def check_timeout(self, curr_time):
return curr_time == self.timeout
def execute(self):
self.callback(data)
class Core(CorePluginBase): class Core(CorePluginBase):
"""=============enable/disable functions============="""
def enable(self): def enable(self):
#initiate variables
self.config = deluge.configmanager.ConfigManager("feeder.conf", DEFAULT_PREFS) self.config = deluge.configmanager.ConfigManager("feeder.conf", DEFAULT_PREFS)
self.feeds = {} self.feeds = {}
self.timers = {} self.timers = {}
self.history = self.config['history'] self.history = self.config['history']
self.time = 0
# Setting default timer to configured update time # Setting default timer to configured update time
for feed in self.config['feeds']: for feed in self.config['feeds']:
self.timers[feed] = gobject.timeout_add( self.timers[feed] = Timer( self,time,
self.config['feeds'][feed].updatetime * 60 * 1000, self.config['feeds'][feed].updatetime * 60,
self.update_feed, feed ) self.update_feed, feed )
# update all feeds on startup # update all feeds on startup
self.update_feeds() self.update_feeds()
def disable(self): def disable(self):
self.config['history'] = self.history self.config['history'] = self.history
self.config.save() self.config.save()
def update(self):
self.time += 1
for timer in self.timers:
if timer.check_timeout(time):
timer.execute()
"""=============Internal functions============="""
#=================Exported functions==================
@export
def set_config(self, config):
"""sets the config dictionary"""
for key in config.keys():
self.config[key] = config[key]
self.config.save()
####################Configuration Getters##################
@export
def get_config(self):
"""returns the config dictionary"""
return self.config.config
@export
def get_feed_config(self, feedname):
"""Returns configuration for a feed"""
return self.config['feeds'][feedname].get_config()
@export
def get_filter_config(self, filtername):
"""Returns a configuration for a filter"""
return self.config['filters'][filtername].get_config()
####################Information Getters####################
@export
def get_feeds(self):
"""Returns a list of the configured feeds"""
feeds = []
for feedname in self.config['feeds']:
feeds.append(feedname)
feeds.sort(key=string.lower)
return feeds
@export
def get_filters(self):
"""Returns a list of all available filters"""
filters = []
for filter in self.config['filters']:
filters.append(filter)
filters.sort(key=string.lower)
return filters
@export
def get_items(self, feedname):
"""Returns a dictionary with feedname:link"""
try:
items = {}
feed = self.feeds[feedname]
for entry in feed['entries']:
items[entry.title] = entry.link
except Exception, e:
items = {}
log.warning("Feed '%s' not loaded", feedname)
return items
@export
def test_filter(self, regex):
filters = { "to_test":Filter() }
conf = filters["to_test"].get_config()
conf["regex"] = regex
filters["to_test"].set_config(conf)
hits = {}
for feed in self.feeds:
hits.update(self.run_filters(feed, filters, test=True))
return hits
@export
def add_feed(self, config):
"""adds/updates a feed and, for whatever reason, sets the default timeout"""
# save the feedname and remove it from the config
feedname = config['name']
del config['name']
# check if the feed already exists and save config
try:
conf = self.config['feeds'][feedname].get_config()
del self.config['feeds'][feedname]
except Exception, e:
conf = {}
# update configuration
for var in config:
conf[var] = config[var]
# save as default update time
try:
self.config['updatetime'] = config['updatetime']
except Exception, e:
log.warning("updatetime not set when adding feed %s", feedname)
# Create the new feed
newfeed = Feed()
newfeed.set_config(conf)
# Add a timer (with default timer for now, since we can't get ttl just yet)...
self.timers[feedname] = Timer( self.time,
newfeed.updatetime * 60,
self.update_feed, feedname )
# Save the new feed
self.config['feeds'].update({feedname: newfeed })
self.config.save()
# And update the new feed
self.update_feed(feedname)
@export
def remove_feed(self, feedname):
"""Remove a feed"""
if self.feeds.has_key(feedname): # Check if we have the feed saved and remove it
del self.feeds[feedname]
if self.timers.has_key(feedname): # Check if we have a timer for this feed and remove it
del self.timers[feedname]
if self.config['feeds'].has_key(feedname): # Check if we have the feed in the configuration and remove it
del self.config['feeds'][feedname]
self.config.save()
@export
def add_filter(self, name):
"""Adds a new filter to the configuration"""
if not self.config['filters'].has_key(name): # we don't want to add a filter that already exists
self.config['filters'][name] = Filter()
self.config.save()
@export
def set_filter_config(self, filtername, conf):
"""Changes the options for a filter"""
oldconf = self.config['filters'][filtername].get_config()
for item in conf:
oldconf[item] = conf[item]
self.config['filters'][filtername].set_config(oldconf)
self.config.save()
for feed in self.config['feeds']: # we would like to check if the filter now matches something new
self.run_filters(feed)
@export
def remove_filter(self, name):
"""Removes a filter"""
if self.config['filters'].has_key(name): # Can't remove a filter that doesn't exists
del self.config['filters'][name]
self.config.save()
#=================Internal functions================
def update_feeds(self): def update_feeds(self):
"Start threads to update all feeds" """Start threads to update all feeds"""
for feedname in self.config['feeds']: for feedname in self.config['feeds']:
self.update_feed(feedname) self.update_feed(feedname)
def update_feed(self, feedname): def update_feed(self, feedname):
"Start a thread to update a single feed" """Start a thread to update a single feed"""
threading.Thread( threading.Thread(
target=self.update_feed_thread, target=self.update_feed_thread,
args=(self.on_feed_updated, feedname)).start() args=(self.on_feed_updated, feedname)).start()
@ -193,7 +362,7 @@ class Core(CorePluginBase):
return True return True
def update_feed_thread(self, callback, feedname): def update_feed_thread(self, callback, feedname):
"updates a feed" """updates a feed"""
feed = self.config['feeds'][feedname] feed = self.config['feeds'][feedname]
try: try:
self.feeds[feedname] = feedparser.parse(feed.url) self.feeds[feedname] = feedparser.parse(feed.url)
@ -203,7 +372,7 @@ class Core(CorePluginBase):
callback(feedname) callback(feedname)
def on_feed_updated(self, feedname): def on_feed_updated(self, feedname):
"Run stuff when a feed has been updated" """Run stuff when a feed has been updated"""
# Not all feeds contain a ttl value, but if it does # Not all feeds contain a ttl value, but if it does
# we would like to obey it # we would like to obey it
@ -212,7 +381,7 @@ class Core(CorePluginBase):
log.debug("feed '%s' request a ttl of %s, updating timer", feedname, self.feeds[feedname].ttl) log.debug("feed '%s' request a ttl of %s, updating timer", feedname, self.feeds[feedname].ttl)
self.config['feeds'][feedname].updatetime = self.feeds[feedname].ttl self.config['feeds'][feedname].updatetime = self.feeds[feedname].ttl
del self.timers[feedname] del self.timers[feedname]
self.timers[feedname] = gobject.timeout_add( self.timers[feedname] = Timer( self.time,
self.config['feeds'][feedname].updatetime * 60 * 1000, self.config['feeds'][feedname].updatetime * 60 * 1000,
self.update_feed, feedname ) self.update_feed, feedname )
except Exception, e: except Exception, e:
@ -222,7 +391,7 @@ class Core(CorePluginBase):
self.run_filters(feedname) self.run_filters(feedname)
def run_filters(self, feedname, filters={}, test=False): def run_filters(self, feedname, filters={}, test=False):
"Test all available filters on the given feed" """Test all available filters on the given feed"""
if not filters: if not filters:
filters = self.config['filters'] filters = self.config['filters']
log.debug("will test filters %s", filters) log.debug("will test filters %s", filters)
@ -271,7 +440,7 @@ class Core(CorePluginBase):
def test_filter(self, entry, filter): def test_filter(self, entry, filter):
"Tests a filter to a given rss entry" """Tests a filter to a given rss entry"""
f = re.compile(filter, re.IGNORECASE) f = re.compile(filter, re.IGNORECASE)
if f.search(entry.title) or f.search(entry.link): if f.search(entry.title) or f.search(entry.link):
log.debug("RSS item '%s' matches filter '%s'", entry.title, filter) log.debug("RSS item '%s' matches filter '%s'", entry.title, filter)
@ -281,139 +450,4 @@ class Core(CorePluginBase):
def add_torrent(self, url, torrent_options): def add_torrent(self, url, torrent_options):
log.debug("Attempting to add torrent %s", url) log.debug("Attempting to add torrent %s", url)
client.add_torrent_url(url, torrent_options) component.get("Core").add_torrent_url(url, torrent_options)
"""=============Export functions============="""
"""#############Configuration Setters#############"""
def export_add_feed(self, config):
"adds/updates a feed and, for whatever reason, sets the default timeout"
# save the feedname and remove it from the config
feedname = config['name']
del config['name']
# check if the feed already exists and save config
try:
conf = self.config['feeds'][feedname].get_config()
del self.config['feeds'][feedname]
except Exception, e:
conf = {}
# update configuration
for var in config:
conf[var] = config[var]
# save as default update time
try:
self.config['updatetime'] = config['updatetime']
except Exception, e:
log.warning("updatetime not set when adding feed %s", feedname)
# Create the new feed
newfeed = Feed()
newfeed.set_config(conf)
# Add a timer (with default timer for now, since we can't get ttl just yet)...
self.timers[feedname] = gobject.timeout_add(
newfeed.updatetime * 60 * 1000,
self.update_feed, feedname )
# Save the new feed
self.config['feeds'].update({feedname: newfeed })
self.config.save()
# And update the new feed
self.update_feed(feedname)
def export_remove_feed(self, feedname):
"Remove a feed"
if self.feeds.has_key(feedname): # Check if we have the feed saved and remove it
del self.feeds[feedname]
if self.timers.has_key(feedname): # Check if we have a timer for this feed and remove it
del self.timers[feedname]
if self.config['feeds'].has_key(feedname): # Check if we have the feed in the configuration and remove it
del self.config['feeds'][feedname]
self.config.save()
def export_add_filter(self, name):
"Adds a new filter to the configuration"
if not self.config['filters'].has_key(name): # we don't want to add a filter that already exists
self.config['filters'][name] = Filter()
self.config.save()
def export_set_filter_config(self, filtername, conf):
"Changes the options for a filter"
oldconf = self.config['filters'][filtername].get_config()
for item in conf:
oldconf[item] = conf[item]
self.config['filters'][filtername].set_config(oldconf)
self.config.save()
for feed in self.config['feeds']: # we would like to check if the filter now matches something new
self.run_filters(feed)
def export_remove_filter(self, name):
"Removes a filter"
if self.config['filters'].has_key(name): # Can't remove a filter that doesn't exists
del self.config['filters'][name]
self.config.save()
"""#############Configuration Getters#############"""
def export_get_config(self):
"returns the config dictionary"
return self.config.config
def export_get_feed_config(self, feedname):
"Returns configuration for a feed"
return self.config['feeds'][feedname].get_config()
def export_get_filter_config(self, filtername):
"Returns a configuration for a filter"
return self.config['filters'][filtername].get_config()
"""#############Information Getters#############"""
def export_get_feeds(self):
"Returns a list of the configured feeds"
feeds = []
for feedname in self.config['feeds']:
feeds.append(feedname)
feeds.sort(key=string.lower)
return feeds
def export_get_filters(self):
"Returns a list of all available filters"
filters = []
for filter in self.config['filters']:
filters.append(filter)
filters.sort(key=string.lower)
return filters
def export_get_items(self, feedname):
"Returns a dictionary with feedname:link"
try:
items = {}
feed = self.feeds[feedname]
for entry in feed['entries']:
items[entry.title] = entry.link
except Exception, e:
items = {}
log.warning("Feed '%s' not loaded", feedname)
return items
def export_test_filter(self, regex):
filters = { "to_test":Filter() }
conf = filters["to_test"].get_config()
conf["regex"] = regex
filters["to_test"].set_config(conf)
hits = {}
for feed in self.feeds:
hits.update(self.run_filters(feed, filters, test=True))
return hits