diff options
-rw-r--r-- | ranger/core/actions.py | 6 | ||||
-rw-r--r-- | ranger/core/fm.py | 14 | ||||
-rw-r--r-- | ranger/core/main.py | 8 | ||||
-rw-r--r-- | ranger/ext/logutils.py | 78 |
4 files changed, 102 insertions, 4 deletions
diff --git a/ranger/core/actions.py b/ranger/core/actions.py index c119c501..6d1824c2 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -869,11 +869,13 @@ class Actions(FileManagerAware, SettingsAware): self.notify("Could not find manpage.", bad=True) def display_log(self): + logs = list(self.get_log()) pager = self.ui.open_pager() - if self.log: - pager.set_source(["Message Log:"] + list(self.log)) + if logs: + pager.set_source(["Message Log:"] + logs) else: pager.set_source(["Message Log:", "No messages!"]) + pager.move(to=100, percentage=True) def display_file(self): if not self.thisfile or not self.thisfile.is_file: diff --git a/ranger/core/fm.py b/ranger/core/fm.py index a08de2e1..719479eb 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -5,6 +5,7 @@ from time import time from collections import deque +import logging import mimetypes import os.path import pwd @@ -27,6 +28,9 @@ from ranger.container.directory import Directory from ranger.ext.signals import SignalDispatcher from ranger import __version__ from ranger.core.loader import Loader +from ranger.ext import logutils + +log = logging.getLogger(__name__) class FM(Actions, SignalDispatcher): @@ -50,7 +54,6 @@ class FM(Actions, SignalDispatcher): self.ui = ui self.start_paths = paths self.directories = dict() - self.log = deque(maxlen=1000) self.bookmarks = bookmarks self.current_tab = 1 self.tabs = {} @@ -205,6 +208,15 @@ class FM(Actions, SignalDispatcher): if debug: raise + def get_log(self): + """Return the current log + + The log is returned as a list of string + """ + for log in logutils.log_queue: + for line in log.split('\n'): + yield line + def _get_image_displayer(self): if self.settings.preview_images_method == "w3m": return W3MImageDisplayer() diff --git a/ranger/core/main.py b/ranger/core/main.py index 341b48e6..d2f5c709 100644 --- a/ranger/core/main.py +++ b/ranger/core/main.py @@ -6,6 +6,9 @@ import os.path import sys import tempfile +from logging import getLogger + +log = getLogger(__name__) def main(): @@ -15,6 +18,10 @@ def main(): from ranger.container.settings import Settings from ranger.core.shared import FileManagerAware, SettingsAware from ranger.core.fm import FM + from ranger.ext.logutils import setup_logging + + ranger.arg = arg = parse_arguments() + setup_logging(debug=arg.debug, logfile=arg.logfile) try: locale.setlocale(locale.LC_ALL, '') @@ -31,7 +38,6 @@ def main(): if 'SHELL' not in os.environ: os.environ['SHELL'] = 'sh' - ranger.arg = arg = parse_arguments() if arg.copy_config is not None: fm = FM() fm.copy_config_files(arg.copy_config) diff --git a/ranger/ext/logutils.py b/ranger/ext/logutils.py new file mode 100644 index 00000000..0de6c333 --- /dev/null +++ b/ranger/ext/logutils.py @@ -0,0 +1,78 @@ +import logging +from collections import deque + +LOG_FORMAT = "[%(levelname)s] %(message)s" +LOG_FORMAT_EXT = "%(asctime)s,%(msecs)d [%(name)s] |%(levelname)s| %(message)s" +LOG_DATA_FORMAT = "%H:%M:%S" + + +class QueueHandler(logging.Handler): + """ + This handler store logs events into a queue. + """ + + def __init__(self, queue): + """ + Initialize an instance, using the passed queue. + """ + logging.Handler.__init__(self) + self.queue = queue + + def enqueue(self, record): + """ + Enqueue a log record. + """ + self.queue.append(record) + + def emit(self, record): + self.enqueue(self.format(record)) + + +log_queue = deque(maxlen=1000) +concise_formatter = logging.Formatter(fmt=LOG_FORMAT, datefmt=LOG_DATA_FORMAT) +extended_formatter = logging.Formatter(fmt=LOG_FORMAT_EXT, datefmt=LOG_DATA_FORMAT) + + +def setup_logging(debug=True, logfile=None): + """ + All the produced logs using the standard logging function + will be collected in a queue by the `queue_handler` as well + as outputted on the standard error `stderr_handler`. + + The verbosity and the format of the log message is + controlled by the `debug` parameter + + - debug=False: + a concise log format will be used, debug messsages will be discarded + and only important message will be passed to the `stderr_handler` + + - debug=True: + an extended log format will be used, all messages will be processed + by both the handlers + """ + root_logger = logging.getLogger() + + if debug: + # print all logging in extended format + log_level = logging.DEBUG + formatter = extended_formatter + else: + # print only warning and critical message + # in a concise format + log_level = logging.INFO + formatter = concise_formatter + + handlers = [] + handlers.append(QueueHandler(log_queue)) + if logfile: + if logfile is '-': + handlers.append(logging.StreamHandler()) + else: + handlers.append(logging.FileHandler(logfile)) + + for handler in handlers: + handler.setLevel(log_level) + handler.setFormatter(formatter) + root_logger.addHandler(handler) + + root_logger.setLevel(0) |