[anaconda][PATCH 2/2] Update all of the relevant UI files with category changes.

Samantha N. Bueno sbueno+anaconda at redhat.com
Wed Sep 3 20:05:24 UTC 2014


This adds collect_spokes, collect_categories, and collectCategoriesAndSpokes
to pyanaconda.ui.common (rather than in each TUI and GUI file). This also
updates the relevant UI files to point to the right category path.

Resolves: rhbz#1128616
---
 pyanaconda/ui/common.py                    | 62 +++++++++++++++++++++++++++++-
 pyanaconda/ui/gui/__init__.py              | 10 ++---
 pyanaconda/ui/gui/hubs/__init__.py         | 21 +---------
 pyanaconda/ui/gui/spokes/__init__.py       | 21 +---------
 pyanaconda/ui/gui/spokes/custom.py         |  2 +-
 pyanaconda/ui/gui/spokes/datetime_spoke.py |  2 +-
 pyanaconda/ui/gui/spokes/filter.py         |  2 +-
 pyanaconda/ui/gui/spokes/keyboard.py       |  2 +-
 pyanaconda/ui/gui/spokes/langsupport.py    |  2 +-
 pyanaconda/ui/gui/spokes/network.py        |  2 +-
 pyanaconda/ui/gui/spokes/password.py       |  2 +-
 pyanaconda/ui/gui/spokes/software.py       |  2 +-
 pyanaconda/ui/gui/spokes/source.py         |  2 +-
 pyanaconda/ui/gui/spokes/storage.py        |  2 +-
 pyanaconda/ui/gui/spokes/user.py           |  2 +-
 pyanaconda/ui/gui/tools/run-spoke.py       |  2 +-
 pyanaconda/ui/tui/__init__.py              | 14 ++++---
 pyanaconda/ui/tui/hubs/__init__.py         | 27 ++++++-------
 pyanaconda/ui/tui/spokes/__init__.py       | 26 +------------
 pyanaconda/ui/tui/spokes/askvnc.py         |  2 -
 pyanaconda/ui/tui/spokes/network.py        |  3 +-
 pyanaconda/ui/tui/spokes/password.py       |  3 +-
 pyanaconda/ui/tui/spokes/shell_spoke.py    |  3 +-
 pyanaconda/ui/tui/spokes/software.py       |  3 +-
 pyanaconda/ui/tui/spokes/source.py         | 11 +++---
 pyanaconda/ui/tui/spokes/storage.py        |  7 ++--
 pyanaconda/ui/tui/spokes/time.py           |  3 +-
 pyanaconda/ui/tui/spokes/user.py           |  3 +-
 28 files changed, 125 insertions(+), 118 deletions(-)

diff --git a/pyanaconda/ui/common.py b/pyanaconda/ui/common.py
index 7568965..6e5da5d 100644
--- a/pyanaconda/ui/common.py
+++ b/pyanaconda/ui/common.py
@@ -28,7 +28,7 @@ import sys
 import types
 
 from pyanaconda.constants import ANACONDA_ENVIRON, FIRSTBOOT_ENVIRON
-from pykickstart.constants import FIRSTBOOT_RECONFIG
+from pykickstart.constants import FIRSTBOOT_RECONFIG, DISPLAY_MODE_TEXT
 
 import logging
 log = logging.getLogger("anaconda")
@@ -515,6 +515,13 @@ class Hub(UIObject):
         """Update the paths attribute with list of tuples in the form (module
            name format string, directory name)"""
         self.paths[path_id] = paths
+
+    def _collectCategoriesAndSpokes(self):
+        """This method is provided so that it can be overridden in a subclass
+            by a custom collect method.
+            One example of such usage is the Initial Setup application.
+        """
+        return collectCategoriesAndSpokes(self.paths, self.__class__, self.data.displaymode.displayMode)
         
 def collect(module_pattern, path, pred):
     """Traverse the directory (given by path), import all files as a module
@@ -648,3 +655,56 @@ def collect(module_pattern, path, pred):
 
     return retval
 
+def collect_spokes(mask_paths, category):
+    """ 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 o fmask, 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: hasattr(obj, "category") and obj.category is not None and obj.category.__name__ == category))
+
+    return spokes
+
+def collect_categories(mask_paths, displaymode):
+    """ Return a list of all category subclasses. Look for them in modules
+        imported as module_mask % basename(f) where f is name of all files in path.
+    """
+    categories = []
+    if displaymode == DISPLAY_MODE_TEXT:
+        for mask, path in mask_paths:
+            categories.extend(collect(mask, path, lambda obj: getattr(obj, "displayOnHubTUI", None) is not None))
+    else:
+        for mask, path in mask_paths:
+            categories.extend(collect(mask, path, lambda obj: getattr(obj, "displayOnHubGUI", None) is not None))
+
+    return categories
+
+def collectCategoriesAndSpokes(paths, klass, displaymode):
+    """collects categories and spokes to be displayed on this Hub
+
+       :param paths: dictionary mapping categories, spokes, and hubs to their
+        respective search path(s)
+       :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.
+    if displaymode == DISPLAY_MODE_TEXT:
+        categories = sorted(filter(lambda c: c.displayOnHubTUI == klass.__name__, collect_categories(paths["categories"], displaymode)),
+                            key = lambda c: c.sortOrder)
+    else:
+        categories = sorted(filter(lambda c: c.displayOnHubGUI == klass.__name__, collect_categories(paths["categories"], displaymode)),
+                            key=lambda c: c.sortOrder)
+    for c in categories:
+        ret[c] = collect_spokes(paths["spokes"], c.__name__)
+
+    return ret
diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py
index 2c387c4..351ed2e 100644
--- a/pyanaconda/ui/gui/__init__.py
+++ b/pyanaconda/ui/gui/__init__.py
@@ -262,10 +262,10 @@ class GraphicalUserInterface(UserInterface):
         self._mehInterface = GraphicalExceptionHandlingIface(
                                     self.lightbox_over_current_action)
 
-    basemask = "pyanaconda.ui.gui"
+    basemask = "pyanaconda.ui"
     basepath = os.path.dirname(__file__)
-    updatepath = "/tmp/updates/pyanaconda/ui/gui"
-    sitepackages = [os.path.join(dir, "pyanaconda", "ui", "gui")
+    updatepath = "/tmp/updates/pyanaconda/ui"
+    sitepackages = [os.path.join(dir, "pyanaconda", "ui")
                     for dir in site.getsitepackages()]
     pathlist = set([updatepath, basepath] + sitepackages)
 
@@ -273,10 +273,10 @@ class GraphicalUserInterface(UserInterface):
             "categories": [(basemask + ".categories.%s",
                         os.path.join(path, "categories"))
                         for path in pathlist],
-            "spokes": [(basemask + ".spokes.%s",
+            "spokes": [(basemask + ".gui.spokes.%s",
                         os.path.join(path, "spokes"))
                         for path in pathlist],
-            "hubs": [(basemask + ".hubs.%s",
+            "hubs": [(basemask + ".gui.hubs.%s",
                       os.path.join(path, "hubs"))
                       for path in pathlist]
             }
diff --git a/pyanaconda/ui/gui/hubs/__init__.py b/pyanaconda/ui/gui/hubs/__init__.py
index ce71929..8a3b220 100644
--- a/pyanaconda/ui/gui/hubs/__init__.py
+++ b/pyanaconda/ui/gui/hubs/__init__.py
@@ -30,8 +30,7 @@ from pyanaconda.product import distributionText
 
 from pyanaconda.ui import common
 from pyanaconda.ui.gui import GUIObject
-from pyanaconda.ui.gui.categories import collect_categories
-from pyanaconda.ui.gui.spokes import StandaloneSpoke, collect_spokes
+from pyanaconda.ui.gui.spokes import StandaloneSpoke
 from pyanaconda.ui.gui.utils import gtk_call_once, escape_markup
 from pyanaconda.constants import ANACONDA_ENVIRON
 
@@ -127,24 +126,6 @@ class Hub(GUIObject, common.Hub):
             action.execute()
             action._visitedSinceApplied = False
 
-    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.
-        categories = sorted(filter(lambda c: c.displayOnHub == self.__class__, collect_categories(self.paths["categories"])),
-                            key=lambda c: c.sortOrder)
-        for c in categories:
-            ret[c] = collect_spokes(self.paths["spokes"], c.__name__)
-
-        return ret
-
     def _createBox(self):
         from gi.repository import Gtk, AnacondaWidgets
         from pyanaconda.ui.gui.utils import setViewportBackground
diff --git a/pyanaconda/ui/gui/spokes/__init__.py b/pyanaconda/ui/gui/spokes/__init__.py
index 32a1469..75d8537 100644
--- a/pyanaconda/ui/gui/spokes/__init__.py
+++ b/pyanaconda/ui/gui/spokes/__init__.py
@@ -20,12 +20,10 @@
 #                    Martin Sivak <msivak at redhat.com>
 
 from pyanaconda.ui import common
-from pyanaconda.ui.common import collect
 from pyanaconda.ui.gui import GUIObject
 import os.path
 
-__all__ = ["StandaloneSpoke", "NormalSpoke", "PersonalizationSpoke",
-           "collect_spokes"]
+__all__ = ["StandaloneSpoke", "NormalSpoke", "PersonalizationSpoke"]
 
 class Spoke(GUIObject):
     def __init__(self, data):
@@ -98,20 +96,3 @@ class PersonalizationSpoke(Spoke, common.PersonalizationSpoke):
     def __init__(self, data, storage, payload, instclass):
         Spoke.__init__(self, data)
         common.PersonalizationSpoke.__init__(self, data, storage, payload, instclass)
-
-def collect_spokes(mask_paths, category):
-    """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: hasattr(obj, "category") and obj.category != None and obj.category.__name__ == category))
-        
-    return spokes
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index 8d4365b..c707522 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -79,7 +79,7 @@ from pyanaconda.ui.gui.spokes.lib.refresh import RefreshDialog
 from pyanaconda.ui.gui.spokes.lib.summary import ActionSummaryDialog
 from pyanaconda.ui.gui.utils import setViewportBackground, gtk_action_wait, enlightbox, fancy_set_sensitive, ignoreEscape,\
         really_hide, really_show, escape_markup
