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()
def ConfigManager(config, defaults=None):
def ConfigManager(config, defaults=None): # NOQA
return _configmanager.get_config(config, defaults)

View file

@ -115,7 +115,7 @@ def format_request(call):
class ServerContextFactory(object):
def getContext(self):
def getContext(self): # NOQA
"""
Create an SSL context.
@ -130,7 +130,6 @@ class ServerContextFactory(object):
class DelugeRPCProtocol(DelugeTransferProtocol):
def message_received(self, request):
"""
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))
reactor.callLater(0, self.dispatch, *call)
def sendData(self, data):
def sendData(self, data): # NOQA
"""
Sends the data to the client.
@ -169,7 +168,7 @@ class DelugeRPCProtocol(DelugeTransferProtocol):
"""
self.transfer_message(data)
def connectionMade(self):
def connectionMade(self): # NOQA
"""
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
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.

View file

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

View file

@ -19,7 +19,7 @@ from twisted.python.log import PythonLoggingObserver
from deluge import common
__all__ = ["setupLogger", "setLoggerLevel", "getPluginLogger", "LOG"]
__all__ = ["setup_logger", "set_logger_level", "get_plugin_logger", "LOG"]
LoggingLoggerClass = logging.getLoggerClass()
@ -79,7 +79,7 @@ class Logging(LoggingLoggerClass):
def exception(self, msg, *args, **kwargs):
yield LoggingLoggerClass.exception(self, msg, *args, **kwargs)
def findCaller(self):
def find_caller(self):
f = logging.currentframe().f_back
rv = "(unknown file)", 0, "(unknown function)"
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
to that file instead of stdout.
@ -192,10 +192,10 @@ def tweak_logging_levels():
continue
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.
@ -208,7 +208,7 @@ def setLoggerLevel(level, logger_name=None):
logging.getLogger(logger_name).setLevel(levels.get(level, "error"))
def getPluginLogger(logger_name):
def get_plugin_logger(logger_name):
import warnings
stack = inspect.stack()
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
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"
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.
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.

View file

@ -24,7 +24,7 @@ from optparse import OptionParser
import deluge.common
import deluge.configmanager
import deluge.error
from deluge.log import setupLogger
from deluge.log import setup_logger
def version_callback(option, opt_str, value, parser):
@ -74,7 +74,7 @@ def start_ui():
logfile_mode = 'w'
if options.rotate_logs:
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__)
if options.config:
@ -181,7 +181,7 @@ def start_daemon():
logfile_mode = 'w'
if options.rotate_logs:
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__)
# 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):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)

View file

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

View file

@ -106,10 +106,10 @@ class OptionsDialog():
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+'_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:
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):
self.glade.get_widget('isnt_add_paused').set_active(True)
if not options.get('queue_to_top', True):
@ -119,17 +119,17 @@ class OptionsDialog():
for field in ['move_completed_path', 'path', 'download_location',
'copy_torrent']:
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("~"))
)
self.glade.get_widget(field+"_chooser").show()
self.glade.get_widget(field+"_entry").hide()
self.glade.get_widget(field + "_chooser").show()
self.glade.get_widget(field + "_entry").hide()
else:
self.glade.get_widget(field+"_entry").set_text(
self.glade.get_widget(field + "_entry").set_text(
options.get(field, "")
)
self.glade.get_widget(field+"_entry").show()
self.glade.get_widget(field+"_chooser").hide()
self.glade.get_widget(field + "_entry").show()
self.glade.get_widget(field + "_chooser").hide()
self.set_sensitive()
def on_core_config(config):
@ -225,7 +225,7 @@ class OptionsDialog():
'max_upload_speed', 'max_connections',
'max_upload_slots', 'add_paused', 'auto_managed',
'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):
toggle = str(tb.name).replace("_toggle", "")
@ -329,13 +329,13 @@ class OptionsDialog():
for id in self.spin_ids:
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:
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:
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']:
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"
__description__ = "Monitors folders for .torrent files."
__long_description__ = """"""
__pkg_data__ = {'deluge.plugins.'+__plugin_name__.lower(): ["template/*", "data/*"]}
__pkg_data__ = {'deluge.plugins.' + __plugin_name__.lower(): ["template/*", "data/*"]}
setup(
name=__plugin_name__,
@ -45,5 +45,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web]
%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):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)

View file

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

View file

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

View file

@ -1,54 +1,31 @@
#
# __init__.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Damien Churchill <damoxc@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.
#
from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
super(WebUIPlugin, self).__init__(plugin_name)
from .webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)

View file

@ -1,36 +1,10 @@
#
# common.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 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 os.path

View file

@ -1,36 +1,10 @@
#
# core.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 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 hashlib
@ -110,7 +84,7 @@ class Core(CorePluginBase):
torrent = component.get("TorrentManager").torrents[torrent_id]
info = torrent.get_status(["name", "download_location"])
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):
if event == "added" and arg[0]:

View file

@ -1,36 +1,10 @@
#
# gtkui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Damien Churchill <damoxc@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
@ -60,6 +34,7 @@ EVENT_MAP = {
EVENTS = ["complete", "added", "removed"]
class ExecutePreferences(object):
def __init__(self, plugin):
self.plugin = plugin
@ -80,8 +55,7 @@ class ExecutePreferences(object):
events.set_model(store)
events.set_active(0)
self.plugin.add_preferences_page(_("Execute"),
self.glade.get_widget("execute_box"))
self.plugin.add_preferences_page(_("Execute"), self.glade.get_widget("execute_box"))
self.plugin.register_hook("on_show_prefs", self.load_commands)
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)
self.remove_command(command_id)
class GtkUI(GtkPluginBase):
def enable(self):

View file

@ -1,49 +1,21 @@
#
# webui.py
# -*- coding: utf-8 -*-
#
# 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
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource
log = logging.getLogger(__name__)
class WebUI(WebPluginBase):
scripts = [get_resource("execute.js")]

View file

@ -41,7 +41,7 @@ __url__ = "http://deluge-torrent.org"
__license__ = "GPLv3"
__description__ = "Plugin to execute a command upon an event"
__long_description__ = __description__
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["data/*"]}
__pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["data/*"]}
setup(
name=__plugin_name__,
@ -54,8 +54,8 @@ setup(
long_description=__long_description__,
packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"],
package_data = __pkg_data__,
namespace_packages=["deluge", "deluge.plugins"],
package_data=__pkg_data__,
entry_points="""
[deluge.plugin.core]
@ -64,5 +64,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web]
%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):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
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
"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]}
__pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup(
name=__plugin_name__,
@ -53,5 +53,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3)
""" % ((__plugin_name__, __plugin_name__.lower()) * 3)
)

View file

@ -1,54 +1,35 @@
#
# __init__.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 Martijn Voncken <mvoncken@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.
# Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2008 Andrew Resch <andrewresch@gmail.com>
#
# 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
class CorePlugin(PluginInitBase):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)

View file

@ -1,36 +1,15 @@
# -*- coding: utf-8 -*-
#
# 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
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
# 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.
#
# 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.
@ -39,8 +18,6 @@ adds a status field for tracker.
import logging
import re
import traceback
from urlparse import urlparse
import deluge.component as component
from deluge.configmanager import ConfigManager
@ -57,35 +34,35 @@ TRACKER = "tracker"
KEYWORD = "keyword"
LABEL = "label"
CONFIG_DEFAULTS = {
"torrent_labels": {}, #torrent_id:label_id
"labels": {}, #label_id:{name:value}
"torrent_labels": {}, # torrent_id:label_id
"labels": {}, # label_id:{name:value}
}
CORE_OPTIONS = ["auto_add_trackers"]
OPTIONS_DEFAULTS = {
"apply_max":False,
"max_download_speed":-1,
"max_upload_speed":-1,
"max_connections":-1,
"max_upload_slots":-1,
"prioritize_first_last":False,
"apply_queue":False,
"is_auto_managed":False,
"stop_at_ratio":False,
"stop_ratio":2.0,
"remove_at_ratio":False,
"apply_move_completed":False,
"move_completed":False,
"move_completed_path":"",
"auto_add":False,
"auto_add_trackers":[]
"apply_max": False,
"max_download_speed": -1,
"max_upload_speed": -1,
"max_connections": -1,
"max_upload_slots": -1,
"prioritize_first_last": False,
"apply_queue": False,
"is_auto_managed": False,
"stop_at_ratio": False,
"stop_ratio": 2.0,
"remove_at_ratio": False,
"apply_move_completed": False,
"move_completed": False,
"move_completed_path": "",
"auto_add": False,
"auto_add_trackers": []
}
NO_LABEL = "No Label"
def CheckInput(cond, message):
def check_input(cond, message):
if not cond:
raise Exception(message)
@ -173,7 +150,7 @@ class Core(CorePluginBase):
for label, options in self.labels.items():
for key, value in options.items():
if value == None:
if value is None:
self.labels[label][key] = OPTIONS_DEFAULTS[key]
def save_config(self):
@ -191,9 +168,9 @@ class Core(CorePluginBase):
see label_set_options for more options.
"""
label_id = label_id.lower()
CheckInput(RE_VALID.match(label_id), _("Invalid label, valid characters:[a-z0-9_-]"))
CheckInput(label_id, _("Empty Label"))
CheckInput(not (label_id in self.labels), _("Label already exists"))
check_input(RE_VALID.match(label_id), _("Invalid label, valid characters:[a-z0-9_-]"))
check_input(label_id, _("Empty Label"))
check_input(not (label_id in self.labels), _("Label already exists"))
self.labels[label_id] = dict(OPTIONS_DEFAULTS)
self.config.save()
@ -201,7 +178,7 @@ class Core(CorePluginBase):
@export
def remove(self, label_id):
"""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]
self.clean_config()
self.config.save()
@ -211,7 +188,7 @@ class Core(CorePluginBase):
torrent = self.torrents[torrent_id]
if not options["move_completed_path"]:
options["move_completed_path"] = "" #no None.
options["move_completed_path"] = "" # no None.
if options["apply_max"]:
torrent.set_max_download_speed(options["max_download_speed"])
@ -281,7 +258,7 @@ class Core(CorePluginBase):
"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():
if not key in OPTIONS_DEFAULTS:
raise Exception("label: Invalid options_dict key:%s" % key)
@ -316,8 +293,8 @@ class Core(CorePluginBase):
if label_id == NO_LABEL:
label_id = None
CheckInput((not label_id) or (label_id in self.labels), _("Unknown Label"))
CheckInput(torrent_id in self.torrents, _("Unknown Torrent"))
check_input((not label_id) or (label_id in self.labels), _("Unknown Label"))
check_input(torrent_id in self.torrents, _("Unknown Torrent"))
if torrent_id in self.torrent_labels:
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):
return self.torrent_labels.get(torrent_id) or ""
if __name__ == "__main__":
from . import test

View file

@ -1,46 +1,15 @@
#
# __init__.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 Martijn Voncken <mvoncken@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 os
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
import gtk, gobject
from deluge.ui.client import client
from . import sidebar_menu
from . import label_config
@ -50,9 +19,11 @@ log = logging.getLogger(__name__)
NO_LABEL = "No Label"
def cell_data_label(column, cell, model, row, data):
cell.set_property('text', str(model.get_value(row, data)))
class GtkUI(GtkPluginBase):
def start(self):
if self.label_menu:
@ -68,9 +39,9 @@ class GtkUI(GtkPluginBase):
def disable(self):
try:
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()
del self.sidebar_menu
@ -84,7 +55,7 @@ class GtkUI(GtkPluginBase):
#sidebar
#disabled
if not self.sidebar_menu:
self.sidebar_menu = sidebar_menu.LabelSidebarMenu()
self.sidebar_menu = sidebar_menu.LabelSidebarMenu()
#self.sidebar.load()
#menu:
@ -99,7 +70,7 @@ class GtkUI(GtkPluginBase):
#config:
if not self.labelcfg:
self.labelcfg = label_config.LabelConfig(self.plugin)
self.labelcfg = label_config.LabelConfig(self.plugin)
self.labelcfg.load()
log.debug('Finished loading Label plugin')

View file

@ -1,37 +1,11 @@
# -*- coding: utf-8 -*-
#
# 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 os
@ -40,8 +14,6 @@ import gtk
import gtk.glade
import pkg_resources # access plugin egg
import deluge.common
import deluge.component as component
from deluge.ui.client import client
log = logging.getLogger(__name__)
@ -59,7 +31,6 @@ class LabelConfig(object):
log.debug('Adding Label Preferences page')
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.register_hook("on_show_prefs", self.load_settings)
self.plugin.register_hook("on_apply_prefs", self.on_apply_prefs)

View file

@ -1,46 +1,18 @@
#
# sidebar_menu.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 Martijn Voncken <mvoncken@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 gtk
import gtk.glade
import deluge.common
import deluge.component as component
from deluge.ui.client import client
@ -48,6 +20,7 @@ log = logging.getLogger(__name__)
NO_LABEL = "No Label"
#helpers:
def get_resource(filename):
import pkg_resources
@ -56,11 +29,12 @@ def get_resource(filename):
"deluge.plugins.label", os.path.join("data", filename)
)
#menu
class LabelSidebarMenu(object):
def __init__(self):
self.treeview = component.get("FilterTreeView")
self.treeview = component.get("FilterTreeView")
self.menu = self.treeview.menu
self.items = []
@ -79,17 +53,16 @@ class LabelSidebarMenu(object):
#hooks:
self.menu.connect("show", self.on_show, None)
def _add_item(self, id, label, stock):
"""I hate glade.
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.get_children()[0].set_label(label)
item.connect("activate", func)
self.menu.prepend(item)
setattr(self, "item_%s" % id, item)
setattr(self, "item_%s" % id, item)
self.items.append(item)
return item
@ -99,7 +72,7 @@ class LabelSidebarMenu(object):
def on_remove(self, event=None):
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)
def on_show(self, widget=None, data=None):
@ -114,7 +87,7 @@ class LabelSidebarMenu(object):
item.show()
#default items
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)
#add is allways enabled.
@ -133,8 +106,6 @@ class LabelSidebarMenu(object):
self.items = []
#dialogs:
class AddDialog(object):
def __init__(self):
@ -164,15 +135,15 @@ class OptionsDialog(object):
spin_ids = ["max_download_speed", "max_upload_speed", "stop_ratio"]
spin_int_ids = ["max_upload_slots", "max_connections"]
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.
sensitive_groups = [
("apply_max", ["max_download_speed", "max_upload_speed", "max_upload_slots", "max_connections"]),
("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"]),
("move_completed", ["move_completed_path"]), #nested
("move_completed", ["move_completed_path"]), # nested
("auto_add", ["auto_add_trackers"])
]
@ -192,7 +163,7 @@ class OptionsDialog(object):
# Show the label name in the header 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.connect("toggled", self.apply_sensitivity)
@ -237,9 +208,9 @@ class OptionsDialog(object):
else:
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...
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.
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")
options["auto_add_trackers"] = [x for x in tracker_lst if x] # filter out empty lines.
log.debug(options)
client.label.set_options(self.label, options)

