From 2cb3df32c47c5f125af9aaa5224fac3eb49204a0 Mon Sep 17 00:00:00 2001 From: g7 Date: Sun, 15 Jan 2012 16:36:26 +0100 Subject: [PATCH] * Added mirrorselect module. * Begin work on the gtk3 frontend. * Fixed crash if some updates are found. --- .bzrignore | 4 + config/semplice-base | 8 +- debian/changelog | 8 + debian/linstaller-modules-base.install | 1 + linstaller/frontends/gtk3.py | 331 ++++++++++++++++++ linstaller/modules/mirrorselect/__init__.py | 0 .../modules/mirrorselect/front/__init__.py | 20 ++ linstaller/modules/mirrorselect/front/cli.py | 42 +++ .../modules/mirrorselect/inst/__init__.py | 49 +++ linstaller/modules/mirrorselect/inst/cli.py | 44 +++ linstaller/modules/update/front/__init__.py | 4 +- linstaller/modules/userhost/front/gtk3.py | 216 ++++++++++++ linstaller/modules/welcome/front/gtk3.py | 33 ++ setup.py | 4 + 14 files changed, 760 insertions(+), 4 deletions(-) create mode 100644 linstaller/frontends/gtk3.py create mode 100644 linstaller/modules/mirrorselect/__init__.py create mode 100644 linstaller/modules/mirrorselect/front/__init__.py create mode 100644 linstaller/modules/mirrorselect/front/cli.py create mode 100644 linstaller/modules/mirrorselect/inst/__init__.py create mode 100644 linstaller/modules/mirrorselect/inst/cli.py create mode 100644 linstaller/modules/userhost/front/gtk3.py create mode 100644 linstaller/modules/welcome/front/gtk3.py diff --git a/.bzrignore b/.bzrignore index bfe5c93..4a09292 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1 +1,5 @@ linstaller/modules/*/*.old +linstaller/modules/*/*/gtk3.* +linstaller/frontends/gtk3.py +linstaller/modules/welcome/front/gtk3.py +linstaller/modules/userhost/front/gtk3.py diff --git a/config/semplice-base b/config/semplice-base index f530ff5..f0220c8 100644 --- a/config/semplice-base +++ b/config/semplice-base @@ -2,7 +2,7 @@ [linstaller] distribution = Semplice -modules = welcome.front language.front update.front timezone.front userhost.front partdisks.front bootloader.front summary.front partdisks.inst unsquash.inst language.inst timezone.inst userhost.inst fstab.inst debian.inst semplice.inst clean.inst bootloader.inst end.front +modules = welcome.front language.front update.front timezone.front userhost.front partdisks.front bootloader.front mirrorselect.front summary.front partdisks.inst unsquash.inst language.inst timezone.inst userhost.inst fstab.inst debian.inst semplice.inst mirrorselect.inst clean.inst bootloader.inst end.front special = partdisks.inst unsquash.inst [module:unsquash] @@ -12,4 +12,8 @@ image = /live/image/live/filesystem.squashfs remove = /live/image/live/filesystem.packages-remove [module:update] -packages = linstaller linstaller-modules-base linstaller-config-semplice alan-ext-linstaller +packages = linstaller linstaller-frontend-cli linstaller-modules-base linstaller-config-semplice alan-ext-linstaller + +[module:mirrorselect] +enable_sources = False +sets = debian semplice diff --git a/debian/changelog b/debian/changelog index 7710bc0..22e5a04 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +linstaller (2.10.4-1) pulse; urgency=low + + * Added mirrorselect module. + * Begin work on the gtk3 frontend. + * Fixed crash if some updates are found. + + -- Eugenio Paolantonio (g7) Sun, 15 Jan 2012 16:34:21 +0100 + linstaller (2.10.3-1) pulse; urgency=low * userhost: renamed the password_max_chars preseed to password_min_chars: diff --git a/debian/linstaller-modules-base.install b/debian/linstaller-modules-base.install index a48e2f7..38581fb 100644 --- a/debian/linstaller-modules-base.install +++ b/debian/linstaller-modules-base.install @@ -1,5 +1,6 @@ /usr/share/linstaller/linstaller/modules/bootloader /usr/share/linstaller/linstaller/modules/debian +/usr/share/linstaller/linstaller/modules/mirrorselect /usr/share/linstaller/linstaller/modules/clean /usr/share/linstaller/linstaller/modules/semplice /usr/share/linstaller/linstaller/modules/end diff --git a/linstaller/frontends/gtk3.py b/linstaller/frontends/gtk3.py new file mode 100644 index 0000000..c5f5658 --- /dev/null +++ b/linstaller/frontends/gtk3.py @@ -0,0 +1,331 @@ +# -*- coding: utf-8 -*- +# linstaller gtk3 frontend - (C) 2011-12 Eugenio "g7" Paolantonio and the Semplice Team. +# All rights reserved. Work released under the GNU GPL license, version 3 or later. +# +# This is a frontend of linstaller, should not be executed as a standalone application. + +import os, sys +import getpass + +from gi.repository import Gtk, Gdk + +import linstaller.core.main as m +from linstaller.core.main import warn,info,verbose + +import t9n.library +_ = t9n.library.translation_init("linstaller") + +### HEADER TYPES ### +head_col = {"error":"#F07568","info":"#729fcf","ok":"#73d216","hold":"#f57900"} +head_ico = {"info":Gtk.STOCK_INFO,"error":Gtk.STOCK_DIALOG_ERROR,"ok":Gtk.STOCK_OK,"hold":Gtk.STOCK_EXECUTE} + +class Frontend: + class InstallerWindow(Gtk.Window): + def __init__(self, frontend, header=False): + """ Initialize the InstallerWindow. """ + + Gtk.Window.__init__(self, title=header) + + self.frontend = frontend + + self.main_vbox = Gtk.VBox() # Create the main vbox. + self.add(self.main_vbox) # Add the main vbox to the window. + + self.connect("delete-event",self.on_cancel) + + # Create the fixed three buttons at bottom + self.button_cancel = Gtk.Button(stock=Gtk.STOCK_CANCEL) + self.button_next = Gtk.Button(stock=Gtk.STOCK_GO_FORWARD) + self.button_back = Gtk.Button(stock=Gtk.STOCK_GO_BACK) + + self.button_cancel.connect("clicked",self.on_cancel) + self.button_next.connect("clicked",self.on_next) + self.button_back.connect("clicked",self.on_back) + + self.button_box = Gtk.ButtonBox() + self.button_box.pack_start(self.button_cancel, True, True, 0) + self.button_box.pack_start(self.button_next, True, True, 0) + self.button_box.pack_start(self.button_back, True, True, 0) + + # Create another vbox, on which put the header. + self.page_vbox = Gtk.VBox() + + self.main_vbox.pack_start(self.page_vbox, True, True, 0) + # Add the button_box to the end of the main vbox + self.main_vbox.pack_end(self.button_box, True, True, 0) + + # Create the header. + self.header_eventbox = Gtk.EventBox() + self.header = Gtk.HBox() + self.header_icon = Gtk.Image() + self.header_message_container = Gtk.VBox() + self.header_message_title = Gtk.Label() + self.header_message_subtitle = Gtk.Label() + + self.header_message_container.pack_start(self.header_message_title, True, True, 0) + self.header_message_container.pack_start(self.header_message_subtitle, True, True, 0) + + self.header.pack_start(self.header_icon, True, True, 0) + self.header.pack_start(self.header_message_container, True, True, 0) + + self.header_eventbox.add(self.header) + self.page_vbox.pack_start(self.header_eventbox, True, True, 0) + + def set_header(self, icon, title, subtitle): + """ Sets the header with the delcared icon, title and subtitle. """ + + # Get color + color_s = head_col[icon] + color = Gdk.RGBA() + color.parse(color_s) + + # Get icon + icon = head_ico[icon] + + # Set icon + self.header_icon.set_from_stock(icon, 6) + # Set header message and window title + self.header_message_title.set_markup("%s" % title) + self.header_message_subtitle.set_text(subtitle) + self.set_title(title) + + # Set color + self.header_eventbox.override_background_color(0, color) + + def text_new(self, string=""): + """ Adds new text to the page_vbox. """ + + text = Gtk.Label() + text.set_markup(string) + text.show() + + self.page_vbox.pack_start(text, True, True, 0) + + def entry(self, string, password=False): + """ Adds a new entry to the page_vbox. """ + + container = Gtk.HBox() + label = Gtk.Label() + text = label.set_markup(string) + entry = Gtk.Entry() + if password: + entry.set_visibility(False) + + container.pack_start(label, True, True, 0) + container.pack_start(entry, True, True, 0) + container.show_all() + + self.page_vbox.pack_start(container, True, True, 0) + + return container, entry + + def password_entry(self, string): + """ Adds a new password entry to the page_vbox. """ + + return self.entry(string, password=True) + + def password_entry_with_confirm(self, string): + """ Adds two password entries to the page_vbox. + Returns both entry object. """ + + entry1 = self.password_entry(string) + entry2 = self.password_entry(string + _(" (again)")) + + return entry1, entry2 + + def switch(self, string, default=False): + """ Adds a new switch to the page_vbox. """ + + container = Gtk.HBox() + label = Gtk.Label() + text = label.set_markup(string) + switch = Gtk.Switch() + if default: + switch.set_active(True) + else: + switch.set_active(False) + + container.pack_start(label, True, True, 0) + container.pack_start(switch, True, True, 0) + container.show_all() + + self.page_vbox.pack_start(container, True, True, 0) + + return container, switch + + def reset_position(self): + """ Resets the window position. """ + + self.set_position(Gtk.WindowPosition.CENTER) + + def on_cancel(self, button, other=None): + Gtk.main_quit() + self.frontend.end() + + def on_back(self, button): + Gtk.main_quit() + return "back" + + def on_next(self, button): + Gtk.main_quit() + return + + + def __init__(self, moduleclass): + + self.moduleclass = moduleclass + self.settings = moduleclass.settings + self.changed = moduleclass.changed + + self.window = self.InstallerWindow(self) + self.window.show_all() + + def end(self): + """ close frontend and parents. """ + + verbose("User requested to end.") + sys.exit(0) + + def header(self, _pass): + """ Displays the installer's header (new page) """ + + # First, running "clear" + os.system("clear") + + # Second, write the header + print(_pass) + # Now write ------- lines after the pass + for num in range(0, len(_pass)): + sys.stdout.write("-") + sys.stdout.write("\n\n") + + def entry(self, text, password=False, blank=False): + """ Displays and entry prompt (normal or password) """ + + if password == True: + choice = getpass.getpass(text + ": ") + else: + choice = raw_input(text + ": ") + + if not choice and blank == False: + warn(_("You must insert something!")) + return self.entry(text, password=password, blank=blank) + else: + return choice + + def question(self, text, default=None): + """ A simple yes/no prompt. + + if default == None; the user should insert y or n + if default == False; the user can press ENTER to say n + if default == True; the user can press ENTER to say y + """ + + if default != None: + # We can enable blank on entry. + blank = True + if default == True: + # Modify suffix: + prompt_suffix = _("[Y/n]") + else: + # default = False + prompt_suffix = _("[y/N]") + else: + # Nothing default... + prompt_suffix = _("[y/n]") + blank = False + + result = self.entry("%s %s" % (text, prompt_suffix), blank=blank) + if not result: + # result is "", so blank == True... we should set to "y" or "n" according to default. + if default: + # = yes + result = True + else: + # = no + result = False + else: + # result is populated. + result = result.lower() # Make sure it is all lowered + if _("y") == result: + # Set y, untranslated. + result = True + elif _("n") == result: + # Set n, untranslated. + result = False + elif _("yes") in result: + # This should be y. + result = True + elif _("no") in result: + # This should be n. + result = False + else: + # Unknown value... + warn(_("Unknown value %s. Please re-try." % result)) + result = self.question(text, default=default) + + # Finally return value + return result + + def progressbar(self, text, maxval): + """ Creates a progressbar object. """ + + widgets = [text, progressbar.Percentage(), ' ', progressbar.Bar(marker='#',left='[',right=']'),' ', progressbar.ETA()] + return self.__ProgressBar(widgets=widgets, maxval=maxval) + + def action_list(self, lst, typ="ordered", after=False, selection_text=_("Please insert your action here"), skip_list=False): + """ Creates a ordered/unordered list. + + Paramters: + lst = dictionary that contains action name and action to be executed. + type = "ordered" or "unordered". Default is "ordered". + after = str that will be printed after the list. + selection_text = text of the selection entry + + skip_list = internal + + WARNING: UNORDERED LIST WILL *NOT* PROMPT FOR ANYTHING. + """ + + actions = {} + + ORDERED_OPERATOR = 0 + UNORDERED_OPERATOR = "*" + + if not skip_list: + if typ == "unordered": + # unordered uses tuples/lists for actions. + + for thing in lst: + print " %s %s" % (UNORDERED_OPERATOR, thing) + else: + # An example lst: {"Format partition":self.edit_partitions_format, ...} + + for name, action in lst.items(): + ORDERED_OPERATOR += 1 # Increase the operator by one + + # Print string + print " %d) %s" % (ORDERED_OPERATOR, name) + + # Link number to action + actions[ORDERED_OPERATOR] = action + + # Print after. + if after: print "\n" + after + + if typ == "unordered": return # If unordered, exit. + + print + + # Make the question + result = self.entry(selection_text) + try: + result = int(result) + except: + return self.list(lst, typ=typ, selection_text=selection_text, skip_list=True) + if not result in actions: + return self.list(lst, typ=typ, selection_text=selection_text, skip_list=True) + + return actions[result] + + diff --git a/linstaller/modules/mirrorselect/__init__.py b/linstaller/modules/mirrorselect/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/linstaller/modules/mirrorselect/front/__init__.py b/linstaller/modules/mirrorselect/front/__init__.py new file mode 100644 index 0000000..04f47e2 --- /dev/null +++ b/linstaller/modules/mirrorselect/front/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# linstaller language module frontend - (C) 2012 Eugenio "g7" Paolantonio and the Semplice Team. +# All rights reserved. Work released under the GNU GPL license, version 3 or later. +# +# This is a module of linstaller, should not be executed as a standalone application. + +import linstaller.core.module as module + +class Module(module.Module): + def start(self): + """ Start module. """ + + module.Module.start(self) + + def seedpre(self): + """ Caches variables used by this module. """ + + self.cache("check") + self.cache("sets", "debian") + self.cache("enable_sources") diff --git a/linstaller/modules/mirrorselect/front/cli.py b/linstaller/modules/mirrorselect/front/cli.py new file mode 100644 index 0000000..21cba98 --- /dev/null +++ b/linstaller/modules/mirrorselect/front/cli.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# linstaller language module frontend - (C) 2011 Eugenio "g7" Paolantonio and the Semplice Team. +# All rights reserved. Work released under the GNU GPL license, version 3 or later. +# +# This is a module of linstaller, should not be executed as a standalone application. + +import linstaller.frontends.cli as cli +import linstaller.core.main as m +import t9n.library +_ = t9n.library.translation_init("linstaller") + +from linstaller.core.main import warn,info,verbose + +class Frontend(cli.Frontend): + def start(self): + """ Start the frontend """ + + self.header(_("Mirror selection")) + + if self.settings["check"] == False: + + print(_("%(distroname)s has many mirrors worldwide.") % {"distroname":self.moduleclass.main_settings["distro"]}) + print(_("You can let the installer to test all mirrors and to find the fastest for your zone.")) + print + print(_("This requires a working internet connection.")) + print + + # We should continue? + res = self.question(_("Do you want to check for the fastest mirror?"), default=True) + if res: + self.settings["check"] = True + else: + self.settings["check"] = None + + if self.settings["enable_sources"] == None: + # Ask if we should enable deb-src entries + res = self.question(_("Do you want to enable deb-src entries?"), default=False) + if res: + self.settings["enable_sources"] = True + else: + self.settings["enable_sources"] = None + diff --git a/linstaller/modules/mirrorselect/inst/__init__.py b/linstaller/modules/mirrorselect/inst/__init__.py new file mode 100644 index 0000000..0d7e28c --- /dev/null +++ b/linstaller/modules/mirrorselect/inst/__init__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# linstaller mirrorselect module install - (C) 2012 Eugenio "g7" Paolantonio and the Semplice Team. +# All rights reserved. Work released under the GNU GPL license, version 3 or later. +# +# This is a module of linstaller, should not be executed as a standalone application. + +import linstaller.core.module as module +import os +import linstaller.core.main as m + +from linstaller.core.main import info,warn,verbose + +class Install(module.Install): + def prechecks(self): + """ Checks if mirrorselect exists and a working internet connection is present. """ + + if not os.path.exists("/usr/bin/mirrorselect"): + verbose("mirrorselect is not installed.") + return False + + try: + m.sexec("ping -c1 www.google.com") + except: + # No connection + verbose("A working internet connection is not present.") + return False + + return True + + def select(self, set): + """ Selects the fastest mirror using mirrorselect. """ + + verbose("Running mirrorselect with set %s..." % set) + + # Create arguments + args = [] + args.append("-s %s" % set) # Set + args.append("-n") # Non-interactive + if self.moduleclass.modules_settings["mirrorselect"]["enable_sources"]: args.append("-o") # Enable sources + + m.sexec("/usr/bin/mirrorselect %s" % " ".join(args)) + +class Module(module.Module): + def start(self): + """ Start module. """ + + self.install = Install(self) + + module.Module.start(self) diff --git a/linstaller/modules/mirrorselect/inst/cli.py b/linstaller/modules/mirrorselect/inst/cli.py new file mode 100644 index 0000000..7b78e5b --- /dev/null +++ b/linstaller/modules/mirrorselect/inst/cli.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# linstaller mirrorselect module install - (C) 2012 Eugenio "g7" Paolantonio and the Semplice Team. +# All rights reserved. Work released under the GNU GPL license, version 3 or later. +# +# This is a module of linstaller, should not be executed as a standalone application. + +import linstaller.frontends.cli as cli +import linstaller.core.main as m +import t9n.library +_ = t9n.library.translation_init("linstaller") + +from linstaller.core.main import warn,info,verbose + +class Frontend(cli.Frontend): + def start(self): + """ Start the frontend """ + + # Sets + sets = self.moduleclass.modules_settings["mirrorselect"]["sets"].split(" ") + check = self.moduleclass.modules_settings["mirrorselect"]["check"] + + if check == None: + return # Should not check + + if not self.moduleclass.install.prechecks(): + return # We can't continue. + + # Get a progressbar + progress = self.progressbar(_("Selecting mirrors:"), len(sets)) + + # Start progressbar + progress.start() + + try: + num = 0 + for set in sets: + num += 1 + self.moduleclass.install.select(set) + progress.update(num) + finally: + # Exit from chroot + self.moduleclass.install.close() + + progress.finish() diff --git a/linstaller/modules/update/front/__init__.py b/linstaller/modules/update/front/__init__.py index 7ace7b8..dd8321c 100644 --- a/linstaller/modules/update/front/__init__.py +++ b/linstaller/modules/update/front/__init__.py @@ -38,7 +38,7 @@ def check(self): for pkg in pkgs: try: if self.cac[pkg].is_upgradable: - info(_("Found version %(version)s of %(package)s.") % {"package":pkg, "version":cac[pkg].candidate.version}) + info(_("Found version %(version)s of %(package)s.") % {"package":pkg, "version":self.cac[pkg].candidate.version}) verbose("Marking %s to be upgrated." % pkg) self.cac[pkg].mark_upgrade() atleastone = True @@ -67,4 +67,4 @@ def start(self): def seedpre(self): """ Caches variables used by this module. """ - self.cache("packages", "linstaller linstaller-modules-base") + self.cache("packages", "linstaller linstaller-modules-base linstaller-frontend-cli") diff --git a/linstaller/modules/userhost/front/gtk3.py b/linstaller/modules/userhost/front/gtk3.py new file mode 100644 index 0000000..620285e --- /dev/null +++ b/linstaller/modules/userhost/front/gtk3.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# linstaller timezone module frontend - (C) 2011 Eugenio "g7" Paolantonio and the Semplice Team. +# All rights reserved. Work released under the GNU GPL license, version 3 or later. +# +# This is a module of linstaller, should not be executed as a standalone application. + +import linstaller.frontends.gtk3 as gtk3 +import linstaller.core.main as m +import t9n.library +_ = t9n.library.translation_init("linstaller") + +from linstaller.core.main import warn,info,verbose + +class Frontend(gtk3.Frontend): + def start(self): + """ Start the frontend """ + + self.window.set_header("info", _("Users & Hostname"), _("Set users and hostname")) + + # Initial user + userfullname_container, userfullname = self.window.entry(_("New user's full name (e.g. John Doe)")) + username_container, username = self.window.entry(_("%s's username (no spaces; e.g: john)") % self.settings["userfullname"]) + self.window.text_new() + + # Passwords + password1, password2 = self.window.password_entry_with_confirm(_("%s's password") % self.settings["userfullname"]) + self.window.text_new() + + password1_container, password1 = password1 + password2_container, password2 = password2 + + # Root + root_switch_container, root_switch = self.window.switch(_("Do you want to enable root account?"), default=False) + root_password1, root_password2 = self.window.password_entry_with_confirm(_("root's password")) + + root_password1_container, root_password1 = root_password1 # Split the confirms + root_password2_container, root_password2 = root_password2 # Same. + + # Hostname + hostname_container, hostname = self.window.entry(_("Computer's name (e.g. johndesktop)")) + + # Set and hide + if self.settings["userfullname"]: + userfullname_container.hide() + userfullname.set_text(self.settings["userfullname"]) + if self.settings["username"]: + username_container.hide() + username.set_text(self.settings["username"]) + if self.settings["password"]: + password1_container.hide() + password2_container.hide() + password1.set_text(self.settings["password"]) + password2.set_text(self.settings["password"]) + if not self.settings["root"] == None: + # We should at least handle root. + if self.settings["root"]: + # Is true, make the switch True. + root_switch.set_active(True) + if self.settings["rootpassword"]: + # Set password and hide entries + root_password1_container.hide() + root_password2_container.hide() + root_password1.set_text(self.settings["rootpassword"]) + root_password2.set_text(self.settings["rootpassword"]) + else: + # Hide all + root_switch_container.hide() + root_password1_container.hide() + root_password2_container.hide() + verbose("Root disabled.") + if self.settings["hostname"]: + hostname_container.hide() + hostname.set_text(self.settings["hostname"]) + + # Connect. + userfullname.connect("changed", self.on_userfullname_change) + username.connect("changed", self.on_username_change) + password1.connect("changed", self.on_password_change) + password2.connect("changed", self.on_password_change) + root_switch.connect("activate", self.on_rootswitch_change) + root_password1.connect("changed", self.on_root_password_change) + root_password2.connect("changed", self.on_root_password_change) + hostname.connect("changed", self.on_hostname_change) + + gtk3.Gtk.main() + + def on_userfullname_change(self, obj): + """ Handles userfullname change. """ + + self.window.set_header("error", "LOL", "ASD") + + def on_username_change(self, obj): + """ Handles username change. """ + + pass + + def on_password_change(self, obj): + """ Handles password change. """ + + pass + + def on_rootswitch_change(self, obj, other): + """ Handles rootswitch change. """ + + pass + + def on_root_password_change(self, obj): + """ Handles root password change. """ + + pass + + def on_hostname_change(self, obj): + """ Handles hostname change. """ + + pass + +# if not self.settings["root"] == None: +# if not self.settings["root"]: +# res = self.window.switch(_("Do you want to enable root account?"), default=False) +# else: +# res = True +# if res and not self.settings["rootpassword"]: +# self.settings["rootpassword"] = self.password_prompt(_("root's password")) +# self.settings["root"] = True +# verbose("Selected root password.") +# elif not res: +# verbose("Root disabled.") +# else: +# verbose("preseeded root password.") +# print +# else: +# root_switch_container.hide() # Hide root switch +# root_password1_container.hide() +# root_password2_container.hide() # Hide password entries +# verbose("Root disabled.") + + + + # Users + if not self.settings["userfullname"]: + self.settings["userfullname"] = self.entry(_("New user's full name (e.g. John Doe)")) + if not self.settings["username"]: + self.settings["username"] = self.check("username", _("%s's username (no spaces; e.g: john)") % self.settings["userfullname"]) + print + + verbose("Selected username %s (%s)." % (self.settings["username"], self.settings["userfullname"])) + + # Passwords + if not self.settings["password"]: + self.settings["password"] = self.password_prompt(_("%s's password") % self.settings["userfullname"]) + print + + verbose("Selected password.") + + # Root + if not self.settings["root"] == None: + if not self.settings["root"]: + res = self.question(_("Do you want to enable root account?"), default=False) + else: + res = True + if res and not self.settings["rootpassword"]: + self.settings["rootpassword"] = self.password_prompt(_("root's password")) + self.settings["root"] = True + verbose("Selected root password.") + elif not res: + verbose("Root disabled.") + else: + verbose("preseeded root password.") + print + else: + verbose("Root disabled.") + + + # Hostname + if not self.settings["hostname"]: + self.settings["hostname"] = self.check("hostname", _("Computer's name (e.g. johndesktop)")) + + verbose("Selected hostname %s." % self.settings["hostname"]) + + def check(self, what, text): + """ Checks if a hostname/username is valid. """ + + if what == "hostname": + ALLOWED_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-" + else: + ALLOWED_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789.-" + + string = self.entry(text) + + unallowed = [] + for lettera in string: + if lettera not in ALLOWED_CHARS: + unallowed += lettera + + if unallowed: + warn(_("You can't use these chars in the %s, please re-try: ") % (what) + str(unallowed)) + return self.check(what, text) + else: + return string + + def password_prompt(self, text): + """ A simple password prompt """ + + passw1 = self.entry(text, password=True) + if len(passw1) < 6: + # Pasword lenght is lesser than six + warn(_("The password should be composed of at least six charchters.")) + return self.password_prompt(text) + passw2 = self.entry(text + _(" (again)"), password=True) + + if not passw1 == passw2: + # Wrong! + warn(_("The passwords don't match! Please retry.")) + return self.password_prompt(text) + else: + return passw1 diff --git a/linstaller/modules/welcome/front/gtk3.py b/linstaller/modules/welcome/front/gtk3.py new file mode 100644 index 0000000..6f483ba --- /dev/null +++ b/linstaller/modules/welcome/front/gtk3.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# linstaller welcome module frontend - (C) 2011 Eugenio "g7" Paolantonio and the Semplice Team. +# All rights reserved. Work released under the GNU GPL license, version 3 or later. +# +# This is a module of linstaller, should not be executed as a standalone application. + +import linstaller.frontends.cli as cli +import linstaller.frontends.gtk3 as gtk3 +import t9n.library +_ = t9n.library.translation_init("linstaller") + +from linstaller.core.main import warn,info,verbose,root_check + +class Frontend(gtk3.Frontend): + def start(self): + """ Start the frontend """ + + # Check if we are root... + root_check() + + self.window.set_header("info", _("Welcome!"), "") + + self.window.text_new(_("Welcome to the %s installation wizard!") % self.moduleclass.main_settings["distro"]) + self.window.text_new() + self.window.text_new(_("This wizard will help you with the installation of the distribution into your Hard Disk or another removable media.")) + self.window.text_new(_("Keep in mind that this installer it's still in testing phase.")) + self.window.text_new(_("Please reports any problem at http://bugs.launchpad.net/linstaller.")) + self.window.text_new() + + self.window.reset_position() + gtk3.Gtk.main() + + verbose("Starting installation prompts.") diff --git a/setup.py b/setup.py index c164bb7..14b56e4 100644 --- a/setup.py +++ b/setup.py @@ -25,6 +25,10 @@ "linstaller.modules.debian", "linstaller.modules.debian.inst", + "linstaller.modules.mirrorselect", + "linstaller.modules.mirrorselect.front" + "linstaller.modules.mirrorselect.inst", + "linstaller.modules.clean", "linstaller.modules.clean.inst",