-from pyanaconda.ui.gui.categories.system import SystemCategory
+from pyanaconda.ui.categories.system import SystemCategory
 from pyanaconda.ui.lib.disks import size_str
 from pyanaconda.kickstart import refreshAutoSwapSize
 
diff --git a/pyanaconda/ui/gui/spokes/datetime_spoke.py b/pyanaconda/ui/gui/spokes/datetime_spoke.py
index bb33389..ed3e256 100644
--- a/pyanaconda/ui/gui/spokes/datetime_spoke.py
+++ b/pyanaconda/ui/gui/spokes/datetime_spoke.py
@@ -28,7 +28,7 @@ from pyanaconda.ui.communication import hubQ
 from pyanaconda.ui.common import FirstbootSpokeMixIn
 from pyanaconda.ui.gui import GUIObject
 from pyanaconda.ui.gui.spokes import NormalSpoke
-from pyanaconda.ui.gui.categories.localization import LocalizationCategory
+from pyanaconda.ui.categories.localization import LocalizationCategory
 from pyanaconda.ui.gui.utils import enlightbox, gtk_action_nowait, gtk_call_once
 from pyanaconda.ui.gui.utils import override_cell_property
 
diff --git a/pyanaconda/ui/gui/spokes/filter.py b/pyanaconda/ui/gui/spokes/filter.py
index 97b07ca..88afcc9 100644
--- a/pyanaconda/ui/gui/spokes/filter.py
+++ b/pyanaconda/ui/gui/spokes/filter.py
@@ -39,7 +39,7 @@ from pyanaconda.ui.gui.spokes.advstorage.fcoe import FCoEDialog
 from pyanaconda.ui.gui.spokes.advstorage.iscsi import ISCSIDialog
 from pyanaconda.ui.gui.spokes.advstorage.zfcp import ZFCPDialog
 from pyanaconda.ui.gui.spokes.lib.cart import SelectedDisksDialog
-from pyanaconda.ui.gui.categories.system import SystemCategory
+from pyanaconda.ui.categories.system import SystemCategory
 
 __all__ = ["FilterSpoke"]
 
diff --git a/pyanaconda/ui/gui/spokes/keyboard.py b/pyanaconda/ui/gui/spokes/keyboard.py
index 632d0fc..79bd652 100644
--- a/pyanaconda/ui/gui/spokes/keyboard.py
+++ b/pyanaconda/ui/gui/spokes/keyboard.py
@@ -24,7 +24,7 @@ from gi.repository import Gkbd, Gtk, Gdk
 
 from pyanaconda.ui.gui import GUIObject
 from pyanaconda.ui.gui.spokes import NormalSpoke
-from pyanaconda.ui.gui.categories.localization import LocalizationCategory
+from pyanaconda.ui.categories.localization import LocalizationCategory
 from pyanaconda.ui.gui.utils import enlightbox, gtk_call_once, escape_markup, override_cell_property
 from pyanaconda import keyboard
 from pyanaconda import flags
diff --git a/pyanaconda/ui/gui/spokes/langsupport.py b/pyanaconda/ui/gui/spokes/langsupport.py
index 0b3bb99..dfdf491 100644
--- a/pyanaconda/ui/gui/spokes/langsupport.py
+++ b/pyanaconda/ui/gui/spokes/langsupport.py
@@ -26,7 +26,7 @@ from pyanaconda.i18n import N_
 from pyanaconda.ui.gui.utils import escape_markup
 from pyanaconda.ui.gui.spokes import NormalSpoke
 from pyanaconda.ui.gui.spokes.lib.lang_locale_handler import LangLocaleHandler
-from pyanaconda.ui.gui.categories.localization import LocalizationCategory
+from pyanaconda.ui.categories.localization import LocalizationCategory
 from pyanaconda.ui.gui.utils import override_cell_property
 from pyanaconda import localization
 
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py
index 9163b6a..7d1adaf 100644
--- a/pyanaconda/ui/gui/spokes/network.py
+++ b/pyanaconda/ui/gui/spokes/network.py
@@ -37,7 +37,7 @@ from pyanaconda import constants
 from pyanaconda.ui.communication import hubQ
 from pyanaconda.ui.gui import GUIObject
 from pyanaconda.ui.gui.spokes import NormalSpoke, StandaloneSpoke
