# Path: sen/exceptions.py
# class NotifyError(Exception):
#     """
#     There was an error, we should notify user.
#     """
# 
# Path: sen/tui/buffer.py
# class HelpBuffer(Buffer):
#     # TODO: apply this interface to other buffers: create views
#     description = "Show information about currently displayed buffer and " + \
#                   "what keybindings are available there"
#     display_name = "Help"
# 
#     def __init__(self, ui, inp):
#         """
#         display buffer with more info about object 'inp'
# 
#         :param ui: UI instance
#         :param inp: Buffer, Command instance
#         """
#         self.ui = ui
#         if isinstance(inp, Buffer):
#             self.display_name += "({})".format(inp.display_name)
#             self.widget = HelpBufferView(ui, inp, self.global_keybinds)
#         elif isinstance(inp, Command):
#             self.display_name += "({})".format(inp.name)
#             self.widget = HelpCommandView(ui, inp)
# 
#         super().__init__()
# 
# class TreeBuffer(Buffer):
#     display_name = "Layers"
#     description = "Tree view of all layers available on your docker engine."
#     keybinds = {
#         "enter": "display-info",
#     }
# 
#     def __init__(self, ui, docker_backend):
#         self.widget = ImageTree(ui, docker_backend)
#         super().__init__()
# 
# Path: sen/tui/commands/base.py
# def register_command(kls):
#     commands_mapping[kls.name] = kls
#     for a in kls.aliases:
#         commands_mapping[a] = kls
#     return kls
# 
# class SameThreadCommand(Command):
#     priority = SameThreadPriority()
# 
# class Option(ArgumentBase):
#     """
#     options alter behavior, are not positional
#     """
#     def __init__(self, name, description, action=true_action, aliases=None, default=None):
#         super().__init__(name, description, action=action, default=default)
#         self.aliases = aliases or []
# 
#     def __str__(self):
#         return "{} default={} action=\"{}\" aliases={}".format(
#             self.name, self.default, self.action, self.aliases
#         )
# 
#     def __unicode__(self):
#         return self.__str__()
# 
# class Argument(ArgumentBase):
#     """
#     arguments are positional
#     """
#     pass
# 
# class NoSuchCommand(Exception):
#     pass
# 
# Path: sen/util.py
# def log_traceback(func):
#     @functools.wraps(func)
#     def wrapper(*args, **kwargs):
#         logger.info("function %s is about to be started", func)
#         try:
#             response = func(*args, **kwargs)
#         except Exception:
#             log_last_traceback()
#         else:
#             logger.info("function %s finished", func)
#             # TODO: how long it took?
#             return response
#     return wrapper
# 
# def log_last_traceback():
#     logger.error(traceback.format_exc())


import logging
import urwid
from sen.exceptions import NotifyError
from sen.tui.buffer import HelpBuffer, TreeBuffer
from sen.tui.commands.base import (
    register_command, SameThreadCommand,
    Option, Argument,
    NoSuchCommand
)
from sen.util import log_traceback, log_last_traceback
            command = self.ui.commander.get_command(self.arguments.query)
        except NoSuchCommand:
            self.ui.notify_message("There is no such command: %r" % self.arguments.query)
        else:
            self.ui.add_and_display_buffer(HelpBuffer(self.ui, command))
            return
        # TODO: help view for commands could be displayed in footer


@register_command
class DisplayLayersCommand(DisplayBufferCommand):
    name = "layers"
    description = "open a tree view of all image layers (`docker images --tree` equivalent)"

    def run(self):
        self.arguments.set_argument("buffer", TreeBuffer(self.ui, self.docker_backend))
        super().run()


@log_traceback
def run_command_callback(ui, docker_object, edit_widget, text_input):
    logger.debug("%r %r", edit_widget, text_input)
    if "\n" in text_input:
        inp = text_input.strip()
        inp = inp.replace("\n", "")
        # first restore statusbar and then run the command
        ui.prompt_bar = None
        ui.set_focus("body")
        try:
            ui.run_command(inp, docker_object=docker_object)

