6352 Add MimeType support for adding Authorities and Packages via PM
authorJohn Rice <john.rice@sun.com>
Tue, 10 Mar 2009 00:01:30 +0000
changeset 927 2beb452e6245
parent 926 6ee411c9026a
child 928 c74cd8014b6f
6352 Add MimeType support for adding Authorities and Packages via PM
.hgignore
src/gui/Makefile
src/gui/data/addmoresoftware.desktop.in
src/gui/data/gnome-mime-application-vnd.pkg5.info.png
src/gui/data/packagemanager-info.xml.in
src/gui/data/packagemanager.desktop.in
src/gui/data/packagemanager.glade
src/gui/modules/cache.py
src/gui/modules/enumerations.py
src/gui/modules/installupdate.py
src/gui/modules/misc.py
src/gui/modules/repository.py
src/gui/modules/webinstall.py
src/packagemanager.py
src/pkgdefs/SUNWipkg-gui/prototype
src/tests/gui_pylintrc
src/updatemanager.py
--- a/.hgignore	Mon Mar 09 16:09:13 2009 -0500
+++ b/.hgignore	Tue Mar 10 00:01:30 2009 +0000
@@ -20,6 +20,7 @@
 ^src/gui/data/packagemanager.desktop$
 ^src/gui/data/packagemanager.png$
 ^src/gui/help/.*/package-manager.xml$
+^src/gui/data/packagemanager-info.xml$
 ^src/man/pkg.1$
 ^src/man/pkg.5$
 ^src/man/pkg.depotd.1m$
--- a/src/gui/Makefile	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/gui/Makefile	Tue Mar 10 00:01:30 2009 +0000
@@ -33,6 +33,8 @@
 ROOTUSRLIB = $(ROOT)/lib
 
 ROOTAPPICONSHARE = $(ROOT)/share/icons/hicolor/48x48/apps
+ROOTMIMETYPESHARE = $(ROOT)/share/mime/packages
+ROOTMIMEICONSHARE = $(ROOT)/share/icons/hicolor/48x48/mimetypes
 ROOTDATASHARE = $(ROOTSHARE)/data
 ROOTDESKTOPSHARE = $(ROOT)/share/applications
 ROOTGCONFSHARE = $(ROOTETC)/gconf/schemas
@@ -46,6 +48,8 @@
 
 ROOTDIRS = \
    $(ROOTAPPICONSHARE) \
+   $(ROOTMIMETYPESHARE) \
+   $(ROOTMIMEICONSHARE) \
    $(ROOTDATASHARE) \
    $(ROOTDESKTOPSHARE) \
    $(ROOTGCONFSHARE) \
@@ -58,6 +62,12 @@
 APPICONS = \
    data/packagemanager.png
 
+MIMETYPE = \
+   data/packagemanager-info.xml
+
+MIMEICONS = \
+   data/gnome-mime-application-vnd.pkg5.info.png
+
 CATALOG = \
    data/opensolaris.org \
    data/opensolaris.org.sections
@@ -127,6 +137,7 @@
    modules/repository.py \
    modules/enumerations.py \
    modules/parseqs.py \
+   modules/webinstall.py \
    modules/misc.py \
    modules/beadmin.py
 
@@ -138,6 +149,10 @@
 #
 ROOTAPPICONS = $(APPICONS:data/%=$(ROOTAPPICONSHARE)/%)
 
+ROOTMIMETYPE = $(MIMETYPE:data/%=$(ROOTMIMETYPESHARE)/%)
+
+ROOTMIMEICONS = $(MIMEICONS:data/%=$(ROOTMIMEICONSHARE)/%)
+
 ROOTCATALOG = $(CATALOG:data/%=$(ROOTDATASHARE)/%)
 
 ROOTDESKTOP = $(DESKTOP:data/%=$(ROOTDESKTOPSHARE)/%)
@@ -172,6 +187,8 @@
 
 ROOTCOMPONENTS = \
    $(ROOTAPPICONS) \
+   $(ROOTMIMETYPE) \
+   $(ROOTMIMEICONS) \
    $(ROOTCATALOG) \
    $(ROOTDESKTOP) \
    $(ROOTGCONF) \
@@ -253,6 +270,12 @@
 $(ROOTAPPICONSHARE)/%: $(ROOTDIRS) data/%
 	$(INSTALL) -f $(ROOTAPPICONSHARE) -m 0644 $<
 
+$(ROOTMIMETYPESHARE)/%: $(ROOTDIRS) data/%
+	$(INSTALL) -f $(ROOTMIMETYPESHARE) -m 0644 $<
+
+$(ROOTMIMEICONSHARE)/%: $(ROOTDIRS) data/%
+	$(INSTALL) -f $(ROOTMIMEICONSHARE) -m 0644 $<
+
 $(ROOTSPDIRS): $(ROOTDIRS)
 	$(INSTALL) -d -m 0755 $@
 
--- a/src/gui/data/addmoresoftware.desktop.in	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/gui/data/addmoresoftware.desktop.in	Tue Mar 10 00:01:30 2009 +0000
@@ -6,7 +6,7 @@
 Icon=packagemanager
 Terminal=false
 MultipleArgs=false
-StartupNotify=true
+StartupNotify=false
 Type=Application
 Encoding=UTF-8
 NoDisplay=true
Binary file src/gui/data/gnome-mime-application-vnd.pkg5.info.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/data/packagemanager-info.xml.in	Tue Mar 10 00:01:30 2009 +0000
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+<mime-type type="application/vnd.pkg5.info">
+<comment>IPS info files</comment>
+<glob pattern="*.p5i"/>
+</mime-type>
+</mime-info>
--- a/src/gui/data/packagemanager.desktop.in	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/gui/data/packagemanager.desktop.in	Tue Mar 10 00:01:30 2009 +0000
@@ -6,9 +6,10 @@
 Icon=packagemanager
 Terminal=false
 MultipleArgs=false
-StartupNotify=true
+StartupNotify=false
 Type=Application
 Encoding=UTF-8
 Categories=PackageManager;Applications;GTK;System;Settings
 NotShowIn=KDE
 X-KDE-SubstituteUID=true
+MimeType=application/vnd.pkg5.info;
--- a/src/gui/data/packagemanager.glade	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/gui/data/packagemanager.glade	Tue Mar 10 00:01:30 2009 +0000
@@ -2440,6 +2440,7 @@
                 </child>
                 <child>
                   <widget class="GtkHBox" id="hbox36">
+                    <property name="visible">True</property>
                     <property name="no_show_all">True</property>
                     <child>
                       <widget class="GtkAlignment" id="alignment27">
--- a/src/gui/modules/cache.py	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/gui/modules/cache.py	Tue Mar 10 00:01:30 2009 +0000
@@ -30,7 +30,7 @@
 import pkg.gui.enumerations as enumerations
 import pkg.gui.misc as gui_misc
 
-CACHE_VERSION=3
+CACHE_VERSION=4
 INDEX_HASH_LENGTH=41
 
 class CacheListStores:
@@ -41,14 +41,14 @@
                 self.category_icon = gui_misc.get_pixbuf_from_path(application_dir +
                     "/usr/share/package-manager/", "legend_newupdate")
 
-        def check_if_cache_uptodate(self, authority):
+        def check_if_cache_uptodate(self, publisher):
                 try:
-                        info = self.__load_cache_info(authority)
+                        info = self.__load_cache_info(publisher)
                         if info:
                                 if info.get("version") != CACHE_VERSION:
                                         return False
                                 image_last_modified = \
-                                    self.__get_authority_timestamp(authority)
+                                    self.__get_publisher_timestamp(publisher)
                                 cache_last_modified = info.get("date")
                                 if not cache_last_modified or \
                                     cache_last_modified != image_last_modified:
@@ -91,39 +91,33 @@
                         return index_hash
                 return index_hash
 
-        def __get_authority_timestamp(self, authority):
-                img = self.api_o.img
-                catalog_o = img.catalogs.get(authority)
-                last_modified = None
-                if not catalog_o:
-                        croot = "%s/catalog/%s" % (img.imgdir, authority)
-                        catalog_o = catalog.Catalog(croot,
-                            authority = authority)
-                if catalog_o:
-                        last_modified = catalog_o.last_modified()
-                return last_modified
+        def __get_publisher_timestamp(self, publisher):
+                dt = self.api_o.get_publisher_last_update_time(prefix=publisher)
+                if dt:
+                        return dt.ctime()
+                return dt
 
-        def dump_datamodels(self, authority, application_list, category_list, 
+        def dump_datamodels(self, publisher, application_list, category_list, 
             section_list):
                 cache_dir = self.__get_cache_dir()
                 if not cache_dir:
                         return
                 dump_info = {}
                 dump_info["version"] = CACHE_VERSION
-                dump_info["date"] = self.__get_authority_timestamp(authority)
-                dump_info["authority"] = authority
+                dump_info["date"] = self.__get_publisher_timestamp(publisher)
+                dump_info["publisher"] = publisher
                 dump_info["index_hash"] = self.__get_index_hash()
                 try:
-                        self.__dump_cache_file(cache_dir + authority+".cpl", dump_info)
-                        self.__dump_category_list(authority, category_list)
-                        self.__dump_application_list(authority, application_list)
-                        self.__dump_section_list(authority, section_list)
+                        self.__dump_cache_file(cache_dir + publisher+".cpl", dump_info)
+                        self.__dump_category_list(publisher, category_list)
+                        self.__dump_application_list(publisher, application_list)
+                        self.__dump_section_list(publisher, section_list)
                 except IOError:
                         #Silently return, as probably user doesn't have permissions or
                         #other error which simply doesn't affect the GUI work
                         return
 
-        def __dump_category_list(self, authority, category_list):
+        def __dump_category_list(self, publisher, category_list):
                 cache_dir = self.__get_cache_dir()
                 if not cache_dir:
                         return
@@ -139,9 +133,9 @@
                         cat["visible"] = category[enumerations.CATEGORY_VISIBLE]
                         cat["section_list"] = category[enumerations.SECTION_LIST_OBJECT]
                         categories.append(cat)
-                self.__dump_cache_file(cache_dir + authority+"_categories.cpl", categories)
+                self.__dump_cache_file(cache_dir + publisher+"_categories.cpl", categories)
 
-        def __dump_application_list(self, authority, application_list):
+        def __dump_application_list(self, publisher, application_list):
                 cache_dir = self.__get_cache_dir()
                 if not cache_dir:
                         return
@@ -158,9 +152,9 @@
                         app["is_visible"] = application[enumerations.IS_VISIBLE_COLUMN]
                         app["category_list"] = application[enumerations.CATEGORY_LIST_COLUMN]
                         apps.append(app)
-                self.__dump_cache_file(cache_dir + authority+"_packages.cpl", apps)
+                self.__dump_cache_file(cache_dir + publisher+"_packages.cpl", apps)
 
-        def __dump_section_list(self, authority, section_list):
+        def __dump_section_list(self, publisher, section_list):
                 cache_dir = self.__get_cache_dir()
                 if not cache_dir:
                         return
@@ -172,20 +166,20 @@
                         sec["subcategory"] = section[enumerations.SECTION_SUBCATEGORY]
                         sec["enabled"] = section[enumerations.SECTION_ENABLED]
                         sections.append(sec)
-                self.__dump_cache_file(cache_dir + authority+"_sections.cpl", sections)
+                self.__dump_cache_file(cache_dir + publisher+"_sections.cpl", sections)
 
-        def __load_cache_info(self, authority):
+        def __load_cache_info(self, publisher):
                 cache_dir = self.__get_cache_dir()
                 if not cache_dir:
                         return None
-                info = self.__read_cache_file(cache_dir + authority+".cpl")
+                info = self.__read_cache_file(cache_dir + publisher+".cpl")
                 return info
 
-        def load_category_list(self, authority, category_list):
+        def load_category_list(self, publisher, category_list):
                 cache_dir = self.__get_cache_dir()
                 if not cache_dir:
                         return
-                categories = self.__read_cache_file(cache_dir + authority+"_categories.cpl")
+                categories = self.__read_cache_file(cache_dir + publisher+"_categories.cpl")
                 cat_count = 0
                 for cat in categories:
                         cat_id = cat.get("id")
@@ -205,18 +199,18 @@
                         category_list.insert(cat_count, cat)
                         cat_count += 1
 
-        def load_application_list(self, authority, application_list, 
+        def load_application_list(self, publisher, application_list, 
             selected_pkgs=None):
                 cache_dir = self.__get_cache_dir()
                 if not cache_dir:
                         return
-                applications = self.__read_cache_file(cache_dir + authority+"_packages.cpl")
+                applications = self.__read_cache_file(cache_dir + publisher+"_packages.cpl")
                 app_count = len(application_list)
                 if app_count > 0:
                         app_count += 1
-                selected_pkgs_auth = None
+                selected_pkgs_pub = None
                 if selected_pkgs != None:
-                        selected_pkgs_auth = selected_pkgs.get(authority)
+                        selected_pkgs_pub = selected_pkgs.get(publisher)
                 for app in applications:
                         marked = False
                         status_icon = None
@@ -229,8 +223,8 @@
                                 status_icon = self.update_available_icon
                         fmri = app.get("fmri")
                         stem = app.get("stem")
-                        if selected_pkgs_auth != None:
-                                if stem in selected_pkgs_auth:
+                        if selected_pkgs_pub != None:
+                                if stem in selected_pkgs_pub:
                                         marked = True
                         display_name = app.get("display_name")
                         is_visible = app.get("is_visible")
@@ -244,11 +238,11 @@
                         application_list.insert(app_count, app)
                         app_count += 1
 
-        def load_section_list(self, authority, section_list):
+        def load_section_list(self, publisher, section_list):
                 cache_dir = self.__get_cache_dir()
                 if not cache_dir:
                         return
-                sections = self.__read_cache_file(cache_dir + authority+"_sections.cpl")
+                sections = self.__read_cache_file(cache_dir + publisher+"_sections.cpl")
                 sec_count = 0
                 for sec in sections:
                         sec_id = sec.get("id")
--- a/src/gui/modules/enumerations.py	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/gui/modules/enumerations.py	Tue Mar 10 00:01:30 2009 +0000
@@ -87,13 +87,13 @@
 
 #Repository List in Manage Repositories Dialog
 (
-AUTHORITY_NAME,
-AUTHORITY_PREFERRED,
-AUTHORITY_URL,
-AUTHORITY_SSL_KEY,
-AUTHORITY_SSL_CERT,
-AUTHORITY_MIRRORS,
-AUTHORITY_ENABLED,
+PUBLISHER_NAME,
+PUBLISHER_PREFERRED,
+PUBLISHER_URL,
+PUBLISHER_SSL_KEY,
+PUBLISHER_SSL_CERT,
+PUBLISHER_MIRRORS,
+PUBLISHER_ENABLED,
 ) = range(7)
 
 
--- a/src/gui/modules/installupdate.py	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/gui/modules/installupdate.py	Tue Mar 10 00:01:30 2009 +0000
@@ -66,10 +66,12 @@
         def __init__(self, list_of_packages, parent, api_o,
             ips_update = False, action = -1, be_name = None, 
             parent_name = "", pkg_list = None, main_window = None,
-            icon_confirm_dialog = None):
+            icon_confirm_dialog = None, title = None, web_install = False):
                 if action == -1:
                         return
                 progress.ProgressTracker.__init__(self)
+                self.web_install = web_install
+                self.web_updates_list = None
                 api_o.progresstracker = self
                 self.api_o = api_o
                 self.parent = parent
@@ -78,6 +80,7 @@
                 self.parent_name = parent_name
                 self.ipkg_ipkgui_list = pkg_list
                 self.icon_confirm_dialog = icon_confirm_dialog
+                self.title = title
                 self.w_main_window = main_window
                 self.ips_update = ips_update
                 self.list_of_packages = list_of_packages
@@ -229,7 +232,10 @@
                                 self.proposed_be_name = self.be_name
                                 self.__proceed_with_stages()
                 else:
-                        self.w_dialog.set_title(_("Install/Update"))
+                        if self.title != None:
+                                self.w_dialog.set_title(self.title)
+                        else:
+                                self.w_dialog.set_title(_("Install/Update"))
                         self.__proceed_with_stages()
 
 
@@ -253,9 +259,19 @@
                         self.w_cancel_button.set_sensitive(False)
                 if self.operations_done:
                         self.w_dialog.hide()
+                        if self.web_install:
+                                gobject.idle_add(self.parent.update_package_list, 
+                                    self.web_updates_list)
+                                return
+                        gobject.idle_add(self.parent.update_package_list, None)
 
         def __on_ua_cancel_button_clicked(self, widget):
                 self.w_ua_dialog.hide()
+                if self.web_install:
+                        gobject.idle_add(self.parent.update_package_list, 
+                            self.web_updates_list)
+                        return
+                gobject.idle_add(self.parent.update_package_list, None)
 
         def __on_ua_proceed_button_clicked(self, widget):
                 proposed_be_name = self.w_ua_be_name_entry.get_text()
@@ -353,7 +369,7 @@
                                 else:
                                         self.api_o.reset()
                         self.__proceed_with_stages_thread()
-                except api_errors.InvalidCertException:
+                except api_errors.CertificateError:
                         self.stop_bouncing_progress = True
                         msg = _("Accessing this restricted repository failed."
                             "\nYou either need to register to access this repository,"
@@ -381,9 +397,10 @@
                 except (api_errors.NetworkUnavailableException, 
                     TransferTimedOutException, TransportException, URLError, 
                     ManifestRetrievalError, DatastreamRetrievalError, 
-                    FileListRetrievalError):
+                    FileListRetrievalError), ex:
                         msg = _("Please check the network "
-                            "connection.\nIs the repository accessible?")
+                            "connection.\nIs the repository accessible?\n\n"
+                            "%s" % str(ex))
                         self.__g_error_stage(msg)
                         return
                 except api_errors.IpkgOutOfDateException:
@@ -501,6 +518,12 @@
                         self.api_o.execute_plan()
                         gobject.idle_add(self.__operations_done)
                 else:
+                        if self.web_install:
+                                gobject.idle_add(self.w_expander.hide)
+                                gobject.idle_add(self.__operations_done, 
+                                    _("All packages already installed."))
+                                return
+                                
                         msg = None
                         if self.action == enumerations.INSTALL_UPDATE:
                                 msg = _("Selected package(s) cannot be updated on "
@@ -555,6 +578,7 @@
                 gobject.idle_add(self.current_stage_icon.set_from_stock, 
                     gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_MENU)
                 gobject.idle_add(self.w_expander.set_expanded, True)
+                gobject.idle_add(self.w_cancel_button.set_sensitive, True)
 
         def __g_exception_stage(self, tracebk):
                 self.operations_done = True
@@ -581,6 +605,7 @@
                         msg = _("No futher information available")
                         self.__g_update_details_text("%s\n" % msg, "level2")
                 gobject.idle_add(self.w_expander.set_expanded, True)
+                gobject.idle_add(self.w_cancel_button.set_sensitive, True)
 
         def __start_substage(self, text, bounce_progress=True):
                 if text:
@@ -667,12 +692,14 @@
                                     ,_("Catalog refresh failed during Update All."))
                 return stuff_to_do
 
-        def __operations_done(self):
+        def __operations_done(self, alternate_done_txt = None):
                 done_txt = _("Installation completed successfully.")
                 if self.action == enumerations.REMOVE:
                         done_txt = _("Packages removed successfully.")
                 elif self.action == enumerations.IMAGE_UPDATE:
                         done_txt = _("Packages updated successfully.")
+                if alternate_done_txt != None:
+                        done_txt = alternate_done_txt
                 self.w_stages_box.hide()
                 self.w_stages_icon.set_from_stock(
                     gtk.STOCK_OK, gtk.ICON_SIZE_DND)
@@ -684,9 +711,11 @@
                 self.stop_bouncing_progress = True
                 self.operations_done = True
                 if self.parent != None:
-                        if not self.ips_update and not self.action == \
-                            enumerations.IMAGE_UPDATE:
+                        if not self.web_install and not self.ips_update \
+                            and not self.action == enumerations.IMAGE_UPDATE:
                                 self.parent.update_package_list(self.update_list)
+                        if self.web_install:
+                                self.web_updates_list = self.update_list
                 if self.ips_update:
                         self.w_dialog.hide()
                         self.parent.restart_after_ips_update("be_name")
@@ -748,12 +777,12 @@
                 s_ver = pkginfo.version
                 s_bran = pkginfo.branch
                 pkg_name = pkginfo.pkg_stem
-                pkg_authority = pkginfo.authority
-                if not pkg_authority in self.update_list:
-                        self.update_list[pkg_authority] = []
-                auth_list = self.update_list.get(pkg_authority)
-                if not pkg_name in auth_list:
-                        auth_list.append(pkg_name)
+                pkg_publisher = pkginfo.publisher
+                if not pkg_publisher in self.update_list:
+                        self.update_list[pkg_publisher] = []
+                pub_list = self.update_list.get(pkg_publisher)
+                if not pkg_name in pub_list:
+                        pub_list.append(pkg_name)
                 l_ver = 0
                 version_pref = ""
                 while l_ver < len(s_ver) -1:
--- a/src/gui/modules/misc.py	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/gui/modules/misc.py	Tue Mar 10 00:01:30 2009 +0000
@@ -31,6 +31,10 @@
 except ImportError:
         sys.exit(1)
 
+def get_app_pixbuf(application_dir, icon_name):
+        return get_pixbuf_from_path(application_dir +
+            "/usr/share/package-manager/", icon_name)
+
 def get_icon_pixbuf(application_dir, icon_name):
         return get_pixbuf_from_path(application_dir +
             "/usr/share/icons/package-manager/", icon_name)
--- a/src/gui/modules/repository.py	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/gui/modules/repository.py	Tue Mar 10 00:01:30 2009 +0000
@@ -26,8 +26,10 @@
 import sys
 import os
 from threading import Thread
+from pkg.client.api_errors import InvalidDepotResponseException
 
 try:
+        import gnome
         import gobject
         gobject.threads_init()
         import gtk
@@ -37,6 +39,7 @@
 except ImportError:
         sys.exit(1)
 
+import pkg.client.publisher as publisher
 import pkg.client.api_errors as api_errors
 import pkg.misc as misc
 import pkg.gui.enumerations as enumerations
@@ -44,19 +47,23 @@
 ERROR_FORMAT = "<span color = \"red\">%s</span>"
 
 class Repository:
-        def __init__(self, parent):
+        def __init__(self, parent, webinstall_new=False):
                 self.parent = parent
-                self.img = parent.api_o.img
+                self.api_o = parent.api_o
+                self.webinstall_new = webinstall_new
+                self.registration_url = None
+                self.pub_copy = None
+                self.repo_copy = None
 
                 self.repository_list = \
                     gtk.ListStore(
-                        gobject.TYPE_STRING,      # enumerations.AUTHORITY_NAME
-                        gobject.TYPE_BOOLEAN,     # enumerations.AUTHORITY_PREFERRED
-                        gobject.TYPE_STRING,      # enumerations.AUTHORITY_URL
-                        gobject.TYPE_STRING,      # enumerations.AUTHORITY_SSL_KEY
-                        gobject.TYPE_STRING,      # enumerations.AUTHORITY_SSL_CERT
-                        gobject.TYPE_PYOBJECT,    # enumerations.AUTHORITY_MIRRORS
-                        gobject.TYPE_BOOLEAN,     # enumerations.AUTHORITY_ENABLED
+                        gobject.TYPE_STRING,      # enumerations.PUBLISHER_NAME
+                        gobject.TYPE_BOOLEAN,     # enumerations.PUBLISHER_PREFERRED
+                        gobject.TYPE_STRING,      # enumerations.PUBLISHER_URL
+                        gobject.TYPE_STRING,      # enumerations.PUBLISHER_SSL_KEY
+                        gobject.TYPE_STRING,      # enumerations.PUBLISHER_SSL_CERT
+                        gobject.TYPE_PYOBJECT,    # enumerations.PUBLISHER_MIRRORS
+                        gobject.TYPE_BOOLEAN,     # enumerations.PUBLISHER_ENABLED
                         )
                 self.mirror_list = \
                     gtk.ListStore(
@@ -76,6 +83,7 @@
                 progress_button = w_tree_progress.get_widget("progresscancel")
                 self.w_progressbar = w_tree_progress.get_widget("progressbar")
                 self.w_repository_dialog = w_tree_repository.get_widget("repository")
+                self.error_dialog_parent =  self.w_repository_dialog
                 self.w_repository_name = w_tree_repository.get_widget("repositoryname")
                 self.w_repository_url = w_tree_repository.get_widget("repositoryurl")
                 self.w_repository_treeview = \
@@ -101,6 +109,8 @@
                     w_tree_repositorymodify.get_widget("repositorymodifyname")
                 self.w_repositorymodify_url = \
                     w_tree_repositorymodify.get_widget("repositorymodifyurl")
+                self.w_repositorymodify_error_label = \
+                        w_tree_repositorymodify.get_widget("moderror_label")
                 self.w_repositorymodify_keybrowse_button = \
                     w_tree_repositorymodify.get_widget("modkeybrowse")
                 self.w_repositorymodify_certbrowse_button = \
@@ -115,6 +125,21 @@
                     w_tree_repositorymodify.get_widget("repositorymodifycancel")
                 self.w_mirror_treeview = \
                     w_tree_repositorymodify.get_widget("mirrortreeview")
+                self.w_repositorymodify_title_label = \
+                    w_tree_repositorymodify.get_widget("repositorymodifytitlelabel")
+                    
+                self.w_repositorymodify_registration_comment_label = \
+                    w_tree_repositorymodify.get_widget(
+                        "repositorymodifyregistrationcommentlabel")
+                self.w_repositorymodify_registration_link = \
+                    w_tree_repositorymodify.get_widget(
+                        "repositorymodifyregistrationlinkbutton")                    
+                    
+                self.w_repositorymodify_ssl_expander = \
+                    w_tree_repositorymodify.get_widget("repositorymodifysslexpander")
+                self.w_repositorymodify_mirrors_expander = \
+                    w_tree_repositorymodify.get_widget("repositorymodifymirrorsexpander")
+
                 self.mirror_list_filter = self.mirror_list.filter_new()
                 self.w_mirror_add_entry = \
                     w_tree_repositorymodify.get_widget("addmirror_entry")
@@ -122,7 +147,9 @@
                     w_tree_repositorymodify.get_widget("addmirror_button")
                 self.w_mirror_remove_button = \
                     w_tree_repositorymodify.get_widget("mirrorremove")
-
+                self.w_repositorymodify_url.connect('focus-in-event', 
+                    self.on_focus_in_modurl)
+                    
                 #Modify name of the repository is disabled, see #4990
                 self.w_repositorymodify_name.set_sensitive(False)
 
@@ -158,11 +185,6 @@
                 self.w_progress_dialog.set_transient_for(self.w_repository_dialog)
                 self.w_sslkeyandcert_dialog.set_transient_for(self.w_repository_dialog)
                 self.w_repositorymodify_dialog.set_transient_for(self.w_repository_dialog)
-                self.old_modify_name = None
-                self.old_modify_url = None
-                self.old_modify_preferred = False
-                self.old_modify_ssl_key = None
-                self.old_modify_ssl_cert = None
                 self.is_name_valid = False
                 self.is_url_valid = False
                 self.name_error = None
@@ -198,6 +220,10 @@
                                     self.__on_repositorymodifycancel_clicked,
                                 "on_repositorymodifyok_clicked": \
                                     self.__on_repositorymodifyok_clicked,
+                                "on_repositorymodifyregistrationlinkbutton_clicked": \
+                                    self.__on_repositorymodifyregistrationlink_clicked,
+                                "on_repositorymodifyurl_changed": \
+                                    self.__on_repositorymodifyurl_changed,
                                 "on_sslkeybrowse_clicked": \
                                     self.__on_modify_keybrowse_clicked,
                                 "on_sslcertbrowse_clicked": \
@@ -238,10 +264,75 @@
                             "Check repository.py signals") \
                             % error
 
-                Thread(target = self.__prepare_repository_list).start()
-                self.w_repository_dialog.show_all()
+                if not self.webinstall_new:
+                        Thread(target = self.__prepare_repository_list).start()
+                        self.w_repository_dialog.show_all()
                 self.w_repository_error_label.hide()
 