-from pyanaconda.ui.gui.categories.system import SystemCategory
+from pyanaconda.ui.categories.system import SystemCategory
 from pyanaconda.ui.gui.hubs.summary import SummaryHub
 from pyanaconda.ui.gui.utils import gtk_call_once, enlightbox, escape_markup
 from pyanaconda.ui.common import FirstbootSpokeMixIn
diff --git a/pyanaconda/ui/gui/spokes/password.py b/pyanaconda/ui/gui/spokes/password.py
index 6d0565a..df1132e 100644
--- a/pyanaconda/ui/gui/spokes/password.py
+++ b/pyanaconda/ui/gui/spokes/password.py
@@ -26,7 +26,7 @@ from pyanaconda.users import cryptPassword, validatePassword, checkPassword
 from pwquality import PWQError
 
 from pyanaconda.ui.gui.spokes import NormalSpoke
-from pyanaconda.ui.gui.categories.user_settings import UserSettingsCategory
+from pyanaconda.ui.categories.user_settings import UserSettingsCategory
 from pyanaconda.ui.common import FirstbootSpokeMixIn
 
 __all__ = ["PasswordSpoke"]
diff --git a/pyanaconda/ui/gui/spokes/software.py b/pyanaconda/ui/gui/spokes/software.py
index ff4346c..ec66c69 100644
--- a/pyanaconda/ui/gui/spokes/software.py
+++ b/pyanaconda/ui/gui/spokes/software.py
@@ -31,7 +31,7 @@ from pyanaconda.ui.communication import hubQ
 from pyanaconda.ui.gui.spokes import NormalSpoke
 from pyanaconda.ui.gui.spokes.lib.detailederror import DetailedErrorDialog
 from pyanaconda.ui.gui.utils import enlightbox, gtk_action_wait, escape_markup
-from pyanaconda.ui.gui.categories.software import SoftwareCategory
+from pyanaconda.ui.categories.software import SoftwareCategory
 
 import sys
 
diff --git a/pyanaconda/ui/gui/spokes/source.py b/pyanaconda/ui/gui/spokes/source.py
index d1ce6a1..00288c5 100644
--- a/pyanaconda/ui/gui/spokes/source.py
+++ b/pyanaconda/ui/gui/spokes/source.py
@@ -35,7 +35,7 @@ from pyanaconda.image import opticalInstallMedia, potentialHdisoSources
 from pyanaconda.ui.communication import hubQ
 from pyanaconda.ui.gui import GUIObject
 from pyanaconda.ui.gui.spokes import NormalSpoke
-from pyanaconda.ui.gui.categories.software import SoftwareCategory
+from pyanaconda.ui.categories.software import SoftwareCategory
 from pyanaconda.ui.gui.utils import enlightbox, gtk_action_wait
 from pyanaconda.iutil import ProxyString, ProxyStringError, cmp_obj_attrs
 from pyanaconda.ui.gui.utils import gtk_call_once, really_hide, really_show
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 0f0d2d2..a54de9e 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -50,7 +50,7 @@ from pyanaconda.ui.gui.spokes.lib.passphrase import PassphraseDialog
 from pyanaconda.ui.gui.spokes.lib.detailederror import DetailedErrorDialog
 from pyanaconda.ui.gui.spokes.lib.resize import ResizeDialog
 from pyanaconda.ui.gui.spokes.lib.dasdfmt import DasdFormatDialog
-from pyanaconda.ui.gui.categories.system import SystemCategory
+from pyanaconda.ui.categories.system import SystemCategory
 from pyanaconda.ui.gui.utils import enlightbox, gtk_action_nowait, ignoreEscape, escape_markup
 
 from pyanaconda.kickstart import doKickstartStorage, refreshAutoSwapSize
diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py
index 82fb22d..e3ea4a7 100644
--- a/pyanaconda/ui/gui/spokes/user.py
+++ b/pyanaconda/ui/gui/spokes/user.py
@@ -27,7 +27,7 @@ from pwquality import PWQError
 
 from pyanaconda.ui.gui.spokes import NormalSpoke
 from pyanaconda.ui.gui import GUIObject
-from pyanaconda.ui.gui.categories.user_settings import UserSettingsCategory
+from pyanaconda.ui.categories.user_settings import UserSettingsCategory
 from pyanaconda.ui.common import FirstbootSpokeMixIn
 from pyanaconda.ui.gui.utils import enlightbox
 