View file

@ -1,56 +1,30 @@
#
# submenu.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 Martijn Voncken <mvoncken@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 os
import gobject
import gtk
import pkg_resources # access plugin egg
from deluge import component # for systray
from deluge.ui.client import client
log = logging.getLogger(__name__)
# Deferred Translation
def _(message): return message
def _(message):
return message
NO_LABEL = _("No Label")
del _
class LabelMenu(gtk.MenuItem):
def __init__(self):
gtk.MenuItem.__init__(self, _("Label"))
@ -60,7 +34,7 @@ class LabelMenu(gtk.MenuItem):
self.items = []
#attach..
torrentmenu = component.get("MenuBar").torrentmenu
component.get("MenuBar").torrentmenu
self.sub_menu.connect("show", self.on_show, None)
def get_torrent_ids(self):
@ -83,6 +57,6 @@ class LabelMenu(gtk.MenuItem):
self.show_all()
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():
client.label.set_torrent(torrent_id, label_id)

View file

@ -1,34 +1,13 @@
#!/usr/bin/env python
# -*- 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
# 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.
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
#
# 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
@ -57,15 +36,15 @@ sclient.label_add("test")
print("#set")
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")
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")
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")
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, ['name', 'tracker_host', 'label']))

View file

@ -1,40 +1,14 @@
#
# webui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
#
# Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <mvoncken@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.
# Copyright (C) 2007-2008 Andrew Resch <andrewresch@gmail.com>
#
# 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
@ -42,17 +16,16 @@ import os
import pkg_resources
from deluge import component
from deluge.common import fspeed
from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
log = logging.getLogger(__name__)
def get_resource(filename):
return pkg_resources.resource_filename("deluge.plugins.label",
os.path.join("data", filename))
class WebUI(WebPluginBase):
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
"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]}
__pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup(
name=__plugin_name__,
@ -58,8 +58,8 @@ setup(
long_description=__long_description__,
packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"],
package_data = __pkg_data__,
namespace_packages=["deluge", "deluge.plugins"],
package_data=__pkg_data__,
entry_points="""
[deluge.plugin.core]
@ -68,5 +68,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3)
""" % ((__plugin_name__, __plugin_name__.lower()) * 3)
)

View file

@ -1,5 +1,4 @@
#
# __init__.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
#
@ -8,51 +7,30 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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.
#
from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)

View file

@ -1,5 +1,4 @@
#
# common.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
#
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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
@ -53,9 +28,9 @@ except ImportError:
def get_resource(filename):
import pkg_resources, os
return pkg_resources.resource_filename("deluge.plugins.notifications",
os.path.join("data", filename))
import os
import pkg_resources
return pkg_resources.resource_filename("deluge.plugins.notifications", os.path.join("data", filename))
class CustomNotifications(object):
@ -97,8 +72,7 @@ class CustomNotifications(object):
return defer.succeed("Event not handled")
if eventtype not in self.custom_notifications:
def wrapper(*args, **kwargs):
return self._handle_custom_providers(kind, eventtype,
*args, **kwargs)
return self._handle_custom_providers(kind, eventtype, *args, **kwargs)
self.custom_notifications[kind][eventtype] = (wrapper, handler)
else:
wrapper, handler = self.custom_notifications[kind][eventtype]

