From 64da09675e740c8d003d6d744d03b0bb06317b27 Mon Sep 17 00:00:00 2001 From: bendikro Date: Sat, 16 Jan 2016 23:23:37 +0100 Subject: [PATCH] [#1119] [Console] ignore logging when no file specified Add wrapper around the stream passed to the loggers streamhandler when no log file is specified. Console in interactive mode now ignores the log output with no logfile specified. --- deluge/log.py | 6 ++++-- deluge/ui/baseargparser.py | 9 ++++++++- deluge/ui/console/console.py | 15 +++++++++++++-- deluge/ui/console/main.py | 18 +++++++++++++++++- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/deluge/log.py b/deluge/log.py index d8e98a458..d58600bea 100644 --- a/deluge/log.py +++ b/deluge/log.py @@ -107,7 +107,8 @@ levels = { } -def setup_logger(level="error", filename=None, filemode="w", logrotate=None, twisted_observer=True): +def setup_logger(level="error", filename=None, filemode="w", logrotate=None, + output_stream=sys.stdout, twisted_observer=True): """ Sets up the basic logger and if `:param:filename` is set, then it will log to that file instead of stdout. @@ -119,6 +120,7 @@ def setup_logger(level="error", filename=None, filemode="w", logrotate=None, twi filemode (str): The filemode to use when opening the log file logrotate (int, optional): The size of the logfile in bytes when enabling log rotation (Default is None meaning disabled) + output_stream (file descriptor): File descriptor to log to if not logging to file twisted_observer (bool): Whether to setup the custom twisted logging observer. """ if logging.getLoggerClass() is not Logging: @@ -141,7 +143,7 @@ def setup_logger(level="error", filename=None, filemode="w", logrotate=None, twi handler_cls = getattr(logging.handlers, "WatchedFileHandler", logging.FileHandler) handler = handler_cls(filename, mode=filemode, encoding="utf-8") else: - handler = logging.StreamHandler(stream=sys.stdout) + handler = logging.StreamHandler(stream=output_stream) handler.setLevel(level) diff --git a/deluge/ui/baseargparser.py b/deluge/ui/baseargparser.py index 2693d3dd7..4684f1de8 100644 --- a/deluge/ui/baseargparser.py +++ b/deluge/ui/baseargparser.py @@ -154,8 +154,14 @@ class BaseArgParser(argparse.ArgumentParser): def __init__(self, *args, **kwargs): if "formatter_class" not in kwargs: kwargs["formatter_class"] = lambda prog: DelugeTextHelpFormatter(prog, max_help_position=33, width=90) + kwargs["add_help"] = kwargs.get("add_help", False) common_help = kwargs.pop("common_help", True) + self.log_stream = sys.stdout + if "log_stream" in kwargs: + self.log_stream = kwargs["log_stream"] + del kwargs["log_stream"] + super(BaseArgParser, self).__init__(*args, **kwargs) self.common_setup = False @@ -229,6 +235,7 @@ class BaseArgParser(argparse.ArgumentParser): """ if not self.common_setup: self.common_setup = True + # Setup the logger if options.quiet: options.loglevel = "none" @@ -243,7 +250,7 @@ class BaseArgParser(argparse.ArgumentParser): # Setup the logger deluge.log.setup_logger(level=options.loglevel, filename=options.logfile, filemode=logfile_mode, - logrotate=logrotate) + logrotate=logrotate, output_stream=self.log_stream) if options.config: if not set_config_dir(options.config): diff --git a/deluge/ui/console/console.py b/deluge/ui/console/console.py index a58514792..7d81e7696 100644 --- a/deluge/ui/console/console.py +++ b/deluge/ui/console/console.py @@ -11,6 +11,7 @@ from __future__ import print_function import logging import os +import sys import deluge.common from deluge.ui.baseargparser import BaseArgParser, DelugeTextHelpFormatter @@ -49,12 +50,22 @@ def load_commands(command_dir): return {} +class LogStream(object): + out = sys.stdout + + def write(self, data): + self.out.write(data) + + def flush(self): + self.out.flush() + + class Console(UI): cmd_description = """Console or command-line user interface""" def __init__(self, *args, **kwargs): - super(Console, self).__init__("console", *args, **kwargs) + super(Console, self).__init__("console", *args, log_stream=LogStream(), **kwargs) group = self.parser.add_argument_group(_("Console Options"), "These daemon connect options will be " "used for commands, or if console ui autoconnect is enabled.") @@ -94,7 +105,7 @@ class Console(UI): def run(options): try: - c = ConsoleUI(self.options, self.console_cmds) + c = ConsoleUI(self.options, self.console_cmds, self.parser.log_stream) return c.start_ui() except Exception as ex: log.exception(ex) diff --git a/deluge/ui/console/main.py b/deluge/ui/console/main.py index a8ba152ee..efef43e90 100644 --- a/deluge/ui/console/main.py +++ b/deluge/ui/console/main.py @@ -217,9 +217,11 @@ class BaseCommand(object): class ConsoleUI(component.Component): - def __init__(self, options=None, cmds=None): + def __init__(self, options, cmds, log_stream): component.Component.__init__(self, "ConsoleUI", 2) self.options = options + self.log_stream = log_stream + # keep track of events for the log view self.events = [] self.statusbars = None @@ -274,6 +276,20 @@ Please use commands from the command line, e.g.:\n deluge-console.exe "add -p c:\\mytorrents c:\\new.torrent" """) else: + class ConsoleLog(object): + def write(self, data): + pass + + def flush(self): + pass + + self.log_stream.out = ConsoleLog() + + # Set Esc key delay to 0 to avoid a very annoying delay + # due to curses waiting in case of other key are pressed + # after ESC is pressed + os.environ.setdefault('ESCDELAY', '0') + # We use the curses.wrapper function to prevent the console from getting # messed up if an uncaught exception is experienced. import curses.wrapper