Flake8 pass of entire codebase

* Use the inline '# NOQA' to supress N802 lower-case warnings
This commit is contained in:
Calum Lind 2014-09-19 19:10:09 +01:00
parent d0b8e17873
commit 30a0f3c9ed
103 changed files with 1047 additions and 2067 deletions

View File

@ -97,7 +97,7 @@ class _ConfigManager:
_configmanager = _ConfigManager() _configmanager = _ConfigManager()
def ConfigManager(config, defaults=None): def ConfigManager(config, defaults=None): # NOQA
return _configmanager.get_config(config, defaults) return _configmanager.get_config(config, defaults)

View File

@ -115,7 +115,7 @@ def format_request(call):
class ServerContextFactory(object): class ServerContextFactory(object):
def getContext(self): def getContext(self): # NOQA
""" """
Create an SSL context. Create an SSL context.
@ -130,7 +130,6 @@ class ServerContextFactory(object):
class DelugeRPCProtocol(DelugeTransferProtocol): class DelugeRPCProtocol(DelugeTransferProtocol):
def message_received(self, request): def message_received(self, request):
""" """
This method is called whenever a message is received from a client. The This method is called whenever a message is received from a client. The
@ -158,7 +157,7 @@ class DelugeRPCProtocol(DelugeTransferProtocol):
#log.debug("RPCRequest: %s", format_request(call)) #log.debug("RPCRequest: %s", format_request(call))
reactor.callLater(0, self.dispatch, *call) reactor.callLater(0, self.dispatch, *call)
def sendData(self, data): def sendData(self, data): # NOQA
""" """
Sends the data to the client. Sends the data to the client.
@ -169,7 +168,7 @@ class DelugeRPCProtocol(DelugeTransferProtocol):
""" """
self.transfer_message(data) self.transfer_message(data)
def connectionMade(self): def connectionMade(self): # NOQA
""" """
This method is called when a new client connects. This method is called when a new client connects.
""" """
@ -179,7 +178,7 @@ class DelugeRPCProtocol(DelugeTransferProtocol):
# Set the initial auth level of this session to AUTH_LEVEL_NONE # Set the initial auth level of this session to AUTH_LEVEL_NONE
self.factory.authorized_sessions[self.transport.sessionno] = AUTH_LEVEL_NONE self.factory.authorized_sessions[self.transport.sessionno] = AUTH_LEVEL_NONE
def connectionLost(self, reason): def connectionLost(self, reason): # NOQA
""" """
This method is called when the client is disconnected. This method is called when the client is disconnected.

View File

@ -49,11 +49,11 @@ class HTTPDownloader(client.HTTPDownloader):
agent = "Deluge/%s (http://deluge-torrent.org)" % get_version() agent = "Deluge/%s (http://deluge-torrent.org)" % get_version()
client.HTTPDownloader.__init__(self, url, filename, headers=headers, agent=agent) client.HTTPDownloader.__init__(self, url, filename, headers=headers, agent=agent)
def gotStatus(self, version, status, message): def gotStatus(self, version, status, message): # NOQA
self.code = int(status) self.code = int(status)
client.HTTPDownloader.gotStatus(self, version, status, message) client.HTTPDownloader.gotStatus(self, version, status, message)
def gotHeaders(self, headers): def gotHeaders(self, headers): # NOQA
if self.code == http.OK: if self.code == http.OK:
if "content-length" in headers: if "content-length" in headers:
self.total_length = int(headers["content-length"][0]) self.total_length = int(headers["content-length"][0])
@ -89,7 +89,7 @@ class HTTPDownloader(client.HTTPDownloader):
return client.HTTPDownloader.gotHeaders(self, headers) return client.HTTPDownloader.gotHeaders(self, headers)
def pagePart(self, data): def pagePart(self, data): # NOQA
if self.code == http.OK: if self.code == http.OK:
self.current_length += len(data) self.current_length += len(data)
if self.decoder: if self.decoder:
@ -99,7 +99,7 @@ class HTTPDownloader(client.HTTPDownloader):
return client.HTTPDownloader.pagePart(self, data) return client.HTTPDownloader.pagePart(self, data)
def pageEnd(self): def pageEnd(self): # NOQA
if self.decoder: if self.decoder:
data = self.decoder.flush() data = self.decoder.flush()
self.current_length -= len(data) self.current_length -= len(data)

View File

@ -19,7 +19,7 @@ from twisted.python.log import PythonLoggingObserver
from deluge import common from deluge import common
__all__ = ["setupLogger", "setLoggerLevel", "getPluginLogger", "LOG"] __all__ = ["setup_logger", "set_logger_level", "get_plugin_logger", "LOG"]
LoggingLoggerClass = logging.getLoggerClass() LoggingLoggerClass = logging.getLoggerClass()
@ -79,7 +79,7 @@ class Logging(LoggingLoggerClass):
def exception(self, msg, *args, **kwargs): def exception(self, msg, *args, **kwargs):
yield LoggingLoggerClass.exception(self, msg, *args, **kwargs) yield LoggingLoggerClass.exception(self, msg, *args, **kwargs)
def findCaller(self): def find_caller(self):
f = logging.currentframe().f_back f = logging.currentframe().f_back
rv = "(unknown file)", 0, "(unknown function)" rv = "(unknown file)", 0, "(unknown function)"
while hasattr(f, "f_code"): while hasattr(f, "f_code"):
@ -106,7 +106,7 @@ levels = {
} }
def setupLogger(level="error", filename=None, filemode="w"): def setup_logger(level="error", filename=None, filemode="w"):
""" """
Sets up the basic logger and if `:param:filename` is set, then it will log Sets up the basic logger and if `:param:filename` is set, then it will log
to that file instead of stdout. to that file instead of stdout.
@ -192,10 +192,10 @@ def tweak_logging_levels():
continue continue
log.warn("Setting logger \"%s\" to logging level \"%s\"", name, level) log.warn("Setting logger \"%s\" to logging level \"%s\"", name, level)
setLoggerLevel(level, name) set_logger_level(level, name)
def setLoggerLevel(level, logger_name=None): def set_logger_level(level, logger_name=None):
""" """
Sets the logger level. Sets the logger level.
@ -208,7 +208,7 @@ def setLoggerLevel(level, logger_name=None):
logging.getLogger(logger_name).setLevel(levels.get(level, "error")) logging.getLogger(logger_name).setLevel(levels.get(level, "error"))
def getPluginLogger(logger_name): def get_plugin_logger(logger_name):
import warnings import warnings
stack = inspect.stack() stack = inspect.stack()
stack.pop(0) # The logging call from this module stack.pop(0) # The logging call from this module
@ -229,10 +229,10 @@ DEPRECATION_WARNING = """You seem to be using old style logging on your code, ie
from deluge.log import LOG as log from deluge.log import LOG as log
or: or:
from deluge.log import getPluginLogger from deluge.log import get_plugin_logger
This has been deprecated in favour of an enhanced logging system and both "LOG" This has been deprecated in favour of an enhanced logging system and both "LOG"
and "getPluginLogger" will be removed on the next major version release of Deluge, and "get_plugin_logger" will be removed on the next major version release of Deluge,
meaning, code will break, specially plugins. meaning, code will break, specially plugins.
If you're seeing this message and you're not the developer of the plugin which If you're seeing this message and you're not the developer of the plugin which
triggered this warning, please report to it's author. triggered this warning, please report to it's author.

View File

@ -24,7 +24,7 @@ from optparse import OptionParser
import deluge.common import deluge.common
import deluge.configmanager import deluge.configmanager
import deluge.error import deluge.error
from deluge.log import setupLogger from deluge.log import setup_logger
def version_callback(option, opt_str, value, parser): def version_callback(option, opt_str, value, parser):
@ -74,7 +74,7 @@ def start_ui():
logfile_mode = 'w' logfile_mode = 'w'
if options.rotate_logs: if options.rotate_logs:
logfile_mode = 'a' logfile_mode = 'a'
setupLogger(level=options.loglevel, filename=options.logfile, filemode=logfile_mode) setup_logger(level=options.loglevel, filename=options.logfile, filemode=logfile_mode)
log = getLogger(__name__) log = getLogger(__name__)
if options.config: if options.config:
@ -181,7 +181,7 @@ def start_daemon():
logfile_mode = 'w' logfile_mode = 'w'
if options.rotate_logs: if options.rotate_logs:
logfile_mode = 'a' logfile_mode = 'a'
setupLogger(level=options.loglevel, filename=options.logfile, filemode=logfile_mode) setup_logger(level=options.loglevel, filename=options.logfile, filemode=logfile_mode)
log = getLogger(__name__) log = getLogger(__name__)
# If no logfile specified add logging to default location (as well as stdout) # If no logfile specified add logging to default location (as well as stdout)

View File

@ -17,20 +17,20 @@ from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls from .webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -100,7 +100,7 @@ class Core(CorePluginBase):
def enable_looping(self): def enable_looping(self):
# Enable all looping calls for enabled watchdirs here # Enable all looping calls for enabled watchdirs here
for watchdir_id, watchdir in self.watchdirs.iteritems(): for watchdir_id, watchdir in self.watchdirs.iteritems():
if watchdir['enabled']: if watchdir["enabled"]:
self.enable_watchdir(watchdir_id) self.enable_watchdir(watchdir_id)
def disable(self): def disable(self):
@ -124,16 +124,16 @@ class Core(CorePluginBase):
watchdir_id in self.watchdirs, _("Watch folder does not exist.") watchdir_id in self.watchdirs, _("Watch folder does not exist.")
) )
if "path" in options: if "path" in options:
options['abspath'] = os.path.abspath(options['path']) options["abspath"] = os.path.abspath(options["path"])
check_input( check_input(
os.path.isdir(options['abspath']), _("Path does not exist.") os.path.isdir(options["abspath"]), _("Path does not exist.")
) )
for w_id, w in self.watchdirs.iteritems(): for w_id, w in self.watchdirs.iteritems():
if options['abspath'] == w['abspath'] and watchdir_id != w_id: if options["abspath"] == w["abspath"] and watchdir_id != w_id:
raise Exception("Path is already being watched.") raise Exception("Path is already being watched.")
for key in options.keys(): for key in options.keys():
if key not in OPTIONS_AVAILABLE: if key not in OPTIONS_AVAILABLE:
if key not in [key2+'_toggle' for key2 in OPTIONS_AVAILABLE.iterkeys()]: if key not in [key2 + "_toggle" for key2 in OPTIONS_AVAILABLE.iterkeys()]:
raise Exception("autoadd: Invalid options key:%s" % key) raise Exception("autoadd: Invalid options key:%s" % key)
#disable the watch loop if it was active #disable the watch loop if it was active
if watchdir_id in self.update_timers: if watchdir_id in self.update_timers:
@ -141,7 +141,7 @@ class Core(CorePluginBase):
self.watchdirs[watchdir_id].update(options) self.watchdirs[watchdir_id].update(options)
#re-enable watch loop if appropriate #re-enable watch loop if appropriate
if self.watchdirs[watchdir_id]['enabled']: if self.watchdirs[watchdir_id]["enabled"]:
self.enable_watchdir(watchdir_id) self.enable_watchdir(watchdir_id)
self.config.save() self.config.save()
component.get("EventManager").emit(AutoaddOptionsChangedEvent()) component.get("EventManager").emit(AutoaddOptionsChangedEvent())
@ -160,7 +160,7 @@ class Core(CorePluginBase):
_file.close() _file.close()
except IOError as ex: except IOError as ex:
log.warning("Unable to open %s: %s", filename, ex) log.warning("Unable to open %s: %s", filename, ex)
raise e raise ex
# Get the info to see if any exceptions are raised # Get the info to see if any exceptions are raised
if not magnet: if not magnet:
@ -174,7 +174,7 @@ class Core(CorePluginBase):
_file = open(filename, "r") _file = open(filename, "r")
except IOError as ex: except IOError as ex:
log.warning("Unable to open %s: %s", filename, ex) log.warning("Unable to open %s: %s", filename, ex)
raise e raise ex
else: else:
magnets = list(filter(len, _file.readlines())) magnets = list(filter(len, _file.readlines()))
_file.close() _file.close()
@ -183,12 +183,12 @@ class Core(CorePluginBase):
n = 0 n = 0
path = filename.rsplit(os.sep, 1)[0] path = filename.rsplit(os.sep, 1)[0]
for magnet in magnets: for magnet in magnets:
for part in magnet.split('&'): for part in magnet.split("&"):
if part.startswith("dn="): if part.startswith("dn="):
mname = os.sep.join([path, part[3:] + ".magnet"]) mname = os.sep.join([path, part[3:] + ".magnet"])
break break
else: else:
mname = '.'.join([filename, str(n), "magnet"]) mname = ".".join([filename, str(n), "magnet"])
n += 1 n += 1
try: try:
_mfile = open(mname, "w") _mfile = open(mname, "w")
@ -204,7 +204,7 @@ class Core(CorePluginBase):
log.trace("Updating watchdir id: %s", watchdir_id) log.trace("Updating watchdir id: %s", watchdir_id)
watchdir_id = str(watchdir_id) watchdir_id = str(watchdir_id)
watchdir = self.watchdirs[watchdir_id] watchdir = self.watchdirs[watchdir_id]
if not watchdir['enabled']: if not watchdir["enabled"]:
# We shouldn't be updating because this watchdir is not enabled # We shouldn't be updating because this watchdir is not enabled
log.debug("Watchdir id %s is not enabled. Disabling it.", log.debug("Watchdir id %s is not enabled. Disabling it.",
watchdir_id) watchdir_id)
@ -218,13 +218,13 @@ class Core(CorePluginBase):
# Generate options dict for watchdir # Generate options dict for watchdir
opts = {} opts = {}
if 'stop_at_ratio_toggle' in watchdir: if "stop_at_ratio_toggle" in watchdir:
watchdir['stop_ratio_toggle'] = watchdir['stop_at_ratio_toggle'] watchdir["stop_ratio_toggle"] = watchdir["stop_at_ratio_toggle"]
# We default to True when reading _toggle values, so a config # We default to True when reading _toggle values, so a config
# without them is valid, and applies all its settings. # without them is valid, and applies all its settings.
for option, value in watchdir.iteritems(): for option, value in watchdir.iteritems():
if OPTIONS_AVAILABLE.get(option): if OPTIONS_AVAILABLE.get(option):
if watchdir.get(option+'_toggle', True) or option in ["owner", "seed_mode"]: if watchdir.get(option + "_toggle", True) or option in ["owner", "seed_mode"]:
opts[option] = value opts[option] = value
# Check for .magnet files containing multiple magnet links and # Check for .magnet files containing multiple magnet links and
@ -287,14 +287,14 @@ class Core(CorePluginBase):
# If the torrent added successfully, set the extra options. # If the torrent added successfully, set the extra options.
if torrent_id: if torrent_id:
if 'Label' in component.get("CorePluginManager").get_enabled_plugins(): if "Label" in component.get("CorePluginManager").get_enabled_plugins():
if watchdir.get('label_toggle', True) and watchdir.get('label'): if watchdir.get("label_toggle", True) and watchdir.get("label"):
label = component.get("CorePlugin.Label") label = component.get("CorePlugin.Label")
if not watchdir['label'] in label.get_labels(): if not watchdir["label"] in label.get_labels():
label.add(watchdir['label']) label.add(watchdir["label"])
label.set_torrent(torrent_id, watchdir['label']) label.set_torrent(torrent_id, watchdir["label"])
if watchdir.get('queue_to_top_toggle', True) and 'queue_to_top' in watchdir: if watchdir.get("queue_to_top_toggle", True) and "queue_to_top" in watchdir:
if watchdir['queue_to_top']: if watchdir["queue_to_top"]:
component.get("TorrentManager").queue_top(torrent_id) component.get("TorrentManager").queue_top(torrent_id)
else: else:
component.get("TorrentManager").queue_bottom(torrent_id) component.get("TorrentManager").queue_bottom(torrent_id)
@ -306,12 +306,12 @@ class Core(CorePluginBase):
continue continue
# Rename, copy or delete the torrent once added to deluge. # Rename, copy or delete the torrent once added to deluge.
if watchdir.get('append_extension_toggle'): if watchdir.get("append_extension_toggle"):
if not watchdir.get('append_extension'): if not watchdir.get("append_extension"):
watchdir['append_extension'] = ".added" watchdir["append_extension"] = ".added"
os.rename(filepath, filepath + watchdir['append_extension']) os.rename(filepath, filepath + watchdir["append_extension"])
elif watchdir.get('copy_torrent_toggle'): elif watchdir.get("copy_torrent_toggle"):
copy_torrent_path = watchdir['copy_torrent'] copy_torrent_path = watchdir["copy_torrent"]
copy_torrent_file = os.path.join(copy_torrent_path, filename) copy_torrent_file = os.path.join(copy_torrent_path, filename)
log.debug("Moving added torrent file \"%s\" to \"%s\"", log.debug("Moving added torrent file \"%s\" to \"%s\"",
os.path.basename(filepath), copy_torrent_path) os.path.basename(filepath), copy_torrent_path)
@ -336,8 +336,8 @@ class Core(CorePluginBase):
self.on_update_watchdir_error, w_id self.on_update_watchdir_error, w_id
) )
# Update the config # Update the config
if not self.watchdirs[w_id]['enabled']: if not self.watchdirs[w_id]["enabled"]:
self.watchdirs[w_id]['enabled'] = True self.watchdirs[w_id]["enabled"] = True
self.config.save() self.config.save()
component.get("EventManager").emit(AutoaddOptionsChangedEvent()) component.get("EventManager").emit(AutoaddOptionsChangedEvent())
@ -350,8 +350,8 @@ class Core(CorePluginBase):
self.update_timers[w_id].stop() self.update_timers[w_id].stop()
del self.update_timers[w_id] del self.update_timers[w_id]
# Update the config # Update the config
if self.watchdirs[w_id]['enabled']: if self.watchdirs[w_id]["enabled"]:
self.watchdirs[w_id]['enabled'] = False self.watchdirs[w_id]["enabled"] = False
self.config.save() self.config.save()
component.get("EventManager").emit(AutoaddOptionsChangedEvent()) component.get("EventManager").emit(AutoaddOptionsChangedEvent())
@ -400,21 +400,21 @@ class Core(CorePluginBase):
def add(self, options={}): def add(self, options={}):
"""Add a watch folder.""" """Add a watch folder."""
options = self._make_unicode(options) options = self._make_unicode(options)
abswatchdir = os.path.abspath(options['path']) abswatchdir = os.path.abspath(options["path"])
check_input(os.path.isdir(abswatchdir), _("Path does not exist.")) check_input(os.path.isdir(abswatchdir), _("Path does not exist."))
check_input( check_input(
os.access(abswatchdir, os.R_OK | os.W_OK), os.access(abswatchdir, os.R_OK | os.W_OK),
"You must have read and write access to watch folder." "You must have read and write access to watch folder."
) )
if abswatchdir in [wd['abspath'] for wd in self.watchdirs.itervalues()]: if abswatchdir in [wd["abspath"] for wd in self.watchdirs.itervalues()]:
raise Exception("Path is already being watched.") raise Exception("Path is already being watched.")
options.setdefault('enabled', False) options.setdefault("enabled", False)
options['abspath'] = abswatchdir options["abspath"] = abswatchdir
watchdir_id = self.config['next_id'] watchdir_id = self.config["next_id"]
self.watchdirs[str(watchdir_id)] = options self.watchdirs[str(watchdir_id)] = options
if options.get('enabled'): if options.get("enabled"):
self.enable_watchdir(watchdir_id) self.enable_watchdir(watchdir_id)
self.config['next_id'] = watchdir_id + 1 self.config["next_id"] = watchdir_id + 1
self.config.save() self.config.save()
component.get("EventManager").emit(AutoaddOptionsChangedEvent()) component.get("EventManager").emit(AutoaddOptionsChangedEvent())
return watchdir_id return watchdir_id
@ -424,15 +424,15 @@ class Core(CorePluginBase):
"""Remove a watch folder.""" """Remove a watch folder."""
watchdir_id = str(watchdir_id) watchdir_id = str(watchdir_id)
check_input(watchdir_id in self.watchdirs, "Unknown Watchdir: %s" % self.watchdirs) check_input(watchdir_id in self.watchdirs, "Unknown Watchdir: %s" % self.watchdirs)
if self.watchdirs[watchdir_id]['enabled']: if self.watchdirs[watchdir_id]["enabled"]:
self.disable_watchdir(watchdir_id) self.disable_watchdir(watchdir_id)
del self.watchdirs[watchdir_id] del self.watchdirs[watchdir_id]
self.config.save() self.config.save()
component.get("EventManager").emit(AutoaddOptionsChangedEvent()) component.get("EventManager").emit(AutoaddOptionsChangedEvent())
def __migrate_config_1_to_2(self, config): def __migrate_config_1_to_2(self, config):
for watchdir_id in config['watchdirs'].iterkeys(): for watchdir_id in config["watchdirs"].iterkeys():
config['watchdirs'][watchdir_id]['owner'] = 'localclient' config["watchdirs"][watchdir_id]["owner"] = "localclient"
return config return config
def __on_pre_torrent_removed(self, torrent_id): def __on_pre_torrent_removed(self, torrent_id):
@ -445,13 +445,13 @@ class Core(CorePluginBase):
return return
torrent_fname = torrent.filename torrent_fname = torrent.filename
for watchdir in self.watchdirs.itervalues(): for watchdir in self.watchdirs.itervalues():
if not watchdir.get('copy_torrent_toggle', False): if not watchdir.get("copy_torrent_toggle", False):
# This watchlist does copy torrents # This watchlist does copy torrents
continue continue
elif not watchdir.get('delete_copy_torrent_toggle', False): elif not watchdir.get("delete_copy_torrent_toggle", False):
# This watchlist is not set to delete finished torrents # This watchlist is not set to delete finished torrents
continue continue
copy_torrent_path = watchdir['copy_torrent'] copy_torrent_path = watchdir["copy_torrent"]
torrent_fname_path = os.path.join(copy_torrent_path, torrent_fname) torrent_fname_path = os.path.join(copy_torrent_path, torrent_fname)
if os.path.isfile(torrent_fname_path): if os.path.isfile(torrent_fname_path):
try: try:

View File

@ -106,10 +106,10 @@ class OptionsDialog():
for id in self.spin_ids + self.spin_int_ids: for id in self.spin_ids + self.spin_int_ids:
self.glade.get_widget(id).set_value(options.get(id, 0)) self.glade.get_widget(id).set_value(options.get(id, 0))
self.glade.get_widget(id+'_toggle').set_active(options.get(id+'_toggle', False)) self.glade.get_widget(id + "_toggle").set_active(options.get(id + "_toggle", False))
for id in self.chk_ids: for id in self.chk_ids:
self.glade.get_widget(id).set_active(bool(options.get(id, True))) self.glade.get_widget(id).set_active(bool(options.get(id, True)))
self.glade.get_widget(id+'_toggle').set_active(options.get(id+'_toggle', False)) self.glade.get_widget(id + "_toggle").set_active(options.get(id + "_toggle", False))
if not options.get('add_paused', True): if not options.get('add_paused', True):
self.glade.get_widget('isnt_add_paused').set_active(True) self.glade.get_widget('isnt_add_paused').set_active(True)
if not options.get('queue_to_top', True): if not options.get('queue_to_top', True):
@ -119,17 +119,17 @@ class OptionsDialog():
for field in ['move_completed_path', 'path', 'download_location', for field in ['move_completed_path', 'path', 'download_location',
'copy_torrent']: 'copy_torrent']:
if client.is_localhost(): if client.is_localhost():
self.glade.get_widget(field+"_chooser").set_current_folder( self.glade.get_widget(field + "_chooser").set_current_folder(
options.get(field, os.path.expanduser("~")) options.get(field, os.path.expanduser("~"))
) )
self.glade.get_widget(field+"_chooser").show() self.glade.get_widget(field + "_chooser").show()
self.glade.get_widget(field+"_entry").hide() self.glade.get_widget(field + "_entry").hide()
else: else:
self.glade.get_widget(field+"_entry").set_text( self.glade.get_widget(field + "_entry").set_text(
options.get(field, "") options.get(field, "")
) )
self.glade.get_widget(field+"_entry").show() self.glade.get_widget(field + "_entry").show()
self.glade.get_widget(field+"_chooser").hide() self.glade.get_widget(field + "_chooser").hide()
self.set_sensitive() self.set_sensitive()
def on_core_config(config): def on_core_config(config):
@ -225,7 +225,7 @@ class OptionsDialog():
'max_upload_speed', 'max_connections', 'max_upload_speed', 'max_connections',
'max_upload_slots', 'add_paused', 'auto_managed', 'max_upload_slots', 'add_paused', 'auto_managed',
'stop_at_ratio', 'queue_to_top', 'copy_torrent'] 'stop_at_ratio', 'queue_to_top', 'copy_torrent']
[self.on_toggle_toggled(self.glade.get_widget(x+'_toggle')) for x in maintoggles] [self.on_toggle_toggled(self.glade.get_widget(x + "_toggle")) for x in maintoggles]
def on_toggle_toggled(self, tb): def on_toggle_toggled(self, tb):
toggle = str(tb.name).replace("_toggle", "") toggle = str(tb.name).replace("_toggle", "")
@ -329,13 +329,13 @@ class OptionsDialog():
for id in self.spin_ids: for id in self.spin_ids:
options[id] = self.glade.get_widget(id).get_value() options[id] = self.glade.get_widget(id).get_value()
options[id+'_toggle'] = self.glade.get_widget(id+'_toggle').get_active() options[id + "_toggle"] = self.glade.get_widget(id + "_toggle").get_active()
for id in self.spin_int_ids: for id in self.spin_int_ids:
options[id] = self.glade.get_widget(id).get_value_as_int() options[id] = self.glade.get_widget(id).get_value_as_int()
options[id+'_toggle'] = self.glade.get_widget(id+'_toggle').get_active() options[id + "_toggle"] = self.glade.get_widget(id + "_toggle").get_active()
for id in self.chk_ids: for id in self.chk_ids:
options[id] = self.glade.get_widget(id).get_active() options[id] = self.glade.get_widget(id).get_active()
options[id+'_toggle'] = self.glade.get_widget(id+'_toggle').get_active() options[id + "_toggle"] = self.glade.get_widget(id + "_toggle").get_active()
if options['copy_torrent_toggle'] and options['path'] == options['copy_torrent']: if options['copy_torrent_toggle'] and options['path'] == options['copy_torrent']:
raise IncompatibleOption(_("\"Watch Folder\" directory and \"Copy of .torrent" raise IncompatibleOption(_("\"Watch Folder\" directory and \"Copy of .torrent"

View File

@ -23,7 +23,7 @@ __url__ = "http://dev.deluge-torrent.org/wiki/Plugins/AutoAdd"
__license__ = "GPLv3" __license__ = "GPLv3"
__description__ = "Monitors folders for .torrent files." __description__ = "Monitors folders for .torrent files."
__long_description__ = """""" __long_description__ = """"""
__pkg_data__ = {'deluge.plugins.'+__plugin_name__.lower(): ["template/*", "data/*"]} __pkg_data__ = {'deluge.plugins.' + __plugin_name__.lower(): ["template/*", "data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -45,5 +45,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web] [deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin %s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3) """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
) )