View file

@ -1,5 +1,4 @@
#
# core.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
#
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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
@ -60,7 +35,7 @@ DEFAULT_PREFS = {
"smtp_user": "",
"smtp_pass": "",
"smtp_from": "",
"smtp_tls": False, # SSL or TLS
"smtp_tls": False, # SSL or TLS
"smtp_recipients": [],
# Subscriptions
"subscriptions": {
@ -68,6 +43,7 @@ DEFAULT_PREFS = {
}
}
class CoreNotifications(CustomNotifications):
def enable(self):
@ -126,10 +102,10 @@ Date: %(date)s
""" % {'smtp_from': self.config['smtp_from'],
'subject': subject,
'smtp_recipients': to_addrs_str,
'date': formatdate()
}
'subject': subject,
'smtp_recipients': to_addrs_str,
'date': formatdate()
}
message = '\r\n'.join((headers + message).splitlines())
@ -194,7 +170,6 @@ Date: %(date)s
server.quit()
return _("Notification email sent.")
def _on_torrent_finished_event(self, torrent_id):
log.debug("Handler for TorrentFinishedEvent called for CORE")
torrent = component.get("TorrentManager")[torrent_id]

View file

@ -1,5 +1,4 @@
#
# gtkui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
#
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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
@ -95,6 +70,7 @@ RECIPIENT_FIELD, RECIPIENT_EDIT = range(2)
SUB_NOT_SOUND) = range(6)
SND_EVENT, SND_EVENT_DOC, SND_NAME, SND_PATH = range(4)
class GtkUiNotifications(CustomNotifications):
def enable(self):
@ -190,8 +166,7 @@ class GtkUiNotifications(CustomNotifications):
return defer.fail(_("pynotify is not installed"))
if pynotify.init("Deluge"):
icon = gtk.gdk.pixbuf_new_from_file_at_size(
deluge.common.get_pixmap("deluge.svg"), 48, 48)
icon = gtk.gdk.pixbuf_new_from_file_at_size(deluge.common.get_pixmap("deluge.svg"), 48, 48)
self.note = pynotify.Notification(title, message)
self.note.set_icon_from_pixbuf(icon)
if not self.note.show():
@ -225,7 +200,7 @@ class GtkUiNotifications(CustomNotifications):
return defer.succeed(msg)
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):
# Since there's no custom sound hardcoded, just return ''
@ -248,6 +223,7 @@ class GtkUiNotifications(CustomNotifications):
"has finished downloading.") % torrent_status
return title, message
class GtkUI(GtkPluginBase, GtkUiNotifications):
def __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_notifications_model_populate_treeview()
client.notifications.get_handled_events().addCallback(
self.popuplate_what_needs_handled_events
)
@ -279,8 +254,7 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
'on_enabled_toggled': self.on_enabled_toggled,
'on_sound_enabled_toggled': self.on_sound_enabled_toggled,
'on_sounds_edit_button_clicked': self.on_sounds_edit_button_clicked,
'on_sounds_revert_button_clicked': \
self.on_sounds_revert_button_clicked,
'on_sounds_revert_button_clicked': self.on_sounds_revert_button_clicked,
'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)
renderer = gtk.CellRendererToggle()
renderer.set_property('activatable', True)
renderer.connect( 'toggled', self._on_popup_col_toggled)
renderer.set_property("activatable", True)
renderer.connect("toggled", self._on_popup_col_toggled)
column = gtk.TreeViewColumn("Popup", renderer, active=SUB_NOT_POPUP)
column.set_clickable(True)
self.subscriptions_treeview.append_column(column)
renderer = gtk.CellRendererToggle()
renderer.set_property('activatable', True)
renderer.connect( 'toggled', self._on_blink_col_toggled)
renderer.set_property("activatable", True)
renderer.connect("toggled", self._on_blink_col_toggled)
column = gtk.TreeViewColumn("Blink", renderer, active=SUB_NOT_BLINK)
column.set_clickable(True)
self.subscriptions_treeview.append_column(column)
@ -471,7 +445,6 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
SUB_NOT_SOUND, event_name in subscriptions_dict['sound']
)
def on_apply_prefs(self):
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_tls": self.glade.get_widget("smtp_tls").get_active(),
"smtp_recipients": [dest[0] for dest in self.recipients_model if
dest[0]!='USER@HOST'],
dest[0] != "USER@HOST"],
"subscriptions": {"email": current_email_subscriptions}
}
@ -587,12 +560,10 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
selection = treeview.get_selection()
model, iter = selection.get_selected()
if iter:
path = model.get_path(iter)[0]
model.remove(iter)
def on_cell_edited(self, cell, path_string, new_text, model):
iter = model.get_iter_from_string(path_string)
path = model.get_path(iter)[0]
model.set(iter, RECIPIENT_FIELD, new_text)
def on_recipients_treeview_selection_changed(self, selection):
@ -616,21 +587,17 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
def on_sounds_treeview_selection_changed(self, selection):
model, iter = selection.get_selected()
if iter:
self.glade.get_widget("sounds_edit_button").set_property(
'sensitive', True)
self.glade.get_widget("sounds_edit_button").set_property("sensitive", True)
path = model.get(iter, SND_PATH)[0]
log.debug("Sound selection changed: %s", path)
if path != self.config['sound_path']:
self.glade.get_widget("sounds_revert_button").set_property(
'sensitive', True)
self.glade.get_widget("sounds_revert_button").set_property("sensitive", True)
else:
self.glade.get_widget("sounds_revert_button").set_property(
'sensitive', False)
self.glade.get_widget("sounds_revert_button").set_property("sensitive", False)
else:
self.glade.get_widget("sounds_edit_button").set_property(
'sensitive', False)
self.glade.get_widget("sounds_revert_button").set_property(
'sensitive', False)
self.glade.get_widget("sounds_edit_button").set_property("sensitive", False)
self.glade.get_widget("sounds_revert_button").set_property("sensitive", False)
def on_sounds_revert_button_clicked(self, widget):
log.debug("on_sounds_revert_button_clicked")
selection = self.sounds_treeview.get_selection()
@ -655,6 +622,7 @@ class GtkUI(GtkPluginBase, GtkUiNotifications):
gtk.RESPONSE_OK)
)
dialog.set_filename(path)
def update_model(response):
if response == gtk.RESPONSE_OK:
new_filename = dialog.get_filename()

View file

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

View file

@ -1,5 +1,4 @@
#
# webui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
#
@ -8,45 +7,20 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource
log = logging.getLogger(__name__)
class WebUI(WebPluginBase):
scripts = [get_resource("notifications.js")]

View file

@ -1,5 +1,4 @@
#
# setup.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
#
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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.
#
from setuptools import find_packages, setup
@ -46,7 +21,7 @@ __version__ = "0.2"
__url__ = "http://dev.deluge-torrent.org/"
__license__ = "GPLv3"
__description__ = "Plugin which provides notifications to Deluge."
__long_description__ = """
__long_description__ = """
Plugin which provides notifications to Deluge
Email, Popup, Blink and Sound notifications
@ -54,7 +29,7 @@ Email, Popup, Blink and Sound notifications
The plugin also allows other plugins to make
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(
name=__plugin_name__,
@ -67,8 +42,8 @@ setup(
long_description=__long_description__ if __long_description__ else __description__,
packages=find_packages(exclude=['**/test.py']),
namespace_packages = ["deluge", "deluge.plugins"],
package_data = __pkg_data__,
namespace_packages=["deluge", "deluge.plugins"],
package_data=__pkg_data__,
entry_points="""
[deluge.plugin.core]
@ -77,5 +52,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3)
""" % ((__plugin_name__, __plugin_name__.lower()) * 3)
)

View file

@ -1,5 +1,4 @@
#
# __init__.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
#
@ -7,51 +6,30 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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.
#
from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)

View file

@ -1,5 +1,4 @@
#
# common.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
#
@ -7,36 +6,13 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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.
#
def get_resource(filename):
import pkg_resources, os
return pkg_resources.resource_filename("deluge.plugins.scheduler",
os.path.join("data", filename))
import os
import pkg_resources
return pkg_resources.resource_filename("deluge.plugins.scheduler", os.path.join("data", filename))

View file

@ -1,5 +1,4 @@
#
# core.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
#
@ -7,33 +6,9 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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
@ -72,6 +47,7 @@ CONTROLLED_SETTINGS = [
"max_active_seeding"
]
class SchedulerEvent(DelugeEvent):
"""
Emitted when a schedule state changes.
@ -82,6 +58,7 @@ class SchedulerEvent(DelugeEvent):
"""
self._args = [colour]
class Core(CorePluginBase):
def enable(self):
# Create the defaults with the core config
@ -118,7 +95,6 @@ class Core(CorePluginBase):
def update(self):
pass
def on_config_value_changed(self, key, value):
if key in CONTROLLED_SETTINGS:
self.do_schedule(False)

View file

@ -1,5 +1,4 @@
#
# gtkui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
#
@ -7,40 +6,15 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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 gtk
import deluge.common
import deluge.component as component
from deluge.plugins.pluginbase import GtkPluginBase
from deluge.ui.client import client
@ -51,10 +25,12 @@ log = logging.getLogger(__name__)
DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
class SchedulerSelectWidget(gtk.DrawingArea):
def __init__(self, hover):
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("button_press_event", self.mouse_down)
@ -62,7 +38,9 @@ class SchedulerSelectWidget(gtk.DrawingArea):
self.connect("motion_notify_event", self.mouse_hover)
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.start_point = [0, 0]
@ -89,8 +67,11 @@ class SchedulerSelectWidget(gtk.DrawingArea):
for y in xrange(7):
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.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.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.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.set_source_rgba(0.5, 0.5, 0.5, 0.5)
self.context.stroke()
@ -98,13 +79,17 @@ class SchedulerSelectWidget(gtk.DrawingArea):
#coordinates --> which box
def get_point(self, event):
size = self.window.get_size()
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))
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))
if x > 23: x = 23
elif x < 0: x = 0
if y > 6: y = 6
elif y < 0: y = 0
if x > 23:
x = 23
elif x < 0:
x = 0
if y > 6:
y = 6
elif y < 0:
y = 0
return [x, y]
@ -136,13 +121,14 @@ class SchedulerSelectWidget(gtk.DrawingArea):
if self.get_point(event) != self.hover_point:
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]]]
for x in xrange(min(points[0]), max(points[0])+1):
for y in xrange(min(points[1]), max(points[1])+1):
for x in xrange(min(points[0]), max(points[0]) + 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.queue_draw()
@ -152,6 +138,7 @@ class SchedulerSelectWidget(gtk.DrawingArea):
self.hover_label.set_text("")
self.hover_point = [-1, -1]
class GtkUI(GtkPluginBase):
def enable(self):
self.create_prefs_page()
@ -201,7 +188,6 @@ class GtkUI(GtkPluginBase):
self.spin_active_down.set_value(config["low_active_down"])
self.spin_active_up.set_value(config["low_active_up"])
client.scheduler.get_config().addCallback(on_get_config)
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:
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource
log = logging.getLogger(__name__)
class WebUI(WebPluginBase):
scripts = [get_resource("scheduler.js")]

View file

@ -1,5 +1,4 @@
#
# setup.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
#
@ -7,33 +6,9 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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.
#
from setuptools import find_packages, setup
@ -46,7 +21,7 @@ __url__ = "http://deluge-torrent.org"
__license__ = "GPLv3"
__description__ = "Schedule limits on a per-hour per-day basis."
__long_description__ = """"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]}
__pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup(
name=__plugin_name__,
@ -59,8 +34,8 @@ setup(
long_description=__long_description__ if __long_description__ else __description__,
packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"],
package_data = __pkg_data__,
namespace_packages=["deluge", "deluge.plugins"],
package_data=__pkg_data__,
entry_points="""
[deluge.plugin.core]
@ -69,5 +44,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3)
""" % ((__plugin_name__, __plugin_name__.lower()) * 3)
)

View file

@ -1,57 +1,35 @@
#
# __init__.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
#
# Basic plugin template created by:
# 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.
#
# 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.
#
from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)

