# Path: sen/exceptions.py
# class NotifyError(Exception):
#     """
#     There was an error, we should notify user.
#     """
# 
# class NotAvailableAnymore(Exception):
#     """
#     This object was available but isn't anymore.
#     """
# 
# Path: sen/tui/chunks/misc.py
# def get_row(docker_object):
#     if isinstance(docker_object, DockerImage):
#         return get_detailed_image_row(docker_object)
#     elif isinstance(docker_object, DockerContainer):
#         return get_detailed_container_row(docker_object)
#     else:
#         raise Exception("what ")
# 
# Path: sen/tui/widgets/list/util.py
# def get_operation_notify_widget(operation, notif_level="info", display_always=True):
#     if not operation:
#         return
#     attr = "notif_{}".format(notif_level)
#     took = operation.took
#     text_list = []
#     if took > 300:
#         fmt_str = "{} Query took "
#         text_list.append((attr, fmt_str.format(operation.pretty_message)))
#         command_took_str = "{:.2f}".format(took)
#         if took < 500:
#             text_list.append(("notif_text_yellow", command_took_str))
#         elif took < 1000:
#             text_list.append(("notif_text_orange", command_took_str))
#         else:
#             command_took_str = "{:.2f}".format(took / 1000.0)
#             text_list.append(("notif_text_red", command_took_str))
#             text_list.append((attr, " s"))
#         if took < 1000:
#             text_list.append((attr, " ms"))
#     elif display_always:
#         text_list.append((attr, operation.pretty_message))
#     else:
#         return
#     return urwid.AttrMap(urwid.Text(text_list), attr)
# 
# class ResponsiveRowWidget(RowWidget):
#     def __init__(self, columns, attr="main_list_dg", focus_map=MAIN_LIST_FOCUS, dividechars=1):
#         self.widgets = columns
#         self.columns = ResponsiveColumns(columns, dividechars=dividechars)
#         urwid.AttrMap.__init__(self, self.columns, attr, focus_map=focus_map)
# 
# Path: sen/tui/widgets/table.py
# class ResponsiveTable(WidgetBase):
#     def __init__(self, ui, walker, headers=None, dividechars=1, responsive=True):
#         """
#         :param walker: list of ResponsiveRow instances
#         :param headers: list of widgets which should be displayed as headers
#         """
#         self.dividechars = dividechars
#         self.responsive = responsive
# 
#         super().__init__(ui, walker)
# 
#     def render(self, size, focus=False):
#         screen_width = size[0]
# 
#         # max text length for each column -- table
#         min_col_lengths = calculate_max_cols_length(self.body, size)
# 
#         # compute maximal column width -- looks nicer
#         max_col_width = int(screen_width / len(min_col_lengths)) - self.dividechars
#         for k, v in min_col_lengths.items():
#             min_col_lengths[k] = min(min_col_lengths[k], max_col_width)
# 
#         columns_occupy = sum(min_col_lengths.values())
# 
#         if self.responsive:
#             # responsibility! spread the columns
#             to_spread = screen_width - len(min_col_lengths) * self.dividechars - columns_occupy
#             if to_spread:
#                 spread_remaining = to_spread
#                 weights = {}  # longer cols will get more space
#                 sum_weights = 0
#                 sorted_by_length = sorted(min_col_lengths.items(), key=lambda x: x[1])
#                 longest_col = sorted_by_length[-1][0]
#                 for weight, (idx, length) in enumerate(sorted_by_length):
#                     weights[idx] = weight + 1  # first weight is 1; 0 doesn't add anything
#                     sum_weights += weight + 1
#                 for k, v in min_col_lengths.items():
#                     expansion = int(to_spread * weights[k] / sum_weights)
#                     min_col_lengths[k] += expansion
#                     spread_remaining -= expansion
#                 # add remaining to the longest col
#                 min_col_lengths[longest_col] += spread_remaining
# 
#         for row in self.body:
#             row.contents[:] = [
#                 (w, (urwid.GIVEN, min_col_lengths[idx], is_box))
#                 for idx, (w, (_, _, is_box)) in enumerate(row.contents)
#             ]
# 
#         return super().render(size, focus=focus)
# 
# Path: sen/util.py
# def graceful_chain_get(d, *args, default=None):
#     t = d
#     for a in args:
#         try:
#             t = t[a]
#         except (KeyError, ValueError, TypeError, AttributeError):
#             logger.debug("can't get %r from %s", a, t)
#             return default
#     return t


import logging
import re
import threading
import time
import urwid
from sen.exceptions import NotifyError, NotAvailableAnymore
from sen.tui.chunks.misc import get_row
from sen.tui.widgets.list.util import (
    get_operation_notify_widget, ResponsiveRowWidget
)
from sen.tui.widgets.table import ResponsiveTable
from sen.util import graceful_chain_get



logger = logging.getLogger(__name__)


class MainLineWidget(ResponsiveRowWidget):
    def __init__(self, docker_object):
        self.docker_object = docker_object
        super().__init__(get_row(docker_object))

    def matches_search(self, s):
        return self.docker_object.matches_search(s)

    def __repr__(self):
        return "{}({})".format(self.__class__.__name__, self.docker_object)