View File

@ -12,20 +12,20 @@ from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls from .webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -12,7 +12,7 @@ import gzip
import zipfile import zipfile
def Zipped(reader): def Zipped(reader): # NOQA
"""Blocklist reader for zipped blocklists""" """Blocklist reader for zipped blocklists"""
def open(self): def open(self):
z = zipfile.ZipFile(self.file) z = zipfile.ZipFile(self.file)
@ -27,7 +27,7 @@ def Zipped(reader):
return reader return reader
def GZipped(reader): def GZipped(reader): # NOQA
"""Blocklist reader for gzipped blocklists""" """Blocklist reader for gzipped blocklists"""
def open(self): def open(self):
return gzip.open(self.file) return gzip.open(self.file)
@ -35,7 +35,7 @@ def GZipped(reader):
return reader return reader
def BZipped2(reader): def BZipped2(reader): # NOQA
"""Blocklist reader for bzipped2 blocklists""" """Blocklist reader for bzipped2 blocklists"""
def open(self): def open(self):
return bz2.BZ2File(self.file) return bz2.BZ2File(self.file)

View File

@ -17,7 +17,7 @@ __url__ = "http://deluge-torrent.org"
__license__ = "GPLv3" __license__ = "GPLv3"
__description__ = "Download and import IP blocklists" __description__ = "Download and import IP blocklists"
__long_description__ = __description__ __long_description__ = __description__
__pkg_data__ = {'deluge.plugins.'+__plugin_name__.lower(): ["data/*"]} __pkg_data__ = {'deluge.plugins.' + __plugin_name__.lower(): ["data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -39,5 +39,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web] [deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin %s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3) """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
) )

View File

@ -1,54 +1,31 @@
# # -*- coding: utf-8 -*-
# __init__.py
# #
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#
# #
from deluge.plugins.init import PluginInitBase from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls from .webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -1,36 +1,10 @@
# # -*- coding: utf-8 -*-
# common.py
# #
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 os.path import os.path

View File

@ -1,36 +1,10 @@
# # -*- coding: utf-8 -*-
# core.py
# #
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 hashlib import hashlib
@ -110,7 +84,7 @@ class Core(CorePluginBase):
torrent = component.get("TorrentManager").torrents[torrent_id] torrent = component.get("TorrentManager").torrents[torrent_id]
info = torrent.get_status(["name", "download_location"]) info = torrent.get_status(["name", "download_location"])
self.preremoved_cache[torrent_id] = [utf8_encoded(torrent_id), utf8_encoded(info["name"]), self.preremoved_cache[torrent_id] = [utf8_encoded(torrent_id), utf8_encoded(info["name"]),
utf8_encoded(info["download_location"])] utf8_encoded(info["download_location"])]
def execute_commands(self, torrent_id, event, *arg): def execute_commands(self, torrent_id, event, *arg):
if event == "added" and arg[0]: if event == "added" and arg[0]:

View File

@ -1,36 +1,10 @@
# # -*- coding: utf-8 -*-
# gtkui.py
# #
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
@ -60,6 +34,7 @@ EVENT_MAP = {
EVENTS = ["complete", "added", "removed"] EVENTS = ["complete", "added", "removed"]
class ExecutePreferences(object): class ExecutePreferences(object):
def __init__(self, plugin): def __init__(self, plugin):
self.plugin = plugin self.plugin = plugin
@ -80,8 +55,7 @@ class ExecutePreferences(object):
events.set_model(store) events.set_model(store)
events.set_active(0) events.set_active(0)
self.plugin.add_preferences_page(_("Execute"), self.plugin.add_preferences_page(_("Execute"), self.glade.get_widget("execute_box"))
self.glade.get_widget("execute_box"))
self.plugin.register_hook("on_show_prefs", self.load_commands) self.plugin.register_hook("on_show_prefs", self.load_commands)
self.plugin.register_hook("on_apply_prefs", self.on_apply_prefs) self.plugin.register_hook("on_apply_prefs", self.on_apply_prefs)
@ -169,6 +143,7 @@ class ExecutePreferences(object):
log.debug("Removing command %s", command_id) log.debug("Removing command %s", command_id)
self.remove_command(command_id) self.remove_command(command_id)
class GtkUI(GtkPluginBase): class GtkUI(GtkPluginBase):
def enable(self): def enable(self):

View File

@ -1,49 +1,21 @@
# # -*- coding: utf-8 -*-
# webui.py
# #
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource from .common import get_resource
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class WebUI(WebPluginBase): class WebUI(WebPluginBase):
scripts = [get_resource("execute.js")] scripts = [get_resource("execute.js")]

View File

@ -41,7 +41,7 @@ __url__ = "http://deluge-torrent.org"
__license__ = "GPLv3" __license__ = "GPLv3"
__description__ = "Plugin to execute a command upon an event" __description__ = "Plugin to execute a command upon an event"
__long_description__ = __description__ __long_description__ = __description__
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["data/*"]} __pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -54,8 +54,8 @@ setup(
long_description=__long_description__, long_description=__long_description__,
packages=find_packages(), packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"], namespace_packages=["deluge", "deluge.plugins"],
package_data = __pkg_data__, package_data=__pkg_data__,
entry_points=""" entry_points="""
[deluge.plugin.core] [deluge.plugin.core]
@ -64,5 +64,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web] [deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin %s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3) """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
) )

View File

@ -16,20 +16,20 @@ from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls from .webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -30,7 +30,7 @@ Windows support: .rar, .zip, .tar, .7z, .xz, .lzma
Note: Will not extract with 'Move Completed' enabled Note: Will not extract with 'Move Completed' enabled
""" """
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]} __pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -53,5 +53,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web] [deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin %s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3) """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
) )

View File

@ -1,54 +1,35 @@
# # -*- coding: utf-8 -*-
# __init__.py
# #
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# Deluge is free software. # Basic plugin template created by:
# # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# You may redistribute it and/or modify it under the terms of the # Copyright (C) 2007-2008 Andrew Resch <andrewresch@gmail.com>
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
from deluge.plugins.init import PluginInitBase from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls from .webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -1,36 +1,15 @@
# -*- coding: utf-8 -*-
# #
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# Deluge is free software. # Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2008 Andrew Resch <andrewresch@gmail.com>
# #
# You may redistribute it and/or modify it under the terms of the # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# GNU General Public License, as published by the Free Software # the additional special exception to link portions of this program with the OpenSSL library.
# Foundation; either version 3 of the License, or (at your option) # See LICENSE for more details.
# any later version.
# #
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#
#
""" """
torrent-label core plugin. torrent-label core plugin.
@ -39,8 +18,6 @@ adds a status field for tracker.
import logging import logging
import re import re
import traceback
from urlparse import urlparse
import deluge.component as component import deluge.component as component
from deluge.configmanager import ConfigManager from deluge.configmanager import ConfigManager
@ -57,35 +34,35 @@ TRACKER = "tracker"
KEYWORD = "keyword" KEYWORD = "keyword"
LABEL = "label" LABEL = "label"
CONFIG_DEFAULTS = { CONFIG_DEFAULTS = {
"torrent_labels": {}, #torrent_id:label_id "torrent_labels": {}, # torrent_id:label_id
"labels": {}, #label_id:{name:value} "labels": {}, # label_id:{name:value}
} }
CORE_OPTIONS = ["auto_add_trackers"] CORE_OPTIONS = ["auto_add_trackers"]
OPTIONS_DEFAULTS = { OPTIONS_DEFAULTS = {
"apply_max":False, "apply_max": False,
"max_download_speed":-1, "max_download_speed": -1,
"max_upload_speed":-1, "max_upload_speed": -1,
"max_connections":-1, "max_connections": -1,
"max_upload_slots":-1, "max_upload_slots": -1,
"prioritize_first_last":False, "prioritize_first_last": False,
"apply_queue":False, "apply_queue": False,
"is_auto_managed":False, "is_auto_managed": False,
"stop_at_ratio":False, "stop_at_ratio": False,
"stop_ratio":2.0, "stop_ratio": 2.0,
"remove_at_ratio":False, "remove_at_ratio": False,
"apply_move_completed":False, "apply_move_completed": False,
"move_completed":False, "move_completed": False,
"move_completed_path":"", "move_completed_path": "",
"auto_add":False, "auto_add": False,
"auto_add_trackers":[] "auto_add_trackers": []
} }
NO_LABEL = "No Label" NO_LABEL = "No Label"
def CheckInput(cond, message): def check_input(cond, message):
if not cond: if not cond:
raise Exception(message) raise Exception(message)
@ -173,7 +150,7 @@ class Core(CorePluginBase):
for label, options in self.labels.items(): for label, options in self.labels.items():
for key, value in options.items(): for key, value in options.items():
if value == None: if value is None:
self.labels[label][key] = OPTIONS_DEFAULTS[key] self.labels[label][key] = OPTIONS_DEFAULTS[key]
def save_config(self): def save_config(self):
@ -191,9 +168,9 @@ class Core(CorePluginBase):
see label_set_options for more options. see label_set_options for more options.
""" """
label_id = label_id.lower() label_id = label_id.lower()
CheckInput(RE_VALID.match(label_id), _("Invalid label, valid characters:[a-z0-9_-]")) check_input(RE_VALID.match(label_id), _("Invalid label, valid characters:[a-z0-9_-]"))
CheckInput(label_id, _("Empty Label")) check_input(label_id, _("Empty Label"))
CheckInput(not (label_id in self.labels), _("Label already exists")) check_input(not (label_id in self.labels), _("Label already exists"))
self.labels[label_id] = dict(OPTIONS_DEFAULTS) self.labels[label_id] = dict(OPTIONS_DEFAULTS)
self.config.save() self.config.save()
@ -201,7 +178,7 @@ class Core(CorePluginBase):
@export @export
def remove(self, label_id): def remove(self, label_id):
"""remove a label""" """remove a label"""
CheckInput(label_id in self.labels, _("Unknown Label")) check_input(label_id in self.labels, _("Unknown Label"))
del self.labels[label_id] del self.labels[label_id]
self.clean_config() self.clean_config()
self.config.save() self.config.save()
@ -211,7 +188,7 @@ class Core(CorePluginBase):
torrent = self.torrents[torrent_id] torrent = self.torrents[torrent_id]
if not options["move_completed_path"]: if not options["move_completed_path"]:
options["move_completed_path"] = "" #no None. options["move_completed_path"] = "" # no None.
if options["apply_max"]: if options["apply_max"]:
torrent.set_max_download_speed(options["max_download_speed"]) torrent.set_max_download_speed(options["max_download_speed"])
@ -281,7 +258,7 @@ class Core(CorePluginBase):
"move_completed_to":string() or None "move_completed_to":string() or None
} }
""" """
CheckInput(label_id in self.labels, _("Unknown Label")) check_input(label_id in self.labels, _("Unknown Label"))
for key in options_dict.keys(): for key in options_dict.keys():
if not key in OPTIONS_DEFAULTS: if not key in OPTIONS_DEFAULTS:
raise Exception("label: Invalid options_dict key:%s" % key) raise Exception("label: Invalid options_dict key:%s" % key)
@ -316,8 +293,8 @@ class Core(CorePluginBase):
if label_id == NO_LABEL: if label_id == NO_LABEL:
label_id = None label_id = None
CheckInput((not label_id) or (label_id in self.labels), _("Unknown Label")) check_input((not label_id) or (label_id in self.labels), _("Unknown Label"))
CheckInput(torrent_id in self.torrents, _("Unknown Torrent")) check_input(torrent_id in self.torrents, _("Unknown Torrent"))
if torrent_id in self.torrent_labels: if torrent_id in self.torrent_labels:
self._unset_torrent_options(torrent_id, self.torrent_labels[torrent_id]) self._unset_torrent_options(torrent_id, self.torrent_labels[torrent_id])
@ -346,6 +323,3 @@ class Core(CorePluginBase):
def _status_get_label(self, torrent_id): def _status_get_label(self, torrent_id):
return self.torrent_labels.get(torrent_id) or "" return self.torrent_labels.get(torrent_id) or ""
if __name__ == "__main__":
from . import test

View File

@ -1,46 +1,15 @@
# # -*- coding: utf-8 -*-
# __init__.py
# #
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 os
import logging import logging
import pkg_resources # access plugin egg from deluge import component # for systray
from deluge import component # for systray
from deluge.plugins.pluginbase import GtkPluginBase from deluge.plugins.pluginbase import GtkPluginBase
import gtk, gobject
from deluge.ui.client import client
from . import sidebar_menu from . import sidebar_menu
from . import label_config from . import label_config
@ -50,9 +19,11 @@ log = logging.getLogger(__name__)
NO_LABEL = "No Label" NO_LABEL = "No Label"
def cell_data_label(column, cell, model, row, data): def cell_data_label(column, cell, model, row, data):
cell.set_property('text', str(model.get_value(row, data))) cell.set_property('text', str(model.get_value(row, data)))
class GtkUI(GtkPluginBase): class GtkUI(GtkPluginBase):
def start(self): def start(self):
if self.label_menu: if self.label_menu:
@ -68,9 +39,9 @@ class GtkUI(GtkPluginBase):
def disable(self): def disable(self):
try: try:
torrentmenu = component.get("MenuBar").torrentmenu torrentmenu = component.get("MenuBar").torrentmenu
torrentmenu.remove(self.label_menu) # ok torrentmenu.remove(self.label_menu) # ok
self.labelcfg.unload() # ok self.labelcfg.unload() # ok
self.sidebar_menu.unload() self.sidebar_menu.unload()
del self.sidebar_menu del self.sidebar_menu
@ -84,7 +55,7 @@ class GtkUI(GtkPluginBase):
#sidebar #sidebar
#disabled #disabled
if not self.sidebar_menu: if not self.sidebar_menu:
self.sidebar_menu = sidebar_menu.LabelSidebarMenu() self.sidebar_menu = sidebar_menu.LabelSidebarMenu()
#self.sidebar.load() #self.sidebar.load()
#menu: #menu:
@ -99,7 +70,7 @@ class GtkUI(GtkPluginBase):
#config: #config:
if not self.labelcfg: if not self.labelcfg:
self.labelcfg = label_config.LabelConfig(self.plugin) self.labelcfg = label_config.LabelConfig(self.plugin)
self.labelcfg.load() self.labelcfg.load()
log.debug('Finished loading Label plugin') log.debug('Finished loading Label plugin')

View File

