Ejemplo n.º 1
0
class Sidebar(BoxWidget):
    signals = ['select', 'search']

    def __init__(self, phones):
        self.phone_edit = EnterEdit('Phone:', '')
        self.chan_edit = EnterEdit('Chanl:', '')
        self.call_id_edit = EnterEdit('SipID:', '')
        self.text_edit = EnterEdit('Find:', '')
        connect_signal(self.phone_edit, 'enter', self.on_change, 'phone')
        connect_signal(self.chan_edit, 'enter', self.on_change, 'chan')
        connect_signal(self.call_id_edit, 'enter', self.on_change, 'call_id')
        connect_signal(self.text_edit, 'enter', self.on_change, 'text')
        self.phones_text = Text([('key', 'F4'), ' Phones'])
        self.head = Pile([
            AttrWrap(Text([('key', 'F3'), ' Search']), 'bar'),
            AttrWrap(self.phone_edit, 'no', 'selection'),
            AttrWrap(self.chan_edit, 'no', 'selection'),
            AttrWrap(self.call_id_edit, 'no', 'selection'),
            Divider('-'),
            AttrWrap(self.text_edit, 'no', 'selection'),
            AttrWrap(self.phones_text, 'bar'),
        ])
        self.items = SimpleListWalker([])
        self.set_results(phones)
        self.listbox = ListBox(self.items)
        self.frame = Frame(self.listbox, header=self.head)

    def set_results(self, results):
        self.phones_text.set_text([('key', 'F4'),
                                   ' Results (%s)' % len(results)])
        self.items[:] = []
        group = []
        for ref in results:
            item = RadioButton(group, ref, state=False)
            connect_signal(item, 'change', self.on_select_phone, ref)
            item = AttrWrap(item, 'no', 'selection')
            self.items.append(item)

    def render(self, size, focus=False):
        return self.frame.render(size, focus)

    def keypress(self, size, key):
        return self.frame.keypress(size, key)

    # noinspection PyUnusedLocal
    def on_select_phone(self, button, new_state, call_id):
        if new_state:
            self._emit('select', call_id)

    # noinspection PyUnusedLocal
    def on_change(self, widget, value, field_name):
        self._emit('search', field_name, value)
Ejemplo n.º 2
0
class Client(Component):

    channel = "client"

    def init(self, host, port=6667, opts=None):
        self.host = host
        self.port = port
        self.opts = opts
        self.hostname = gethostname()

        self.nick = opts.nick
        self.ircchannel = opts.channel

        # Add TCPClient and IRC to the system.
        TCPClient(channel=self.channel).register(self)
        IRC(channel=self.channel).register(self)

        self.create_interface()

    def create_interface(self):
        self.screen = Screen()
        self.screen.start()

        self.screen.register_palette([
            ("title", "white", "dark blue", "standout"),
            ("line", "light gray", "black"),
            ("help", "white", "dark blue")]
        )

        self.body = ListBox(SimpleListWalker([]))
        self.lines = self.body.body

        self.title = Text(MAIN_TITLE)
        self.header = AttrWrap(self.title, "title")

        self.help = AttrWrap(
            Text(HELP_STRINGS["main"]),
            "help"
        )

        self.input = Edit(caption="%s> " % self.ircchannel)
        self.footer = Pile([self.help, self.input])

        self.top = Frame(self.body, self.header, self.footer)

    def ready(self, component):
        """Ready Event

        This event is triggered by the underlying ``TCPClient`` Component
        when it is ready to start making a new connection.
        """

        self.fire(connect(self.host, self.port))

    def connected(self, host, port):
        """connected Event

        This event is triggered by the underlying ``TCPClient`` Component
        when a successfully connection has been made.
        """

        nick = self.nick
        hostname = self.hostname
        name = "%s on %s using circuits/%s" % (nick, hostname, systemVersion)

        self.fire(NICK(nick))
        self.fire(USER(nick, hostname, host, name))

    def numeric(self, source, numeric, *args):
        """Numeric Event

        This event is triggered by the ``IRC`` Protocol Component when we have
        received an IRC Numberic Event from server we are connected to.
        """

        if numeric == ERR_NICKNAMEINUSE:
            self.fire(NICK("{0:s}_".format(args[0])))
        elif numeric in (RPL_ENDOFMOTD, ERR_NOMOTD):
            self.fire(JOIN(self.ircchannel))

    @handler("stopped", channel="*")
    def _on_stopped(self, component):
        self.screen.stop()

    @handler("generate_events")
    def _on_generate_events(self, event):
        event.reduce_time_left(0)

        size = self.screen.get_cols_rows()

        if not select(
                self.screen.get_input_descriptors(), [], [], 0.1)[0] == []:
            timeout, keys, raw = self.screen.get_input_nonblocking()

            for k in keys:
                if k == "window resize":
                    size = self.screen.get_cols_rows()
                    continue
                elif k == "enter":
                    self.processCommand(self.input.get_edit_text())
                    self.input.set_edit_text("")
                    continue

                self.top.keypress(size, k)
                self.input.set_edit_text(self.input.get_edit_text() + k)

        self.update_screen(size)

    def unknownCommand(self, command):
        self.lines.append(Text("Unknown command: %s" % command))

    def syntaxError(self, command, args, expected):
        self.lines.append(
            Text("Syntax error ({0:s}): {1:s} Expected: {2:s}".format(
                command, args, expected)
            )
        )

    def processCommand(self, s):  # noqa

        match = CMD_REGEX.match(s)
        if match is not None:

            command = match.groupdict()["command"]
            if not match.groupdict()["args"] == "":
                tokens = match.groupdict()["args"].split(" ")
            else:
                tokens = []

            fn = "cmd" + command.upper()
            if hasattr(self, fn):
                f = getattr(self, fn)
                if callable(f):

                    args, vargs, kwargs, default = getargspec(f)
                    args.remove("self")
                    if len(args) == len(tokens):
                        if len(args) == 0:
                            f()
                        else:
                            f(*tokens)
                    else:
                        if len(tokens) > len(args):
                            if vargs is None:
                                if len(args) > 0:
                                    factor = len(tokens) - len(args) + 1
                                    f(*back_merge(tokens, factor))
                                else:
                                    self.syntaxError(
                                        command, " ".join(tokens),
                                        " ".join(
                                            x for x in args + [vargs]
                                            if x is not None
                                        )
                                    )
                            else:
                                f(*tokens)
                        elif default is not None and \
                                len(args) == (
                                    len(tokens) + len(default)):
                            f(*(tokens + list(default)))
                        else:
                            self.syntaxError(
                                command,
                                " ".join(tokens),
                                " ".join(
                                    x for x in args + [vargs]
                                    if x is not None
                                )
                            )
        else:
            if self.ircchannel is not None:
                self.lines.append(Text("<%s> %s" % (self.nick, s)))
                self.fire(PRIVMSG(self.ircchannel, s))
            else:
                self.lines.append(Text(
                    "No channel joined. Try /join #<channel>"))

    def cmdEXIT(self, message=""):
        self.fire(QUIT(message))
        raise SystemExit(0)

    def cmdSERVER(self, host, port=6667):
        self.fire(connect(host, port))

    def cmdSSLSERVER(self, host, port=6697):
        self.fire(connect(host, port, secure=True))

    def cmdJOIN(self, channel):
        if self.ircchannel is not None:
            self.cmdPART(self.ircchannel, "Joining %s" % channel)
        self.fire(JOIN(channel))
        self.ircchannel = channel

    def cmdPART(self, channel=None, message="Leaving"):
        if channel is None:
            channel = self.ircchannel
        if channel is not None:
            self.fire(PART(channel, message))
            self.ircchannel = None

    def cmdQUOTE(self, message):
        self.fire(request(Message(message)))

    def cmdQUIT(self, message="Bye"):
        self.fire(QUIT(message))

    def update_screen(self, size):
        canvas = self.top.render(size, focus=True)
        self.screen.draw_screen(size, canvas)

    @handler("notice", "privmsg")
    def _on_notice_or_privmsg(self, event, source, target, message):
        nick, ident, host = source

        if event.name == "notice":
            self.lines.append(Text("-%s- %s" % (nick, message)))
        else:
            self.lines.append(Text("<%s> %s" % (nick, message)))
Ejemplo n.º 3
0
class Client(Component):

    channel = "client"

    def init(self, host, port=6667, opts=None):
        self.host = host
        self.port = port
        self.opts = opts
        self.hostname = gethostname()

        self.nick = opts.nick
        self.ircchannel = opts.channel

        # Add TCPClient and IRC to the system.
        TCPClient(channel=self.channel).register(self)
        IRC(channel=self.channel).register(self)

        self.create_interface()

    def create_interface(self):
        self.screen = Screen()
        self.screen.start()

        self.screen.register_palette([
            ("title", "white", "dark blue", "standout"),
            ("line", "light gray", "black"),
            ("help", "white", "dark blue")]
        )

        self.body = ListBox(SimpleListWalker([]))
        self.lines = self.body.body

        self.title = Text(MAIN_TITLE)
        self.header = AttrWrap(self.title, "title")

        self.help = AttrWrap(
            Text(HELP_STRINGS["main"]),
            "help"
        )

        self.input = Edit(caption="%s> " % self.ircchannel)
        self.footer = Pile([self.help, self.input])

        self.top = Frame(self.body, self.header, self.footer)

    def ready(self, component):
        """Ready Event

        This event is triggered by the underlying ``TCPClient`` Component
        when it is ready to start making a new connection.
        """

        self.fire(connect(self.host, self.port))

    def connected(self, host, port):
        """connected Event

        This event is triggered by the underlying ``TCPClient`` Component
        when a successfully connection has been made.
        """

        nick = self.nick
        hostname = self.hostname
        name = "%s on %s using circuits/%s" % (nick, hostname, systemVersion)

        self.fire(NICK(nick))
        self.fire(USER(nick, hostname, host, name))

    def numeric(self, source, numeric, *args):
        """Numeric Event

        This event is triggered by the ``IRC`` Protocol Component when we have
        received an IRC Numberic Event from server we are connected to.
        """

        if numeric == ERR_NICKNAMEINUSE:
            self.fire(NICK("{0:s}_".format(args[0])))
        elif numeric in (RPL_ENDOFMOTD, ERR_NOMOTD):
            self.fire(JOIN(self.ircchannel))

    @handler("stopped", channel="*")
    def _on_stopped(self, component):
        self.screen.stop()

    @handler("generate_events")
    def _on_generate_events(self, event):
        event.reduce_time_left(0)

        size = self.screen.get_cols_rows()

        if not select(
                self.screen.get_input_descriptors(), [], [], 0.1)[0] == []:
            timeout, keys, raw = self.screen.get_input_nonblocking()

            for k in keys:
                if k == "window resize":
                    size = self.screen.get_cols_rows()
                    continue
                elif k == "enter":
                    self.processCommand(self.input.get_edit_text())
                    self.input.set_edit_text("")
                    continue

                self.top.keypress(size, k)
                self.input.set_edit_text(self.input.get_edit_text() + k)

        self.update_screen(size)

    def unknownCommand(self, command):
        self.lines.append(Text("Unknown command: %s" % command))

    def syntaxError(self, command, args, expected):
        self.lines.append(
            Text("Syntax error ({0:s}): {1:s} Expected: {2:s}".format(
                command, args, expected)
            )
        )

    def processCommand(self, s):  # noqa

        match = CMD_REGEX.match(s)
        if match is not None:

            command = match.groupdict()["command"]
            if not match.groupdict()["args"] == "":
                tokens = match.groupdict()["args"].split(" ")
            else:
                tokens = []

            fn = "cmd" + command.upper()
            if hasattr(self, fn):
                f = getattr(self, fn)
                if callable(f):

                    args, vargs, kwargs, default = getargspec(f)
                    args.remove("self")
                    if len(args) == len(tokens):
                        if len(args) == 0:
                            f()
                        else:
                            f(*tokens)
                    else:
                        if len(tokens) > len(args):
                            if vargs is None:
                                if len(args) > 0:
                                    factor = len(tokens) - len(args) + 1
                                    f(*back_merge(tokens, factor))
                                else:
                                    self.syntaxError(
                                        command, " ".join(tokens),
                                        " ".join(
                                            x for x in args + [vargs]
                                            if x is not None
                                        )
                                    )
                            else:
                                f(*tokens)
                        elif default is not None and \
                                len(args) == (
                                    len(tokens) + len(default)):
                            f(*(tokens + list(default)))
                        else:
                            self.syntaxError(
                                command,
                                " ".join(tokens),
                                " ".join(
                                    x for x in args + [vargs]
                                    if x is not None
                                )
                            )
        else:
            if self.ircchannel is not None:
                self.lines.append(Text("<%s> %s" % (self.nick, s)))
                self.fire(PRIVMSG(self.ircchannel, s))
            else:
                self.lines.append(Text(
                    "No channel joined. Try /join #<channel>"))

    def cmdEXIT(self, message=""):
        self.fire(QUIT(message))
        raise SystemExit(0)

    def cmdSERVER(self, host, port=6667):
        self.fire(connect(host, port))

    def cmdSSLSERVER(self, host, port=6697):
        self.fire(connect(host, port, secure=True))

    def cmdJOIN(self, channel):
        if self.ircchannel is not None:
            self.cmdPART(self.ircchannel, "Joining %s" % channel)
        self.fire(JOIN(channel))
        self.ircchannel = channel

    def cmdPART(self, channel=None, message="Leaving"):
        if channel is None:
            channel = self.ircchannel
        if channel is not None:
            self.fire(PART(channel, message))
            self.ircchannel = None

    def cmdQUOTE(self, message):
        self.fire(request(Message(message)))

    def cmdQUIT(self, message="Bye"):
        self.fire(QUIT(message))

    def update_screen(self, size):
        canvas = self.top.render(size, focus=True)
        self.screen.draw_screen(size, canvas)

    @handler("notice", "privmsg")
    def _on_notice_or_privmsg(self, event, source, target, message):
        nick, ident, host = source

        if event.name == "notice":
            self.lines.append(Text("-%s- %s" % (nick, message)))
        else:
            self.lines.append(Text("<%s> %s" % (nick, message)))
Ejemplo n.º 4
0
class LogDisplay(BoxWidget):
    def __init__(self, parser, encoding):
        self.parser = parser
        self.encoding = encoding
        self.find = {'ref': '', 'text': ''}
        self.isolate_filter = (None, None)
        self.line_collection = None
        self.jump_stack = []
        self.expansions = {}
        self.show_sip_level = 2
        self.show_ladder = False
        self.show_only_filtered = False
        self.show_verbose = True
        self.show_channel = True
        self.line_no_before_isolate = 0
        self.showing_help = False

        self.walker = LogLineWalker([('Select call on the left side', None)],
                                    self.jump, self.expand, self.isolate)
        self.header = AttrWrap(Text([('key', 'F6'), ' Log']), 'bar')
        self.listbox = ListBox(self.walker)
        self.frame = Frame(self.listbox, header=self.header)

    def render(self, size, focus=False):
        return self.frame.render(size, focus)

    def keypress(self, size, key):
        return self.frame.keypress(size, key)

    def set_line_collection(self, line_collection):
        self.jump_stack = []
        self.line_collection = line_collection
        self.walker.lines = line_collection.lines
        self.walker.set_focus(0)
        lc, mc = len(line_collection.lines), line_collection.match_count
        self.header.set_text([
            ('key', 'F6'),
            ' Log lines: %d, matches: %s | ' % (lc, mc),
            ('key', 's'),
            '/',
            ('key', 'S'),
            ' toggle sip messages/ladders | ',
            ('key', 'n'),
            '/',
            ('key', 'N'),
            ' next/previous | ',
            ('key', 'f'),
            ' toggle filter | ',
            ('key', 'i'),
            '/',
            ('key', 'I'),
            ' isolate/un-isolate | ',
            ('key', 'enter'),
            '/',
            ('key', 'backspace'),
            ' jump/back | ',
            ('key', 'space'),
            ' expand/collapse',
        ])
        self.line_collection.set_filter(self.show_only_filtered)

    def help(self):
        if self.showing_help:
            self.refresh_log()
        else:
            lc = LineCollection({})
            for markup in HELP:
                lc.add(markup)
            self.set_line_collection(lc)
        self.showing_help = not self.showing_help

    @property
    def compiled_find(self):
        find_text = self.find['text']
        if find_text and len(find_text) > 2:
            try:
                find_text = re.compile(find_text)
            except Exception as e:
                log.debug('Invalid RE %r: %s', find_text, e)

        # noinspection PyDictCreation
        find_map = {self.find['ref']: 'find1'}
        # possibly override
        find_map[find_text] = {'style': 'find2', 'jump': True}
        return find_map

    def load_result(self, ref):
        self.isolate_filter = (None, None)
        self.find['ref'] = ref
        self.refresh_log()

    def toggle_filter(self):
        if not self.line_collection or self.listbox.get_focus()[0] is None:
            return
        self.jump_stack = []
        self.expansions = {}
        self.show_only_filtered = not self.show_only_filtered
        self.listbox.set_focus(0)
        self.line_collection.set_filter(self.show_only_filtered)
        self.listbox.set_focus(0)

    def toggle_sip(self):
        self.jump_stack = []
        self.expansions = {}
        self.show_sip_level = (self.show_sip_level + 1) % 3

    def jump(self, where):
        cur = self.listbox.get_focus()[1]
        if where == 'home':
            self.listbox.set_focus(0)
        elif where == 'end':
            self.listbox.set_focus(len(self.line_collection.lines) - 1)
        elif where == 'next':
            if self.show_only_filtered:
                return
            for line_no in self.line_collection.line_numbers_with_needle:
                pos = self.line_collection.line_number_map.get(line_no)  # + 1
                if pos > cur:
                    self.listbox.set_focus(pos)
                    break
        elif where == 'previous':
            if self.show_only_filtered:
                return
            collection = self.line_collection.line_numbers_with_needle
            for i in range(len(collection) - 1, -1, -1):
                line_no = collection[i]
                pos = self.line_collection.line_number_map.get(line_no)  # + 1
                if pos < cur:
                    self.listbox.set_focus(pos)
                    break
        elif where == -1:
            # Jump back from where we came
            if self.jump_stack:
                pos = self.jump_stack.pop()
                self.listbox.set_focus(pos)
        else:
            pos = self.line_collection.line_number_map.get(where)
            if pos and pos != cur:
                self.jump_stack.append(cur)
                self.listbox.set_focus(pos)

    def expand(self, tag):
        if self.show_ladder:
            return  # No effect when showing all ladders

        cur = self.listbox.get_focus()[1]

        ref_type, ref = ref_tag(tag)
        # Collapse
        if ref in self.expansions:
            old, markups = self.expansions[ref]
            self.line_collection.remove(old, len(markups))
            del self.expansions[ref]
            self.listbox.set_focus(cur)
            return

        # Expand
        markups = []
        if ref_type == 'call_id':
            dialog = self.parser.find_obj(ref_type, ref)
            markups = message_sequence_chart(dialog)
            markups = [[' ' * 9] + m for m in markups]  # indent
        elif ref_type == 'sip_ref':
            sip = self.parser.find_obj(ref_type, ref)
            instructions = sip_payload_instructions(sip)
            markups = [(s, m) for (_l, s, m) in instructions]
        elif ref_type == 'chan':
            channel = self.parser.find_obj(ref_type, ref)
            markups = dial_chart(channel)
            markups = [[' ' * 9] + m for m in markups]  # indent

        if markups:
            self.expansions[ref] = (cur + 1, markups)
            self.line_collection.insert(cur + 1, markups)
            self.listbox.set_focus(cur)

    def isolate(self, tag):
        ref_type, ref = ref_tag(tag)
        if ref_type and ref:
            self.line_no_before_isolate = self.listbox.get_focus()[1]
            self.isolate_filter = (ref_type, ref)
            self.refresh_log()
        else:
            self.isolate_filter = (None, None)
            self.refresh_log(focus_line=self.line_no_before_isolate)

    def refresh_log(self, focus_line=False):

        groups, objects = self.parser.get_linked_objects(
            self.find['ref'], self.isolate_filter)

        old_pos = self.listbox.get_focus()[1]

        warning_count = 0
        error_count = 0

        lc = LineCollection(self.compiled_find)
        if objects:

            # Prepare markup for "Overview" section

            lc.add([('section', 'Overview ')])  # must be a list
            for group in groups:
                tab, tab2 = '= ', '   '
                for line_no, what, obj in group.overview:
                    markup = obj
                    dialog = None
                    tag = None
                    if what == 'dialog':
                        sip = obj
                        dialog = sip.dialog
                        style = get_sip_style(sip)
                        if dialog:
                            dialog_status = dialog.dialog_status or ''
                            dialog_ack = dialog.dialog_ack or ''
                            dialog_bye = dialog.bye_addr or ''
                        else:
                            dialog_status = ''
                            dialog_ack = ''
                            dialog_bye = ''
                        markup = [
                            ('', ' '),
                            ('line-no', '%07d' % (line_no + 1)),
                            ('', ' '),
                            ('mute', '[%s] ' % sip.when),
                            (style, sip.request or sip.status or '?'),
                            ('', ' %s -> %s ' % (sip.from_num, sip.to_num)),
                            ('sip-status', '%s' % (dialog_status or ' ')),
                            ('', ' '),
                            ('sip-method', '%s' % (dialog_ack or ' ')),
                        ]
                        if dialog and dialog.timeout:
                            markup.extend([('', ' '),
                                           ('sip-timeout', 'TIMEOUT')])
                        if dialog_bye:
                            markup.extend([
                                ('', ' '),
                                ('sip-bye2', 'BYE'),
                                ('mute', ' from '),
                                ('mute', dialog_bye),
                            ])
                        markup.append(('sip-call-id', '  %s' % sip.call_id))
                        tag = {'call_id': sip.call_id}
                    elif what == 'channel':
                        channel = obj
                        markup = [('line-no', '%07d' % (line_no + 1)),
                                  ('', ' '), ('mute', '[%s] ' % channel.when),
                                  ('channel-name', channel.name)]
                        for phone in set(channel.extensions):
                            markup.append(('', ' '))
                            markup.append(('', phone))
                        if channel.clid_num:
                            markup.append(('channel-phone',
                                           ' (clid:%s)' % channel.clid_num))
                        for i, app in enumerate(channel.apps):
                            dial_style = get_dial_status_style(app.status)
                            markup.append(('mute', '; ' if i else ': '))
                            markup.append(('mute', '%s ' % app.app_name))
                            markup.append(('', app.data or ' '))
                            markup.append(('mute', ' '))
                            markup.append((dial_style, app.status))
                        tag = {'chan': channel.name}
                    elif what == 'astcall':
                        acall = obj
                        markup = [('line-no', '%07d' % (line_no + 1)),
                                  ('', ' '), ('mute', '[%s] ' % acall.when),
                                  ('acall-id', acall.acall_id)]
                        tag = {'acall_id': acall.acall_id}
                    lc.add(['%s%s%s ' % (tab, what, tab2), markup or '?'],
                           tag=tag)

                    if dialog and dialog.timeout:
                        timeout_line_no, timeout_when = dialog.timeout
                        markup = [('', ' '),
                                  ('line-no', '%07d' % (timeout_line_no + 1)),
                                  ('mute', ' [%s] ' % timeout_when),
                                  ('sip-timeout', 'TIMEOUT')]
                        lc.add(['%s%s%s ' % (tab, '      ', tab2), markup])

                    if dialog and self.show_ladder:
                        for markup in message_sequence_chart(dialog):
                            lc.add([' ' * 9] + markup)
                    tab, tab2 = '  - ', ' '
            lc.add('')

            # Prepare markup for "Log" section

            flat = objects.items()
            flat.sort()

            lc.add(('section', 'Log'))
            old_line_no = None
            for line_no, (style, obj) in flat:
                # Text is kept as bytes, convert to unicode only when displaying
                if isinstance(obj, _bytes3):
                    obj = obj.decode(self.encoding, errors='replace')
                if old_line_no is not None and old_line_no + 1 != line_no:
                    # If Missing single unimportant line, omit "..."
                    if not (style == 'sip' and old_line_no + 2 == line_no):
                        lc.add(('mute', '...'))
                old_line_no = line_no
                if style == 'sip':
                    if self.show_sip_level == 0:
                        continue
                    sip = obj
                    line_no = sip.line_no
                    tag = None
                    markup = [('sip-intro', '==== %s ' % sip.when),
                              ('elapsed', '(ela: %s) ' % sip.elapsed_sec)]
                    if self.show_sip_level == 1:
                        if sip.request:
                            markup.append((get_sip_style(sip), str(sip)))
                        else:
                            markup.append(('sip-status', str(sip)))
                        # Adding tag also allows message expansion
                        tag = {'sip_ref': sip.ref}
                    if sip.attempt_no:
                        markup.append(
                            ('sip-retransmit', 'ATTEMPT #%s' % sip.attempt_no))
                    markup.append(('', ' %s ' % sip.direction))
                    # markup.append(('sip-direction', ' '))
                    if sip.direction == 'IN':
                        markup.append(('sip-addr', '%s' % sip.recipient_addr))
                        markup.append(('', ' <- '))
                        markup.append(('sip-addr', '%s' % sip.sender_addr))
                    else:
                        markup.append(('sip-addr', '%s' % sip.sender_addr))
                        markup.append(('', ' -> '))
                        markup.append(('sip-addr', '%s' % sip.recipient_addr))
                    lc.add(markup, tag=tag)
                    if self.show_sip_level == 1:
                        continue
                    instructions = sip_payload_instructions(sip)
                    # We use line_no again on purpose
                    # noinspection PyAssignmentToLoopOrWithParameter
                    for line_no, sty2, markup in instructions:
                        lc.add((sty2, markup), line_no)
                elif style == 'channel':
                    if self.show_channel:
                        lc.add((style, obj), line_no, {
                            'Dial': 'asterisk-app',
                            'Queue': 'asterisk-app',
                        })
                elif self.show_verbose:
                    if b'WARNING' in obj:
                        lc.add(('warning', obj), line_no)
                        warning_count += 1
                    if b'ERROR' in obj:
                        lc.add(('error', obj), line_no)
                        error_count += 1
                    else:
                        lc.add((style, obj), line_no)
                old_line_no = line_no

        if warning_count:
            lc.lines[0][0].append(
                ('warning', ' Warnings: %d ' % warning_count))
        if error_count:
            lc.lines[0][0].append(('error', ' Errors: %d ' % error_count))

        self.set_line_collection(lc)

        if focus_line:
            focus_line = focus_line if isinstance(focus_line, int) else old_pos
            try:
                self.listbox.set_focus(focus_line, 'above')
            except IndexError:
                pass
Ejemplo n.º 5
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
Ejemplo n.º 6
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