Exemple #1
0
class ProgressView(BaseView):
    def __init__(self, controller):
        self.controller = controller
        self.listwalker = SimpleFocusListWalker([])
        self.listbox = ListBox(self.listwalker)
        self.linebox = MyLineBox(self.listbox)
        body = [
            ('pack', Text("")),
            ('weight', 1, Padding.center_79(self.linebox)),
            ('pack', Text("")),
        ]
        self.pile = Pile(body)
        super().__init__(self.pile)

    def add_log_tail(self, text):
        at_end = len(
            self.listwalker) == 0 or self.listbox.focus_position == len(
                self.listwalker) - 1
        for line in text.splitlines():
            self.listwalker.append(Text(line))
        if at_end:
            self.listbox.set_focus(len(self.listwalker) - 1)
            self.listbox.set_focus_valign('bottom')

    def clear_log_tail(self):
        self.listwalker[:] = []

    def set_status(self, text):
        self.linebox.set_title(text)

    def show_complete(self, include_exit=False):
        buttons = [
            ok_btn(_("Reboot Now"), on_press=self.reboot),
        ]
        if include_exit:
            buttons.append(cancel_btn(_("Exit To Shell"), on_press=self.quit))
        buttons = button_pile(buttons)

        new_pile = Pile([
            ('pack', Text("")),
            buttons,
            ('pack', Text("")),
        ])
        self.pile.contents[-1] = (new_pile, self.pile.options('pack'))
        self.pile.focus_position = len(self.pile.contents) - 1

    def reboot(self, btn):
        self.controller.reboot()

    def quit(self, btn):
        self.controller.quit()
Exemple #2
0
class ProgressView(BaseView):
    def __init__(self, controller):
        self.controller = controller
        self.spinner = Spinner(controller.loop)

        self.event_listwalker = SimpleFocusListWalker([])
        self.event_listbox = ListBox(self.event_listwalker)
        self.event_linebox = MyLineBox(self.event_listbox)
        self.event_buttons = button_pile([other_btn("View full log", on_press=self.view_log)])
        event_body = [
            ('pack', Text("")),
            ('weight', 1, Padding.center_79(self.event_linebox)),
            ('pack', Text("")),
            ('pack', self.event_buttons),
            ('pack', Text("")),
        ]
        self.event_pile = Pile(event_body)

        self.log_listwalker = SimpleFocusListWalker([])
        self.log_listbox = ListBox(self.log_listwalker)
        log_linebox = MyLineBox(self.log_listbox, _("Full installer output"))
        log_body = [
            ('weight', 1, log_linebox),
            ('pack', button_pile([other_btn(_("Close"), on_press=self.close_log)])),
            ]
        self.log_pile = Pile(log_body)

        super().__init__(self.event_pile)

    def add_event(self, text):
        at_end = len(self.event_listwalker) == 0 or self.event_listbox.focus_position == len(self.event_listwalker) - 1
        if len(self.event_listwalker) > 0:
            self.event_listwalker[-1] = self.event_listwalker[-1][0]
        self.event_listwalker.append(Columns([('pack', Text(text)), ('pack', self.spinner)], dividechars=1))
        if at_end:
            self.event_listbox.set_focus(len(self.event_listwalker) - 1)
            self.event_listbox.set_focus_valign('bottom')

    def add_log_line(self, text):
        at_end = len(self.log_listwalker) == 0 or self.log_listbox.focus_position == len(self.log_listwalker) - 1
        self.log_listwalker.append(Text(text))
        if at_end:
            self.log_listbox.set_focus(len(self.log_listwalker) - 1)
            self.log_listbox.set_focus_valign('bottom')

    def set_status(self, text):
        self.event_linebox.set_title(text)

    def show_complete(self, include_exit=False):
        p = self.event_buttons.original_widget
        p.contents.append(
            (ok_btn(_("Reboot Now"), on_press=self.reboot), p.options('pack')))
        if include_exit:
            p.contents.append(
                (cancel_btn(_("Exit To Shell"), on_press=self.quit), p.options('pack')))

        w = 0
        for b, o in p.contents:
            w = max(len(b.base_widget.label), w)
        self.event_buttons.width = self.event_buttons.min_width = w + 4
        self.event_pile.focus_position = 3
        p.focus_position = 1

    def reboot(self, btn):
        self.controller.reboot()

    def quit(self, btn):
        self.controller.quit()

    def view_log(self, btn):
        self._w = self.log_pile

    def close_log(self, btn):
        self._w = self.event_pile