@ -1,37 +1,11 @@
# -*- coding: utf-8 -*-
# #
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
import os import os
@ -40,8 +14,6 @@ import gtk
import gtk.glade import gtk.glade
import pkg_resources # access plugin egg import pkg_resources # access plugin egg
import deluge.common
import deluge.component as component
from deluge.ui.client import client from deluge.ui.client import client
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -59,7 +31,6 @@ class LabelConfig(object):
log.debug('Adding Label Preferences page') log.debug('Adding Label Preferences page')
self.glade = gtk.glade.XML(self.get_resource("label_pref.glade")) self.glade = gtk.glade.XML(self.get_resource("label_pref.glade"))
self.plugin.add_preferences_page(_("Label"), self.glade.get_widget("label_prefs_box")) self.plugin.add_preferences_page(_("Label"), self.glade.get_widget("label_prefs_box"))
self.plugin.register_hook("on_show_prefs", self.load_settings) self.plugin.register_hook("on_show_prefs", self.load_settings)
self.plugin.register_hook("on_apply_prefs", self.on_apply_prefs) self.plugin.register_hook("on_apply_prefs", self.on_apply_prefs)

View File

@ -1,46 +1,18 @@
# # -*- coding: utf-8 -*-
# sidebar_menu.py
# #
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
import gtk import gtk
import gtk.glade import gtk.glade
import deluge.common
import deluge.component as component import deluge.component as component
from deluge.ui.client import client from deluge.ui.client import client
@ -48,6 +20,7 @@ log = logging.getLogger(__name__)
NO_LABEL = "No Label" NO_LABEL = "No Label"
#helpers: #helpers:
def get_resource(filename): def get_resource(filename):
import pkg_resources import pkg_resources
@ -56,11 +29,12 @@ def get_resource(filename):
"deluge.plugins.label", os.path.join("data", filename) "deluge.plugins.label", os.path.join("data", filename)
) )
#menu #menu
class LabelSidebarMenu(object): class LabelSidebarMenu(object):
def __init__(self): def __init__(self):
self.treeview = component.get("FilterTreeView") self.treeview = component.get("FilterTreeView")
self.menu = self.treeview.menu self.menu = self.treeview.menu
self.items = [] self.items = []
@ -79,17 +53,16 @@ class LabelSidebarMenu(object):
#hooks: #hooks:
self.menu.connect("show", self.on_show, None) self.menu.connect("show", self.on_show, None)
def _add_item(self, id, label, stock): def _add_item(self, id, label, stock):
"""I hate glade. """I hate glade.
id is automatically-added as self.item_<id> id is automatically-added as self.item_<id>
""" """
func = getattr(self, "on_%s" % id) func = getattr(self, "on_%s" % id)
item = gtk.ImageMenuItem(stock) item = gtk.ImageMenuItem(stock)
item.get_children()[0].set_label(label) item.get_children()[0].set_label(label)
item.connect("activate", func) item.connect("activate", func)
self.menu.prepend(item) self.menu.prepend(item)
setattr(self, "item_%s" % id, item) setattr(self, "item_%s" % id, item)
self.items.append(item) self.items.append(item)
return item return item
@ -99,7 +72,7 @@ class LabelSidebarMenu(object):
def on_remove(self, event=None): def on_remove(self, event=None):
client.label.remove(self.treeview.value) client.label.remove(self.treeview.value)
def on_options (self, event=None): def on_options(self, event=None):
self.options_dialog.show(self.treeview.value) self.options_dialog.show(self.treeview.value)
def on_show(self, widget=None, data=None): def on_show(self, widget=None, data=None):
@ -114,7 +87,7 @@ class LabelSidebarMenu(object):
item.show() item.show()
#default items #default items
sensitive = ((label not in (NO_LABEL, None, "", "All")) and (cat != "cat")) sensitive = ((label not in (NO_LABEL, None, "", "All")) and (cat != "cat"))
for item in self.items: for item in self.items:
item.set_sensitive(sensitive) item.set_sensitive(sensitive)
#add is allways enabled. #add is allways enabled.
@ -133,8 +106,6 @@ class LabelSidebarMenu(object):
self.items = [] self.items = []
#dialogs: #dialogs:
class AddDialog(object): class AddDialog(object):
def __init__(self): def __init__(self):
@ -164,15 +135,15 @@ class OptionsDialog(object):
spin_ids = ["max_download_speed", "max_upload_speed", "stop_ratio"] spin_ids = ["max_download_speed", "max_upload_speed", "stop_ratio"]
spin_int_ids = ["max_upload_slots", "max_connections"] spin_int_ids = ["max_upload_slots", "max_connections"]
chk_ids = ["apply_max", "apply_queue", "stop_at_ratio", "apply_queue", "remove_at_ratio", chk_ids = ["apply_max", "apply_queue", "stop_at_ratio", "apply_queue", "remove_at_ratio",
"apply_move_completed", "move_completed", "is_auto_managed", "auto_add"] "apply_move_completed", "move_completed", "is_auto_managed", "auto_add"]
#list of tuples, because order matters when nesting. #list of tuples, because order matters when nesting.
sensitive_groups = [ sensitive_groups = [
("apply_max", ["max_download_speed", "max_upload_speed", "max_upload_slots", "max_connections"]), ("apply_max", ["max_download_speed", "max_upload_speed", "max_upload_slots", "max_connections"]),
("apply_queue", ["is_auto_managed", "stop_at_ratio"]), ("apply_queue", ["is_auto_managed", "stop_at_ratio"]),
("stop_at_ratio", ["remove_at_ratio", "stop_ratio"]), #nested ("stop_at_ratio", ["remove_at_ratio", "stop_ratio"]), # nested
("apply_move_completed", ["move_completed"]), ("apply_move_completed", ["move_completed"]),
("move_completed", ["move_completed_path"]), #nested ("move_completed", ["move_completed_path"]), # nested
("auto_add", ["auto_add_trackers"]) ("auto_add", ["auto_add_trackers"])
] ]
@ -192,7 +163,7 @@ class OptionsDialog(object):
# Show the label name in the header label # Show the label name in the header label
self.glade.get_widget("label_header").set_markup("<b>%s:</b> %s" % (_("Label Options"), self.label)) self.glade.get_widget("label_header").set_markup("<b>%s:</b> %s" % (_("Label Options"), self.label))
for chk_id, group in self.sensitive_groups: for chk_id, group in self.sensitive_groups:
chk = self.glade.get_widget(chk_id) chk = self.glade.get_widget(chk_id)
chk.connect("toggled", self.apply_sensitivity) chk.connect("toggled", self.apply_sensitivity)
@ -237,9 +208,9 @@ class OptionsDialog(object):
else: else:
options["move_completed_path"] = self.glade.get_widget("move_completed_path_entry").get_text() options["move_completed_path"] = self.glade.get_widget("move_completed_path_entry").get_text()
buff = self.glade.get_widget("auto_add_trackers").get_buffer() #sometimes I hate gtk... buff = self.glade.get_widget("auto_add_trackers").get_buffer() # sometimes I hate gtk...
tracker_lst = buff.get_text(buff.get_start_iter(), buff.get_end_iter()).strip().split("\n") tracker_lst = buff.get_text(buff.get_start_iter(), buff.get_end_iter()).strip().split("\n")
options["auto_add_trackers"] = [x for x in tracker_lst if x] #filter out empty lines. options["auto_add_trackers"] = [x for x in tracker_lst if x] # filter out empty lines.
log.debug(options) log.debug(options)
client.label.set_options(self.label, options) client.label.set_options(self.label, options)

View File

@ -1,56 +1,30 @@
# # -*- coding: utf-8 -*-
# submenu.py
# #
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
import os
import gobject
import gtk import gtk
import pkg_resources # access plugin egg
from deluge import component # for systray from deluge import component # for systray
from deluge.ui.client import client from deluge.ui.client import client
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Deferred Translation # Deferred Translation
def _(message): return message def _(message):
return message
NO_LABEL = _("No Label") NO_LABEL = _("No Label")
del _ del _
class LabelMenu(gtk.MenuItem): class LabelMenu(gtk.MenuItem):
def __init__(self): def __init__(self):
gtk.MenuItem.__init__(self, _("Label")) gtk.MenuItem.__init__(self, _("Label"))
@ -60,7 +34,7 @@ class LabelMenu(gtk.MenuItem):
self.items = [] self.items = []
#attach.. #attach..
torrentmenu = component.get("MenuBar").torrentmenu component.get("MenuBar").torrentmenu
self.sub_menu.connect("show", self.on_show, None) self.sub_menu.connect("show", self.on_show, None)
def get_torrent_ids(self): def get_torrent_ids(self):
@ -83,6 +57,6 @@ class LabelMenu(gtk.MenuItem):
self.show_all() self.show_all()
def on_select_label(self, widget=None, label_id=None): def on_select_label(self, widget=None, label_id=None):
log.debug("select label:%s,%s" % (label_id, self.get_torrent_ids()) ) log.debug("select label:%s,%s" % (label_id, self.get_torrent_ids()))
for torrent_id in self.get_torrent_ids(): for torrent_id in self.get_torrent_ids():
client.label.set_torrent(torrent_id, label_id) client.label.set_torrent(torrent_id, label_id)

View File

@ -1,34 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# Copyright (C) Martijn Voncken 2008 <mvoncken@gmail.com> # -*- coding: utf-8 -*-
# #
# This program is free software; you can redistribute it and/or modify # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
from __future__ import print_function from __future__ import print_function
@ -57,15 +36,15 @@ sclient.label_add("test")
print("#set") print("#set")
sclient.label_set_torrent(id, "test") sclient.label_set_torrent(id, "test")
print(sclient.get_torrents_status({"label":"test"}, "name")) print(sclient.get_torrents_status({"label": "test"}, "name"))
print("#set options") print("#set options")
sclient.label_set_options("test", {"max_download_speed":999}, True) sclient.label_set_options("test", {"max_download_speed": 999}, True)
print(sclient.get_torrent_status(id, ["max_download_speed"]), "999") print(sclient.get_torrent_status(id, ["max_download_speed"]), "999")
sclient.label_set_options("test", {"max_download_speed":9}, True) sclient.label_set_options("test", {"max_download_speed": 9}, True)
print(sclient.get_torrent_status(id, ["max_download_speed"]), "9") print(sclient.get_torrent_status(id, ["max_download_speed"]), "9")
sclient.label_set_options("test", {"max_download_speed":888}, False) sclient.label_set_options("test", {"max_download_speed": 888}, False)
print(sclient.get_torrent_status(id, ["max_download_speed"]), "9 (888)") print(sclient.get_torrent_status(id, ["max_download_speed"]), "9 (888)")
print(sclient.get_torrent_status(id, ['name', 'tracker_host', 'label'])) print(sclient.get_torrent_status(id, ['name', 'tracker_host', 'label']))

View File

@ -1,40 +1,14 @@
# # -*- coding: utf-8 -*-
# webui.py
# #
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# 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-2008 Andrew Resch <andrewresch@gmail.com>
#
# Deluge is free software.
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
import logging import logging
@ -42,17 +16,16 @@ import os
import pkg_resources import pkg_resources
from deluge import component
from deluge.common import fspeed
from deluge.plugins.pluginbase import WebPluginBase from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def get_resource(filename): def get_resource(filename):
return pkg_resources.resource_filename("deluge.plugins.label", return pkg_resources.resource_filename("deluge.plugins.label",
os.path.join("data", filename)) os.path.join("data", filename))
class WebUI(WebPluginBase): class WebUI(WebPluginBase):
scripts = [get_resource("label.js")] scripts = [get_resource("label.js")]

View File

