From 5a380da9c7d19260ec8c033ae8b28b2f1c647d96 Mon Sep 17 00:00:00 2001 From: Nikos Skalkotos Date: Wed, 19 Jun 2013 16:38:25 +0300 Subject: [PATCH] Create a new cloud wizard page Make the cloud selection wizard page an instance of WizardMenuPage --- image_creator/dialog_util.py | 6 +- image_creator/dialog_wizard.py | 160 ++++++++++++++++++++++++++++------------ 2 files changed, 113 insertions(+), 53 deletions(-) diff --git a/image_creator/dialog_util.py b/image_creator/dialog_util.py index fdd0d51..ec5be5f 100644 --- a/image_creator/dialog_util.py +++ b/image_creator/dialog_util.py @@ -252,12 +252,10 @@ def edit_cloud(session, name): info = Kamaki.get_cloud_by_name(name) assert info, "Cloud: `%s' does not exist" % name - assert 'url' in info, "Cloud: `%s' does not have a url attr" % name - assert 'token' in info, "Cloud: `%s' does not have a token attr" % name description = info['description'] if 'description' in info else "" - url = info['url'] - token = info['token'] + url = info['url'] if 'url' in info else "" + token = info['token'] if 'token' in info else "" d = session['dialog'] diff --git a/image_creator/dialog_wizard.py b/image_creator/dialog_wizard.py index fb92f29..a21f2df 100644 --- a/image_creator/dialog_wizard.py +++ b/image_creator/dialog_wizard.py @@ -48,6 +48,7 @@ from image_creator.dialog_util import extract_image, update_background_title, \ add_cloud, edit_cloud PAGE_WIDTH = 70 +PAGE_HEIGHT = 10 class WizardExit(Exception): @@ -55,8 +56,8 @@ class WizardExit(Exception): pass -class WizardInvalidData(Exception): - """Exception triggered when the user provided data are invalid""" +class WizardReloadPage(Exception): + """Exception that reloads the last WizardPage""" pass @@ -85,7 +86,7 @@ class Wizard: idx += self.pages[idx].run(self.session, idx, len(self.pages)) except WizardExit: return False - except WizardInvalidData: + except WizardReloadPage: continue if idx >= len(self.pages): @@ -146,13 +147,13 @@ class WizardRadioListPage(WizardPage): w = session['wizard'] choices = [] - for i in range(len(self.choices)): - default = 1 if self.choices[i][0] == self.default else 0 - choices.append((self.choices[i][0], self.choices[i][1], default)) + for choice in self.choices(): + default = 1 if choice[0] == self.default else 0 + choices.append((choice[0], choice[1], default)) (code, answer) = d.radiolist( - self.message, height=10, width=PAGE_WIDTH, ok_label="Next", - cancel="Back", choices=choices, + self.message, width=PAGE_WIDTH, ok_label="Next", cancel="Back", + choices=choices, height=PAGE_HEIGHT, title="(%d/%d) %s" % (index + 1, total, self.title)) if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): @@ -182,7 +183,8 @@ class WizardInputPage(WizardPage): (code, answer) = d.inputbox( self.message, init=self.init, width=PAGE_WIDTH, ok_label="Next", - cancel="Back", title="(%d/%d) %s" % (index + 1, total, self.title)) + cancel="Back", height=PAGE_HEIGHT, + title="(%d/%d) %s" % (index + 1, total, self.title)) if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): return self.PREV @@ -195,45 +197,100 @@ class WizardInputPage(WizardPage): return self.NEXT +class WizardMenuPage(WizardPage): + """Represents a menu dialog in a wizard""" + def __init__(self, name, printable, message, choices, **kargs): + super(WizardMenuPage, self).__init__(**kargs) + self.name = name + self.printable = printable + self.message = message + self.info = "%s: " % self.printable + self.choices = choices + self.title = kargs['title'] if 'title' in kargs else '' + self.default = kargs['default'] if 'default' in kargs else "" + self.extra = kargs['extra'] if 'extra' in kargs else None + self.extra_label = \ + kargs['extra_label'] if 'extra_label' in kargs else 'Extra' + self.fallback = kargs['fallback'] if 'fallback' in kargs else None + + def run(self, session, index, total): + d = session['dialog'] + w = session['wizard'] + + extra_button = 1 if self.extra else 0 + + choices = self.choices() + + if len(choices) == 0: + assert self.fallback, "Zero choices and no fallback" + if self.fallback(): + raise WizardReloadPage + else: + return self.PREV + + default_item = self.default if self.default else choices[0][0] + + (code, choice) = d.menu( + self.message, width=PAGE_WIDTH, ok_label="Next", cancel="Back", + title="(%d/%d) %s" % (index + 1, total, self.title), + choices=choices, height=PAGE_HEIGHT, default_item=default_item, + extra_label=self.extra_label, extra_button=extra_button) + + if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): + return self.PREV + elif code == d.DIALOG_EXTRA: + self.extra() + raise WizardReloadPage + + self.default = choice + w[self.name] = self.validate(choice) + self.info = "%s: %s" % (self.printable, self.display(w[self.name])) + + return self.NEXT + + def start_wizard(session): """Run the image creation wizard""" - d = session['dialog'] - clouds = Kamaki.get_clouds() - if not len(clouds): - if not add_cloud(session): - return False - else: - while 1: - choices = [] - for (name, cloud) in clouds.items(): - descr = cloud['description'] if 'description' in cloud else '' - choices.append((name, descr)) - - (code, choice) = d.menu( - "In this menu you can select existing cloud account to use " - " or add new ones. Press