mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-02 22:48:40 +00:00
Fix up the console ui so that command-line options work again.. Also,
use the new UI class for the 'deluge-console' script.
This commit is contained in:
parent
56735452a8
commit
c4a247018b
14 changed files with 141 additions and 54 deletions
|
@ -22,3 +22,4 @@
|
||||||
# Boston, MA 02110-1301, USA.
|
# Boston, MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
UI_PATH = __path__[0]
|
UI_PATH = __path__[0]
|
||||||
|
from main import start
|
||||||
|
|
|
@ -93,6 +93,17 @@ def replace_tabs(line):
|
||||||
line = line.replace("\t", " " * tab_length, 1)
|
line = line.replace("\t", " " * tab_length, 1)
|
||||||
return line
|
return line
|
||||||
|
|
||||||
|
def strip_colors(line):
|
||||||
|
"""
|
||||||
|
Returns a string with the color formatting removed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Remove all the color tags
|
||||||
|
while line.find("{!") != -1:
|
||||||
|
line = line[:line.find("{!")] + line[line.find("!}") + 2:]
|
||||||
|
|
||||||
|
return line
|
||||||
|
|
||||||
def get_line_length(line):
|
def get_line_length(line):
|
||||||
"""
|
"""
|
||||||
Returns the string length without the color formatting.
|
Returns the string length without the color formatting.
|
||||||
|
@ -102,8 +113,7 @@ def get_line_length(line):
|
||||||
raise BadColorString("Number of {! is not equal to number of !}")
|
raise BadColorString("Number of {! is not equal to number of !}")
|
||||||
|
|
||||||
# Remove all the color tags
|
# Remove all the color tags
|
||||||
while line.find("{!") != -1:
|
line = strip_colors(line)
|
||||||
line = line[:line.find("{!")] + line[line.find("!}") + 2:]
|
|
||||||
|
|
||||||
# Replace tabs with the appropriate amount of spaces
|
# Replace tabs with the appropriate amount of spaces
|
||||||
line = replace_tabs(line)
|
line = replace_tabs(line)
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
# 51 Franklin Street, Fifth Floor
|
# 51 Franklin Street, Fifth Floor
|
||||||
# Boston, MA 02110-1301, USA.
|
# Boston, MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
|
from twisted.internet import defer
|
||||||
|
|
||||||
from deluge.ui.console.main import BaseCommand
|
from deluge.ui.console.main import BaseCommand
|
||||||
import deluge.ui.console.colors as colors
|
import deluge.ui.console.colors as colors
|
||||||
from deluge.ui.client import client
|
from deluge.ui.client import client
|
||||||
|
@ -47,6 +49,8 @@ class Command(BaseCommand):
|
||||||
if options["path"]:
|
if options["path"]:
|
||||||
t_options["download_location"] = options["path"]
|
t_options["download_location"] = options["path"]
|
||||||
|
|
||||||
|
# Keep a list of deferreds to make a DeferredList
|
||||||
|
deferreds = []
|
||||||
for arg in args:
|
for arg in args:
|
||||||
if not os.path.isfile(arg):
|
if not os.path.isfile(arg):
|
||||||
self.console.write("{!error!}This is a directory!")
|
self.console.write("{!error!}This is a directory!")
|
||||||
|
@ -60,7 +64,9 @@ class Command(BaseCommand):
|
||||||
def on_fail(result):
|
def on_fail(result):
|
||||||
self.console.write("{!error!}Torrent was not added! %s" % result)
|
self.console.write("{!error!}Torrent was not added! %s" % result)
|
||||||
|
|
||||||
client.core.add_torrent_file(filename, filedump, t_options).addCallback(on_success).addErrback(on_fail)
|
deferreds.append(client.core.add_torrent_file(filename, filedump, t_options).addCallback(on_success).addErrback(on_fail))
|
||||||
|
|
||||||
|
return defer.DeferredList(deferreds)
|
||||||
|
|
||||||
def complete(self, line):
|
def complete(self, line):
|
||||||
line = os.path.abspath(os.path.expanduser(line))
|
line = os.path.abspath(os.path.expanduser(line))
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
# Boston, MA 02110-1301, USA.
|
# Boston, MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from twisted.internet import defer
|
||||||
|
|
||||||
from deluge.ui.console.main import BaseCommand
|
from deluge.ui.console.main import BaseCommand
|
||||||
import deluge.ui.console.colors as colors
|
import deluge.ui.console.colors as colors
|
||||||
from deluge.ui.client import client
|
from deluge.ui.client import client
|
||||||
|
@ -63,7 +65,7 @@ def simple_eval(source):
|
||||||
taken from http://effbot.org/zone/simple-iterator-parser.htm"""
|
taken from http://effbot.org/zone/simple-iterator-parser.htm"""
|
||||||
src = cStringIO.StringIO(source).readline
|
src = cStringIO.StringIO(source).readline
|
||||||
src = tokenize.generate_tokens(src)
|
src = tokenize.generate_tokens(src)
|
||||||
src = (token for token in src if token[0] is not tokenize.NL)
|
src = (token for token in src if token[0] is not tokenize.NL37)
|
||||||
res = atom(src.next, src.next())
|
res = atom(src.next, src.next())
|
||||||
if src.next()[0] is not tokenize.ENDMARKER:
|
if src.next()[0] is not tokenize.ENDMARKER:
|
||||||
raise SyntaxError("bogus data after expression")
|
raise SyntaxError("bogus data after expression")
|
||||||
|
@ -83,38 +85,47 @@ class Command(BaseCommand):
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
self.console = component.get("ConsoleUI")
|
self.console = component.get("ConsoleUI")
|
||||||
if options['set']:
|
if options['set']:
|
||||||
self._set_config(*args, **options)
|
return self._set_config(*args, **options)
|
||||||
else:
|
else:
|
||||||
self._get_config(*args, **options)
|
return self._get_config(*args, **options)
|
||||||
|
|
||||||
def _get_config(self, *args, **options):
|
def _get_config(self, *args, **options):
|
||||||
config = component.get("CoreConfig")
|
deferred = defer.Deferred()
|
||||||
|
def on_get_config(result):
|
||||||
|
config = component.get("CoreConfig")
|
||||||
|
keys = config.keys()
|
||||||
|
keys.sort()
|
||||||
|
s = ""
|
||||||
|
for key in keys:
|
||||||
|
if args and key not in args:
|
||||||
|
continue
|
||||||
|
color = "{!white,black,bold!}"
|
||||||
|
value = config[key]
|
||||||
|
if type(value) in colors.type_color:
|
||||||
|
color = colors.type_color[type(value)]
|
||||||
|
|
||||||
keys = config.keys()
|
# We need to format dicts for printing
|
||||||
keys.sort()
|
if isinstance(value, dict):
|
||||||
s = ""
|
import pprint
|
||||||
for key in keys:
|
value = pprint.pformat(value, 2, 80)
|
||||||
if args and key not in args:
|
new_value = []
|
||||||
continue
|
for line in value.splitlines():
|
||||||
color = "{!white,black,bold!}"
|
new_value.append("%s%s" % (color, line))
|
||||||
value = config[key]
|
value = "\n".join(new_value)
|
||||||
if type(value) in colors.type_color:
|
|
||||||
color = colors.type_color[type(value)]
|
|
||||||
|
|
||||||
# We need to format dicts for printing
|
s += " %s: %s%s\n" % (key, color, value)
|
||||||
if isinstance(value, dict):
|
|
||||||
import pprint
|
|
||||||
value = pprint.pformat(value, 2, 80)
|
|
||||||
new_value = []
|
|
||||||
for line in value.splitlines():
|
|
||||||
new_value.append("%s%s" % (color, line))
|
|
||||||
value = "\n".join(new_value)
|
|
||||||
|
|
||||||
s += " %s: %s%s\n" % (key, color, value)
|
self.console.write(s)
|
||||||
|
deferred.callback(True)
|
||||||
|
return config
|
||||||
|
|
||||||
self.console.write(s)
|
# We need to ensure the config dict has been received first
|
||||||
|
component.get("CoreConfig").start_defer.addCallback(on_get_config)
|
||||||
|
|
||||||
|
return deferred
|
||||||
|
|
||||||
def _set_config(self, *args, **options):
|
def _set_config(self, *args, **options):
|
||||||
|
deferred = defer.Deferred()
|
||||||
config = component.get("CoreConfig")
|
config = component.get("CoreConfig")
|
||||||
key = args[0]
|
key = args[0]
|
||||||
if key not in config.keys():
|
if key not in config.keys():
|
||||||
|
@ -132,7 +143,10 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
def on_set_config(result):
|
def on_set_config(result):
|
||||||
self.console.write("{!success!}Configuration value successfully updated.")
|
self.console.write("{!success!}Configuration value successfully updated.")
|
||||||
|
deferred.callback(True)
|
||||||
|
|
||||||
client.core.set_config({key: val}).addCallback(on_set_config)
|
client.core.set_config({key: val}).addCallback(on_set_config)
|
||||||
|
return deferred
|
||||||
|
|
||||||
def complete(self, text):
|
def complete(self, text):
|
||||||
return [ k for k in component.get("CoreConfig").keys() if k.startswith(text) ]
|
return [ k for k in component.get("CoreConfig").keys() if k.startswith(text) ]
|
||||||
|
|
|
@ -42,3 +42,4 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
d.addCallback(on_connect)
|
d.addCallback(on_connect)
|
||||||
d.addErrback(on_connect_fail)
|
d.addErrback(on_connect_fail)
|
||||||
|
return d
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
# 51 Franklin Street, Fifth Floor
|
# 51 Franklin Street, Fifth Floor
|
||||||
# Boston, MA 02110-1301, USA.
|
# Boston, MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from twisted.internet import defer
|
||||||
|
|
||||||
from deluge.ui.console.main import BaseCommand
|
from deluge.ui.console.main import BaseCommand
|
||||||
from deluge.ui.client import client
|
from deluge.ui.client import client
|
||||||
import deluge.ui.console.colors as colors
|
import deluge.ui.console.colors as colors
|
||||||
|
@ -39,5 +42,7 @@ class Command(BaseCommand):
|
||||||
else:
|
else:
|
||||||
component.get("ConsoleUI").write("{!error!}%s" % usage)
|
component.get("ConsoleUI").write("{!error!}%s" % usage)
|
||||||
|
|
||||||
|
return defer.succeed(True)
|
||||||
|
|
||||||
def complete(self, text):
|
def complete(self, text):
|
||||||
return [x for x in ['on', 'off'] if x.startswith(text)]
|
return [x for x in ['on', 'off'] if x.startswith(text)]
|
||||||
|
|
|
@ -38,4 +38,4 @@ class Command(BaseCommand):
|
||||||
def on_shutdown_fail(reason):
|
def on_shutdown_fail(reason):
|
||||||
self.write("{!error!}Unable to shutdown daemon: %s" % reason)
|
self.write("{!error!}Unable to shutdown daemon: %s" % reason)
|
||||||
|
|
||||||
client.daemon.shutdown().addCallback(on_shutdown).addErrback(on_shutdown_fail)
|
return client.daemon.shutdown().addCallback(on_shutdown).addErrback(on_shutdown_fail)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#
|
|
||||||
# help.py
|
# help.py
|
||||||
#
|
#
|
||||||
# Copyright (C) 2008-2009 Ido Abramovich <ido.deluge@gmail.com>
|
# Copyright (C) 2008-2009 Ido Abramovich <ido.deluge@gmail.com>
|
||||||
|
@ -22,6 +21,9 @@
|
||||||
# 51 Franklin Street, Fifth Floor
|
# 51 Franklin Street, Fifth Floor
|
||||||
# Boston, MA 02110-1301, USA.
|
# Boston, MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from twisted.internet import defer
|
||||||
|
|
||||||
from deluge.ui.console.main import BaseCommand
|
from deluge.ui.console.main import BaseCommand
|
||||||
import deluge.ui.console.colors as colors
|
import deluge.ui.console.colors as colors
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
|
@ -34,15 +36,16 @@ class Command(BaseCommand):
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
self.console = component.get("ConsoleUI")
|
self.console = component.get("ConsoleUI")
|
||||||
self._commands = self.console._commands
|
self._commands = self.console._commands
|
||||||
|
deferred = defer.succeed(True)
|
||||||
if args:
|
if args:
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
self.console.write(usage)
|
self.console.write(usage)
|
||||||
return
|
return deferred
|
||||||
try:
|
try:
|
||||||
cmd = self._commands[args[0]]
|
cmd = self._commands[args[0]]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.console.write("{!error!}Unknown command %r" % args[0])
|
self.console.write("{!error!}Unknown command %r" % args[0])
|
||||||
return
|
return deferred
|
||||||
try:
|
try:
|
||||||
parser = cmd.create_parser()
|
parser = cmd.create_parser()
|
||||||
self.console.write(parser.format_help())
|
self.console.write(parser.format_help())
|
||||||
|
@ -55,5 +58,7 @@ class Command(BaseCommand):
|
||||||
self.console.write(" ")
|
self.console.write(" ")
|
||||||
self.console.write('For help on a specific command, use "<command> --help"')
|
self.console.write('For help on a specific command, use "<command> --help"')
|
||||||
|
|
||||||
|
return deferred
|
||||||
|
|
||||||
def complete(self, line):
|
def complete(self, line):
|
||||||
return [x for x in component.get("ConsoleUI")._commands if x.startswith(line)]
|
return [x for x in component.get("ConsoleUI")._commands if x.startswith(line)]
|
||||||
|
|
|
@ -110,6 +110,7 @@ class Command(BaseCommand):
|
||||||
d = client.core.get_torrents_status({"id": torrent_ids}, status_keys)
|
d = client.core.get_torrents_status({"id": torrent_ids}, status_keys)
|
||||||
d.addCallback(on_torrents_status)
|
d.addCallback(on_torrents_status)
|
||||||
d.addErrback(on_torrents_status_fail)
|
d.addErrback(on_torrents_status_fail)
|
||||||
|
return d
|
||||||
|
|
||||||
def show_info(self, torrent_id, status, verbose=False):
|
def show_info(self, torrent_id, status, verbose=False):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -45,7 +45,7 @@ class Command(BaseCommand):
|
||||||
torrent_ids.extend(self.console.match_torrent(arg))
|
torrent_ids.extend(self.console.match_torrent(arg))
|
||||||
|
|
||||||
if torrent_ids:
|
if torrent_ids:
|
||||||
client.core.pause_torrent(torrent_ids)
|
return client.core.pause_torrent(torrent_ids)
|
||||||
|
|
||||||
def complete(self, line):
|
def complete(self, line):
|
||||||
# We use the ConsoleUI torrent tab complete method
|
# We use the ConsoleUI torrent tab complete method
|
||||||
|
|
|
@ -33,6 +33,6 @@ class Command(BaseCommand):
|
||||||
if client.connected():
|
if client.connected():
|
||||||
def on_disconnect(result):
|
def on_disconnect(result):
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
client.disconnect().addCallback(on_disconnect)
|
return client.disconnect().addCallback(on_disconnect)
|
||||||
else:
|
else:
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
# 51 Franklin Street, Fifth Floor
|
# 51 Franklin Street, Fifth Floor
|
||||||
# Boston, MA 02110-1301, USA.
|
# Boston, MA 02110-1301, USA.
|
||||||
#
|
#
|
||||||
|
|
||||||
from deluge.ui.console.main import BaseCommand
|
from deluge.ui.console.main import BaseCommand
|
||||||
from deluge.ui.client import client
|
from deluge.ui.client import client
|
||||||
import deluge.ui.console.colors as colors
|
import deluge.ui.console.colors as colors
|
||||||
|
@ -45,7 +46,7 @@ class Command(BaseCommand):
|
||||||
torrent_ids.extend(self.console.match_torrent(arg))
|
torrent_ids.extend(self.console.match_torrent(arg))
|
||||||
|
|
||||||
if torrent_ids:
|
if torrent_ids:
|
||||||
client.core.resume_torrent(torrent_ids)
|
return client.core.resume_torrent(torrent_ids)
|
||||||
|
|
||||||
def complete(self, line):
|
def complete(self, line):
|
||||||
# We use the ConsoleUI torrent tab complete method
|
# We use the ConsoleUI torrent tab complete method
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Command(BaseCommand):
|
||||||
for arg in args:
|
for arg in args:
|
||||||
torrent_ids.extend(self.console.match_torrent(arg))
|
torrent_ids.extend(self.console.match_torrent(arg))
|
||||||
|
|
||||||
client.core.remove_torrent(torrent_ids, options['remove_data'])
|
return client.core.remove_torrent(torrent_ids, options['remove_data'])
|
||||||
|
|
||||||
def complete(self, line):
|
def complete(self, line):
|
||||||
# We use the ConsoleUI torrent tab complete method
|
# We use the ConsoleUI torrent tab complete method
|
||||||
|
|
|
@ -36,9 +36,30 @@ import deluge.common
|
||||||
from deluge.ui.coreconfig import CoreConfig
|
from deluge.ui.coreconfig import CoreConfig
|
||||||
from deluge.ui.console.statusbars import StatusBars
|
from deluge.ui.console.statusbars import StatusBars
|
||||||
from deluge.ui.console.eventlog import EventLog
|
from deluge.ui.console.eventlog import EventLog
|
||||||
import deluge.ui.console.screen as screen
|
import screen
|
||||||
import deluge.ui.console.colors as colors
|
import colors
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
|
from deluge.ui.ui import _UI
|
||||||
|
|
||||||
|
class Console(_UI):
|
||||||
|
|
||||||
|
help = """Starts the Deluge console interface"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(Console, self).__init__("console")
|
||||||
|
cmds = load_commands(os.path.join(UI_PATH, 'commands'))
|
||||||
|
|
||||||
|
group = optparse.OptionGroup(self.parser, "Console Commands",
|
||||||
|
"\n".join(cmds.keys()))
|
||||||
|
self.parser.add_option_group(group)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
super(Console, self).start()
|
||||||
|
|
||||||
|
ConsoleUI(self.args)
|
||||||
|
|
||||||
|
def start():
|
||||||
|
Console().start()
|
||||||
|
|
||||||
class OptionParser(optparse.OptionParser):
|
class OptionParser(optparse.OptionParser):
|
||||||
"""subclass from optparse.OptionParser so exit() won't exit."""
|
"""subclass from optparse.OptionParser so exit() won't exit."""
|
||||||
|
@ -108,27 +129,42 @@ class ConsoleUI(component.Component):
|
||||||
# Load all the commands
|
# Load all the commands
|
||||||
self._commands = load_commands(os.path.join(UI_PATH, 'commands'))
|
self._commands = load_commands(os.path.join(UI_PATH, 'commands'))
|
||||||
|
|
||||||
# Try to connect to the localhost daemon
|
|
||||||
def on_connect(result):
|
|
||||||
component.start()
|
|
||||||
client.connect().addCallback(on_connect)
|
|
||||||
|
|
||||||
# Set the interactive flag to indicate where we should print the output
|
# Set the interactive flag to indicate where we should print the output
|
||||||
self.interactive = True
|
self.interactive = True
|
||||||
if args:
|
if args:
|
||||||
|
args = args[0]
|
||||||
self.interactive = False
|
self.interactive = False
|
||||||
# If we have args, lets process them and quit
|
|
||||||
#allow multiple commands split by ";"
|
# Try to connect to the localhost daemon
|
||||||
for arg in args.split(";"):
|
def on_connect(result):
|
||||||
self.do_command(arg)
|
component.start()
|
||||||
sys.exit(0)
|
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(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)
|
||||||
|
|
||||||
|
client.connect().addCallback(on_connect)
|
||||||
|
|
||||||
self.coreconfig = CoreConfig()
|
self.coreconfig = CoreConfig()
|
||||||
|
if self.interactive:
|
||||||
# We use the curses.wrapper function to prevent the console from getting
|
# We use the curses.wrapper function to prevent the console from getting
|
||||||
# messed up if an uncaught exception is experienced.
|
# messed up if an uncaught exception is experienced.
|
||||||
import curses.wrapper
|
import curses.wrapper
|
||||||
curses.wrapper(self.run)
|
curses.wrapper(self.run)
|
||||||
|
else:
|
||||||
|
reactor.run()
|
||||||
|
|
||||||
def run(self, stdscr):
|
def run(self, stdscr):
|
||||||
"""
|
"""
|
||||||
|
@ -157,12 +193,16 @@ class ConsoleUI(component.Component):
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
||||||
def start(self):
|
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
|
# Maintain a list of (torrent_id, name) for use in tab completion
|
||||||
self.torrents = []
|
self.torrents = []
|
||||||
def on_session_state(result):
|
def on_session_state(result):
|
||||||
def on_torrents_status(torrents):
|
def on_torrents_status(torrents):
|
||||||
for torrent_id, status in torrents.items():
|
for torrent_id, status in torrents.items():
|
||||||
self.torrents.append((torrent_id, status["name"]))
|
self.torrents.append((torrent_id, status["name"]))
|
||||||
|
self.started_deferred.callback(True)
|
||||||
|
|
||||||
client.core.get_torrents_status({"id": result}, ["name"]).addCallback(on_torrents_status)
|
client.core.get_torrents_status({"id": result}, ["name"]).addCallback(on_torrents_status)
|
||||||
client.core.get_session_state().addCallback(on_session_state)
|
client.core.get_session_state().addCallback(on_session_state)
|
||||||
|
@ -184,7 +224,7 @@ class ConsoleUI(component.Component):
|
||||||
if self.interactive:
|
if self.interactive:
|
||||||
self.screen.add_line(line)
|
self.screen.add_line(line)
|
||||||
else:
|
else:
|
||||||
print(line)
|
print(colors.strip_colors(line))
|
||||||
|
|
||||||
def do_command(self, cmd):
|
def do_command(self, cmd):
|
||||||
"""
|
"""
|
||||||
|
@ -215,12 +255,15 @@ class ConsoleUI(component.Component):
|
||||||
options, args = parser.parse_args(args)
|
options, args = parser.parse_args(args)
|
||||||
if not getattr(options, '_exit', False):
|
if not getattr(options, '_exit', False):
|
||||||
try:
|
try:
|
||||||
self._commands[cmd].handle(*args, **options.__dict__)
|
ret = self._commands[cmd].handle(*args, **options.__dict__)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.write("{!error!}" + str(e))
|
self.write("{!error!}" + str(e))
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
import traceback
|
import traceback
|
||||||
self.write("%s" % traceback.format_exc())
|
self.write("%s" % traceback.format_exc())
|
||||||
|
return defer.succeed(True)
|
||||||
|
else:
|
||||||
|
return ret
|
||||||
|
|
||||||
def tab_completer(self, line, cursor, second_hit):
|
def tab_completer(self, line, cursor, second_hit):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue