Esempio n. 1
0
def exploreFieldSet(field_set, args, options={}):
    charset = getTerminalCharset()

    ui = urwid.curses_display.Screen()
    ui.register_palette((
        ('focus', 'white', 'dark blue'),
        ('sep', 'white', 'dark red'),
        ('input', 'black', 'light gray'),
    ))

    msgs = [[], [], 0]
    hachoir_log.use_print = False

    def logger(level, prefix, text, ctxt):
        if ctxt is not None:
            c = []
            if hasattr(ctxt, "_logger"):
                c[:0] = [ctxt._logger()]
            if issubclass(ctxt.__class__, Field):
                ctxt = ctxt["/"]
            name = logger.objects.get(ctxt)
            if name:
                c[:0] = [name]
            if c:
                text = "[%s] %s" % ('|'.join(c), text)
        if not isinstance(text, str):
            text = str(text, charset)
        msgs[0].append((level, prefix, text))

    logger.objects = WeakKeyDictionary()
    hachoir_log.on_new_message = logger

    preload_fields = 1 + max(0, args.preload)

    log_count = [0, 0, 0]
    sep = Separator("log: %%u/%%u/%%u  |  %s  " % "F1: help")
    sep.set_info(*tuple(log_count))
    body = Tabbed(sep)
    help = ('help', ListBox([Text(getHelpMessage())]))
    logger.objects[field_set] = logger.objects[
        field_set.stream] = name = 'root'
    body.append((name,
                 TreeBox(charset, Node(field_set, None), preload_fields,
                         args.path, options)))

    log = BoxAdapter(ListBox(msgs[1]), 0)
    log.selectable = lambda: False
    wrapped_sep = AttrWrap(sep, 'sep')
    footer = Pile([('flow', wrapped_sep), log])

    # awful way to allow the user to hide the log widget
    log.render = lambda size, focus=False: BoxAdapter.render(
        log, size[:1], focus)
    footer.render = lambda arg, focus=False: Pile.render(
        footer, (arg[0], sep.rows(arg) + log.height), focus)

    top = Frame(body, None, footer)

    def input_enter(w):
        footer.widget_list[0] = w
        footer.set_focus(0)
        top.set_focus('footer')

    def input_leave():
        footer.widget_list[0] = wrapped_sep
        footer.set_focus(0)
        top.set_focus('body')

    input = Input(input_enter, input_leave)

    def run():
        msg = _resize = retry = 0
        events = ("window resize", )
        profile_display = args.profile_display
        while True:
            for e in events:
                try:
                    if e == "window resize":
                        size = ui.get_cols_rows()
                        resize = log.height
                    else:
                        e = top.keypress(size, e)
                        if e is None:
                            pass
                        elif e in ('f1', '?'):
                            try:
                                body.select(body.tabs.index(help))
                            except ValueError:
                                body.append(help)
                                resize = log.height
                        elif e in ('esc', 'ctrl w'):
                            body.close()
                            if body.original_widget is None:
                                return
                            resize = log.height
                        elif e == '+':
                            if log.height:
                                resize = log.height - 1
                        elif e == '-':
                            resize = log.height + 1
                        elif e == 'q':
                            return
                # except AssertionError:
                #     hachoir_log.error(getBacktrace())
                except NewTab_Stream as e:
                    stream = e.field.getSubIStream()
                    logger.objects[stream] = e = "%u/%s" % (
                        body.active, e.field.absolute_address)
                    parser = guessParser(stream)
                    if not parser:
                        hachoir_log.error("No parser found for %s" %
                                          stream.source)
                    else:
                        logger.objects[parser] = e
                        body.append((e,
                                     TreeBox(charset, Node(parser, None),
                                             preload_fields, None, options)))
                        resize = log.height
                except NeedInput as e:
                    input.do(*e.args)
                if profile_display:
                    events = events[1:]
                    break
            while True:
                if msgs[0]:
                    for level, prefix, text in msgs[0]:
                        log_count[level] += 1
                        txt = Text("[%u]%s %s" % (msg, prefix, text))
                        msg += 1
                        msgs[1].append(txt)
                        _resize += txt.rows(size[:1])
                    if log.height < _resize and (resize is None
                                                 or resize < _resize):
                        resize = _resize
                    try:
                        log.set_focus(len(msgs[1]) - 1)
                    except IndexError:
                        pass
                    sep.set_info(*tuple(log_count))
                    msgs[0] = []
                if resize is not None:
                    body.height = size[1] - sep.rows(size[:1]) - resize
                    if body.height <= 0:
                        resize += body.height - 1
                        body.height = 1
                    log.height = resize
                    resize = None
                canvas = top.render(size, focus=True)
                if not msgs[0]:
                    _resize = retry = 0
                    break
                assert not retry
                retry += 1
            ui.draw_screen(size, canvas)
            msgs[2] = len(msgs[1])
            if profile_display and events:
                continue
            while True:
                events = ui.get_input()
                if events:
                    break

    try:
        ui.run_wrapper(run)
    except Exception:
        pending = [msg.get_text()[0] for msg in msgs[1][msgs[2]:]] + \
                  ["[*]%s %s" % (prefix, text)
                   for level, prefix, text in msgs[0]]
        if pending:
            print("\nPending messages:\n" + '\n'.join(pending))
        raise
