[PATCHv2] Read /etc/os-release to get product title (#1000426)

Martin Kolman mkolman at redhat.com
Thu Sep 5 10:56:56 UTC 2013


On Thu, 2013-09-05 at 11:42 +0200, Vratislav Podzimek wrote:
> The /etc/os-release file contains, among the other things, the release name that
> we want to display in the UI.
> 
> For GUI we can use just the product title because the string "INITIAL SETUP" is
> shown in the top-left corner. For TUI we should inform user that this is an
> initial setup of the system.
> 
> Also rename the hub files not to clash with the the Python package name.
> 
> Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
> ---
>  initial_setup/gui/gui.py                    | 13 +++---
>  initial_setup/gui/hubs/__init__.py          |  2 +-
>  initial_setup/gui/hubs/initial_setup.py     | 60 ----------------------------
>  initial_setup/gui/hubs/initial_setup_hub.py | 60 ++++++++++++++++++++++++++++
>  initial_setup/product.py                    | 34 ++++++++++++++++
>  initial_setup/tui/hubs/__init__.py          |  2 +-
>  initial_setup/tui/hubs/initial_setup.py     | 55 --------------------------
>  initial_setup/tui/hubs/initial_setup_hub.py | 61 +++++++++++++++++++++++++++++
>  initial_setup/tui/tui.py                    | 13 +++---
>  9 files changed, 167 insertions(+), 133 deletions(-)
>  delete mode 100644 initial_setup/gui/hubs/initial_setup.py
>  create mode 100644 initial_setup/gui/hubs/initial_setup_hub.py
>  create mode 100644 initial_setup/product.py
>  delete mode 100644 initial_setup/tui/hubs/initial_setup.py
>  create mode 100644 initial_setup/tui/hubs/initial_setup_hub.py
> 
> diff --git a/initial_setup/gui/gui.py b/initial_setup/gui/gui.py
> index 24e5a27..3afe5da 100644
> --- a/initial_setup/gui/gui.py
> +++ b/initial_setup/gui/gui.py
> @@ -1,5 +1,5 @@
>  from pyanaconda.ui.gui import QuitDialog, GUIObject, GraphicalUserInterface
> -#from .product import productName, productVersion
> +from initial_setup.product import product_title, is_final
>  from .hubs import InitialSetupMainHub
>  from pyanaconda.ui.gui.spokes import StandaloneSpoke
>  import pyanaconda.ui.gui.spokes
> @@ -13,27 +13,24 @@ from di import inject, usesclassinject
>  _ = lambda t: t
>  N_ = lambda t: t
>  
> -productTitle = lambda: "Initial Setup of Fedora"
> -isFinal = lambda: False
> -
>  class InitialSetupQuitDialog(QuitDialog):
>      MESSAGE = N_("Are you sure you want to quit the configuration process?\n"
>                   "You might end up with unusable system if you do.")
>  
> - at inject(Gdk, productTitle = productTitle, isFinal = isFinal)
> + at inject(Gdk, product_title = product_title, is_final = is_final)
>  class InitialSetupGraphicalUserInterface(GraphicalUserInterface):
>      """This is the main Gtk based firstboot interface. It inherits from
>         anaconda to make the look & feel as similar as possible.
>      """
>  
>      screenshots_directory = "/tmp/initial-setup-screenshots"
> -    
> +
>      @usesclassinject
>      def __init__(self, storage, payload, instclass):
>          GraphicalUserInterface.__init__(self, storage, payload, instclass,
> -                                        productTitle, isFinal,
> +                                        product_title, is_final,
>                                          quitDialog = InitialSetupQuitDialog)
> -        
> +
>      def _list_hubs(self):
>          return [InitialSetupMainHub]
>  
> diff --git a/initial_setup/gui/hubs/__init__.py b/initial_setup/gui/hubs/__init__.py
> index 5d166d6..39d8b13 100644
> --- a/initial_setup/gui/hubs/__init__.py
> +++ b/initial_setup/gui/hubs/__init__.py
> @@ -1 +1 @@
> -from .initial_setup import InitialSetupMainHub
> +from .initial_setup_hub import InitialSetupMainHub
> diff --git a/initial_setup/gui/hubs/initial_setup.py b/initial_setup/gui/hubs/initial_setup.py
> deleted file mode 100644
> index f966782..0000000
> --- a/initial_setup/gui/hubs/initial_setup.py
> +++ /dev/null
> @@ -1,60 +0,0 @@
> -from pyanaconda.ui.gui.hubs import Hub
> -from pyanaconda.ui.gui.spokes import Spoke
> -from pyanaconda.ui.common import collect
> -import os
> -
> -__all__ = ["InitialSetupMainHub"]
> -
> -def collect_spokes(mask_paths):
> -    """Return a list of all spoke subclasses that should appear for a given
> -       category. Look for them in files imported as module_path % basename(f)
> -
> -       :param mask_paths: list of mask, path tuples to search for classes
> -       :type mask_paths: list of (mask, path)
> -
> -       :return: list of Spoke classes belonging to category
> -       :rtype: list of Spoke classes
> -
> -    """
> -    spokes = []
> -    for mask, path in mask_paths:
> -        spokes.extend(collect(mask, path,
> -                              lambda obj: issubclass(obj, Spoke) and obj.should_run("firstboot", None)))
> -
> -    print spokes
> -    return spokes
> -
> -
> -class InitialSetupMainHub(Hub):
> -    uiFile = "initial_setup.glade"
> -    builderObjects = ["summaryWindow"]
> -    mainWidgetName = "summaryWindow"
> -    
> -    def _collectCategoriesAndSpokes(self):
> -        """collects categories and spokes to be displayed on this Hub
> -
> -           :return: dictionary mapping category class to list of spoke classes
> -           :rtype: dictionary[category class] -> [ list of spoke classes ]
> -        """
> -
> -        ret = {}
> -
> -        # Collect all the categories this hub displays, then collect all the
> -        # spokes belonging to all those categories.
> -        candidate_spokes = collect_spokes(self.paths["spokes"])
> -        spokes = [spoke for spoke in candidate_spokes \
> -                        if spoke.should_run("firstboot", self.data)]
> -
> -        for spoke in spokes:
> -            ret.setdefault(spoke.category, [])
> -            ret[spoke.category].append(spoke)
> -
> -        return ret
> -
> -    @property
> -    def continueButton(self):
> -        return self.builder.get_object("continueButton")
> -
> -    @property
> -    def quitButton(self):
> -        return self.builder.get_object("quitButton")
> diff --git a/initial_setup/gui/hubs/initial_setup_hub.py b/initial_setup/gui/hubs/initial_setup_hub.py
> new file mode 100644
> index 0000000..d0ac15b
> --- /dev/null
> +++ b/initial_setup/gui/hubs/initial_setup_hub.py
> @@ -0,0 +1,60 @@
> +from pyanaconda.ui.gui.hubs import Hub
> +from pyanaconda.ui.gui.spokes import Spoke
> +from pyanaconda.ui.common import collect
> +import os
> +
> +__all__ = ["InitialSetupMainHub"]
> +
> +def collect_spokes(mask_paths):
> +    """Return a list of all spoke subclasses that should appear for a given
> +       category. Look for them in files imported as module_path % basename(f)
> +
> +       :param mask_paths: list of mask, path tuples to search for classes
> +       :type mask_paths: list of (mask, path)
> +
> +       :return: list of Spoke classes belonging to category
> +       :rtype: list of Spoke classes
> +
> +    """
> +    spokes = []
> +    for mask, path in mask_paths:
> +        spokes.extend(collect(mask, path,
> +                              lambda obj: issubclass(obj, Spoke) and obj.should_run("firstboot", None)))
> +
> +    print spokes
> +    return spokes
> +
> +
> +class InitialSetupMainHub(Hub):
> +    uiFile = "initial_setup.glade"
> +    builderObjects = ["summaryWindow"]
> +    mainWidgetName = "summaryWindow"
> +
> +    def _collectCategoriesAndSpokes(self):
> +        """collects categories and spokes to be displayed on this Hub
> +
> +           :return: dictionary mapping category class to list of spoke classes
> +           :rtype: dictionary[category class] -> [ list of spoke classes ]
> +        """
> +
> +        ret = {}
> +
> +        # Collect all the categories this hub displays, then collect all the
> +        # spokes belonging to all those categories.
> +        candidate_spokes = collect_spokes(self.paths["spokes"])
> +        spokes = [spoke for spoke in candidate_spokes \
> +                        if spoke.should_run("firstboot", self.data)]
> +
> +        for spoke in spokes:
> +            ret.setdefault(spoke.category, [])
> +            ret[spoke.category].append(spoke)
> +
> +        return ret
> +
> +    @property
> +    def continueButton(self):
> +        return self.builder.get_object("continueButton")
> +
> +    @property
> +    def quitButton(self):
> +        return self.builder.get_object("quitButton")
> diff --git a/initial_setup/product.py b/initial_setup/product.py
> new file mode 100644
> index 0000000..9a18c59
> --- /dev/null
> +++ b/initial_setup/product.py
> @@ -0,0 +1,34 @@
> +"""Module providing information about the installed product."""
> +
> +RELEASE_STRING_FILE = "/etc/os-release"
> +
> +def product_title():
> +    """
> +    Get product title.
> +
> +    :return: product title
> +    :rtype: str
> +
> +    """
> +
> +    try:
> +        with open(RELEASE_STRING_FILE, "r") as fobj:
> +            for line in fobj:
> +                (key, _eq, value) = line.strip().partition("=")
> +                if not key or not _eq or not value:
> +                    continue
> +                if key == "PRETTY_NAME":
> +                    return value.strip('"')
> +    except IOError:
> +        return ""
> +
> +def is_final():
> +    """
> +    Whether it is a final release of the product or not.
> +
> +    :rtype: bool
> +
> +    """
> +
> +    # doesn't really matter for the Initial Setup
> +    return True
> diff --git a/initial_setup/tui/hubs/__init__.py b/initial_setup/tui/hubs/__init__.py
> index 5d166d6..39d8b13 100644
> --- a/initial_setup/tui/hubs/__init__.py
> +++ b/initial_setup/tui/hubs/__init__.py
> @@ -1 +1 @@
> -from .initial_setup import InitialSetupMainHub
> +from .initial_setup_hub import InitialSetupMainHub
> diff --git a/initial_setup/tui/hubs/initial_setup.py b/initial_setup/tui/hubs/initial_setup.py
> deleted file mode 100644
> index a8521ad..0000000
> --- a/initial_setup/tui/hubs/initial_setup.py
> +++ /dev/null
> @@ -1,55 +0,0 @@
> -from pyanaconda.ui.tui.hubs import TUIHub
> -from pyanaconda.ui.tui.spokes import TUISpoke
> -from pyanaconda.ui.common import collect
> -import os
> -
> -__all__ = ["InitialSetupMainHub"]
> -
> -# localization
> -_ = lambda t: t
> -N_ = lambda t: t
> -
> -def collect_spokes(mask_paths):
> -    """Return a list of all spoke subclasses that should appear for a given
> -       category. Look for them in files imported as module_path % basename(f)
> -
> -       :param mask_paths: list of mask, path tuples to search for classes
> -       :type mask_paths: list of (mask, path)
> -
> -       :return: list of Spoke classes belonging to category
> -       :rtype: list of Spoke classes
> -
> -    """
> -    spokes = []
> -    for mask, path in mask_paths:
> -        spokes.extend(collect(mask, path,
> -                              lambda obj: issubclass(obj, Spoke) and obj.should_run("firstboot", None)))
> -
> -    print spokes
> -    return spokes
> -
> -
> -class InitialSetupMainHub(TUIHub):
> -    categories = ["password", "localization"]
> -    title = _("Initial setup of Fedora")
> -    
> -    def _collectCategoriesAndSpokes(self):
> -        """collects categories and spokes to be displayed on this Hub
> -
> -           :return: dictionary mapping category class to list of spoke classes
> -           :rtype: dictionary[category class] -> [ list of spoke classes ]
> -        """
> -
> -        ret = {}
> -
> -        # Collect all the categories this hub displays, then collect all the
> -        # spokes belonging to all those categories.
> -        candidate_spokes = collect_spokes(self.paths["spokes"])
> -        spokes = [spoke for spoke in candidate_spokes \
> -                        if spoke.should_run("firstboot", self.data)]
> -
> -        for spoke in spokes:
> -            ret.setdefault(spoke.category, [])
> -            ret[spoke.category].append(spoke)
> -
> -        return ret
> diff --git a/initial_setup/tui/hubs/initial_setup_hub.py b/initial_setup/tui/hubs/initial_setup_hub.py
> new file mode 100644
> index 0000000..6316179
> --- /dev/null
> +++ b/initial_setup/tui/hubs/initial_setup_hub.py
> @@ -0,0 +1,61 @@
> +from pyanaconda.ui.tui.hubs import TUIHub
> +from pyanaconda.ui.tui.spokes import TUISpoke
> +from pyanaconda.ui.common import collect
> +from initial_setup import product
> +import os
> +
> +__all__ = ["InitialSetupMainHub"]
> +
> +# localization
> +_ = lambda t: t
> +N_ = lambda t: t
> +
> +def collect_spokes(mask_paths):
> +    """Return a list of all spoke subclasses that should appear for a given
> +       category. Look for them in files imported as module_path % basename(f)
> +
> +       :param mask_paths: list of mask, path tuples to search for classes
> +       :type mask_paths: list of (mask, path)
> +
> +       :return: list of Spoke classes belonging to category
> +       :rtype: list of Spoke classes
> +
> +    """
> +    spokes = []
> +    for mask, path in mask_paths:
> +        spokes.extend(collect(mask, path,
> +                              lambda obj: issubclass(obj, Spoke) and obj.should_run("firstboot", None)))
> +
> +    print spokes
> +    return spokes
> +
> +
> +class InitialSetupMainHub(TUIHub):
> +    categories = ["password", "localization"]
> +
> +    prod_title = product.product_title()
> +    if prod_title:
> +        title = _("Initial setup of %(product)s") % {"product": prod_title}
> +    else:
> +        title = _("Initial setup")
> +
> +    def _collectCategoriesAndSpokes(self):
> +        """collects categories and spokes to be displayed on this Hub
> +
> +           :return: dictionary mapping category class to list of spoke classes
> +           :rtype: dictionary[category class] -> [ list of spoke classes ]
> +        """
> +
> +        ret = {}
> +
> +        # Collect all the categories this hub displays, then collect all the
> +        # spokes belonging to all those categories.
> +        candidate_spokes = collect_spokes(self.paths["spokes"])
> +        spokes = [spoke for spoke in candidate_spokes \
> +                        if spoke.should_run("firstboot", self.data)]
> +
> +        for spoke in spokes:
> +            ret.setdefault(spoke.category, [])
> +            ret[spoke.category].append(spoke)
> +
> +        return ret
> diff --git a/initial_setup/tui/tui.py b/initial_setup/tui/tui.py
> index 14b5af2..05cbd2c 100644
> --- a/initial_setup/tui/tui.py
> +++ b/initial_setup/tui/tui.py
> @@ -1,5 +1,5 @@
>  from pyanaconda.ui.tui import TextUserInterface
> -#from .product import productName, productVersion
> +from initial_setup.product import product_title, is_final
>  from .hubs import InitialSetupMainHub
>  from pyanaconda.ui.tui.spokes import StandaloneSpoke
>  import pyanaconda.ui.tui.spokes
> @@ -12,25 +12,22 @@ from di import inject, usesclassinject
>  _ = lambda t: t
>  N_ = lambda t: t
>  
> -productTitle = lambda: "Initial Setup of Fedora"
> -isFinal = lambda: False
> -
>  QUIT_MESSAGE = N_("Are you sure you want to quit the configuration process?\n"
>                    "You might end up with unusable system if you do.")
>  
> - at inject(productTitle = productTitle, isFinal = isFinal)
> + at inject(product_title = product_title, is_final = is_final)
>  class InitialSetupTextUserInterface(TextUserInterface):
>      """This is the main text based firstboot interface. It inherits from
>         anaconda to make the look & feel as similar as possible.
>      """
>  
>      ENVIRONMENT = "firstboot"
> -    
> +
>      @usesclassinject
>      def __init__(self, storage, payload, instclass):
>          TextUserInterface.__init__(self, storage, payload, instclass,
> -                                         productTitle, isFinal, quitMessage = QUIT_MESSAGE)
> -        
> +                                         product_title, is_final, quitMessage = QUIT_MESSAGE)
> +
>      def _list_hubs(self):
>          return [InitialSetupMainHub]
>  
Looks fine, thanks!



More information about the anaconda-patches mailing list