[PATCH 1/3] Add the User creation spoke including the Advanced dialog

Vratislav Podzimek vpodzime at redhat.com
Tue Feb 12 11:41:22 UTC 2013


On Mon, 2013-02-11 at 14:24 +0100, Martin Sivak wrote:
> ---
>  pyanaconda/ui/gui/spokes/advanced_user.glade | 429 +++++++++++++++++++++++++++
>  pyanaconda/ui/gui/spokes/password.py         |   2 +-
>  pyanaconda/ui/gui/spokes/user.glade          | 363 +++++++++++++++++++++++
>  pyanaconda/ui/gui/spokes/user.py             | 421 ++++++++++++++++++++++++++
>  4 files changed, 1214 insertions(+), 1 deletion(-)
>  create mode 100644 pyanaconda/ui/gui/spokes/advanced_user.glade
>  create mode 100644 pyanaconda/ui/gui/spokes/user.glade
>  create mode 100644 pyanaconda/ui/gui/spokes/user.py

> diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py
> new file mode 100644
> index 0000000..6655be6
> --- /dev/null
> +++ b/pyanaconda/ui/gui/spokes/user.py
> @@ -0,0 +1,421 @@
> +# User creation spoke
> +#
> +# Copyright (C) 2012 Red Hat, Inc.
                  ^^ 2013 :)

> +#
> +# 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): Martin Sivak <msivak at redhat.com>
> +#
> +
> +import gettext
> +_ = lambda x: gettext.ldgettext("anaconda", x)
> +N_ = lambda x: x
> +
> +from gi.repository import Gtk
> +
> +from pyanaconda.users import cryptPassword, validatePassword
> +from pwquality import PWQError
> +import string
> +
> +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.common import FirstbootSpokeMixIn
> +from pyanaconda.ui.gui.utils import enlightbox
> +
> +import unicodedata
> +import pwquality
> +
> +__all__ = ["UserSpoke", "AdvancedUserDialog"]
> +
> +def strip_accents(s):
> +    """This function takes arbitrary unicode string
> +    and returns it with all the diacritics removed.
> +
> +    :param s: arbitrary string
> +    :type s: unicode
> +
> +    :return: s with diacritics removed
> +    :rtype: unicode
> +
> +    """
> +    return ''.join((c for c in unicodedata.normalize('NFD', s)
> +                      if unicodedata.category(c) != 'Mn'))
> +
> +class AdvancedUserDialog(GUIObject):
> +    builderObjects = ["advancedUserDialog", "uid", "gid"]
> +    mainWidgetName = "advancedUserDialog"
> +    uiFile = "advanced_user.glade"
> +
> +    def __init__(self, user, groupDict, data):
> +        GUIObject.__init__(self, data)
> +        self._user = user
> +        self._groupDict = groupDict
> +
> +    def initialize(self):
> +        pass
> +
> +    def _checkboxes(self, _editable, data = None):
> +        """Update the state of this screen according to the
> +        checkbox states on the screen. It is called from
> +        the toggled Gtk event.
> +        """
I believe this method should have a better "action-based" name like
"_update_checkboxes_sensitivity" or something like that.

> +        c_home = self.builder.get_object("c_home").get_active()
> +        c_uid = self.builder.get_object("c_uid").get_active()
> +        c_gid = self.builder.get_object("c_gid").get_active()
> +
> +        self.builder.get_object("t_home").set_sensitive(c_home)
> +        self.builder.get_object("l_home").set_sensitive(c_home)
> +        self.builder.get_object("spin_uid").set_sensitive(c_uid)
> +        self.builder.get_object("spin_gid").set_sensitive(c_gid)
> +
> +    def refresh(self):
> +        t_home = self.builder.get_object("t_home")
> +        if self._user.homedir:
> +            t_home.set_text(self._user.homedir)
> +        elif self._user.name:
> +            t_home.set_text("/home/%s" % self._user.name)
> +
> +        groups = []
> +        for group_name in self._user.groups:
> +            group = self._groupDict[group_name]
> +
> +            if group.name and group.gid is not None:
> +                groups.append("%s (%d)" % (group.name, group.gid))
> +            elif group.name:
> +                groups.append(group.name)
> +            elif group.gid is not None:
> +                groups.append("(%d)" % (group.gid,))
> +
> +        self.builder.get_object("t_groups").set_text(", ".join(groups))
> +
> +    def run(self):
> +        self.window.show()
> +        rc = self.window.run()
> +        self.window.hide()
> +
> +        #OK clicked
> +        if rc == 1:
> +            if self.builder.get_object("c_home").get_active():
> +                self._user.homedir = self.builder.get_object("t_home").get_text()
> +            else:
> +                self._user.homedir = None
> +
> +            if self.builder.get_object("c_uid").get_active():
> +                self._user.uid = int(self.builder.get_object("uid").get_value())
> +            else:
> +                self._user.uid = None
> +
> +            if self.builder.get_object("c_gid").get_active():
> +                pass
> +                #self._user.gid = int(self.builder.get_widget("gid").get_value())
> +            else:
> +                #self._user.gid = None
> +                pass
Some leftovers?

> +
> +            groups = self.builder.get_object("t_groups").get_text().split(",")
> +            self._user.groups = []
> +            for group in groups:
> +                group = group.strip()
> +                if group not in self._groupDict:
> +                    self._groupDict[group] = self.data.GroupData(name = group)
> +                self._user.groups.append(group)
> +
> +        #Cancel clicked, window destroyed...
> +        else:
> +            pass
> +
> +        return rc
> +
> +
> +
> +class UserSpoke(FirstbootSpokeMixIn, NormalSpoke):
> +    builderObjects = ["userCreationWindow"]
> +
> +    mainWidgetName = "userCreationWindow"
> +    uiFile = "spokes/user.glade"
> +
> +    category = UserSettingsCategory
> +
> +    icon = "avatar-default-symbolic"
> +    title = N_("_USER CREATION")
> +
> +    def __init__(self, *args):
> +        NormalSpoke.__init__(self, *args)
> +        self._oldweak = None
> +        self._error = None
> +
> +    def initialize(self):
> +        NormalSpoke.initialize(self)
> +        self._user = self.data.UserData()
> +        self._wheel = self.data.GroupData(name = "wheel")
> +        self._groupDict = {"wheel": self._wheel}
> +
> +        # place holders for the text boxes
> +        self.fullname = self.builder.get_object("t_fullname")
> +        self.username = self.builder.get_object("t_username")
> +        self.pw = self.builder.get_object("t_password")
> +        self.confirm = self.builder.get_object("t_verifypassword")
> +        self.admin = self.builder.get_object("c_admin")
> +        self.usepassword = self.builder.get_object("c_usepassword")
> +
> +        self.guesser = {
> +            self.username: True
> +            }
> +
> +        self.pw.connect("changed", self._checkPassword)
> +        self.confirm.connect("changed", self._checkPassword)
> +        self.fullname.connect("changed", self._guessNames)
> +        self.username.connect("changed", self._guessNameDisabler)
> +        self.usepassword.connect("toggled", self._passwordDisabler)
These should go to the .glade file, if possible.

-- 
Vratislav Podzimek

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



More information about the anaconda-patches mailing list