+        def webinstall_new_pub(self, parent, pub = None):
+                if pub == None:
+                        return
+                self.w_progress_dialog.set_transient_for(parent)
+                auth = origin_uri = registration_url = mirror_datalist = None
+                
+                self.pub_copy = pub
+                self.repo_copy = pub.selected_repository
+
+                auth = self.pub_copy.prefix
+                origin_uri = self.repo_copy.origins[0].uri
+
+                scheme = None                
+                if origin_uri != None and origin_uri.startswith("https"):
+                        scheme = "https"
+
+                reg_uri = self.__get_registration_uri(self.repo_copy)
+                if reg_uri != None:
+                        registration_url = reg_uri
+                elif scheme == "https":
+                        registration_url = origin_uri
+                mirror_datalist = self.repo_copy.mirrors
+
+                self.__webinstall_new_repository(parent, auth, origin_uri,
+                    registration_url, mirror_datalist, scheme)
+
+        def __webinstall_new_repository(self, parent, auth = None, origin_uri = None,
+            registration_url = None, mirror_datalist = None, scheme = None):
+                if (auth == None or origin_uri == None):
+                        return
+                        
+                self.registration_url = registration_url
+                self.error_dialog_parent = parent
+                self.w_repositorymodify_dialog.set_title(
+                    _("Add New Repository"))
+                self.w_repositorymodify_name.set_text(auth)
+                self.w_repositorymodify_url.set_text(origin_uri)
+                self.w_repositorymodify_name.set_sensitive(False)
+                self.w_repositorymodify_url.set_sensitive(False)
+                self.w_repositorymodify_dialog.set_modal(True)
+                self.w_repositorymodify_dialog.set_transient_for(parent)
+                self.w_repositorymodify_title_label.set_markup(
+                    _("<b>New Repository</b>"))
+
+                if scheme != "https" and registration_url == None:
+                        self.__on_repositorymodifyok_clicked(None)
+                        return
+                        
+                self.w_repositorymodify_ssl_expander.set_expanded(True)
+                self.w_repositorymodify_registration_link.set_uri(registration_url)
+                        
+                self.w_repositorymodify_dialog.show_all()
+                self.w_repositorymodify_error_label.hide()
+
+                if scheme == "https":
+                        self.w_repositorymodify_ssl_expander.show()
+                else:
+                        self.w_repositorymodify_ssl_expander.hide()
+                        
+                if mirror_datalist == None or len(mirror_datalist) == 0:
+                        self.w_repositorymodify_mirrors_expander.hide()
+                else:
+                        gobject.idle_add(self.__setup_mirrors, mirror_datalist)
+
         def on_focus_in(self, widget, event):
                 self.w_repository_modify_button.set_sensitive(False)
                 self.w_repository_remove_button.set_sensitive(False)
@@ -251,6 +342,9 @@
                 self.w_repository_modify_button.set_sensitive(False)
                 self.w_repository_remove_button.set_sensitive(False)
 
+        def on_focus_in_modurl(self, widget, event):
+                self.__validate_modurl(widget)
+
         def on_focus_in_url(self, widget, event):
                 self.__validate_url(widget)
                 self.w_repository_modify_button.set_sensitive(False)
@@ -263,20 +357,20 @@
                 repository_list_sort = gtk.TreeModelSort(self.repository_list_filter)
                 name_renderer = gtk.CellRendererText()
                 column = gtk.TreeViewColumn(_("Repository Name"),
-                    name_renderer,  text = enumerations.AUTHORITY_NAME)
+                    name_renderer,  text = enumerations.PUBLISHER_NAME)
                 column.set_expand(True)
-                column.set_sort_column_id(enumerations.AUTHORITY_NAME)
+                column.set_sort_column_id(enumerations.PUBLISHER_NAME)
                 column.set_sort_indicator(True)
                 column.set_cell_data_func(name_renderer,
                     self.name_data_function, None)
                 self.w_repository_treeview.append_column(column)
                 radio_renderer = gtk.CellRendererToggle()
                 column = gtk.TreeViewColumn(_("Preferred"),
-                    radio_renderer, active = enumerations.AUTHORITY_PREFERRED)
+                    radio_renderer, active = enumerations.PUBLISHER_PREFERRED)
                 radio_renderer.set_property("activatable", True)
                 radio_renderer.set_property("radio", True)
                 column.set_expand(False)
-                column.set_sort_column_id(enumerations.AUTHORITY_PREFERRED)
+                column.set_sort_column_id(enumerations.PUBLISHER_PREFERRED)
                 column.set_sort_indicator(True)
                 radio_renderer.connect('toggled', self.__preferred_default)
                 column.set_cell_data_func(radio_renderer,
@@ -284,10 +378,10 @@
                 self.w_repository_treeview.append_column(column)
                 toggle_renderer = gtk.CellRendererToggle()
                 column = gtk.TreeViewColumn(_("Enabled"),
-                    toggle_renderer, active = enumerations.AUTHORITY_ENABLED)
+                    toggle_renderer, active = enumerations.PUBLISHER_ENABLED)
                 toggle_renderer.set_property("activatable", True)
                 column.set_expand(False)
-                column.set_sort_column_id(enumerations.AUTHORITY_ENABLED)
+                column.set_sort_column_id(enumerations.PUBLISHER_ENABLED)
                 column.set_sort_indicator(True)
                 toggle_renderer.connect('toggled', self.__enable_disable)
                 column.set_cell_data_func(toggle_renderer, 
@@ -300,18 +394,17 @@
                 self.w_mirror_treeview.append_column(column)
                 self.w_repository_treeview.set_model(repository_list_sort)
 
-        def __prepare_repository_list(self, clear_add_entries=True, selected_auth=None,
+        def __prepare_repository_list(self, clear_add_entries=True, selected_pub=None,
             stop_thread=True):
                 self.number_of_changes += 1
-                self.img.load_config()
-                auths = self.img.gen_authorities(inc_disabled=True)
-                gobject.idle_add(self.__create_view_with_auths, auths,
-                    clear_add_entries, selected_auth)
+                pubs = self.api_o.get_publishers()
+                gobject.idle_add(self.__create_view_with_pubs, pubs,
+                    clear_add_entries, selected_pub)
                 if stop_thread:
                         self.progress_stop_thread = True
                 return
 
-        def __create_view_with_auths(self, auths, clear_add_entries, selected_auth):
+        def __create_view_with_pubs(self, pubs, clear_add_entries, selected_pub):
                 model = self.w_repository_treeview.get_model()
                 self.w_repository_treeview.set_model(None)
                 self.repository_list.clear()
@@ -320,51 +413,54 @@
                         self.w_repository_url.set_text("")
                 self.w_repository_name.grab_focus()
                 j = 0
-                select_auth = -1
-                self.preferred = self.img.get_default_authority()
+                select_pub = -1
+                pref_pub = self.api_o.get_preferred_publisher()
+                self.preferred = pref_pub.prefix
                 self.original_preferred = self.preferred
-                for a in auths:
-                        l = self.img.split_authority(a)
-                        name = l[0]
+                for pub in pubs:
+                        repo = pub.selected_repository
+                        origin = repo.origins[0]
+
+                        name = pub.prefix
                         is_preferred = name == self.preferred
                         if is_preferred:
                                 self.initial_default = j
-                        if selected_auth:
-                                if name == selected_auth:
-                                        select_auth = j
-                        self.repository_list.insert(j, 
-                            [name, is_preferred, l[1], l[2], l[3], l[5], \
-                            not a["disabled"]])
+                        if selected_pub:
+                                if name == selected_pub:
+                                        select_pub = j
+                        self.repository_list.insert(j, [name, is_preferred,
+                            origin.uri, origin.ssl_key, origin.ssl_cert,
+                            [m.uri for m in repo.mirrors], not pub.disabled])
                         j += 1
                 if j > 0:
                         self.w_repository_modify_button.set_sensitive(False)
                         self.w_repository_remove_button.set_sensitive(False)
                 self.w_repository_treeview.set_model(model)
-                if select_auth == -1:
-                        select_auth = self.initial_default
-                self.w_repository_treeview.set_cursor(select_auth,
+                if select_pub == -1:
+                        select_pub = self.initial_default
+                self.w_repository_treeview.set_cursor(select_pub,
                     None, start_editing=False)
-                self.w_repository_treeview.scroll_to_cell(select_auth)
+                self.w_repository_treeview.scroll_to_cell(select_pub)
 
         @staticmethod
         def name_data_function(column, renderer, model, itr, data):
                 if itr:
                         renderer.set_property("sensitive", 
 
-                            model.get_value(itr, enumerations.AUTHORITY_ENABLED))
+                            model.get_value(itr, enumerations.PUBLISHER_ENABLED))
 
         @staticmethod
         def radio_data_function(column, renderer, model, itr, data):
                 if itr:
                         renderer.set_property("sensitive", 
-                            model.get_value(itr, enumerations.AUTHORITY_ENABLED))
+                            model.get_value(itr, enumerations.PUBLISHER_ENABLED))
 
         @staticmethod
         def toggle_data_function(column, renderer, model, itr, data):
                 if itr:
                         renderer.set_property("sensitive", 
                             not model.get_value(itr, 
-                            enumerations.AUTHORITY_PREFERRED))
+                            enumerations.PUBLISHER_PREFERRED))
 
         def __enable_disable(self, cell, filtered_path):
                 sorted_model = self.w_repository_treeview.get_model()
@@ -374,41 +470,42 @@
                 itr = model.get_iter(path)
                 if itr:
                         preferred = model.get_value(itr, 
-                            enumerations.AUTHORITY_PREFERRED)
+                            enumerations.PUBLISHER_PREFERRED)
                         if preferred == True:
                                 return
                         enabled = model.get_value(itr,
-                            enumerations.AUTHORITY_ENABLED)
-                        auth = model.get_value(itr, enumerations.AUTHORITY_NAME)
+                            enumerations.PUBLISHER_ENABLED)
+                        pub = model.get_value(itr, enumerations.PUBLISHER_NAME)
                         try:
-                                self.img.set_authority(auth,
-                                    refresh_allowed=False,
-                                    disabled=enabled)
+                                pub = self.api_o.get_publisher(pub, duplicate=True)
+                                pub.disabled = enabled
+                                self.api_o.update_publisher(pub,
+                                    refresh_allowed=False)
                                 self.number_of_changes += 1
                                 model.set_value(itr, 
-                                    enumerations.AUTHORITY_ENABLED,
+                                    enumerations.PUBLISHER_ENABLED,
                                     not enabled)
-                        except RuntimeError, ex:
+                        except api_errors.PublisherError, ex:
                                 if enabled:
-                                        err = _("Failed to disable %s.\n") % auth
+                                        err = _("Failed to disable %s.\n") % pub
                                 else:
-                                        err = _("Failed to enable %s.\n") % auth
+                                        err = _("Failed to enable %s.\n") % pub
                                 err += str(ex)
                                 self.__error_occurred(err,
                                     msg_type=gtk.MESSAGE_INFO)
                         except api_errors.PermissionsException:
                                 if enabled:
-                                        err1 = _("Failed to disable %s.") % auth
+                                        err1 = _("Failed to disable %s.") % pub
                                 else:
-                                        err1 = _("Failed to enable %s.") % auth
+                                        err1 = _("Failed to enable %s.") % pub
                                 err = err1 + _("\nPlease check your permissions.")
                                 self.__error_occurred(err,
                                     msg_type=gtk.MESSAGE_INFO)
                         except api_errors.CatalogRefreshException:
                                 if enabled:
-                                        err1 = _("Failed to disable %s.") % auth
+                                        err1 = _("Failed to disable %s.") % pub
                                 else:
-                                        err1 = _("Failed to enable %s.") % auth
+                                        err1 = _("Failed to enable %s.") % pub
                                 err = err1 + _(
                                     "\nPlease check the network connection or URL.\n"
                                     "Is the repository accessible?")
@@ -423,33 +520,31 @@
                 itr = model.get_iter(path)
                 if itr:
                         preferred = model.get_value(itr, 
-                            enumerations.AUTHORITY_PREFERRED)
+                            enumerations.PUBLISHER_PREFERRED)
                         enabled = model.get_value(itr,
-                            enumerations.AUTHORITY_ENABLED)
+                            enumerations.PUBLISHER_ENABLED)
                         if preferred == False and enabled == True:
-                                auth = model.get_value(itr, 
-                                    enumerations.AUTHORITY_NAME)
+                                pub = model.get_value(itr, 
+                                    enumerations.PUBLISHER_NAME)
                                 try:
-                                        self.img.set_preferred_authority(auth)
-                                        self.preferred = auth
-                                        index = enumerations.AUTHORITY_PREFERRED
+                                        self.api_o.set_preferred_publisher(pub)
+                                        self.preferred = pub
+                                        index = enumerations.PUBLISHER_PREFERRED
                                         for row in model:
                                                 row[index] = False
                                         model.set_value(itr, 
-                                            enumerations.AUTHORITY_PREFERRED,
+                                            enumerations.PUBLISHER_PREFERRED,
                                             not preferred)
+                                except api_errors.PublisherError, err:
+                                        self.__error_occurred(str(err),
+                                            msg_type=gtk.MESSAGE_INFO) 
+                                        self.__prepare_repository_list()
                                 except api_errors.PermissionsException:
                                         err = _("Couldn't change"
-                                            " the preferred authority.\n"
+                                            " the preferred publisher.\n"
                                             "Please check your permissions.")
                                         self.__error_occurred(err,
                                             msg_type=gtk.MESSAGE_INFO) 
-                                except Exception, ex:
-                                        err = _("Couldn't change"
-                                            " the preferred authority.\n")
-                                        err += str(ex)
-                                        self.__error_occurred(err,
-                                            msg_type=gtk.MESSAGE_INFO) 
 
         def __progress_pulse(self):
                 if not self.progress_stop_thread:
@@ -463,32 +558,50 @@
         def __on_repositoryurl_changed(self, widget):
                 self.__validate_url(widget)
 
+        def __on_repositorymodifyurl_changed(self, widget):
+                self.__validate_modurl(widget)
+
         def __validate_url(self, widget):
-                url = widget.get_text()
+                w_url_text = widget
+                w_error_label = self.w_repository_error_label
+                w_action_button = self.w_repository_add_button
+                self.__validate_url_generic(w_url_text, w_error_label, w_action_button,
+                    self.is_name_valid)
+
+        def __validate_modurl(self, widget):
+                w_url_text = widget
+                w_error_label = self.w_repositorymodify_error_label
+                w_action_button = self.w_repositorymodify_ok_button
+                self.__validate_url_generic(w_url_text, w_error_label, w_action_button, 
+                    True)
+
+        def __validate_url_generic(self, w_url_text, w_error_label, w_action_button,
+                name_valid = False):
+                url = w_url_text.get_text()
                 self.is_url_valid = self.__is_url_valid(url)
-                self.w_repository_error_label.hide()
+                w_error_label.hide()
                 if self.is_url_valid:
-                        if self.is_name_valid:
-                                self.w_repository_add_button.set_sensitive(True)
+                        if name_valid:
+                                w_action_button.set_sensitive(True)
                         else:
-                                self.w_repository_add_button.set_sensitive(False)
+                                w_action_button.set_sensitive(False)
                                 if self.name_error != None:
                                         error_str = ERROR_FORMAT % self.name_error
-                                        self.w_repository_error_label.set_markup(
+                                        w_error_label.set_markup(
                                             error_str)
-                                        self.w_repository_error_label.show()
+                                        w_error_label.show()
                 else:
-                        self.w_repository_add_button.set_sensitive(False)
+                        w_action_button.set_sensitive(False)
                         if self.url_error != None:
                                 error_str = ERROR_FORMAT % self.url_error
-                                self.w_repository_error_label.set_markup(error_str)
-                                self.w_repository_error_label.show()
+                                w_error_label.set_markup(error_str)
+                                w_error_label.show()
                         
         def __is_name_valid(self, name):
                 self.name_error = None
                 if len(name) == 0:
                         return False
-                if not misc.valid_auth_prefix(name):
+                if not misc.valid_pub_prefix(name):
                         self.name_error = _("Name contains invalid characters")
                         return False
 
@@ -505,7 +618,7 @@
                 if len(name) == 0:
                         return False
 
-                if not misc.valid_auth_url(name):
+                if not misc.valid_pub_url(name):
                         # Check whether the user has started typing a valid URL.
                         # If he has we do not display an error message.
                         valid_start = False
@@ -577,6 +690,10 @@
         def __do_add_repository(self, name, url, ssl_key=None, ssl_cert=None):
                 p_title = _("Applying changes")
                 p_text = _("Applying changes, please wait ...")
+                repo = publisher.Repository()
+                repo.add_origin(url)
+                self.pub_copy = publisher.Publisher(name, repositories=[repo])
+                
                 self.__run_with_prog_in_thread(self.__add_repository, p_title,
                     p_text, name, url, ssl_key, ssl_cert)
 
@@ -596,180 +713,154 @@
                     p_text)
 
         def __on_repositorymodify_clicked(self, widget):
+                self.__clear_repositorymodify()
+                self.pub_copy = None
+                self.repo_copy = None
+                
                 tsel = self.w_repository_treeview.get_selection()
                 selection = tsel.get_selected()
                 itr = selection[1]
-                if itr != None:
-                        model = selection[0]
-                        self.old_modify_name = model.get_value(itr, 
-                            enumerations.AUTHORITY_NAME)
-                        self.old_modify_url = model.get_value(itr,
-                            enumerations.AUTHORITY_URL)
-                        self.old_modify_ssl_key = model.get_value(itr,
-                            enumerations.AUTHORITY_SSL_KEY)
-                        self.old_modify_ssl_cert = model.get_value(itr,
-                            enumerations.AUTHORITY_SSL_CERT)
-                        self.old_modify_preferred = model.get_value(itr,
-                            enumerations.AUTHORITY_PREFERRED)
-                        self.mirror_list.clear()
-                        mirrors = model.get_value(itr,
-                            enumerations.AUTHORITY_MIRRORS)
-                        self.__setup_mirrors(mirrors)
-                        self.w_repositorymodify_name.set_text(self.old_modify_name)
-                        self.w_repositorymodify_url.set_text(self.old_modify_url)
-                        if self.old_modify_ssl_key != None:
-                                self.w_repositorymodify_key_entry.set_text(
-                                    self.old_modify_ssl_key)
-                        if self.old_modify_ssl_cert != None:
-                                self.w_repositorymodify_cert_entry.set_text(
-                                    self.old_modify_ssl_cert)
-                        self.w_mirror_add_button.set_sensitive(False)
-                        self.w_repositorymodify_dialog.show_all()
+                if itr == None:
+                        return
+                        
+                model = selection[0]
+                prefix = model.get_value(itr, enumerations.PUBLISHER_NAME)
+                url = model.get_value(itr, enumerations.PUBLISHER_URL)
+                
+                try:                        
+                        self.pub_copy = self.api_o.get_publisher(prefix,
+                            duplicate=True)
+                        self.repo_copy = self.pub_copy.selected_repository
+                        
+                except api_errors.PublisherError, ex:
+                        gobject.idle_add(self.__error_occurred, str(ex),
+                            gtk.MESSAGE_ERROR)
+                        gobject.idle_add(self.w_repository_name.grab_focus)
+                        return
+                                        
+                self.mirror_list.clear()
+                self.__setup_mirrors(self.repo_copy.mirrors)
+                if len(self.repo_copy.mirrors) > 0:
+                        self.w_repositorymodify_mirrors_expander.set_expanded(True)
 
+                self.w_repositorymodify_name.set_text(prefix)
+                self.w_repositorymodify_url.set_text(url)
+                
+                origin = self.repo_copy.origins[0]
+                if origin.ssl_key != None:
+                        self.w_repositorymodify_key_entry.set_text(origin.ssl_key)
+                if origin.ssl_cert != None:
+                        self.w_repositorymodify_cert_entry.set_text(
+                            origin.ssl_cert)
+                self.w_mirror_add_button.set_sensitive(False)
+                
+                self.w_repositorymodify_dialog.show_all()
+                self.w_repositorymodify_error_label.hide()
+                self.w_repositorymodify_registration_comment_label.hide()
+                self.w_repositorymodify_registration_link.hide()
+                self.w_repositorymodify_registration_link.set_uri("")
+                self.w_repositorymodify_ssl_expander.set_expanded(False) 
+                
+                reg_uri = self.__get_registration_uri(self.repo_copy)
+                if reg_uri == None and origin.ssl_key == None:
+                        return
+                            
+                self.w_repositorymodify_registration_comment_label.show()
+                self.w_repositorymodify_registration_link.show()
+                                
+                if reg_uri != None:
+                        self.registration_url = reg_uri
+                else:
+                        self.registration_url = url
+                self.w_repositorymodify_registration_link.set_uri(self.registration_url)
+                        
+                if origin.ssl_key != None:
+                        self.w_repositorymodify_ssl_expander.set_expanded(True)
+                
+        @staticmethod
+        def __get_registration_uri(repo):
+                #TBD: Change Publisher API to return an RegistrationURI or a String
+                # but not either.
+                # Currently RegistrationURI is coming back with a trailing / this should
+                # be removed.
+                if repo == None:
+                        return None                      
+                if repo.registration_uri == None:
+                        return None
+                ret_uri = None
+                if isinstance(repo.registration_uri, str):
+                        if len(repo.registration_uri) > 0:
+                                ret_uri = repo.registration_uri.strip("/")
+                elif isinstance(repo.registration_uri, publisher.RepositoryURI):
+                        uri = repo.registration_uri.uri
+                        if uri != None and len(uri) > 0:
+                                ret_uri = uri.strip("/")                
+                return ret_uri              
+                
         def __on_repository_delete_event(self, widget, event):
                 self.__on_repositoryclose_clicked(widget)
 
         def __on_repositoryclose_clicked(self, widget):
                 # if the number is greater then 1 it means that we did something
                 # to the repository list and it is safer to reload package info
-                if self.number_of_changes > 1 or \
-                    self.original_preferred != self.preferred:
+                if (not self.webinstall_new and self.number_of_changes > 1) or \
+                    (not self.webinstall_new and 
+                    self.original_preferred != self.preferred):
                         self.parent.reload_packages()
                 self.w_repository_dialog.hide()
 
+        def __on_repositorymodifyregistrationlink_clicked(self, widget):
+                try:
+                        gnome.url_show(self.registration_url)
+                except gobject.GError:
+                        self.__error_occurred(_("Unable to navigate to:\n\t%s") % 
+                            self.registration_url, title=_("Registration"))
+                
         def __on_repositorymodifyok_clicked(self, widget):
-                self.w_repository_treeview.grab_focus()
                 self.w_repositorymodify_dialog.hide()
                 name =  self.w_repositorymodify_name.get_text()
                 url =  self.w_repositorymodify_url.get_text()
+                if self.webinstall_new:
+                        p_title = _("Adding New Repository")
+                        p_text = _("Adding:\n\t%s (%s)..." % (name, url))
+                else:
+                        self.w_repository_treeview.grab_focus()
+                        p_title = _("Applying changes")
+                        p_text = _("Applying changes, please wait ...")
+                        
                 ssl_key =  self.w_repositorymodify_key_entry.get_text()
                 if ssl_key == "":
                         ssl_key = None
                 ssl_cert =  self.w_repositorymodify_cert_entry.get_text()
                 if ssl_cert == "":
                         ssl_cert = None
-                p_title = _("Applying changes")
-                p_text = _("Applying changes, please wait ...")
-                self.__run_with_prog_in_thread(self.__update_repository, p_title,
+                self.__run_with_prog_in_thread(self.__add_repository, p_title,
                     p_text, name, url, ssl_key, ssl_cert)
-
-        def __update_repository(self, name, url, ssl_key, ssl_cert):
-                url_same = True
-                name_same = True
-                ssl_key_same = True
-                ssl_cert_same = True
-                if name != self.old_modify_name:
-                        name_same = False
-                if url != self.old_modify_url:
-                        url_same = False
-                if ssl_key != self.old_modify_ssl_key:
-                        ssl_key_same = False
-                if ssl_cert != self.old_modify_ssl_cert:
-                        ssl_cert_same = False
-                if url_same and name_same and ssl_key_same and ssl_cert_same:
-                        self.progress_stop_thread = True
-                        return
-                #we don't enable changing the name of the repository
-                #so this part of the code should be skipped in the current
-                #implementation.
-                if not name_same:
-                        omn = self.old_modify_name
-                        if not self.__is_name_valid(name):
-                                self.progress_stop_thread = True
-                                err = _("Failed to modify %(old_name)s."
-                                    "\nThe chosen repository name %(new_name)s is "
-                                    "already in use") % \
-                                    {'old_name': omn,
-                                     'new_name': name}
-                                gobject.idle_add(self.__error_occurred, err)
-                                self.progress_stop_thread = True
-                                return
-                        try:
-                                self.__delete_repository(self.old_modify_name, False)
-                        except api_errors.PermissionsException:
-                                # Do nothing
-                                err = _("Failed to modify %s." 
-                                    "\nPlease check your permissions.") % omn
-                                self.__error_with_reset_repo_selection(err,
-                                    gtk.MESSAGE_INFO)
-                                return
-                        except RuntimeError, ex:
-                                if "no defined authorities" in str(ex):
-                                        pass
-                                else:
-                                        err = str(ex)
-                                        self.__error_with_reset_repo_selection(err)
-                                        return
-                        except Exception, ex:
-                                err = _("Failed to modify %s.\n") % omn
-                                err += str(ex)
-                                self.__error_with_reset_repo_selection(err)
-                                return
-                try:
-                        self.__add_repository(name, url, ssl_key, ssl_cert, silent=False)
-                        if self.old_modify_preferred:
-                                self.img.set_preferred_authority(name)
-                                self.__prepare_repository_list(False)
-                except api_errors.PermissionsException:
-                        # Do nothing
-                        somn = self.old_modify_name
-                        err = _("Failed to modify %s."
-                            "\nPlease check your permissions.") % omn
-                        self.__error_with_reset_repo_selection(err,
-                            gtk.MESSAGE_INFO)
-                        return
-                except RuntimeError, ex:
-                        #The "no defined authorities" should never happen
-                        #Because we skipped removal of repository during name
-                        #change as we disabled name changing.
-                        if "no defined authorities" in str(ex):
-                                pass
-                        else:
-                                err = str(ex)
-                                self.__error_with_reset_repo_selection(err)
-                                return
-                except api_errors.CatalogRefreshException:
-                        try:
-                                somn = self.old_modify_name
-                                self.__add_repository(somn,
-                                    self.old_modify_url, silent=False, stop_thread=False)
-                                if somn != name:
-                                        self.__delete_repository(name, False)
-                                err = _("Failed to modify %s.") % somn + \
-                                    _(
-                                    "\nPlease check the network connection or URL.\n"
-                                    "Is the repository accessible?")
-                                gobject.idle_add(self.__error_occurred, err,
-                                    gtk.MESSAGE_INFO)
-                        except api_errors.CatalogRefreshException:
-                                #We need to show at least one warning dialog
-                                #This is for repository which didn't existed 
-                                #and was modified
-                                #To not existed repository
-                                somn = self.old_modify_name
-                                err = _("Failed to modify %s.") % somn + \
-                                    _(
-                                    "\nPlease check the network connection or URL.\n"
-                                    "Is the repository accessible?")
-                                gobject.idle_add(self.__error_occurred, err,
-                                    gtk.MESSAGE_INFO)
-                except Exception, ex:
-                        err = _("Failed to modify %s.\n") % omn
-                        err += str(ex)
-                        self.__error_with_reset_repo_selection(err)
-                        return
-
-                self.progress_stop_thread = True
-                return
-
+                    
+                self.__clear_repositorymodify()
 
         def __on_repositorymodify_delete_event(self, widget, event):
                 self.__on_repositorymodifycancel_clicked(widget)
+                return True
 
+        def __clear_repositorymodify(self):
+                self.w_repositorymodify_registration_comment_label.hide()
+                self.w_repositorymodify_registration_link.hide()
+                self.w_repositorymodify_registration_link.set_uri("")
+                
+                self.w_repositorymodify_ssl_expander.set_expanded(False)                
+                self.w_repositorymodify_key_entry.set_text("")
+                self.w_repositorymodify_cert_entry.set_text("")
+                
+                self.w_repositorymodify_mirrors_expander.set_expanded(False)
+                self.w_mirror_add_entry.set_text("")
+                
         def __on_repositorymodifycancel_clicked(self, widget):
                 self.w_repository_treeview.grab_focus()
                 self.w_repositorymodify_dialog.hide()
-
+                self.webinstall_new = False
+                self.__clear_repositorymodify()
+                
         def __delete_selected_row(self):
                 tsel = self.w_repository_treeview.get_selection()
                 selection = tsel.get_selected()
@@ -779,63 +870,98 @@
                         name = model.get_value(itr, 0)
                         self.__delete_repository(name)
 
-        def __add_repository(self, auth, origin_url, ssl_key=None, 
+        def __add_repository(self, prefix, origin_url, ssl_key=None, 
             ssl_cert=None, silent=True, stop_thread=True):
+                if self.pub_copy == None:
+                        return
+                pub = self.pub_copy
+                repo = pub.selected_repository
+
+                try:
+                        new_pub = not self.api_o.has_publisher(pub.prefix)
+
+                        # XXX once image configuration supports storing this
+                        # information at the uri level, ssl info should
+                        # be set here instead of below.
+                        if not repo.origins:
+                                repo.add_origin(origin_url)
+                                origin = repo.origins[0]
+                        else:
+                                origin = repo.origins[0]
+                                origin.uri = origin_url
 
-                if not misc.valid_auth_url(origin_url):
-                        err = _("Invalid URL:\n%s" % origin_url)
-                        gobject.idle_add(self.__error_occurred, err)
+                        for uri in repo.origins:
+                                if ssl_cert is not None:
+                                        uri.ssl_cert = ssl_cert
+                                if ssl_key is not None:
+                                        uri.ssl_key = ssl_key
+                        for uri in repo.mirrors:
+                                if ssl_cert is not None:
+                                        uri.ssl_cert = ssl_cert
+                                if ssl_key is not None:
+                                        uri.ssl_key = ssl_key
+                                        
+                        if new_pub:
+                                self.api_o.add_publisher(pub)
+                        else:
+                                self.api_o.update_publisher(pub)
+                                
+                        if self.webinstall_new:
+                                self.webinstall_new = False
+                                self.progress_stop_thread = True
+                                self.parent.reload_packages()
+                        else:
+                                self.__prepare_repository_list(silent,
+                                        selected_pub=prefix, stop_thread=stop_thread)
+                        self.pub_copy = None
+                        self.repo_copy = None
+                        
+                except api_errors.PublisherError, ex:
+                        if not silent:
+                                raise
+                        gobject.idle_add(self.__error_occurred, str(ex),
+                            gtk.MESSAGE_ERROR)
                         gobject.idle_add(self.w_repository_name.grab_focus)
                         self.progress_stop_thread = True
-                        return
-                try:
-                        refresh_catalogs = True
-                        self.img.set_authority(auth, origin_url=origin_url,
-                            ssl_key=ssl_key, ssl_cert=ssl_cert,
-                            refresh_allowed=refresh_catalogs)
-                        self.__prepare_repository_list(silent,
-                            auth, stop_thread=stop_thread)
+                except InvalidDepotResponseException, idrex:
+                        if not silent:
+                                raise
+                        err = (_("Failed to add repository: %s\n\n") % prefix)
+                        err += str(idrex)
+                        self.__error_with_reset_repo_selection(err)
                 except RuntimeError, ex:
                         if not silent:
                                 raise
-                        err = (_("Failed to add %s.\n") % auth)
+                        err = (_("Failed to add %s.\n") % prefix)
                         err += str(ex)
                         self.__error_with_reset_repo_selection(err)
                         return
                 except api_errors.PermissionsException:
                         if not silent:
                                 raise
-                        err = (_("Failed to add %s.") % auth) + \
+                        err = (_("Failed to add %s.") % prefix) + \
                             _("\nPlease check your permissions.")
                         self.__error_with_reset_repo_selection(err,
                             gtk.MESSAGE_INFO)
                 except api_errors.CatalogRefreshException:
                         if not silent:
                                 raise
-                        self.__delete_repository(auth)
-                        err = _("Failed to add %s.") % auth + \
+                        self.__delete_repository(pub)
+                        err = _("Failed to add %s.") % prefix + \
                             _(
                             "\nPlease check the network connection or URL.\nIs the "
                             "repository accessible?")
                         self.__error_with_reset_repo_selection(err, gtk.MESSAGE_INFO)
-                except Exception, ex:
-                        if not silent:
-                                raise
-                        err = (_("Failed to add %s.\n") % auth)
-                        err += str(ex)
-                        self.__error_with_reset_repo_selection(err)
 
         def __delete_repository(self, name, silent=True):
                 try:
-                        self.img.delete_authority(name)
+                        self.api_o.remove_publisher(name)
                         self.__prepare_repository_list(clear_add_entries = False, \
                             stop_thread = silent)
-                except RuntimeError, ex:
+                except api_errors.PublisherError, ex:
                         if not silent:
                                 raise
-                        err = (_("Failed to delete %s.\n") % name)
-                        err += str(ex)
-                        self.__error_with_reset_repo_selection(err)
+                        self.__error_with_reset_repo_selection(str(ex))
                         return
                 except api_errors.PermissionsException:
                         if not silent:
@@ -844,13 +970,6 @@
                             _("\nPlease check your permissions.")
                         self.__error_with_reset_repo_selection(err,
                             gtk.MESSAGE_INFO)
-                        return
-                except Exception, ex:
-                        if not silent:
-                                raise
-                        err = (_("Failed to delete %s.\n") % name)
-                        err += str(ex)
-                        self.__error_with_reset_repo_selection(err)
 
         def __setup_mirrors(self, mirrors):
                 self.mirror_list.clear()
@@ -868,111 +987,35 @@
                         self.w_mirror_remove_button.set_sensitive(False)
 
         def __add_mirror(self):
-                name = self.w_repositorymodify_name.get_text()
                 mirror = self.w_mirror_add_entry.get_text()
+                self.w_mirror_add_entry.set_text("")
                 try:
-                        self.img.add_mirror(name, mirror)
-                        self.w_mirror_add_entry.set_text("")
-                        tsel = self.w_repository_treeview.get_selection()
-                        selection = tsel.get_selected()
-                        itr = selection[1]
-                        if itr != None:
-                                model = selection[0]
-                                mirrors = model.get_value(itr,
-                                    enumerations.AUTHORITY_MIRRORS)
-                                gobject.idle_add(self.__setup_mirrors, mirrors)
-                        self.progress_stop_thread = True
-                except RuntimeError, ex:
-                        err = (_("Failed to add mirror %(mirror)s for "
-                            "repository %(repository)s.\n") % \
-                            {'mirror': mirror,
-                             'repository': name})
-                        err += str(ex)
-                        gobject.idle_add(self.__error_occurred, err,
-                            gtk.MESSAGE_ERROR)
-                        self.progress_stop_thread = True
-                        return
-                except api_errors.PermissionsException:
-                        err = (_("Failed to add mirror %(mirror)s for "
-                            "repository %(repository)s.") % \
-                            {'mirror': mirror,
-                             'repository': name}) + \
-                            _("\nPlease check your permissions.")
-                        gobject.idle_add(self.__error_occurred, err,
-                            gtk.MESSAGE_INFO)
-                        self.progress_stop_thread = True
-                        return
-                except Exception, ex:
-                        err = (_("Failed to add mirror %(mirror)s for "
-                            "repository %(repository)s.\n") % \
-                            {'mirror': mirror,
-                             'repository': name})
-                        err += str(ex)
-                        gobject.idle_add(self.__error_occurred, err,
-                            gtk.MESSAGE_ERROR)
-                        self.progress_stop_thread = True
-                        return
+                        self.repo_copy.add_mirror(mirror)
+                except api_errors.PublisherError, ex:
+                        self.__error_with_reset_repo_selection(str(ex))
+                        return                        
+                gobject.idle_add(self.__setup_mirrors, self.repo_copy.mirrors)
 
-        def __delete_mirror(self, name, mirror):
+        def __delete_mirror(self, mirror):
                 try:
-                        self.img.del_mirror(name, mirror)
-                        tsel = self.w_repository_treeview.get_selection()
-                        selection = tsel.get_selected()
-                        itr = selection[1]
-                        if itr != None:
-                                model = selection[0]
-                                mirrors = model.get_value(itr,
-                                    enumerations.AUTHORITY_MIRRORS)
-                                gobject.idle_add(self.__setup_mirrors, mirrors)
-                        self.progress_stop_thread = True
-                except RuntimeError, ex:
-                        err = (_("Failed to delete mirror %(mirror)s for "
-                            "repository %(repository)s.\n") % \
-                            {'mirror': mirror,
-                             'repository': name})
-                        err += str(ex)
-                        gobject.idle_add(self.__error_occurred, err,
-                            gtk.MESSAGE_ERROR)
-                        self.progress_stop_thread = True
-                        return
-                except api_errors.PermissionsException:
-                        err = (_("Failed to delete mirror %(mirror)s for "
-                            "repository %(repository)s.") % \
-                            {'mirror': mirror,
-                             'repository': name}) + \
-                            _("\nPlease check your permissions.")
-                        gobject.idle_add(self.__error_occurred, err,
-                            gtk.MESSAGE_INFO)
-                        self.progress_stop_thread = True
-                        return
-                except Exception, ex:
-                        err = (_("Failed to delete mirror %(mirror)s for "
-                            "repository %(repository)s.\n") % \
-                            {'mirror': mirror,
-                             'repository': name})
-                        err += str(ex)
-                        gobject.idle_add(self.__error_occurred, err,
-                            gtk.MESSAGE_ERROR)
-                        self.progress_stop_thread = True
-                        return
+                        self.repo_copy.remove_mirror(mirror)
+                except api_errors.PublisherError, ex:
+                        self.__error_with_reset_repo_selection(str(ex))
+                        return                        
+                gobject.idle_add(self.__setup_mirrors, self.repo_copy.mirrors)
 
         def __delete_selected_mirror(self):
                 tsel = self.w_mirror_treeview.get_selection()
                 selection = tsel.get_selected()
                 itr = selection[1]
-                if itr != None:
-                        model = selection[0]
-                        mirror = model.get_value(itr, 0)
-                        name = self.w_repositorymodify_name.get_text()
-                        self.__delete_mirror(name, mirror)
-                else:
-                        self.progress_stop_thread = True
+                if itr == None:
+                        return
+                model = selection[0]
+                mirror = model.get_value(itr, 0)
+                self.__delete_mirror(mirror)
 
         def __on_mirror_remove_clicked(self, widget):
-                p_title = _("Applying changes")
-                p_text = _("Applying changes, please wait ...")
-                self.__run_with_prog_in_thread(self.__delete_selected_mirror, p_title,
-                    p_text)
+                self.__delete_selected_mirror()
 
         def __on_mirrorentry_changed(self, widget):
                 url = widget.get_text()
@@ -982,10 +1025,7 @@
                         self.w_mirror_add_button.set_sensitive(False)
 
         def __on_mirroradd_button_clicked(self, widget):
-                p_title = _("Applying changes")
-                p_text = _("Applying changes, please wait ...")
-                self.__run_with_prog_in_thread(self.__add_mirror, p_title,
-                    p_text)
+                self.__add_mirror()
 
         def __on_mod_key_or_cert_entry_changed(self, widget):
                 key = self.w_repositorymodify_key_entry.get_text()
@@ -1115,15 +1155,19 @@
                         sel = model.get_value(ite, 0)
                 self.progress_stop_thread = True
 
-        def __error_occurred(self, error_msg, msg_type=gtk.MESSAGE_ERROR):
+        def __error_occurred(self, error_msg, msg_type=gtk.MESSAGE_ERROR, title = None):
                 msgbox = gtk.MessageDialog(parent =
-                    self.w_repository_dialog,
+                    self.error_dialog_parent,
                     buttons = gtk.BUTTONS_CLOSE,
                     flags = gtk.DIALOG_MODAL,
                     type = msg_type,
                     message_format = None)
                 msgbox.set_markup(error_msg)
-                msgbox.set_title("Edit Repositories error")
+                if title != None:
+                        msgbox.set_title(title)
+                else:   # More Generic for WebInstall
+                        msgbox.set_title(_("Repository error"))
+                        
                 msgbox.run()
                 msgbox.destroy()
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/modules/webinstall.py	Tue Mar 10 00:01:30 2009 +0000
@@ -0,0 +1,387 @@
+#!/usr/bin/python2.4
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+CLIENT_API_VERSION = 11
+PKG_CLIENT_NAME = "packagemanager"
+
+import locale
+import os
+import sys
+import gettext
+try:
+        import gobject
+        import gtk
+        import pango
+except ImportError:
+        sys.exit(1)
+import pkg.misc as misc
+import pkg.gui.misc as gui_misc
+import pkg.client.progress as progress
+import pkg.client.api_errors as api_errors
+import pkg.client.api as api
+import pkg.gui.installupdate as installupdate
+import pkg.gui.enumerations as enumerations
+import pkg.gui.repository as repository
+from pkg.client import global_settings
+import pkg.client.publisher as publisher
+        
+debug = False
+
+class Webinstall:
+        def __init__(self, image_dir):
+                global_settings.client_name = PKG_CLIENT_NAME
+                self.image_dir = image_dir
+    
+                try:
+                        self.application_dir = os.environ["PACKAGE_MANAGER_ROOT"]
+                except KeyError:
+                        self.application_dir = "/"
+                misc.setlocale(locale.LC_ALL, "")
+                for module in (gettext, gtk.glade):
+                        module.bindtextdomain("pkg", self.application_dir +
+                            "/usr/share/locale")
+                        module.textdomain("pkg")
+                self.pub_pkg_list = None
+                self.pr = progress.NullProgressTracker()
+                self.pub_new_tasks = []
+                self.pkg_install_tasks = []
+                self.param = None
+                self.preferred = None
+                
+                # Webinstall Dialog
+                self.gladefile = self.application_dir + \
+                        "/usr/share/package-manager/packagemanager.glade"
+                w_xmltree_webinstall = gtk.glade.XML(self.gladefile, "webinstalldialog")
+                self.w_webinstall_dialog = \
+                        w_xmltree_webinstall.get_widget("webinstalldialog")
+                
+                self.w_webinstall_proceed = \
+                        w_xmltree_webinstall.get_widget("proceed_button")
+                self.w_webinstall_cancel = \
+                        w_xmltree_webinstall.get_widget("cancel_button")
+                self.w_webinstall_proceed_label = \
+                        w_xmltree_webinstall.get_widget("proceed_new_repo_label")
+                self.w_webinstall_info_label = \
+                        w_xmltree_webinstall.get_widget("label19")
+
+                self.w_webinstall_textview = \
+                        w_xmltree_webinstall.get_widget("webinstall_textview")  
+                infobuffer = self.w_webinstall_textview.get_buffer()
+                infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+
+                try:
+                        dic = \
+                            {
+                                "on_webinstalldialog_close": \
+                                    self.__on_webinstall_dialog_close,
+                                "on_cancel_button_clicked": \
+                                    self.__on_cancel_button_clicked,
+                                "on_proceed_button_clicked": \
+                                    self.__on_proceed_button_clicked,
+                            }
+                        w_xmltree_webinstall.signal_autoconnect(dic)
+
+
+                except AttributeError, error:
+                        print _("GUI will not respond to any event! %s. "
+                            "Check webinstall.py signals") % error
+ 
+                self.w_webinstall_dialog.show_all()
+                self.w_webinstall_dialog.set_icon(
+                    gui_misc.get_app_pixbuf(self.application_dir,"PM_app_48x"))
+                self.api_o = self.__get_api_object(self.image_dir, self.pr)
+        
+        def __output_new_pub_tasks(self, infobuffer, textiter, num_tasks):
+                if num_tasks == 0:
+                        return                                        
+                if num_tasks == 1:
+                        infobuffer.insert_with_tags_by_name(textiter,
+                            _("\n Add New Repository\n"), "bold")
+                else:
+                        infobuffer.insert_with_tags_by_name(textiter,
+                            _("\n Add New Repositories\n"), "bold")
+                self.__output_pub_tasks(infobuffer, textiter, self.pub_new_tasks)
+
+        def __nothing_todo(self, infobuffer, textiter):
+                infobuffer.insert(textiter,
+                    _("\n All specified repositories and packages are already on the "
+                    "system.\n"))
+
+        @staticmethod
+        def __output_pub_tasks(infobuffer, textiter, pub_tasks):
+                for pub_info in pub_tasks:
+                        if pub_info == None:
+                                continue
+                        infobuffer.insert_with_tags_by_name(textiter,
+                            _("\t%s ") % pub_info.prefix, "bold")
+                        repo = pub_info.selected_repository
+                        if repo != None:
+                                infobuffer.insert(textiter,
+                                        _(" (%s)\n") % repo.origins[0].uri)
+
+        def __output_pkg_install_tasks(self, infobuffer, textiter, num_tasks):
+                if num_tasks == 0:
+                        return                        
+                infobuffer.insert_with_tags_by_name(textiter, _("\n Install Packages\n"),
+                    "bold")
+                for entry in self.pkg_install_tasks:
+                        pub_info = entry[0]
+                        packages = entry[1]
+                        if len(packages) > 0:
+                                for pkg in packages:
+                                        infobuffer.insert_with_tags_by_name(textiter,
+                                            _("\t%s: ")
+                                            % pub_info.prefix, "bold")
+                                        infobuffer.insert(textiter,
+                                            _("%s\n") % pkg)
+                        
+        def process_param(self, param=None):
+                if param == None or self.api_o == None:
+                        self.w_webinstall_proceed.set_sensitive(False)
+                        return
+                self.param = param
+                self.pub_pkg_list = self.api_parse_publisher_info(param)
+                if self.pub_pkg_list == None:
+                        self.w_webinstall_proceed.set_sensitive(False)
+                        return
+                self.__create_task_lists()        
+                infobuffer = self.w_webinstall_textview.get_buffer()
+                infobuffer.set_text("")
+                
+                num_new_pub = len(self.pub_new_tasks)
+                num_install_tasks = len(self.pkg_install_tasks)
+
+                self.__set_proceed_label(num_new_pub)
+                textiter = infobuffer.get_end_iter()
+                if num_new_pub == 0 and num_install_tasks == 0:
+                        self.__nothing_todo(infobuffer, textiter)
+                        self.w_webinstall_proceed.set_sensitive(False)
+                        self.w_webinstall_cancel.grab_focus()
+                        self.w_webinstall_info_label.hide()
+                        return
+                        
+                self.__output_new_pub_tasks(infobuffer, textiter, num_new_pub)
+                self.__output_pkg_install_tasks(infobuffer, textiter, num_install_tasks)
+
+                infobuffer.place_cursor(infobuffer.get_start_iter())
+                self.w_webinstall_proceed.grab_focus()
+                                
+        def __set_proceed_label(self, num_new_pub):
+                if num_new_pub == 0:
+                        self.w_webinstall_proceed_label.hide()
+                else:
+                        if num_new_pub == 1:
+                                self.w_webinstall_proceed_label.set_text(
+                                    _("Proceed only if you trust this new repository "))
+                        else:
+                                self.w_webinstall_proceed_label.set_text(
+                                    _("Proceed only if you trust these new repositories"))
+
+        def __on_webinstall_dialog_close(self, widget, param=None):
+                self.__exit_app()
+
+        def __on_cancel_button_clicked(self, widget):
+                self.__exit_app()
+
+        def __exit_app(self, be_name = None):
+                self.w_webinstall_dialog.destroy()
+                gtk.main_quit()
+                sys.exit(0)
+                return
+
+        def __create_task_lists(self):
+                pub_new_reg_ssl_tasks = []
+                self.pub_new_tasks = []
+                self.pkg_install_tasks = []
+                for entry in self.pub_pkg_list:
+                        pub_info = entry[0]
+                        packages = entry[1]
+                        if not pub_info:
+                                # TBD: For nowe we are skipping p5i files which contains
+                                # only pkg names and not publisher information
+                                continue
+
+                        repo = pub_info.repositories
+
+                        if not self.__is_publisher_registered(pub_info.prefix):
+                                if len(repo) > 0 and repo[0].origins[0] != None and \
+                                    repo[0].origins[0].scheme == "https":
+                                        #TBD: check for registration uri as well as scheme
+                                        #    repo.registration_uri.uri != None:
+                                        pub_new_reg_ssl_tasks.append(pub_info)
+                                else:
+                                        self.pub_new_tasks.append(pub_info)
+                        if packages != None and len(packages) > 0:
+                                self.pkg_install_tasks.append((pub_info, packages))
+                self.pub_new_tasks = pub_new_reg_ssl_tasks + self.pub_new_tasks
+                        
+        def __is_publisher_registered(self, name):
+                try:
+                        if self.api_o != None and self.api_o.has_publisher(name):
+                                return True
+                except api_errors.PublisherError, ex:
+                        gobject.idle_add(self.__error_occurred, self.w_webinstall_dialog, 
+                            str(ex), gtk.MESSAGE_ERROR, _("Repository Error"))
+                return False
+
+        def __on_proceed_button_clicked(self, widget):
+                self.w_webinstall_proceed.set_sensitive(False)
+                self.__create_task_lists()
+                if len(self.pub_new_tasks) > 0:
+                        self.__add_new_pub()
+                        return
+                if len(self.pkg_install_tasks) > 0:
+                        self.__install_pkgs()
+                        return
+                        
+        def __add_new_pub(self):
+                if len(self.pub_new_tasks) == 0:
+                        return
+                pub = self.pub_new_tasks.pop(0)
+                if debug:
+                        print("Add New Publisher:\n\tName: %s" % pub.prefix)
+                        repo = pub.selected_repository
+                        print("\tURL: %s" % repo.origins[0].uri)
+                        
+                repo_gui = repository.Repository(self, True)
+                repo_gui.webinstall_new_pub(self.w_webinstall_dialog, pub)
+
+        # Publisher Callback - invoked at end of adding publisher
+        def reload_packages(self):
+                if len(self.pub_new_tasks) > 0:
+                        self.__add_new_pub()
+                        return
+                elif len(self.pkg_install_tasks) > 0:
+                        self.__install_pkgs()
+                else:
+                        self.__exit_app()
+                
+        def __install_pkgs(self):
+                if len(self.pkg_install_tasks) == 0:
+                        return
+                # Handle all packages from all pubs as single install action
+                pref_pub = self.api_o.get_preferred_publisher()
+                self.preferred = pref_pub.prefix
+                all_package_stems = []        
+                for pkg_installs in self.pkg_install_tasks:
+                        pub_info = pkg_installs[0]
+                        packages = pkg_installs[1]
+                        pub_pkg_stems = self.process_pkg_stems(pub_info, packages)
+                        for pkg in pub_pkg_stems:
+                                all_package_stems.append(pkg)
+                self.pkg_install_tasks = []
+
+                if debug:
+                        print "Install Packages: %s" % all_package_stems
+                
+                #TBD: Having to get new api object, self.api_o.reset() is not working
+                self.api_o = self.__get_api_object(self.image_dir, self.pr)
+                installupdate.InstallUpdate(all_package_stems, self, self.api_o, 
+                    action = enumerations.INSTALL_UPDATE,
+                    parent_name = _("Package Manager"),
+                    main_window = self.w_webinstall_dialog,
+                    icon_confirm_dialog = gui_misc.get_app_pixbuf(
+                        self.application_dir,"PM_package_36x"),
+                    web_install = True)
+
+        def process_pkg_stems(self, pub_info, packages):
+                if not self.__is_publisher_registered(pub_info.prefix):
+                        return []
+                if pub_info.prefix == self.preferred:
+                        pkg_stem = "pkg:/"
+                else:
+                        pkg_stem = "pkg://" + pub_info.prefix + "/"
+                packages_with_stem = []
+                for pkg in packages:
+                        packages_with_stem.append(pkg_stem + pkg)
+                return packages_with_stem
+       
+        # Install Callback - invoked at end of installing packages
+        def update_package_list(self, update_list):
+                self.__exit_app()
+
+        def __get_api_object(self, img_dir, progtrack):
+                api_o = None
+                try:
+                        api_o = api.ImageInterface(img_dir,
+                            CLIENT_API_VERSION,
+                            progtrack, None, PKG_CLIENT_NAME)
+                except (api_errors.VersionException,\
+                    api_errors.ImageNotFoundException), ex:
+                        gobject.idle_add(self.__error_occurred, self.w_webinstall_dialog, 
+                            str(ex), gtk.MESSAGE_ERROR, _("API Error"))
+                return api_o
+
+        # TBD: Move generic error handling into gui misc module and reuse across modules
+        @staticmethod
+        def __error_occurred(parent, error_msg, msg_type=gtk.MESSAGE_ERROR, 
+                title = None):
+                msgbox = gtk.MessageDialog(parent =
+                    parent,
+                    buttons = gtk.BUTTONS_CLOSE,
+                    flags = gtk.DIALOG_MODAL,
+                    type = msg_type,
+                    message_format = None)
+                msgbox.set_markup(error_msg)
+                if title != None:
+                        msgbox.set_title(title)
+                else:
+                        msgbox.set_title(_("Error"))
+                        
+                msgbox.run()
+                msgbox.destroy()
+
+        def api_parse_publisher_info(self, param=None):
+                '''<path to mimetype file|origin_url>
+                   returns list of publisher and package list tuples'''
+                p5i_info = None
+                if self.param.endswith(".p5i"):                
+                        try:
+                                file_obj = open(self.param)
+                                p5i_info = self.api_o.parse_p5i(file_obj)
+                                file_obj.close()
+                        except (api_errors.InvalidP5IFile, 
+                                api_errors.InvalidResourceLocation,
+                                api_errors.RetrievalError,
+                                api_errors.UnsupportedP5IFile,
+                                api_errors.PublisherError), ex:
+                                self.w_webinstall_proceed.set_sensitive(False)
+                                self.__error_occurred( 
+                                    self.w_webinstall_dialog,
+                                    str(ex), gtk.MESSAGE_ERROR, _("Repository Error"))
+                                file_obj.close()
+                                return None
+                        except IOError:
+                                file_obj.close()
+                                self.w_webinstall_proceed.set_sensitive(False)
+                                msg = _("Error reading the p5i file.")
+                                self.__error_occurred(
+                                    self.w_webinstall_dialog,
+                                    msg, gtk.MESSAGE_ERROR, _("Repository Error"))                        
+                                return None
+                else:
+                        self.w_webinstall_proceed.set_sensitive(False)
+                        return None
+                return p5i_info
--- a/src/packagemanager.py	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/packagemanager.py	Tue Mar 10 00:01:30 2009 +0000
@@ -50,7 +50,7 @@
 
 STATUS_COLUMN_INDEX = 2   # Index of Status Column in Application TreeView
 
-CLIENT_API_VERSION = 10
+CLIENT_API_VERSION = 11
 PKG_CLIENT_NAME = "packagemanager"
 
 # Load Start Page from lang dir if available
@@ -72,6 +72,7 @@
 EXTERNAL_PROTOCOL = 'protocol' # External field: optional protocol scheme,
                                # defaults to http
 DEFAULT_PROTOCOL = 'http'
+PKGINFO_SUFFIX   = '.p5i'      # Mime type file extension
 
 import getopt
 import os
@@ -100,7 +101,6 @@
 except ImportError:
         sys.exit(1)
 import pkg.misc as misc
-import pkg.client.history as history
 import pkg.client.progress as progress
 import pkg.client.api_errors as api_errors
 import pkg.client.api as api
@@ -114,6 +114,7 @@
 import pkg.gui.installupdate as installupdate
 import pkg.gui.enumerations as enumerations
 import pkg.gui.parseqs as parseqs
+import pkg.gui.webinstall as webinstall
 from pkg.client import global_settings
 
 # Put _() in the global namespace
@@ -172,7 +173,7 @@
                 self.update_all_proceed = False
                 self.ua_be_name = None
                 self.application_path = None
-                self.default_authority = None
+                self.default_publisher = None
                 self.first_run = True
                 self.selected_pkgstem = None
                 self.selected_model = None
@@ -201,6 +202,7 @@
                 self.category_list = None
                 self.repositories_list = None
                 self.pr = progress.NullProgressTracker()
+                self.pylintstub = None
                 
                 # Create Widgets and show gui
                 self.gladefile = self.application_dir + \
@@ -774,6 +776,7 @@
                     application_list_sort)
                 category_selection = self.w_categories_treeview.get_selection()
                 category_model, category_iter = category_selection.get_selected()
+                self.pylintstub = category_model
                 if not category_iter:         #no category was selected, so select "All"
                         category_selection.select_path(0)
                         category_model, category_iter = category_selection.get_selected()
@@ -958,7 +961,8 @@
                         for column in columns:
                                 treeview.remove_column(column)
 
-        def __init_sections(self, section_list):
+        @staticmethod
+        def __init_sections(section_list):
                 '''This function is for initializing sections combo box, also adds "All"
                 Category. It sets active section combobox entry "All"'''
                 cat_path = None
@@ -1371,62 +1375,63 @@
 
         def __on_repositorycombobox_changed(self, widget):
                 '''On repository combobox changed'''
-                active_authority = self.__get_active_authority()
-                if self.visible_repository == active_authority:
+                active_publisher = self.__get_active_publisher()
+                if self.visible_repository == active_publisher:
                         # If we are coming back to the same repository, we do
-                        # not want to setup authorities. This is the case when
+                        # not want to setup publishers. This is the case when
                         # we are calling Add... then we are firing the event for
                         # Add... case and imidiatelly coming back to the
                         # previously selected repository.
                         return
                 # Checking for Add... is fine enought, as the repository name can't
                 # contain "..." in the name.
-                if active_authority == _("Add..."):
+                if active_publisher == _("Add..."):
                         model = self.w_repository_combobox.get_model()
                         index = -1
                         for entry in model:
                                 if entry[1] == self.visible_repository:
                                         index = entry[0]
                         # We do not want to switch permanently to the Add...
-                        self.w_repository_combobox.set_active(index)                        
+                        self.w_repository_combobox.set_active(index)
                         self.__on_edit_repositories_activate(None)
                         return
                 self.cancelled = True
                 self.in_setup = True
                 self.set_busy_cursor()
                 self.__set_empty_details_panel()
-                auth = [active_authority, ]
-                Thread(target = self.__setup_authority, args = [auth]).start()
+                pub = [active_publisher, ]
+                Thread(target = self.__setup_publisher, args = [pub]).start()
                 self.__set_main_view_package_list()
 
-        def __get_active_authority(self):
-                auth_iter = self.w_repository_combobox.get_active_iter()
-                return self.repositories_list.get_value(auth_iter, \
+        def __get_active_publisher(self):
+                pub_iter = self.w_repository_combobox.get_active_iter()
+                return self.repositories_list.get_value(pub_iter, \
                             enumerations.REPOSITORY_NAME)
 
-        def __setup_authority(self, authorities=[]):
+        def __setup_publisher(self, publishers=[]):
                 application_list, category_list , section_list = \
-                    self.__get_application_categories_lists(authorities)
+                    self.__get_application_categories_lists(publishers)
                 gobject.idle_add(self.__init_tree_views, application_list,
                     category_list, section_list)
 
-        def __get_application_categories_lists(self, authorities=[]):
+        def __get_application_categories_lists(self, publishers=[]):
                 if not self.visible_repository:
-                        self.visible_repository = self.__get_active_authority()
+                        self.visible_repository = self.__get_active_publisher()
                 application_list = self.__get_new_application_liststore()
                 category_list = self.__get_new_category_liststore()
                 section_list = self.__get_new_section_liststore()
                 first_loop = True
-                for authority in authorities:
+                for publisher in publishers:
                         uptodate = False
                         try:
-                                uptodate = self.__check_if_cache_uptodate(authority)
+                                uptodate = self.__check_if_cache_uptodate(publisher)
                                 if uptodate:
-                                        self.__add_pkgs_to_lists_from_cache(authority, 
+                                        self.__add_pkgs_to_lists_from_cache(publisher,
                                             application_list, category_list, 
                                             section_list)
                         except (UnpicklingError, EOFError):
-                                #Most likely cache is corrupted, silently load list from api.
+                                #Most likely cache is corrupted, silently load list
+                                #from api.
                                 application_list = self.__get_new_application_liststore()
                                 category_list = self.__get_new_category_liststore()
                                 uptodate = False
@@ -1437,8 +1442,8 @@
                                 self.catalog_loaded = False
                                 self.api_o.img.load_catalogs(self.pr)
                                 self.catalog_loaded = True
-                                self.__add_pkgs_to_lists_from_api(authority, application_list, 
-                                    category_list, section_list)
+                                self.__add_pkgs_to_lists_from_api(publisher,
+                                    application_list, category_list, section_list)
                                 category_list.prepend([0, _('All'), None, None, False, 
                                     True, None])
                         if self.application_list and self.category_list and \
@@ -1446,20 +1451,20 @@
                                 self.__dump_datamodels(self.visible_repository, 
                                     self.application_list, self.category_list,
                                     self.section_list)
-                        self.visible_repository = self.__get_active_authority()
+                        self.visible_repository = self.__get_active_publisher()
                         self.visible_repository_uptodate = uptodate
                 return application_list, category_list, section_list
 
-        def __check_if_cache_uptodate(self, authority):
+        def __check_if_cache_uptodate(self, publisher):
                 if self.cache_o:
-                        return self.cache_o.check_if_cache_uptodate(authority)
+                        return self.cache_o.check_if_cache_uptodate(publisher)
                 return False
 
-        def __dump_datamodels(self, authority, application_list, category_list,
+        def __dump_datamodels(self, publisher, application_list, category_list,
             section_list):
                 if self.cache_o:
                         Thread(target = self.cache_o.dump_datamodels,
-                            args = (authority, application_list, category_list,
+                            args = (publisher, application_list, category_list,
                             section_list)).start()
 
         def __on_install_update(self, widget):
@@ -1586,25 +1591,22 @@
                 return False
 
         def __setup_repositories_combobox(self, api_o, repositories_list):
-                img = api_o.img
-                if img == None:
-                        return
                 self.__disconnect_repository_model()
-                img.load_config()
-                auths = img.gen_authorities()
-                default_auth = img.get_default_authority()
-                if self.default_authority != default_auth:
+                default_pub = api_o.get_preferred_publisher().prefix
+                if self.default_publisher != default_pub:
                         self.__clear_pkg_selections()
-                        self.default_authority = default_auth
+                        self.default_publisher = default_pub
                 selected_repos = []
                 enabled_repos = []
                 for repo in self.selected_pkgs:
                         selected_repos.append(repo)
                 i = 0
                 active = 0
-                for repo in auths:
-                        prefix = repo.get("prefix")
-                        if cmp(prefix, self.default_authority) == 0:
+                for pub in api_o.get_publishers():
+                        if pub.disabled:
+                                continue
+                        prefix = pub.prefix
+                        if cmp(prefix, self.default_publisher) == 0:
                                 active = i
                         repositories_list.append([i, prefix, ])
                         enabled_repos.append(prefix)
@@ -1620,7 +1622,7 @@
                 for pkg_stem in pkgs_to_remove:
                         self.__remove_pkg_stem_from_list(pkg_stem)
                 self.w_repository_combobox.set_model(repositories_list)
-                if self.default_authority:
+                if self.default_publisher:
                         self.w_repository_combobox.set_active(active)
                 else:
                         self.w_repository_combobox.set_active(0)
@@ -1653,41 +1655,41 @@
                         self.w_reload_button.set_sensitive(False)
 
         def __add_pkg_stem_to_list(self, stem, status):
-                authority = self.__get_active_authority()
-                if self.selected_pkgs.get(authority) == None:
-                        self.selected_pkgs[authority] = {}
-                self.selected_pkgs.get(authority)[stem] = status
+                publisher = self.__get_active_publisher()
+                if self.selected_pkgs.get(publisher) == None:
+                        self.selected_pkgs[publisher] = {}
+                self.selected_pkgs.get(publisher)[stem] = status
                 if status == enumerations.NOT_INSTALLED or \
                     status == enumerations.UPDATABLE:
-                        if self.to_install_update.get(authority) == None:
-                                self.to_install_update[authority] = 1
+                        if self.to_install_update.get(publisher) == None:
+                                self.to_install_update[publisher] = 1
                         else:
-                                self.to_install_update[authority] += 1
+                                self.to_install_update[publisher] += 1
                 if status == enumerations.UPDATABLE or status == enumerations.INSTALLED:
-                        if self.to_remove.get(authority) == None:
-                                self.to_remove[authority] = 1
+                        if self.to_remove.get(publisher) == None:
+                                self.to_remove[publisher] = 1
                         else:
-                                self.to_remove[authority] += 1
+                                self.to_remove[publisher] += 1
                 self.__update_tooltips()
 
         def __update_tooltips(self):
                 to_remove = None
                 to_install = None
                 no_iter = 0
-                for authority in self.to_remove:
-                        packages = self.to_remove.get(authority)
+                for publisher in self.to_remove:
+                        packages = self.to_remove.get(publisher)
                         if packages > 0:
                                 if no_iter == 0:
                                         to_remove = _("Selected for Removal:")
-                                to_remove += "\n   %s: %d" % (authority, packages)
+                                to_remove += "\n   %s: %d" % (publisher, packages)
                                 no_iter += 1
                 no_iter = 0
-                for authority in self.to_install_update:
-                        packages = self.to_install_update.get(authority)
+                for publisher in self.to_install_update:
+                        packages = self.to_install_update.get(publisher)
                         if packages > 0:
                                 if no_iter == 0:
                                         to_install = _("Selected for Install/Update:")
-                                to_install += "\n   %s: %d" % (authority, packages)
+                                to_install += "\n   %s: %d" % (publisher, packages)
                                 no_iter += 1
                 if not to_install:
                         to_install = _("Select packages by marking checkbox\n"+
@@ -1700,39 +1702,39 @@
                 self.w_remove_button.set_tooltip(self.remove_button_tooltip, to_remove)
 
         def __remove_pkg_stem_from_list(self, stem):
-                remove_auth = []
-                for authority in self.selected_pkgs:
-                        pkgs = self.selected_pkgs.get(authority)
+                remove_pub = []
+                for publisher in self.selected_pkgs:
+                        pkgs = self.selected_pkgs.get(publisher)
                         status = None
                         if stem in pkgs:
                                 status = pkgs.pop(stem)
                         if status == enumerations.NOT_INSTALLED or \
                             status == enumerations.UPDATABLE:
-                                if self.to_install_update.get(authority) == None:
-                                        self.to_install_update[authority] = 0
+                                if self.to_install_update.get(publisher) == None:
+                                        self.to_install_update[publisher] = 0
                                 else:
-                                        self.to_install_update[authority] -= 1
+                                        self.to_install_update[publisher] -= 1
                         if status == enumerations.UPDATABLE or \
                             status == enumerations.INSTALLED:
-                                if self.to_remove.get(authority) == None:
-                                        self.to_remove[authority] = 0
+                                if self.to_remove.get(publisher) == None:
+                                        self.to_remove[publisher] = 0
                                 else:
-                                        self.to_remove[authority] -= 1
+                                        self.to_remove[publisher] -= 1
                         if len(pkgs) == 0:
-                                remove_auth.append(authority)
-                for authority in remove_auth:
-                        self.selected_pkgs.pop(authority)
+                                remove_pub.append(publisher)
+                for publisher in remove_pub:
+                        self.selected_pkgs.pop(publisher)
                 self.__update_tooltips()
 
         def __clear_pkg_selections(self):
                 # We clear the selections as the preffered repository was changed
                 # and pkg stems are not valid.
-                remove_auth = []
-                for authority in self.selected_pkgs:
-                        stems = self.selected_pkgs.get(authority)
+                remove_pub = []
+                for publisher in self.selected_pkgs:
+                        stems = self.selected_pkgs.get(publisher)
                         for pkg_stem in stems:
-                                remove_auth.append(pkg_stem)
-                for pkg_stem in remove_auth:
+                                remove_pub.append(pkg_stem)
+                for pkg_stem in remove_pub:
                         self.__remove_pkg_stem_from_list(pkg_stem)
 
         def __set_empty_details_panel(self):
@@ -1984,8 +1986,7 @@
                 pkg_status = model.get_value(itr, enumerations.STATUS_COLUMN)
                 if self.info_cache.has_key(pkg_stem):
                         return
-                img = self.api_o.img
-                img.history.operation_name = "info"
+                self.api_o.log_operation_start("info")
                 local_info = None
                 remote_info = None
                 if show_id == self.show_info_id and (pkg_status == 
@@ -1999,7 +2000,7 @@
                 if show_id == self.show_info_id:
                         gobject.idle_add(self.__update_package_info, pkg, 
                             local_info, remote_info)
-                img.history.operation_result = history.RESULT_SUCCEEDED
+                self.api_o.log_operation_end()
                 return
 
         # This function is ported from pkg.actions.generic.distinguished_name()
@@ -2061,8 +2062,8 @@
                                     filter_id))
                 else:
                         return False
-
-        def __is_package_filtered(self, model, itr, filter_id):
+        @staticmethod
+        def __is_package_filtered(model, itr, filter_id):
                 '''Function for filtercombobox'''
                 if filter_id == 0:
                         return True
@@ -2083,14 +2084,14 @@
                         pkg = model.get_value(itr, enumerations.FMRI_COLUMN)
                         if not pkg:
                                 return False
-                        if cmp(pkg.get_authority(), visible_repository) == 0:
+                        if cmp(pkg.get_publisher(), visible_repository) == 0:
                                 return True
                         else:
                                 return False
 
         def __get_visible_repository_name(self):
-                auth_iter = self.w_repository_combobox.get_active_iter()
-                visible = self.repositories_list.get_value(auth_iter, \
+                pub_iter = self.w_repository_combobox.get_active_iter()
+                visible = self.repositories_list.get_value(pub_iter, \
                     enumerations.REPOSITORY_NAME)
                 return visible
 
@@ -2202,7 +2203,9 @@
                             all_known, all_versions)
                         for pfmri, state in res:
                                 if state["upgradable"]:
+                                        self.pylintstub = pfmri    
                                         return True
+                                        
                 except api_errors.InventoryException:
                         return False
                 return False
@@ -2222,15 +2225,14 @@
 
         def __catalog_refresh(self, reload_gui=True):
                 """Update image's catalogs."""
-                full_refresh = True
                 try:
-                        self.api_o.refresh(full_refresh)
+                        self.api_o.refresh(True)
                         self.catalog_loaded = False
                         self.api_o.img.load_catalogs(self.pr)
                         self.catalog_loaded = True
-                except api_errors.UnrecognizedAuthorityException:
+                except api_errors.PublisherError:
                         # In current implementation, this will never happen
-                        # We are not refrehsing specific authority
+                        # We are not refrehsing specific publisher
                         self.__catalog_refresh_done()
                         raise
                 except api_errors.PermissionsException:
@@ -2245,7 +2247,7 @@
                         ermsg += _("Details:\n")
                         ermsg += "%s/%s" % (succeeded, total) 
                         ermsg += _(" catalogs successfully updated:\n") 
-                        for auth, err in cre.failed:
+                        for pub, err in cre.failed:
                                 if isinstance(err, HTTPError):
                                         ermsg += "   %s: %s - %s\n" % \
                                             (err.filename, err.code, err.msg)
@@ -2253,16 +2255,16 @@
                                         if err.args[0][0] == 8:
                                                 ermsg += "    %s: %s\n" % \
                                                     (urlparse.urlsplit(
-                                                        auth["origin"])[1].split(":")[0],
+                                                        pub["origin"])[1].split(":")[0],
                                                     err.args[0][1])
                                         else:
                                                 if isinstance(err.args[0], \
                                                     socket.timeout):
                                                         ermsg += "    %s: %s\n" % \
-                                                            (auth["origin"], "timeout")
+                                                            (pub["origin"], "timeout")
                                                 else:
                                                         ermsg += "    %s: %s\n" % \
-                                                            (auth["origin"], \
+                                                            (pub["origin"], \
                                                             err.args[0][1])
                                 elif "data" in err.__dict__ and err.data:
                                         ermsg += err.data
@@ -2275,7 +2277,7 @@
                         self.__catalog_refresh_done()
                         return -1
 
-                except api_errors.UnrecognizedAuthorityException:
+                except api_errors.PublisherError:
                         self.__catalog_refresh_done()
                         raise
                 except Exception:
@@ -2285,20 +2287,20 @@
                         self.__catalog_refresh_done()
                 return 0
 
-        def __add_pkgs_to_lists_from_cache(self, authority, application_list, 
+        def __add_pkgs_to_lists_from_cache(self, publisher, application_list, 
             category_list, section_list):
                 if self.cache_o:
-                        self.cache_o.load_application_list(authority, application_list, 
+                        self.cache_o.load_application_list(publisher, application_list, 
                             self.selected_pkgs)
-                        self.cache_o.load_category_list(authority, category_list)
-                        self.cache_o.load_section_list(authority, section_list)
+                        self.cache_o.load_category_list(publisher, category_list)
+                        self.cache_o.load_section_list(publisher, section_list)
 
-        def __add_pkgs_to_lists_from_api(self, authority, application_list,
+        def __add_pkgs_to_lists_from_api(self, publisher, application_list,
             category_list, section_list):
                 """ This method set up image from the given directory and
                 returns the image object or None"""                
                 pargs = []
-                pargs.append("pkg://" + authority + "/*")
+                pargs.append("pkg://" + publisher + "/*")
                 try:
                         pkgs_known = misc.get_inventory_list(self.api_o.img, pargs, 
                             True, True)
@@ -2368,7 +2370,7 @@
                                     application_list,
                                     pkg_add, pkg_name,
                                     category_icon,
-                                    categories, category_list, authority)
+                                    categories, category_list, publisher)
                                 pkg_add += 1
                         prev_stem = pkg.get_pkg_stem()
                         prev_pfmri_str = pkg.get_short_fmri()
@@ -2396,8 +2398,8 @@
                                 else:
                                         status_icon = installed_icon
                         marked = False
-                        authority = self.__get_active_authority()
-                        pkgs = self.selected_pkgs.get(authority)
+                        publisher = self.__get_active_publisher()
+                        pkgs = self.selected_pkgs.get(publisher)
                         if pkgs != None:
                                 if pkg_stem in pkgs:
                                         marked = True
@@ -2409,11 +2411,11 @@
                         pkg_count += 1
 
                 self.__add_package_to_list(next_app, application_list, pkg_add, 
-                    pkg_name, category_icon, categories, category_list, authority)
+                    pkg_name, category_icon, categories, category_list, publisher)
                 pkg_add += 1
-                for authority in sections:
-                        for section in sections[authority]:
-                                for category in sections[authority][section].split(","):
+                for publisher in sections:
+                        for section in sections[publisher]:
+                                for category in sections[publisher][section].split(","):
                                         self.__add_category_to_section(_(category),
                                             _(section), category_list, section_list)
  
@@ -2428,11 +2430,11 @@
                 return
 
         def __add_package_to_list(self, app, application_list, pkg_add, 
-            pkg_name, category_icon, categories, category_list, authority):
+            pkg_name, category_icon, categories, category_list, publisher):
                 row_iter = application_list.insert(pkg_add, app)
-                cat_auth = categories.get(authority)
-                if pkg_name in cat_auth:
-                        pkg_categories = cat_auth.get(pkg_name)
+                cat_pub = categories.get(publisher)
+                if pkg_name in cat_pub:
+                        pkg_categories = cat_pub.get(pkg_name)
                         for pcat in pkg_categories.split(","):
                                 self.__add_package_to_category(_(pcat), None, 
                                     category_icon, row_iter, application_list, 
@@ -2474,7 +2476,8 @@
                         application_list.set(package,
                             enumerations.CATEGORY_LIST_COLUMN, category_list)
 
-        def __add_category_to_section(self, category_name, section_name, category_list, 
+        @staticmethod
+        def __add_category_to_section(category_name, section_name, category_list, 
             section_list):
                 '''Adds the section to section list in category. If there is no such 
                 section, than it is not added. If there was already section than it
@@ -2489,7 +2492,8 @@
                                             category_name:
                                                 section_lst = category[ \
                                                     enumerations.SECTION_LIST_OBJECT]
-                                                section[enumerations.SECTION_ENABLED] = True
+                                                section[enumerations.SECTION_ENABLED] = \
+                                                    True
                                                 if not section_lst:
                                                         category[ \
                                                     enumerations.SECTION_LIST_OBJECT] = \
@@ -2655,7 +2659,8 @@
                 self.image_directory = image_directory
                 if not self.api_o:
                         self.api_o = self.__get_api_object(image_directory, self.pr)
-                        self.cache_o = self.__get_cache_obj(self.application_dir, self.api_o)
+                        self.cache_o = self.__get_cache_obj(self.application_dir,
+                            self.api_o)
                 self.repositories_list = self.__get_new_repositories_liststore()
                 self.__setup_repositories_combobox(self.api_o, self.repositories_list)
 
@@ -2726,8 +2731,8 @@
                         count += 1
                         if count % 2 ==  0:
                                 time.sleep(0.001)
-                img.history.operation_name = "info"
-                img.history.operation_result = history.RESULT_SUCCEEDED
+                self.api_o.log_operation_start("info")
+                self.api_o.log_operation_end()
                 self.description_thread_running = False
                 
         def update_statusbar(self):
@@ -2754,9 +2759,11 @@
                 self.w_main_statusbar.push(0, status_str)
 
         def update_package_list(self, update_list):
+                if update_list == None:
+                        return
                 img = self.api_o.img
                 visible_repository = self.__get_visible_repository_name()
-                default_authority = self.default_authority
+                default_publisher = self.default_publisher
                 img.clear_pkg_state()
                 self.catalog_loaded = False
                 img.load_catalogs(self.pr)
@@ -2791,13 +2798,14 @@
                         self.__dump_datamodels(visible_repository, 
                                 self.application_list, self.category_list,
                                 self.section_list)
-                for authority in update_list:
-                        if authority != visible_repository:
-                                pkg_list = update_list.get(authority)
+                for publisher in update_list:
+                        if publisher != visible_repository:
+                                pkg_list = update_list.get(publisher)
                                 for pkg in pkg_list:
                                         pkg_stem = None
-                                        if authority != default_authority:
-                                                pkg_stem = "pkg://%s/%s" % (authority, pkg)
+                                        if publisher != default_publisher:
+                                                pkg_stem = "pkg://%s/%s" % \
+                                                        (publisher, pkg)
                                         else:
                                                 pkg_stem = "pkg:/%s" % pkg
                                         if pkg_stem:
@@ -2942,22 +2950,25 @@
 
 if __name__ == '__main__':
         debug = False
-        packagemanager = PackageManager()
         passed_test_arg = False
-        passed_imagedir_arg = False
+        update_all_proceed = False
+        ua_be_name = None
+        app_path = None
+        image_dir = None
+        info_install = False
 
         try:
-                opts, args = getopt.getopt(sys.argv[1:], "htR:U:", \
-                    ["help", "test-gui", "image-dir=", "update-all="])
+                opts, args = getopt.getopt(sys.argv[1:], "htR:U:i", \
+                    ["help", "test-gui", "image-dir=", "update-all=", "info-install"])
         except getopt.error, msg:
                 print "%s, for help use --help" % msg
                 sys.exit(2)
 
         if os.path.isabs(sys.argv[0]):
-                packagemanager.application_path = sys.argv[0]
+                app_path = sys.argv[0]
         else: 
                 cmd = os.path.join(os.getcwd(), sys.argv[0])
-                packagemanager.application_path = os.path.realpath(cmd)
+                app_path = os.path.realpath(cmd)
 
         for option, argument in opts:
                 if option in ("-h", "--help"):
@@ -2969,22 +2980,37 @@
                 if option in ("-t", "--test-gui"):
                         passed_test_arg = True
                 if option in ("-R", "--image-dir"):
-                        packagemanager.image_dir_arg = argument
                         image_dir = argument
-                        passed_imagedir_arg = True
                 if option in ("-U", "--update-all"):
-                        packagemanager.update_all_proceed = True
-                        packagemanager.ua_be_name = argument
+                        update_all_proceed = True
+                        ua_be_name = argument
+                if option in ("-i", "--info-install"):
+                        info_install = True
 
-        if passed_test_arg and passed_imagedir_arg:
+        if passed_test_arg and image_dir != None:
                 print "Options -R and -t can not be used together."
                 sys.exit(2)
-        if not passed_imagedir_arg:
+        if image_dir == None:
                 try:
                         image_dir = os.environ["PKG_IMAGE"]
                 except KeyError:
                         image_dir = os.getcwd()
 
+        
+        # Setup webinstall
+        if info_install or (len(sys.argv) == 2 and sys.argv[1].endswith(PKGINFO_SUFFIX)):
+                webinstall = webinstall.Webinstall(image_dir)
+                webinstall.process_param(sys.argv[1])
+                main() 
+                sys.exit(0)
+        
+        # Setup packagemanager
+        packagemanager = PackageManager()
+        packagemanager.application_path = app_path
+        packagemanager.image_dir_arg = image_dir
+        packagemanager.update_all_proceed = update_all_proceed
+        packagemanager.ua_be_name = ua_be_name
+        
         while gtk.events_pending():
                 gtk.main_iteration(False)
 
--- a/src/pkgdefs/SUNWipkg-gui/prototype	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/pkgdefs/SUNWipkg-gui/prototype	Tue Mar 10 00:01:30 2009 +0000
@@ -30,6 +30,8 @@
 f none usr/lib/python2.4/vendor-packages/pkg/gui/parseqs.pyc 444 root bin
 f none usr/lib/python2.4/vendor-packages/pkg/gui/repository.py 444 root bin
 f none usr/lib/python2.4/vendor-packages/pkg/gui/repository.pyc 444 root bin
+f none usr/lib/python2.4/vendor-packages/pkg/gui/webinstall.py 444 root bin
+f none usr/lib/python2.4/vendor-packages/pkg/gui/webinstall.pyc 444 root bin
 d none usr/share 755 root sys
 d none usr/share/applications 755 root other
 f none usr/share/applications/addmoresoftware.desktop 444 root other
@@ -47,12 +49,17 @@
 d none usr/share/icons/hicolor 755 root other
 d none usr/share/icons/hicolor/48x48 755 root other
 f none usr/share/icons/hicolor/48x48/apps/packagemanager.png 444 root other
+d none usr/share/icons/hicolor/48x48/mimetypes 755 root other
+f none usr/share/icons/hicolor/48x48/mimetypes/gnome-mime-application-vnd.pkg5.info.png 644 root other
 d none usr/share/icons/package-manager 755 root other
 f none usr/share/icons/package-manager/progress_blank.png 444 root other
 f none usr/share/icons/package-manager/progress_checkmark.png 444 root other
 f none usr/share/icons/package-manager/status_checkmark.png 444 root other
 f none usr/share/icons/package-manager/status_installed.png 444 root other
 f none usr/share/icons/package-manager/status_newupdate.png 444 root other
+d none usr/share/mime 755 root root
+d none usr/share/mime/packages 755 root root
+f none usr/share/mime/packages/packagemanager-info.xml 644 root bin
 d none usr/share/package-manager 755 root bin
 f none usr/share/package-manager/PM_app_48x.png 444 root bin
 f none usr/share/package-manager/PM_package_36x.png 444 root bin
--- a/src/tests/gui_pylintrc	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/tests/gui_pylintrc	Tue Mar 10 00:01:30 2009 +0000
@@ -117,7 +117,7 @@
 [DESIGN]
 
 # Maximum number of arguments for function / method
-max-args=10
+max-args=20
 
 # Maximum number of locals for function / method body
 max-locals=60
@@ -137,7 +137,7 @@
 # Maximum number of attributes for a class (see R0902).
 # Require large number of instance attributes as we are loading up handles to widget elements and only want to do this in init
 # for performance reasons
-max-attributes=100
+max-attributes=150
 
 # Minimum number of public methods for a class (see R0903).
 min-public-methods=0
--- a/src/updatemanager.py	Mon Mar 09 16:09:13 2009 -0500
+++ b/src/updatemanager.py	Tue Mar 10 00:01:30 2009 +0000
@@ -62,7 +62,7 @@
 
 IMAGE_DIRECTORY_DEFAULT = "/"   # Image default directory
 IMAGE_DIR_COMMAND = "svcprop -p update/image_dir svc:/application/pkg/update"
-CLIENT_API_VERSION = 10          # API version
+CLIENT_API_VERSION = 11          # API version
 PKG_CLIENT_NAME = "updatemanager" # API client name
 SELECTION_CHANGE_LIMIT = 0.5    # Time limit in seconds to cancel selection updates
 IND_DELAY = 0.05                # Time delay for printing index progress