mirror of
https://github.com/codex-storage/deluge.git
synced 2025-01-11 12:04:10 +00:00
Revert 67ea05921cb904cb2ddf5811cd96534321bfeefa which changed how event handlers worked.
Unfortunately this will not work with plugins as they do not have the events defined and the creation of the event object fails.
This commit is contained in:
parent
5f0f7204a8
commit
499a58f50d
@ -10,7 +10,6 @@
|
||||
* #1247: Fix deluge-gtk from hanging on shutdown
|
||||
* #995: Rewrote tracker_icons
|
||||
* Make the distinction between adding to the session new unmanaged torrents and torrents loaded from state. This will break backwards compatability.
|
||||
* Pass a copy of an event instead of passing the event arguments to the event handlers. This will break backwards compatability.
|
||||
|
||||
==== GtkUI ====
|
||||
* Fix uncaught exception when closing deluge in classic mode
|
||||
|
@ -55,7 +55,7 @@ class EventManager(component.Component):
|
||||
if event.name in self.handlers:
|
||||
for handler in self.handlers[event.name]:
|
||||
#log.debug("Running handler %s for event %s with args: %s", event.name, handler, event.args)
|
||||
handler(event.copy())
|
||||
handler(*event.args)
|
||||
|
||||
def register_event_handler(self, event, handler):
|
||||
"""
|
||||
|
@ -486,8 +486,7 @@ class RPCServer(component.Component):
|
||||
# Find sessions interested in this event
|
||||
for session_id, interest in self.factory.interested_events.iteritems():
|
||||
if event.name in interest:
|
||||
log.debug("Emit Event: %s %s", event.name, zip(event.__slots__,
|
||||
event.args))
|
||||
log.debug("Emit Event: %s %s", event.name, event.args)
|
||||
# This session is interested so send a RPC_EVENT
|
||||
self.factory.session_protocols[session_id].sendData(
|
||||
(RPC_EVENT, event.name, event.args)
|
||||
|
@ -2,7 +2,6 @@
|
||||
# event.py
|
||||
#
|
||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
||||
# Copyright (C) 2010 Pedro Algarvio <pedro@algarvio.me>
|
||||
#
|
||||
# Deluge is free software.
|
||||
#
|
||||
@ -48,8 +47,6 @@ class DelugeEventMetaClass(type):
|
||||
"""
|
||||
This metaclass simply keeps a list of all events classes created.
|
||||
"""
|
||||
__slots__ = ()
|
||||
|
||||
def __init__(cls, name, bases, dct):
|
||||
super(DelugeEventMetaClass, cls).__init__(name, bases, dct)
|
||||
if name != "DelugeEvent":
|
||||
@ -65,26 +62,23 @@ class DelugeEvent(object):
|
||||
:type args: list
|
||||
|
||||
"""
|
||||
__slots__ = ()
|
||||
__metaclass__ = DelugeEventMetaClass
|
||||
|
||||
def _get_name(self):
|
||||
return self.__class__.__name__
|
||||
name = property(fget=_get_name)
|
||||
|
||||
def _get_args(self):
|
||||
return [getattr(self, arg) for arg in self.__slots__]
|
||||
args = property(fget=_get_args)
|
||||
if not hasattr(self, "_args"):
|
||||
return []
|
||||
return self._args
|
||||
|
||||
def copy(self):
|
||||
return self.__class__(*self.args)
|
||||
name = property(fget=_get_name)
|
||||
args = property(fget=_get_args)
|
||||
|
||||
class TorrentAddedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a new torrent is successfully added to the session.
|
||||
"""
|
||||
__slots__ = ('torrent_id', 'from_state')
|
||||
|
||||
def __init__(self, torrent_id, from_state):
|
||||
"""
|
||||
:param torrent_id: the torrent_id of the torrent that was added
|
||||
@ -92,41 +86,34 @@ class TorrentAddedEvent(DelugeEvent):
|
||||
:param from_state: was the torrent loaded from state? Or is it a new torrent.
|
||||
:type from_state: bool
|
||||
"""
|
||||
self.torrent_id = torrent_id
|
||||
self.from_state = from_state
|
||||
self._args = [torrent_id, from_state]
|
||||
|
||||
class TorrentRemovedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a torrent has been removed from the session.
|
||||
"""
|
||||
__slots__ = ('torrent_id',)
|
||||
|
||||
def __init__(self, torrent_id):
|
||||
"""
|
||||
:param torrent_id: the torrent_id
|
||||
:type torrent_id: string
|
||||
"""
|
||||
self.torrent_id = torrent_id
|
||||
self._args = [torrent_id]
|
||||
|
||||
class PreTorrentRemovedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a torrent is about to be removed from the session.
|
||||
"""
|
||||
__slots__ = ('torrent_id',)
|
||||
|
||||
def __init__(self, torrent_id):
|
||||
"""
|
||||
:param torrent_id: the torrent_id
|
||||
:type torrent_id: string
|
||||
"""
|
||||
self.torrent_id = torrent_id
|
||||
self._args = [torrent_id]
|
||||
|
||||
class TorrentStateChangedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a torrent changes state.
|
||||
"""
|
||||
__slots__ = ('torrent_id', 'state')
|
||||
|
||||
def __init__(self, torrent_id, state):
|
||||
"""
|
||||
:param torrent_id: the torrent_id
|
||||
@ -134,20 +121,18 @@ class TorrentStateChangedEvent(DelugeEvent):
|
||||
:param state: the new state
|
||||
:type state: string
|
||||
"""
|
||||
self.torrent_id = torrent_id
|
||||
self.state = state
|
||||
self._args = [torrent_id, state]
|
||||
|
||||
class TorrentQueueChangedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when the queue order has changed.
|
||||
"""
|
||||
pass
|
||||
|
||||
class TorrentFolderRenamedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a folder within a torrent has been renamed.
|
||||
"""
|
||||
__slots__ = ('torrent_id', 'old', 'new')
|
||||
|
||||
def __init__(self, torrent_id, old, new):
|
||||
"""
|
||||
:param torrent_id: the torrent_id
|
||||
@ -157,54 +142,44 @@ class TorrentFolderRenamedEvent(DelugeEvent):
|
||||
:param new: the new folder name
|
||||
:type new: string
|
||||
"""
|
||||
self.torrent_id = torrent_id
|
||||
self.old = old
|
||||
self.new = new
|
||||
self._args = [torrent_id, old, new]
|
||||
|
||||
class TorrentFileRenamedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a file within a torrent has been renamed.
|
||||
"""
|
||||
__slots__ = ('torrent_id', 'index', 'filename')
|
||||
|
||||
def __init__(self, torrent_id, index, filename):
|
||||
def __init__(self, torrent_id, index, name):
|
||||
"""
|
||||
:param torrent_id: the torrent_id
|
||||
:type torrent_id: string
|
||||
:param index: the index of the file
|
||||
:type index: int
|
||||
:param filename: the new filename
|
||||
:type filename: string
|
||||
:param name: the new filename
|
||||
:type name: string
|
||||
"""
|
||||
self.torrent_id = torrent_id
|
||||
self.index = index
|
||||
self.filename = filename
|
||||
self._args = [torrent_id, index, name]
|
||||
|
||||
class TorrentFinishedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a torrent finishes downloading.
|
||||
"""
|
||||
__slots__ = ('torrent_id',)
|
||||
|
||||
def __init__(self, torrent_id):
|
||||
"""
|
||||
:param torrent_id: the torrent_id
|
||||
:type torrent_id: string
|
||||
"""
|
||||
self.torrent_id = torrent_id
|
||||
self._args = [torrent_id]
|
||||
|
||||
class TorrentResumedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a torrent resumes from a paused state.
|
||||
"""
|
||||
__slots__ = ('torrent_id',)
|
||||
|
||||
def __init__(self, torrent_id):
|
||||
"""
|
||||
:param torrent_id: the torrent_id
|
||||
:type torrent_id: string
|
||||
"""
|
||||
self.torrent_id = torrent_id
|
||||
self._args = [torrent_id]
|
||||
|
||||
class TorrentFileCompletedEvent(DelugeEvent):
|
||||
"""
|
||||
@ -213,8 +188,6 @@ class TorrentFileCompletedEvent(DelugeEvent):
|
||||
This will only work with libtorrent 0.15 or greater.
|
||||
|
||||
"""
|
||||
__slots__ = ('torrent_id', 'index')
|
||||
|
||||
def __init__(self, torrent_id, index):
|
||||
"""
|
||||
:param torrent_id: the torrent_id
|
||||
@ -222,75 +195,60 @@ class TorrentFileCompletedEvent(DelugeEvent):
|
||||
:param index: the file index
|
||||
:type index: int
|
||||
"""
|
||||
self.torrent_id = torrent_id
|
||||
self.index = index
|
||||
self._args = [torrent_id, index]
|
||||
|
||||
class NewVersionAvailableEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a more recent version of Deluge is available.
|
||||
"""
|
||||
__slots__ = ('new_release',)
|
||||
|
||||
def __init__(self, new_release):
|
||||
"""
|
||||
:param new_release: the new version that is available
|
||||
:type new_release: string
|
||||
"""
|
||||
self.new_release = new_release
|
||||
self._args = [new_release]
|
||||
|
||||
class SessionStartedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a session has started. This typically only happens once when
|
||||
the daemon is initially started.
|
||||
"""
|
||||
pass
|
||||
|
||||
class SessionPausedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when the session has been paused.
|
||||
"""
|
||||
pass
|
||||
|
||||
class SessionResumedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when the session has been resumed.
|
||||
"""
|
||||
pass
|
||||
|
||||
class ConfigValueChangedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a config value changes in the Core.
|
||||
"""
|
||||
__slots__ = ('key', 'value')
|
||||
|
||||
def __init__(self, key, value):
|
||||
"""
|
||||
:param key: the key that changed
|
||||
:type key: string
|
||||
:param value: the new value of the `:param:key`
|
||||
"""
|
||||
self.key = key
|
||||
self.value = value
|
||||
self._args = [key, value]
|
||||
|
||||
class PluginEnabledEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a plugin is enabled in the Core.
|
||||
"""
|
||||
__slots__ = ('plugin_name',)
|
||||
|
||||
def __init__(self, plugin_name):
|
||||
"""
|
||||
:param plugin_name: the plugin name
|
||||
:type plugin_name: string
|
||||
"""
|
||||
self.plugin_name = plugin_name
|
||||
def __init__(self, name):
|
||||
self._args = [name]
|
||||
|
||||
class PluginDisabledEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a plugin is disabled in the Core.
|
||||
"""
|
||||
__slots__ = ('plugin_name',)
|
||||
|
||||
def __init__(self, plugin_name):
|
||||
"""
|
||||
:param plugin_name: the plugin name
|
||||
:type plugin_name: string
|
||||
"""
|
||||
self.plugin_name = plugin_name
|
||||
def __init__(self, name):
|
||||
self._args = [name]
|
||||
|
@ -45,7 +45,7 @@ import zlib
|
||||
|
||||
import deluge.common
|
||||
import deluge.component as component
|
||||
from deluge.event import known_events
|
||||
from deluge.log import LOG as log
|
||||
|
||||
if deluge.common.windows_check():
|
||||
import win32api
|
||||
@ -166,14 +166,13 @@ class DelugeRPCProtocol(Protocol):
|
||||
message_type = request[0]
|
||||
|
||||
if message_type == RPC_EVENT:
|
||||
event_name = request[1]
|
||||
event = request[1]
|
||||
#log.debug("Received RPCEvent: %s", event)
|
||||
# A RPCEvent was received from the daemon so run any handlers
|
||||
# associated with it.
|
||||
if event_name in self.factory.event_handlers:
|
||||
event = known_events[event_name](*request[2])
|
||||
for handler in self.factory.event_handlers[event_name]:
|
||||
reactor.callLater(0, handler, event.copy())
|
||||
if event in self.factory.event_handlers:
|
||||
for handler in self.factory.event_handlers[event]:
|
||||
reactor.callLater(0, handler, *request[2])
|
||||
continue
|
||||
|
||||
request_id = request[1]
|
||||
|
@ -62,53 +62,53 @@ class EventLog(component.Component):
|
||||
client.register_event_handler("PluginEnabledEvent", self.on_plugin_enabled_event)
|
||||
client.register_event_handler("PluginDisabledEvent", self.on_plugin_disabled_event)
|
||||
|
||||
def on_torrent_added_event(self, event):
|
||||
def on_torrent_added_event(self, torrent_id, from_state):
|
||||
def on_torrent_status(status):
|
||||
self.console.write(self.prefix + "TorrentAdded(from_state=%s): {!info!}%s (%s)" % (
|
||||
event.from_state, status["name"], event.torrent_id)
|
||||
from_state, status["name"], torrent_id)
|
||||
)
|
||||
client.core.get_torrent_status(event.torrent_id, ["name"]).addCallback(on_torrent_status)
|
||||
client.core.get_torrent_status(torrent_id, ["name"]).addCallback(on_torrent_status)
|
||||
|
||||
def on_torrent_removed_event(self, event):
|
||||
def on_torrent_removed_event(self, torrent_id):
|
||||
self.console.write(self.prefix + "TorrentRemoved: {!info!}%s (%s)" %
|
||||
(self.console.get_torrent_name(event.torrent_id), event.torrent_id))
|
||||
(self.console.get_torrent_name(torrent_id), torrent_id))
|
||||
|
||||
def on_torrent_state_changed_event(self, event):
|
||||
def on_torrent_state_changed_event(self, torrent_id, state):
|
||||
# Modify the state string color
|
||||
if event.state in colors.state_color:
|
||||
state = colors.state_color[event.state] + event.state
|
||||
if state in colors.state_color:
|
||||
state = colors.state_color[state] + state
|
||||
|
||||
self.console.write(self.prefix + "TorrentStateChanged: %s {!info!}%s (%s)" %
|
||||
(state, self.console.get_torrent_name(event.torrent_id), event.torrent_id))
|
||||
(state, self.console.get_torrent_name(torrent_id), torrent_id))
|
||||
|
||||
def on_torrent_paused_event(self, event):
|
||||
def on_torrent_paused_event(self, torrent_id):
|
||||
self.console.write(self.prefix + "TorrentPaused: {!info!}%s (%s)" %
|
||||
(self.console.get_torrent_name(event.torrent_id), event.torrent_id))
|
||||
(self.console.get_torrent_name(torrent_id), torrent_id))
|
||||
|
||||
def on_torrent_finished_event(self, event):
|
||||
def on_torrent_finished_event(self, torrent_id):
|
||||
self.console.write(self.prefix + "TorrentFinished: {!info!}%s (%s)" %
|
||||
(self.console.get_torrent_name(event.torrent_id), event.torrent_id))
|
||||
(self.console.get_torrent_name(torrent_id), torrent_id))
|
||||
|
||||
def on_new_version_available_event(self, event):
|
||||
def on_new_version_available_event(self, version):
|
||||
self.console.write(self.prefix + "NewVersionAvailable: {!info!}%s" %
|
||||
(event.new_release))
|
||||
(version))
|
||||
|
||||
def on_session_paused_event(self, event):
|
||||
def on_session_paused_event(self):
|
||||
self.console.write(self.prefix + "SessionPaused")
|
||||
|
||||
def on_session_resumed_event(self, event):
|
||||
def on_session_resumed_event(self):
|
||||
self.console.write(self.prefix + "SessionResumed")
|
||||
|
||||
def on_config_value_changed_event(self, event):
|
||||
def on_config_value_changed_event(self, key, value):
|
||||
color = "{!white,black,bold!}"
|
||||
if type(event.value) in colors.type_color:
|
||||
color = colors.type_color[type(event.value)]
|
||||
if type(value) in colors.type_color:
|
||||
color = colors.type_color[type(value)]
|
||||
|
||||
self.console.write(self.prefix + "ConfigValueChanged: {!input!}%s: %s%s" %
|
||||
(event.key, color, event.value))
|
||||
(key, color, value))
|
||||
|
||||
def on_plugin_enabled_event(self, event):
|
||||
self.console.write(self.prefix + "PluginEnabled: {!info!}%s" % event.plugin_name)
|
||||
def on_plugin_enabled_event(self, name):
|
||||
self.console.write(self.prefix + "PluginEnabled: {!info!}%s" % name)
|
||||
|
||||
def on_plugin_disabled_event(self, event):
|
||||
self.console.write(self.prefix + "PluginDisabled: {!info!}%s" % event.plugin_name)
|
||||
def on_plugin_disabled_event(self, name):
|
||||
self.console.write(self.prefix + "PluginDisabled: {!info!}%s" % name)
|
||||
|
@ -34,28 +34,24 @@
|
||||
#
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
import os, sys
|
||||
import optparse
|
||||
import shlex
|
||||
import locale
|
||||
|
||||
from twisted.internet import defer, reactor
|
||||
|
||||
from deluge.ui.console import UI_PATH
|
||||
import deluge.component as component
|
||||
from deluge.ui.client import client
|
||||
import deluge.common
|
||||
from deluge.ui.coreconfig import CoreConfig
|
||||
from deluge.ui.sessionproxy import SessionProxy
|
||||
from deluge.ui.console.statusbars import StatusBars
|
||||
from deluge.ui.console.eventlog import EventLog
|
||||
#import screen
|
||||
import screen
|
||||
import colors
|
||||
from deluge.log import LOG as log
|
||||
from deluge.ui.ui import _UI
|
||||
from deluge.ui.console import UI_PATH
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class Console(_UI):
|
||||
|
||||
@ -63,62 +59,16 @@ class Console(_UI):
|
||||
|
||||
def __init__(self):
|
||||
super(Console, self).__init__("console")
|
||||
group = optparse.OptionGroup(self.parser, "Console Options","These options control how "
|
||||
"the console connects to the daemon. These options will be "
|
||||
"used if you pass a command, or if you have autoconnect "
|
||||
"enabled for the console ui.")
|
||||
cmds = load_commands(os.path.join(UI_PATH, 'commands'))
|
||||
|
||||
group.add_option("-d","--daemon",dest="daemon_addr",
|
||||
action="store",type="str",default="127.0.0.1",
|
||||
help="Set the address of the daemon to connect to."
|
||||
" [default: %default]")
|
||||
group.add_option("-p","--port",dest="daemon_port",
|
||||
help="Set the port to connect to the daemon on. [default: %default]",
|
||||
action="store",type="int",default=58846)
|
||||
group.add_option("-u","--username",dest="daemon_user",
|
||||
help="Set the username to connect to the daemon with. [default: %default]",
|
||||
action="store",type="string")
|
||||
group.add_option("-P","--password",dest="daemon_pass",
|
||||
help="Set the password to connect to the daemon with. [default: %default]",
|
||||
action="store",type="string")
|
||||
group = optparse.OptionGroup(self.parser, "Console Commands",
|
||||
"\n".join(cmds.keys()))
|
||||
self.parser.add_option_group(group)
|
||||
|
||||
self.cmds = load_commands(os.path.join(UI_PATH, 'commands'))
|
||||
class CommandOptionGroup(optparse.OptionGroup):
|
||||
def __init__(self, parser, title, description=None, cmds = None):
|
||||
optparse.OptionGroup.__init__(self,parser,title,description)
|
||||
self.cmds = cmds
|
||||
|
||||
def format_help(self, formatter):
|
||||
result = formatter.format_heading(self.title)
|
||||
formatter.indent()
|
||||
if self.description:
|
||||
result += "%s\n"%formatter.format_description(self.description)
|
||||
for cname in self.cmds:
|
||||
cmd = self.cmds[cname]
|
||||
if cmd.interactive_only or cname in cmd.aliases: continue
|
||||
allnames = [cname]
|
||||
allnames.extend(cmd.aliases)
|
||||
cname = "/".join(allnames)
|
||||
result += formatter.format_heading(" - ".join([cname,cmd.__doc__]))
|
||||
formatter.indent()
|
||||
result += "%*s%s\n" % (formatter.current_indent, "", cmd.usage)
|
||||
formatter.dedent()
|
||||
formatter.dedent()
|
||||
return result
|
||||
cmd_group = CommandOptionGroup(self.parser, "Console Commands",
|
||||
description="The following commands can be issued at the "
|
||||
"command line. Commands should be quoted, so, for example, "
|
||||
"to pause torrent with id 'abc' you would run: '%s "
|
||||
"\"pause abc\"'"%os.path.basename(sys.argv[0]),
|
||||
cmds=self.cmds)
|
||||
self.parser.add_option_group(cmd_group)
|
||||
|
||||
def start(self):
|
||||
super(Console, self).start()
|
||||
ConsoleUI(self.args,self.cmds,(self.options.daemon_addr,
|
||||
self.options.daemon_port,self.options.daemon_user,
|
||||
self.options.daemon_pass))
|
||||
|
||||
ConsoleUI(self.args)
|
||||
|
||||
def start():
|
||||
Console().start()
|
||||
@ -139,11 +89,9 @@ class OptionParser(optparse.OptionParser):
|
||||
"""
|
||||
raise Exception(msg)
|
||||
|
||||
|
||||
class BaseCommand(object):
|
||||
|
||||
usage = 'usage'
|
||||
interactive_only = False
|
||||
option_list = tuple()
|
||||
aliases = []
|
||||
|
||||
@ -171,7 +119,6 @@ class BaseCommand(object):
|
||||
epilog = self.epilog,
|
||||
option_list = self.option_list)
|
||||
|
||||
|
||||
def load_commands(command_dir, exclude=[]):
|
||||
def get_command(name):
|
||||
return getattr(__import__('deluge.ui.console.commands.%s' % name, {}, {}, ['Command']), 'Command')()
|
||||
@ -192,13 +139,11 @@ def load_commands(command_dir, exclude=[]):
|
||||
except OSError, e:
|
||||
return {}
|
||||
|
||||
|
||||
class ConsoleUI(component.Component):
|
||||
def __init__(self, args=None, cmds = None, daemon = None):
|
||||
def __init__(self, args=None):
|
||||
component.Component.__init__(self, "ConsoleUI", 2)
|
||||
|
||||
# keep track of events for the log view
|
||||
self.events = []
|
||||
self.batch_write = False
|
||||
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
@ -207,10 +152,8 @@ class ConsoleUI(component.Component):
|
||||
self.encoding = sys.getdefaultencoding()
|
||||
|
||||
log.debug("Using encoding: %s", self.encoding)
|
||||
|
||||
|
||||
# start up the session proxy
|
||||
self.sessionproxy = SessionProxy()
|
||||
# Load all the commands
|
||||
self._commands = load_commands(os.path.join(UI_PATH, 'commands'))
|
||||
|
||||
client.set_disconnect_callback(self.on_client_disconnect)
|
||||
|
||||
@ -219,18 +162,30 @@ class ConsoleUI(component.Component):
|
||||
if args:
|
||||
args = args[0]
|
||||
self.interactive = False
|
||||
if not cmds:
|
||||
print "Sorry, couldn't find any commands"
|
||||
return
|
||||
else:
|
||||
self._commands = cmds
|
||||
from commander import Commander
|
||||
cmdr = Commander(cmds)
|
||||
if daemon:
|
||||
cmdr.exec_args(args,*daemon)
|
||||
else:
|
||||
cmdr.exec_args(args,None,None,None,None)
|
||||
|
||||
# Try to connect to the localhost daemon
|
||||
def on_connect(result):
|
||||
def on_started(result):
|
||||
if not self.interactive:
|
||||
def on_started(result):
|
||||
deferreds = []
|
||||
# If we have args, lets process them and quit
|
||||
# allow multiple commands split by ";"
|
||||
for arg in args.split(";"):
|
||||
deferreds.append(defer.maybeDeferred(self.do_command, arg.strip()))
|
||||
|
||||
def on_complete(result):
|
||||
self.do_command("quit")
|
||||
|
||||
dl = defer.DeferredList(deferreds).addCallback(on_complete)
|
||||
|
||||
# We need to wait for the rpcs in start() to finish before processing
|
||||
# any of the commands.
|
||||
self.started_deferred.addCallback(on_started)
|
||||
component.start().addCallback(on_started)
|
||||
|
||||
d = client.connect()
|
||||
d.addCallback(on_connect)
|
||||
|
||||
self.coreconfig = CoreConfig()
|
||||
if self.interactive and not deluge.common.windows_check():
|
||||
@ -239,13 +194,8 @@ class ConsoleUI(component.Component):
|
||||
import curses.wrapper
|
||||
curses.wrapper(self.run)
|
||||
elif self.interactive and deluge.common.windows_check():
|
||||
print """\nDeluge-console does not run in interactive mode on Windows. \n
|
||||
Please use commands from the command line, eg:\n
|
||||
deluge-console.exe help
|
||||
deluge-console.exe info
|
||||
deluge-console.exe "add --help"
|
||||
deluge-console.exe "add -p c:\\mytorrents c:\\new.torrent"
|
||||
"""
|
||||
print "You cannot run the deluge-console in interactive mode in Windows.\
|
||||
Please use commands from the command line, eg: deluge-console config;help;exit"
|
||||
else:
|
||||
reactor.run()
|
||||
|
||||
@ -260,9 +210,8 @@ Please use commands from the command line, eg:\n
|
||||
# We want to do an interactive session, so start up the curses screen and
|
||||
# pass it the function that handles commands
|
||||
colors.init_colors()
|
||||
self.screen = screen.Screen(stdscr, self.do_command, self.tab_completer, self.encoding)
|
||||
self.statusbars = StatusBars()
|
||||
from modes.connectionmanager import ConnectionManager
|
||||
self.screen = ConnectionManager(stdscr, self.encoding)
|
||||
self.eventlog = EventLog()
|
||||
|
||||
self.screen.topbar = "{!status!}Deluge " + deluge.common.get_version() + " Console"
|
||||
@ -276,12 +225,12 @@ Please use commands from the command line, eg:\n
|
||||
# Start the twisted mainloop
|
||||
reactor.run()
|
||||
|
||||
|
||||
def start(self):
|
||||
# This gets fired once we have received the torrents list from the core
|
||||
self.started_deferred = defer.Deferred()
|
||||
|
||||
# Maintain a list of (torrent_id, name) for use in tab completion
|
||||
self.torrents = []
|
||||
if not self.interactive:
|
||||
self.started_deferred = defer.Deferred()
|
||||
def on_session_state(result):
|
||||
def on_torrents_status(torrents):
|
||||
for torrent_id, status in torrents.items():
|
||||
@ -291,6 +240,186 @@ Please use commands from the command line, eg:\n
|
||||
client.core.get_torrents_status({"id": result}, ["name"]).addCallback(on_torrents_status)
|
||||
client.core.get_session_state().addCallback(on_session_state)
|
||||
|
||||
# Register some event handlers to keep the torrent list up-to-date
|
||||
client.register_event_handler("TorrentAddedEvent", self.on_torrent_added_event)
|
||||
client.register_event_handler("TorrentRemovedEvent", self.on_torrent_removed_event)
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
def set_batch_write(self, batch):
|
||||
"""
|
||||
When this is set the screen is not refreshed after a `:meth:write` until
|
||||
this is set to False.
|
||||
|
||||
:param batch: set True to prevent screen refreshes after a `:meth:write`
|
||||
:type batch: bool
|
||||
|
||||
"""
|
||||
self.batch_write = batch
|
||||
if not batch and self.interactive:
|
||||
self.screen.refresh()
|
||||
|
||||
def write(self, line):
|
||||
"""
|
||||
Writes a line out depending on if we're in interactive mode or not.
|
||||
|
||||
:param line: str, the line to print
|
||||
|
||||
"""
|
||||
if self.interactive:
|
||||
self.screen.add_line(line, not self.batch_write)
|
||||
else:
|
||||
print(colors.strip_colors(line))
|
||||
|
||||
def do_command(self, cmd):
|
||||
"""
|
||||
Processes a command.
|
||||
|
||||
:param cmd: str, the command string
|
||||
|
||||
"""
|
||||
if not cmd:
|
||||
return
|
||||
cmd, _, line = cmd.partition(' ')
|
||||
try:
|
||||
parser = self._commands[cmd].create_parser()
|
||||
except KeyError:
|
||||
self.write("{!error!}Unknown command: %s" % cmd)
|
||||
return
|
||||
args = self._commands[cmd].split(line)
|
||||
|
||||
# Do a little hack here to print 'command --help' properly
|
||||
parser._print_help = parser.print_help
|
||||
def print_help(f=None):
|
||||
if self.interactive:
|
||||
self.write(parser.format_help())
|
||||
else:
|
||||
parser._print_help(f)
|
||||
parser.print_help = print_help
|
||||
|
||||
# Only these commands can be run when not connected to a daemon
|
||||
not_connected_cmds = ["help", "connect", "quit"]
|
||||
aliases = []
|
||||
for c in not_connected_cmds:
|
||||
aliases.extend(self._commands[c].aliases)
|
||||
not_connected_cmds.extend(aliases)
|
||||
|
||||
if not client.connected() and cmd not in not_connected_cmds:
|
||||
self.write("{!error!}Not connected to a daemon, please use the connect command first.")
|
||||
return
|
||||
|
||||
try:
|
||||
options, args = parser.parse_args(args)
|
||||
except Exception, e:
|
||||
self.write("{!error!}Error parsing options: %s" % e)
|
||||
return
|
||||
|
||||
if not getattr(options, '_exit', False):
|
||||
try:
|
||||
ret = self._commands[cmd].handle(*args, **options.__dict__)
|
||||
except Exception, e:
|
||||
self.write("{!error!}" + str(e))
|
||||
log.exception(e)
|
||||
import traceback
|
||||
self.write("%s" % traceback.format_exc())
|
||||
return defer.succeed(True)
|
||||
else:
|
||||
return ret
|
||||
|
||||
def tab_completer(self, line, cursor, second_hit):
|
||||
"""
|
||||
Called when the user hits 'tab' and will autocomplete or show options.
|
||||
If a command is already supplied in the line, this function will call the
|
||||
complete method of the command.
|
||||
|
||||
:param line: str, the current input string
|
||||
:param cursor: int, the cursor position in the line
|
||||
:param second_hit: bool, if this is the second time in a row the tab key
|
||||
has been pressed
|
||||
|
||||
:returns: 2-tuple (string, cursor position)
|
||||
|
||||
"""
|
||||
# First check to see if there is no space, this will mean that it's a
|
||||
# command that needs to be completed.
|
||||
if " " not in line:
|
||||
possible_matches = []
|
||||
# Iterate through the commands looking for ones that startwith the
|
||||
# line.
|
||||
for cmd in self._commands:
|
||||
if cmd.startswith(line):
|
||||
possible_matches.append(cmd + " ")
|
||||
|
||||
line_prefix = ""
|
||||
else:
|
||||
cmd = line.split(" ")[0]
|
||||
if cmd in self._commands:
|
||||
# Call the command's complete method to get 'er done
|
||||
possible_matches = self._commands[cmd].complete(line.split(" ")[-1])
|
||||
line_prefix = " ".join(line.split(" ")[:-1]) + " "
|
||||
else:
|
||||
# This is a bogus command
|
||||
return (line, cursor)
|
||||
|
||||
# No matches, so just return what we got passed
|
||||
if len(possible_matches) == 0:
|
||||
return (line, cursor)
|
||||
# If we only have 1 possible match, then just modify the line and
|
||||
# return it, else we need to print out the matches without modifying
|
||||
# the line.
|
||||
elif len(possible_matches) == 1:
|
||||
new_line = line_prefix + possible_matches[0]
|
||||
return (new_line, len(new_line))
|
||||
else:
|
||||
if second_hit:
|
||||
# Only print these out if it's a second_hit
|
||||
self.write(" ")
|
||||
for match in possible_matches:
|
||||
self.write(match)
|
||||
else:
|
||||
p = " ".join(line.split(" ")[:-1])
|
||||
new_line = " ".join([p, os.path.commonprefix(possible_matches)])
|
||||
if len(new_line) > len(line):
|
||||
line = new_line
|
||||
cursor = len(line)
|
||||
return (line, cursor)
|
||||
|
||||
def tab_complete_torrent(self, line):
|
||||
"""
|
||||
Completes torrent_ids or names.
|
||||
|
||||
:param line: str, the string to complete
|
||||
|
||||
:returns: list of matches
|
||||
|
||||
"""
|
||||
|
||||
possible_matches = []
|
||||
|
||||
# Find all possible matches
|
||||
for torrent_id, torrent_name in self.torrents:
|
||||
if torrent_id.startswith(line):
|
||||
possible_matches.append(torrent_id + " ")
|
||||
if torrent_name.startswith(line):
|
||||
possible_matches.append(torrent_name + " ")
|
||||
|
||||
return possible_matches
|
||||
|
||||
def get_torrent_name(self, torrent_id):
|
||||
"""
|
||||
Gets a torrent name from the torrents list.
|
||||
|
||||
:param torrent_id: str, the torrent_id
|
||||
|
||||
:returns: the name of the torrent or None
|
||||
"""
|
||||
|
||||
for tid, name in self.torrents:
|
||||
if torrent_id == tid:
|
||||
return name
|
||||
|
||||
return None
|
||||
|
||||
def match_torrent(self, string):
|
||||
"""
|
||||
@ -310,33 +439,15 @@ Please use commands from the command line, eg:\n
|
||||
|
||||
return ret
|
||||
|
||||
def on_torrent_added_event(self, event):
|
||||
def on_torrent_status(status):
|
||||
self.torrents.append((event.torrent_id, status["name"]))
|
||||
client.core.get_torrent_status(event.torrent_id, ["name"]).addCallback(on_torrent_status)
|
||||
|
||||
def get_torrent_name(self, torrent_id):
|
||||
if self.interactive and hasattr(self.screen,"get_torrent_name"):
|
||||
return self.screen.get_torrent_name(torrent_id)
|
||||
|
||||
for tid, name in self.torrents:
|
||||
if torrent_id == tid:
|
||||
return name
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def set_batch_write(self, batch):
|
||||
# only kept for legacy reasons, don't actually do anything
|
||||
pass
|
||||
|
||||
def set_mode(self, mode):
|
||||
reactor.removeReader(self.screen)
|
||||
self.screen = mode
|
||||
self.statusbars.screen = self.screen
|
||||
reactor.addReader(self.screen)
|
||||
def on_torrent_removed_event(self, event):
|
||||
for index, (tid, name) in enumerate(self.torrents):
|
||||
if event.torrent_id == tid:
|
||||
del self.torrents[index]
|
||||
|
||||
def on_client_disconnect(self):
|
||||
component.stop()
|
||||
|
||||
def write(self, s):
|
||||
if self.interactive:
|
||||
self.events.append(s)
|
||||
else:
|
||||
print colors.strip_colors(s)
|
||||
|
@ -45,8 +45,8 @@ class CoreConfig(component.Component):
|
||||
log.debug("CoreConfig init..")
|
||||
component.Component.__init__(self, "CoreConfig")
|
||||
self.config = {}
|
||||
def on_configvaluechanged_event(event):
|
||||
self.config[event.key] = event.value
|
||||
def on_configvaluechanged_event(key, value):
|
||||
self.config[key] = value
|
||||
client.register_event_handler("ConfigValueChangedEvent", on_configvaluechanged_event)
|
||||
|
||||
def start(self):
|
||||
|
@ -627,34 +627,34 @@ class FilesTab(Tab):
|
||||
def _on_filename_editing_canceled(self, renderer):
|
||||
self._editing_index = None
|
||||
|
||||
def _on_torrentfilerenamed_event(self, event):
|
||||
log.debug("index: %s name: %s", event.index, event.filename)
|
||||
def _on_torrentfilerenamed_event(self, torrent_id, index, name):
|
||||
log.debug("index: %s name: %s", index, name)
|
||||
|
||||
if event.torrent_id not in self.files_list:
|
||||
if torrent_id not in self.files_list:
|
||||
return
|
||||
|
||||
old_name = self.files_list[event.torrent_id][event.index]["path"]
|
||||
self.files_list[event.torrent_id][event.index]["path"] = event.filename
|
||||
old_name = self.files_list[torrent_id][index]["path"]
|
||||
self.files_list[torrent_id][index]["path"] = name
|
||||
|
||||
# We need to update the filename displayed if we're currently viewing
|
||||
# this torrents files.
|
||||
if event.torrent_id == self.torrent_id:
|
||||
if torrent_id == self.torrent_id:
|
||||
old_name_len = len(old_name.split("/"))
|
||||
name_len = len(event.filename.split("/"))
|
||||
name_len = len(name.split("/"))
|
||||
if old_name_len != name_len:
|
||||
# The parent path list changes depending on which way the file
|
||||
# is moving in the tree
|
||||
if old_name_len < name_len:
|
||||
parent_path = [o for o in old_name.split("/")[:-1]]
|
||||
else:
|
||||
parent_path = [o for o in event.filename.split("/")[:-1]]
|
||||
parent_path = [o for o in name.split("/")[:-1]]
|
||||
# Find the iter to the parent folder we need to add a new folder
|
||||
# to.
|
||||
def find_parent(model, path, itr, user_data):
|
||||
if model[itr][0] == parent_path[0] + "/":
|
||||
if len(parent_path) == 1:
|
||||
# This is the parent iter
|
||||
to_create = event.filename.split("/")[len(old_name.split("/")[:-1]):-1]
|
||||
to_create = name.split("/")[len(old_name.split("/")[:-1]):-1]
|
||||
parent_iter = itr
|
||||
|
||||
for tc in to_create:
|
||||
@ -673,8 +673,8 @@ class FilesTab(Tab):
|
||||
|
||||
# Find the iter for the file that needs to be moved
|
||||
def get_file_iter(model, path, itr, user_data):
|
||||
if model[itr][5] == event.index:
|
||||
model[itr][0] = event.filename.split("/")[-1]
|
||||
if model[itr][5] == index:
|
||||
model[itr][0] = name.split("/")[-1]
|
||||
t = self.treestore.append(
|
||||
parent_iter,
|
||||
self.treestore.get(itr,
|
||||
@ -693,7 +693,7 @@ class FilesTab(Tab):
|
||||
if parent_path:
|
||||
self.treestore.foreach(find_parent, None)
|
||||
else:
|
||||
new_folders = event.filename.split("/")[:-1]
|
||||
new_folders = name.split("/")[:-1]
|
||||
parent_iter = None
|
||||
for f in new_folders:
|
||||
parent_iter = self.treestore.append(parent_iter,
|
||||
@ -707,8 +707,8 @@ class FilesTab(Tab):
|
||||
else:
|
||||
# This is just changing a filename without any folder changes
|
||||
def set_file_name(model, path, itr, user_data):
|
||||
if model[itr][5] == event.index:
|
||||
model[itr][0] = os.path.split(event.filename)[-1]
|
||||
if model[itr][5] == index:
|
||||
model[itr][0] = os.path.split(name)[-1]
|
||||
return True
|
||||
self.treestore.foreach(set_file_name, None)
|
||||
|
||||
@ -754,40 +754,40 @@ class FilesTab(Tab):
|
||||
self.treestore.remove(itr)
|
||||
itr = parent
|
||||
|
||||
def _on_torrentfolderrenamed_event(self, event):
|
||||
def _on_torrentfolderrenamed_event(self, torrent_id, old_folder, new_folder):
|
||||
log.debug("on_torrent_folder_renamed_signal")
|
||||
log.debug("old_folder: %s new_folder: %s", event.old, event.new)
|
||||
log.debug("old_folder: %s new_folder: %s", old_folder, new_folder)
|
||||
|
||||
if event.torrent_id not in self.files_list:
|
||||
if torrent_id not in self.files_list:
|
||||
return
|
||||
|
||||
if event.old[-1] != "/":
|
||||
event.old += "/"
|
||||
if event.new[-1] != "/":
|
||||
event.new += "/"
|
||||
if old_folder[-1] != "/":
|
||||
old_folder += "/"
|
||||
if new_folder[-1] != "/":
|
||||
new_folder += "/"
|
||||
|
||||
for fd in self.files_list[event.torrent_id]:
|
||||
if fd["path"].startswith(event.old):
|
||||
fd["path"] = fd["path"].replace(event.old, event.new, 1)
|
||||
for fd in self.files_list[torrent_id]:
|
||||
if fd["path"].startswith(old_folder):
|
||||
fd["path"] = fd["path"].replace(old_folder, new_folder, 1)
|
||||
|
||||
if event.torrent_id == self.torrent_id:
|
||||
if torrent_id == self.torrent_id:
|
||||
|
||||
old_split = event.old.split("/")
|
||||
old_split = old_folder.split("/")
|
||||
try:
|
||||
old_split.remove("")
|
||||
except:
|
||||
pass
|
||||
|
||||
new_split = event.new.split("/")
|
||||
new_split = new_folder.split("/")
|
||||
try:
|
||||
new_split.remove("")
|
||||
except:
|
||||
pass
|
||||
|
||||
old_folder_iter = self.get_iter_at_path(event.old)
|
||||
old_folder_iter = self.get_iter_at_path(old_folder)
|
||||
old_folder_iter_parent = self.treestore.iter_parent(old_folder_iter)
|
||||
|
||||
new_folder_iter = self.get_iter_at_path(event.new)
|
||||
new_folder_iter = self.get_iter_at_path(new_folder)
|
||||
if len(new_split) == len(old_split):
|
||||
# These are at the same tree depth, so it's a simple rename
|
||||
self.treestore[old_folder_iter][0] = new_split[-1] + "/"
|
||||
@ -807,9 +807,9 @@ class FilesTab(Tab):
|
||||
# and if so, we delete it
|
||||
self.remove_childless_folders(old_folder_iter_parent)
|
||||
|
||||
def _on_torrentremoved_event(self, event):
|
||||
if event.torrent_id in self.files_list:
|
||||
del self.files_list[event.torrent_id]
|
||||
def _on_torrentremoved_event(self, torrent_id):
|
||||
if torrent_id in self.files_list:
|
||||
del self.files_list[torrent_id]
|
||||
|
||||
def _on_drag_data_get_data(self, treeview, context, selection, target_id, etime):
|
||||
paths = self.listview.get_selection().get_selected_rows()[1]
|
||||
|
@ -247,11 +247,11 @@ class MainWindow(component.Component):
|
||||
else:
|
||||
self.window.set_title("Deluge")
|
||||
|
||||
def on_newversionavailable_event(self, event):
|
||||
def on_newversionavailable_event(self, new_version):
|
||||
if self.config["show_new_releases"]:
|
||||
from deluge.ui.gtkui.new_release_dialog import NewReleaseDialog
|
||||
reactor.callLater(5.0, NewReleaseDialog().show, event.new_release)
|
||||
reactor.callLater(5.0, NewReleaseDialog().show, new_version)
|
||||
|
||||
def on_torrentfinished_event(self, event):
|
||||
def on_torrentfinished_event(self, torrent_id):
|
||||
from deluge.ui.gtkui.notification import Notification
|
||||
Notification().notify(event.torrent_id)
|
||||
Notification().notify(torrent_id)
|
||||
|
@ -230,11 +230,11 @@ class MenuBar(component.Component):
|
||||
return sep
|
||||
|
||||
### Callbacks ###
|
||||
def on_torrentstatechanged_event(self, event):
|
||||
if event.state == "Paused":
|
||||
def on_torrentstatechanged_event(self, torrent_id, state):
|
||||
if state == "Paused":
|
||||
self.update_menu()
|
||||
|
||||
def on_torrentresumed_event(self, event):
|
||||
def on_torrentresumed_event(self, torrent_id):
|
||||
self.update_menu()
|
||||
|
||||
def on_sessionpaused_event(self):
|
||||
|
@ -91,11 +91,11 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase,
|
||||
for plugin in enabled_plugins:
|
||||
self.enable_plugin(plugin)
|
||||
|
||||
def _on_plugin_enabled_event(self, event):
|
||||
self.enable_plugin(event.plugin_name)
|
||||
def _on_plugin_enabled_event(self, name):
|
||||
self.enable_plugin(name)
|
||||
|
||||
def _on_plugin_disabled_event(self, event):
|
||||
self.disable_plugin(event.plugin_name)
|
||||
def _on_plugin_disabled_event(self, name):
|
||||
self.disable_plugin(name)
|
||||
|
||||
## Hook functions
|
||||
def run_on_show_prefs(self):
|
||||
|
@ -288,14 +288,14 @@ class StatusBar(component.Component):
|
||||
client.core.get_session_status(keys).addCallback(self._on_get_session_status)
|
||||
client.core.get_free_space().addCallback(self._on_get_free_space)
|
||||
|
||||
def on_configvaluechanged_event(self, event):
|
||||
def on_configvaluechanged_event(self, key, value):
|
||||
"""
|
||||
This is called when we receive a ConfigValueChangedEvent from
|
||||
the core.
|
||||
"""
|
||||
|
||||
if event.key in self.config_value_changed_dict.keys():
|
||||
self.config_value_changed_dict[event.key](event.value)
|
||||
if key in self.config_value_changed_dict.keys():
|
||||
self.config_value_changed_dict[key](value)
|
||||
|
||||
def _on_max_connections_global(self, max_connections):
|
||||
self.max_connections = max_connections
|
||||
|
@ -210,12 +210,12 @@ class SystemTray(component.Component):
|
||||
"payload_upload_rate",
|
||||
"payload_download_rate"]).addCallback(self._on_get_session_status)
|
||||
|
||||
def config_value_changed(self, event):
|
||||
def config_value_changed(self, key, value):
|
||||
"""This is called when we received a config_value_changed signal from
|
||||
the core."""
|
||||
|
||||
if event.key in self.config_value_changed_dict.keys():
|
||||
self.config_value_changed_dict[event.key](event.value)
|
||||
if key in self.config_value_changed_dict.keys():
|
||||
self.config_value_changed_dict[key](value)
|
||||
|
||||
def _on_max_download_speed(self, max_download_speed):
|
||||
if self.max_download_speed != max_download_speed:
|
||||
|
@ -521,31 +521,31 @@ class TorrentView(listview.ListView, component.Component):
|
||||
def on_drag_drop(self, widget, drag_context, x, y, timestamp):
|
||||
widget.stop_emission("drag-drop")
|
||||
|
||||
def on_torrentadded_event(self, event):
|
||||
self.add_row(event.torrent_id)
|
||||
self.mark_dirty(event.torrent_id)
|
||||
def on_torrentadded_event(self, torrent_id, from_state):
|
||||
self.add_row(torrent_id)
|
||||
self.mark_dirty(torrent_id)
|
||||
|
||||
def on_torrentremoved_event(self, event):
|
||||
self.remove_row(event.torrent_id)
|
||||
def on_torrentremoved_event(self, torrent_id):
|
||||
self.remove_row(torrent_id)
|
||||
|
||||
def on_torrentstatechanged_event(self, event):
|
||||
def on_torrentstatechanged_event(self, torrent_id, state):
|
||||
# Update the torrents state
|
||||
for row in self.liststore:
|
||||
if not event.torrent_id == row[self.columns["torrent_id"].column_indices[0]]:
|
||||
if not torrent_id == row[self.columns["torrent_id"].column_indices[0]]:
|
||||
continue
|
||||
row[self.get_column_index(_("Progress"))[1]] = event.state
|
||||
row[self.get_column_index(_("Progress"))[1]] = state
|
||||
|
||||
self.mark_dirty(event.torrent_id)
|
||||
self.mark_dirty(torrent_id)
|
||||
|
||||
def on_sessionpaused_event(self, event):
|
||||
def on_sessionpaused_event(self):
|
||||
self.mark_dirty()
|
||||
self.update()
|
||||
|
||||
def on_sessionresumed_event(self, event):
|
||||
def on_sessionresumed_event(self):
|
||||
self.mark_dirty()
|
||||
self.update()
|
||||
|
||||
def on_torrentqueuechanged_event(self, event):
|
||||
def on_torrentqueuechanged_event(self):
|
||||
self.mark_dirty()
|
||||
self.update()
|
||||
|
||||
|
@ -236,21 +236,21 @@ class SessionProxy(component.Component):
|
||||
d = client.core.get_torrents_status(filter_dict, keys, True)
|
||||
return d.addCallback(on_status, None, keys)
|
||||
|
||||
def on_torrent_state_changed(self, event):
|
||||
if event.torrent_id in self.torrents:
|
||||
self.torrents[event.torrent_id][1]["state"] = event.state
|
||||
self.cache_times[event.torrent_id]["state"] = time.time()
|
||||
def on_torrent_state_changed(self, torrent_id, state):
|
||||
if torrent_id in self.torrents:
|
||||
self.torrents[torrent_id][1]["state"] = state
|
||||
self.cache_times[torrent_id]["state"] = time.time()
|
||||
|
||||
def on_torrent_added(self, event):
|
||||
self.torrents[event.torrent_id] = [time.time() - self.cache_time - 1, {}]
|
||||
self.cache_times[event.torrent_id] = {}
|
||||
def on_torrent_added(self, torrent_id, from_state):
|
||||
self.torrents[torrent_id] = [time.time() - self.cache_time - 1, {}]
|
||||
self.cache_times[torrent_id] = {}
|
||||
def on_status(status):
|
||||
self.torrents[event.torrent_id][1].update(status)
|
||||
self.torrents[torrent_id][1].update(status)
|
||||
t = time.time()
|
||||
for key in status:
|
||||
self.cache_times[event.torrent_id][key] = t
|
||||
client.core.get_torrent_status(event.torrent_id, []).addCallback(on_status)
|
||||
self.cache_times[torrent_id][key] = t
|
||||
client.core.get_torrent_status(torrent_id, []).addCallback(on_status)
|
||||
|
||||
def on_torrent_removed(self, event):
|
||||
del self.torrents[event.torrent_id]
|
||||
del self.cache_times[event.torrent_id]
|
||||
def on_torrent_removed(self, torrent_id):
|
||||
del self.torrents[torrent_id]
|
||||
del self.cache_times[torrent_id]
|
||||
|
@ -72,11 +72,11 @@ class PluginManager(PluginManagerBase, component.Component):
|
||||
for plugin in plugins:
|
||||
self.enable_plugin(plugin)
|
||||
|
||||
def _on_plugin_enabled_event(self, event):
|
||||
self.enable_plugin(event.plugin_name)
|
||||
def _on_plugin_enabled_event(self, name):
|
||||
self.enable_plugin(name)
|
||||
|
||||
def _on_plugin_disabled_event(self, event):
|
||||
self.disable_plugin(event.plugin_name)
|
||||
def _on_plugin_disabled_event(self, name):
|
||||
self.disable_plugin(name)
|
||||
|
||||
def disable_plugin(self, name):
|
||||
# Get the plugin instance
|
||||
|
Loading…
x
Reference in New Issue
Block a user