# Path: sen/exceptions.py
# class NotifyError(Exception):
#     """
#     There was an error, we should notify user.
#     """
# 
# Path: sen/tui/buffer.py
# class HelpBuffer(Buffer):
#     # TODO: apply this interface to other buffers: create views
#     description = "Show information about currently displayed buffer and " + \
#                   "what keybindings are available there"
#     display_name = "Help"
# 
#     def __init__(self, ui, inp):
#         """
#         display buffer with more info about object 'inp'
# 
#         :param ui: UI instance
#         :param inp: Buffer, Command instance
#         """
#         self.ui = ui
#         if isinstance(inp, Buffer):
#             self.display_name += "({})".format(inp.display_name)
#             self.widget = HelpBufferView(ui, inp, self.global_keybinds)
#         elif isinstance(inp, Command):
#             self.display_name += "({})".format(inp.name)
#             self.widget = HelpCommandView(ui, inp)
# 
#         super().__init__()
# 
# class TreeBuffer(Buffer):
#     display_name = "Layers"
#     description = "Tree view of all layers available on your docker engine."
#     keybinds = {
#         "enter": "display-info",
#     }
# 
#     def __init__(self, ui, docker_backend):
#         self.widget = ImageTree(ui, docker_backend)
#         super().__init__()
# 
# Path: sen/tui/commands/base.py
# def register_command(kls):
#     commands_mapping[kls.name] = kls
#     for a in kls.aliases:
#         commands_mapping[a] = kls
#     return kls
# 
# class SameThreadCommand(Command):
#     priority = SameThreadPriority()
# 
# class Option(ArgumentBase):
#     """
#     options alter behavior, are not positional
#     """
#     def __init__(self, name, description, action=true_action, aliases=None, default=None):
#         super().__init__(name, description, action=action, default=default)
#         self.aliases = aliases or []
# 
#     def __str__(self):
#         return "{} default={} action=\"{}\" aliases={}".format(
#             self.name, self.default, self.action, self.aliases
#         )
# 
#     def __unicode__(self):
#         return self.__str__()
# 
# class Argument(ArgumentBase):
#     """
#     arguments are positional
#     """
#     pass
# 
# class NoSuchCommand(Exception):
#     pass
# 
# Path: sen/util.py
# def log_traceback(func):
#     @functools.wraps(func)
#     def wrapper(*args, **kwargs):
#         logger.info("function %s is about to be started", func)
#         try:
#             response = func(*args, **kwargs)
#         except Exception:
#             log_last_traceback()
#         else:
#             logger.info("function %s finished", func)
#             # TODO: how long it took?
#             return response
#     return wrapper
# 
# def log_last_traceback():
#     logger.error(traceback.format_exc())


# Path: sen/tui/commands/ui.py
import logging
import urwid
from sen.exceptions import NotifyError
from sen.tui.buffer import HelpBuffer, TreeBuffer
from sen.tui.commands.base import (
    register_command, SameThreadCommand,
    Option, Argument,
    NoSuchCommand
)
from sen.util import log_traceback, log_last_traceback

            command = self.ui.commander.get_command(self.arguments.query)
        except NoSuchCommand:
            self.ui.notify_message("There is no such command: %r" % self.arguments.query)
        else:
            self.ui.add_and_display_buffer(HelpBuffer(self.ui, command))
            return
        # TODO: help view for commands could be displayed in footer


@register_command
class DisplayLayersCommand(DisplayBufferCommand):
    name = "layers"
    description = "open a tree view of all image layers (`docker images --tree` equivalent)"

    def run(self):
        self.arguments.set_argument("buffer", TreeBuffer(self.ui, self.docker_backend))
        super().run()


@log_traceback
def run_command_callback(ui, docker_object, edit_widget, text_input):
    logger.debug("%r %r", edit_widget, text_input)
    if "\n" in text_input:
        inp = text_input.strip()
        inp = inp.replace("\n", "")
        # first restore statusbar and then run the command
        ui.prompt_bar = None
        ui.set_focus("body")
        try:
            ui.run_command(inp, docker_object=docker_object)

        except NoSuchCommand as ex: