This just backports and squashes together some commits from master, specifically:
[anaconda] 69484b44 823ad562 b65c9247 4e3a8082 5821956a 674f596c
[initial-setup] 1276f37c
Things are pretty much the same as when these were first reviewed, but I figured I'd post them again since the changes touch a lot of files.
Get rid of separately managed TUI and GUI categories.
Resolves: rhbz#1128616 --- po/POTFILES.in | 12 +++--- pyanaconda/ui/categories/Makefile.am | 22 +++++++++++ pyanaconda/ui/categories/__init__.py | 47 ++++++++++++++++++++++ pyanaconda/ui/categories/customization.py | 32 +++++++++++++++ pyanaconda/ui/categories/localization.py | 31 +++++++++++++++ pyanaconda/ui/categories/software.py | 31 +++++++++++++++ pyanaconda/ui/categories/system.py | 32 +++++++++++++++ pyanaconda/ui/categories/user_settings.py | 32 +++++++++++++++ pyanaconda/ui/gui/categories/Makefile.am | 22 ----------- pyanaconda/ui/gui/categories/__init__.py | 57 --------------------------- pyanaconda/ui/gui/categories/customization.py | 32 --------------- pyanaconda/ui/gui/categories/localization.py | 31 --------------- pyanaconda/ui/gui/categories/software.py | 31 --------------- pyanaconda/ui/gui/categories/system.py | 32 --------------- pyanaconda/ui/gui/categories/user_settings.py | 32 --------------- 15 files changed, 233 insertions(+), 243 deletions(-) create mode 100644 pyanaconda/ui/categories/Makefile.am create mode 100644 pyanaconda/ui/categories/__init__.py create mode 100644 pyanaconda/ui/categories/customization.py create mode 100644 pyanaconda/ui/categories/localization.py create mode 100644 pyanaconda/ui/categories/software.py create mode 100644 pyanaconda/ui/categories/system.py create mode 100644 pyanaconda/ui/categories/user_settings.py delete mode 100644 pyanaconda/ui/gui/categories/Makefile.am delete mode 100644 pyanaconda/ui/gui/categories/__init__.py delete mode 100644 pyanaconda/ui/gui/categories/customization.py delete mode 100644 pyanaconda/ui/gui/categories/localization.py delete mode 100644 pyanaconda/ui/gui/categories/software.py delete mode 100644 pyanaconda/ui/gui/categories/system.py delete mode 100644 pyanaconda/ui/gui/categories/user_settings.py
diff --git a/po/POTFILES.in b/po/POTFILES.in index da1880f..b298e17 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -37,6 +37,12 @@ pyanaconda/packaging/rpmostreepayload.py # Interfaces pyanaconda/ui/common.py pyanaconda/ui/__init__.py +pyanaconda/ui/categories/__init__.py +pyanaconda/ui/categories/customization.py +pyanaconda/ui/categories/localization.py +pyanaconda/ui/categories/software.py +pyanaconda/ui/categories/system.py +pyanaconda/ui/categories/user_settings.py
# Common stuff pyanaconda/ui/lib/space.py @@ -64,12 +70,6 @@ pyanaconda/ui/tui/__init__.py
# Graphical interface pyanaconda/ui/gui/__init__.py -pyanaconda/ui/gui/categories/__init__.py -pyanaconda/ui/gui/categories/customization.py -pyanaconda/ui/gui/categories/localization.py -pyanaconda/ui/gui/categories/software.py -pyanaconda/ui/gui/categories/system.py -pyanaconda/ui/gui/categories/user_settings.py pyanaconda/ui/gui/hubs/__init__.py pyanaconda/ui/gui/hubs/progress.py pyanaconda/ui/gui/spokes/custom.py diff --git a/pyanaconda/ui/categories/Makefile.am b/pyanaconda/ui/categories/Makefile.am new file mode 100644 index 0000000..e7d0e34 --- /dev/null +++ b/pyanaconda/ui/categories/Makefile.am @@ -0,0 +1,22 @@ +# Copyright (C) 2011 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# Author: Chris Lumens clumens@redhat.com + +MAINTAINERCLEANFILES = Makefile.in + +pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME) +categoriesdir = $(pkgpyexecdir)/ui/categories +categories_PYTHON = $(srcdir)/*.py diff --git a/pyanaconda/ui/categories/__init__.py b/pyanaconda/ui/categories/__init__.py new file mode 100644 index 0000000..024436b --- /dev/null +++ b/pyanaconda/ui/categories/__init__.py @@ -0,0 +1,47 @@ +# Base classes for spoke categories. +# +# Copyright (C) 2011, 2013 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Chris Lumens clumens@redhat.com +# + +import os.path +from pyanaconda.i18n import N_ + +__all__ = ["SpokeCategory"] + +class SpokeCategory(object): + """A SpokeCategory is an object used to group multiple related Spokes + together on a hub. It consists of a title displayed above, and then + a two-column grid of SpokeSelectors. Each SpokeSelector is associated + with a Spoke subclass. A SpokeCategory will only display those Spokes + with a matching category attribute. + + Class attributes: + + displayOnHub -- The Hub subclass to display this Category on. If + None, this Category will be skipped. + sortOrder -- A number indicating the order in which this Category + will be displayed. A lower number indicates display + higher up in the Hub. + title -- The title of this SpokeCategory, to be displayed above + the grid. + """ + displayOnHubGUI = None + displayOnHubTUI = None + sortOrder = 1000 + title = N_("DEFAULT TITLE") diff --git a/pyanaconda/ui/categories/customization.py b/pyanaconda/ui/categories/customization.py new file mode 100644 index 0000000..f2c6e05 --- /dev/null +++ b/pyanaconda/ui/categories/customization.py @@ -0,0 +1,32 @@ +# Localization category classes +# +# Copyright (C) 2011, 2013 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Chris Lumens clumens@redhat.com +# Martin Sivak msivak@redhat.com +# + +from pyanaconda.i18n import N_ +from pyanaconda.ui.gui.categories import SpokeCategory + +__all__ = ["CustomizationCategory"] + +class CustomizationCategory(SpokeCategory): + displayOnHubGUI = "SummaryHub" + displayOnHubTUI = "SummaryHub" + sortOrder = 100 + title = N_("CUSTOMIZATION") diff --git a/pyanaconda/ui/categories/localization.py b/pyanaconda/ui/categories/localization.py new file mode 100644 index 0000000..dead551 --- /dev/null +++ b/pyanaconda/ui/categories/localization.py @@ -0,0 +1,31 @@ +# Localization category classes +# +# Copyright (C) 2011, 2013 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Chris Lumens clumens@redhat.com +# + +from pyanaconda.i18n import N_ +from pyanaconda.ui.gui.categories import SpokeCategory + +__all__ = ["LocalizationCategory"] + +class LocalizationCategory(SpokeCategory): + displayOnHubGUI = "SummaryHub" + displayOnHubTUI = "SummaryHub" + sortOrder = 100 + title = N_("LOCALIZATION") diff --git a/pyanaconda/ui/categories/software.py b/pyanaconda/ui/categories/software.py new file mode 100644 index 0000000..0a4969b --- /dev/null +++ b/pyanaconda/ui/categories/software.py @@ -0,0 +1,31 @@ +# Software category classes +# +# Copyright (C) 2011, 2013 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Chris Lumens clumens@redhat.com +# + +from pyanaconda.i18n import N_ +from pyanaconda.ui.gui.categories import SpokeCategory + +__all__ = ["SoftwareCategory"] + +class SoftwareCategory(SpokeCategory): + displayOnHubGUI = "SummaryHub" + displayOnHubTUI = "SummaryHub" + sortOrder = 200 + title = N_("SOFTWARE") diff --git a/pyanaconda/ui/categories/system.py b/pyanaconda/ui/categories/system.py new file mode 100644 index 0000000..bd8da3d --- /dev/null +++ b/pyanaconda/ui/categories/system.py @@ -0,0 +1,32 @@ +# System category classes +# +# Copyright (C) 2011, 2013 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Chris Lumens clumens@redhat.com +# David Lehman dlehman@redhat.com +# + +from pyanaconda.i18n import N_ +from pyanaconda.ui.gui.categories import SpokeCategory + +__all__ = ["SystemCategory"] + +class SystemCategory(SpokeCategory): + displayOnHubGUI = "SummaryHub" + displayOnHubTUI = "SummaryHub" + sortOrder = 300 + title = N_("SYSTEM") diff --git a/pyanaconda/ui/categories/user_settings.py b/pyanaconda/ui/categories/user_settings.py new file mode 100644 index 0000000..d04d1f4 --- /dev/null +++ b/pyanaconda/ui/categories/user_settings.py @@ -0,0 +1,32 @@ +# User settings category classes +# +# Copyright (C) 2011, 2013 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Chris Lumens clumens@redhat.com +# Martin Sivak msivak@redhat.com +# + +from pyanaconda.i18n import N_ +from pyanaconda.ui.gui.categories import SpokeCategory + +__all__ = ["UserSettingsCategory"] + +class UserSettingsCategory(SpokeCategory): + displayOnHubGUI = "ProgressHub" + displayOnHubTUI = "SummaryHub" + sortOrder = 200 + title = N_("USER SETTINGS") diff --git a/pyanaconda/ui/gui/categories/Makefile.am b/pyanaconda/ui/gui/categories/Makefile.am deleted file mode 100644 index ed3ecee..0000000 --- a/pyanaconda/ui/gui/categories/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (C) 2011 Red Hat, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. -# -# Author: Chris Lumens clumens@redhat.com - -MAINTAINERCLEANFILES = Makefile.in - -pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME) -categoriesdir = $(pkgpyexecdir)/ui/gui/categories -categories_PYTHON = $(srcdir)/*.py diff --git a/pyanaconda/ui/gui/categories/__init__.py b/pyanaconda/ui/gui/categories/__init__.py deleted file mode 100644 index 66bd5d4..0000000 --- a/pyanaconda/ui/gui/categories/__init__.py +++ /dev/null @@ -1,57 +0,0 @@ -# Base classes for spoke categories. -# -# Copyright (C) 2011, 2013 Red Hat, Inc. -# -# This copyrighted material is made available to anyone wishing to use, -# modify, copy, or redistribute it subject to the terms and conditions of -# the GNU General Public License v.2, or (at your option) any later version. -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY expressed or implied, including the implied warranties of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. You should have received a copy of the -# GNU General Public License along with this program; if not, write to the -# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the -# source code or documentation are not subject to the GNU General Public -# License and may only be used or replicated with the express permission of -# Red Hat, Inc. -# -# Red Hat Author(s): Chris Lumens clumens@redhat.com -# - -import os.path -from pyanaconda.i18n import N_ -from pyanaconda.ui.common import collect - -__all__ = ["SpokeCategory", "collect_categories"] - -class SpokeCategory(object): - """A SpokeCategory is an object used to group multiple related Spokes - together on a hub. It consists of a title displayed above, and then - a two-column grid of SpokeSelectors. Each SpokeSelector is associated - with a Spoke subclass. A SpokeCategory will only display those Spokes - with a matching category attribute. - - Class attributes: - - displayOnHub -- The Hub subclass to display this Category on. If - None, this Category will be skipped. - sortOrder -- A number indicating the order in which this Category - will be displayed. A lower number indicates display - higher up in the Hub. - title -- The title of this SpokeCategory, to be displayed above - the grid. - """ - displayOnHub = None - sortOrder = 1000 - title = N_("DEFAULT TITLE") - -def collect_categories(mask_paths): - """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 = [] - for mask, path in mask_paths: - categories.extend(collect(mask, path, lambda obj: getattr(obj, "displayOnHub", None) != None)) - - return categories diff --git a/pyanaconda/ui/gui/categories/customization.py b/pyanaconda/ui/gui/categories/customization.py deleted file mode 100644 index be59dec..0000000 --- a/pyanaconda/ui/gui/categories/customization.py +++ /dev/null @@ -1,32 +0,0 @@ -# Localization category classes -# -# Copyright (C) 2011, 2013 Red Hat, Inc. -# -# This copyrighted material is made available to anyone wishing to use, -# modify, copy, or redistribute it subject to the terms and conditions of -# the GNU General Public License v.2, or (at your option) any later version. -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY expressed or implied, including the implied warranties of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. You should have received a copy of the -# GNU General Public License along with this program; if not, write to the -# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the -# source code or documentation are not subject to the GNU General Public -# License and may only be used or replicated with the express permission of -# Red Hat, Inc. -# -# Red Hat Author(s): Chris Lumens clumens@redhat.com -# Martin Sivak msivak@redhat.com -# - -from pyanaconda.i18n import N_ -from pyanaconda.ui.gui.categories import SpokeCategory -from pyanaconda.ui.gui.hubs.progress import ProgressHub - -__all__ = ["CustomizationCategory"] - -class CustomizationCategory(SpokeCategory): - displayOnHub = ProgressHub - sortOrder = 100 - title = N_("CUSTOMIZATION") diff --git a/pyanaconda/ui/gui/categories/localization.py b/pyanaconda/ui/gui/categories/localization.py deleted file mode 100644 index 19a77ee..0000000 --- a/pyanaconda/ui/gui/categories/localization.py +++ /dev/null @@ -1,31 +0,0 @@ -# Localization category classes -# -# Copyright (C) 2011, 2013 Red Hat, Inc. -# -# This copyrighted material is made available to anyone wishing to use, -# modify, copy, or redistribute it subject to the terms and conditions of -# the GNU General Public License v.2, or (at your option) any later version. -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY expressed or implied, including the implied warranties of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. You should have received a copy of the -# GNU General Public License along with this program; if not, write to the -# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the -# source code or documentation are not subject to the GNU General Public -# License and may only be used or replicated with the express permission of -# Red Hat, Inc. -# -# Red Hat Author(s): Chris Lumens clumens@redhat.com -# - -from pyanaconda.i18n import N_ -from pyanaconda.ui.gui.categories import SpokeCategory -from pyanaconda.ui.gui.hubs.summary import SummaryHub - -__all__ = ["LocalizationCategory"] - -class LocalizationCategory(SpokeCategory): - displayOnHub = SummaryHub - sortOrder = 100 - title = N_("LOCALIZATION") diff --git a/pyanaconda/ui/gui/categories/software.py b/pyanaconda/ui/gui/categories/software.py deleted file mode 100644 index 843f736..0000000 --- a/pyanaconda/ui/gui/categories/software.py +++ /dev/null @@ -1,31 +0,0 @@ -# Software category classes -# -# Copyright (C) 2011, 2013 Red Hat, Inc. -# -# This copyrighted material is made available to anyone wishing to use, -# modify, copy, or redistribute it subject to the terms and conditions of -# the GNU General Public License v.2, or (at your option) any later version. -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY expressed or implied, including the implied warranties of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. You should have received a copy of the -# GNU General Public License along with this program; if not, write to the -# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the -# source code or documentation are not subject to the GNU General Public -# License and may only be used or replicated with the express permission of -# Red Hat, Inc. -# -# Red Hat Author(s): Chris Lumens clumens@redhat.com -# - -from pyanaconda.i18n import N_ -from pyanaconda.ui.gui.categories import SpokeCategory -from pyanaconda.ui.gui.hubs.summary import SummaryHub - -__all__ = ["SoftwareCategory"] - -class SoftwareCategory(SpokeCategory): - displayOnHub = SummaryHub - sortOrder = 200 - title = N_("SOFTWARE") diff --git a/pyanaconda/ui/gui/categories/system.py b/pyanaconda/ui/gui/categories/system.py deleted file mode 100644 index d8ca268..0000000 --- a/pyanaconda/ui/gui/categories/system.py +++ /dev/null @@ -1,32 +0,0 @@ -# System category classes -# -# Copyright (C) 2011, 2013 Red Hat, Inc. -# -# This copyrighted material is made available to anyone wishing to use, -# modify, copy, or redistribute it subject to the terms and conditions of -# the GNU General Public License v.2, or (at your option) any later version. -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY expressed or implied, including the implied warranties of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. You should have received a copy of the -# GNU General Public License along with this program; if not, write to the -# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the -# source code or documentation are not subject to the GNU General Public -# License and may only be used or replicated with the express permission of -# Red Hat, Inc. -# -# Red Hat Author(s): Chris Lumens clumens@redhat.com -# David Lehman dlehman@redhat.com -# - -from pyanaconda.i18n import N_ -from pyanaconda.ui.gui.categories import SpokeCategory -from pyanaconda.ui.gui.hubs.summary import SummaryHub - -__all__ = ["SystemCategory"] - -class SystemCategory(SpokeCategory): - displayOnHub = SummaryHub - sortOrder = 300 - title = N_("SYSTEM") diff --git a/pyanaconda/ui/gui/categories/user_settings.py b/pyanaconda/ui/gui/categories/user_settings.py deleted file mode 100644 index e025428..0000000 --- a/pyanaconda/ui/gui/categories/user_settings.py +++ /dev/null @@ -1,32 +0,0 @@ -# User settings category classes -# -# Copyright (C) 2011, 2013 Red Hat, Inc. -# -# This copyrighted material is made available to anyone wishing to use, -# modify, copy, or redistribute it subject to the terms and conditions of -# the GNU General Public License v.2, or (at your option) any later version. -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY expressed or implied, including the implied warranties of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. You should have received a copy of the -# GNU General Public License along with this program; if not, write to the -# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the -# source code or documentation are not subject to the GNU General Public -# License and may only be used or replicated with the express permission of -# Red Hat, Inc. -# -# Red Hat Author(s): Chris Lumens clumens@redhat.com -# Martin Sivak msivak@redhat.com -# - -from pyanaconda.i18n import N_ -from pyanaconda.ui.gui.categories import SpokeCategory -from pyanaconda.ui.gui.hubs.progress import ProgressHub - -__all__ = ["UserSettingsCategory"] - -class UserSettingsCategory(SpokeCategory): - displayOnHub = ProgressHub - sortOrder = 200 - title = N_("USER SETTINGS")
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@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@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@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),
And move them to a common file to avoid code duplication.
Cherry-picked from commit 1276f37cf107defc68aa8d0bc5f9b3a2b0c4046.
Related: rhbz#1128616 --- initial_setup/common.py | 54 +++++++++++++++++++++++++++++ initial_setup/gui/hubs/initial_setup_hub.py | 42 ++-------------------- initial_setup/tui/hubs/initial_setup_hub.py | 5 +++ 3 files changed, 62 insertions(+), 39 deletions(-) create mode 100644 initial_setup/common.py
diff --git a/initial_setup/common.py b/initial_setup/common.py new file mode 100644 index 0000000..2009128 --- /dev/null +++ b/initial_setup/common.py @@ -0,0 +1,54 @@ +"""Common methods for Initial Setup""" + +from pyanaconda.ui.common import collect +from pyanaconda.constants import FIRSTBOOT_ENVIRON + +def collect_spokes(mask_paths, spoke_parent_class): + """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) + + :param spoke_parent_class: Spoke parent class used for checking spoke compatibility + :type spoke_parent_class: GUI or TUI Spoke class + + :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_parent_class) and obj.should_run("firstboot", None))) + return spokes + + +def collectCategoriesAndSpokes(hub_instance, spoke_parent_class): + """Collects categories and spokes to be displayed on this Hub, + this method overrides the Anacondas implementation so that + spokes relevant to Initial setup are collected + + :param hub_instance: an Initial Setup GUI or TUI Hub class instance + :type hub_instance: class instance + + :param spoke_parent_class: Spoke parent class used for checking spoke compatibility + :type spoke_parent_class: GUI or TUI Spoke class + + :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(hub_instance.paths["spokes"], spoke_parent_class) + spokes = [spoke for spoke in candidate_spokes + if spoke.should_run(FIRSTBOOT_ENVIRON, hub_instance.data)] + + for spoke in spokes: + ret.setdefault(spoke.category, []) + ret[spoke.category].append(spoke) + + return ret diff --git a/initial_setup/gui/hubs/initial_setup_hub.py b/initial_setup/gui/hubs/initial_setup_hub.py index 19aab55..9df65ab 100644 --- a/initial_setup/gui/hubs/initial_setup_hub.py +++ b/initial_setup/gui/hubs/initial_setup_hub.py @@ -1,31 +1,13 @@ from pyanaconda.constants import FIRSTBOOT_ENVIRON from pyanaconda.ui.gui.hubs import Hub -from pyanaconda.ui.gui.spokes import Spoke -from pyanaconda.ui.common import collect +from pyanaconda.ui.gui.spokes import Spoke as GUI_spoke_class from initial_setup import product +from initial_setup import common import os import sys
__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))) - - return spokes -
class InitialSetupMainHub(Hub): uiFile = "initial_setup.glade" @@ -38,25 +20,7 @@ class InitialSetupMainHub(Hub): self._environs = [FIRSTBOOT_ENVIRON]
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_ENVIRON, self.data)] - - for spoke in spokes: - ret.setdefault(spoke.category, []) - ret[spoke.category].append(spoke) - - return ret + return common.collectCategoriesAndSpokes(self, GUI_spoke_class)
def _createBox(self): Hub._createBox(self) diff --git a/initial_setup/tui/hubs/initial_setup_hub.py b/initial_setup/tui/hubs/initial_setup_hub.py index 021a48a..a1ec2c3 100644 --- a/initial_setup/tui/hubs/initial_setup_hub.py +++ b/initial_setup/tui/hubs/initial_setup_hub.py @@ -1,6 +1,8 @@ from pyanaconda.constants import FIRSTBOOT_ENVIRON from pyanaconda.ui.tui.hubs import TUIHub +from pyanaconda.ui.tui.spokes import Spoke as TUI_spoke_class from initial_setup import product +from initial_setup import common import gettext
__all__ = ["InitialSetupMainHub"] @@ -21,3 +23,6 @@ class InitialSetupMainHub(TUIHub): def __init__(self, *args): TUIHub.__init__(self, *args) self._environs = [FIRSTBOOT_ENVIRON] + + def _collectCategoriesAndSpokes(self): + return common.collectCategoriesAndSpokes(self, TUI_spoke_class)
On Wed, 2014-09-03 at 16:05 -0400, Samantha N. Bueno wrote:
This just backports and squashes together some commits from master, specifically:
[anaconda] 69484b44 823ad562 b65c9247 4e3a8082 5821956a 674f596c
[initial-setup] 1276f37c
Things are pretty much the same as when these were first reviewed, but I figured I'd post them again since the changes touch a lot of files.
I have a bad feeling that there was some "typo-like" fix after the anaconda patches listed above, something like 'spoke.__class__' -> 'obj.__class__' or vice versa, but I cannot find it now.
All these patches look good to me, just run pylint on the changed files to check for things like the example above, they are quite common when porting patches from master to rhel*-branches.
anaconda-patches@lists.fedorahosted.org