Esempio n. 2
0
def exploreFieldSet(field_set, args, options={}):
    charset = getTerminalCharset()

    ui = urwid.curses_display.Screen()
    ui.register_palette((
        ('focus', 'white', 'dark blue'),
        ('sep', 'white', 'dark red'),
        ('input', 'black', 'light gray'),
    ))

    msgs = [[],[],0]
    hachoir_log.use_print = False
    def logger(level, prefix, text, ctxt):
        if ctxt is not None:
            c = []
            if hasattr(ctxt, "_logger"):
                c[:0] = [ ctxt._logger() ]
            if issubclass(ctxt.__class__, Field):
                ctxt = ctxt["/"]
            name = logger.objects.get(ctxt)
            if name:
                c[:0] = [ name ]
            if c:
                text = "[%s] %s" % ('|'.join(c), text)
        if not isinstance(text, unicode):
            text = unicode(text, charset)
        msgs[0].append((level, prefix, text))
    logger.objects = WeakKeyDictionary()
    hachoir_log.on_new_message = logger

    preload_fields = 1 + max(0, args.preload)

    log_count = [ 0, 0, 0 ]
    sep = Separator("log: %%u/%%u/%%u  |  %s  " % _("F1: help"))
    sep.set_info(*tuple(log_count))
    body = Tabbed(sep)
    help = ('help', ListBox([ Text(getHelpMessage()) ]))
    logger.objects[field_set] = logger.objects[field_set.stream] = name = u'root'
    body.append((name, TreeBox(charset, Node(field_set, None), preload_fields, args.path, options)))

    log = BoxAdapter(ListBox(msgs[1]), 0)
    log.selectable = lambda: False
    wrapped_sep = AttrWrap(sep, 'sep')
    footer = Pile([ ('flow', wrapped_sep), log ])

    # awful way to allow the user to hide the log widget
    log.render = lambda size, focus=False: BoxAdapter.render(log, size[:1], focus)
    footer.render = lambda (maxcol,), focus=False: Pile.render(footer, (maxcol, sep.rows((maxcol,))+log.height), focus)

    top = Frame(body, None, footer)

    def input_enter(w):
        footer.widget_list[0] = w
        footer.set_focus(0)
        top.set_focus('footer')
    def input_leave():
        footer.widget_list[0] = wrapped_sep
        footer.set_focus(0)
        top.set_focus('body')
    input = Input(input_enter, input_leave)

    def run():
        msg = _resize = retry = 0
        events = ( "window resize", )
        profile_display = args.profile_display
        while True:
            for e in events:
                try:
                    if e == "window resize":
                        size = ui.get_cols_rows()
                        resize = log.height
                    else:
                        e = top.keypress(size, e)
                        if e is None:
                            pass
                        elif e in ('f1', '?'):
                            try:
                                body.select(body.tabs.index(help))
                            except ValueError:
                                body.append(help)
                                resize = log.height
                        elif e in ('esc', 'ctrl w'):
                            body.close()
                            if body.box_widget is None:
                                return
                            resize = log.height
                        elif e == '+':
                            if log.height:
                                resize = log.height - 1
                        elif e == '-':
                            resize = log.height + 1
                        elif e == 'q':
                            return
                #except AssertionError:
                #    hachoir_log.error(getBacktrace())
                except NewTab_Stream, e:
                    stream = e.field.getSubIStream()
                    logger.objects[stream] = e = "%u/%s" % (body.active, e.field.absolute_address)
                    parser = guessParser(stream)
                    if not parser:
                        hachoir_log.error(_("No parser found for %s") % stream.source)
                    else:
                        logger.objects[parser] = e
                        body.append((e, TreeBox(charset, Node(parser, None), preload_fields, None, options)))
                        resize = log.height
                except NeedInput, e:
                    input.do(*e.args)
                if profile_display:
                    events = events[1:]
                    break
            while True:
                if msgs[0]:
                    for level, prefix, text in msgs[0]:
                        log_count[level] += 1
                        txt = Text("[%u]%s %s" % (msg, prefix, text))
                        msg += 1
                        msgs[1].append(txt)
                        _resize += txt.rows(size[:1])
                    if log.height < _resize and (resize is None or resize < _resize):
                        resize = _resize
                    log.set_focus(len(msgs[1])-1)
                    sep.set_info(*tuple(log_count))
                    msgs[0] = []
                if resize is not None:
                    body.height = size[1] - sep.rows(size[:1]) - resize
                    if body.height <= 0:
                        resize += body.height - 1
                        body.height = 1
                    log.height = resize
                    resize = None
                canvas = top.render(size, focus=True)
                if not msgs[0]:
                    _resize = retry = 0
                    break
                assert not retry
                retry += 1
            ui.draw_screen(size, canvas)
            msgs[2] = len(msgs[1])
            if profile_display and events:
                continue
            while True:
                events = ui.get_input()
                if events: break