@ -45,7 +45,7 @@ Allows labels to be assigned to torrents
Also offers filters on state, tracker and keywords Also offers filters on state, tracker and keywords
""" """
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]} __pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -58,8 +58,8 @@ setup(
long_description=__long_description__, long_description=__long_description__,
packages=find_packages(), packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"], namespace_packages=["deluge", "deluge.plugins"],
package_data = __pkg_data__, package_data=__pkg_data__,
entry_points=""" entry_points="""
[deluge.plugin.core] [deluge.plugin.core]
@ -68,5 +68,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web] [deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin %s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3) """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
) )

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# __init__.py
# #
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me> # Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
# #
@ -8,51 +7,30 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
from deluge.plugins.init import PluginInitBase from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls from .webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# common.py
# #
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me> # Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
# #
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
@ -53,9 +28,9 @@ except ImportError:
def get_resource(filename): def get_resource(filename):
import pkg_resources, os import os
return pkg_resources.resource_filename("deluge.plugins.notifications", import pkg_resources
os.path.join("data", filename)) return pkg_resources.resource_filename("deluge.plugins.notifications", os.path.join("data", filename))
class CustomNotifications(object): class CustomNotifications(object):
@ -97,8 +72,7 @@ class CustomNotifications(object):
return defer.succeed("Event not handled") return defer.succeed("Event not handled")
if eventtype not in self.custom_notifications: if eventtype not in self.custom_notifications:
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
return self._handle_custom_providers(kind, eventtype, return self._handle_custom_providers(kind, eventtype, *args, **kwargs)
*args, **kwargs)
self.custom_notifications[kind][eventtype] = (wrapper, handler) self.custom_notifications[kind][eventtype] = (wrapper, handler)
else: else:
wrapper, handler = self.custom_notifications[kind][eventtype] wrapper, handler = self.custom_notifications[kind][eventtype]

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# core.py
# #
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me> # Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
# #
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
@ -60,7 +35,7 @@ DEFAULT_PREFS = {
"smtp_user": "", "smtp_user": "",
"smtp_pass": "", "smtp_pass": "",
"smtp_from": "", "smtp_from": "",
"smtp_tls": False, # SSL or TLS "smtp_tls": False, # SSL or TLS
"smtp_recipients": [], "smtp_recipients": [],
# Subscriptions # Subscriptions
"subscriptions": { "subscriptions": {
@ -68,6 +43,7 @@ DEFAULT_PREFS = {
} }
} }
class CoreNotifications(CustomNotifications): class CoreNotifications(CustomNotifications):
def enable(self): def enable(self):
@ -126,10 +102,10 @@ Date: %(date)s
""" % {'smtp_from': self.config['smtp_from'], """ % {'smtp_from': self.config['smtp_from'],
'subject': subject, 'subject': subject,
'smtp_recipients': to_addrs_str, 'smtp_recipients': to_addrs_str,
'date': formatdate() 'date': formatdate()
} }
message = '\r\n'.join((headers + message).splitlines()) message = '\r\n'.join((headers + message).splitlines())
@ -194,7 +170,6 @@ Date: %(date)s
server.quit() server.quit()
return _("Notification email sent.") return _("Notification email sent.")
def _on_torrent_finished_event(self, torrent_id): def _on_torrent_finished_event(self, torrent_id):
log.debug("Handler for TorrentFinishedEvent called for CORE") log.debug("Handler for TorrentFinishedEvent called for CORE")
torrent = component.get("TorrentManager")[torrent_id] torrent = component.get("TorrentManager")[torrent_id]

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# gtkui.py
# #
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me> # Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
# #
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
@ -95,6 +70,7 @@ RECIPIENT_FIELD, RECIPIENT_EDIT = range(2)
SUB_NOT_SOUND) = range(6) SUB_NOT_SOUND) = range(6)
SND_EVENT, SND_EVENT_DOC, SND_NAME, SND_PATH = range(4) SND_EVENT, SND_EVENT_DOC, SND_NAME, SND_PATH = range(4)
class GtkUiNotifications(CustomNotifications): class GtkUiNotifications(CustomNotifications):
def enable(self): def enable(self):
@ -190,8 +166,7 @@ class GtkUiNotifications(CustomNotifications):
return defer.fail(_("pynotify is not installed")) return defer.fail(_("pynotify is not installed"))
if pynotify.init("Deluge"): if pynotify.init("Deluge"):
icon = gtk.gdk.pixbuf_new_from_file_at_size( icon = gtk.gdk.pixbuf_new_from_file_at_size(deluge.common.get_pixmap("deluge.svg"), 48, 48)
deluge.common.get_pixmap("deluge.svg"), 48, 48)
self.note = pynotify.Notification(title, message) self.note = pynotify.Notification(title, message)
self.note.set_icon_from_pixbuf(icon) self.note.set_icon_from_pixbuf(icon)
if not self.note.show(): if not self.note.show():
@ -225,7 +200,7 @@ class GtkUiNotifications(CustomNotifications):
return defer.succeed(msg) return defer.succeed(msg)
def _on_torrent_finished_event_blink(self, torrent_id): def _on_torrent_finished_event_blink(self, torrent_id):
return True # Yes, Blink return True # Yes, Blink
def _on_torrent_finished_event_sound(self, torrent_id): def _on_torrent_finished_event_sound(self, torrent_id):
# Since there's no custom sound hardcoded, just return '' # Since there's no custom sound hardcoded, just return ''
@ -248,6 +223,7 @@ class GtkUiNotifications(CustomNotifications):
"has finished downloading.") % torrent_status "has finished downloading.") % torrent_status
return title, message return title, message
class GtkUI(GtkPluginBase, GtkUiNotifications): class GtkUI(GtkPluginBase, GtkUiNotifications):
def __init__(self, plugin_name): def __init__(self, plugin_name):
GtkPluginBase.__init__(self, plugin_name) GtkPluginBase.__init__(self, plugin_name)
@ -266,7 +242,6 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
self.build_sounds_model_populate_treeview() self.build_sounds_model_populate_treeview()
self.build_notifications_model_populate_treeview() self.build_notifications_model_populate_treeview()
client.notifications.get_handled_events().addCallback( client.notifications.get_handled_events().addCallback(
self.popuplate_what_needs_handled_events self.popuplate_what_needs_handled_events
) )
@ -279,8 +254,7 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
'on_enabled_toggled': self.on_enabled_toggled, 'on_enabled_toggled': self.on_enabled_toggled,
'on_sound_enabled_toggled': self.on_sound_enabled_toggled, 'on_sound_enabled_toggled': self.on_sound_enabled_toggled,
'on_sounds_edit_button_clicked': self.on_sounds_edit_button_clicked, 'on_sounds_edit_button_clicked': self.on_sounds_edit_button_clicked,
'on_sounds_revert_button_clicked': \ 'on_sounds_revert_button_clicked': self.on_sounds_revert_button_clicked,
self.on_sounds_revert_button_clicked,
'on_sound_path_update_preview': self.on_sound_path_update_preview 'on_sound_path_update_preview': self.on_sound_path_update_preview
}) })
@ -413,15 +387,15 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
self.subscriptions_treeview.append_column(column) self.subscriptions_treeview.append_column(column)
renderer = gtk.CellRendererToggle() renderer = gtk.CellRendererToggle()
renderer.set_property('activatable', True) renderer.set_property("activatable", True)
renderer.connect( 'toggled', self._on_popup_col_toggled) renderer.connect("toggled", self._on_popup_col_toggled)
column = gtk.TreeViewColumn("Popup", renderer, active=SUB_NOT_POPUP) column = gtk.TreeViewColumn("Popup", renderer, active=SUB_NOT_POPUP)
column.set_clickable(True) column.set_clickable(True)
self.subscriptions_treeview.append_column(column) self.subscriptions_treeview.append_column(column)
renderer = gtk.CellRendererToggle() renderer = gtk.CellRendererToggle()
renderer.set_property('activatable', True) renderer.set_property("activatable", True)
renderer.connect( 'toggled', self._on_blink_col_toggled) renderer.connect("toggled", self._on_blink_col_toggled)
column = gtk.TreeViewColumn("Blink", renderer, active=SUB_NOT_BLINK) column = gtk.TreeViewColumn("Blink", renderer, active=SUB_NOT_BLINK)
column.set_clickable(True) column.set_clickable(True)
self.subscriptions_treeview.append_column(column) self.subscriptions_treeview.append_column(column)
@ -471,7 +445,6 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
SUB_NOT_SOUND, event_name in subscriptions_dict['sound'] SUB_NOT_SOUND, event_name in subscriptions_dict['sound']
) )
def on_apply_prefs(self): def on_apply_prefs(self):
log.debug("applying prefs for Notifications") log.debug("applying prefs for Notifications")
@ -523,7 +496,7 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
"smtp_from": self.glade.get_widget("smtp_from").get_text(), "smtp_from": self.glade.get_widget("smtp_from").get_text(),
"smtp_tls": self.glade.get_widget("smtp_tls").get_active(), "smtp_tls": self.glade.get_widget("smtp_tls").get_active(),
"smtp_recipients": [dest[0] for dest in self.recipients_model if "smtp_recipients": [dest[0] for dest in self.recipients_model if
dest[0]!='USER@HOST'], dest[0] != "USER@HOST"],
"subscriptions": {"email": current_email_subscriptions} "subscriptions": {"email": current_email_subscriptions}
} }
@ -587,12 +560,10 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
selection = treeview.get_selection() selection = treeview.get_selection()
model, iter = selection.get_selected() model, iter = selection.get_selected()
if iter: if iter:
path = model.get_path(iter)[0]
model.remove(iter) model.remove(iter)
def on_cell_edited(self, cell, path_string, new_text, model): def on_cell_edited(self, cell, path_string, new_text, model):
iter = model.get_iter_from_string(path_string) iter = model.get_iter_from_string(path_string)
path = model.get_path(iter)[0]
model.set(iter, RECIPIENT_FIELD, new_text) model.set(iter, RECIPIENT_FIELD, new_text)
def on_recipients_treeview_selection_changed(self, selection): def on_recipients_treeview_selection_changed(self, selection):
@ -616,21 +587,17 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
def on_sounds_treeview_selection_changed(self, selection): def on_sounds_treeview_selection_changed(self, selection):
model, iter = selection.get_selected() model, iter = selection.get_selected()
if iter: if iter:
self.glade.get_widget("sounds_edit_button").set_property( self.glade.get_widget("sounds_edit_button").set_property("sensitive", True)
'sensitive', True)
path = model.get(iter, SND_PATH)[0] path = model.get(iter, SND_PATH)[0]
log.debug("Sound selection changed: %s", path) log.debug("Sound selection changed: %s", path)
if path != self.config['sound_path']: if path != self.config['sound_path']:
self.glade.get_widget("sounds_revert_button").set_property( self.glade.get_widget("sounds_revert_button").set_property("sensitive", True)
'sensitive', True)
else: else:
self.glade.get_widget("sounds_revert_button").set_property( self.glade.get_widget("sounds_revert_button").set_property("sensitive", False)
'sensitive', False)
else: else:
self.glade.get_widget("sounds_edit_button").set_property( self.glade.get_widget("sounds_edit_button").set_property("sensitive", False)
'sensitive', False) self.glade.get_widget("sounds_revert_button").set_property("sensitive", False)
self.glade.get_widget("sounds_revert_button").set_property(
'sensitive', False)
def on_sounds_revert_button_clicked(self, widget): def on_sounds_revert_button_clicked(self, widget):
log.debug("on_sounds_revert_button_clicked") log.debug("on_sounds_revert_button_clicked")
selection = self.sounds_treeview.get_selection() selection = self.sounds_treeview.get_selection()
@ -655,6 +622,7 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
gtk.RESPONSE_OK) gtk.RESPONSE_OK)
) )
dialog.set_filename(path) dialog.set_filename(path)
def update_model(response): def update_model(response):
if response == gtk.RESPONSE_OK: if response == gtk.RESPONSE_OK:
new_filename = dialog.get_filename() new_filename = dialog.get_filename()

View File

@ -15,12 +15,15 @@ from deluge.event import DelugeEvent
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class FooEvent(DelugeEvent): class FooEvent(DelugeEvent):
"""foo Event""" """foo Event"""
class CustomEvent(DelugeEvent): class CustomEvent(DelugeEvent):
"""Just a custom event to test""" """Just a custom event to test"""
class TestEmailNotifications(component.Component): class TestEmailNotifications(component.Component):
def __init__(self, imp): def __init__(self, imp):
component.Component.__init__(self, self.__class__.__name__, 5) component.Component.__init__(self, self.__class__.__name__, 5)
@ -32,6 +35,7 @@ class TestEmailNotifications(component.Component):
CustomEvent() CustomEvent()
] ]
self.events_classes = [] self.events_classes = []
def enable(self): def enable(self):
log.debug("\n\nEnabling %s", self.__class__.__name__) log.debug("\n\nEnabling %s", self.__class__.__name__)
for event in self.events: for event in self.events:
@ -65,7 +69,7 @@ class TestEmailNotifications(component.Component):
def update(self): def update(self):
if self.__imp == 'core': if self.__imp == 'core':
log.debug("\n\nUpdating %s", self.__class__.__name__) log.debug("\n\nUpdating %s", self.__class__.__name__)
self.events.append(self.events.pop(0)) # Re-Queue self.events.append(self.events.pop(0)) # Re-Queue
self.n += 1 self.n += 1
component.get("EventManager").emit(self.events[0]) component.get("EventManager").emit(self.events[0])

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# webui.py
# #
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me> # Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
# #
@ -8,45 +7,20 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource from .common import get_resource
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class WebUI(WebPluginBase): class WebUI(WebPluginBase):
scripts = [get_resource("notifications.js")] scripts = [get_resource("notifications.js")]

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# setup.py
# #
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me> # Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
# #
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
from setuptools import find_packages, setup from setuptools import find_packages, setup
@ -46,7 +21,7 @@ __version__ = "0.2"
__url__ = "http://dev.deluge-torrent.org/" __url__ = "http://dev.deluge-torrent.org/"
__license__ = "GPLv3" __license__ = "GPLv3"
__description__ = "Plugin which provides notifications to Deluge." __description__ = "Plugin which provides notifications to Deluge."
__long_description__ = """ __long_description__ = """
Plugin which provides notifications to Deluge Plugin which provides notifications to Deluge
Email, Popup, Blink and Sound notifications Email, Popup, Blink and Sound notifications
@ -54,7 +29,7 @@ Email, Popup, Blink and Sound notifications
The plugin also allows other plugins to make The plugin also allows other plugins to make
use of itself for their own custom notifications use of itself for their own custom notifications
""" """
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]} __pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -67,8 +42,8 @@ setup(
long_description=__long_description__ if __long_description__ else __description__, long_description=__long_description__ if __long_description__ else __description__,
packages=find_packages(exclude=['**/test.py']), packages=find_packages(exclude=['**/test.py']),
namespace_packages = ["deluge", "deluge.plugins"], namespace_packages=["deluge", "deluge.plugins"],
package_data = __pkg_data__, package_data=__pkg_data__,
entry_points=""" entry_points="""
[deluge.plugin.core] [deluge.plugin.core]
@ -77,5 +52,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web] [deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin %s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3) """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
) )

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# __init__.py
# #
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
# #
@ -7,51 +6,30 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
from deluge.plugins.init import PluginInitBase from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls from .webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# common.py
# #
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
# #
@ -7,36 +6,13 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
def get_resource(filename): def get_resource(filename):
import pkg_resources, os import os
return pkg_resources.resource_filename("deluge.plugins.scheduler", import pkg_resources
os.path.join("data", filename)) return pkg_resources.resource_filename("deluge.plugins.scheduler", os.path.join("data", filename))

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# core.py
# #
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
# #
@ -7,33 +6,9 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
@ -72,6 +47,7 @@ CONTROLLED_SETTINGS = [
"max_active_seeding" "max_active_seeding"
] ]
class SchedulerEvent(DelugeEvent): class SchedulerEvent(DelugeEvent):
""" """
Emitted when a schedule state changes. Emitted when a schedule state changes.
@ -82,6 +58,7 @@ class SchedulerEvent(DelugeEvent):
""" """
self._args = [colour] self._args = [colour]
class Core(CorePluginBase): class Core(CorePluginBase):
def enable(self): def enable(self):
# Create the defaults with the core config # Create the defaults with the core config
@ -118,7 +95,6 @@ class Core(CorePluginBase):
def update(self): def update(self):
pass pass
def on_config_value_changed(self, key, value): def on_config_value_changed(self, key, value):
if key in CONTROLLED_SETTINGS: if key in CONTROLLED_SETTINGS:
self.do_schedule(False) self.do_schedule(False)

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# gtkui.py
# #
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
# #
@ -7,40 +6,15 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
import gtk import gtk
import deluge.common
import deluge.component as component import deluge.component as component
from deluge.plugins.pluginbase import GtkPluginBase from deluge.plugins.pluginbase import GtkPluginBase
from deluge.ui.client import client from deluge.ui.client import client
@ -51,10 +25,12 @@ log = logging.getLogger(__name__)
DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
class SchedulerSelectWidget(gtk.DrawingArea): class SchedulerSelectWidget(gtk.DrawingArea):
def __init__(self, hover): def __init__(self, hover):
gtk.DrawingArea.__init__(self) gtk.DrawingArea.__init__(self)
self.set_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.LEAVE_NOTIFY_MASK) self.set_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK |
gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.LEAVE_NOTIFY_MASK)
self.connect("expose_event", self.expose) self.connect("expose_event", self.expose)
self.connect("button_press_event", self.mouse_down) self.connect("button_press_event", self.mouse_down)
@ -62,7 +38,9 @@ class SchedulerSelectWidget(gtk.DrawingArea):
self.connect("motion_notify_event", self.mouse_hover) self.connect("motion_notify_event", self.mouse_hover)
self.connect("leave_notify_event", self.mouse_leave) self.connect("leave_notify_event", self.mouse_leave)
self.colors = [[115.0/255, 210.0/255, 22.0/255], [237.0/255, 212.0/255, 0.0/255], [204.0/255, 0.0/255, 0.0/255]] self.colors = [[115.0 / 255, 210.0 / 255, 22.0 / 255],
[237.0 / 255, 212.0 / 255, 0.0 / 255],
[204.0 / 255, 0.0 / 255, 0.0 / 255]]
self.button_state = [[0] * 7 for dummy in xrange(24)] self.button_state = [[0] * 7 for dummy in xrange(24)]
self.start_point = [0, 0] self.start_point = [0, 0]
@ -89,8 +67,11 @@ class SchedulerSelectWidget(gtk.DrawingArea):
for y in xrange(7): for y in xrange(7):
for x in xrange(24): for x in xrange(24):
self.context.set_source_rgba(self.colors[self.button_state[x][y]][0], self.colors[self.button_state[x][y]][1], self.colors[self.button_state[x][y]][2], 0.7) self.context.set_source_rgba(self.colors[self.button_state[x][y]][0],
self.context.rectangle(width*(6*x/145.0+1/145.0), height*(6*y/43.0+1/43.0), 5*width/145.0, 5*height/43.0) self.colors[self.button_state[x][y]][1],
self.colors[self.button_state[x][y]][2], 0.7)
self.context.rectangle(width * (6 * x / 145.0 + 1 / 145.0), height * (6 * y / 43.0 + 1 / 43.0),
5 * width / 145.0, 5 * height / 43.0)
self.context.fill_preserve() self.context.fill_preserve()
self.context.set_source_rgba(0.5, 0.5, 0.5, 0.5) self.context.set_source_rgba(0.5, 0.5, 0.5, 0.5)
self.context.stroke() self.context.stroke()
@ -98,13 +79,17 @@ class SchedulerSelectWidget(gtk.DrawingArea):
#coordinates --> which box #coordinates --> which box
def get_point(self, event): def get_point(self, event):
size = self.window.get_size() size = self.window.get_size()
x = int((event.x-size[0]*0.5/145.0)/(6*size[0]/145.0)) x = int((event.x - size[0] * 0.5 / 145.0) / (6 * size[0] / 145.0))
y = int((event.y-size[1]*0.5/43.0)/(6*size[1]/43.0)) y = int((event.y - size[1] * 0.5 / 43.0) / (6 * size[1] / 43.0))
if x > 23: x = 23 if x > 23:
elif x < 0: x = 0 x = 23
if y > 6: y = 6 elif x < 0:
elif y < 0: y = 0 x = 0
if y > 6:
y = 6
elif y < 0:
y = 0
return [x, y] return [x, y]
@ -136,13 +121,14 @@ class SchedulerSelectWidget(gtk.DrawingArea):
if self.get_point(event) != self.hover_point: if self.get_point(event) != self.hover_point:
self.hover_point = self.get_point(event) self.hover_point = self.get_point(event)
self.hover_label.set_text(self.hover_days[self.hover_point[1]] + " " + str(self.hover_point[0]) + ":00 - " + str(self.hover_point[0]) + ":59") self.hover_label.set_text(self.hover_days[self.hover_point[1]] + " " + str(self.hover_point[0])
+ ":00 - " + str(self.hover_point[0]) + ":59")
if self.mouse_press == True: if self.mouse_press:
points = [[self.hover_point[0], self.start_point[0]], [self.hover_point[1], self.start_point[1]]] points = [[self.hover_point[0], self.start_point[0]], [self.hover_point[1], self.start_point[1]]]
for x in xrange(min(points[0]), max(points[0])+1): for x in xrange(min(points[0]), max(points[0]) + 1):
for y in xrange(min(points[1]), max(points[1])+1): for y in xrange(min(points[1]), max(points[1]) + 1):
self.button_state[x][y] = self.button_state[self.start_point[0]][self.start_point[1]] self.button_state[x][y] = self.button_state[self.start_point[0]][self.start_point[1]]
self.queue_draw() self.queue_draw()
@ -152,6 +138,7 @@ class SchedulerSelectWidget(gtk.DrawingArea):
self.hover_label.set_text("") self.hover_label.set_text("")
self.hover_point = [-1, -1] self.hover_point = [-1, -1]
class GtkUI(GtkPluginBase): class GtkUI(GtkPluginBase):
def enable(self): def enable(self):
self.create_prefs_page() self.create_prefs_page()
@ -201,7 +188,6 @@ class GtkUI(GtkPluginBase):
self.spin_active_down.set_value(config["low_active_down"]) self.spin_active_down.set_value(config["low_active_down"])
self.spin_active_up.set_value(config["low_active_up"]) self.spin_active_up.set_value(config["low_active_up"])
client.scheduler.get_config().addCallback(on_get_config) client.scheduler.get_config().addCallback(on_get_config)
def on_scheduler_event(self, state): def on_scheduler_event(self, state):

View File

@ -1,51 +1,26 @@
# #
# webui.py # -*- coding: utf-8 -*-
# #
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
# #
# 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-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource from .common import get_resource
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class WebUI(WebPluginBase): class WebUI(WebPluginBase):
scripts = [get_resource("scheduler.js")] scripts = [get_resource("scheduler.js")]

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# setup.py
# #
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
# #
@ -7,33 +6,9 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
from setuptools import find_packages, setup from setuptools import find_packages, setup
@ -46,7 +21,7 @@ __url__ = "http://deluge-torrent.org"
__license__ = "GPLv3" __license__ = "GPLv3"
__description__ = "Schedule limits on a per-hour per-day basis." __description__ = "Schedule limits on a per-hour per-day basis."
__long_description__ = """""" __long_description__ = """"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]} __pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -59,8 +34,8 @@ setup(
long_description=__long_description__ if __long_description__ else __description__, long_description=__long_description__ if __long_description__ else __description__,
packages=find_packages(), packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"], namespace_packages=["deluge", "deluge.plugins"],
package_data = __pkg_data__, package_data=__pkg_data__,
entry_points=""" entry_points="""
[deluge.plugin.core] [deluge.plugin.core]
@ -69,5 +44,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web] [deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin %s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3) """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
) )

View File

@ -1,57 +1,35 @@
# # -*- coding: utf-8 -*-
# __init__.py
# #
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# 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. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
from deluge.plugins.init import PluginInitBase from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls from .webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -1,35 +1,10 @@
# # -*- coding: utf-8 -*-
# common.py
# #
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 os.path import os.path

View File

@ -1,37 +1,15 @@
# #
# core.py # -*- coding: utf-8 -*-
# #
# Copyright (C) 2009 Ian Martin <ianmartin@cantab.net> # Copyright (C) 2009 Ian Martin <ianmartin@cantab.net>
# Copyright (C) 2008 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2008 Damien Churchill <damoxc@gmail.com>
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) Marcos Pinto 2007 <markybob@gmail.com> # Copyright (C) 2007 Marcos Pinto <markybob@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
import logging import logging
import time import time

View File