View file

@ -1,35 +1,10 @@
#
# common.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 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 os.path

View file

@ -1,37 +1,15 @@
#
# core.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Ian Martin <ianmartin@cantab.net>
# Copyright (C) 2008 Damien Churchill <damoxc@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 time

View file

@ -1,38 +1,15 @@
#
# graph.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Ian Martin <ianmartin@cantab.net>
# Copyright (C) 2008 Damien Churchill <damoxc@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.
@ -43,8 +20,6 @@ import time
import cairo
from deluge.ui.client import client
log = logging.getLogger(__name__)
black = (0, 0, 0)
@ -56,9 +31,11 @@ green = (0, 1.0, 0)
blue = (0, 0, 1.0)
orange = (1.0, 0.74, 0)
def default_formatter(value):
return str(value)
def size_formatter_scale(value):
scale = 1.0
for i in range(0, 3):
@ -66,6 +43,7 @@ def size_formatter_scale(value):
if value / scale < 1024:
return scale
def change_opacity(color, opactiy):
"""A method to assist in changing the opactiy of a color inorder to draw the
fills.
@ -77,6 +55,7 @@ def change_opacity(color, opactiy):
color.append(opactiy)
return tuple(color)
class Graph:
def __init__(self):
self.width = 100
@ -89,8 +68,8 @@ class Graph:
self.legend_selected = True
self.max_selected = True
self.black = (0, 0, 0,)
self.interval = 2 # 2 secs
self.text_bg = (255, 255, 255, 128) # prototyping
self.interval = 2 # 2 secs
self.text_bg = (255, 255, 255, 128) # prototyping
self.set_left_axis()
def set_left_axis(self, **kargs):
@ -103,7 +82,7 @@ class Graph:
'line': line,
'fill': fill,
'color': color
}
}
def set_stats(self, stats):
self.last_update = stats["_last_update"]
@ -135,7 +114,6 @@ class Graph:
self.draw_to_context(ctx, width, height)
return surface
def draw_x_axis(self, bounds):
(left, top, right, bottom) = bounds
duration = self.length * self.interval
@ -150,32 +128,32 @@ class Graph:
break
else:
# 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...
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):
text = time.strftime('%H:%M', time.localtime(start + seconds_to_step + i*x_step))
for i in xrange(0, duration / x_step + 1):
text = time.strftime('%H:%M', time.localtime(start + seconds_to_step + i * x_step))
# + 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_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):
font_extents = self.ctx.font_extents()
x_axis_space = font_extents[2] + 2 + self.line_size / 2.0
plot_height = self.height - x_axis_space
#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
for stat in self.stat_info:
if self.stat_info[stat]['axis'] == 'left':
try:
l_max = max(self.stats[stat])
l_max = max(self.stats[stat])
except ValueError:
l_max = 0
if l_max > max_value:
@ -187,6 +165,7 @@ class Graph:
max_value = y_ticks[-1]
#find the width of the y_ticks
y_tick_text = [self.left_axis['formatter'](tick) for tick in y_ticks]
def space_required(text):
te = self.ctx.text_extents(text)
return math.ceil(te[4] - te[0])
@ -194,7 +173,7 @@ class Graph:
top = font_extents[2] / 2.0
#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_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
#count the 0 tick in limit
if limit is not None:
if limit <3:
if limit < 3:
limit = 2
else:
limit = limit -1
limit = limit - 1
scale = 1
if 'formatter_scale' in self.left_axis:
scale = self.left_axis['formatter_scale'](x)
@ -220,15 +199,15 @@ class Graph:
intbit = math.floor(log)
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
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
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
steps = steps * 2
@ -239,7 +218,7 @@ class Graph:
else:
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
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]['color'] = change_opacity(stats[stat]['color'], 0.8)
height = bottom - top
height = bottom - top
max_value = y_ticks[-1]
ratio = height / max_value
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:
self.draw_dotted_line(gray, left, y, right, y)
self.draw_y_text(y_tick_text[i], left, y)
@ -271,7 +250,6 @@ class Graph:
def draw_legend(self):
pass
def trace_path(self, values, max_value, bounds):
(left, top, right, bottom) = bounds
ratio = (bottom - top) / max_value
@ -280,10 +258,10 @@ class Graph:
self.ctx.set_line_width(line_width)
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
step = (right - left) / float(self.length -1)
step = (right - left) / float(self.length - 1)
for i, value in enumerate(values):
if i == self.length - 1:
x = left
@ -292,11 +270,10 @@ class Graph:
x -= step
self.ctx.line_to(
int(right - (len(values) - 1) * step),
int(right - (len(values) - 1) * step),
bottom)
self.ctx.close_path()
def draw_value_poly(self, values, color, max_value, bounds, fill=False):
self.trace_path(values, max_value, bounds)
self.ctx.set_source_rgba(*color)
@ -313,7 +290,7 @@ class Graph:
height = fe[2]
x_bearing = te[0]
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.show_text(text)
@ -325,7 +302,7 @@ class Graph:
ascent = fe[0]
x_bearing = te[0]
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.show_text(text)
@ -350,6 +327,3 @@ class Graph:
self.ctx.line_to(x2, y2)
self.ctx.stroke()
self.ctx.set_dash(dash, offset)
if __name__ == "__main__":
from . import test

View file

@ -1,43 +1,19 @@
#
# gtkui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Ian Martin <ianmartin@cantab.net>
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
#
# Basic plugin template created by:
# 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 gobject
import gtk
import gtk.glade
from gtk.glade import XML
@ -49,29 +25,31 @@ from deluge.plugins.pluginbase import GtkPluginBase
from deluge.ui.client import client
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__)
DEFAULT_CONF = { 'version': 1,
'colors' :{
'bandwidth_graph': {'upload_rate': str(gtk.gdk.Color("blue")),
'download_rate': str(gtk.gdk.Color("green")),
DEFAULT_CONF = {'version': 1,
'colors': {
'bandwidth_graph': {'upload_rate': str(gtk.gdk.Color("blue")),
'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):
"""Render seconds as seconds or minutes with label"""
seconds = model.get_value(iter, 0)
if seconds >60:
if seconds > 60:
text = "%d %s" % (seconds / 60, _("minutes"))
elif seconds == 60:
text = _("1 minute")
@ -82,16 +60,18 @@ def neat_time(column, cell, model, iter):
cell.set_property('text', text)
return
def int_str(number):
return (str(int(number)))
def gtk_to_graph_color(color):
"""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)
red = gtk_color.red / MAX
green = gtk_color.green / MAX
blue = gtk_color.blue / MAX
red = gtk_color.red / max_val
green = gtk_color.green / max_val
blue = gtk_color.blue / max_val
return (red, green, blue)
@ -120,7 +100,7 @@ class GraphsTab(Tab):
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.window.unparent()
@ -134,12 +114,10 @@ class GraphsTab(Tab):
self.intervals_combo.connect("changed", self._on_selected_interval_changed)
self.update_intervals()
def graph_expose(self, widget, event):
context = self.graph_widget.window.cairo_create()
# set a clip region
context.rectangle(event.area.x, event.area.y,
event.area.width, event.area.height)
context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
context.clip()
self.graph.draw_to_context(context,
self.graph_widget.allocation.width,
@ -150,6 +128,7 @@ class GraphsTab(Tab):
def update(self):
d1 = client.stats.get_stats(self.graph.stat_info.keys(), self.selected_interval)
d1.addCallback(self.graph.set_stats)
def _update_complete(result):
self.graph_widget.queue_draw()
d1.addCallback(_update_complete)
@ -163,20 +142,20 @@ class GraphsTab(Tab):
def select_bandwidth_graph(self):
log.debug("Selecting bandwidth graph")
self.graph_widget = self.bandwidth_graph
self.graph = graph.Graph()
self.graph_widget = self.bandwidth_graph
self.graph = Graph()
colors = self.colors['bandwidth_graph']
self.graph.add_stat('download_rate', label='Download Rate',
color=gtk_to_graph_color(colors['download_rate']))
self.graph.add_stat('upload_rate', label='Upload Rate',
color=gtk_to_graph_color(colors['upload_rate']))
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):
log.debug("Selecting connections graph")
self.graph_widget = self.connections_graph
g = graph.Graph()
self.graph_widget = self.connections_graph
g = Graph()
self.graph = g
colors = self.colors['connections_graph']
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):
log.debug("Selecting connections graph")
self.graph_widget = self.seeds_graph
self.graph = graph.Graph()
self.graph_widget = self.seeds_graph
self.graph = Graph()
colors = self.colors['seeds_graph']
self.graph.add_stat('num_peers', color=gtk_to_graph_color(colors['num_peers']))
self.graph.set_left_axis(formatter=int_str, min=10)
@ -197,7 +176,7 @@ class GraphsTab(Tab):
self.colors = colors
# Fake switch page to update the graph colors (HACKY)
self._on_notebook_switch_page(self.notebook,
None, #This is unused
None, # This is unused
self.notebook.get_current_page())
def _on_intervals_changed(self, intervals):
@ -232,6 +211,7 @@ class GraphsTab(Tab):
self.update()
return True
class GtkUI(GtkPluginBase):
def enable(self):
log.debug("Stats plugin enable called")
@ -266,7 +246,7 @@ class GtkUI(GtkPluginBase):
self.config['colors'] = gtkconf
self.graphs_tab.set_colors(self.config['colors'])
config = { }
config = {}
client.stats.set_config(config)
def on_show_prefs(self):

