def __init__(self, parent): self.parent = parent close = ActionBackButton("(close)") connect_signal(close, "click", self.close) group = [Color.menu_button(close)] width = 0 for i, option in enumerate(self.parent._options): if option.enabled: if isinstance(option.label, Widget): btn = option.label else: btn = Color.menu_button(ActionMenuButton(option.label)) width = max(width, len(btn.base_widget.label)) connect_signal(btn.base_widget, 'click', self.click, option.value) else: label = option.label if isinstance(label, Widget): label = label.base_widget.label width = max(width, len(label)) btn = Columns([ ('fixed', 1, Text("")), Text(label), ('fixed', 1, Text(">")), ], dividechars=1) btn = AttrWrap(btn, 'info_minor') group.append(btn) self.width = width super().__init__(LineBox(ListBox(group)))
def _build_iface_inputs(self): if len(self.dev.actual_ssids) > 0: networks_btn = Color.menu_button( menu_btn("Choose a visible network", on_press=self.show_ssid_list)) else: networks_btn = Color.info_minor( Columns([('fixed', 1, Text("")), Text("No visible networks"), ('fixed', 1, Text(">"))], dividechars=1)) if not self.dev.scan_state: scan_btn = Color.menu_button( menu_btn("Scan for networks", on_press=self.start_scan)) else: scan_btn = Color.info_minor( Columns([('fixed', 1, Text("")), Text("Scanning for networks"), ('fixed', 1, Text(">"))], dividechars=1)) col = [ Padding.center_79( Color.info_minor( Text( "Only open or WPA2/PSK networks are supported at this time." ))), Padding.line_break(""), self.ssid_row, Padding.fixed_30(networks_btn), Padding.fixed_30(scan_btn), self.psk_row, ] return col
def _build_default_routes(self): ''' iterate through interfaces collecting any uniq provider (aka, gateway) and associate the interface name with the gateway then generate a line per key in the gateway dict and display the keys. Upon selection of the gateway entry (ip) then we set model.set_default_gateway(ip) if manual is selected, then we update the second entry into a IPAddressEditor and accept the value, submitting it to the model. ''' providers = {} for iface in self.model.get_all_interfaces(): if self.family == netifaces.AF_INET: ip_providers = iface.ip4_providers elif self.family == netifaces.AF_INET6: ip_providers = iface.ip6_providers for provider in ip_providers: log.debug('ipv4 provider: {}'.format(provider)) gw = provider if gw in providers: providers[gw].append(iface.ifname) else: providers[gw] = [iface.ifname] log.debug('gateway providers: {}'.format(providers)) items = [] items.append( Padding.center_79( Color.menu_button(menu_btn(label="None", on_press=self.done), focus_map="menu_button focus"))) for (gw, ifaces) in providers.items(): if gw is None: continue items.append( Padding.center_79( Color.menu_button(menu_btn(label="{gw} ({ifaces})".format( gw=gw, ifaces=(",".join(ifaces))), on_press=self.done), focus_map="menu_button focus"))) items.append( Padding.center_79( Color.menu_button(menu_btn( label="Specify the default route manually", on_press=self.show_edit_default_route), focus_map="menu_button focus"))) return items
def show_disk_info_w(self): """ Runs hdparm against device and displays its output """ text = ("Show disk information") return Color.menu_button(menu_btn(label=text, on_press=self.show_disk_info), focus_map='menu_button focus')
def __init__(self, parent, snap, max_name_len, max_publisher_len): self.parent = parent self.snap = snap self.box = StarCheckBox(snap.name, on_state_change=self.state_change) self.name_and_publisher_width = ( max_name_len + self.box.reserve_columns + max_publisher_len + 2) self.two_column = Color.menu_button(Columns([ (max_name_len+self.box.reserve_columns, self.box), Text(snap.summary, wrap='clip'), ], dividechars=1)) self.three_column = Color.menu_button(Columns([ (max_name_len+4, self.box), (max_publisher_len, Text(snap.publisher)), Text(snap.summary, wrap='clip'), ], dividechars=1)) super().__init__(self.two_column)
def make_main_screen(self, snap_list): self.snap_boxes = {} body = [] for snap in snap_list: box = self.snap_boxes[snap.name] = SnapCheckBox(self, snap) row = [ box, Text(snap.publisher), Text(snap.summary, wrap='clip'), ] body.append(Color.menu_button(TableRow(row))) table = NoTabCyclingTableListBox(body, colspecs={ 1: ColSpec(omittable=True), 2: ColSpec(pack=False, min_width=40), }) ok = ok_btn(label=_("Done"), on_press=self.done) self._main_screen = screen( table, [ok], focus_buttons=False, excerpt=_( "These are popular snaps in server environments. Select or " "deselect with SPACE, press ENTER to see more details of the " "package, publisher and versions available."))
def __init__(self, parent, snap, cur_channel): self.parent = parent self.snap = snap self.channels = [] self.needs_focus = True channel_width = (max(len(csi.channel_name) for csi in snap.channels) + StarRadioButton.reserve_columns + 1) max_version = max(len(csi.version) for csi in snap.channels) max_revision = max(len(str(csi.revision)) for csi in snap.channels) + 2 max_size = max(len(humanize_size(csi.size)) for csi in snap.channels) self.description = Text(snap.description.replace('\r', '').strip()) self.lb_description = ListBox([self.description]) radio_group = [] for csi in snap.channels: notes = '-' if csi.confinement != "strict": notes = csi.confinement btn = StarRadioButton(radio_group, "{}:".format(csi.channel_name), state=csi.channel_name == cur_channel, on_state_change=self.state_change, user_data=SnapSelection( channel=csi.channel_name, is_classic=csi.confinement == "classic")) self.channels.append( Color.menu_button( Columns([ (channel_width, btn), (max_version, Text(csi.version)), (max_revision, Text("({})".format(csi.revision))), (max_size, Text(humanize_size(csi.size))), ('pack', Text(notes)), ], dividechars=1))) self.lb_channels = NoTabCyclingListBox(self.channels) title = Columns([ Text(snap.name), ('pack', Text(_("Publisher: {}").format(snap.publisher), align='right')), ], dividechars=1) contents = [ ('pack', title), ('pack', Text("")), ('pack', Text(snap.summary)), ('pack', Text("")), self.lb_description, # overwritten in render() ('pack', Text("")), ('weight', 1, self.lb_channels), ] self.description_index = contents.index(self.lb_description) self.pile = Pile(contents) super().__init__(self.pile)
def _build_model_inputs(self): sl = [] for lang in self.model.get_menu(): sl.append( Color.menu_button(menu_btn(label=lang, on_press=self.confirm), focus_map="menu_button focus")) return BoxAdapter(SimpleList(sl), height=len(sl))
def _build_ipv6_method_buttons(self): button_padding = 70 buttons = [] btn = menu_btn(label="Use a static IPv6 configuration", on_press=self.show_ipv6_configuration) buttons.append(Color.menu_button(btn)) btn = menu_btn(label="Use DHCPv6 on this interface", on_press=self.enable_dhcp6) buttons.append(Color.menu_button(btn)) btn = menu_btn(label="Do not use", on_press=self.clear_ipv6) buttons.append(Color.menu_button(btn)) padding = getattr(Padding, 'left_{}'.format(button_padding)) buttons = [padding(button) for button in buttons] return buttons
def set_bound_form_field(self, bff): super().set_bound_form_field(bff) self.all_rows = [] for kind, device in bff.form.all_devices: if kind == LABEL: self.all_rows.append(TableRow([ Text(" " + device.label), Text(humanize_size(device.size), align='right') ])) self.no_selector_rows.append(self.all_rows[-1]) self.all_rows.append(TableRow([ (2, Color.info_minor(Text(" " + device.desc()))) ])) self.no_selector_rows.append(self.all_rows[-1]) else: if kind == DEVICE: label = device.label prefix = " " elif kind == PART: label = _(" partition {}").format(device._number) prefix = " " else: raise Exception("unexpected kind {}".format(kind)) box = CheckBox( label, on_state_change=self._state_change_device, user_data=device) self.device_to_checkbox[device] = box size = Text(humanize_size(device.size), align='right') self.all_rows.append(Color.menu_button(TableRow([box, size]))) self.no_selector_rows.append(self.all_rows[-1]) selector = Selector(['active', 'spare']) connect_signal( selector, 'select', self._select_active_spare, device) selector = Toggleable( UrwidPadding( Color.menu_button(selector), left=len(prefix))) selector.disable() self.device_to_selector[device] = selector self.all_rows.append(TableRow([(2, selector)])) # Do not append that one to no_selector_rows! self.all_rows.append(self._summarize(prefix, device)) self.no_selector_rows.append(self.all_rows[-1]) self.table.set_contents(self.all_rows) log.debug("%s", self.table._w.focus_position)
def _build_ipv4_method_buttons(self): dhcp4 = self.iface_obj.dhcp6 button_padding = 70 buttons = [] btn = menu_btn(label="Use a static IPv4 configuration", on_press=self.show_ipv4_configuration) buttons.append(Color.menu_button(btn, focus_map="menu_button focus")) btn = menu_btn(label="Use DHCPv4 on this interface", on_press=self.enable_dhcp4) buttons.append(Color.menu_button(btn, focus_map="menu_button focus")) btn = menu_btn(label="Do not use", on_press=self.clear_ipv4) buttons.append(Color.menu_button(btn, focus_map="menu_button focus")) padding = getattr(Padding, 'left_{}'.format(button_padding)) buttons = [padding(button) for button in buttons] return buttons
def _build_model_inputs(self): sl = [] for ipath, sig in self.model.get_menu(): log.debug("Building inputs: {}".format(ipath)) sl.append( Color.menu_button(menu_btn(label=ipath, on_press=self.confirm, user_data=sig), focus_map='menu_button focus')) return BoxAdapter(SimpleList(sl), height=len(sl))
def _build_menu(self): items = [] for label, sig in self.model.get_menu(): items.append( Columns([("weight", 0.2, Text("")), ("weight", 0.3, Color.menu_button( menu_btn(label=label, on_press=self.confirm, user_data=sig)))])) return Pile(items)
def _build_menu(self): log.debug('FileSystemView: building menu') opts = [] avail_disks = self.model.get_available_disk_names() for opt, sig in self.model.get_menu(): if len(avail_disks) > 1: opts.append( Color.menu_button(menu_btn(label=opt, on_press=self.on_fs_menu_press, user_data=sig), focus_map='menu_button focus')) return Pile(opts)
def create_swap_w(self): """ Handles presenting an enabled create swap on entire device button if no partition exists, otherwise it is disabled. """ text = ("Format or create swap on entire " "device (unusual, advanced)") if len(self.disk_obj.partitions) == 0 and \ self.disk_obj.available: return Color.menu_button(menu_btn(label=text, on_press=self.create_swap), focus_map='menu_button focus')
def __init__(self, parent, ssids): self.parent = parent button = cancel_btn(on_press=self.do_cancel) ssid_list = [ Color.menu_button(Button(label=ssid, on_press=self.do_network)) for ssid in ssids ] p = Pile([ BoxAdapter(ListBox(ssid_list), height=10), Padding.fixed_10(button) ]) box = LineBox(p, title="Select a network") super().__init__(box)
def add_partition_w(self): """ Handles presenting the add partition widget button depending on if partitions exist already or not. """ text = "Add first GPT partition" if len(self.disk_obj.partitions) > 0: text = "Add partition (max size {})".format( _humanize_size(self.disk_obj.freespace)) if self.disk_obj.available and \ self.disk_obj.blocktype not in self.model.no_partition_blocktypes: return Color.menu_button(menu_btn(label=text, on_press=self.add_partition), focus_map='menu_button focus')
def __init__(self, parent): self.parent = parent close_text = "(close)" close = ActionBackButton(close_text) connect_signal(close, "click", self.close) group = [Color.menu_button(close)] width = len(close_text) for i, action in enumerate(self.parent._actions): if action.enabled: if isinstance(action.label, Widget): btn = action.label elif action.opens_dialog: btn = Color.menu_button(ActionMenuOpenButton(action.label)) else: btn = Color.menu_button(ActionMenuButton(action.label)) width = max(width, len(btn.base_widget.label)) connect_signal(btn.base_widget, 'click', self.click, action.value) else: label = action.label if isinstance(label, Widget): label = label.base_widget.label width = max(width, len(label)) if action.opens_dialog: rhs = "\N{BLACK RIGHT-POINTING SMALL TRIANGLE}" else: rhs = "" btn = Columns([ ('fixed', 1, Text("")), Text(label), ('fixed', 1, Text(rhs)), ], dividechars=1) btn = AttrWrap(btn, 'info_minor') group.append(btn) self.width = width super().__init__(LineBox(ListBox(group)))
def _build_model_inputs(self): log.debug('FileSystemView: building model inputs') col_1 = [] col_2 = [] avail_disks = self.model.get_available_disk_names() if len(avail_disks) == 0: return Pile([Color.info_minor(Text("No available disks."))]) for dname in avail_disks: disk = self.model.get_disk_info(dname) device = self.model.get_disk(dname) btn = menu_btn(label=disk.name, on_press=self.show_disk_partition_view) col_1.append(Color.menu_button(btn, focus_map='menu_button focus')) disk_sz = _humanize_size(disk.size) log.debug('device partitions: {}'.format(len(device.partitions))) # if we've consumed some of the device, show # the remaining space and percentage of the whole if len(device.partitions) > 0: free, percent = self._get_percent_free(device) disk_sz = "{} ({}%) free".format(free, percent) col_2.append(Text(disk_sz)) for partname in device.available_partitions: part = device.get_partition(partname) btn = menu_btn(label=partname, on_press=self.show_disk_partition_view) col_1.append( Color.menu_button(btn, focus_map='menu_button focus')) col_2.append(Text(_humanize_size(part.size))) col_1 = BoxAdapter(SimpleList(col_1), height=len(col_1)) col_2 = BoxAdapter(SimpleList(col_2, is_selectable=False), height=len(col_2)) return Columns([(16, col_1), col_2], 2)
def _build_additional_options(self): labels = [] ifaces = self.model.get_all_interface_names() # 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(ifaces) < 2: log.debug('Skipping default route menu option' ' (only one nic)') continue if ':bond-interfaces' in sig: not_bonded = [iface for iface in ifaces if not self.model.iface_is_bonded(iface)] 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), focus_map='button focus')) padding = getattr(Padding, 'left_{}'.format(max_btn_len + 10)) buttons = [ padding(button) for button in buttons ] return Pile(labels + buttons)
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 _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 __init__(self, parent, snap, cur_channel): self.parent = parent self.snap = snap self.needs_focus = True self.description = Text(snap.description.replace('\r', '').strip()) self.lb_description = ListBox([self.description]) latest_update = datetime.datetime.min radio_group = [] channel_rows = [] for csi in snap.channels: latest_update = max(latest_update, csi.released_at) btn = StarRadioButton(radio_group, csi.channel_name, state=csi.channel_name == cur_channel, on_state_change=self.state_change, user_data=SnapSelection( channel=csi.channel_name, is_classic=csi.confinement == "classic")) channel_rows.append( Color.menu_button( TableRow([ btn, Text(csi.version), Text("(" + csi.revision + ")"), Text(humanize_size(csi.size)), Text(format_datetime(csi.released_at)), Text(csi.confinement), ]))) first_info_row = TableRow([ (3, Text([ ('info_minor', "LICENSE: "), snap.license, ], wrap='clip')), (3, Text([ ('info_minor', "LAST UPDATED: "), format_datetime(latest_update), ])), ]) heading_row = Color.info_minor( TableRow([ Text("CHANNEL"), (2, Text("VERSION")), Text("SIZE"), Text("PUBLISHED"), Text("CONFINEMENT"), ])) colspecs = { 1: ColSpec(can_shrink=True), } info_table = TablePile([ first_info_row, TableRow([Text("")]), heading_row, ], spacing=2, colspecs=colspecs) self.lb_channels = NoTabCyclingTableListBox(channel_rows, spacing=2, colspecs=colspecs) info_table.bind(self.lb_channels) self.info_padding = Padding.pull_1(info_table) publisher = [('info_minor header', "by: "), snap.publisher] if snap.verified: publisher.append(('verified header', ' \N{check mark}')) self.title = Columns([ Text(snap.name), ('pack', Text(publisher, align='right')), ], dividechars=1) contents = [ ('pack', Text(snap.summary)), ('pack', Text("")), self.lb_description, # overwritten in render() ('pack', Text("")), ('pack', self.info_padding), ('pack', Text("")), ('weight', 1, self.lb_channels), ] self.description_index = contents.index(self.lb_description) self.pile = Pile(contents) super().__init__(self.pile)
def row_for_report(self, report): return Color.menu_button( TableRow(self.cells_for_report(report)))
def _build_wifi_config(self): btn = menu_btn(label="Configure WIFI settings", on_press=self.show_wlan_configuration) return [Padding.left_70(Color.menu_button(btn))]