[PATCH 2/3] Add TUI Eula spoke (#1000409)

Vratislav Podzimek vpodzime at redhat.com
Tue Oct 8 08:01:26 UTC 2013


On Mon, 2013-10-07 at 14:30 -0400, Samantha N. Bueno wrote:
> On Mon, Oct 07, 2013 at 05:16:46PM +0200, Vratislav Podzimek wrote:
> > 
> > Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
> > ---
> >  initial_setup/tui/hubs/initial_setup_hub.py |  2 +-
> >  initial_setup/tui/spokes/eula.py            | 87 +++++++++++++++++++++++++++++
> >  2 files changed, 88 insertions(+), 1 deletion(-)
> >  create mode 100644 initial_setup/tui/spokes/eula.py
> > 
> > diff --git a/initial_setup/tui/hubs/initial_setup_hub.py b/initial_setup/tui/hubs/initial_setup_hub.py
> > index 73f8269..bd214a6 100644
> > --- a/initial_setup/tui/hubs/initial_setup_hub.py
> > +++ b/initial_setup/tui/hubs/initial_setup_hub.py
> > @@ -13,7 +13,7 @@ _ = lambda x: gettext.ldgettext("initial-setup", x)
> >  N_ = lambda x: x
> >  
> >  class InitialSetupMainHub(TUIHub):
> > -    categories = ["password", "localization"]
> > +    categories = ["password", "localization", "system"]
> >  
> >      prod_title = product.product_title()
> >      if prod_title:
> > diff --git a/initial_setup/tui/spokes/eula.py b/initial_setup/tui/spokes/eula.py
> > new file mode 100644
> > index 0000000..56ee3fa
> > --- /dev/null
> > +++ b/initial_setup/tui/spokes/eula.py
> > @@ -0,0 +1,87 @@
> > +"""EULA TUI spoke for the Initial Setup"""
> > +
> > +import gettext
> > +
> > +from pyanaconda.ui.tui.spokes import NormalTUISpoke
> > +from pyanaconda.ui.tui.simpleline.widgets import TextWidget, CheckboxWidget
> > +from pyanaconda.ui.tui.simpleline.base import UIScreen
> > +from pyanaconda.ui.common import FirstbootOnlySpokeMixIn
> > +from pyanaconda.constants_text import INPUT_PROCESSED
> > +from initial_setup.product import get_license_file_name
> > +
> > +_ = lambda x: gettext.ldgettext("initial-setup", x)
> > +N_ = lambda x: x
> > +
> > +__all__ = ["EULAspoke"]
> > +
> > +class EULAspoke(FirstbootOnlySpokeMixIn, NormalTUISpoke):
> 
> Maybe you want to mark this spoke as mandatory?
> 
>     @property
>     def mandatory(self):
>         return True
Good point.

> 
> > +    title = _("License information")
> > +    category = "system"
> > +
> > +    def __init__(self, *args, **kwargs):
> > +        NormalTUISpoke.__init__(self, *args, **kwargs)
> > +
> > +        self._have_eula = True
> > +
> > +    def initialize(self):
> > +        NormalTUISpoke.initialize(self)
> > +
> > +        license_file = get_license_file_name()
> > +        if not license_file:
> > +            self._have_eula = False
> > +
> > +    def refresh(self, args=None):
> > +        NormalTUISpoke.refresh(self, args)
> > +
> > +        if self._have_eula:
> > +            self._window += [TextWidget("    1) %s" % _("Read the License Agreement")), ""]
> > +            self._window += [CheckboxWidget(title="2) %s" % _("I accept the license agreement."),
> > +                                            completed=self.data.eula.agreed), ""]
> > +        else:
> > +            self._window += [TextWidget(_("No license found. Please report this "
> > +                                          "at http://bugzilla.redhat.com")), ""]
> > +
> > +    @property
> > +    def completed(self):
> > +        return not self._have_eula or self.data.eula.agreed
> > +
> > +    @property
> > +    def status(self):
> > +        if not self._have_eula:
> > +            return _("No license found")
> > +
> > +        return _("License agreed") if self.data.eula.agreed else _("License not agreed")
> > +
> > +    def input(self, args, key):
> > +        try:
> > +            keyid = int(key)
> > +        except ValueError:
> > +            # only number choices are processed here
> > +            return key
> > +
> > +        if keyid == 1:
> > +            eula_screen = LicenseScreen(self._app)
> > +            self.app.switch_screen_with_return(eula_screen)
> > +            return INPUT_PROCESSED
> > +        elif keyid == 2:
> > +            self.data.eula.agreed = not self.data.eula.agreed
> > +            return INPUT_PROCESSED
> > +
> > +        return key
> > +
> > +class LicenseScreen(UIScreen):
> > +    # no title needed, we just want to show the license
> > +    title = ""
> > +
> > +    def __init__(self, app, screen_height=25):
> > +        UIScreen.__init__(self, app, screen_height)
> > +        license_file = get_license_file_name()
> > +        with open(license_file, "r") as fobj:
> > +            self._buf = u"".join(fobj.xreadlines())
> > +
> > +    def refresh(self, args=None):
> > +        self._window += [TextWidget(self._buf), ""]
> > +
> > +    def prompt(self, args=None):
> > +        self.close()
> > +        return None
> 
> return None is effectively the same as return INPUT_PROCESSED, so that
> seems like it would be a bit more consistent.
Well, I'm not sure about this. INPUT_PROCESSED is for the 'input' method
whereas I'm returning None from the 'prompt' method meaning that this
screen doesn't want to prompt user at all. Shall I add a constants for
this? I believe it is quite clear here: 
no prompt -> prompt() returns None.

> 
> The only other nitpicky thing is that I think it'd be nice to have
> docstrings, even though for a lot of these functions/properties it's
> obvious what their purpose is.
I've added some comments, but I don't think docstrings would be useful
here. Purpose and arguments of those methods/properties are quite
obvious, I think.

I'm sending a new version of the patches with all changes you and Martin
suggested. Thanks for that!

-- 
Vratislav Podzimek

Anaconda Rider | Red Hat, Inc. | Brno - Czech Republic



More information about the anaconda-patches mailing list