# Path: sen/exceptions.py
# class NotifyError(Exception):
#     """
#     There was an error, we should notify user.
#     """
# 
# class NotAvailableAnymore(Exception):
#     """
#     This object was available but isn't anymore.
#     """
# 
# Path: sen/tui/chunks/misc.py
# def get_row(docker_object):
#     if isinstance(docker_object, DockerImage):
#         return get_detailed_image_row(docker_object)
#     elif isinstance(docker_object, DockerContainer):
#         return get_detailed_container_row(docker_object)
#     else:
#         raise Exception("what ")
# 
# Path: sen/tui/widgets/list/util.py
# def get_operation_notify_widget(operation, notif_level="info", display_always=True):
#     if not operation:
#         return
#     attr = "notif_{}".format(notif_level)
#     took = operation.took
#     text_list = []
#     if took > 300:
#         fmt_str = "{} Query took "
#         text_list.append((attr, fmt_str.format(operation.pretty_message)))
#         command_took_str = "{:.2f}".format(took)
#         if took < 500:
#             text_list.append(("notif_text_yellow", command_took_str))
#         elif took < 1000:
#             text_list.append(("notif_text_orange", command_took_str))
#         else:
#             command_took_str = "{:.2f}".format(took / 1000.0)
#             text_list.append(("notif_text_red", command_took_str))
#             text_list.append((attr, " s"))
#         if took < 1000:
#             text_list.append((attr, " ms"))
#     elif display_always:
#         text_list.append((attr, operation.pretty_message))
#     else:
#         return
#     return urwid.AttrMap(urwid.Text(text_list), attr)
# 
# class ResponsiveRowWidget(RowWidget):
#     def __init__(self, columns, attr="main_list_dg", focus_map=MAIN_LIST_FOCUS, dividechars=1):
#         self.widgets = columns
#         self.columns = ResponsiveColumns(columns, dividechars=dividechars)
#         urwid.AttrMap.__init__(self, self.columns, attr, focus_map=focus_map)
# 
# Path: sen/tui/widgets/table.py
# class ResponsiveTable(WidgetBase):
#     def __init__(self, ui, walker, headers=None, dividechars=1, responsive=True):
#         """
#         :param walker: list of ResponsiveRow instances
#         :param headers: list of widgets which should be displayed as headers
#         """
#         self.dividechars = dividechars
#         self.responsive = responsive
# 
#         super().__init__(ui, walker)
# 
#     def render(self, size, focus=False):
#         screen_width = size[0]
# 
#         # max text length for each column -- table
#         min_col_lengths = calculate_max_cols_length(self.body, size)
# 
#         # compute maximal column width -- looks nicer
#         max_col_width = int(screen_width / len(min_col_lengths)) - self.dividechars
#         for k, v in min_col_lengths.items():
#             min_col_lengths[k] = min(min_col_lengths[k], max_col_width)
# 
#         columns_occupy = sum(min_col_lengths.values())
# 
#         if self.responsive:
#             # responsibility! spread the columns
#             to_spread = screen_width - len(min_col_lengths) * self.dividechars - columns_occupy
#             if to_spread:
#                 spread_remaining = to_spread
#                 weights = {}  # longer cols will get more space
#                 sum_weights = 0
#                 sorted_by_length = sorted(min_col_lengths.items(), key=lambda x: x[1])
#                 longest_col = sorted_by_length[-1][0]
#                 for weight, (idx, length) in enumerate(sorted_by_length):
#                     weights[idx] = weight + 1  # first weight is 1; 0 doesn't add anything
#                     sum_weights += weight + 1
#                 for k, v in min_col_lengths.items():
#                     expansion = int(to_spread * weights[k] / sum_weights)
#                     min_col_lengths[k] += expansion
#                     spread_remaining -= expansion
#                 # add remaining to the longest col
#                 min_col_lengths[longest_col] += spread_remaining
# 
#         for row in self.body:
#             row.contents[:] = [
#                 (w, (urwid.GIVEN, min_col_lengths[idx], is_box))
#                 for idx, (w, (_, _, is_box)) in enumerate(row.contents)
#             ]
# 
#         return super().render(size, focus=focus)
# 
# Path: sen/util.py
# def graceful_chain_get(d, *args, default=None):
#     t = d
#     for a in args:
#         try:
#             t = t[a]
#         except (KeyError, ValueError, TypeError, AttributeError):
#             logger.debug("can't get %r from %s", a, t)
#             return default
#     return t


# Path: sen/tui/views/main.py
import logging
import re
import threading
import time
import urwid
from sen.exceptions import NotifyError, NotAvailableAnymore
from sen.tui.chunks.misc import get_row
from sen.tui.widgets.list.util import (
    get_operation_notify_widget, ResponsiveRowWidget
)
from sen.tui.widgets.table import ResponsiveTable
from sen.util import graceful_chain_get




logger = logging.getLogger(__name__)


class MainLineWidget(ResponsiveRowWidget):
    def __init__(self, docker_object):
        self.docker_object = docker_object
        super().__init__(get_row(docker_object))

    def matches_search(self, s):
        return self.docker_object.matches_search(s)

    def __repr__(self):
        return "{}({})".format(self.__class__.__name__, self.docker_object)


    def __str__(self):