@ -1,38 +1,15 @@
# #
# graph.py # -*- coding: utf-8 -*-
# #
# Copyright (C) 2009 Ian Martin <ianmartin@cantab.net> # Copyright (C) 2009 Ian Martin <ianmartin@cantab.net>
# Copyright (C) 2008 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2008 Damien Churchill <damoxc@gmail.com>
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) Marcos Pinto 2007 <markybob@gmail.com> # Copyright (C) 2007 Marcos Pinto <markybob@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
""" """
port of old plugin by markybob. port of old plugin by markybob.
@ -43,8 +20,6 @@ import time
import cairo import cairo
from deluge.ui.client import client
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
black = (0, 0, 0) black = (0, 0, 0)
@ -56,9 +31,11 @@ green = (0, 1.0, 0)
blue = (0, 0, 1.0) blue = (0, 0, 1.0)
orange = (1.0, 0.74, 0) orange = (1.0, 0.74, 0)
def default_formatter(value): def default_formatter(value):
return str(value) return str(value)
def size_formatter_scale(value): def size_formatter_scale(value):
scale = 1.0 scale = 1.0
for i in range(0, 3): for i in range(0, 3):
@ -66,6 +43,7 @@ def size_formatter_scale(value):
if value / scale < 1024: if value / scale < 1024:
return scale return scale
def change_opacity(color, opactiy): def change_opacity(color, opactiy):
"""A method to assist in changing the opactiy of a color inorder to draw the """A method to assist in changing the opactiy of a color inorder to draw the
fills. fills.
@ -77,6 +55,7 @@ def change_opacity(color, opactiy):
color.append(opactiy) color.append(opactiy)
return tuple(color) return tuple(color)
class Graph: class Graph:
def __init__(self): def __init__(self):
self.width = 100 self.width = 100
@ -89,8 +68,8 @@ class Graph:
self.legend_selected = True self.legend_selected = True
self.max_selected = True self.max_selected = True
self.black = (0, 0, 0,) self.black = (0, 0, 0,)
self.interval = 2 # 2 secs self.interval = 2 # 2 secs
self.text_bg = (255, 255, 255, 128) # prototyping self.text_bg = (255, 255, 255, 128) # prototyping
self.set_left_axis() self.set_left_axis()
def set_left_axis(self, **kargs): def set_left_axis(self, **kargs):
@ -103,7 +82,7 @@ class Graph:
'line': line, 'line': line,
'fill': fill, 'fill': fill,
'color': color 'color': color
} }
def set_stats(self, stats): def set_stats(self, stats):
self.last_update = stats["_last_update"] self.last_update = stats["_last_update"]
@ -135,7 +114,6 @@ class Graph:
self.draw_to_context(ctx, width, height) self.draw_to_context(ctx, width, height)
return surface return surface
def draw_x_axis(self, bounds): def draw_x_axis(self, bounds):
(left, top, right, bottom) = bounds (left, top, right, bottom) = bounds
duration = self.length * self.interval duration = self.length * self.interval
@ -150,32 +128,32 @@ class Graph:
break break
else: else:
# if there wasnt anything useful find a nice fitting hourly divisor # if there wasnt anything useful find a nice fitting hourly divisor
x_step = ((duration / 5) /3600 )* 3600 x_step = ((duration / 5) / 3600) * 3600
#this doesnt allow for dst and timezones... #this doesnt allow for dst and timezones...
seconds_to_step = math.ceil(start/float(x_step)) * x_step - start seconds_to_step = math.ceil(start / float(x_step)) * x_step - start
for i in xrange(0, duration/x_step + 1): for i in xrange(0, duration / x_step + 1):
text = time.strftime('%H:%M', time.localtime(start + seconds_to_step + i*x_step)) text = time.strftime('%H:%M', time.localtime(start + seconds_to_step + i * x_step))
# + 0.5 to allign x to nearest pixel # + 0.5 to allign x to nearest pixel
x = int(ratio * (seconds_to_step + i*x_step) + left) + 0.5 x = int(ratio * (seconds_to_step + i * x_step) + left) + 0.5
self.draw_x_text(text, x, bottom) self.draw_x_text(text, x, bottom)
self.draw_dotted_line(gray, x, top-0.5, x, bottom+0.5) self.draw_dotted_line(gray, x, top - 0.5, x, bottom + 0.5)
self.draw_line(gray, left, bottom+0.5, right, bottom+0.5) self.draw_line(gray, left, bottom + 0.5, right, bottom + 0.5)
def draw_graph(self): def draw_graph(self):
font_extents = self.ctx.font_extents() font_extents = self.ctx.font_extents()
x_axis_space = font_extents[2] + 2 + self.line_size / 2.0 x_axis_space = font_extents[2] + 2 + self.line_size / 2.0
plot_height = self.height - x_axis_space plot_height = self.height - x_axis_space
#lets say we need 2n-1*font height pixels to plot the y ticks #lets say we need 2n-1*font height pixels to plot the y ticks
tick_limit = (plot_height / font_extents[3] )# / 2.0 tick_limit = (plot_height / font_extents[3]) # / 2.0
max_value = 0 max_value = 0
for stat in self.stat_info: for stat in self.stat_info:
if self.stat_info[stat]['axis'] == 'left': if self.stat_info[stat]['axis'] == 'left':
try: try:
l_max = max(self.stats[stat]) l_max = max(self.stats[stat])
except ValueError: except ValueError:
l_max = 0 l_max = 0
if l_max > max_value: if l_max > max_value:
@ -187,6 +165,7 @@ class Graph:
max_value = y_ticks[-1] max_value = y_ticks[-1]
#find the width of the y_ticks #find the width of the y_ticks
y_tick_text = [self.left_axis['formatter'](tick) for tick in y_ticks] y_tick_text = [self.left_axis['formatter'](tick) for tick in y_ticks]
def space_required(text): def space_required(text):
te = self.ctx.text_extents(text) te = self.ctx.text_extents(text)
return math.ceil(te[4] - te[0]) return math.ceil(te[4] - te[0])
@ -194,7 +173,7 @@ class Graph:
top = font_extents[2] / 2.0 top = font_extents[2] / 2.0
#bounds(left, top, right, bottom) #bounds(left, top, right, bottom)
bounds = (y_tick_width + 4, top + 2, self.width, self.height - x_axis_space) bounds = (y_tick_width + 4, top + 2, self.width, self.height - x_axis_space)
self.draw_x_axis(bounds) self.draw_x_axis(bounds)
self.draw_left_axis(bounds, y_ticks, y_tick_text) self.draw_left_axis(bounds, y_ticks, y_tick_text)
@ -206,10 +185,10 @@ class Graph:
#Limit is the number of ticks which is 1 + the number of steps as we #Limit is the number of ticks which is 1 + the number of steps as we
#count the 0 tick in limit #count the 0 tick in limit
if limit is not None: if limit is not None:
if limit <3: if limit < 3:
limit = 2 limit = 2
else: else:
limit = limit -1 limit = limit - 1
scale = 1 scale = 1
if 'formatter_scale' in self.left_axis: if 'formatter_scale' in self.left_axis:
scale = self.left_axis['formatter_scale'](x) scale = self.left_axis['formatter_scale'](x)
@ -220,15 +199,15 @@ class Graph:
intbit = math.floor(log) intbit = math.floor(log)
interval = math.pow(10, intbit) interval = math.pow(10, intbit)
steps = int(math.ceil(x / interval)) steps = int(math.ceil(x / interval))
if steps <= 1 and (limit is None or limit >= 10*steps): if steps <= 1 and (limit is None or limit >= 10 * steps):
interval = interval * 0.1 interval = interval * 0.1
steps = steps * 10 steps = steps * 10
elif steps <= 2 and (limit is None or limit >= 5*steps): elif steps <= 2 and (limit is None or limit >= 5 * steps):
interval = interval * 0.2 interval = interval * 0.2
steps = steps * 5 steps = steps * 5
elif steps <=5 and (limit is None or limit >= 2*steps): elif steps <= 5 and (limit is None or limit >= 2 * steps):
interval = interval * 0.5 interval = interval * 0.5
steps = steps * 2 steps = steps * 2
@ -239,7 +218,7 @@ class Graph:
else: else:
interval = interval * 2 interval = interval * 2
intervals = [i * interval * scale for i in xrange(1+int(math.ceil(x/ interval)))] intervals = [i * interval * scale for i in xrange(1 + int(math.ceil(x / interval)))]
return intervals return intervals
def draw_left_axis(self, bounds, y_ticks, y_tick_text): def draw_left_axis(self, bounds, y_ticks, y_tick_text):
@ -252,12 +231,12 @@ class Graph:
stats[stat]['fill_color'] = change_opacity(stats[stat]['color'], 0.5) stats[stat]['fill_color'] = change_opacity(stats[stat]['color'], 0.5)
stats[stat]['color'] = change_opacity(stats[stat]['color'], 0.8) stats[stat]['color'] = change_opacity(stats[stat]['color'], 0.8)
height = bottom - top height = bottom - top
max_value = y_ticks[-1] max_value = y_ticks[-1]
ratio = height / max_value ratio = height / max_value
for i, y_val in enumerate(y_ticks): for i, y_val in enumerate(y_ticks):
y = int(bottom - y_val * ratio ) - 0.5 y = int(bottom - y_val * ratio) - 0.5
if i != 0: if i != 0:
self.draw_dotted_line(gray, left, y, right, y) self.draw_dotted_line(gray, left, y, right, y)
self.draw_y_text(y_tick_text[i], left, y) self.draw_y_text(y_tick_text[i], left, y)
@ -271,7 +250,6 @@ class Graph:
def draw_legend(self): def draw_legend(self):
pass pass
def trace_path(self, values, max_value, bounds): def trace_path(self, values, max_value, bounds):
(left, top, right, bottom) = bounds (left, top, right, bottom) = bounds
ratio = (bottom - top) / max_value ratio = (bottom - top) / max_value
@ -280,10 +258,10 @@ class Graph:
self.ctx.set_line_width(line_width) self.ctx.set_line_width(line_width)
self.ctx.move_to(right, bottom) self.ctx.move_to(right, bottom)
self.ctx.line_to(right, int(bottom - values[0] * ratio )) self.ctx.line_to(right, int(bottom - values[0] * ratio))
x = right x = right
step = (right - left) / float(self.length -1) step = (right - left) / float(self.length - 1)
for i, value in enumerate(values): for i, value in enumerate(values):
if i == self.length - 1: if i == self.length - 1:
x = left x = left
@ -292,11 +270,10 @@ class Graph:
x -= step x -= step
self.ctx.line_to( self.ctx.line_to(
int(right - (len(values) - 1) * step), int(right - (len(values) - 1) * step),
bottom) bottom)
self.ctx.close_path() self.ctx.close_path()
def draw_value_poly(self, values, color, max_value, bounds, fill=False): def draw_value_poly(self, values, color, max_value, bounds, fill=False):
self.trace_path(values, max_value, bounds) self.trace_path(values, max_value, bounds)
self.ctx.set_source_rgba(*color) self.ctx.set_source_rgba(*color)
@ -313,7 +290,7 @@ class Graph:
height = fe[2] height = fe[2]
x_bearing = te[0] x_bearing = te[0]
width = te[2] width = te[2]
self.ctx.move_to(int(x - width/2.0 + x_bearing), int(y + height)) self.ctx.move_to(int(x - width / 2.0 + x_bearing), int(y + height))
self.ctx.set_source_rgba(*self.black) self.ctx.set_source_rgba(*self.black)
self.ctx.show_text(text) self.ctx.show_text(text)
@ -325,7 +302,7 @@ class Graph:
ascent = fe[0] ascent = fe[0]
x_bearing = te[0] x_bearing = te[0]
width = te[4] width = te[4]
self.ctx.move_to(int(x - width - x_bearing - 2), int(y + (ascent - descent)/2.0)) self.ctx.move_to(int(x - width - x_bearing - 2), int(y + (ascent - descent) / 2.0))
self.ctx.set_source_rgba(*self.black) self.ctx.set_source_rgba(*self.black)
self.ctx.show_text(text) self.ctx.show_text(text)
@ -350,6 +327,3 @@ class Graph:
self.ctx.line_to(x2, y2) self.ctx.line_to(x2, y2)
self.ctx.stroke() self.ctx.stroke()
self.ctx.set_dash(dash, offset) self.ctx.set_dash(dash, offset)
if __name__ == "__main__":
from . import test

View File

