[PATCH] Mark language search string translatable. (#955229)
by Samantha N. Bueno
---
pyanaconda/ui/gui/spokes/welcome.glade | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyanaconda/ui/gui/spokes/welcome.glade b/pyanaconda/ui/gui/spokes/welcome.glade
index f0a4602..4f79b7c 100644
--- a/pyanaconda/ui/gui/spokes/welcome.glade
+++ b/pyanaconda/ui/gui/spokes/welcome.glade
@@ -367,7 +367,7 @@
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
<property name="secondary_icon_name">edit-clear-symbolic</property>
- <property name="placeholder_text">Type here to search.</property>
+ <property name="placeholder_text" translatable="yes">Type here to search.</property>
<signal name="changed" handler="on_entry_changed" swapped="no"/>
<signal name="icon-release" handler="on_clear_icon_clicked" swapped="no"/>
</object>
--
1.7.11.7
10 years, 2 months
[anaconda][PATCH] Allow hubs and standalone spokes decide if it is possible to continue
by Vratislav Podzimek
Related: rhbz#965797
Signed-off-by: Vratislav Podzimek <vpodzime(a)redhat.com>
---
pyanaconda/ui/gui/hubs/__init__.py | 29 +++++++++++++++++++++++++++--
pyanaconda/ui/gui/spokes/__init__.py | 18 ++++++++++++++++--
2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/gui/hubs/__init__.py b/pyanaconda/ui/gui/hubs/__init__.py
index 37daf47..bb473b6 100644
--- a/pyanaconda/ui/gui/hubs/__init__.py
+++ b/pyanaconda/ui/gui/hubs/__init__.py
@@ -354,11 +354,36 @@ class Hub(GUIObject, common.Hub):
self._update_spoke_id = GLib.timeout_add_seconds(1, self._update_spokes)
- ### SIGNAL HANDLERS
+ @property
+ def continue_possible(self):
+ """
+ Indicates whether it is possible to continue to the next action (hub,
+ standalone spoke,...). When overridden, IT IS THE HUB'S RESPONSIBILITY
+ to inform user, where the problem is and how to fix it.
+
+ """
+
+ return True
+
+ ### SIGNAL HANDLING
+ def _checked_continue(self, cb):
+ """
+ Checks if continue is possible (from the hub's perspective and if yes,
+ runs the callback.
+
+ """
+
+ if self.continue_possible:
+ cb()
+
+ def _register_continue_event_cb(self, cb):
+ """Registers the callback for the continue event adding the check."""
+
+ self.continueButton.connect("clicked", lambda *args: self._checked_continue(cb))
def register_event_cb(self, event, cb):
if event == "continue" and hasattr(self, "continueButton"):
- self.continueButton.connect("clicked", lambda *args: cb())
+ self._register_continue_event_cb(cb)
elif event == "quit" and hasattr(self, "quitButton"):
self.quitButton.connect("clicked", lambda *args: cb())
diff --git a/pyanaconda/ui/gui/spokes/__init__.py b/pyanaconda/ui/gui/spokes/__init__.py
index c1a35b3..bb85e1e 100644
--- a/pyanaconda/ui/gui/spokes/__init__.py
+++ b/pyanaconda/ui/gui/spokes/__init__.py
@@ -63,9 +63,23 @@ class StandaloneSpoke(Spoke, common.StandaloneSpoke):
Spoke.__init__(self, data)
common.StandaloneSpoke.__init__(self, data, storage, payload, instclass)
+ @property
+ def continue_possible(self):
+ """
+ Indicates whether it is possible to continue to the next action (hub,
+ standalone spoke,...). When overridden, IT IS THE SPOKES'S
+ RESPONSIBILITY to inform user, where the problem is and how to fix it.
+
+ """
+
+ return True
+
+
+ ### SIGNAL HANDLING
def _on_continue_clicked(self, cb):
- self.apply()
- cb()
+ if self.continue_possible:
+ self.apply()
+ cb()
def register_event_cb(self, event, cb):
if event == "continue":
--
1.7.11.7
10 years, 4 months
[master/rhel7-branch] A bit controversial one for the MountpointSelectors' usage
by Vratislav Podzimek
The following patch fixes the bug #975838 by moving the focus changes handling
from the MountpointSelector widget to the Page and spoke it appears in,
respectively. The controversy lies in making the MountpointSelector's behaviour
relying on the widget it is placed into. The MounpointSelector widget per se no
longer handles focus changes correctly and it looks like being selected/chosen
even if it loses focus. However, this is what we want -- to keep it look like
that when user clicks to the right part of the screen to change parameters of
the mount point being chosen. And since I doubt anybody will reuse the
MountpointSelector as a standalone widget without the Page and the Accordion I
think this change could be done.
I've recorded a video preview [1] showing the functionality with this patch
applied.
[1] http://vpodzime.fedorapeople.org/MountpointSelector_focus.webm
Let me know if I should add more comments to some places.
Vratislav Podzimek (1):
Handle focus changes of MountpointSelectors from outside (#975838)
pyanaconda/ui/gui/spokes/custom.py | 2 ++
pyanaconda/ui/gui/spokes/lib/accordion.py | 6 ++++++
widgets/src/MountpointSelector.c | 31 ++++++++-----------------------
3 files changed, 16 insertions(+), 23 deletions(-)
--
1.7.11.7
10 years, 6 months
[master] Languages and locales related patches
by Vratislav Podzimek
These patches do mainly three things:
1) Rework the Welcome spoke and Langsupport spoke to work with all locales
available instead of few locales we think are best for languages we have
translations for.
2) Remove the cryptic checkbutton for setting only the language-default keyboard
layout instead of a combination with the 'us' layout. Having the layout
indicator now, we may set the language-default layout as the only one and switch
to it from the default 'us' layout (active on the Welcome spoke) automatically.
Exceptions are languages the default layout of which don't support typing ASCII
characters. For those layouts we should append 'us' to the list of activated
layouts and set up layout switching automatically.
3) Get rid of the expand_langs() function and it's usage resulting in
highly-probably nondeterministic results.
I've recorded a video preview [1] demonstrating the new look and behaviour.
[1] http://vpodzime.fedorapeople.org/locales_changes.webm
Altough there are many lines of code added by those patches, the overall user
experience should be much better and they resolve a lot of bugs and complaints.
And I want to come up with a patch dealing with a lot of code duplicated in
Welcome and Langsupport spokes' code that should result in many lines removed.
However, I'd like to see those 7 patches landing in the Fedora 20 asap because
it is quite a significant change for users.
Vratislav Podzimek (7):
Remove an unused argument of get_available_translations
Allow seting up locale without modifying ksdata
Remove the cryptic "language-default keyboard" checkbutton
Improve import in GUI utils a bit
Rework the Welcome spoke to allow users choose from all locales
Rework the Langsupport spoke to work with all locales
Get rid of the non-deterministic expand_langs and its usage
pyanaconda/localization.py | 156 ++++++++-----
pyanaconda/packaging/yumpayload.py | 9 +-
pyanaconda/ui/gui/hubs/progress.py | 53 +++--
pyanaconda/ui/gui/spokes/langsupport.glade | 167 ++++++++++----
pyanaconda/ui/gui/spokes/langsupport.py | 244 +++++++++++---------
pyanaconda/ui/gui/spokes/welcome.glade | 336 ++++++++++++++--------------
pyanaconda/ui/gui/spokes/welcome.py | 192 +++++++++-------
pyanaconda/ui/gui/utils.py | 45 +++-
tests/pyanaconda_tests/localization_test.py | 61 ++++-
9 files changed, 772 insertions(+), 491 deletions(-)
--
1.7.11.7
10 years, 7 months
[PATCH rhel6-branch] PPC: strengthen PReP-picking algorithm (#877852)
by Will Woods
pSeries-style systems can have multiple PReP partitions, as long as
there's only one per disk. It's kind of like the x86 MBR that way.
The current code in booty and platform.py *always* picks the first PReP
partition, which will fail if if you have (e.g.) an OS already installed
on /dev/sda and you're doing a new install onto /dev/sdb.
This patch adds ppcBootloaderInfo.pickPReP(), which tries to find the
best PReP partition to use according to the following rules:
1) If we're creating a new PReP partition, use that;
2) Otherwise, if there's a PReP partition already on the disk that
contains /boot, use that;
3) Failing that, use the first available PReP partition (as before).
This should make mkofboot actually install yaboot into the correct PReP
partition.
IPSeriesPPC.bootDevice() has been changed to use this same algorithm, so
the two of them will agree about what the boot device is.
---
booty/ppc.py | 37 ++++++++++++++++++++++++++++++++-----
platform.py | 11 ++---------
2 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/booty/ppc.py b/booty/ppc.py
index 6f62071..401f505 100644
--- a/booty/ppc.py
+++ b/booty/ppc.py
@@ -7,6 +7,35 @@ from bootloaderInfo import *
import iutil
class ppcBootloaderInfo(bootloaderInfo):
+ def pickPReP(self):
+ # if we created a new PReP partition, pick that
+ for a in self.storage.findActions(type="create", obj="format"):
+ if a.format.type == "prepboot":
+ return a.device
+
+ # otherwise, look at the existing PReP partitions.
+ prepdevs = []
+ for dev in self.storage.fsset.devices:
+ if (dev.format.type == "prepboot" and
+ dev.partedPartition.getFlag(parted.PARTITION_BOOT)):
+ prepdevs.append(dev)
+
+ # we'd prefer a PReP partition that's on the same disk as /boot.
+ try:
+ bootdisk = self.storage.mountpoints["/boot"].disk
+ except KeyError:
+ bootdisk = self.storage.rootDevice.disk
+ for dev in prepdevs:
+ if dev.disk == bootdisk:
+ return dev
+
+ # failing that, return the first PReP partition we found
+ if len(prepdevs) != 0:
+ return prepdevs[0]
+
+ # Alas, no PReP to be found..
+ return None
+
def getBootDevs(self, bl):
import parted
@@ -14,10 +43,9 @@ class ppcBootloaderInfo(bootloaderInfo):
machine = iutil.getPPCMachine()
if machine == 'pSeries':
- for dev in self.storage.fsset.devices:
- if (dev.format.type == "prepboot" and
- dev.partedPartition.getFlag(parted.PARTITION_BOOT)):
- retval.append(dev.path)
+ prep = self.pickPReP()
+ if prep:
+ retval.append(prep.path)
elif machine == 'PMac':
for dev in self.storage.fsset.devices:
if dev.format.type == "hfs" and dev.format.bootable:
@@ -31,7 +59,6 @@ class ppcBootloaderInfo(bootloaderInfo):
except KeyError:
# Try / if we don't have this we're not going to work
device = self.storage.rootDevice
-
retval.append(device.path)
else:
if bl.getDevice():
diff --git a/platform.py b/platform.py
index 7bc75ec..e866133 100644
--- a/platform.py
+++ b/platform.py
@@ -392,15 +392,8 @@ class IPSeriesPPC(PPC):
_maxBootPartSize = 10
def bootDevice(self):
- bootDev = None
-
- # We want the first PReP partition.
- for device in self.anaconda.id.storage.partitions:
- if device.format.type == "prepboot":
- bootDev = device
- break
-
- return bootDev
+ # use booty's PReP-picking algorithm
+ return self.anaconda.id.bootloader.pickPReP()
def bootloaderChoices(self, bl):
ret = {}
--
1.8.3.1
10 years, 8 months
[initial-setup][PATCH] Read /etc/system-release to get product title (#1000426)
by Vratislav Podzimek
The /etc/system-release file contains a release name that we want to display in
the UI.
For GUI we can use just the product title because the string "INITIAL SETUP" is
shown in the top-left corner. For TUI we should inform user that this is an
initial setup of the system.
Also rename the hub files not to clash with the the Python package name.
Signed-off-by: Vratislav Podzimek <vpodzime(a)redhat.com>
---
initial_setup/gui/gui.py | 13 +++---
initial_setup/gui/hubs/__init__.py | 2 +-
initial_setup/gui/hubs/initial_setup.py | 60 ----------------------------
initial_setup/gui/hubs/initial_setup_hub.py | 60 ++++++++++++++++++++++++++++
initial_setup/product.py | 31 +++++++++++++++
initial_setup/tui/hubs/__init__.py | 2 +-
initial_setup/tui/hubs/initial_setup.py | 55 --------------------------
initial_setup/tui/hubs/initial_setup_hub.py | 61 +++++++++++++++++++++++++++++
initial_setup/tui/tui.py | 13 +++---
9 files changed, 164 insertions(+), 133 deletions(-)
delete mode 100644 initial_setup/gui/hubs/initial_setup.py
create mode 100644 initial_setup/gui/hubs/initial_setup_hub.py
create mode 100644 initial_setup/product.py
delete mode 100644 initial_setup/tui/hubs/initial_setup.py
create mode 100644 initial_setup/tui/hubs/initial_setup_hub.py
diff --git a/initial_setup/gui/gui.py b/initial_setup/gui/gui.py
index 24e5a27..3afe5da 100644
--- a/initial_setup/gui/gui.py
+++ b/initial_setup/gui/gui.py
@@ -1,5 +1,5 @@
from pyanaconda.ui.gui import QuitDialog, GUIObject, GraphicalUserInterface
-#from .product import productName, productVersion
+from initial_setup.product import product_title, is_final
from .hubs import InitialSetupMainHub
from pyanaconda.ui.gui.spokes import StandaloneSpoke
import pyanaconda.ui.gui.spokes
@@ -13,27 +13,24 @@ from di import inject, usesclassinject
_ = lambda t: t
N_ = lambda t: t
-productTitle = lambda: "Initial Setup of Fedora"
-isFinal = lambda: False
-
class InitialSetupQuitDialog(QuitDialog):
MESSAGE = N_("Are you sure you want to quit the configuration process?\n"
"You might end up with unusable system if you do.")
-@inject(Gdk, productTitle = productTitle, isFinal = isFinal)
+@inject(Gdk, product_title = product_title, is_final = is_final)
class InitialSetupGraphicalUserInterface(GraphicalUserInterface):
"""This is the main Gtk based firstboot interface. It inherits from
anaconda to make the look & feel as similar as possible.
"""
screenshots_directory = "/tmp/initial-setup-screenshots"
-
+
@usesclassinject
def __init__(self, storage, payload, instclass):
GraphicalUserInterface.__init__(self, storage, payload, instclass,
- productTitle, isFinal,
+ product_title, is_final,
quitDialog = InitialSetupQuitDialog)
-
+
def _list_hubs(self):
return [InitialSetupMainHub]
diff --git a/initial_setup/gui/hubs/__init__.py b/initial_setup/gui/hubs/__init__.py
index 5d166d6..39d8b13 100644
--- a/initial_setup/gui/hubs/__init__.py
+++ b/initial_setup/gui/hubs/__init__.py
@@ -1 +1 @@
-from .initial_setup import InitialSetupMainHub
+from .initial_setup_hub import InitialSetupMainHub
diff --git a/initial_setup/gui/hubs/initial_setup.py b/initial_setup/gui/hubs/initial_setup.py
deleted file mode 100644
index f966782..0000000
--- a/initial_setup/gui/hubs/initial_setup.py
+++ /dev/null
@@ -1,60 +0,0 @@
-from pyanaconda.ui.gui.hubs import Hub
-from pyanaconda.ui.gui.spokes import Spoke
-from pyanaconda.ui.common import collect
-import os
-
-__all__ = ["InitialSetupMainHub"]
-
-def collect_spokes(mask_paths):
- """Return a list of all spoke subclasses that should appear for a given
- category. Look for them in files imported as module_path % basename(f)
-
- :param mask_paths: list of mask, path tuples to search for classes
- :type mask_paths: list of (mask, path)
-
- :return: list of Spoke classes belonging to category
- :rtype: list of Spoke classes
-
- """
- spokes = []
- for mask, path in mask_paths:
- spokes.extend(collect(mask, path,
- lambda obj: issubclass(obj, Spoke) and obj.should_run("firstboot", None)))
-
- print spokes
- return spokes
-
-
-class InitialSetupMainHub(Hub):
- uiFile = "initial_setup.glade"
- builderObjects = ["summaryWindow"]
- mainWidgetName = "summaryWindow"
-
- def _collectCategoriesAndSpokes(self):
- """collects categories and spokes to be displayed on this Hub
-
- :return: dictionary mapping category class to list of spoke classes
- :rtype: dictionary[category class] -> [ list of spoke classes ]
- """
-
- ret = {}
-
- # Collect all the categories this hub displays, then collect all the
- # spokes belonging to all those categories.
- candidate_spokes = collect_spokes(self.paths["spokes"])
- spokes = [spoke for spoke in candidate_spokes \
- if spoke.should_run("firstboot", self.data)]
-
- for spoke in spokes:
- ret.setdefault(spoke.category, [])
- ret[spoke.category].append(spoke)
-
- return ret
-
- @property
- def continueButton(self):
- return self.builder.get_object("continueButton")
-
- @property
- def quitButton(self):
- return self.builder.get_object("quitButton")
diff --git a/initial_setup/gui/hubs/initial_setup_hub.py b/initial_setup/gui/hubs/initial_setup_hub.py
new file mode 100644
index 0000000..d0ac15b
--- /dev/null
+++ b/initial_setup/gui/hubs/initial_setup_hub.py
@@ -0,0 +1,60 @@
+from pyanaconda.ui.gui.hubs import Hub
+from pyanaconda.ui.gui.spokes import Spoke
+from pyanaconda.ui.common import collect
+import os
+
+__all__ = ["InitialSetupMainHub"]
+
+def collect_spokes(mask_paths):
+ """Return a list of all spoke subclasses that should appear for a given
+ category. Look for them in files imported as module_path % basename(f)
+
+ :param mask_paths: list of mask, path tuples to search for classes
+ :type mask_paths: list of (mask, path)
+
+ :return: list of Spoke classes belonging to category
+ :rtype: list of Spoke classes
+
+ """
+ spokes = []
+ for mask, path in mask_paths:
+ spokes.extend(collect(mask, path,
+ lambda obj: issubclass(obj, Spoke) and obj.should_run("firstboot", None)))
+
+ print spokes
+ return spokes
+
+
+class InitialSetupMainHub(Hub):
+ uiFile = "initial_setup.glade"
+ builderObjects = ["summaryWindow"]
+ mainWidgetName = "summaryWindow"
+
+ def _collectCategoriesAndSpokes(self):
+ """collects categories and spokes to be displayed on this Hub
+
+ :return: dictionary mapping category class to list of spoke classes
+ :rtype: dictionary[category class] -> [ list of spoke classes ]
+ """
+
+ ret = {}
+
+ # Collect all the categories this hub displays, then collect all the
+ # spokes belonging to all those categories.
+ candidate_spokes = collect_spokes(self.paths["spokes"])
+ spokes = [spoke for spoke in candidate_spokes \
+ if spoke.should_run("firstboot", self.data)]
+
+ for spoke in spokes:
+ ret.setdefault(spoke.category, [])
+ ret[spoke.category].append(spoke)
+
+ return ret
+
+ @property
+ def continueButton(self):
+ return self.builder.get_object("continueButton")
+
+ @property
+ def quitButton(self):
+ return self.builder.get_object("quitButton")
diff --git a/initial_setup/product.py b/initial_setup/product.py
new file mode 100644
index 0000000..40cf45d
--- /dev/null
+++ b/initial_setup/product.py
@@ -0,0 +1,31 @@
+"""Module providing information about the installed product."""
+
+RELEASE_STRING_FILE = "/etc/system-release"
+
+def product_title():
+ """
+ Get product title.
+
+ :return: product title
+ :rtype: str
+
+ """
+
+ try:
+ with open(RELEASE_STRING_FILE, "r") as fobj:
+ title = fobj.readline().strip()
+
+ return title
+ except IOError:
+ return ""
+
+def is_final():
+ """
+ Whether it is a final release of the product or not.
+
+ :rtype: bool
+
+ """
+
+ # doesn't really matter for the Initial Setup
+ return True
diff --git a/initial_setup/tui/hubs/__init__.py b/initial_setup/tui/hubs/__init__.py
index 5d166d6..39d8b13 100644
--- a/initial_setup/tui/hubs/__init__.py
+++ b/initial_setup/tui/hubs/__init__.py
@@ -1 +1 @@
-from .initial_setup import InitialSetupMainHub
+from .initial_setup_hub import InitialSetupMainHub
diff --git a/initial_setup/tui/hubs/initial_setup.py b/initial_setup/tui/hubs/initial_setup.py
deleted file mode 100644
index a8521ad..0000000
--- a/initial_setup/tui/hubs/initial_setup.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from pyanaconda.ui.tui.hubs import TUIHub
-from pyanaconda.ui.tui.spokes import TUISpoke
-from pyanaconda.ui.common import collect
-import os
-
-__all__ = ["InitialSetupMainHub"]
-
-# localization
-_ = lambda t: t
-N_ = lambda t: t
-
-def collect_spokes(mask_paths):
- """Return a list of all spoke subclasses that should appear for a given
- category. Look for them in files imported as module_path % basename(f)
-
- :param mask_paths: list of mask, path tuples to search for classes
- :type mask_paths: list of (mask, path)
-
- :return: list of Spoke classes belonging to category
- :rtype: list of Spoke classes
-
- """
- spokes = []
- for mask, path in mask_paths:
- spokes.extend(collect(mask, path,
- lambda obj: issubclass(obj, Spoke) and obj.should_run("firstboot", None)))
-
- print spokes
- return spokes
-
-
-class InitialSetupMainHub(TUIHub):
- categories = ["password", "localization"]
- title = _("Initial setup of Fedora")
-
- def _collectCategoriesAndSpokes(self):
- """collects categories and spokes to be displayed on this Hub
-
- :return: dictionary mapping category class to list of spoke classes
- :rtype: dictionary[category class] -> [ list of spoke classes ]
- """
-
- ret = {}
-
- # Collect all the categories this hub displays, then collect all the
- # spokes belonging to all those categories.
- candidate_spokes = collect_spokes(self.paths["spokes"])
- spokes = [spoke for spoke in candidate_spokes \
- if spoke.should_run("firstboot", self.data)]
-
- for spoke in spokes:
- ret.setdefault(spoke.category, [])
- ret[spoke.category].append(spoke)
-
- return ret
diff --git a/initial_setup/tui/hubs/initial_setup_hub.py b/initial_setup/tui/hubs/initial_setup_hub.py
new file mode 100644
index 0000000..6316179
--- /dev/null
+++ b/initial_setup/tui/hubs/initial_setup_hub.py
@@ -0,0 +1,61 @@
+from pyanaconda.ui.tui.hubs import TUIHub
+from pyanaconda.ui.tui.spokes import TUISpoke
+from pyanaconda.ui.common import collect
+from initial_setup import product
+import os
+
+__all__ = ["InitialSetupMainHub"]
+
+# localization
+_ = lambda t: t
+N_ = lambda t: t
+
+def collect_spokes(mask_paths):
+ """Return a list of all spoke subclasses that should appear for a given
+ category. Look for them in files imported as module_path % basename(f)
+
+ :param mask_paths: list of mask, path tuples to search for classes
+ :type mask_paths: list of (mask, path)
+
+ :return: list of Spoke classes belonging to category
+ :rtype: list of Spoke classes
+
+ """
+ spokes = []
+ for mask, path in mask_paths:
+ spokes.extend(collect(mask, path,
+ lambda obj: issubclass(obj, Spoke) and obj.should_run("firstboot", None)))
+
+ print spokes
+ return spokes
+
+
+class InitialSetupMainHub(TUIHub):
+ categories = ["password", "localization"]
+
+ prod_title = product.product_title()
+ if prod_title:
+ title = _("Initial setup of %(product)s") % {"product": prod_title}
+ else:
+ title = _("Initial setup")
+
+ def _collectCategoriesAndSpokes(self):
+ """collects categories and spokes to be displayed on this Hub
+
+ :return: dictionary mapping category class to list of spoke classes
+ :rtype: dictionary[category class] -> [ list of spoke classes ]
+ """
+
+ ret = {}
+
+ # Collect all the categories this hub displays, then collect all the
+ # spokes belonging to all those categories.
+ candidate_spokes = collect_spokes(self.paths["spokes"])
+ spokes = [spoke for spoke in candidate_spokes \
+ if spoke.should_run("firstboot", self.data)]
+
+ for spoke in spokes:
+ ret.setdefault(spoke.category, [])
+ ret[spoke.category].append(spoke)
+
+ return ret
diff --git a/initial_setup/tui/tui.py b/initial_setup/tui/tui.py
index 14b5af2..05cbd2c 100644
--- a/initial_setup/tui/tui.py
+++ b/initial_setup/tui/tui.py
@@ -1,5 +1,5 @@
from pyanaconda.ui.tui import TextUserInterface
-#from .product import productName, productVersion
+from initial_setup.product import product_title, is_final
from .hubs import InitialSetupMainHub
from pyanaconda.ui.tui.spokes import StandaloneSpoke
import pyanaconda.ui.tui.spokes
@@ -12,25 +12,22 @@ from di import inject, usesclassinject
_ = lambda t: t
N_ = lambda t: t
-productTitle = lambda: "Initial Setup of Fedora"
-isFinal = lambda: False
-
QUIT_MESSAGE = N_("Are you sure you want to quit the configuration process?\n"
"You might end up with unusable system if you do.")
-@inject(productTitle = productTitle, isFinal = isFinal)
+@inject(product_title = product_title, is_final = is_final)
class InitialSetupTextUserInterface(TextUserInterface):
"""This is the main text based firstboot interface. It inherits from
anaconda to make the look & feel as similar as possible.
"""
ENVIRONMENT = "firstboot"
-
+
@usesclassinject
def __init__(self, storage, payload, instclass):
TextUserInterface.__init__(self, storage, payload, instclass,
- productTitle, isFinal, quitMessage = QUIT_MESSAGE)
-
+ product_title, is_final, quitMessage = QUIT_MESSAGE)
+
def _list_hubs(self):
return [InitialSetupMainHub]
--
1.7.11.7
10 years, 8 months
[master] Another solution for a bug fixed in a different way
by Vratislav Podzimek
I think this should go to rhel7-branch as well.
Vratislav Podzimek (1):
Setup language early to a value we can figure out
anaconda | 9 ++++++---
pyanaconda/ui/gui/hubs/progress.py | 10 ++--------
2 files changed, 8 insertions(+), 11 deletions(-)
--
1.7.11.7
10 years, 8 months
[master/rhel7-branch] Warn user if they enter a weak password in TUI. (#1001039)
by Samantha N. Bueno
This is in keeping some consistency with GUI behavior, check a user's
pw quality score and warn/prompt them to confirm whether they are ok
with using a weak pw.
Resolves: rhbz#1001039
---
pyanaconda/ui/tui/spokes/__init__.py | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/ui/tui/spokes/__init__.py b/pyanaconda/ui/tui/spokes/__init__.py
index 2f92126..fc904b3 100644
--- a/pyanaconda/ui/tui/spokes/__init__.py
+++ b/pyanaconda/ui/tui/spokes/__init__.py
@@ -22,7 +22,7 @@ from pyanaconda.ui.tui import simpleline as tui
from pyanaconda.ui.tui.tuiobject import TUIObject, YesNoDialog
from pyanaconda.ui.common import Spoke, StandaloneSpoke, NormalSpoke, PersonalizationSpoke, collect
from pyanaconda.users import validatePassword
-from pwquality import PWQError
+import pwquality
import re
from collections import namedtuple
from pyanaconda.iutil import setdeepattr, getdeepattr
@@ -104,6 +104,25 @@ class EditTUIDialog(NormalTUISpoke):
return True
def prompt(self, entry = None):
+ def _validatePassword(pw, confirm):
+ """ Better password checking. This sets up a quality checker
+ to score password attempts. This is similar to the pw quality
+ check done in the GUI, except this only raises an error if a
+ password is weak.
+ """
+ # set up quality checker
+ _pwq = pwquality.PWQSettings()
+ _pwq.read_config()
+
+ error = validatePassword(pw, confirm)
+ if error:
+ return error
+ strength = _pwq.check(pw, None, None)
+ if strength < 50:
+ raise pwquality.PWQError
+ else:
+ return None
+
if not entry:
return None
@@ -114,11 +133,11 @@ class EditTUIDialog(NormalTUISpoke):
# just returning an error is either blank or mismatched
# passwords. Raising is because of poor quality.
try:
- error = validatePassword(pw, confirm)
+ error = _validatePassword(pw, confirm)
if error:
print(error)
return None
- except PWQError as e:
+ except pwquality.PWQError as e:
error = _("You have provided a weak password: %s. " % e.message)
error += _("\nWould you like to use it anyway?")
question_window = YesNoDialog(self._app, error)
--
1.7.11.7
10 years, 8 months
[pykickstart rhel7-branch/master][PATCH] Return None for attributes if no method has been set (#1002371)
by David Shea
The method proxy was returning "url" for method.method if no method had
been set, and delegating other attributes to the URL handler. Instead,
return None until one of the handlers has been selected by setting
method.method.
---
pykickstart/commands/method.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/pykickstart/commands/method.py b/pykickstart/commands/method.py
index fb55f25..1e0cf90 100644
--- a/pykickstart/commands/method.py
+++ b/pykickstart/commands/method.py
@@ -44,11 +44,13 @@ class FC3_Method(KickstartCommand):
return "nfs"
else:
return getattr(self.handler.nfs, name)
- else:
+ elif self.handler.url.seen:
if name == "method":
return "url"
else:
return getattr(self.handler.url, name)
+ else:
+ return None
def __setattr__(self, name, value):
if name in self.internals:
--
1.8.3.1
10 years, 8 months
[master][PATCH] Search for all translations, not only one per langauge (#1001446)
by Vratislav Podzimek
There are often more translations for various language-territory combinations.
E.g. en_US and en_GB or zh_TW and zh_CN etc.
Related: rhbz#1000715
Signed-off-by: Vratislav Podzimek <vpodzime(a)redhat.com>
---
pyanaconda/localization.py | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/pyanaconda/localization.py b/pyanaconda/localization.py
index 1997ac0..fc334b7 100644
--- a/pyanaconda/localization.py
+++ b/pyanaconda/localization.py
@@ -228,20 +228,21 @@ def get_available_translations(domain=None, localedir=None):
messagefiles = sorted(glob.glob(localedir + "/*/LC_MESSAGES/anaconda.mo"))
trans_gen = (path.split(os.path.sep)[-3] for path in messagefiles)
- # usually there are no message files for en
- langs = {"en"}
+ yielded_locales = {"en_US.UTF-8"}
yield "en_US.UTF-8"
for trans in trans_gen:
parts = parse_langcode(trans)
- lang = parts.get("language", "")
- if lang and lang not in langs:
- langs.add(lang)
- locales = get_language_locales(lang)
- if not locales:
- continue
-
- # take the first locale (with highest rank) for the language
+ if not parts:
+ continue
+
+ locales = get_language_locales(trans)
+ if not locales:
+ continue
+
+ # take the first locale (with highest rank) for the language
+ if locales[0] not in yielded_locales:
+ yielded_locales.add(locales[0])
yield locales[0]
def get_language_locales(lang):
--
1.7.11.7
10 years, 8 months