fix lint
This commit is contained in:
parent
293793fa49
commit
15a2c1867c
|
@ -83,8 +83,10 @@ def parse_options(argv):
|
|||
help=("Load snap details from examples/snaps instead of store. "
|
||||
"See examples/snaps/README.md for more."))
|
||||
parser.add_argument(
|
||||
'--snap-section', action='store', default='developers', # will change default to server when that exists
|
||||
help=("Show snaps from this section of the store in the snap list screen."))
|
||||
# will change default to server when that exists
|
||||
'--snap-section', action='store', default='developers',
|
||||
help=("Show snaps from this section of the store in the snap "
|
||||
"list screen."))
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
|
|
|
@ -134,7 +134,8 @@ class DownloadSnapTask(BackgroundTask):
|
|||
self.channel = channel
|
||||
|
||||
def start(self):
|
||||
self.controller._install_event_start(_("downloading {}").format(self.snap_name))
|
||||
self.controller._install_event_start(
|
||||
_("downloading {}").format(self.snap_name))
|
||||
os.mkdir(self.this_snap_download_dir)
|
||||
self.proc = utils.start_command(
|
||||
['snap', 'download', '--channel='+self.channel, self.snap_name],
|
||||
|
@ -144,13 +145,14 @@ class DownloadSnapTask(BackgroundTask):
|
|||
stdout, stderr = self.proc.communicate()
|
||||
if self.proc.returncode != 0:
|
||||
raise subprocess.CalledProcessError(
|
||||
self.proc.returncode, self.proc.args, output=stdout, stderr=stderr)
|
||||
self.proc.returncode, self.proc.args, output=stdout,
|
||||
stderr=stderr)
|
||||
|
||||
def end(self, observer, fut):
|
||||
self.controller._install_event_finish()
|
||||
try:
|
||||
fut.result()
|
||||
except:
|
||||
except BaseException:
|
||||
shutil.rmtree(self.this_snap_download_dir)
|
||||
raise
|
||||
else:
|
||||
|
@ -161,10 +163,14 @@ class UpdateSnapSeed(BackgroundTask):
|
|||
|
||||
def __init__(self, controller, root):
|
||||
self.controller = controller
|
||||
self.seed_yaml = os.path.join(root, "var/lib/snapd/seed/seed.yaml")
|
||||
self.tmp_dir = os.path.join(root, "var/lib/snapd/seed/tmp")
|
||||
self.snap_dir = os.path.join(root, "var/lib/snapd/seed/snaps")
|
||||
self.assertions_dir = os.path.join(root, "var/lib/snapd/seed/assertions")
|
||||
self.seed_yaml = os.path.join(
|
||||
root, "var/lib/snapd/seed/seed.yaml")
|
||||
self.tmp_dir = os.path.join(
|
||||
root, "var/lib/snapd/seed/tmp")
|
||||
self.snap_dir = os.path.join(
|
||||
root, "var/lib/snapd/seed/snaps")
|
||||
self.assertions_dir = os.path.join(
|
||||
root, "var/lib/snapd/seed/assertions")
|
||||
|
||||
def start(self):
|
||||
self.controller._install_event_start(_("updating snap seed"))
|
||||
|
@ -175,21 +181,28 @@ class UpdateSnapSeed(BackgroundTask):
|
|||
with open(self.seed_yaml) as fp:
|
||||
seed = yaml.safe_load(fp)
|
||||
|
||||
to_install = self.controller.base_model.snaplist.to_install
|
||||
for snap_name in os.listdir(self.tmp_dir):
|
||||
this_snap_download_dir = os.path.join(self.tmp_dir, snap_name)
|
||||
[snap_path] = glob.glob(os.path.join(this_snap_download_dir, "*.snap"))
|
||||
[assertion_path] = glob.glob(os.path.join(this_snap_download_dir, "*.assert"))
|
||||
[snap_path] = glob.glob(
|
||||
os.path.join(this_snap_download_dir, "*.snap"))
|
||||
[assertion_path] = glob.glob(
|
||||
os.path.join(this_snap_download_dir, "*.assert"))
|
||||
|
||||
snap_file = os.path.basename(snap_path)
|
||||
assertion_file = os.path.basename(assertion_path)
|
||||
os.rename(snap_path, os.path.join(self.snap_dir, snap_file))
|
||||
os.rename(assertion_path, os.path.join(self.assertions_dir, assertion_file))
|
||||
os.rename(
|
||||
snap_path,
|
||||
os.path.join(self.snap_dir, snap_file))
|
||||
os.rename(
|
||||
assertion_path,
|
||||
os.path.join(self.assertions_dir, assertion_file))
|
||||
|
||||
# If this directory is not empty, something very
|
||||
# unexpected has happened and we should fail.
|
||||
os.rmdir(this_snap_download_dir)
|
||||
|
||||
selection = self.controller.base_model.snaplist.to_install[snap_name]
|
||||
selection = to_install[snap_name]
|
||||
seedinfo = {
|
||||
'name': snap_name,
|
||||
'file': snap_file,
|
||||
|
@ -212,6 +225,39 @@ class UpdateSnapSeed(BackgroundTask):
|
|||
observer.task_succeeded()
|
||||
|
||||
|
||||
class SnapSeedTaskWatcher(TaskWatcher):
|
||||
def __init__(self, controller):
|
||||
self.controller = controller
|
||||
self.tasklist = []
|
||||
|
||||
def task_complete(self, stage):
|
||||
self.tasklist.pop(0)
|
||||
|
||||
def task_error(self, stage, info):
|
||||
if stage.startswith("download"):
|
||||
curtask = self.tasklist[0][1]
|
||||
explanation = None
|
||||
if isinstance(info, tuple):
|
||||
log.debug("xxx %s", info)
|
||||
if isinstance(info[1], subprocess.CalledProcessError):
|
||||
explanation = info[1].stderr.strip()
|
||||
else:
|
||||
explanation = "".join(traceback.format_exception(*info))
|
||||
self.controller.progress_view.ask_for_retry_snap(
|
||||
self, curtask.snap_name, explanation)
|
||||
return
|
||||
if isinstance(info, tuple):
|
||||
tb = traceback.format_exception(*info)
|
||||
self.controller.curtin_error("".join(tb))
|
||||
else:
|
||||
self.controller.curtin_error()
|
||||
|
||||
def tasks_finished(self):
|
||||
self.controller._install_event_finish()
|
||||
self.controller.loop.set_alarm_in(
|
||||
0.0, lambda loop, ud: self.controller.postinstall_complete())
|
||||
|
||||
|
||||
class InstallProgressController(BaseController):
|
||||
signals = [
|
||||
('installprogress:filesystem-config-done', 'filesystem_config_done'),
|
||||
|
@ -237,13 +283,15 @@ class InstallProgressController(BaseController):
|
|||
self.curtin_start_install()
|
||||
|
||||
def identity_config_done(self):
|
||||
if self.install_state == InstallState.DONE and self._snap_config_done:
|
||||
if self.install_state == InstallState.DONE and \
|
||||
self._snap_config_done:
|
||||
self.postinstall_configuration()
|
||||
else:
|
||||
self._identity_config_done = True
|
||||
|
||||
def snap_config_done(self):
|
||||
if self.install_state == InstallState.DONE and self._identity_config_done:
|
||||
if self.install_state == InstallState.DONE and \
|
||||
self._identity_config_done:
|
||||
self.postinstall_configuration()
|
||||
else:
|
||||
self._snap_config_done = True
|
||||
|
@ -295,23 +343,7 @@ class InstallProgressController(BaseController):
|
|||
if event_type not in ['start', 'finish']:
|
||||
return
|
||||
if event_type == 'start':
|
||||
<<<<<<< HEAD
|
||||
self._install_event_start(event.get("CURTIN_MESSAGE", "??"))
|
||||
||||||| merged common ancestors
|
||||
message = event.get("CURTIN_MESSAGE", "??")
|
||||
if not self.progress_view_showing is None:
|
||||
self.footer_description.set_text(message)
|
||||
self.progress_view.add_event(self._event_indent + message)
|
||||
self._event_indent += " "
|
||||
self.footer_spinner.start()
|
||||
=======
|
||||
message = event.get("CURTIN_MESSAGE", "??")
|
||||
if self.progress_view_showing is not None:
|
||||
self.footer_description.set_text(message)
|
||||
self.progress_view.add_event(self._event_indent + message)
|
||||
self._event_indent += " "
|
||||
self.footer_spinner.start()
|
||||
>>>>>>> master
|
||||
if event_type == 'finish':
|
||||
self._install_event_finish()
|
||||
|
||||
|
@ -417,54 +449,41 @@ class InstallProgressController(BaseController):
|
|||
self.copy_logs_to_target()
|
||||
|
||||
if self.base_model.snaplist.to_install:
|
||||
class watcher(TaskWatcher):
|
||||
def __init__(self, controller):
|
||||
self.controller = controller
|
||||
self.tasklist = []
|
||||
def task_complete(self, stage):
|
||||
self.tasklist.pop(0)
|
||||
def task_error(self, stage, info):
|
||||
if stage.startswith("download"):
|
||||
curtask = self.tasklist[0][1]
|
||||
explanation = None
|
||||
if isinstance(info, tuple):
|
||||
log.debug("xxx %s", info)
|
||||
if isinstance(info[1], subprocess.CalledProcessError):
|
||||
explanation = info[1].stderr.strip()
|
||||
else:
|
||||
explanation = "".join(traceback.format_exception(*info))
|
||||
self.controller.progress_view.ask_for_retry_snap(self, curtask.snap_name, explanation)
|
||||
return
|
||||
if isinstance(info, tuple):
|
||||
tb = traceback.format_exception(*info)
|
||||
self.controller.curtin_error("".join(tb))
|
||||
else:
|
||||
self.controller.curtin_error()
|
||||
def tasks_finished(self):
|
||||
self.controller._install_event_finish()
|
||||
self.controller.loop.set_alarm_in(0.0, lambda loop, ud:self.controller.postinstall_complete())
|
||||
w = watcher(self)
|
||||
w = SnapSeedTaskWatcher(self)
|
||||
if self.opts.dry_run:
|
||||
root = '.subiquity'
|
||||
shutil.rmtree(os.path.join(root, 'var/lib/snapd/seed'), ignore_errors=True)
|
||||
os.makedirs(os.path.join(root, 'var/lib/snapd/seed/snaps'))
|
||||
os.makedirs(os.path.join(root, 'var/lib/snapd/seed/assertions'))
|
||||
with open(os.path.join(root, 'var/lib/snapd/seed/seed.yaml'), 'w') as fp:
|
||||
fp.write("snaps:\n- name: core\n channel: stable\n file: core_XXXX.snap")
|
||||
shutil.rmtree(
|
||||
os.path.join(root, 'var/lib/snapd/seed'),
|
||||
ignore_errors=True)
|
||||
os.makedirs(
|
||||
os.path.join(root, 'var/lib/snapd/seed/snaps'))
|
||||
os.makedirs(
|
||||
os.path.join(root, 'var/lib/snapd/seed/assertions'))
|
||||
fake_seed = ("snaps:\n"
|
||||
"- name: core\n"
|
||||
" channel: stable\n"
|
||||
" file: core_XXXX.snap")
|
||||
seed_path = os.path.join(root, 'var/lib/snapd/seed/seed.yaml')
|
||||
with open(seed_path, 'w') as fp:
|
||||
fp.write(fake_seed)
|
||||
else:
|
||||
root = TARGET
|
||||
tmp_dir = os.path.join(root, 'var/lib/snapd/seed/tmp')
|
||||
os.mkdir(tmp_dir)
|
||||
w.tasklist.append(('drain', WaitForCurtinEventsTask(self)))
|
||||
for snap_name, selection in sorted(self.base_model.snaplist.to_install.items()):
|
||||
w.tasklist.append(("download " + snap_name, DownloadSnapTask(self, tmp_dir, snap_name, selection.channel)))
|
||||
for snap_name, selection in sorted(
|
||||
self.base_model.snaplist.to_install.items()):
|
||||
w.tasklist.append((
|
||||
"download " + snap_name,
|
||||
DownloadSnapTask(
|
||||
self, tmp_dir, snap_name, selection.channel)
|
||||
))
|
||||
w.tasklist.append(("snapseed", UpdateSnapSeed(self, root)))
|
||||
ts = TaskSequence(self.run_in_bg, w.tasklist, w)
|
||||
ts.run()
|
||||
else:
|
||||
self.postinstall_complete()
|
||||
|
||||
|
||||
def postinstall_complete(self):
|
||||
self.ui.set_header(_("Installation complete!"))
|
||||
self.progress_view.set_status(_("Finished install!"))
|
||||
|
|
|
@ -68,11 +68,12 @@ class SnapdSnapInfoLoader:
|
|||
|
||||
self.session = requests_unixsocket.Session()
|
||||
self.pending_info_snaps = []
|
||||
self.ongoing = {} # {snap:[callbacks]}
|
||||
self.ongoing = {} # {snap:[callbacks]}
|
||||
|
||||
def start(self):
|
||||
self.running = True
|
||||
log.debug("loading list of snaps")
|
||||
|
||||
def cb(snap_list):
|
||||
if not self.running:
|
||||
return
|
||||
|
@ -87,7 +88,8 @@ class SnapdSnapInfoLoader:
|
|||
self.running = False
|
||||
|
||||
def _bg_fetch_list(self):
|
||||
return self.session.get(self.url_base + 'section=' + self.store_section, timeout=60)
|
||||
return self.session.get(
|
||||
self.url_base + 'section=' + self.store_section, timeout=60)
|
||||
|
||||
def _fetched_list(self, fut):
|
||||
if not self.running:
|
||||
|
@ -139,7 +141,8 @@ class SnapdSnapInfoLoader:
|
|||
self._fetch_info_for_snap(snap, self._fetch_next_info)
|
||||
|
||||
def _bg_fetch_next_info(self, snap):
|
||||
return self.session.get(self.url_base + 'name=' + snap.name, timeout=60)
|
||||
return self.session.get(
|
||||
self.url_base + 'name=' + snap.name, timeout=60)
|
||||
|
||||
def _fetched_info(self, snap, fut):
|
||||
if not self.running:
|
||||
|
@ -184,9 +187,15 @@ class SnapListController(BaseController):
|
|||
if self.opts.snaps_from_examples:
|
||||
self.loader = SampleDataSnapInfoLoader(
|
||||
self.model,
|
||||
os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "examples", "snaps"))
|
||||
os.path.join(
|
||||
os.path.dirname(
|
||||
os.path.dirname(
|
||||
os.path.dirname(__file__))),
|
||||
"examples", "snaps"))
|
||||
else:
|
||||
self.loader = SnapdSnapInfoLoader(self.model, self.run_in_bg, self.snapd_socket_path, self.opts.snap_section)
|
||||
self.loader = SnapdSnapInfoLoader(
|
||||
self.model, self.run_in_bg, self.snapd_socket_path,
|
||||
self.opts.snap_section)
|
||||
self.loader.start()
|
||||
|
||||
def network_config_done(self, netplan_path):
|
||||
|
@ -197,8 +206,9 @@ class SnapListController(BaseController):
|
|||
if self.opts.dry_run:
|
||||
cmds = [['sleep', '0.5']]
|
||||
else:
|
||||
os.makedirs('/etc/systemd/system/snapd.service.d', exist_ok=True)
|
||||
with open('/etc/systemd/system/snapd.service.d/snap_proxy.conf', 'w') as fp:
|
||||
dropin_dir = '/etc/systemd/system/snapd.service.d'
|
||||
os.makedirs(dropin_dir, exist_ok=True)
|
||||
with open(os.path.join(dropin_dir, 'snap_proxy.conf'), 'w') as fp:
|
||||
fp.write(self.base_model.proxy.proxy_systemd_dropin())
|
||||
cmds = [
|
||||
['systemctl', 'daemon-reload'],
|
||||
|
|
|
@ -48,13 +48,14 @@ class SnapSelection:
|
|||
|
||||
risks = ["stable", "candidate", "beta", "edge"]
|
||||
|
||||
|
||||
class SnapListModel:
|
||||
"""The overall model for subiquity."""
|
||||
|
||||
def __init__(self):
|
||||
self._snap_info = []
|
||||
self._snaps_by_name = {}
|
||||
self.to_install = {} # snap_name -> SnapSelection
|
||||
self.to_install = {} # snap_name -> SnapSelection
|
||||
|
||||
def load_find_data(self, data):
|
||||
for s in data['result']:
|
||||
|
|
|
@ -37,24 +37,31 @@ class MyLineBox(LineBox):
|
|||
else:
|
||||
return ""
|
||||
|
||||
|
||||
class AskForRetryStretchy(Stretchy):
|
||||
def __init__(self, parent, watcher, snap_name, explanation):
|
||||
self.parent = parent
|
||||
self.watcher = watcher
|
||||
if explanation is None:
|
||||
widgets = [
|
||||
Text(_('Downloading the snap "{}" failed for an unknown reason.').format(snap_name)),
|
||||
Text(_('Downloading the snap "{}" failed for an unknown '
|
||||
'reason.').format(snap_name)),
|
||||
]
|
||||
stretchy_index = 0
|
||||
else:
|
||||
widgets = [
|
||||
Text(_('Downloading the snap "{}" failed with the following output:').format(snap_name)),
|
||||
Text(_('Downloading the snap "{}" failed with the following '
|
||||
'output:').format(snap_name)),
|
||||
Text(""),
|
||||
Text(explanation),
|
||||
]
|
||||
stretchy_index = 2
|
||||
retry = other_btn(label=_("Try again"), on_press=self.cont, user_arg=True)
|
||||
give_up = other_btn(label=_("Give up on this snap"), on_press=self.cont, user_arg=False)
|
||||
retry = other_btn(
|
||||
label=_("Try again"),
|
||||
on_press=self.cont, user_arg=True)
|
||||
give_up = other_btn(
|
||||
label=_("Give up on this snap"),
|
||||
on_press=self.cont, user_arg=False)
|
||||
widgets.extend([
|
||||
Text(""),
|
||||
Text(_("Would you like to try to download this snap again?")),
|
||||
|
@ -68,6 +75,7 @@ class AskForRetryStretchy(Stretchy):
|
|||
self.parent.remove_overlay()
|
||||
self.parent.controller.resume_snap_downloads(self.watcher, retry_cur)
|
||||
|
||||
|
||||
class ProgressView(BaseView):
|
||||
def __init__(self, controller):
|
||||
self.controller = controller
|
||||
|
@ -141,7 +149,8 @@ class ProgressView(BaseView):
|
|||
p.focus_position = 1
|
||||
|
||||
def ask_for_retry_snap(self, watcher, snap_name, explanation):
|
||||
self.show_stretchy_overlay(AskForRetryStretchy(self, watcher, snap_name, explanation))
|
||||
self.show_stretchy_overlay(
|
||||
AskForRetryStretchy(self, watcher, snap_name, explanation))
|
||||
|
||||
def reboot(self, btn):
|
||||
self.controller.reboot()
|
||||
|
|
|
@ -79,7 +79,7 @@ class SnapInfoView(Widget):
|
|||
self.needs_focus = True
|
||||
|
||||
channel_width = (max(len(csi.channel_name) for csi in snap.channels)
|
||||
+ StarRadioButton.reserve_columns + 1)
|
||||
+ 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)
|
||||
|
@ -108,13 +108,15 @@ class SnapInfoView(Widget):
|
|||
('pack', Text(notes)),
|
||||
], dividechars=1)))
|
||||
|
||||
self.lb_channels = Padding.center_79(NoTabCyclingListBox(self.channels))
|
||||
self.lb_channels = Padding.center_79(
|
||||
NoTabCyclingListBox(self.channels))
|
||||
|
||||
contents = [
|
||||
('pack', Text("")),
|
||||
('pack', Padding.center_79(Columns([
|
||||
Text(snap.name),
|
||||
('pack', Text("Publisher: {}".format(snap.publisher), align='right')),
|
||||
('pack', Text(
|
||||
"Publisher: {}".format(snap.publisher), align='right')),
|
||||
], dividechars=1))),
|
||||
('pack', Text("")),
|
||||
('pack', Padding.center_79(Text(snap.summary))),
|
||||
|
@ -123,7 +125,9 @@ class SnapInfoView(Widget):
|
|||
('pack', Text("")),
|
||||
('weight', 1, self.lb_channels),
|
||||
('pack', Text("")),
|
||||
('pack', button_pile([other_btn(label=_("Close"), on_press=self.close)])),
|
||||
('pack', button_pile([
|
||||
other_btn(label=_("Close"), on_press=self.close),
|
||||
])),
|
||||
('pack', Text("")),
|
||||
]
|
||||
self.description_index = contents.index(self.lb_description)
|
||||
|
@ -149,7 +153,8 @@ class SnapInfoView(Widget):
|
|||
if o == pack_option:
|
||||
rows_available -= w.rows((maxcol,), focus)
|
||||
|
||||
rows_wanted_description = Padding.center_79(self.description).rows((maxcol,), False)
|
||||
padded_description = Padding.center_79(self.description)
|
||||
rows_wanted_description = padded_description.rows((maxcol,), False)
|
||||
rows_wanted_channels = len(self.channels)
|
||||
|
||||
if rows_wanted_channels + rows_wanted_description <= rows_available:
|
||||
|
@ -161,7 +166,8 @@ class SnapInfoView(Widget):
|
|||
channel_rows = min(rows_wanted_channels, int(rows_available/3))
|
||||
description_rows = rows_available - channel_rows
|
||||
|
||||
self.pile.contents[self.description_index] = (self.lb_description, self.pile.options('given', description_rows))
|
||||
self.pile.contents[self.description_index] = (
|
||||
self.lb_description, self.pile.options('given', description_rows))
|
||||
if description_rows >= rows_wanted_description:
|
||||
self.lb_description.original_widget._selectable = False
|
||||
else:
|
||||
|
@ -188,7 +194,9 @@ class FetchingInfo(WidgetWrap):
|
|||
Pile([
|
||||
('pack', Text(' ' + text)),
|
||||
('pack', self.spinner),
|
||||
('pack', button_pile([cancel_btn(label=_("Cancel"), on_press=self.close)])),
|
||||
('pack', button_pile([
|
||||
cancel_btn(label=_("Cancel"), on_press=self.close),
|
||||
])),
|
||||
])))
|
||||
|
||||
def close(self, sender=None):
|
||||
|
@ -198,6 +206,7 @@ class FetchingInfo(WidgetWrap):
|
|||
self.spinner.stop()
|
||||
self.parent.remove_overlay()
|
||||
|
||||
|
||||
class FetchingFailed(WidgetWrap):
|
||||
|
||||
def __init__(self, row, snap):
|
||||
|
@ -233,7 +242,8 @@ class SnapListRow(WidgetWrap):
|
|||
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.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'),
|
||||
|
@ -248,23 +258,26 @@ class SnapListRow(WidgetWrap):
|
|||
def load_info(self):
|
||||
called = False
|
||||
fi = None
|
||||
|
||||
def callback():
|
||||
nonlocal called
|
||||
called = True
|
||||
if fi is not None:
|
||||
fi.close()
|
||||
if len(self.snap.channels) == 0: # or other indication of failure
|
||||
if len(self.snap.channels) == 0: # or other indication of failure
|
||||
ff = FetchingFailed(self, self.snap)
|
||||
self.parent.show_overlay(ff, width=ff.width)
|
||||
else:
|
||||
cur_channel = None
|
||||
cur_chan = None
|
||||
if self.snap.name in self.parent.to_install:
|
||||
cur_channel = self.parent.to_install[self.snap.name].channel
|
||||
self.parent._w = SnapInfoView(self.parent, self.snap, cur_channel)
|
||||
cur_chan = self.parent.to_install[self.snap.name].channel
|
||||
self.parent._w = SnapInfoView(self.parent, self.snap, cur_chan)
|
||||
self.parent.controller.get_snap_info(self.snap, callback)
|
||||
# If we didn't get callback synchronously, display a dialog while the info loads.
|
||||
# If we didn't get callback synchronously, display a dialog
|
||||
# while the info loads.
|
||||
if not called:
|
||||
fi = FetchingInfo(self.parent, self.snap, self.parent.controller.loop)
|
||||
fi = FetchingInfo(
|
||||
self.parent, self.snap, self.parent.controller.loop)
|
||||
self.parent.show_overlay(fi, width=fi.width)
|
||||
|
||||
def keypress(self, size, key):
|
||||
|
@ -288,6 +301,7 @@ class SnapListRow(WidgetWrap):
|
|||
else:
|
||||
return self.two_column.render(size, focus)
|
||||
|
||||
|
||||
class SnapListView(BaseView):
|
||||
|
||||
title = _("Featured Server Snaps")
|
||||
|
@ -295,12 +309,13 @@ class SnapListView(BaseView):
|
|||
def __init__(self, model, controller):
|
||||
self.model = model
|
||||
self.controller = controller
|
||||
self.to_install = {} # {snap_name: (channel, is_classic)}
|
||||
self.to_install = {} # {snap_name: (channel, is_classic)}
|
||||
self.load()
|
||||
|
||||
def load(self, sender=None):
|
||||
spinner = None
|
||||
called = False
|
||||
|
||||
def callback(snap_list):
|
||||
nonlocal called
|
||||
called = True
|
||||
|
|
Loading…
Reference in New Issue