@ -1,43 +1,19 @@
# # -*- coding: utf-8 -*-
# gtkui.py
# #
# Copyright (C) 2009 Ian Martin <ianmartin@cantab.net> # Copyright (C) 2009 Ian Martin <ianmartin@cantab.net>
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# 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-2008 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
import logging import logging
import gobject
import gtk import gtk
import gtk.glade import gtk.glade
from gtk.glade import XML from gtk.glade import XML
@ -49,29 +25,31 @@ from deluge.plugins.pluginbase import GtkPluginBase
from deluge.ui.client import client from deluge.ui.client import client
from deluge.ui.gtkui.torrentdetails import Tab from deluge.ui.gtkui.torrentdetails import Tab
from . import common, graph from . import common
from .graph import Graph, size_formatter_scale
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
DEFAULT_CONF = { 'version': 1, DEFAULT_CONF = {'version': 1,
'colors' :{ 'colors': {
'bandwidth_graph': {'upload_rate': str(gtk.gdk.Color("blue")), 'bandwidth_graph': {'upload_rate': str(gtk.gdk.Color("blue")),
'download_rate': str(gtk.gdk.Color("green")), 'download_rate': str(gtk.gdk.Color("green")),
},
'connections_graph': {'dht_nodes': str(gtk.gdk.Color("orange")),
'dht_cache_nodes': str(gtk.gdk.Color("blue")),
'dht_torrents': str(gtk.gdk.Color("green")),
'num_connections': str(gtk.gdk.Color("darkred")),
},
'seeds_graph': {'num_peers': str(gtk.gdk.Color("blue")),
}, },
'connections_graph': { 'dht_nodes': str(gtk.gdk.Color("orange")), }
'dht_cache_nodes': str(gtk.gdk.Color("blue")), }
'dht_torrents': str(gtk.gdk.Color("green")),
'num_connections': str(gtk.gdk.Color("darkred")),
},
'seeds_graph': { 'num_peers': str(gtk.gdk.Color("blue")),
},
}
}
def neat_time(column, cell, model, iter): def neat_time(column, cell, model, iter):
"""Render seconds as seconds or minutes with label""" """Render seconds as seconds or minutes with label"""
seconds = model.get_value(iter, 0) seconds = model.get_value(iter, 0)
if seconds >60: if seconds > 60:
text = "%d %s" % (seconds / 60, _("minutes")) text = "%d %s" % (seconds / 60, _("minutes"))
elif seconds == 60: elif seconds == 60:
text = _("1 minute") text = _("1 minute")
@ -82,16 +60,18 @@ def neat_time(column, cell, model, iter):
cell.set_property('text', text) cell.set_property('text', text)
return return
def int_str(number): def int_str(number):
return (str(int(number))) return (str(int(number)))
def gtk_to_graph_color(color): def gtk_to_graph_color(color):
"""Turns a gtk.gdk.Color into a tuple with range 0-1 as used by the graph""" """Turns a gtk.gdk.Color into a tuple with range 0-1 as used by the graph"""
MAX = float(65535) max_val = float(65535)
gtk_color = gtk.gdk.Color(color) gtk_color = gtk.gdk.Color(color)
red = gtk_color.red / MAX red = gtk_color.red / max_val
green = gtk_color.green / MAX green = gtk_color.green / max_val
blue = gtk_color.blue / MAX blue = gtk_color.blue / max_val
return (red, green, blue) return (red, green, blue)
@ -120,7 +100,7 @@ class GraphsTab(Tab):
self.notebook.connect('switch-page', self._on_notebook_switch_page) self.notebook.connect('switch-page', self._on_notebook_switch_page)
self.selected_interval = 1 #should come from config or similar self.selected_interval = 1 # Should come from config or similar
self.select_bandwidth_graph() self.select_bandwidth_graph()
self.window.unparent() self.window.unparent()
@ -134,12 +114,10 @@ class GraphsTab(Tab):
self.intervals_combo.connect("changed", self._on_selected_interval_changed) self.intervals_combo.connect("changed", self._on_selected_interval_changed)
self.update_intervals() self.update_intervals()
def graph_expose(self, widget, event): def graph_expose(self, widget, event):
context = self.graph_widget.window.cairo_create() context = self.graph_widget.window.cairo_create()
# set a clip region # set a clip region
context.rectangle(event.area.x, event.area.y, context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
event.area.width, event.area.height)
context.clip() context.clip()
self.graph.draw_to_context(context, self.graph.draw_to_context(context,
self.graph_widget.allocation.width, self.graph_widget.allocation.width,
@ -150,6 +128,7 @@ class GraphsTab(Tab):
def update(self): def update(self):
d1 = client.stats.get_stats(self.graph.stat_info.keys(), self.selected_interval) d1 = client.stats.get_stats(self.graph.stat_info.keys(), self.selected_interval)
d1.addCallback(self.graph.set_stats) d1.addCallback(self.graph.set_stats)
def _update_complete(result): def _update_complete(result):
self.graph_widget.queue_draw() self.graph_widget.queue_draw()
d1.addCallback(_update_complete) d1.addCallback(_update_complete)
@ -163,20 +142,20 @@ class GraphsTab(Tab):
def select_bandwidth_graph(self): def select_bandwidth_graph(self):
log.debug("Selecting bandwidth graph") log.debug("Selecting bandwidth graph")
self.graph_widget = self.bandwidth_graph self.graph_widget = self.bandwidth_graph
self.graph = graph.Graph() self.graph = Graph()
colors = self.colors['bandwidth_graph'] colors = self.colors['bandwidth_graph']
self.graph.add_stat('download_rate', label='Download Rate', self.graph.add_stat('download_rate', label='Download Rate',
color=gtk_to_graph_color(colors['download_rate'])) color=gtk_to_graph_color(colors['download_rate']))
self.graph.add_stat('upload_rate', label='Upload Rate', self.graph.add_stat('upload_rate', label='Upload Rate',
color=gtk_to_graph_color(colors['upload_rate'])) color=gtk_to_graph_color(colors['upload_rate']))
self.graph.set_left_axis(formatter=fspeed, min=10240, self.graph.set_left_axis(formatter=fspeed, min=10240,
formatter_scale=graph.size_formatter_scale) formatter_scale=size_formatter_scale)
def select_connections_graph(self): def select_connections_graph(self):
log.debug("Selecting connections graph") log.debug("Selecting connections graph")
self.graph_widget = self.connections_graph self.graph_widget = self.connections_graph
g = graph.Graph() g = Graph()
self.graph = g self.graph = g
colors = self.colors['connections_graph'] colors = self.colors['connections_graph']
g.add_stat('dht_nodes', color=gtk_to_graph_color(colors['dht_nodes'])) g.add_stat('dht_nodes', color=gtk_to_graph_color(colors['dht_nodes']))
@ -187,8 +166,8 @@ class GraphsTab(Tab):
def select_seeds_graph(self): def select_seeds_graph(self):
log.debug("Selecting connections graph") log.debug("Selecting connections graph")
self.graph_widget = self.seeds_graph self.graph_widget = self.seeds_graph
self.graph = graph.Graph() self.graph = Graph()
colors = self.colors['seeds_graph'] colors = self.colors['seeds_graph']
self.graph.add_stat('num_peers', color=gtk_to_graph_color(colors['num_peers'])) self.graph.add_stat('num_peers', color=gtk_to_graph_color(colors['num_peers']))
self.graph.set_left_axis(formatter=int_str, min=10) self.graph.set_left_axis(formatter=int_str, min=10)
@ -197,7 +176,7 @@ class GraphsTab(Tab):
self.colors = colors self.colors = colors
# Fake switch page to update the graph colors (HACKY) # Fake switch page to update the graph colors (HACKY)
self._on_notebook_switch_page(self.notebook, self._on_notebook_switch_page(self.notebook,
None, #This is unused None, # This is unused
self.notebook.get_current_page()) self.notebook.get_current_page())
def _on_intervals_changed(self, intervals): def _on_intervals_changed(self, intervals):
@ -232,6 +211,7 @@ class GraphsTab(Tab):
self.update() self.update()
return True return True
class GtkUI(GtkPluginBase): class GtkUI(GtkPluginBase):
def enable(self): def enable(self):
log.debug("Stats plugin enable called") log.debug("Stats plugin enable called")
@ -266,7 +246,7 @@ class GtkUI(GtkPluginBase):
self.config['colors'] = gtkconf self.config['colors'] = gtkconf
self.graphs_tab.set_colors(self.config['colors']) self.graphs_tab.set_colors(self.config['colors'])
config = { } config = {}
client.stats.set_config(config) client.stats.set_config(config)
def on_show_prefs(self): def on_show_prefs(self):

View File

@ -7,6 +7,7 @@ from . import graph
sclient.set_core_uri() sclient.set_core_uri()
def test_sync(): def test_sync():
if 1: if 1:
upload = sclient.graph_get_upload() upload = sclient.graph_get_upload()
@ -14,8 +15,28 @@ def test_sync():
print(upload) print(upload)
print(download) print(download)
else: else:
upload = [66804, 66915, 66974, 67447, 67540, 67318, 67320, 67249, 66659, 66489, 67027, 66914, 66802, 67303, 67654, 67643, 67763, 67528, 67523, 67431, 67214, 66939, 67316, 67020, 66881, 67103, 67377, 67141, 67366, 67492, 67375, 67203, 67056, 67010, 67029, 66741, 66695, 66868, 66805, 66264, 66249, 66317, 66459, 66306, 66681, 66954, 66662, 66278, 65921, 65695, 65681, 65942, 66000, 66140, 66424, 66480, 66257, 66271, 66145, 65854, 65568, 65268, 65112, 65050, 65027, 64676, 64655, 64178, 64386, 63979, 63271, 62746, 62337, 62297, 62496, 62902, 63801, 64121, 62957, 62921, 63051, 62644, 63240, 64107, 63968, 63987, 63644, 63263, 63153, 62999, 62843, 62777, 63101, 63078, 63178, 63126, 63401, 62630, 62451, 62505, 62254, 61485, 61264, 60937, 60568, 61011, 61109, 60325, 60196, 59640, 59619, 59514, 60813, 60572, 61632, 61689, 63365, 64583, 66396, 67179, 68209, 68295, 67674, 67559, 67195, 66178, 65632, 66124, 66456, 66676, 67183, 67620, 66960, 66347, 65925, 65907, 65896, 66738, 66703, 67060, 67004, 67007, 66329, 65304, 52002, 38969, 25433, 12426, 0, 0] upload = [66804, 66915, 66974, 67447, 67540, 67318, 67320, 67249, 66659, 66489, 67027, 66914, 66802, 67303,
download = [42926, 43853, 43157, 45470, 44254, 46272, 45083, 47344, 46716, 51963, 50112, 52334, 55525, 57545, 53691, 51637, 49574, 49836, 48295, 49843, 52878, 56014, 56966, 56938, 60065, 60461, 56542, 59526, 58678, 54424, 51862, 55109, 52132, 53783, 51687, 56567, 52182, 50758, 46714, 50511, 48161, 50920, 48694, 50528, 55074, 55420, 55882, 59268, 59958, 57938, 57115, 51424, 51180, 53184, 52879, 51177, 54417, 51097, 47901, 49870, 55865, 61118, 61476, 63498, 58878, 49630, 45975, 45632, 45892, 44855, 49495, 48304, 45829, 42152, 39403, 37574, 32384, 34933, 34901, 33492, 31953, 36271, 33826, 34515, 36408, 41106, 43054, 44110, 40810, 41383, 37267, 35881, 38660, 37525, 34857, 36718, 36842, 34281, 39528, 41854, 42952, 40021, 41722, 41045, 42917, 39287, 38672, 32824, 28765, 22686, 18490, 15714, 15268, 14793, 15305, 16354, 16720, 17502, 17857, 16622, 18447, 19929, 31138, 36965, 36158, 32795, 30445, 21997, 18100, 22491, 27227, 29317, 32436, 35700, 39140, 36258, 33697, 24751, 20354, 8211, 3836, 1560, 834, 2034, 1744, 1637, 1637, 1637, 0, 0] 67654, 67643, 67763, 67528, 67523, 67431, 67214, 66939, 67316, 67020, 66881, 67103, 67377, 67141,
67366, 67492, 67375, 67203, 67056, 67010, 67029, 66741, 66695, 66868, 66805, 66264, 66249, 66317,
66459, 66306, 66681, 66954, 66662, 66278, 65921, 65695, 65681, 65942, 66000, 66140, 66424, 66480,
66257, 66271, 66145, 65854, 65568, 65268, 65112, 65050, 65027, 64676, 64655, 64178, 64386, 63979,
63271, 62746, 62337, 62297, 62496, 62902, 63801, 64121, 62957, 62921, 63051, 62644, 63240, 64107,
63968, 63987, 63644, 63263, 63153, 62999, 62843, 62777, 63101, 63078, 63178, 63126, 63401, 62630,
62451, 62505, 62254, 61485, 61264, 60937, 60568, 61011, 61109, 60325, 60196, 59640, 59619, 59514,
60813, 60572, 61632, 61689, 63365, 64583, 66396, 67179, 68209, 68295, 67674, 67559, 67195, 66178,
65632, 66124, 66456, 66676, 67183, 67620, 66960, 66347, 65925, 65907, 65896, 66738, 66703, 67060,
67004, 67007, 66329, 65304, 52002, 38969, 25433, 12426, 0, 0]
download = [42926, 43853, 43157, 45470, 44254, 46272, 45083, 47344, 46716, 51963, 50112, 52334, 55525, 57545,
53691, 51637, 49574, 49836, 48295, 49843, 52878, 56014, 56966, 56938, 60065, 60461, 56542, 59526,
58678, 54424, 51862, 55109, 52132, 53783, 51687, 56567, 52182, 50758, 46714, 50511, 48161, 50920,
48694, 50528, 55074, 55420, 55882, 59268, 59958, 57938, 57115, 51424, 51180, 53184, 52879, 51177,
54417, 51097, 47901, 49870, 55865, 61118, 61476, 63498, 58878, 49630, 45975, 45632, 45892, 44855,
49495, 48304, 45829, 42152, 39403, 37574, 32384, 34933, 34901, 33492, 31953, 36271, 33826, 34515,
36408, 41106, 43054, 44110, 40810, 41383, 37267, 35881, 38660, 37525, 34857, 36718, 36842, 34281,
39528, 41854, 42952, 40021, 41722, 41045, 42917, 39287, 38672, 32824, 28765, 22686, 18490, 15714,
15268, 14793, 15305, 16354, 16720, 17502, 17857, 16622, 18447, 19929, 31138, 36965, 36158, 32795,
30445, 21997, 18100, 22491, 27227, 29317, 32436, 35700, 39140, 36258, 33697, 24751, 20354, 8211,
3836, 1560, 834, 2034, 1744, 1637, 1637, 1637, 0, 0]
from .graph import NetworkGraph from .graph import NetworkGraph
n = NetworkGraph() n = NetworkGraph()
@ -25,6 +46,7 @@ def test_sync():
n.draw(800, 200) n.draw(800, 200)
n.surface.write_to_png('output_sync.png') n.surface.write_to_png('output_sync.png')
def test_async(): def test_async():
g = graph.Graph() g = graph.Graph()
g.add_stat('download_rate', color=graph.green) g.add_stat('download_rate', color=graph.green)
@ -35,6 +57,7 @@ def test_async():
surface = g.draw(600, 300) surface = g.draw(600, 300)
surface.write_to_png('output_async.png') surface.write_to_png('output_async.png')
def test_dht(): def test_dht():
"""'boring graph, but testing if it works'""" """'boring graph, but testing if it works'"""
@ -42,7 +65,7 @@ def test_dht():
g.add_stat('dht_nodes', color=graph.orange) g.add_stat('dht_nodes', color=graph.orange)
g.add_stat('dht_cache_nodes', color=graph.blue) g.add_stat('dht_cache_nodes', color=graph.blue)
g.add_stat('dht_torrents', color=graph.green) g.add_stat('dht_torrents', color=graph.green)
g.add_stat('num_connections', color=graph.darkred) #testing : non dht g.add_stat('num_connections', color=graph.darkred) # testing : non dht
g.set_left_axis(formatter=str, min=10) g.set_left_axis(formatter=str, min=10)
g.async_request() g.async_request()
aclient.force_call(True) aclient.force_call(True)
@ -54,9 +77,10 @@ def test_write():
""" """
writing to a file-like object; need this for webui. writing to a file-like object; need this for webui.
""" """
class fake_file: class FakeFile:
def __init__(self): def __init__(self):
self.data = [] self.data = []
def write(self, str): def write(self, str):
self.data.append(str) self.data.append(str)
@ -68,7 +92,7 @@ def test_write():
aclient.force_call(True) aclient.force_call(True)
surface = g.draw(900, 150) surface = g.draw(900, 150)
file_like = fake_file() file_like = FakeFile()
surface.write_to_png(file_like) surface.write_to_png(file_like)
data = "".join(file_like.data) data = "".join(file_like.data)

View File

@ -1,17 +1,18 @@
from __future__ import print_function from __future__ import print_function
from deluge.common import fsize from deluge.common import fsize
from deluge.ui.client import aclient, sclient from deluge.ui.client import sclient
sclient.set_core_uri() sclient.set_core_uri()
def print_totals(totals): def print_totals(totals):
for name, value in totals.iteritems(): for name, value in totals.iteritems():
print(name, fsize(value)) print(name, fsize(value))
print("overhead:") print("overhead:")
print("up:", fsize(totals["total_upload"] - totals["total_payload_upload"] )) print("up:", fsize(totals["total_upload"] - totals["total_payload_upload"]))
print("down:", fsize(totals["total_download"] - totals["total_payload_download"] )) print("down:", fsize(totals["total_download"] - totals["total_payload_download"]))
print("==totals==") print("==totals==")

View File

@ -1,52 +1,25 @@
# # -*- coding: utf-8 -*-
# webui.py
# #
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# 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-2008 Andrew Resch <andrewresch@gmail.com>
#
# Deluge is free software.
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
import logging import logging
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource from .common import get_resource
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class WebUI(WebPluginBase): class WebUI(WebPluginBase):
scripts = [get_resource("stats.js")] scripts = [get_resource("stats.js")]

View File

@ -1,38 +1,16 @@
# -*- coding: utf-8 -*-
# #
# setup.py
# Copyright (C) 2009 Ian Martin <ianmartin@cantab.net> # Copyright (C) 2009 Ian Martin <ianmartin@cantab.net>
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# #
# 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-2008 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
# #
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
from setuptools import find_packages, setup from setuptools import find_packages, setup
@ -47,7 +25,7 @@ __long_description__ = """
Records lots of extra stats Records lots of extra stats
and produces time series and produces time series
graphs""" graphs"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]} __pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -60,8 +38,8 @@ setup(
long_description=__long_description__, long_description=__long_description__,
packages=find_packages(), packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"], namespace_packages=["deluge", "deluge.plugins"],
package_data = __pkg_data__, package_data=__pkg_data__,
entry_points=""" entry_points="""
[deluge.plugin.core] [deluge.plugin.core]
@ -70,5 +48,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web] [deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin %s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3) """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
) )

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# __init__.py
# #
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com> # Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
# #
@ -8,51 +7,30 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
from deluge.plugins.init import PluginInitBase from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls from .webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# common.py
# #
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com> # Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
# #
@ -8,36 +7,14 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
def get_resource(filename): def get_resource(filename):
import pkg_resources, os import os.path
import pkg_resources
return pkg_resources.resource_filename("deluge.plugins.toggle", return pkg_resources.resource_filename("deluge.plugins.toggle",
os.path.join("data", filename)) os.path.join("data", filename))

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# core.py
# #
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com> # Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
# #
@ -8,39 +7,14 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
import deluge.component as component import deluge.component as component
import deluge.configmanager
from deluge.core.rpcserver import export from deluge.core.rpcserver import export
from deluge.plugins.pluginbase import CorePluginBase from deluge.plugins.pluginbase import CorePluginBase
@ -49,6 +23,7 @@ log = logging.getLogger(__name__)
DEFAULT_PREFS = { DEFAULT_PREFS = {
} }
class Core(CorePluginBase): class Core(CorePluginBase):
def enable(self): def enable(self):
self.core = component.get("Core") self.core = component.get("Core")

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# gtkui.py
# #
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com> # Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
# #
@ -8,54 +7,27 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
import gtk
import deluge.common
import deluge.component as component import deluge.component as component
from deluge.plugins.pluginbase import GtkPluginBase from deluge.plugins.pluginbase import GtkPluginBase
from deluge.ui.client import client from deluge.ui.client import client
from .common import get_resource
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class GtkUI(GtkPluginBase): class GtkUI(GtkPluginBase):
def enable(self): def enable(self):
self.core = client.toggle self.core = client.toggle
self.plugin = component.get("PluginManager") self.plugin = component.get("PluginManager")
self.separator = self.plugin.add_toolbar_separator() self.separator = self.plugin.add_toolbar_separator()
self.button = self.plugin.add_toolbar_button(self._on_button_clicked, label="Pause Session", stock="gtk-media-pause", tooltip="Pause the session") self.button = self.plugin.add_toolbar_button(self._on_button_clicked, label="Pause Session",
stock="gtk-media-pause", tooltip="Pause the session")
def disable(self): def disable(self):
component.get("PluginManager").remove_toolbar_button(self.button) component.get("PluginManager").remove_toolbar_button(self.button)

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# webui.py
# #
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com> # Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
# #
@ -8,45 +7,20 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource from .common import get_resource
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class WebUI(WebPluginBase): class WebUI(WebPluginBase):
scripts = [get_resource("toggle.js")] scripts = [get_resource("toggle.js")]

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# setup.py
# #
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com> # Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
# #
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
from setuptools import find_packages, setup from setuptools import find_packages, setup
@ -47,7 +22,7 @@ __url__ = "http://deluge-torrent.org"
__license__ = "GPLv3" __license__ = "GPLv3"
__description__ = "Toggles the session" __description__ = "Toggles the session"
__long_description__ = """""" __long_description__ = """"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]} __pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -60,8 +35,8 @@ setup(
long_description=__long_description__ if __long_description__ else __description__, long_description=__long_description__ if __long_description__ else __description__,
packages=find_packages(), packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"], namespace_packages=["deluge", "deluge.plugins"],
package_data = __pkg_data__, package_data=__pkg_data__,
entry_points=""" entry_points="""
[deluge.plugin.core] [deluge.plugin.core]
@ -70,5 +45,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web] [deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin %s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3) """ % ((__plugin_name__, __plugin_name__.lower()) * 3)
) )

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# __init__.py
# #
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
@ -7,51 +6,30 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
from deluge.plugins.init import PluginInitBase from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase): class CorePlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .core import Core as _plugin_cls from .core import Core as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name) super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase): class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name) super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase): class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name): def __init__(self, plugin_name):
from webui import WebUI as _plugin_cls from webui import WebUI as _pluginCls
self._plugin_cls = _plugin_cls self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name) super(WebUIPlugin, self).__init__(plugin_name)

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# common.py
# #
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
@ -7,36 +6,14 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
def get_resource(filename): def get_resource(filename):
import pkg_resources, os import os.path
import pkg_resources
return pkg_resources.resource_filename("deluge.plugins.webui", return pkg_resources.resource_filename("deluge.plugins.webui",
os.path.join("data", filename)) os.path.join("data", filename))

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# core.py
# #
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
@ -7,39 +6,14 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
import os
from deluge import common, component, configmanager from deluge import configmanager
from deluge.core.rpcserver import export from deluge.core.rpcserver import export
from deluge.plugins.pluginbase import CorePluginBase from deluge.plugins.pluginbase import CorePluginBase
@ -51,8 +25,8 @@ DEFAULT_PREFS = {
"port": 8112 "port": 8112
} }
class Core(CorePluginBase):
class Core(CorePluginBase):
def enable(self): def enable(self):
self.config = configmanager.ConfigManager("web_plugin.conf", DEFAULT_PREFS) self.config = configmanager.ConfigManager("web_plugin.conf", DEFAULT_PREFS)
@ -80,6 +54,7 @@ class Core(CorePluginBase):
def got_deluge_web(self): def got_deluge_web(self):
try: try:
from deluge.ui.web import server from deluge.ui.web import server
assert server # silence pyflakes
return True return True
except ImportError: except ImportError:
return False return False

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# gtkui.py
# #
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
@ -7,33 +6,9 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# 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 logging import logging
@ -41,7 +16,6 @@ import logging
import gtk import gtk
import gtk.glade import gtk.glade
import deluge.common
import deluge.component as component import deluge.component as component
from deluge.plugins.pluginbase import GtkPluginBase from deluge.plugins.pluginbase import GtkPluginBase
from deluge.ui.client import client from deluge.ui.client import client
@ -50,6 +24,7 @@ from .common import get_resource
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class GtkUI(GtkPluginBase): class GtkUI(GtkPluginBase):
def enable(self): def enable(self):
self.glade = gtk.glade.XML(get_resource("config.glade")) self.glade = gtk.glade.XML(get_resource("config.glade"))
@ -99,7 +74,7 @@ class GtkUI(GtkPluginBase):
hbox.pack_start(icon, False, False) hbox.pack_start(icon, False, False)
label = gtk.Label(_("The Deluge web interface is not installed, " label = gtk.Label(_("The Deluge web interface is not installed, "
"please install the\ninterface and try again")) "please install the\ninterface and try again"))
label.set_alignment(0, 0.5) label.set_alignment(0, 0.5)
label.set_padding(5, 5) label.set_padding(5, 5)
hbox.pack_start(label) hbox.pack_start(label)

View File

@ -1,5 +1,4 @@
# # -*- coding: utf-8 -*-
# setup.py
# #
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com> # Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
# #
@ -7,33 +6,9 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com> # Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# # the additional special exception to link portions of this program with the OpenSSL library.
# You may redistribute it and/or modify it under the terms of the # See LICENSE for more details.
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# 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
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
# #
from setuptools import find_packages, setup from setuptools import find_packages, setup
@ -46,7 +21,7 @@ __url__ = "http://deluge-torrent.org"
__license__ = "GPLv3" __license__ = "GPLv3"
__description__ = "Allows starting the web interface within the daemon." __description__ = "Allows starting the web interface within the daemon."
__long_description__ = """""" __long_description__ = """"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]} __pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup( setup(
name=__plugin_name__, name=__plugin_name__,
@ -59,13 +34,13 @@ setup(
long_description=__long_description__ if __long_description__ else __description__, long_description=__long_description__ if __long_description__ else __description__,
packages=find_packages(), packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"], namespace_packages=["deluge", "deluge.plugins"],
package_data = __pkg_data__, package_data=__pkg_data__,
entry_points=""" entry_points="""
[deluge.plugin.core] [deluge.plugin.core]
%s = deluge.plugins.%s:CorePlugin %s = deluge.plugins.%s:CorePlugin
[deluge.plugin.gtkui] [deluge.plugin.gtkui]
%s = deluge.plugins.%s:GtkUIPlugin %s = deluge.plugins.%s:GtkUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*2) """ % ((__plugin_name__, __plugin_name__.lower()) * 2)
) )

View File

@ -72,15 +72,15 @@ def create_plugin():
def write_file(path, filename, template, include_gpl=True): def write_file(path, filename, template, include_gpl=True):
args = { args = {
"author_name": options.author_name, "author_name": options.author_name,
"author_email": options.author_email, "author_email": options.author_email,
"name": name, "name": name,
"safe_name": safe_name, "safe_name": safe_name,
"filename": filename, "filename": filename,
"plugin_base": plugin_base, "plugin_base": plugin_base,
"python_path": python_path, "python_path": python_path,
"url": options.url, "url": options.url,
"configdir": options.configdir, "configdir": options.configdir,
"current_year": datetime.utcnow().year "current_year": datetime.utcnow().year
} }

View File

@ -13,28 +13,36 @@
import logging import logging
from optparse import OptionParser from optparse import OptionParser
from sys import argv, exit, stderr from sys import exit, stderr
def isFloatDigit (string): def is_float_digit(string):
if string.isdigit(): if string.isdigit():
return True return True
else: else:
try: try:
tmp = float(string) float(string)
return True return True
except: return False; except:
return False
# set up command-line options # set up command-line options
parser = OptionParser() parser = OptionParser()
parser.add_option("--port", help="port for deluge backend host (default: 58846)", default="58846", dest="port") parser.add_option("--port", help="port for deluge backend host (default: 58846)", default="58846", dest="port")
parser.add_option("--host", help="hostname of deluge backend to connect to (default: localhost)", default="localhost", dest="host") parser.add_option("--host", help="hostname of deluge backend to connect to (default: localhost)",
parser.add_option("--max_active_limit", help="sets the absolute maximum number of active torrents on the deluge backend", dest="max_active_limit") default="localhost", dest="host")
parser.add_option("--max_active_downloading", help="sets the maximum number of active downloading torrents on the deluge backend", dest="max_active_downloading") parser.add_option("--max_active_limit", dest="max_active_limit",
parser.add_option("--max_active_seeding", help="sets the maximum number of active seeding torrents on the deluge backend", dest="max_active_seeding") help="sets the absolute maximum number of active torrents on the deluge backend")
parser.add_option("--max_download_speed", help="sets the maximum global download speed on the deluge backend", dest="max_download_speed") parser.add_option("--max_active_downloading", dest="max_active_downloading",
parser.add_option("--max_upload_speed", help="sets the maximum global upload speed on the deluge backend", dest="max_upload_speed") help="sets the maximum number of active downloading torrents on the deluge backend")
parser.add_option("--debug", help="outputs debug information to the console", default=False, action="store_true", dest="debug") parser.add_option("--max_active_seeding", dest="max_active_seeding",
help="sets the maximum number of active seeding torrents on the deluge backend")
parser.add_option("--max_download_speed", help="sets the maximum global download speed on the deluge backend",
dest="max_download_speed")
parser.add_option("--max_upload_speed", help="sets the maximum global upload speed on the deluge backend",
dest="max_upload_speed")
parser.add_option("--debug", help="outputs debug information to the console", default=False, action="store_true",
dest="debug")
# grab command-line options # grab command-line options
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
@ -49,36 +57,38 @@ if options.max_active_limit:
if options.max_active_limit.isdigit() and int(options.max_active_limit) >= 0: if options.max_active_limit.isdigit() and int(options.max_active_limit) >= 0:
settings['max_active_limit'] = int(options.max_active_limit) settings['max_active_limit'] = int(options.max_active_limit)
else: else:
stderr.write ("ERROR: Invalid max_active_limit parameter!\n") stderr.write("ERROR: Invalid max_active_limit parameter!\n")
exit (-1) exit(-1)
if options.max_active_downloading: if options.max_active_downloading:
if options.max_active_downloading.isdigit() and int(options.max_active_downloading) >= 0: if options.max_active_downloading.isdigit() and int(options.max_active_downloading) >= 0:
settings['max_active_downloading'] = int(options.max_active_downloading) settings['max_active_downloading'] = int(options.max_active_downloading)
else: else:
stderr.write ("ERROR: Invalid max_active_downloading parameter!\n") stderr.write("ERROR: Invalid max_active_downloading parameter!\n")
exit (-1) exit(-1)
if options.max_active_seeding: if options.max_active_seeding:
if options.max_active_seeding.isdigit() and int(options.max_active_seeding) >= 0: if options.max_active_seeding.isdigit() and int(options.max_active_seeding) >= 0:
settings['max_active_seeding'] = int(options.max_active_seeding) settings['max_active_seeding'] = int(options.max_active_seeding)
else: else:
stderr.write ("ERROR: Invalid max_active_seeding parameter!\n") stderr.write("ERROR: Invalid max_active_seeding parameter!\n")
exit (-1) exit(-1)
if options.max_download_speed: if options.max_download_speed:
if isFloatDigit(options.max_download_speed) and (float(options.max_download_speed) >= 0.0 or float(options.max_download_speed) == -1.0): if is_float_digit(options.max_download_speed) and (
float(options.max_download_speed) >= 0.0 or float(options.max_download_speed) == -1.0):
settings['max_download_speed'] = float(options.max_download_speed) settings['max_download_speed'] = float(options.max_download_speed)
else: else:
stderr.write ("ERROR: Invalid max_download_speed parameter!\n") stderr.write("ERROR: Invalid max_download_speed parameter!\n")
exit (-1) exit(-1)
if options.max_upload_speed: if options.max_upload_speed:
if isFloatDigit(options.max_upload_speed) and (float(options.max_upload_speed) >= 0.0 or float(options.max_upload_speed) == -1.0): if is_float_digit(options.max_upload_speed) and (
float(options.max_upload_speed) >= 0.0 or float(options.max_upload_speed) == -1.0):
settings['max_upload_speed'] = float(options.max_upload_speed) settings['max_upload_speed'] = float(options.max_upload_speed)
else: else:
stderr.write ("ERROR: Invalid max_upload_speed parameter!\n") stderr.write("ERROR: Invalid max_upload_speed parameter!\n")
exit (-1) exit(-1)
# If there is something to do ... # If there is something to do ...
if settings: if settings:

View File

@ -10,7 +10,7 @@ import deluge.common
import deluge.configmanager import deluge.configmanager
import deluge.log import deluge.log
deluge.log.setupLogger("none") deluge.log.setup_logger("none")
def set_tmp_config_dir(): def set_tmp_config_dir():
@ -27,8 +27,8 @@ deluge.common.setup_translations()
def start_core(listen_port=58846): def start_core(listen_port=58846):
CWD = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) cwd = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
DAEMON_SCRIPT = """ daemon_script = """
import sys import sys
import deluge.main import deluge.main
@ -38,10 +38,10 @@ deluge.main.start_daemon()
""" """
config_directory = set_tmp_config_dir() config_directory = set_tmp_config_dir()
fp = tempfile.TemporaryFile() fp = tempfile.TemporaryFile()
fp.write(DAEMON_SCRIPT % (config_directory, listen_port)) fp.write(daemon_script % (config_directory, listen_port))
fp.seek(0) fp.seek(0)
core = Popen([sys.executable], cwd=CWD, stdin=fp, stdout=PIPE, stderr=PIPE) core = Popen([sys.executable], cwd=cwd, stdin=fp, stdout=PIPE, stderr=PIPE)
while True: while True:
line = core.stderr.readline() line = core.stderr.readline()
if ("starting on %d" % listen_port) in line: if ("starting on %d" % listen_port) in line:

View File

@ -5,13 +5,13 @@ from deluge.core.core import Core
class AlertManagerTestCase(unittest.TestCase): class AlertManagerTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
self.core = Core() self.core = Core()
self.am = component.get("AlertManager") self.am = component.get("AlertManager")
component.start(["AlertManager"]) component.start(["AlertManager"])
def tearDown(self): def tearDown(self): # NOQA
def on_shutdown(result): def on_shutdown(result):
component._ComponentRegistry.components = {} component._ComponentRegistry.components = {}
del self.am del self.am

View File

@ -4,7 +4,7 @@ from deluge.core.authmanager import AUTH_LEVEL_ADMIN, AuthManager
class AuthManagerTestCase(unittest.TestCase): class AuthManagerTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
self.auth = AuthManager() self.auth = AuthManager()
self.auth.start() self.auth.start()

View File

@ -64,7 +64,7 @@ class NoVersionSendingClient(Client):
class ClientTestCase(unittest.TestCase): class ClientTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
self.listen_port = 58846 self.listen_port = 58846
tries = 10 tries = 10
error = None error = None
@ -81,7 +81,7 @@ class ClientTestCase(unittest.TestCase):
if error: if error:
raise error raise error
def tearDown(self): def tearDown(self): # NOQA
self.core.terminate() self.core.terminate()
def test_connect_no_credentials(self): def test_connect_no_credentials(self):

View File

@ -7,10 +7,10 @@ from deluge.common import (fdate, fpcnt, fpeer, fsize, fspeed, ftime, get_path_s
class CommonTestCase(unittest.TestCase): class CommonTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
setup_translations() setup_translations()
def tearDown(self): def tearDown(self): # NOQA
pass pass
def test_fsize(self): def test_fsize(self):
@ -55,7 +55,7 @@ class CommonTestCase(unittest.TestCase):
self.failUnless(is_ip("127.0.0.1")) self.failUnless(is_ip("127.0.0.1"))
self.failIf(is_ip("127..0.0")) self.failIf(is_ip("127..0.0"))
def test_VersionSplit(self): def test_version_split(self):
self.failUnless(VersionSplit("1.2.2") == VersionSplit("1.2.2")) self.failUnless(VersionSplit("1.2.2") == VersionSplit("1.2.2"))
self.failUnless(VersionSplit("1.2.1") < VersionSplit("1.2.2")) self.failUnless(VersionSplit("1.2.1") < VersionSplit("1.2.2"))
self.failUnless(VersionSplit("1.1.9") < VersionSplit("1.2.2")) self.failUnless(VersionSplit("1.1.9") < VersionSplit("1.2.2"))

View File

@ -4,7 +4,7 @@ from twisted.trial import unittest
import deluge.component as component import deluge.component as component
class testcomponent(component.Component): class TestComponent(component.Component):
def __init__(self, name, depend=None): def __init__(self, name, depend=None):
component.Component.__init__(self, name, depend=depend) component.Component.__init__(self, name, depend=depend)
self.start_count = 0 self.start_count = 0
@ -17,7 +17,7 @@ class testcomponent(component.Component):
self.stop_count += 1 self.stop_count += 1
class testcomponent_delaystart(testcomponent): class TestComponentDelayStart(TestComponent):
def start(self): def start(self):
def do_sleep(): def do_sleep():
import time import time
@ -29,7 +29,7 @@ class testcomponent_delaystart(testcomponent):
return d.addCallback(on_done) return d.addCallback(on_done)
class testcomponent_update(component.Component): class TestComponentUpdate(component.Component):
def __init__(self, name): def __init__(self, name):
component.Component.__init__(self, name) component.Component.__init__(self, name)
self.counter = 0 self.counter = 0
@ -43,7 +43,7 @@ class testcomponent_update(component.Component):
self.stop_count += 1 self.stop_count += 1
class testcomponent_shutdown(component.Component): class TestComponentShutdown(component.Component):
def __init__(self, name): def __init__(self, name):
component.Component.__init__(self, name) component.Component.__init__(self, name)
self.shutdowned = False self.shutdowned = False
@ -57,7 +57,7 @@ class testcomponent_shutdown(component.Component):
class ComponentTestClass(unittest.TestCase): class ComponentTestClass(unittest.TestCase):
def tearDown(self): def tearDown(self): # NOQA
component.stop() component.stop()
component._ComponentRegistry.components = {} component._ComponentRegistry.components = {}
@ -66,7 +66,7 @@ class ComponentTestClass(unittest.TestCase):
self.assertEquals(c._component_state, "Started") self.assertEquals(c._component_state, "Started")
self.assertEquals(c.start_count, 1) self.assertEquals(c.start_count, 1)
c = testcomponent("test_start_c1") c = TestComponent("test_start_c1")
d = component.start(["test_start_c1"]) d = component.start(["test_start_c1"])
d.addCallback(on_start, c) d.addCallback(on_start, c)
return d return d
@ -85,20 +85,19 @@ class ComponentTestClass(unittest.TestCase):
self.assertEquals(c2.start_count, 1) self.assertEquals(c2.start_count, 1)
return component.stop(["test_start_depends_c1"]).addCallback(on_stop, c1, c2) return component.stop(["test_start_depends_c1"]).addCallback(on_stop, c1, c2)
c1 = testcomponent("test_start_depends_c1") c1 = TestComponent("test_start_depends_c1")
c2 = testcomponent("test_start_depends_c2", depend=["test_start_depends_c1"]) c2 = TestComponent("test_start_depends_c2", depend=["test_start_depends_c1"])
d = component.start(["test_start_depends_c2"]) d = component.start(["test_start_depends_c2"])
d.addCallback(on_start, c1, c2) d.addCallback(on_start, c1, c2)
return d return d
def start_with_depends(self): def start_with_depends(self):
c1 = testcomponent_delaystart("test_start_all_c1") c1 = TestComponentDelayStart("test_start_all_c1")
c2 = testcomponent("test_start_all_c2", depend=["test_start_all_c4"]) c2 = TestComponent("test_start_all_c2", depend=["test_start_all_c4"])
c3 = testcomponent_delaystart("test_start_all_c3", c3 = TestComponentDelayStart("test_start_all_c3", depend=["test_start_all_c5", "test_start_all_c1"])
depend=["test_start_all_c5", "test_start_all_c1"]) c4 = TestComponent("test_start_all_c4", depend=["test_start_all_c3"])
c4 = testcomponent("test_start_all_c4", depend=["test_start_all_c3"]) c5 = TestComponent("test_start_all_c5")
c5 = testcomponent("test_start_all_c5")
d = component.start() d = component.start()
return (d, c1, c2, c3, c4, c5) return (d, c1, c2, c3, c4, c5)
@ -119,10 +118,10 @@ class ComponentTestClass(unittest.TestCase):
return ret[0] return ret[0]
def test_register_exception(self): def test_register_exception(self):
testcomponent("test_register_exception_c1") TestComponent("test_register_exception_c1")
self.assertRaises( self.assertRaises(
component.ComponentAlreadyRegistered, component.ComponentAlreadyRegistered,
testcomponent, TestComponent,
"test_register_exception_c1") "test_register_exception_c1")
def test_stop_component(self): def test_stop_component(self):
@ -135,7 +134,7 @@ class ComponentTestClass(unittest.TestCase):
self.assertEquals(c._component_state, "Started") self.assertEquals(c._component_state, "Started")
return component.stop(["test_stop_component_c1"]).addCallback(on_stop, c) return component.stop(["test_stop_component_c1"]).addCallback(on_stop, c)
c = testcomponent_update("test_stop_component_c1") c = TestComponentUpdate("test_stop_component_c1")
d = component.start(["test_stop_component_c1"]) d = component.start(["test_stop_component_c1"])
d.addCallback(on_start, c) d.addCallback(on_start, c)
return d return d
@ -163,7 +162,7 @@ class ComponentTestClass(unittest.TestCase):
self.assertNotEqual(c1.counter, counter) self.assertNotEqual(c1.counter, counter)
return component.stop() return component.stop()
c1 = testcomponent_update("test_update_c1") c1 = TestComponentUpdate("test_update_c1")
cnt = int(c1.counter) cnt = int(c1.counter)
d = component.start(["test_update_c1"]) d = component.start(["test_update_c1"])
@ -183,7 +182,7 @@ class ComponentTestClass(unittest.TestCase):
d.addCallback(on_pause, c1, counter) d.addCallback(on_pause, c1, counter)
return d return d
c1 = testcomponent_update("test_pause_c1") c1 = TestComponentUpdate("test_pause_c1")
cnt = int(c1.counter) cnt = int(c1.counter)
d = component.start(["test_pause_c1"]) d = component.start(["test_pause_c1"])
@ -201,7 +200,7 @@ class ComponentTestClass(unittest.TestCase):
d.addCallback(on_shutdown, c1) d.addCallback(on_shutdown, c1)
return d return d
c1 = testcomponent_shutdown("test_shutdown_c1") c1 = TestComponentShutdown("test_shutdown_c1")
d = component.start(["test_shutdown_c1"]) d = component.start(["test_shutdown_c1"])
d.addCallback(on_start, c1) d.addCallback(on_start, c1)
return d return d

View File

@ -13,7 +13,7 @@ DEFAULTS = {"string": "foobar", "int": 1, "float": 0.435, "bool": True, "unicode
class ConfigTestCase(unittest.TestCase): class ConfigTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
self.config_dir = set_tmp_config_dir() self.config_dir = set_tmp_config_dir()
def test_init(self): def test_init(self):

View File

@ -67,14 +67,14 @@ class TopLevelResource(Resource):
class CoreTestCase(unittest.TestCase): class CoreTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
common.set_tmp_config_dir() common.set_tmp_config_dir()
self.rpcserver = RPCServer(listen=False) self.rpcserver = RPCServer(listen=False)
self.core = Core() self.core = Core()
self.listen_port = 51242 self.listen_port = 51242
return component.start().addCallback(self.startWebserver) return component.start().addCallback(self.start_web_server)
def startWebserver(self, result): def start_web_server(self, result):
self.website = Site(TopLevelResource()) self.website = Site(TopLevelResource())
tries = 10 tries = 10
error = None error = None
@ -92,7 +92,7 @@ class CoreTestCase(unittest.TestCase):
raise error raise error
return result return result
def tearDown(self): def tearDown(self): # NOQA
def on_shutdown(result): def on_shutdown(result):
component._ComponentRegistry.components = {} component._ComponentRegistry.components = {}

View File

@ -4,32 +4,32 @@ import deluge.error
class ErrorTestCase(unittest.TestCase): class ErrorTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
pass pass
def tearDown(self): def tearDown(self): # NOQA
pass pass
def test_DelugeError(self): def test_deluge_error(self):
msg = "Some message" msg = "Some message"
e = deluge.error.DelugeError(msg) e = deluge.error.DelugeError(msg)
self.assertEquals(str(e), msg) self.assertEquals(str(e), msg)
self.assertEquals(e._args, (msg,)) self.assertEquals(e._args, (msg,))
self.assertEquals(e._kwargs, {}) self.assertEquals(e._kwargs, {})
def test_IncompatibleClient(self): def test_incompatible_client(self):
version = "1.3.6" version = "1.3.6"
e = deluge.error.IncompatibleClient(version) e = deluge.error.IncompatibleClient(version)
self.assertEquals(str(e), "Your deluge client is not compatible with the daemon. \ self.assertEquals(str(e), "Your deluge client is not compatible with the daemon. \
Please upgrade your client to %s" % version) Please upgrade your client to %s" % version)
def test_NotAuthorizedError(self): def test_not_authorized_error(self):
current_level = 5 current_level = 5
required_level = 10 required_level = 10
e = deluge.error.NotAuthorizedError(current_level, required_level) e = deluge.error.NotAuthorizedError(current_level, required_level)
self.assertEquals(str(e), "Auth level too low: %d < %d" % (current_level, required_level)) self.assertEquals(str(e), "Auth level too low: %d < %d" % (current_level, required_level))
def test_BadLoginError(self): def test_bad_login_error(self):
message = "Login failed" message = "Login failed"
username = "deluge" username = "deluge"
e = deluge.error.BadLoginError(message, username) e = deluge.error.BadLoginError(message, username)

View File

@ -10,7 +10,7 @@ from twisted.web.server import Site
import deluge.tests.common as common import deluge.tests.common as common
from deluge.httpdownloader import download_file from deluge.httpdownloader import download_file
from deluge.log import setupLogger from deluge.log import setup_logger
from deluge.ui.web.common import compress from deluge.ui.web.common import compress
try: try:
@ -75,7 +75,7 @@ class TopLevelResource(Resource):
self.putChild("redirect", TestRedirectResource()) self.putChild("redirect", TestRedirectResource())
self.putChild("rename", TestRenameResource()) self.putChild("rename", TestRenameResource())
def getChild(self, path, request): def getChild(self, path, request): # NOQA
if path == "": if path == "":
return self return self
else: else:
@ -89,8 +89,8 @@ class TopLevelResource(Resource):
class DownloadFileTestCase(unittest.TestCase): class DownloadFileTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
setupLogger("warning", "log_file") setup_logger("warning", "log_file")
self.website = Site(TopLevelResource()) self.website = Site(TopLevelResource())
self.listen_port = 51242 self.listen_port = 51242
tries = 10 tries = 10
@ -108,10 +108,10 @@ class DownloadFileTestCase(unittest.TestCase):
if error: if error:
raise error raise error
def tearDown(self): def tearDown(self): # NOQA
return self.webserver.stopListening() return self.webserver.stopListening()
def assertContains(self, filename, contents): def assertContains(self, filename, contents): # NOQA
f = open(filename) f = open(filename)
try: try:
self.assertEqual(f.read(), contents) self.assertEqual(f.read(), contents)
@ -121,7 +121,7 @@ class DownloadFileTestCase(unittest.TestCase):
f.close() f.close()
return filename return filename
def failIfContains(self, filename, contents): def failIfContains(self, filename, contents): # NOQA
f = open(filename) f = open(filename)
try: try:
self.failIfEqual(f.read(), contents) self.failIfEqual(f.read(), contents)

View File

@ -3,17 +3,17 @@ import logging
from twisted.internet import defer from twisted.internet import defer
from twisted.trial import unittest from twisted.trial import unittest
from deluge.log import setupLogger from deluge.log import setup_logger
class LogTestCase(unittest.TestCase): class LogTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
setupLogger(logging.DEBUG) setup_logger(logging.DEBUG)
def tearDown(self): def tearDown(self): # NOQA
setupLogger("none") setup_logger("none")
def test_old_LOG_deprecation_warning(self): def test_old_log_deprecation_warning(self):
import warnings import warnings
from deluge.log import LOG from deluge.log import LOG
warnings.filterwarnings("ignore", category=DeprecationWarning, warnings.filterwarnings("ignore", category=DeprecationWarning,

View File

@ -14,10 +14,10 @@ import deluge.error
from deluge.core import rpcserver from deluge.core import rpcserver
from deluge.core.authmanager import AuthManager from deluge.core.authmanager import AuthManager
from deluge.core.rpcserver import DelugeRPCProtocol, RPCServer from deluge.core.rpcserver import DelugeRPCProtocol, RPCServer
from deluge.log import setupLogger from deluge.log import setup_logger
from deluge.ui.common import get_localhost_auth from deluge.ui.common import get_localhost_auth
setupLogger("none") setup_logger("none")
class DelugeRPCProtocolTester(DelugeRPCProtocol): class DelugeRPCProtocolTester(DelugeRPCProtocol):
@ -30,7 +30,7 @@ class DelugeRPCProtocolTester(DelugeRPCProtocol):
class RPCServerTestCase(unittest.TestCase): class RPCServerTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
self.rpcserver = RPCServer(listen=False) self.rpcserver = RPCServer(listen=False)
self.rpcserver.factory.protocol = DelugeRPCProtocolTester self.rpcserver.factory.protocol = DelugeRPCProtocolTester
self.factory = self.rpcserver.factory self.factory = self.rpcserver.factory
@ -45,7 +45,7 @@ class RPCServerTestCase(unittest.TestCase):
self.protocol.sessionno = self.session_id self.protocol.sessionno = self.session_id
return component.start() return component.start()
def tearDown(self): def tearDown(self): # NOQA
def on_shutdown(result): def on_shutdown(result):
component._ComponentRegistry.components = {} component._ComponentRegistry.components = {}
del self.rpcserver del self.rpcserver

View File

@ -90,7 +90,7 @@ deluge.ui.sessionproxy.client = client
class SessionProxyTestCase(unittest.TestCase): class SessionProxyTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
self.sp = deluge.ui.sessionproxy.SessionProxy() self.sp = deluge.ui.sessionproxy.SessionProxy()
client.core.reset() client.core.reset()
d = self.sp.start() d = self.sp.start()
@ -101,7 +101,7 @@ class SessionProxyTestCase(unittest.TestCase):
d.addCallback(do_get_torrents_status) d.addCallback(do_get_torrents_status)
return d return d
def tearDown(self): def tearDown(self): # NOQA
return component.deregister(self.sp) return component.deregister(self.sp)
def test_startup(self): def test_startup(self):

View File

@ -38,7 +38,7 @@ class TorrentTestCase(unittest.TestCase):
config_dir=config_dir) config_dir=config_dir)
core_config.save() core_config.save()
def setUp(self): def setUp(self): # NOQA
# Save component and set back on teardown # Save component and set back on teardown
self.original_component = deluge.core.torrent.component self.original_component = deluge.core.torrent.component
deluge.core.torrent.component = sys.modules[__name__] deluge.core.torrent.component = sys.modules[__name__]
@ -51,7 +51,7 @@ class TorrentTestCase(unittest.TestCase):
self.torrent = None self.torrent = None
return component.start() return component.start()
def tearDown(self): def tearDown(self): # NOQA
deluge.core.torrent.component = self.original_component deluge.core.torrent.component = self.original_component
def on_shutdown(result): def on_shutdown(result):

View File

@ -17,7 +17,7 @@ import deluge.log
import deluge.rencode as rencode import deluge.rencode as rencode
from deluge.transfer import DelugeTransferProtocol from deluge.transfer import DelugeTransferProtocol
deluge.log.setupLogger("none") deluge.log.setup_logger("none")
class TransferTestClass(DelugeTransferProtocol): class TransferTestClass(DelugeTransferProtocol):
@ -49,7 +49,7 @@ class TransferTestClass(DelugeTransferProtocol):
def get_messages_in(self): def get_messages_in(self):
return self.messages_in return self.messages_in
def dataReceived_old_protocol(self, data): def data_received_old_protocol(self, data):
""" """
This is the original method logic (as close as possible) for handling data receival on the client This is the original method logic (as close as possible) for handling data receival on the client
@ -106,7 +106,7 @@ class TransferTestClass(DelugeTransferProtocol):
class DelugeTransferProtocolTestCase(unittest.TestCase): class DelugeTransferProtocolTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
""" """
The expected messages corresponds to the test messages (msg1, msg2) after they've been processed The expected messages corresponds to the test messages (msg1, msg2) after they've been processed
by DelugeTransferProtocol.send, which means that they've first been encoded with pickle, by DelugeTransferProtocol.send, which means that they've first been encoded with pickle,
@ -247,7 +247,7 @@ class DelugeTransferProtocolTestCase(unittest.TestCase):
print("two_messages_byte_count:", two_messages_byte_count) print("two_messages_byte_count:", two_messages_byte_count)
print("three_messages_byte_count:", three_messages_byte_count) print("three_messages_byte_count:", three_messages_byte_count)
for d in self.receive_parts_helper(msg_bytes, packet_size, self.transfer.dataReceived_old_protocol): for d in self.receive_parts_helper(msg_bytes, packet_size, self.transfer.data_received_old_protocol):
bytes_received = self.transfer.get_bytes_recv() bytes_received = self.transfer.get_bytes_recv()
if bytes_received >= three_messages_byte_count: if bytes_received >= three_messages_byte_count:

View File

@ -7,10 +7,10 @@ from deluge.ui.common import TorrentInfo
class UICommonTestCase(unittest.TestCase): class UICommonTestCase(unittest.TestCase):
def setUp(self): def setUp(self): # NOQA
pass pass
def tearDown(self): def tearDown(self): # NOQA
pass pass
def test_utf8_encoded_paths(self): def test_utf8_encoded_paths(self):

View File

@ -56,7 +56,7 @@ class DelugeTransferProtocol(Protocol):
self.transport.write(header) self.transport.write(header)
self.transport.write(compressed) self.transport.write(compressed)
def dataReceived(self, data): def dataReceived(self, data): # NOQA
""" """
This method is called whenever data is received. This method is called whenever data is received.

View File

@ -73,7 +73,7 @@ class DelugeRPCRequest(object):
class DelugeRPCProtocol(DelugeTransferProtocol): class DelugeRPCProtocol(DelugeTransferProtocol):
def connectionMade(self): def connectionMade(self): # NOQA
self.__rpc_requests = {} self.__rpc_requests = {}
# Set the protocol in the daemon so it can send data # Set the protocol in the daemon so it can send data
self.factory.daemon.protocol = self self.factory.daemon.protocol = self
@ -192,16 +192,16 @@ class DelugeRPCClientFactory(ClientFactory):
self.daemon = daemon self.daemon = daemon
self.event_handlers = event_handlers self.event_handlers = event_handlers
def startedConnecting(self, connector): def startedConnecting(self, connector): # NOQA
log.info("Connecting to daemon at \"%s:%s\"...", log.info("Connecting to daemon at \"%s:%s\"...",
connector.host, connector.port) connector.host, connector.port)
def clientConnectionFailed(self, connector, reason): def clientConnectionFailed(self, connector, reason): # NOQA
log.warning("Connection to daemon at \"%s:%s\" failed: %s", log.warning("Connection to daemon at \"%s:%s\" failed: %s",
connector.host, connector.port, reason.value) connector.host, connector.port, reason.value)
self.daemon.connect_deferred.errback(reason) self.daemon.connect_deferred.errback(reason)
def clientConnectionLost(self, connector, reason): def clientConnectionLost(self, connector, reason): # NOQA
log.info("Connection lost to daemon at \"%s:%s\" reason: %s", log.info("Connection lost to daemon at \"%s:%s\" reason: %s",
connector.host, connector.port, reason.value) connector.host, connector.port, reason.value)
self.daemon.host = None self.daemon.host = None

View File

@ -21,9 +21,9 @@ class Command(BaseCommand):
def handle(self, state="", **options): def handle(self, state="", **options):
if state == "on": if state == "on":
deluge.log.setLoggerLevel("debug") deluge.log.set_logger_level("debug")
elif state == "off": elif state == "off":
deluge.log.setLoggerLevel("error") deluge.log.set_logger_level("error")
else: else:
component.get("ConsoleUI").write("{!error!}%s" % self.usage) component.get("ConsoleUI").write("{!error!}%s" % self.usage)

View File

@ -21,7 +21,7 @@ from deluge.ui.common import TorrentInfo
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def __bracket_fixup(path): def _bracket_fixup(path):
if (path.find("[") == -1 and path.find("]") == -1): if (path.find("[") == -1 and path.find("]") == -1):
return path return path
sentinal = 256 sentinal = 256
@ -48,7 +48,7 @@ def add_torrent(t_file, options, success_cb, fail_cb, ress):
if is_url or is_magnet: if is_url or is_magnet:
files = [t_file] files = [t_file]
else: else:
files = glob.glob(__bracket_fixup(t_file)) files = glob.glob(_bracket_fixup(t_file))
num_files = len(files) num_files = len(files)
ress["total"] = num_files ress["total"] = num_files

View File

@ -468,7 +468,7 @@ class AddTorrents(BaseMode, component.Component):
self.__refresh_listing() self.__refresh_listing()
def _doRead(self): def read_input(self):
c = self.stdscr.getch() c = self.stdscr.getch()
if self.popup: if self.popup:

View File

@ -1137,7 +1137,7 @@ class AllTorrents(BaseMode, component.Component):
self.search_state = SEARCH_EMPTY self.search_state = SEARCH_EMPTY
self.refresh([]) self.refresh([])
def _doRead(self): def read_input(self):
# Read the character # Read the character
effected_lines = None effected_lines = None

View File

@ -41,11 +41,11 @@ class CursesStdIO(object):
""" We want to select on FD 0 """ """ We want to select on FD 0 """
return 0 return 0
def doRead(self): def doRead(self): # NOQA
"""called when input is ready""" """called when input is ready"""
pass pass
def logPrefix(self): def logPrefix(self): # NOQA
return "CursesClient" return "CursesClient"
@ -57,7 +57,7 @@ class BaseMode(CursesStdIO):
Modes should subclass this and provide overrides for: Modes should subclass this and provide overrides for:
_doRead(self) - Handle user input do_read(self) - Handle user input
refresh(self) - draw the mode to the screen refresh(self) - draw the mode to the screen
add_string(self, row, string) - add a string of text to be displayed. add_string(self, row, string) - add a string of text to be displayed.
see method for detailed info see method for detailed info
@ -107,7 +107,7 @@ class BaseMode(CursesStdIO):
self.on_resize_norefresh(args) self.on_resize_norefresh(args)
self.refresh() self.refresh()
def connectionLost(self, reason): def connectionLost(self, reason): # NOQA
self.close() self.close()
def add_string(self, row, string, scr=None, col=0, pad=True, trim=True): def add_string(self, row, string, scr=None, col=0, pad=True, trim=True):
@ -192,18 +192,18 @@ class BaseMode(CursesStdIO):
self.stdscr.redrawwin() self.stdscr.redrawwin()
self.stdscr.refresh() self.stdscr.refresh()
def doRead(self): def doRead(self): # NOQA
""" """
Called when there is data to be read, ie, input from the keyboard. Called when there is data to be read, ie, input from the keyboard.
""" """
# We wrap this function to catch exceptions and shutdown the mainloop # We wrap this function to catch exceptions and shutdown the mainloop
try: try:
self._doRead() self.read_input()
except Exception as ex: except Exception as ex:
log.exception(ex) log.exception(ex)
reactor.stop() reactor.stop()
def _doRead(self): def read_input(self):
# Read the character # Read the character
self.stdscr.getch() self.stdscr.getch()
self.stdscr.refresh() self.stdscr.refresh()

View File

@ -167,7 +167,7 @@ class ConnectionManager(BaseMode):
self.stdscr.erase() self.stdscr.erase()
self.refresh() self.refresh()
def _doRead(self): def read_input(self):
# Read the character # Read the character
c = self.stdscr.getch() c = self.stdscr.getch()

View File

@ -85,7 +85,7 @@ class EventView(BaseMode):
component.get("ConsoleUI").set_mode(self.parent_mode) component.get("ConsoleUI").set_mode(self.parent_mode)
self.parent_mode.resume() self.parent_mode.resume()
def _doRead(self): def read_input(self):
c = self.stdscr.getch() c = self.stdscr.getch()
if c > 31 and c < 256: if c > 31 and c < 256:

View File

@ -215,7 +215,7 @@ class Legacy(BaseMode, component.Component):
self.add_string(self.rows - 2, self.statusbars.bottombar) self.add_string(self.rows - 2, self.statusbars.bottombar)
self.stdscr.refresh() self.stdscr.refresh()
def _doRead(self): def read_input(self):
# Read the character # Read the character
c = self.stdscr.getch() c = self.stdscr.getch()

View File

@ -41,8 +41,8 @@ class Popup:
NB: The parent mode is responsible for calling refresh on any popups it wants to show. NB: The parent mode is responsible for calling refresh on any popups it wants to show.
This should be called as the last thing in the parents refresh method. This should be called as the last thing in the parents refresh method.
The parent *must* also call _doRead on the popup instead of/in addition to The parent *must* also call read_input on the popup instead of/in addition to
running its own _doRead code if it wants to have the popup handle user input. running its own read_input code if it wants to have the popup handle user input.
:param parent_mode: must be a basemode (or subclass) which the popup will be drawn over :param parent_mode: must be a basemode (or subclass) which the popup will be drawn over
:parem title: string, the title of the popup window :parem title: string, the title of the popup window
@ -54,7 +54,7 @@ class Popup:
add_string(self, row, string) - add string at row. handles triming/ignoring if the string won't fit in the popup add_string(self, row, string) - add string at row. handles triming/ignoring if the string won't fit in the popup
_doRead(self) - handle user input to the popup. read_input(self) - handle user input to the popup.
""" """
self.parent = parent_mode self.parent = parent_mode

View File

@ -247,7 +247,7 @@ class Preferences(BaseMode):
component.get("ConsoleUI").set_mode(self.parent_mode) component.get("ConsoleUI").set_mode(self.parent_mode)
self.parent_mode.resume() self.parent_mode.resume()
def _doRead(self): def read_input(self):
c = self.stdscr.getch() c = self.stdscr.getch()
if self.popup: if self.popup:

View File

@ -843,7 +843,7 @@ class TorrentDetail(BaseMode, component.Component):
self.popup = popup self.popup = popup
def _doRead(self): def read_input(self):
c = self.stdscr.getch() c = self.stdscr.getch()
if self.popup: if self.popup:

View File

@ -34,7 +34,7 @@ log = logging.getLogger(__name__)
class IPCProtocolServer(Protocol): class IPCProtocolServer(Protocol):
def dataReceived(self, data): def dataReceived(self, data): # NOQA
config = ConfigManager("gtkui.conf") config = ConfigManager("gtkui.conf")
data = rencode.loads(data, decode_utf8=True) data = rencode.loads(data, decode_utf8=True)
if not data or config["focus_main_window_on_add"]: if not data or config["focus_main_window_on_add"]:
@ -43,11 +43,11 @@ class IPCProtocolServer(Protocol):
class IPCProtocolClient(Protocol): class IPCProtocolClient(Protocol):
def connectionMade(self): def connectionMade(self): # NOQA
self.transport.write(rencode.dumps(self.factory.args)) self.transport.write(rencode.dumps(self.factory.args))
self.transport.loseConnection() self.transport.loseConnection()
def connectionLost(self, reason): def connectionLost(self, reason): # NOQA
reactor.stop() reactor.stop()
self.factory.stop = True self.factory.stop = True
@ -58,7 +58,7 @@ class IPCClientFactory(ClientFactory):
def __init__(self): def __init__(self):
self.stop = False self.stop = False
def clientConnectionFailed(self, connector, reason): def clientConnectionFailed(self, connector, reason): # NOQA
log.warning("Connection to running instance failed.") log.warning("Connection to running instance failed.")
reactor.stop() reactor.stop()

View File

@ -92,9 +92,9 @@ class _UI(object):
self.__options.loglevel = self.__options.loglevel.lower() self.__options.loglevel = self.__options.loglevel.lower()
# Setup the logger # Setup the logger
deluge.log.setupLogger(level=self.__options.loglevel, deluge.log.setup_logger(level=self.__options.loglevel,
filename=self.__options.logfile, filename=self.__options.logfile,
filemode=logfile_mode) filemode=logfile_mode)
log = logging.getLogger(__name__) log = logging.getLogger(__name__)

View File

@ -276,7 +276,7 @@ class Auth(JSONComponent):
:returns: True if the session is valid, False if not. :returns: True if the session is valid, False if not.
:rtype: booleon :rtype: booleon
""" """
return __request__.session_id is not None return __request__.session_id is not None # NOQA
@export @export
def delete_session(self): def delete_session(self):
@ -287,7 +287,7 @@ class Auth(JSONComponent):
:type session_id: string :type session_id: string
""" """
config = component.get("DelugeWeb").config config = component.get("DelugeWeb").config
del config["sessions"][__request__.session_id] del config["sessions"][__request__.session_id] # NOQA
return True return True
@export(AUTH_LEVEL_NONE) @export(AUTH_LEVEL_NONE)
@ -301,7 +301,7 @@ class Auth(JSONComponent):
:rtype: string or False :rtype: string or False
""" """
if self.check_password(password): if self.check_password(password):
return self._create_session(__request__) return self._create_session(__request__) # NOQA
else: else:
log.error('Login failed (ClientIP %s)', __request__.getClientIP()) log.error('Login failed (ClientIP %s)', __request__.getClientIP()) # NOQA
return False return False

View File

@ -975,7 +975,7 @@ class WebApi(JSONComponent):
:param event: The event name :param event: The event name
:type event: string :type event: string
""" """
self.event_queue.add_listener(__request__.session_id, event) self.event_queue.add_listener(__request__.session_id, event) # NOQA
@export @export
def deregister_event_listener(self, event): def deregister_event_listener(self, event):
@ -985,11 +985,11 @@ class WebApi(JSONComponent):
:param event: The event name :param event: The event name
:type event: string :type event: string
""" """
self.event_queue.remove_listener(__request__.session_id, event) self.event_queue.remove_listener(__request__.session_id, event) # NOQA
@export @export
def get_events(self): def get_events(self):
""" """
Retrieve the pending events for the session. Retrieve the pending events for the session.
""" """
return self.event_queue.get_events(__request__.session_id) return self.event_queue.get_events(__request__.session_id) # NOQA

View File

@ -127,7 +127,7 @@ class Upload(resource.Resource):
class Render(resource.Resource): class Render(resource.Resource):
def getChild(self, path, request): def getChild(self, path, request): # NOQA
request.render_file = path request.render_file = path
return self return self
@ -152,7 +152,7 @@ class Tracker(resource.Resource):
except KeyError: except KeyError:
self.tracker_icons = TrackerIcons() self.tracker_icons = TrackerIcons()
def getChild(self, path, request): def getChild(self, path, request): # NOQA
request.tracker_name = path request.tracker_name = path
return self return self
@ -175,7 +175,7 @@ class Tracker(resource.Resource):
class Flag(resource.Resource): class Flag(resource.Resource):
def getChild(self, path, request): def getChild(self, path, request): # NOQA
request.country = path request.country = path
return self return self
@ -202,18 +202,18 @@ class LookupResource(resource.Resource, component.Component):
self.__paths = {} self.__paths = {}
for directory in directories: for directory in directories:
self.addDirectory(directory) self.add_directory(directory)
def addDirectory(self, directory, path=""): def add_directory(self, directory, path=""):
log.debug("Adding directory `%s` with path `%s`", directory, path) log.debug("Adding directory `%s` with path `%s`", directory, path)
paths = self.__paths.setdefault(path, []) paths = self.__paths.setdefault(path, [])
paths.append(directory) paths.append(directory)
def removeDirectory(self, directory, path=""): def remove_directory(self, directory, path=""):
log.debug("Removing directory `%s`", directory) log.debug("Removing directory `%s`", directory)
self.__paths[path].remove(directory) self.__paths[path].remove(directory)
def getChild(self, path, request): def getChild(self, path, request): # NOQA
if hasattr(request, 'lookup_path'): if hasattr(request, 'lookup_path'):
request.lookup_path = os.path.join(request.lookup_path, path) request.lookup_path = os.path.join(request.lookup_path, path)
else: else:
@ -365,7 +365,7 @@ class ScriptResource(resource.Resource, component.Component):
scripts.append("js/" + path) scripts.append("js/" + path)
return scripts return scripts
def getChild(self, path, request): def getChild(self, path, request): # NOQA
if hasattr(request, "lookup_path"): if hasattr(request, "lookup_path"):
request.lookup_path += '/' + path request.lookup_path += '/' + path
else: else:
@ -475,13 +475,13 @@ class TopLevel(resource.Resource):
self.__scripts.remove(script) self.__scripts.remove(script)
self.__debug_scripts.remove(script) self.__debug_scripts.remove(script)
def getChild(self, path, request): def getChild(self, path, request): # NOQA
if path == "": if path == "":
return self return self
else: else:
return resource.Resource.getChild(self, path, request) return resource.Resource.getChild(self, path, request)
def getChildWithDefault(self, path, request): def getChildWithDefault(self, path, request): # NOQA
# Calculate the request base # Calculate the request base
header = request.getHeader('x-deluge-base') header = request.getHeader('x-deluge-base')
base = header if header else component.get("DelugeWeb").base base = header if header else component.get("DelugeWeb").base
@ -540,7 +540,7 @@ class TopLevel(resource.Resource):
class ServerContextFactory: class ServerContextFactory:
def getContext(self): def getContext(self): # NOQA
"""Creates an SSL context.""" """Creates an SSL context."""
ctx = SSL.Context(SSL.SSLv3_METHOD) ctx = SSL.Context(SSL.SSLv3_METHOD)
deluge_web = component.get("DelugeWeb") deluge_web = component.get("DelugeWeb")

View File

@ -10,8 +10,8 @@
# All configuration values have a default value; values that are commented out # All configuration values have a default value; values that are commented out
# serve to show the default value. # serve to show the default value.
import sys, os import os
import deluge.common import sys
from version import get_version from version import get_version
from datetime import date from datetime import date
@ -20,6 +20,7 @@ from datetime import date
# absolute, like shown here. # absolute, like shown here.
sys.path.append(os.path.abspath(os.path.dirname(__file__ + '../../'))) sys.path.append(os.path.abspath(os.path.dirname(__file__ + '../../')))
class Mock(object): class Mock(object):
__all__ = [] __all__ = []
@ -35,9 +36,9 @@ class Mock(object):
if name in ('__file__', '__path__'): if name in ('__file__', '__path__'):
return '/dev/null' return '/dev/null'
elif name[0] == name[0].upper(): elif name[0] == name[0].upper():
mockType = type(name, (), {}) mock_type = type(name, (), {})
mockType.__module__ = __name__ mock_type.__module__ = __name__
return mockType return mock_type
else: else:
return Mock() return Mock()
@ -193,8 +194,8 @@ htmlhelp_basename = 'delugedoc'
# Grouping the document tree into LaTeX files. List of tuples # Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]). # (source start file, target name, title, author, document class [howto/manual]).
latex_documents = [ latex_documents = [
('index', 'deluge.tex', 'deluge Documentation', ('index', 'deluge.tex', 'deluge Documentation',
'Deluge Team', 'manual'), 'Deluge Team', 'manual'),
] ]
# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of

View File

@ -37,7 +37,7 @@ __version__ = "1.1"
MESSAGES = {} MESSAGES = {}
def usage (ecode, msg=''): def usage(ecode, msg=''):
""" """
Print usage and msg and exit with given code. Print usage and msg and exit with given code.
""" """
@ -47,7 +47,7 @@ def usage (ecode, msg=''):
sys.exit(ecode) sys.exit(ecode)
def add (msgid, transtr, fuzzy): def add(msgid, transtr, fuzzy):
""" """
Add a non-fuzzy translation to the dictionary. Add a non-fuzzy translation to the dictionary.
""" """
@ -56,7 +56,7 @@ def add (msgid, transtr, fuzzy):
MESSAGES[msgid] = transtr MESSAGES[msgid] = transtr
def generate (): def generate():
""" """
Return the generated output. Return the generated output.
""" """
@ -76,7 +76,7 @@ def generate ():
# The header is 7 32-bit unsigned integers. We don't use hash tables, so # The header is 7 32-bit unsigned integers. We don't use hash tables, so
# the keys start right after the index tables. # the keys start right after the index tables.
# translated string. # translated string.
keystart = 7*4+16*len(keys) keystart = 7 * 4 + 16 * len(keys)
# and the values start after the keys # and the values start after the keys
valuestart = keystart + len(ids) valuestart = keystart + len(ids)
koffsets = [] koffsets = []
@ -84,15 +84,15 @@ def generate ():
# The string table first has the list of keys, then the list of values. # The string table first has the list of keys, then the list of values.
# Each entry has first the size of the string, then the file offset. # Each entry has first the size of the string, then the file offset.
for o1, l1, o2, l2 in offsets: for o1, l1, o2, l2 in offsets:
koffsets += [l1, o1+keystart] koffsets += [l1, o1 + keystart]
voffsets += [l2, o2+valuestart] voffsets += [l2, o2 + valuestart]
offsets = koffsets + voffsets offsets = koffsets + voffsets
output = struct.pack("Iiiiiii", output = struct.pack("Iiiiiii",
0x950412deL, # Magic 0x950412deL, # Magic
0, # Version 0, # Version
len(keys), # # of entries len(keys), # # of entries
7*4, # start of key index 7 * 4, # start of key index
7*4+len(keys)*8, # start of value index 7 * 4 + len(keys) * 8, # start of value index
0, 0) # size and offset of hash table 0, 0) # size and offset of hash table
output += array.array("i", offsets).tostring() output += array.array("i", offsets).tostring()
output += ids output += ids
@ -100,9 +100,9 @@ def generate ():
return output return output
def make (filename, outfile): def make(filename, outfile):
ID = 1 section_id = 1
STR = 2 section_str = 2
global MESSAGES global MESSAGES
MESSAGES = {} MESSAGES = {}
@ -129,7 +129,7 @@ def make (filename, outfile):
for l in lines: for l in lines:
lno += 1 lno += 1
# If we get a comment line after a msgstr, this is a new entry # If we get a comment line after a msgstr, this is a new entry
if l[0] == '#' and section == STR: if l[0] == '#' and section == section_str:
add(msgid, msgstr, fuzzy) add(msgid, msgstr, fuzzy)
section = None section = None
fuzzy = 0 fuzzy = 0
@ -145,14 +145,14 @@ def make (filename, outfile):
l = l[12:] l = l[12:]
# Now we are in a msgid section, output previous section # Now we are in a msgid section, output previous section
elif l.startswith('msgid'): elif l.startswith('msgid'):
if section == STR: if section == section_str:
add(msgid, msgstr, fuzzy) add(msgid, msgstr, fuzzy)
section = ID section = section_id
l = l[5:] l = l[5:]
msgid = msgstr = '' msgid = msgstr = ''
# Now we are in a msgstr section # Now we are in a msgstr section
elif l.startswith('msgstr'): elif l.startswith('msgstr'):
section = STR section = section_str
l = l[6:] l = l[6:]
# Check for plural forms # Check for plural forms
if l.startswith('['): if l.startswith('['):
@ -167,29 +167,28 @@ def make (filename, outfile):
continue continue
# XXX: Does this always follow Python escape semantics? # XXX: Does this always follow Python escape semantics?
l = eval(l) l = eval(l)
if section == ID: if section == section_id:
msgid += l msgid += l
elif section == STR: elif section == section_str:
msgstr += l msgstr += l
else: else:
print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \ print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), 'before:'
'before:'
print >> sys.stderr, l print >> sys.stderr, l
sys.exit(1) sys.exit(1)
# Add last entry # Add last entry
if section == STR: if section == section_str:
add(msgid, msgstr, fuzzy) add(msgid, msgstr, fuzzy)
# Compute output # Compute output
output = generate() output = generate()
try: try:
open(outfile,"wb").write(output) open(outfile, "wb").write(output)
except IOError,msg: except IOError, msg:
print >> sys.stderr, msg print >> sys.stderr, msg
def main (): def main():
try: try:
opts, args = getopt.getopt(sys.argv[1:], 'hVo:', opts, args = getopt.getopt(sys.argv[1:], 'hVo:',
['help', 'version', 'output-file=']) ['help', 'version', 'output-file='])

Some files were not shown because too many files have changed in this diff Show More