diff --git a/pyanaconda/ui/gui/tools/run-spoke.py b/pyanaconda/ui/gui/tools/run-spoke.py
index fb5fd1c..c57b51c 100755
--- a/pyanaconda/ui/gui/tools/run-spoke.py
+++ b/pyanaconda/ui/gui/tools/run-spoke.py
@@ -103,7 +103,7 @@ if hasattr(spoke, "register_event_cb"):
 
 if hasattr(spoke, "set_path"):
     spoke.set_path("categories", [
-        ("pyanaconda.ui.gui.categories.%s",
+        ("pyanaconda.ui.categories.%s",
          os.path.join(os.path.dirname(__file__),"..", "categories"))
          ])
     spoke.set_path("spokes", [
diff --git a/pyanaconda/ui/tui/__init__.py b/pyanaconda/ui/tui/__init__.py
index 0d31063..24898b3 100644
--- a/pyanaconda/ui/tui/__init__.py
+++ b/pyanaconda/ui/tui/__init__.py
@@ -100,18 +100,21 @@ class TextUserInterface(ui.UserInterface):
         self.isFinal = isFinal
         self.quitMessage = quitMessage
 
-    basemask = "pyanaconda.ui.tui"
+    basemask = "pyanaconda.ui"
     basepath = os.path.dirname(__file__)
-    updatepath = "/tmp/updates/pyanaconda/ui/tui"
-    sitepackages = [os.path.join(dir, "pyanaconda", "ui", "tui")
+    updatepath = "/tmp/updates/pyanaconda/ui"
+    sitepackages = [os.path.join(dir, "pyanaconda", "ui")
                     for dir in site.getsitepackages()]
     pathlist = set([updatepath, basepath] + sitepackages)
 
     paths = ui.UserInterface.paths + {
-            "spokes": [(basemask + ".spokes.%s",
+            "categories": [(basemask + ".categories.%s",
+                        os.path.join(path, "categories"))
+                        for path in pathlist],
+            "spokes": [(basemask + ".tui.spokes.%s",
                         os.path.join(path, "spokes"))
                         for path in pathlist],
-            "hubs": [(basemask + ".hubs.%s",
+            "hubs": [(basemask + ".tui.hubs.%s",
                       os.path.join(path, "hubs"))
                       for path in pathlist]
             }
@@ -165,6 +168,7 @@ class TextUserInterface(ui.UserInterface):
 
             if hasattr(obj, "set_path"):
                 obj.set_path("spokes", self.paths["spokes"])
+                obj.set_path("categories", self.paths["categories"])
 
             obj.setup(self.ENVIRONMENT)
 
diff --git a/pyanaconda/ui/tui/hubs/__init__.py b/pyanaconda/ui/tui/hubs/__init__.py
index 55a67d8..73d50ed 100644
--- a/pyanaconda/ui/tui/hubs/__init__.py
+++ b/pyanaconda/ui/tui/hubs/__init__.py
@@ -20,7 +20,6 @@
 #
 from .. import simpleline as tui
 from pyanaconda.ui.tui.tuiobject import TUIObject
-from pyanaconda.ui.tui.spokes import collect_spokes
 from pyanaconda.ui import common
 
 from pyanaconda.i18n import _, N_
@@ -50,31 +49,29 @@ class TUIHub(TUIObject, common.Hub):
         self._spoke_count = 0
 
     def setup(self, environment="anaconda"):
-        # look for spokes having category present in self.categories
-        for c in self.categories:
-            spokes = collect_spokes(self.paths["spokes"], c)
+        cats_and_spokes = self._collectCategoriesAndSpokes()
+        categories = cats_and_spokes.keys()
 
-            # sort them according to their priority
-            for s in sorted(spokes, key = lambda s: s.priority):
+        for c in sorted(categories, key=lambda c: c.title):
+            for spokeClass in sorted(cats_and_spokes[c], key=lambda s: s.title):
                 # Check if this spoke is to be shown in anaconda
-                if not s.should_run(environment, self.data):
+                if not spokeClass.should_run(environment, self.data):
                     continue
 
-                spoke = s(self.app, self.data, self.storage, self.payload, self.instclass)
+                spoke = spokeClass(self.app, self.data, self.storage, self.payload, self.instclass)
 
-                if not spoke.showable:
+                if spoke.showable:
+                    spoke.initialize()
+                else:
                     del spoke
                     continue
 
-                spoke.initialize()
-
-                if spoke.indirect:
-                    continue
-
                 self._spoke_count += 1
                 self._keys[self._spoke_count] = spoke
-                self._spokes[spoke.__class__.__name__] = spoke
+                self._spokes[spokeClass.__name__] = spoke
 
+        # only schedule the hub if it has some spokes
+        return self._spoke_count != 0
 
     def refresh(self, args = None):
         """This methods fills the self._window list by all the objects
diff --git a/pyanaconda/ui/tui/spokes/__init__.py b/pyanaconda/ui/tui/spokes/__init__.py
index 321e401..a516d52 100644
--- a/pyanaconda/ui/tui/spokes/__init__.py
+++ b/pyanaconda/ui/tui/spokes/__init__.py
@@ -28,8 +28,8 @@ from collections import namedtuple
 from pyanaconda.iutil import setdeepattr, getdeepattr
 from pyanaconda.i18n import N_, _
 
-__all__ = ["TUISpoke", "EditTUISpoke", "EditTUIDialog", "EditTUISpokeEntry", "StandaloneSpoke", "NormalSpoke", "PersonalizationSpoke",
-           "collect_spokes", "collect_categories"]
+__all__ = ["TUISpoke", "EditTUISpoke", "EditTUIDialog", "EditTUISpokeEntry",
+           "StandaloneSpoke", "NormalSpoke", "PersonalizationSpoke", ]
 
 # Inherit abstract methods from Spoke
 # pylint: disable-msg=W0223
@@ -40,13 +40,9 @@ class TUISpoke(TUIObject, tui.Widget, Spoke):
 
     :param title: title of this spoke
     :type title: unicode
-
-    :param category: category this spoke belongs to
-    :type category: string
     """
 
     title = N_("Default spoke title")
-    category = u""
 
     def __init__(self, app, data, storage, payload, instclass):
         TUIObject.__init__(self, app, data)
@@ -279,21 +275,3 @@ class StandaloneTUISpoke(TUISpoke, StandaloneSpoke):
 
 class PersonalizationTUISpoke(TUISpoke, PersonalizationSpoke):
     pass
-
-def collect_spokes(mask_paths, category):
-    """Return a list of all spoke subclasses that should appear for a given
-       category.
-    """
-    spokes = []
-    for mask, path in mask_paths:
-        spokes.extend(collect(mask, path, lambda obj: hasattr(obj, "category") and obj.category != None and obj.category == category))
-        
-    return spokes
-        
-def collect_categories(mask_paths):
-    classes = []
-    for mask, path in mask_paths:
-        classes.extend(collect(mask, path, lambda obj: hasattr(obj, "category") and obj.category != None and obj.category != ""))
-        
-    categories = set(c.category for c in classes)
-    return categories
diff --git a/pyanaconda/ui/tui/spokes/askvnc.py b/pyanaconda/ui/tui/spokes/askvnc.py
index 200a5a6..4837f58 100644
--- a/pyanaconda/ui/tui/spokes/askvnc.py
+++ b/pyanaconda/ui/tui/spokes/askvnc.py
@@ -27,7 +27,6 @@ import getpass
 
 class AskVNCSpoke(NormalTUISpoke):
     title = N_("VNC")
-    category = "vnc"
 
     # This spoke is kinda standalone, not meant to be used with a hub
     # We pass in some fake data just to make our parents happy
@@ -90,7 +89,6 @@ class AskVNCSpoke(NormalTUISpoke):
 
 class VNCPassSpoke(NormalTUISpoke):
     title = N_("VNC Password")
-    category = "vnc"
 
     def __init__(self, app, data, storage, payload, instclass, message=None):
         NormalTUISpoke.__init__(self, app, data, storage, payload, instclass)
diff --git a/pyanaconda/ui/tui/spokes/network.py b/pyanaconda/ui/tui/spokes/network.py
index 554e83e..e5277b8 100644
--- a/pyanaconda/ui/tui/spokes/network.py
+++ b/pyanaconda/ui/tui/spokes/network.py
@@ -22,6 +22,7 @@
 
 
 from pyanaconda.flags import can_touch_runtime_system
+from pyanaconda.ui.categories.system import SystemCategory
 from pyanaconda.ui.tui.spokes import EditTUISpoke, OneShotEditTUIDialog
 from pyanaconda.ui.tui.spokes import EditTUISpokeEntry as Entry
 from pyanaconda.ui.tui.simpleline import TextWidget, ColumnWidget
@@ -38,7 +39,7 @@ __all__ = ["NetworkSpoke"]
 class NetworkSpoke(EditTUISpoke):
     """ Spoke used to configure network settings. """
     title = N_("Network settings")
-    category = "system"
+    category = SystemCategory
 
     def __init__(self, app, data, storage, payload, instclass):
         EditTUISpoke.__init__(self, app, data, storage, payload, instclass)
diff --git a/pyanaconda/ui/tui/spokes/password.py b/pyanaconda/ui/tui/spokes/password.py
index e4d1624..94d3693 100644
--- a/pyanaconda/ui/tui/spokes/password.py
+++ b/pyanaconda/ui/tui/spokes/password.py
@@ -22,6 +22,7 @@
 #
 
 from pyanaconda.ui.tui.spokes import EditTUIDialog, EditTUISpokeEntry
+from pyanaconda.ui.categories.user_settings import UserSettingsCategory
 from pyanaconda.ui.common import FirstbootSpokeMixIn
 from pyanaconda.ui.tui.simpleline import TextWidget
 from pyanaconda.flags import flags
@@ -29,7 +30,7 @@ from pyanaconda.i18n import N_, _
 
 class PasswordSpoke(FirstbootSpokeMixIn, EditTUIDialog):
     title = N_("Set root password")
-    category = "password"
+    category = UserSettingsCategory
 
     def __init__(self, app, data, storage, payload, instclass):
         EditTUIDialog.__init__(self, app, data, storage, payload, instclass)
diff --git a/pyanaconda/ui/tui/spokes/shell_spoke.py b/pyanaconda/ui/tui/spokes/shell_spoke.py
index 4915f98..e0115ca 100644
--- a/pyanaconda/ui/tui/spokes/shell_spoke.py
+++ b/pyanaconda/ui/tui/spokes/shell_spoke.py
@@ -20,6 +20,7 @@
 
 """Text mode shell spoke"""
 
+from pyanaconda.ui.categories.system import SystemCategory
 from pyanaconda.ui.tui.spokes import NormalTUISpoke
 from pyanaconda.ui.tui.simpleline.widgets import TextWidget
 from pyanaconda.i18n import N_, _
@@ -31,7 +32,7 @@ import subprocess
 
 class ShellSpoke(NormalTUISpoke):
     title = N_("Shell")
-    category = "system"
+    category = SystemCategory
 
     @classmethod
     def should_run(cls, environment, data):
diff --git a/pyanaconda/ui/tui/spokes/software.py b/pyanaconda/ui/tui/spokes/software.py
index d6e0be5..0b5bb6e 100644
--- a/pyanaconda/ui/tui/spokes/software.py
+++ b/pyanaconda/ui/tui/spokes/software.py
@@ -20,6 +20,7 @@
 #
 
 from pyanaconda.flags import flags
+from pyanaconda.ui.categories.software import SoftwareCategory
 from pyanaconda.ui.tui.spokes import NormalTUISpoke
 from pyanaconda.ui.tui.simpleline import TextWidget, ColumnWidget, CheckboxWidget
 from pyanaconda.threads import threadMgr, AnacondaThread
@@ -35,7 +36,7 @@ __all__ = ["SoftwareSpoke"]
 class SoftwareSpoke(NormalTUISpoke):
     """ Spoke used to read new value of text to represent source repo. """
     title = N_("Software selection")
-    category = "software"
+    category = SoftwareCategory
 
     def __init__(self, app, data, storage, payload, instclass):
         NormalTUISpoke.__init__(self, app, data, storage, payload, instclass)
diff --git a/pyanaconda/ui/tui/spokes/source.py b/pyanaconda/ui/tui/spokes/source.py
index 5702291..0542ff3 100644
--- a/pyanaconda/ui/tui/spokes/source.py
+++ b/pyanaconda/ui/tui/spokes/source.py
@@ -21,6 +21,7 @@
 #
 
 from pyanaconda.flags import flags
+from pyanaconda.ui.categories.software import SoftwareCategory
 from pyanaconda.ui.tui.spokes import EditTUISpoke, NormalTUISpoke
 from pyanaconda.ui.tui.spokes import EditTUISpokeEntry as Entry
 from pyanaconda.ui.tui.simpleline import TextWidget, ColumnWidget
@@ -146,7 +147,7 @@ class SourceSwitchHandler(object):
 class SourceSpoke(SourceSwitchHandler, EditTUISpoke):
     """ Spoke used to customize the install source repo. """
     title = N_("Installation source")
-    category = "software"
+    category = SoftwareCategory
 
     _protocols = ["http://", "https://", "ftp://", "nfs", N_("Closest mirror")]
 
@@ -366,7 +367,7 @@ class SourceSpoke(SourceSwitchHandler, EditTUISpoke):
 class SpecifyRepoSpoke(SourceSwitchHandler, EditTUISpoke):
     """ Specify the repo URL here if closest mirror not selected. """
     title = N_("Specify Repo Options")
-    category = "software"
+    category = SoftwareCategory
 
     edit_fields = [
         Entry(N_("Repo URL"), "url", re.compile(".*$"), True)
@@ -404,7 +405,7 @@ class SpecifyRepoSpoke(SourceSwitchHandler, EditTUISpoke):
 class SpecifyNFSRepoSpoke(SourceSwitchHandler, EditTUISpoke):
     """ Specify server and mount opts here if NFS selected. """
     title = N_("Specify Repo Options")
-    category = "software"
+    category = SoftwareCategory
 
     edit_fields = [
         Entry(N_("NFS <server>:/<path>"), "server", re.compile(".*$"), True),
@@ -452,7 +453,7 @@ class SelectDeviceSpoke(NormalTUISpoke):
     """ Select device containing the install source ISO file. """
 
     title = N_("Select device containing the ISO file")
-    category = "source"
+    category = SoftwareCategory
 
     def __init__(self, app, data, storage, payload, instclass):
         NormalTUISpoke.__init__(self, app, data, storage, payload, instclass)
@@ -540,7 +541,7 @@ class SelectISOSpoke(SourceSwitchHandler, NormalTUISpoke):
     """ Select an ISO to use as install source. """
 
     title = N_("Select an ISO to use as install source")
-    category = "source"
+    category = SoftwareCategory
 
     def __init__(self, app, data, storage, payload, instclass, device):
         NormalTUISpoke.__init__(self, app, data, storage, payload, instclass)
diff --git a/pyanaconda/ui/tui/spokes/storage.py b/pyanaconda/ui/tui/spokes/storage.py
index 0e3b9fa..08b8fc6 100644
--- a/pyanaconda/ui/tui/spokes/storage.py
+++ b/pyanaconda/ui/tui/spokes/storage.py
@@ -23,6 +23,7 @@
 #
 
 from pyanaconda.ui.lib.disks import getDisks, size_str, applyDiskSelection
+from pyanaconda.ui.categories.system import SystemCategory
 from pyanaconda.ui.tui.spokes import NormalTUISpoke
 from pyanaconda.ui.tui.simpleline import TextWidget, CheckboxWidget
 from pyanaconda.ui.tui.tuiobject import YesNoDialog
@@ -63,7 +64,7 @@ class StorageSpoke(NormalTUISpoke):
     as disk selection, partitioning, and fs type.
     """
     title = N_("Install Destination")
-    category = "system"
+    category = SystemCategory
 
     def __init__(self, app, data, storage, payload, instclass):
         NormalTUISpoke.__init__(self, app, data, storage, payload, instclass)
@@ -412,7 +413,7 @@ class StorageSpoke(NormalTUISpoke):
 class AutoPartSpoke(NormalTUISpoke):
     """ Autopartitioning options are presented here. """
     title = N_("Autopartitioning Options")
-    category = "system"
+    category = SystemCategory
 
     def __init__(self, app, data, storage, payload, instclass):
         NormalTUISpoke.__init__(self, app, data, storage, payload, instclass)
@@ -481,7 +482,7 @@ class AutoPartSpoke(NormalTUISpoke):
 class PartitionSchemeSpoke(NormalTUISpoke):
     """ SPoke to select what partitioning scheme to use on disk(s). """
     title = N_("Partition Scheme Options")
-    category = "system"
+    category = SystemCategory
 
     # set default FS to LVM, for consistency with graphical behavior
     _selection = 2
diff --git a/pyanaconda/ui/tui/spokes/time.py b/pyanaconda/ui/tui/spokes/time.py
index 403d962..cb10dfc 100644
--- a/pyanaconda/ui/tui/spokes/time.py
+++ b/pyanaconda/ui/tui/spokes/time.py
@@ -19,6 +19,7 @@
 # Red Hat Author(s): Martin Sivak <msivak at redhat.com>
 #
 
+from pyanaconda.ui.categories.localization import LocalizationCategory
 from pyanaconda.ui.tui.spokes import NormalTUISpoke
 from pyanaconda.ui.tui.simpleline import TextWidget, ColumnWidget
 from pyanaconda.ui.common import FirstbootSpokeMixIn
@@ -27,7 +28,7 @@ from pyanaconda.i18n import N_, _
 
 class TimeZoneSpoke(FirstbootSpokeMixIn, NormalTUISpoke):
     title = N_("Timezone settings")
-    category = "localization"
+    category = LocalizationCategory
 
     def __init__(self, app, data, storage, payload, instclass):
         NormalTUISpoke.__init__(self, app, data, storage, payload, instclass)
diff --git a/pyanaconda/ui/tui/spokes/user.py b/pyanaconda/ui/tui/spokes/user.py
index 641bea3..79a3463 100644
--- a/pyanaconda/ui/tui/spokes/user.py
+++ b/pyanaconda/ui/tui/spokes/user.py
@@ -20,6 +20,7 @@
 #                    Chris Lumens <clumens at redhat.com>
 #
 
+from pyanaconda.ui.categories.user_settings import UserSettingsCategory
 from pyanaconda.ui.tui.spokes import EditTUISpoke
 from pyanaconda.ui.tui.spokes import EditTUISpokeEntry as Entry
 from pyanaconda.ui.common import FirstbootSpokeMixIn
@@ -34,7 +35,7 @@ __all__ = ["UserSpoke"]
 
 class UserSpoke(FirstbootSpokeMixIn, EditTUISpoke):
     title = N_("Create user")
-    category = "password"
+    category = UserSettingsCategory
 
     edit_fields = [
         Entry("Create user", "_create", EditTUISpoke.CHECK, True),
-- 
1.9.3



More information about the anaconda-patches mailing list