View file

@ -7,6 +7,7 @@ from . import graph
sclient.set_core_uri()
def test_sync():
if 1:
upload = sclient.graph_get_upload()
@ -14,8 +15,28 @@ def test_sync():
print(upload)
print(download)
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]
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]
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]
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
n = NetworkGraph()
@ -25,6 +46,7 @@ def test_sync():
n.draw(800, 200)
n.surface.write_to_png('output_sync.png')
def test_async():
g = graph.Graph()
g.add_stat('download_rate', color=graph.green)
@ -35,6 +57,7 @@ def test_async():
surface = g.draw(600, 300)
surface.write_to_png('output_async.png')
def test_dht():
"""'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_cache_nodes', color=graph.blue)
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.async_request()
aclient.force_call(True)
@ -54,9 +77,10 @@ def test_write():
"""
writing to a file-like object; need this for webui.
"""
class fake_file:
class FakeFile:
def __init__(self):
self.data = []
def write(self, str):
self.data.append(str)
@ -68,7 +92,7 @@ def test_write():
aclient.force_call(True)
surface = g.draw(900, 150)
file_like = fake_file()
file_like = FakeFile()
surface.write_to_png(file_like)
data = "".join(file_like.data)

View file

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

View file

@ -1,52 +1,25 @@
#
# webui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
#
# Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <mvoncken@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.
# Copyright (C) 2007-2008 Andrew Resch <andrewresch@gmail.com>
#
# 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
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource
log = logging.getLogger(__name__)
class WebUI(WebPluginBase):
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) 2008 Martijn Voncken <mvoncken@gmail.com>
#
# Basic plugin template created by:
# 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
@ -47,7 +25,7 @@ __long_description__ = """
Records lots of extra stats
and produces time series
graphs"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]}
__pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup(
name=__plugin_name__,
@ -60,8 +38,8 @@ setup(
long_description=__long_description__,
packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"],
package_data = __pkg_data__,
namespace_packages=["deluge", "deluge.plugins"],
package_data=__pkg_data__,
entry_points="""
[deluge.plugin.core]
@ -70,5 +48,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3)
""" % ((__plugin_name__, __plugin_name__.lower()) * 3)
)

View file

@ -1,5 +1,4 @@
#
# __init__.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
#
@ -8,51 +7,30 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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.
#
from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)

View file

@ -1,5 +1,4 @@
#
# common.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
#
@ -8,36 +7,14 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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.
#
def get_resource(filename):
import pkg_resources, os
import os.path
import pkg_resources
return pkg_resources.resource_filename("deluge.plugins.toggle",
os.path.join("data", filename))

View file

@ -1,5 +1,4 @@
#
# core.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
#
@ -8,39 +7,14 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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 deluge.component as component
import deluge.configmanager
from deluge.core.rpcserver import export
from deluge.plugins.pluginbase import CorePluginBase
@ -49,6 +23,7 @@ log = logging.getLogger(__name__)
DEFAULT_PREFS = {
}
class Core(CorePluginBase):
def enable(self):
self.core = component.get("Core")

View file

@ -1,5 +1,4 @@
#
# gtkui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
#
@ -8,54 +7,27 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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 gtk
import deluge.common
import deluge.component as component
from deluge.plugins.pluginbase import GtkPluginBase
from deluge.ui.client import client
from .common import get_resource
log = logging.getLogger(__name__)
class GtkUI(GtkPluginBase):
def enable(self):
self.core = client.toggle
self.plugin = component.get("PluginManager")
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):
component.get("PluginManager").remove_toolbar_button(self.button)

View file

@ -1,5 +1,4 @@
#
# webui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
#
@ -8,45 +7,20 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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
from deluge import component
from deluge.plugins.pluginbase import WebPluginBase
from deluge.ui.client import client
from .common import get_resource
log = logging.getLogger(__name__)
class WebUI(WebPluginBase):
scripts = [get_resource("toggle.js")]

View file

@ -1,5 +1,4 @@
#
# setup.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2010 John Garland <johnnybg+deluge@gmail.com>
#
@ -8,33 +7,9 @@
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@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.
#
from setuptools import find_packages, setup
@ -47,7 +22,7 @@ __url__ = "http://deluge-torrent.org"
__license__ = "GPLv3"
__description__ = "Toggles the session"
__long_description__ = """"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]}
__pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup(
name=__plugin_name__,
@ -60,8 +35,8 @@ setup(
long_description=__long_description__ if __long_description__ else __description__,
packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"],
package_data = __pkg_data__,
namespace_packages=["deluge", "deluge.plugins"],
package_data=__pkg_data__,
entry_points="""
[deluge.plugin.core]
@ -70,5 +45,5 @@ setup(
%s = deluge.plugins.%s:GtkUIPlugin
[deluge.plugin.web]
%s = deluge.plugins.%s:WebUIPlugin
""" % ((__plugin_name__, __plugin_name__.lower())*3)
""" % ((__plugin_name__, __plugin_name__.lower()) * 3)
)

View file

@ -1,5 +1,4 @@
#
# __init__.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
#
@ -7,51 +6,30 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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.
#
from deluge.plugins.init import PluginInitBase
class CorePlugin(PluginInitBase):
def __init__(self, plugin_name):
from .core import Core as _plugin_cls
self._plugin_cls = _plugin_cls
from .core import Core as _pluginCls
self._plugin_cls = _pluginCls
super(CorePlugin, self).__init__(plugin_name)
class GtkUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from .gtkui import GtkUI as _plugin_cls
self._plugin_cls = _plugin_cls
from .gtkui import GtkUI as _pluginCls
self._plugin_cls = _pluginCls
super(GtkUIPlugin, self).__init__(plugin_name)
class WebUIPlugin(PluginInitBase):
def __init__(self, plugin_name):
from webui import WebUI as _plugin_cls
self._plugin_cls = _plugin_cls
from webui import WebUI as _pluginCls
self._plugin_cls = _pluginCls
super(WebUIPlugin, self).__init__(plugin_name)

