def __init__(self, controller, systems): self.controller = controller heading_table = TablePile([ TableRow([ Color.info_minor(Text(header)) for header in ["LABEL", "MODEL", "PUBLISHER", ""] ]) ], spacing=2) trows = [] systems = sorted( systems, key=lambda s: (s.brand.display_name, s.model.display_name, s.current, s.label)) for s in systems: actions = [] log.debug('actions: %s', s.actions) for act in sorted(s.actions, key=by_preferred_action_type): actions.append( Action(label=act.title.capitalize(), value=act, enabled=True)) menu = ActionMenu(actions) connect_signal(menu, 'action', self._system_action, s) srow = make_action_menu_row([ Text(s.label), Text(s.model.display_name), Text(s.brand.display_name), Text("(installed)" if s.current else ""), menu, ], menu) trows.append(srow) systems_table = TablePile(trows, spacing=2) systems_table.bind(heading_table) rows = [ Pile([heading_table, systems_table]), ] buttons = [] if controller.model.current is not None: # back to options of current system buttons.append(back_btn("BACK", on_press=self.back)) super().__init__( controller.model.current, screen(rows=rows, buttons=button_pile(buttons), focus_buttons=False, excerpt=self.excerpt))
def __init__(self, app): rows = [] keys = GLOBAL_KEYS if app.opts.run_on_serial: keys += SERIAL_GLOBAL_HELP_KEYS for key, text in keys: rows.append(TableRow([Text(_(key)), Text(_(text))])) if app.opts.dry_run: dro = _('(dry-run only)') for key, text in DRY_RUN_KEYS: rows.append(TableRow([Text(_(key)), Text(_(text) + ' ' + dro)])) table = TablePile(rows, spacing=2, colspecs={1: ColSpec(can_shrink=True)}) widgets = [ Pile([ ('pack', Text(rewrap(GLOBAL_KEY_HELP))), ('pack', Text("")), ('pack', table), ]), Text(""), button_pile([close_btn(app, self)]), ] super().__init__(_("Shortcut Keys"), widgets, 0, 2)
def __init__(self, model, controller): self.model = model self.controller = controller self.dev_to_row = {} self.cur_netdevs = [] self.error = Text("", align='center') self.device_table = TablePile(self._build_model_inputs(), spacing=2, colspecs={ 0: ColSpec(rpad=1), 4: ColSpec(can_shrink=True, rpad=1), }) self._create_bond_btn = menu_btn(_("Create bond"), on_press=self._create_bond) bp = button_pile([self._create_bond_btn]) bp.align = 'left' self.listbox = ListBox([self.device_table] + [ bp, ]) self.bottom = Pile([ Text(""), self._build_buttons(), Text(""), ]) self.error_showing = False self.frame = Pile([('pack', Text("")), ('pack', Padding.center_79(Text(_(self.excerpt)))), ('pack', Text("")), Padding.center_90(self.listbox), ('pack', self.bottom)]) self.frame.set_focus(self.bottom) super().__init__(self.frame)
def __init__(self, app): self.app = app rows = [ TableRow([ Text(""), Text(_("DATE")), Text(_("KIND")), Text(_("STATUS")), Text(""), ]) ] self.report_to_row = {} self.app.error_reporter.load_reports() for report in self.app.error_reporter.reports: connect_signal(report, "changed", self._report_changed, report) r = self.report_to_row[report] = self.row_for_report(report) rows.append(r) self.table = TablePile(rows, colspecs={1: ColSpec(can_shrink=True)}) widgets = [ Text(_("Select an error report to view:")), Text(""), self.table, Text(""), button_pile([close_btn(self)]), ] super().__init__("", widgets, 2, 2)
def _build_table(self): widget = self.widget if self.field.takes_default_style: widget = Color.string_input(widget) self.caption_text = Text(self.field.caption) self.under_text = Text(self.help) if self.field.caption_first: self.caption_text.align = 'right' first_row = [self.caption_text, _Validator(self, widget)] else: first_row = [ _Validator( self, UrwidPadding(widget, align='right', width=widget_width(widget))), self.caption_text, ] self._rows = [ Toggleable(TableRow(row)) for row in [ first_row, [Text(""), self.under_text], ] ] self._table = TablePile(self._rows, spacing=2, colspecs=form_colspecs)
def __init__(self, parent, obj): self.parent = parent self.obj = obj lines = [ Text( _("Do you really want to delete the {desc} {label}?").format( desc=obj.desc(), label=obj.label)), Text(""), ] stretchy_index = 0 fs = obj.fs() if fs is not None: m = fs.mount() if m is not None: lines.append( Text( _("It is formatted as {fstype} and mounted at " "{path}").format(fstype=fs.fstype, path=m.path))) else: lines.append( Text( _("It is formatted as {fstype} and not mounted."). format(fstype=fs.fstype))) elif hasattr(obj, 'partitions') and len(obj.partitions()) > 0: n = len(obj.partitions()) if obj.type == "lvm_volgroup": if n == 1: things = _("logical volume") else: things = _("logical volumes") else: if n == 1: things = _("partition") else: things = _("partitions") lines.append( Text( _("It contains {n} {things}:").format(n=n, things=things))) lines.append(Text("")) stretchy_index = len(lines) rows = [] for p, cells in summarize_device(obj): if p not in [None, obj]: rows.append(TableRow(cells)) lines.append(TablePile(rows)) else: lines.append(Text(_("It is not formatted or mounted."))) delete_btn = danger_btn(label=_("Delete"), on_press=self.confirm) widgets = lines + [ Text(""), button_pile([ delete_btn, other_btn(label=_("Cancel"), on_press=self.cancel), ]), ] super().__init__("", widgets, stretchy_index, len(lines) + 1)
def __init__(self): self.table = TablePile([], spacing=1) self.device_to_checkbox = {} self.device_to_selector = {} self.devices = {} # {device:active|spare} self.all_rows = [] self.no_selector_rows = [] self.supports_spares = True super().__init__(self.table)
def __init__(self, controller, netdev_infos): self.controller = controller self.dev_name_to_table = {} self.cur_netdev_names = [] self.error = Text("", align='center') self.device_colspecs = { 0: ColSpec(rpad=1), 3: ColSpec(min_width=15), 4: ColSpec(can_shrink=True, rpad=1), } self.heading_table = TablePile([ TableRow([ Color.info_minor(Text(header)) for header in [ "", "NAME", "TYPE", "NOTES", "", ] ]) ], spacing=2, colspecs=self.device_colspecs) self.device_pile = Pile([self.heading_table]) for dev_info in netdev_infos: self.new_link(dev_info) self._create_bond_btn = menu_btn(_("Create bond"), on_press=self._create_bond) bp = button_pile([self._create_bond_btn]) bp.align = 'left' rows = [ self.device_pile, bp, ] self.buttons = button_pile([ done_btn("TBD", on_press=self.done), # See _route_watcher back_btn(_("Back"), on_press=self.cancel), ]) self.bottom = Pile([ ('pack', self.buttons), ]) self.error_showing = False super().__init__( screen(rows=rows, buttons=self.bottom, focus_buttons=True, excerpt=_(self.excerpt)))
def _create(self): # Create the widget for a nic. This consists of a Pile containing a # table, an info line and a blank line. The first row of the table is # the one that can be focused and has a menu for manipulating the nic, # the other rows summarize its address config. # [ name type notes ▸ ] \ # address info | <- table # more address info / # mac / vendor info / model info # <blank line> actions = [] for action in NetDevAction: meth = getattr(self.parent, '_action_' + action.name) opens_dialog = getattr(meth, 'opens_dialog', False) if action in self.dev_info.enabled_actions: actions.append( (action.str(), True, (action, meth), opens_dialog)) menu = ActionMenu(actions) connect_signal(menu, 'action', self.parent._action, self) trows = [ make_action_menu_row([ Text("["), Text(self.dev_info.name), Text(self.dev_info.type), Text(self._notes(), wrap='clip'), menu, Text("]"), ], menu) ] + self._address_rows() self.table = TablePile(trows, colspecs=self.parent.device_colspecs, spacing=2) self.table.bind(self.parent.heading_table) if self.dev_info.type == "vlan": info = _("VLAN {id} on interface {link}").format( id=self.dev_info.vlan.id, link=self.dev_info.vlan.link) elif self.dev_info.type == "bond": info = _("bond master for {interfaces}").format( interfaces=', '.join(self.dev_info.bond.interfaces)) else: info = " / ".join([ self.dev_info.hwaddr, self.dev_info.vendor, self.dev_info.model, ]) return Pile([ ('pack', self.table), ('pack', Color.info_minor(Text(" " + info))), ('pack', Text("")), ])
def _device_widget(self, dev, netdev_i=None): # Create the widget for a nic. This consists of a Pile containing a # table, an info line and a blank line. The first row of the table is # the one that can be focused and has a menu for manipulating the nic, # the other rows summarize its address config. # [ name type notes ▸ ] \ # address info | <- table # more address info / # mac / vendor info / model info # <blank line> if netdev_i is None: netdev_i = len(self.cur_netdevs) self.cur_netdevs[netdev_i:netdev_i] = [dev] actions = [] for action in NetDevAction: meth = getattr(self, '_action_' + action.name) opens_dialog = getattr(meth, 'opens_dialog', False) if dev.supports_action(action): actions.append( (_(action.value), True, (action, meth), opens_dialog)) menu = ActionMenu(actions) connect_signal(menu, 'action', self._action, dev) trows = [ make_action_menu_row([ Text("["), Text(dev.name), Text(dev.type), Text(self._notes_for_device(dev), wrap='clip'), menu, Text("]"), ], menu) ] + self._address_rows_for_device(dev) table = TablePile(trows, colspecs=self.device_colspecs, spacing=2) self.dev_to_table[dev] = table table.bind(self.heading_table) if dev.type == "vlan": info = _("VLAN {id} on interface {link}").format(**dev.config) elif dev.type == "bond": info = _("bond master for {interfaces}").format( interfaces=', '.join(dev.config['interfaces'])) else: info = " / ".join( [dev.info.hwaddr, dev.info.vendor, dev.info.model]) return Pile([ ('pack', table), ('pack', Color.info_minor(Text(" " + info))), ('pack', Text("")), ])
def __init__(self, parent): self.parent = parent self.table = TablePile([], spacing=2, colspecs={ 0: ColSpec(rpad=1), 1: ColSpec(can_shrink=True), 2: ColSpec(min_width=9), 4: ColSpec(rpad=1), 5: ColSpec(rpad=1), }) self._no_mounts_content = Color.info_minor( Text(_("No disks or partitions mounted."))) super().__init__(self.table)
def _build_model_inputs(self): self.heading_table = TablePile([ TableRow([ Color.info_minor(Text(header)) for header in [ "", "NAME", "TYPE", "NOTES", "", ] ]) ], spacing=2, colspecs=self.device_colspecs) rows = [self.heading_table] for dev in self.model.get_all_netdevs(): rows.append(self._device_widget(dev)) return rows
def show_apply_spinner(self): s = Spinner(self.controller.loop) s.start() c = TablePile([ TableRow([ Text(_("Applying changes")), s, ]), ], align='center') self.bottom.contents[0:0] = [ (c, self.bottom.options()), (Text(""), self.bottom.options()), ]
def ssh_help_texts(ssh_info): texts = [_(SSH_HELP_PROLOGUE), ""] if ssh_info is not None: if len(ssh_info.ips) > 1: texts.append(_(SSH_HELP_MULTIPLE_ADDRESSES)) texts.append("") for ip in ssh_info.ips: texts.append(Text( "{}@{}".format(ssh_info.username, ip), align='center')) else: texts.append(_(SSH_HELP_ONE_ADDRESSES).format( username=ssh_info.username, ip=str(ssh_info.ips[0]))) texts.append("") if ssh_info.authorized_key_fingerprints: if len(ssh_info.authorized_key_fingerprints) == 1: key = ssh_info.authorized_key_fingerprints[0] texts.append(Text(_(SSH_HELP_EPILOGUE_ONE_KEY).format( keytype=key.keytype, fingerprint=key.fingerprint))) else: texts.append(_(SSH_HELP_EPILOGUE_MULTIPLE_KEYS)) texts.append("") rows = [] for key in ssh_info.authorized_key_fingerprints: rows.append( TableRow([Text(key.keytype), Text(key.fingerprint)])) texts.append(TablePile(rows)) if ssh_info.password_kind == PasswordKind.KNOWN: texts.append("") texts.append(SSH_HELP_EPILOGUE_KNOWN_PASS_KEYS.format( password=ssh_info.password)) elif ssh_info.password_kind == PasswordKind.UNKNOWN: texts.append("") texts.append(SSH_HELP_EPILOGUE_UNKNOWN_PASS_KEYS) else: if ssh_info.password_kind == PasswordKind.KNOWN: texts.append(SSH_HELP_EPILOGUE_KNOWN_PASS_NO_KEYS.format( password=ssh_info.password)) elif ssh_info.password_kind == PasswordKind.UNKNOWN: texts.append(SSH_HELP_EPILOGUE_UNKNOWN_PASS_NO_KEYS) texts.append("") texts.append(Text(summarize_host_keys([ (key.keytype, key.fingerprint) for key in ssh_info.host_key_fingerprints ]))) else: texts.append("") texts.append(_(SSH_HELP_NO_ADDRESSES)) return texts
def __init__(self, parent): self.parent = parent self.table = TablePile( [], spacing=2, colspecs={ 0: ColSpec(rpad=2), 1: ColSpec(rpad=2), 2: ColSpec(rpad=2), 3: ColSpec(rpad=2), }) self._no_zdev_content = Color.info_minor( Text(_("No zdev devices found."))) super().__init__(self.table)
def __init__(self, parent, disk): self.parent = parent dinfo = disk.info_for_display() rows = [] for label, key in labels_keys: v = str(dinfo[key]) rows.append(TableRow([Text(label, align='right'), Text(v)])) widgets = [ TablePile(rows, colspecs={1: ColSpec(can_shrink=True)}), Text(""), button_pile([done_btn(_("Close"), on_press=self.close)]), ] title = _("Info for {}").format(disk.label) super().__init__(title, widgets, 0, 2)
def __init__(self, parent, show_available): self.parent = parent self.show_available = show_available self.table = TablePile([], spacing=2, colspecs={ 0: ColSpec(rpad=1), 2: ColSpec(can_shrink=True), 4: ColSpec(min_width=9), 5: ColSpec(rpad=1), }) if show_available: text = _("No available devices") else: text = _("No used devices") self._no_devices_content = Color.info_minor(Text(text)) super().__init__(self.table)
def __init__(self, parent): super().__init__(parent) options = [] tables = [] for disk in parent.model.all_disks(): for obj, cells in summarize_device(disk): table = TablePile([TableRow(cells)]) tables.append(table) options.append(Option((table, obj is disk, obj))) t0 = tables[0] for t in tables[1:]: t0.bind(t) self.disk.widget.options = options self.disk.widget.index = 0 connect_signal(self.use_lvm.widget, 'change', self._toggle) self.lvm_options.enabled = self.use_lvm.value
def _build_table(self): widget = self.widget if self.field.takes_default_style: widget = Color.string_input(widget) self.caption_text = Text(self.field.caption, align="right") self.under_text = Text(self.help) self._rows = [ Toggleable(TableRow(row)) for row in [ [self.caption_text, _Validator(self, widget)], [Text(""), self.under_text], ] ] self._table = TablePile(self._rows, spacing=2, colspecs=form_colspecs)
def _guidance(self): todos = [] if not self.model.is_root_mounted(): todos.append(_("Mount a filesystem at /")) if self.model.needs_bootloader_partition(): todos.append(_("Select a boot disk")) if not todos: return None rows = [ TableRow([ Text(_("To continue you need to:")), Text(todos[0]), ]), ] for todo in todos[1:]: rows.append(TableRow([Text(""), Text(todo)])) rows.append(TableRow([Text("")])) return TablePile(rows)
def __init__(self, app, parent): rows = [] for key, text in GLOBAL_KEYS: rows.append(TableRow([Text(_(key)), Text(_(text))])) if app.opts.dry_run: for key, text in DRY_RUN_KEYS: rows.append(TableRow([Text(_(key)), Text(_(text))])) table = TablePile( rows, spacing=2, colspecs={1: ColSpec(can_shrink=True)}) widgets = [ Pile([ ('pack', Text(rewrap(GLOBAL_KEY_HELP))), ('pack', Text("")), ('pack', table), ]), Text(""), button_pile([close_btn(parent)]), ] super().__init__(_("Shortcut Keys"), widgets, 0, 2)
def __init__(self, parent): super().__init__(parent) options = [] tables = [] initial = -1 for disk in parent.model.all_disks(): for obj, cells in summarize_device(disk): table = TablePile([TableRow(cells)]) tables.append(table) enabled = False if obj is disk and disk.size > 6 * (2**30): enabled = True if initial < 0: initial = len(options) options.append(Option((table, enabled, obj))) t0 = tables[0] for t in tables[1:]: t0.bind(t) self.disk.widget.options = options self.disk.widget.index = initial connect_signal(self.use_lvm.widget, 'change', self._toggle) self.lvm_options.enabled = self.use_lvm.value
def __init__(self, parent, show_available): self.parent = parent self.show_available = show_available self.table = TablePile( [], spacing=2, colspecs={ 0: ColSpec(rpad=1), 1: ColSpec(can_shrink=True), 2: ColSpec(min_width=9), 3: ColSpec(rpad=1), 4: ColSpec(rpad=1), }) if show_available: text = _("No available devices") else: text = _("No used devices") self._no_devices_content = Color.info_minor(Text(text)) super().__init__(self.table) self.refresh_model_inputs() # I don't really know why this is required: self.table._select_first_selectable()
def __init__(self, model, controller): self.model = model self.controller = controller self.dev_to_row = {} self.cur_netdevs = [] self.error = Text("", align='center') self.device_table = TablePile( self._build_model_inputs(), spacing=2, colspecs={ 0: ColSpec(rpad=1), 4: ColSpec(can_shrink=True, rpad=1), }) self._create_bond_btn = menu_btn( _("Create bond"), on_press=self._create_bond) bp = button_pile([self._create_bond_btn]) bp.align = 'left' rows = [ self.device_table, bp, ] buttons = button_pile([ done_btn(_("Done"), on_press=self.done), back_btn(_("Back"), on_press=self.cancel), ]) self.bottom = Pile([ ('pack', buttons), ]) self.error_showing = False super().__init__(screen( rows=rows, buttons=self.bottom, focus_buttons=True, excerpt=self.excerpt))
def _build_table(self): widget = self.widget if self.field.takes_default_style: widget = Color.string_input(widget) if self.help is not NO_HELP: self.under_text = Text(self.help) else: self.under_text = Text("") if self.field.caption is NO_CAPTION: first_row = [(2, _Validator(self, widget))] second_row = [(2, self.under_text)] else: self.caption_text = Text(_(self.field.caption)) if self.field.caption_first: self.caption_text.align = 'right' first_row = [self.caption_text, _Validator(self, widget)] else: first_row = [ _Validator( self, UrwidPadding(widget, align='right', width=widget_width(widget))), self.caption_text, ] second_row = [Text(""), self.under_text] rows = [first_row] if self.help is not NO_HELP: rows.append(second_row) self._rows = [Toggleable(TableRow(row)) for row in rows] self._table = TablePile(self._rows, spacing=2, colspecs=form_colspecs)
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)