From c902d25524b453e294a3baa82261afd2b08e417c Mon Sep 17 00:00:00 2001 From: Jimmy Kiselak Date: Mon, 12 Oct 2015 13:52:47 -0400 Subject: [PATCH] start upgroading the console interface --- lbrynet/lbrynet_console/CommandHandlers.py | 40 ++++++++++ lbrynet/lbrynet_console/ConsoleControl.py | 90 +++++++++++++++++++++- lbrynet/lbrynet_console/LBRYConsole.py | 8 +- 3 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 lbrynet/lbrynet_console/CommandHandlers.py diff --git a/lbrynet/lbrynet_console/CommandHandlers.py b/lbrynet/lbrynet_console/CommandHandlers.py new file mode 100644 index 000000000..2e1eb0b91 --- /dev/null +++ b/lbrynet/lbrynet_console/CommandHandlers.py @@ -0,0 +1,40 @@ +import logging +from zope.interface import implements +from twisted.internet import defer +from lbrynet.lbrynet_console.interfaces import ICommandHandlerFactory, ICommandHandler + +log = logging.getLogger(__name__) + + +class CommandHandlerFactory(object): + implements(ICommandHandlerFactory) + short_help = "This should be overridden" + full_help = "This should really be overridden" + control_handler_class = None + + def __init__(self, *args): + self.args = args + + def get_handler(self, *args): + all_args = self.args + args + return self.control_handler_class(*all_args) + + +class CommandHandler(object): + implements(ICommandHandler) + + def __init__(self): + self.finished_deferred = defer.Deferred() + + def handle_line(self): + raise NotImplementedError() + + +class AddStream(CommandHandler): + pass + + +class AddStreamFactory(CommandHandlerFactory): + control_handler_class = AddStream + short_help = "Pull from the network" + full_help = "Pull from the network" \ No newline at end of file diff --git a/lbrynet/lbrynet_console/ConsoleControl.py b/lbrynet/lbrynet_console/ConsoleControl.py index 782dce528..54eb2d276 100644 --- a/lbrynet/lbrynet_console/ConsoleControl.py +++ b/lbrynet/lbrynet_console/ConsoleControl.py @@ -1,5 +1,9 @@ from twisted.protocols import basic from twisted.internet import defer +import logging + + +log = logging.getLogger(__name__) class ConsoleControl(basic.LineReceiver): @@ -57,4 +61,88 @@ class ConsoleControl(basic.LineReceiver): self.sendLine("") self.sendLine(self.categories[num]) self.sendLine("") - self.sendLine("[" + str(num) + "] " + handler.get_prompt_description()) \ No newline at end of file + self.sendLine("[" + str(num) + "] " + handler.get_prompt_description()) + + +class ConsoleControl2(basic.LineReceiver): + from os import linesep as delimiter + + def __init__(self, command_handlers): + self.command_handlers = command_handlers + self.current_handler = None + + def connectionMade(self): + self.sendLine("Enter a command. Try 'get wonderfullife' or 'help' to see more options.") + self.show_prompt() + + def send(self, s): + self.transport.write(s) + + def show_prompt(self): + self.send(">") + + def show_help_overview(self): + self.sendLine("Available commands:") + self.sendLine("") + for command, handler in sorted(self.command_handlers.items(), key=lambda x: x[0]): + self.sendLine(command + " - " + handler.short_help) + self.sendLine("") + self.sendLine("For more information about any command type 'help '") + + def handler_done(self): + self.current_handler = None + self.show_prompt() + + def lineReceived(self, line): + if self.current_handler is None: + words = line.split() + command, args = words[0], words[1:] + if command == "help": + if len(args) == 0: + self.show_help_overview() + self.show_prompt() + return + if args[0] in self.command_handlers: + self.sendLine(self.command_handlers[args[0]].full_help) + self.show_prompt() + return + if command in self.command_handlers: + command_handler = self.command_handlers[command] + else: + candidates = [k for k in self.command_handlers.keys() if k.startswith(command)] + if len(candidates) == 0: + self.sendLine("Unknown command. Type 'help' for a list of commands.") + self.show_prompt() + return + if len(candidates) >= 2: + l = "Ambiguous command. Matches: " + for candidate in candidates: + l += candidate + l += ", " + l = l[:-2] + l += l + self.sendLine(l) + self.show_prompt() + return + else: + command_handler = self.command_handlers[candidates[0]] + try: + self.current_handler = command_handler.get_handler(self, *args) + except Exception as e: + self.current_handler = None + import traceback + self.sendline(traceback.format_exc()) + log.error(traceback.format_exc()) + self.show_prompt() + return + self.current_handler.finished_deferred.addCallback(lambda _: self.handler_done()) + else: + try: + self.current_handler.handle_line(line) + except Exception as e: + self.current_handler = None + import traceback + self.sendline(traceback.format_exc()) + log.error(traceback.format_exc()) + self.show_prompt() + return \ No newline at end of file diff --git a/lbrynet/lbrynet_console/LBRYConsole.py b/lbrynet/lbrynet_console/LBRYConsole.py index 1d627b3fe..b28ed89cb 100644 --- a/lbrynet/lbrynet_console/LBRYConsole.py +++ b/lbrynet/lbrynet_console/LBRYConsole.py @@ -4,7 +4,7 @@ import os.path import argparse from yapsy.PluginManager import PluginManager from twisted.internet import defer, threads, stdio, task -from lbrynet.lbrynet_console.ConsoleControl import ConsoleControl +from lbrynet.lbrynet_console.ConsoleControl import ConsoleControl, ConsoleControl2 from lbrynet.lbrynet_console.LBRYSettings import LBRYSettings from lbrynet.lbryfilemanager.LBRYFileManager import LBRYFileManager from lbrynet.conf import MIN_BLOB_DATA_PAYMENT_RATE # , MIN_BLOB_INFO_PAYMENT_RATE @@ -80,6 +80,7 @@ class LBRYConsole(): os.path.join(os.path.dirname(__file__), "plugins"), ]) self.control_handlers = [] + self.command_handlers = [] self.query_handlers = {} self.settings = LBRYSettings(self.db_dir) @@ -299,6 +300,8 @@ class LBRYConsole(): return defer.succeed(True) def _setup_control_handlers(self): + self.command_handlers = [('get', AddStreamFactory(self.sd_identifier, self.session, + self.session.wallet))] handlers = [ ('General', ApplicationStatusFactory(self.session.rate_limiter, self.session.dht_node)), @@ -432,7 +435,8 @@ class LBRYConsole(): return defer.succeed(True) def _start_controller(self): - self.control_class(self.control_handlers) + #self.control_class(self.control_handlers) + ConsoleControl2(self.command_handlers) return defer.succeed(True) def _shut_down(self):