View file

@ -1,5 +1,4 @@
#
# common.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
#
@ -7,36 +6,14 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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.
#
def get_resource(filename):
import pkg_resources, os
import os.path
import pkg_resources
return pkg_resources.resource_filename("deluge.plugins.webui",
os.path.join("data", filename))

View file

@ -1,5 +1,4 @@
#
# core.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
#
@ -7,39 +6,14 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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 os
from deluge import common, component, configmanager
from deluge import configmanager
from deluge.core.rpcserver import export
from deluge.plugins.pluginbase import CorePluginBase
@ -51,8 +25,8 @@ DEFAULT_PREFS = {
"port": 8112
}
class Core(CorePluginBase):
class Core(CorePluginBase):
def enable(self):
self.config = configmanager.ConfigManager("web_plugin.conf", DEFAULT_PREFS)
@ -80,6 +54,7 @@ class Core(CorePluginBase):
def got_deluge_web(self):
try:
from deluge.ui.web import server
assert server # silence pyflakes
return True
except ImportError:
return False

View file

@ -1,5 +1,4 @@
#
# gtkui.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
#
@ -7,33 +6,9 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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
@ -41,7 +16,6 @@ import logging
import gtk
import gtk.glade
import deluge.common
import deluge.component as component
from deluge.plugins.pluginbase import GtkPluginBase
from deluge.ui.client import client
@ -50,6 +24,7 @@ from .common import get_resource
log = logging.getLogger(__name__)
class GtkUI(GtkPluginBase):
def enable(self):
self.glade = gtk.glade.XML(get_resource("config.glade"))
@ -99,7 +74,7 @@ class GtkUI(GtkPluginBase):
hbox.pack_start(icon, False, False)
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_padding(5, 5)
hbox.pack_start(label)

View file

@ -1,5 +1,4 @@
#
# setup.py
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
#
@ -7,33 +6,9 @@
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 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.
#
from setuptools import find_packages, setup
@ -46,7 +21,7 @@ __url__ = "http://deluge-torrent.org"
__license__ = "GPLv3"
__description__ = "Allows starting the web interface within the daemon."
__long_description__ = """"""
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): ["template/*", "data/*"]}
__pkg_data__ = {"deluge.plugins." + __plugin_name__.lower(): ["template/*", "data/*"]}
setup(
name=__plugin_name__,
@ -59,13 +34,13 @@ setup(
long_description=__long_description__ if __long_description__ else __description__,
packages=find_packages(),
namespace_packages = ["deluge", "deluge.plugins"],
package_data = __pkg_data__,
namespace_packages=["deluge", "deluge.plugins"],
package_data=__pkg_data__,
entry_points="""
[deluge.plugin.core]
%s = deluge.plugins.%s:CorePlugin
[deluge.plugin.gtkui]
%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):
args = {
"author_name": options.author_name,
"author_name": options.author_name,
"author_email": options.author_email,
"name": name,
"safe_name": safe_name,
"filename": filename,
"plugin_base": plugin_base,
"python_path": python_path,
"url": options.url,
"configdir": options.configdir,
"name": name,
"safe_name": safe_name,
"filename": filename,
"plugin_base": plugin_base,
"python_path": python_path,
"url": options.url,
"configdir": options.configdir,
"current_year": datetime.utcnow().year
}

View file

@ -13,28 +13,36 @@
import logging
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():
return True
else:
try:
tmp = float(string)
float(string)
return True
except: return False;
except:
return False
# set up command-line options
parser = OptionParser()
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("--max_active_limit", help="sets the absolute maximum number of active torrents on the deluge backend", dest="max_active_limit")
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_seeding", help="sets the maximum number of active seeding torrents on the deluge backend", dest="max_active_seeding")
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")
parser.add_option("--host", help="hostname of deluge backend to connect to (default: localhost)",
default="localhost", dest="host")
parser.add_option("--max_active_limit", dest="max_active_limit",
help="sets the absolute maximum number of active torrents on the deluge backend")
parser.add_option("--max_active_downloading", dest="max_active_downloading",
help="sets the maximum number of active downloading torrents on the deluge backend")
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
(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:
settings['max_active_limit'] = int(options.max_active_limit)
else:
stderr.write ("ERROR: Invalid max_active_limit parameter!\n")
exit (-1)
stderr.write("ERROR: Invalid max_active_limit parameter!\n")
exit(-1)
if options.max_active_downloading:
if options.max_active_downloading.isdigit() and int(options.max_active_downloading) >= 0:
settings['max_active_downloading'] = int(options.max_active_downloading)
else:
stderr.write ("ERROR: Invalid max_active_downloading parameter!\n")
exit (-1)
stderr.write("ERROR: Invalid max_active_downloading parameter!\n")
exit(-1)
if options.max_active_seeding:
if options.max_active_seeding.isdigit() and int(options.max_active_seeding) >= 0:
settings['max_active_seeding'] = int(options.max_active_seeding)
else:
stderr.write ("ERROR: Invalid max_active_seeding parameter!\n")
exit (-1)
stderr.write("ERROR: Invalid max_active_seeding parameter!\n")
exit(-1)
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)
else:
stderr.write ("ERROR: Invalid max_download_speed parameter!\n")
exit (-1)
stderr.write("ERROR: Invalid max_download_speed parameter!\n")
exit(-1)
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)
else:
stderr.write ("ERROR: Invalid max_upload_speed parameter!\n")
exit (-1)
stderr.write("ERROR: Invalid max_upload_speed parameter!\n")
exit(-1)
# If there is something to do ...
if settings:

View file

@ -10,7 +10,7 @@ import deluge.common
import deluge.configmanager
import deluge.log
deluge.log.setupLogger("none")
deluge.log.setup_logger("none")
def set_tmp_config_dir():
@ -27,8 +27,8 @@ deluge.common.setup_translations()
def start_core(listen_port=58846):
CWD = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
DAEMON_SCRIPT = """
cwd = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
daemon_script = """
import sys
import deluge.main
@ -38,10 +38,10 @@ deluge.main.start_daemon()
"""
config_directory = set_tmp_config_dir()
fp = tempfile.TemporaryFile()
fp.write(DAEMON_SCRIPT % (config_directory, listen_port))
fp.write(daemon_script % (config_directory, listen_port))
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:
line = core.stderr.readline()
if ("starting on %d" % listen_port) in line:

View file

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

View file

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

View file

@ -64,7 +64,7 @@ class NoVersionSendingClient(Client):
class ClientTestCase(unittest.TestCase):
def setUp(self):
def setUp(self): # NOQA
self.listen_port = 58846
tries = 10
error = None
@ -81,7 +81,7 @@ class ClientTestCase(unittest.TestCase):
if error:
raise error
def tearDown(self):
def tearDown(self): # NOQA
self.core.terminate()
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):
def setUp(self):
def setUp(self): # NOQA
setup_translations()
def tearDown(self):
def tearDown(self): # NOQA
pass
def test_fsize(self):
@ -55,7 +55,7 @@ class CommonTestCase(unittest.TestCase):
self.failUnless(is_ip("127.0.0.1"))
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.1") < 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
class testcomponent(component.Component):
class TestComponent(component.Component):
def __init__(self, name, depend=None):
component.Component.__init__(self, name, depend=depend)
self.start_count = 0
@ -17,7 +17,7 @@ class testcomponent(component.Component):
self.stop_count += 1
class testcomponent_delaystart(testcomponent):
class TestComponentDelayStart(TestComponent):
def start(self):
def do_sleep():
import time
@ -29,7 +29,7 @@ class testcomponent_delaystart(testcomponent):
return d.addCallback(on_done)
class testcomponent_update(component.Component):
class TestComponentUpdate(component.Component):
def __init__(self, name):
component.Component.__init__(self, name)
self.counter = 0
@ -43,7 +43,7 @@ class testcomponent_update(component.Component):
self.stop_count += 1
class testcomponent_shutdown(component.Component):
class TestComponentShutdown(component.Component):
def __init__(self, name):
component.Component.__init__(self, name)
self.shutdowned = False
@ -57,7 +57,7 @@ class testcomponent_shutdown(component.Component):
class ComponentTestClass(unittest.TestCase):
def tearDown(self):
def tearDown(self): # NOQA
component.stop()
component._ComponentRegistry.components = {}
@ -66,7 +66,7 @@ class ComponentTestClass(unittest.TestCase):
self.assertEquals(c._component_state, "Started")
self.assertEquals(c.start_count, 1)
c = testcomponent("test_start_c1")
c = TestComponent("test_start_c1")
d = component.start(["test_start_c1"])
d.addCallback(on_start, c)
return d
@ -85,20 +85,19 @@ class ComponentTestClass(unittest.TestCase):
self.assertEquals(c2.start_count, 1)
return component.stop(["test_start_depends_c1"]).addCallback(on_stop, c1, c2)
c1 = testcomponent("test_start_depends_c1")
c2 = testcomponent("test_start_depends_c2", depend=["test_start_depends_c1"])
c1 = TestComponent("test_start_depends_c1")
c2 = TestComponent("test_start_depends_c2", depend=["test_start_depends_c1"])
d = component.start(["test_start_depends_c2"])
d.addCallback(on_start, c1, c2)
return d
def start_with_depends(self):
c1 = testcomponent_delaystart("test_start_all_c1")
c2 = testcomponent("test_start_all_c2", depend=["test_start_all_c4"])
c3 = testcomponent_delaystart("test_start_all_c3",
depend=["test_start_all_c5", "test_start_all_c1"])
c4 = testcomponent("test_start_all_c4", depend=["test_start_all_c3"])
c5 = testcomponent("test_start_all_c5")
c1 = TestComponentDelayStart("test_start_all_c1")
c2 = TestComponent("test_start_all_c2", depend=["test_start_all_c4"])
c3 = TestComponentDelayStart("test_start_all_c3", depend=["test_start_all_c5", "test_start_all_c1"])
c4 = TestComponent("test_start_all_c4", depend=["test_start_all_c3"])
c5 = TestComponent("test_start_all_c5")
d = component.start()
return (d, c1, c2, c3, c4, c5)
@ -119,10 +118,10 @@ class ComponentTestClass(unittest.TestCase):
return ret[0]
def test_register_exception(self):
testcomponent("test_register_exception_c1")
TestComponent("test_register_exception_c1")
self.assertRaises(
component.ComponentAlreadyRegistered,
testcomponent,
TestComponent,
"test_register_exception_c1")
def test_stop_component(self):
@ -135,7 +134,7 @@ class ComponentTestClass(unittest.TestCase):
self.assertEquals(c._component_state, "Started")
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.addCallback(on_start, c)
return d
@ -163,7 +162,7 @@ class ComponentTestClass(unittest.TestCase):
self.assertNotEqual(c1.counter, counter)
return component.stop()
c1 = testcomponent_update("test_update_c1")
c1 = TestComponentUpdate("test_update_c1")
cnt = int(c1.counter)
d = component.start(["test_update_c1"])
@ -183,7 +182,7 @@ class ComponentTestClass(unittest.TestCase):
d.addCallback(on_pause, c1, counter)
return d
c1 = testcomponent_update("test_pause_c1")
c1 = TestComponentUpdate("test_pause_c1")
cnt = int(c1.counter)
d = component.start(["test_pause_c1"])
@ -201,7 +200,7 @@ class ComponentTestClass(unittest.TestCase):
d.addCallback(on_shutdown, c1)
return d
c1 = testcomponent_shutdown("test_shutdown_c1")
c1 = TestComponentShutdown("test_shutdown_c1")
d = component.start(["test_shutdown_c1"])
d.addCallback(on_start, c1)
return d

View file

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

View file

@ -67,14 +67,14 @@ class TopLevelResource(Resource):
class CoreTestCase(unittest.TestCase):
def setUp(self):
def setUp(self): # NOQA
common.set_tmp_config_dir()
self.rpcserver = RPCServer(listen=False)
self.core = Core()
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())
tries = 10
error = None
@ -92,7 +92,7 @@ class CoreTestCase(unittest.TestCase):
raise error
return result
def tearDown(self):
def tearDown(self): # NOQA
def on_shutdown(result):
component._ComponentRegistry.components = {}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -17,7 +17,7 @@ import deluge.log
import deluge.rencode as rencode
from deluge.transfer import DelugeTransferProtocol
deluge.log.setupLogger("none")
deluge.log.setup_logger("none")
class TransferTestClass(DelugeTransferProtocol):
@ -49,7 +49,7 @@ class TransferTestClass(DelugeTransferProtocol):
def get_messages_in(self):
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
@ -106,7 +106,7 @@ class TransferTestClass(DelugeTransferProtocol):
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
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("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()
if bytes_received >= three_messages_byte_count:

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -41,11 +41,11 @@ class CursesStdIO(object):
""" We want to select on FD 0 """
return 0
def doRead(self):
def doRead(self): # NOQA
"""called when input is ready"""
pass
def logPrefix(self):
def logPrefix(self): # NOQA
return "CursesClient"
@ -57,7 +57,7 @@ class BaseMode(CursesStdIO):
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
add_string(self, row, string) - add a string of text to be displayed.
see method for detailed info
@ -107,7 +107,7 @@ class BaseMode(CursesStdIO):
self.on_resize_norefresh(args)
self.refresh()
def connectionLost(self, reason):
def connectionLost(self, reason): # NOQA
self.close()
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.refresh()
def doRead(self):
def doRead(self): # NOQA
"""
Called when there is data to be read, ie, input from the keyboard.
"""
# We wrap this function to catch exceptions and shutdown the mainloop
try:
self._doRead()
self.read_input()
except Exception as ex:
log.exception(ex)
reactor.stop()
def _doRead(self):
def read_input(self):
# Read the character
self.stdscr.getch()
self.stdscr.refresh()

View file

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

View file

@ -85,7 +85,7 @@ class EventView(BaseMode):
component.get("ConsoleUI").set_mode(self.parent_mode)
self.parent_mode.resume()
def _doRead(self):
def read_input(self):
c = self.stdscr.getch()
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.stdscr.refresh()
def _doRead(self):
def read_input(self):
# Read the character
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.
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
running its own _doRead code if it wants to have the popup handle user input.
The parent *must* also call read_input on the popup instead of/in addition to
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
: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
_doRead(self) - handle user input to the popup.
read_input(self) - handle user input to the popup.
"""
self.parent = parent_mode

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -975,7 +975,7 @@ class WebApi(JSONComponent):
:param event: The event name
:type event: string
"""
self.event_queue.add_listener(__request__.session_id, event)
self.event_queue.add_listener(__request__.session_id, event) # NOQA
@export
def deregister_event_listener(self, event):
@ -985,11 +985,11 @@ class WebApi(JSONComponent):
:param event: The event name
:type event: string
"""
self.event_queue.remove_listener(__request__.session_id, event)
self.event_queue.remove_listener(__request__.session_id, event) # NOQA
@export
def get_events(self):
"""
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):
def getChild(self, path, request):
def getChild(self, path, request): # NOQA
request.render_file = path
return self
@ -152,7 +152,7 @@ class Tracker(resource.Resource):
except KeyError:
self.tracker_icons = TrackerIcons()
def getChild(self, path, request):
def getChild(self, path, request): # NOQA
request.tracker_name = path
return self
@ -175,7 +175,7 @@ class Tracker(resource.Resource):
class Flag(resource.Resource):
def getChild(self, path, request):
def getChild(self, path, request): # NOQA
request.country = path
return self
@ -202,18 +202,18 @@ class LookupResource(resource.Resource, component.Component):
self.__paths = {}
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)
paths = self.__paths.setdefault(path, [])
paths.append(directory)
def removeDirectory(self, directory, path=""):
def remove_directory(self, directory, path=""):
log.debug("Removing directory `%s`", directory)
self.__paths[path].remove(directory)
def getChild(self, path, request):
def getChild(self, path, request): # NOQA
if hasattr(request, 'lookup_path'):
request.lookup_path = os.path.join(request.lookup_path, path)
else:
@ -365,7 +365,7 @@ class ScriptResource(resource.Resource, component.Component):
scripts.append("js/" + path)
return scripts
def getChild(self, path, request):
def getChild(self, path, request): # NOQA
if hasattr(request, "lookup_path"):
request.lookup_path += '/' + path
else:
@ -475,13 +475,13 @@ class TopLevel(resource.Resource):
self.__scripts.remove(script)
self.__debug_scripts.remove(script)
def getChild(self, path, request):
def getChild(self, path, request): # NOQA
if path == "":
return self
else:
return resource.Resource.getChild(self, path, request)
def getChildWithDefault(self, path, request):
def getChildWithDefault(self, path, request): # NOQA
# Calculate the request base
header = request.getHeader('x-deluge-base')
base = header if header else component.get("DelugeWeb").base
@ -540,7 +540,7 @@ class TopLevel(resource.Resource):
class ServerContextFactory:
def getContext(self):
def getContext(self): # NOQA
"""Creates an SSL context."""
ctx = SSL.Context(SSL.SSLv3_METHOD)
deluge_web = component.get("DelugeWeb")

View file

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

437
msgfmt.py
View file