Exemple #3
0
class NetworkView(BaseView):
    def __init__(self, model, controller):
        self.model = model
        self.controller = controller
        self.items = []
        self.error = Text("", align='center')
        self.model_inputs = Pile(self._build_model_inputs())
        self.additional_options = Pile(self._build_additional_options())
        self.body = [
            Padding.center_79(self.model_inputs),
            Padding.line_break(""),
            Padding.center_79(self.additional_options),
            Padding.line_break(""),
            Padding.center_79(Color.info_error(self.error)),
            Padding.line_break(""),
            Padding.fixed_10(self._build_buttons()),
        ]
        # FIXME determine which UX widget should have focus
        self.lb = ListBox(self.body)
        self.lb.set_focus(4)  # _build_buttons
        super().__init__(self.lb)

    def _build_buttons(self):
        cancel = Color.button(cancel_btn(on_press=self.cancel))
        done = Color.button(done_btn(on_press=self.done))
        self.default_focus = done

        buttons = [done, cancel]
        return Pile(buttons, focus_item=done)

    def _build_model_inputs(self):
        netdevs = self.model.get_all_netdevs()
        ifname_width = 8  # default padding
        if netdevs:
            ifname_width += max(map(lambda dev: len(dev.name), netdevs))
            if ifname_width > 20:
                ifname_width = 20

        iface_menus = []

        # Display each interface -- name in first column, then configured IPs
        # in the second.
        log.debug('interfaces: {}'.format(netdevs))
        for dev in netdevs:
            col_1 = []
            col_2 = []

            col_1.append(
                Color.menu_button(
                    menu_btn(label=dev.name, on_press=self.on_net_dev_press)))

            if dev.type == 'wlan':
                col_2.extend(_build_wifi_info(dev))
            if len(dev.actual_ip_addresses) == 0 and dev.type == 'eth' and not dev.is_connected:
                col_2.append(Color.info_primary(Text("Not connected")))
            col_2.extend(_build_gateway_ip_info_for_version(dev, 4))
            col_2.extend(_build_gateway_ip_info_for_version(dev, 6))

            # Other device info (MAC, vendor/model, speed)
            template = ''
            if dev.hwaddr:
                template += '{} '.format(dev.hwaddr)
            if dev.is_bond_slave:
                template += '(Bonded) '
            if not dev.vendor.lower().startswith('unknown'):
                vendor = textwrap.wrap(dev.vendor, 15)[0]
                template += '{} '.format(vendor)
            if not dev.model.lower().startswith('unknown'):
                model = textwrap.wrap(dev.model, 20)[0]
                template += '{} '.format(model)
            if dev.speed:
                template += '({})'.format(dev.speed)

            col_2.append(Color.info_minor(Text(template)))
            iface_menus.append(Columns([(ifname_width, Pile(col_1)), Pile(col_2)], 2))

        return iface_menus

    def refresh_model_inputs(self):
        self.model_inputs.contents = [ (obj, ('pack', None)) for obj in self._build_model_inputs() ]
        self.additional_options.contents = [ (obj, ('pack', None)) for obj in self._build_additional_options() ]

    def _build_additional_options(self):
        labels = []
        netdevs = self.model.get_all_netdevs()

        # Display default route status
        if self.model.default_v4_gateway is not None:
            v4_route_source = "via " + self.model.default_v4_gateway

            default_v4_route_w = Color.info_minor(
                Text("  IPv4 default route " + v4_route_source + "."))
            labels.append(default_v4_route_w)

        if self.model.default_v6_gateway is not None:
            v6_route_source = "via " + self.model.default_v6_gateway

            default_v6_route_w = Color.info_minor(
                Text("  IPv6 default route " + v6_route_source + "."))
            labels.append(default_v6_route_w)

        max_btn_len = 0
        buttons = []
        for opt, sig in self.model.get_menu():
            if ':set-default-route' in sig:
                if len(netdevs) < 2:
                    log.debug('Skipping default route menu option'
                              ' (only one nic)')
                    continue
            if ':bond-interfaces' in sig:
                not_bonded = [dev for dev in netdevs if not dev.is_bonded]
                if len(not_bonded) < 2:
                    log.debug('Skipping bonding menu option'
                              ' (not enough available nics)')
                    continue

            if len(opt) > max_btn_len:
                max_btn_len = len(opt)

            buttons.append(
                Color.menu_button(
                    menu_btn(label=opt,
                             on_press=self.additional_menu_select,
                             user_data=sig)))

        from urwid import Padding
        buttons = [ Padding(button, align='left', width=max_btn_len + 6) for button in buttons ]
        return labels + buttons

    def additional_menu_select(self, result, sig):
        self.controller.signal.emit_signal(sig)

    def on_net_dev_press(self, result):
        log.debug("Selected network dev: {}".format(result.label))
        self.controller.network_configure_interface(result.label)

    def show_network_error(self, action, info=None):
        if action == 'generate':
            self.error.set_text("Network configuration failed: %r" % (info,))
        elif action == 'apply':
            self.error.set_text("Network configuration could not be applied; " + \
                                "please verify your settings.")
        elif action == 'timeout':
            self.error.set_text("Network configuration timed out; " + \
                                "please verify your settings.")
        elif action == 'canceled':
            self.error.set_text("Network configuration canceled.")
        else:
            self.error.set_text("An unexpected error has occurred; " + \
                                "please verify your settings.")

    def done(self, result):
        self.controller.network_finish(self.model.render())

    def cancel(self, button):
        self.controller.cancel()