@ -1,220 +1,219 @@
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
# Written by Martin v. Lwis <loewis@informatik.hu-berlin.de>
# Plural forms support added by alexander smishlajev <alex@tycobka.lv>
"""
Generate binary message catalog from textual translation description.
This program converts a textual Uniforum-style message catalog (.po file) into
a binary GNU catalog (.mo file). This is essentially the same function as the
GNU msgfmt program, however, it is a simpler implementation.
Usage: msgfmt.py [OPTIONS] filename.po
Options:
-o file
--output-file=file
Specify the output file to write to. If omitted, output will go to a
file named filename.mo (based off the input file name).
-h
--help
Print this message and exit.
-V
--version
Display version information and exit.
"""
import sys
import os
import getopt
import struct
import array
__version__ = "1.1"
MESSAGES = {}
def usage (ecode, msg=''):
"""
Print usage and msg and exit with given code.
"""
print >> sys.stderr, __doc__
if msg:
print >> sys.stderr, msg
sys.exit(ecode)
def add (msgid, transtr, fuzzy):
"""
Add a non-fuzzy translation to the dictionary.
"""
global MESSAGES
if not fuzzy and transtr and not transtr.startswith('\0'):
MESSAGES[msgid] = transtr
def generate ():
"""
Return the generated output.
"""
global MESSAGES
keys = MESSAGES.keys()
# the keys are sorted in the .mo file
keys.sort()
offsets = []
ids = strs = ''
for _id in keys:
# For each string, we need size and file offset. Each string is NUL
# terminated; the NUL does not count into the size.
offsets.append((len(ids), len(_id), len(strs), len(MESSAGES[_id])))
ids += _id + '\0'
strs += MESSAGES[_id] + '\0'
output = ''
# The header is 7 32-bit unsigned integers. We don't use hash tables, so
# the keys start right after the index tables.
# translated string.
keystart = 7*4+16*len(keys)
# and the values start after the keys
valuestart = keystart + len(ids)
koffsets = []
voffsets = []
# 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.
for o1, l1, o2, l2 in offsets:
koffsets += [l1, o1+keystart]
voffsets += [l2, o2+valuestart]
offsets = koffsets + voffsets
output = struct.pack("Iiiiiii",
0x950412deL, # Magic
0, # Version
len(keys), # # of entries
7*4, # start of key index
7*4+len(keys)*8, # start of value index
0, 0) # size and offset of hash table
output += array.array("i", offsets).tostring()
output += ids
output += strs
return output
def make (filename, outfile):
ID = 1
STR = 2
global MESSAGES
MESSAGES = {}
# Compute .mo name from .po name and arguments
if filename.endswith('.po'):
infile = filename
else:
infile = filename + '.po'
if outfile is None:
outfile = os.path.splitext(infile)[0] + '.mo'
try:
lines = open(infile).readlines()
except IOError, msg:
print >> sys.stderr, msg
sys.exit(1)
section = None
fuzzy = 0
# Parse the catalog
msgid = msgstr = ''
lno = 0
for l in lines:
lno += 1
# If we get a comment line after a msgstr, this is a new entry
if l[0] == '#' and section == STR:
add(msgid, msgstr, fuzzy)
section = None
fuzzy = 0
# Record a fuzzy mark
if l[:2] == '#,' and (l.find('fuzzy') >= 0):
fuzzy = 1
# Skip comments
if l[0] == '#':
continue
# Start of msgid_plural section, separate from singular form with \0
if l.startswith('msgid_plural'):
msgid += '\0'
l = l[12:]
# Now we are in a msgid section, output previous section
elif l.startswith('msgid'):
if section == STR:
add(msgid, msgstr, fuzzy)
section = ID
l = l[5:]
msgid = msgstr = ''
# Now we are in a msgstr section
elif l.startswith('msgstr'):
section = STR
l = l[6:]
# Check for plural forms
if l.startswith('['):
# Separate plural forms with \0
if not l.startswith('[0]'):
msgstr += '\0'
# Ignore the index - must come in sequence
l = l[l.index(']') + 1:]
# Skip empty lines
l = l.strip()
if not l:
continue
# XXX: Does this always follow Python escape semantics?
l = eval(l)
if section == ID:
msgid += l
elif section == STR:
msgstr += l
else:
print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \
'before:'
print >> sys.stderr, l
sys.exit(1)
# Add last entry
if section == STR:
add(msgid, msgstr, fuzzy)
# Compute output
output = generate()
try:
open(outfile,"wb").write(output)
except IOError,msg:
print >> sys.stderr, msg
def main ():
try:
opts, args = getopt.getopt(sys.argv[1:], 'hVo:',
['help', 'version', 'output-file='])
except getopt.error, msg:
usage(1, msg)
outfile = None
# parse options
for opt, arg in opts:
if opt in ('-h', '--help'):
usage(0)
elif opt in ('-V', '--version'):
print >> sys.stderr, "msgfmt.py", __version__
sys.exit(0)
elif opt in ('-o', '--output-file'):
outfile = arg
# do it
if not args:
print >> sys.stderr, 'No input file given'
print >> sys.stderr, "Try `msgfmt --help' for more information."
return
for filename in args:
make(filename, outfile)
if __name__ == '__main__':
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
# Written by Martin v. Lwis <loewis@informatik.hu-berlin.de>
# Plural forms support added by alexander smishlajev <alex@tycobka.lv>
"""
Generate binary message catalog from textual translation description.
This program converts a textual Uniforum-style message catalog (.po file) into
a binary GNU catalog (.mo file). This is essentially the same function as the
GNU msgfmt program, however, it is a simpler implementation.
Usage: msgfmt.py [OPTIONS] filename.po
Options:
-o file
--output-file=file
Specify the output file to write to. If omitted, output will go to a
file named filename.mo (based off the input file name).
-h
--help
Print this message and exit.
-V
--version
Display version information and exit.
"""
import sys
import os
import getopt
import struct
import array
__version__ = "1.1"
MESSAGES = {}
def usage(ecode, msg=''):
"""
Print usage and msg and exit with given code.
"""
print >> sys.stderr, __doc__
if msg:
print >> sys.stderr, msg
sys.exit(ecode)
def add(msgid, transtr, fuzzy):
"""
Add a non-fuzzy translation to the dictionary.
"""
global MESSAGES
if not fuzzy and transtr and not transtr.startswith('\0'):
MESSAGES[msgid] = transtr
def generate():
"""
Return the generated output.
"""
global MESSAGES
keys = MESSAGES.keys()
# the keys are sorted in the .mo file
keys.sort()
offsets = []
ids = strs = ''
for _id in keys:
# For each string, we need size and file offset. Each string is NUL
# terminated; the NUL does not count into the size.
offsets.append((len(ids), len(_id), len(strs), len(MESSAGES[_id])))
ids += _id + '\0'
strs += MESSAGES[_id] + '\0'
output = ''
# The header is 7 32-bit unsigned integers. We don't use hash tables, so
# the keys start right after the index tables.
# translated string.
keystart = 7 * 4 + 16 * len(keys)
# and the values start after the keys
valuestart = keystart + len(ids)
koffsets = []
voffsets = []
# 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.
for o1, l1, o2, l2 in offsets:
koffsets += [l1, o1 + keystart]
voffsets += [l2, o2 + valuestart]
offsets = koffsets + voffsets
output = struct.pack("Iiiiiii",
0x950412deL, # Magic
0, # Version
len(keys), # # of entries
7 * 4, # start of key index
7 * 4 + len(keys) * 8, # start of value index
0, 0) # size and offset of hash table
output += array.array("i", offsets).tostring()
output += ids
output += strs
return output
def make(filename, outfile):
section_id = 1
section_str = 2
global MESSAGES
MESSAGES = {}
# Compute .mo name from .po name and arguments
if filename.endswith('.po'):
infile = filename
else:
infile = filename + '.po'
if outfile is None:
outfile = os.path.splitext(infile)[0] + '.mo'
try:
lines = open(infile).readlines()
except IOError, msg:
print >> sys.stderr, msg
sys.exit(1)
section = None
fuzzy = 0
# Parse the catalog
msgid = msgstr = ''
lno = 0
for l in lines:
lno += 1
# If we get a comment line after a msgstr, this is a new entry
if l[0] == '#' and section == section_str:
add(msgid, msgstr, fuzzy)
section = None
fuzzy = 0
# Record a fuzzy mark
if l[:2] == '#,' and (l.find('fuzzy') >= 0):
fuzzy = 1
# Skip comments
if l[0] == '#':
continue
# Start of msgid_plural section, separate from singular form with \0
if l.startswith('msgid_plural'):
msgid += '\0'
l = l[12:]
# Now we are in a msgid section, output previous section
elif l.startswith('msgid'):
if section == section_str:
add(msgid, msgstr, fuzzy)
section = section_id
l = l[5:]
msgid = msgstr = ''
# Now we are in a msgstr section
elif l.startswith('msgstr'):
section = section_str
l = l[6:]
# Check for plural forms
if l.startswith('['):
# Separate plural forms with \0
if not l.startswith('[0]'):
msgstr += '\0'
# Ignore the index - must come in sequence
l = l[l.index(']') + 1:]
# Skip empty lines
l = l.strip()
if not l:
continue
# XXX: Does this always follow Python escape semantics?
l = eval(l)
if section == section_id:
msgid += l
elif section == section_str:
msgstr += l
else:
print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), 'before:'
print >> sys.stderr, l
sys.exit(1)
# Add last entry
if section == section_str:
add(msgid, msgstr, fuzzy)
# Compute output
output = generate()
try:
open(outfile, "wb").write(output)
except IOError, msg:
print >> sys.stderr, msg
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], 'hVo:',
['help', 'version', 'output-file='])
except getopt.error, msg:
usage(1, msg)
outfile = None
# parse options
for opt, arg in opts:
if opt in ('-h', '--help'):
usage(0)
elif opt in ('-V', '--version'):
print >> sys.stderr, "msgfmt.py", __version__
sys.exit(0)
elif opt in ('-o', '--output-file'):
outfile = arg
# do it
if not args:
print >> sys.stderr, 'No input file given'
print >> sys.stderr, "Try `msgfmt --help' for more information."
return
for filename in args:
make(filename, outfile)
if __name__ == '__main__':
main()

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