--- a/.hgignore Fri Sep 02 13:50:59 2011 -0700
+++ b/.hgignore Mon Aug 29 14:13:13 2011 -0700
@@ -21,9 +21,6 @@
^doc/guide-main.tex
^doc/guide-main.toc
^doc/html-out
-^src/brand/fmri_compare$
-^src/brand/support$
-^src/extern/.*
^src/gui/data/addmoresoftware.desktop$
^src/gui/data/packagemanager-info.xml$
^src/gui/data/packagemanager-preferences.schemas$
--- a/src/Makefile Fri Sep 02 13:50:59 2011 -0700
+++ b/src/Makefile Mon Aug 29 14:13:13 2011 -0700
@@ -38,7 +38,7 @@
test-generate := TARGET = test-generate
test-leaks := TARGET = test-leaks
-SUBDIRS=web gui um po util/misc zoneproxy tsol
+SUBDIRS=zoneproxy tsol
all: $(SUBDIRS)
$(PYTHON) setup.py build
--- a/src/gui/Makefile Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,466 +0,0 @@
-#
-# 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 (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-MACH:sh = uname -p
-
-KSH=/usr/bin/ksh
-PYTHON = /usr/bin/python2.6
-INSTALL = /usr/sbin/install -s
-
-ROOT = ../../proto/root_${MACH}/usr
-ROOTETC = ../../proto/root_${MACH}/etc
-ROOTSHARE = $(ROOT)/share/package-manager
-ROOTUSRLIB = $(ROOT)/lib
-
-ROOTAPPICONSHARE = $(ROOT)/share/icons/hicolor/48x48/apps
-ROOTAPPHIGHICONSHARE = $(ROOT)/share/icons/HighContrast/48x48/apps
-ROOTAPPHIGHINVICONSHARE = $(ROOT)/share/icons/HighContrastInverse/48x48/apps
-ROOTDATASHARE = $(ROOTSHARE)/data
-ROOTDESKTOPSHARE = $(ROOT)/share/applications
-ROOTGCONFSHARE = $(ROOTETC)/gconf/schemas
-ROOTHELPSHARE = $(ROOT)/share/gnome/help/package-manager
-ROOTHIGHICON16SHARE = $(ROOTSHARE)/icons/HighContrast/16x16/actions
-ROOTHIGHICON24SHARE = $(ROOTSHARE)/icons/HighContrast/24x24/actions
-ROOTHIGHICON48SHARE = $(ROOTSHARE)/icons/HighContrast/48x48/actions
-ROOTHIGHINV = $(ROOTSHARE)/icons/HighContrastInverse
-ROOTHIGHINVICON16SHARE = $(ROOTSHARE)/icons/HighContrastInverse/16x16/actions
-ROOTHIGHINVICON24SHARE = $(ROOTSHARE)/icons/HighContrastInverse/24x24/actions
-ROOTHIGHINVICON48SHARE = $(ROOTSHARE)/icons/HighContrastInverse/48x48/actions
-ROOTHIGHPRINTINV = $(ROOTSHARE)/icons/HighContrastLargePrintInverse
-ROOTICON16SHARE = $(ROOTSHARE)/icons/hicolor/16x16/actions
-ROOTICON24SHARE = $(ROOTSHARE)/icons/hicolor/24x24/actions
-ROOTICON48SHARE = $(ROOTSHARE)/icons/hicolor/48x48/actions
-ROOTMIMEICONSHARE = $(ROOT)/share/icons/hicolor/48x48/mimetypes
-ROOTMIMETYPESHARE = $(ROOT)/share/mime/packages
-ROOTOMFSHARE = $(ROOT)/share/omf/package-manager
-ROOTPYTHON = $(ROOTUSRLIB)/python2.6
-ROOTPYTHONPKG = $(ROOTPYTHONVENDOR)/pkg/gui
-ROOTPYTHONVENDOR = $(ROOTPYTHON)/vendor-packages
-ROOTSPSHARE = $(ROOTSHARE)/data/startpagebase
-
-ROOTDIRS = \
- $(ROOTAPPICONSHARE) \
- $(ROOTAPPHIGHICONSHARE) \
- $(ROOTAPPHIGHINVICONSHARE) \
- $(ROOTDATASHARE) \
- $(ROOTDESKTOPSHARE) \
- $(ROOTGCONFSHARE) \
- $(ROOTHELPSHARE) \
- $(ROOTHIGHICON16SHARE) \
- $(ROOTHIGHICON24SHARE) \
- $(ROOTHIGHICON48SHARE) \
- $(ROOTHIGHINVICON16SHARE) \
- $(ROOTHIGHINVICON24SHARE) \
- $(ROOTHIGHINVICON48SHARE) \
- $(ROOTICON16SHARE) \
- $(ROOTICON24SHARE) \
- $(ROOTICON48SHARE) \
- $(ROOTMIMEICONSHARE) \
- $(ROOTMIMETYPESHARE) \
- $(ROOTPYTHONPKG) \
- $(ROOTOMFSHARE) \
- $(ROOTSHARE) \
- $(ROOTSPSHARE)
-
-APPICONS = \
- data/icons/48x48/packagemanager.png
-
-APPHIGHICONS = \
- data/icons/HighContrast/48x48/packagemanager.png
-
-APPHIGHINVICONS = \
- data/icons/HighContrastInverse/48x48/packagemanager.png
-
-DESKTOP = \
- data/packagemanager.desktop \
- data/addmoresoftware.desktop
-
-GCONF = \
- data/packagemanager-preferences.schemas
-
-MIMEICONS = \
- data/gnome-mime-application-vnd.pkg5.info.png
-
-MIMETYPE = \
- data/packagemanager-info.xml
-
-#
-# List of locales for which to build help. From this we build
-# the list of help file names.
-#
-C_ONLY_HELP_LOCALES = C
-HELP_LOCALES = C ar ca cs de es fr hu id it ja ko pl pt_BR ru sv zh_CN zh_HK zh_TW
-C_ONLY_SP_LOCALES = C
-SP_LOCALES = C ar ca cs de es fr hu id it ja ko nl pt_BR ru sv zh_CN zh_HK zh_TW
-
-
-#
-# package-manager.xml is constructed from package-manager.xml.in and
-# from help/<locale>/<locale.mo> (which is in turn built from
-# help/<locale>/<locale.po>). This list names all help files created
-# in the build process.
-#
-BUILDHELPFILES = \
- $(HELP_LOCALES:%=help/%/package-manager.xml) \
-
-HIGHICONS16 = \
- data/icons/HighContrast/16x16/filter_all.png \
- data/icons/HighContrast/16x16/filter_selected.png \
- data/icons/HighContrast/16x16/progress_checkmark.png \
- data/icons/HighContrast/16x16/selection.png \
- data/icons/HighContrast/16x16/status_checkmark.png \
- data/icons/HighContrast/16x16/status_installed.png \
- data/icons/HighContrast/16x16/status_newupdate.png \
- data/icons/HighContrast/16x16/status_notinstalled.png
-
-HIGHINVICONS16 = \
- data/icons/HighContrastInverse/16x16/filter_all.png \
- data/icons/HighContrastInverse/16x16/filter_selected.png \
- data/icons/HighContrastInverse/16x16/progress_checkmark.png \
- data/icons/HighContrastInverse/16x16/selection.png \
- data/icons/HighContrastInverse/16x16/status_checkmark.png \
- data/icons/HighContrastInverse/16x16/status_installed.png \
- data/icons/HighContrastInverse/16x16/status_newupdate.png \
- data/icons/HighContrastInverse/16x16/status_notinstalled.png
-
-HIGHICONS24 = \
- data/icons/HighContrast/24x24/pm-install_update.png \
- data/icons/HighContrast/24x24/pm-refresh.png \
- data/icons/HighContrast/24x24/pm-remove.png \
- data/icons/HighContrast/24x24/pm-update_all.png
-
-HIGHINVICONS24 = \
- data/icons/HighContrastInverse/24x24/pm-install_update.png \
- data/icons/HighContrastInverse/24x24/pm-refresh.png \
- data/icons/HighContrastInverse/24x24/pm-remove.png \
- data/icons/HighContrastInverse/24x24/pm-update_all.png
-
-HIGHICONS48 = \
- data/icons/HighContrast/48x48/packagemanager.png \
- data/icons/HighContrast/48x48/pm-install_update.png \
- data/icons/HighContrast/48x48/pm-refresh.png \
- data/icons/HighContrast/48x48/pm-remove.png \
- data/icons/HighContrast/48x48/pm-update_all.png
-
-HIGHINVICONS48 = \
- data/icons/HighContrastInverse/48x48/packagemanager.png \
- data/icons/HighContrastInverse/48x48/pm-install_update.png \
- data/icons/HighContrastInverse/48x48/pm-refresh.png \
- data/icons/HighContrastInverse/48x48/pm-remove.png \
- data/icons/HighContrastInverse/48x48/pm-update_all.png
-
-ICONS16 = \
- data/icons/16x16/filter_all.png \
- data/icons/16x16/filter_selected.png \
- data/icons/16x16/progress_blank.png \
- data/icons/16x16/progress_checkmark.png \
- data/icons/16x16/selection.png \
- data/icons/16x16/status_checkmark.png \
- data/icons/16x16/status_installed.png \
- data/icons/16x16/status_newupdate.png \
- data/icons/16x16/status_notinstalled.png
-
-ICONS24 = \
- data/icons/24x24/pm-check.png \
- data/icons/24x24/pm-install_update.png \
- data/icons/24x24/pm-refresh.png \
- data/icons/24x24/pm-remove.png \
- data/icons/24x24/pm-update_all.png
-
-ICONS48 = \
- data/icons/48x48/packagemanager.png \
- data/icons/48x48/pm-install_update.png \
- data/icons/48x48/pm-refresh.png \
- data/icons/48x48/pm-remove.png \
- data/icons/48x48/pm-update_all.png
-
-OMFFILES = \
- help/package-manager-ar.omf \
- help/package-manager-C.omf \
- help/package-manager-ca.omf \
- help/package-manager-cs.omf \
- help/package-manager-de.omf \
- help/package-manager-es.omf \
- help/package-manager-fr.omf \
- help/package-manager-hu.omf \
- help/package-manager-id.omf \
- help/package-manager-it.omf \
- help/package-manager-ja.omf \
- help/package-manager-ko.omf \
- help/package-manager-pl.omf \
- help/package-manager-pt_BR.omf \
- help/package-manager-ru.omf \
- help/package-manager-sv.omf \
- help/package-manager-zh_CN.omf \
- help/package-manager-zh_HK.omf \
- help/package-manager-zh_TW.omf
-
-PYMODS = \
- modules/__init__.py \
- modules/beadmin.py \
- modules/cache.py \
- modules/detailspanel.py \
- modules/entrystyle.py \
- modules/enumerations.py \
- modules/exportconfirm.py \
- modules/globalexceptionhandler.py \
- modules/imageinfo.py \
- modules/installupdate.py \
- modules/misc.py \
- modules/misc_non_gui.py \
- modules/parseqs.py \
- modules/pmgconf.py \
- modules/pmlogging.py \
- modules/preferences.py \
- modules/progress.py \
- modules/repository.py \
- modules/searcherror.py \
- modules/startpage.py \
- modules/uarenamebe.py \
- modules/versioninfo.py \
- modules/webinstall.py
-
-PYCMODS = $(PYMODS:%.py=%.pyc)
-
-STATICHELPFILES = \
- $(C_ONLY_HELP_LOCALES:%=help/%/figures/pkgmgr-main.png) \
- $(C_ONLY_HELP_LOCALES:%=help/%/figures/startpage_new.png) \
- $(C_ONLY_HELP_LOCALES:%=help/%/figures/update_all_new.png) \
- $(C_ONLY_HELP_LOCALES:%=help/%/figures/webinstall.png)
-
-STATICSPFILES = \
- $(SP_LOCALES:%=data/startpagebase/%/startpage.html) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/dialog-information.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/dialog-warning.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/hc_dialog-information.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/hc_dialog-warning.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/hc_install.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/hc_opensolaris.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/hci_dialog-information.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/hci_dialog-warning.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/hci_install.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/hci_opensolaris.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/install.png) \
- $(C_ONLY_SP_LOCALES:%=data/startpagebase/%/opensolaris.png) \
-
-#
-# Define the paths to all of the stuff we'll install.
-#
-ROOTAPPICONS = $(APPICONS:data/icons/48x48/%=$(ROOTAPPICONSHARE)/%)
-ROOTAPPHIGHICONS = $(APPHIGHICONS:data/icons/HighContrast/48x48/%=$(ROOTAPPHIGHICONSHARE)/%)
-ROOTAPPHIGHINVICONS = $(APPHIGHINVICONS:data/icons/HighContrastInverse/48x48/%=$(ROOTAPPHIGHINVICONSHARE)/%)
-
-ROOTDESKTOP = $(DESKTOP:data/%=$(ROOTDESKTOPSHARE)/%)
-
-ROOTGCONF = $(GCONF:data/%=$(ROOTGCONFSHARE)/%)
-
-ROOTHELPDIRS = \
- $(HELP_LOCALES:%=$(ROOTHELPSHARE)/%) \
- $(C_ONLY_HELP_LOCALES:%=$(ROOTHELPSHARE)/%/figures) \
-
-ROOTHELPFILES = \
- $(BUILDHELPFILES:help/%=$(ROOTHELPSHARE)/%) \
- $(STATICHELPFILES:help/%=$(ROOTHELPSHARE)/%)
-
-ROOTMIMEICONS = $(MIMEICONS:data/%=$(ROOTMIMEICONSHARE)/%)
-
-ROOTMIMETYPE = $(MIMETYPE:data/%=$(ROOTMIMETYPESHARE)/%)
-
-ROOTOMFFILES = $(OMFFILES:help/%=$(ROOTOMFSHARE)/%)
-
-ROOTSPDIRS = \
- $(SP_LOCALES:%=$(ROOTSPSHARE)/%)
-
-ROOTSPFILES = \
- $(STATICSPFILES:data/startpagebase/%=$(ROOTSPSHARE)/%)
-
-ROOTHIGHICONS16 = $(HIGHICONS16:data/icons/HighContrast/16x16/%=$(ROOTHIGHICON16SHARE)/%)
-ROOTHIGHICONS24 = $(HIGHICONS24:data/icons/HighContrast/24x24/%=$(ROOTHIGHICON24SHARE)/%)
-ROOTHIGHICONS48 = $(HIGHICONS48:data/icons/HighContrast/48x48/%=$(ROOTHIGHICON48SHARE)/%)
-
-ROOTHIGHINVICONS16 = $(HIGHINVICONS16:data/icons/HighContrastInverse/16x16/%=$(ROOTHIGHINVICON16SHARE)/%)
-ROOTHIGHINVICONS24 = $(HIGHINVICONS24:data/icons/HighContrastInverse/24x24/%=$(ROOTHIGHINVICON24SHARE)/%)
-ROOTHIGHINVICONS48 = $(HIGHINVICONS48:data/icons/HighContrastInverse/48x48/%=$(ROOTHIGHINVICON48SHARE)/%)
-
-ROOTICONS16 = $(ICONS16:data/icons/16x16/%=$(ROOTICON16SHARE)/%)
-ROOTICONS24 = $(ICONS24:data/icons/24x24/%=$(ROOTICON24SHARE)/%)
-ROOTICONS48 = $(ICONS48:data/icons/48x48/%=$(ROOTICON48SHARE)/%)
-
-ROOTPYGLADE = $(ROOTSHARE)/packagemanager.ui
-
-#
-# .py and .pyc files
-#
-ROOTPYMODS = $(PYMODS:modules/%=$(ROOTPYTHONPKG)/%)
-ROOTPYCALLMODS = $(ROOTPYMODS:%.py=%.pyc)
-
-ROOTCOMPONENTS = \
- $(ROOTAPPICONS) \
- $(ROOTAPPHIGHICONS) \
- $(ROOTAPPHIGHINVICONS) \
- $(ROOTDESKTOP) \
- $(ROOTGCONF) \
- $(ROOTHELPFILES) \
- $(ROOTHIGHICONS16) \
- $(ROOTHIGHICONS24) \
- $(ROOTHIGHICONS48) \
- $(ROOTHIGHINVICONS16) \
- $(ROOTHIGHINVICONS24) \
- $(ROOTHIGHINVICONS48) \
- $(ROOTHIGHPRINTINV) \
- $(ROOTICONS16) \
- $(ROOTICONS24) \
- $(ROOTICONS48) \
- $(ROOTMIMEICONS) \
- $(ROOTMIMETYPE) \
- $(ROOTPYGLADE) \
- $(ROOTPYMODS) \
- $(ROOTPYCALLMODS) \
- $(ROOTOMFFILES) \
- $(ROOTSPFILES)
-
-#
-# Triggered by all:'s dependency. Drives production of e.g.
-# data/packagemanager.desktop from data/packagemanager.desktop.in
-#
-data/%: data/%.in
- LC_ALL=C intltool-merge -d -u \
- -c ../po/.intltool-merge-cache ../po [email protected] $@
-
-all: $(DESKTOP) $(GCONF) $(PYCMODS) $(BUILDHELPFILES)
-
-install: all $(ROOTCOMPONENTS) $(ROOTDIRS)
-
-clean:
- rm -f $(PYCMODS) $(DESKTOP) $(GCONF)
- rm -f $(BUILDHELPFILES)
- rm -f ../po/.intltool-merge-cache
-
-clobber: clean
- rm -f $(ROOTCOMPONENTS)
-
-#
-# These rules drive the production of the .mo and package-manager.xml
-# files, which are built into help/<locale>/...
-#
-help/%/%.mo: help/%/%.po
- msgfmt -o $@ $<
-
-help/%/package-manager.xml: help/%/%.mo
- xml2po -t $< -o $@ [email protected]
-
-#
-# Build .pyc compile python files.
-#
-modules/%.pyc: modules/%.py
- python -m compileall -l $(@D)
-
-$(ROOTDIRS):
- $(INSTALL) -d -m 0755 $@
-
-$(ROOTAPPHIGHICONSHARE)/%: $(ROOTDIRS) data/icons/HighContrast/48x48/%
- $(INSTALL) -f $(ROOTAPPHIGHICONSHARE) -m 0644 $<
-
-$(ROOTAPPHIGHINVICONSHARE)/%: $(ROOTDIRS) data/icons/HighContrastInverse/48x48/%
- $(INSTALL) -f $(ROOTAPPHIGHINVICONSHARE) -m 0644 $<
-
-$(ROOTAPPICONSHARE)/%: $(ROOTDIRS) data/icons/48x48/%
- $(INSTALL) -f $(ROOTAPPICONSHARE) -m 0644 $<
-
-# Ordering of Rules important to have these executed first before more general rules
-# Breaking Alphabetical layout
-$(ROOTMIMETYPESHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTMIMETYPESHARE) -m 0644 $<
-
-# Ordering of Rules important to have these executed first before more general rules
-# Breaking Alphabetical layout
-$(ROOTMIMEICONSHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTMIMEICONSHARE) -m 0644 $<
-
-$(ROOTOMFSHARE)/%: $(ROOTDIRS) help/%
- $(INSTALL) -f $(ROOTOMFSHARE) -m 0644 $<
-
-$(ROOTSPDIRS): $(ROOTDIRS)
- $(INSTALL) -d -m 0755 $@
-
-$(ROOTSPSHARE)/%: $(ROOTSPDIRS) data/startpagebase/%
- $(INSTALL) -f $(@D) -m 0644 $<
-
-$(ROOTDATASHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTDATASHARE) -m 0644 $<
-
-$(ROOTDESKTOPSHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTDESKTOPSHARE) -m 0644 $<
-
-$(ROOTGCONFSHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTGCONFSHARE) -m 0644 $<
-
-#
-# These two are broad rules, but at present everything in help is just
-# copied from the help directory in a straightforward way.
-#
-$(ROOTHELPDIRS): $(ROOTDIRS)
- $(INSTALL) -d -m 0755 $@
-
-$(ROOTHELPSHARE)/%: $(ROOTHELPDIRS) help/%
- $(INSTALL) -f $(@D) -m 0644 $<
-
-$(ROOTHIGHICON16SHARE)/%: $(ROOTDIRS) data/icons/HighContrast/16x16/%
- $(INSTALL) -f $(ROOTHIGHICON16SHARE) -m 0644 $<
-
-$(ROOTHIGHICON24SHARE)/%: $(ROOTDIRS) data/icons/HighContrast/24x24/%
- $(INSTALL) -f $(ROOTHIGHICON24SHARE) -m 0644 $<
-
-$(ROOTHIGHICON48SHARE)/%: $(ROOTDIRS) data/icons/HighContrast/48x48/%
- $(INSTALL) -f $(ROOTHIGHICON48SHARE) -m 0644 $<
-
-$(ROOTHIGHINVICON16SHARE)/%: $(ROOTDIRS) data/icons/HighContrastInverse/16x16/%
- $(INSTALL) -f $(ROOTHIGHINVICON16SHARE) -m 0644 $<
-
-$(ROOTHIGHINVICON24SHARE)/%: $(ROOTDIRS) data/icons/HighContrastInverse/24x24/%
- $(INSTALL) -f $(ROOTHIGHINVICON24SHARE) -m 0644 $<
-
-$(ROOTHIGHINVICON48SHARE)/%: $(ROOTDIRS) data/icons/HighContrastInverse/48x48/%
- $(INSTALL) -f $(ROOTHIGHINVICON48SHARE) -m 0644 $<
-
-$(ROOTICON16SHARE)/%: $(ROOTDIRS) data/icons/16x16/%
- $(INSTALL) -f $(ROOTICON16SHARE) -m 0644 $<
-
-$(ROOTICON24SHARE)/%: $(ROOTDIRS) data/icons/24x24/%
- $(INSTALL) -f $(ROOTICON24SHARE) -m 0644 $<
-
-$(ROOTICON48SHARE)/%: $(ROOTDIRS) data/icons/48x48/%
- $(INSTALL) -f $(ROOTICON48SHARE) -m 0644 $<
-
-$(ROOTHIGHPRINTINV):
- rm -f $(ROOTHIGHPRINTINV)
- ln -s HighContrastInverse $(ROOTHIGHPRINTINV)
-
-$(ROOTPYTHONPKG)/%: $(ROOTDIRS) modules/%
- $(INSTALL) -f $(ROOTPYTHONPKG) -m 0644 $<
-
-$(ROOTSHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTSHARE) -m 0644 $<
-
--- a/src/gui/modules/__init__.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#!/usr/bin/python
-#
-# 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.
-#
-
-__all__ = ['installupdate', 'enumerations', \
- 'repository', 'imageinfo', 'beadmin', 'cache', \
- 'uarenamebe']
--- a/src/gui/modules/beadmin.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,632 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-import sys
-import os
-import pango
-import time
-import datetime
-import locale
-import pkg.pkgsubprocess as subprocess
-from threading import Thread
-
-try:
- import gobject
- gobject.threads_init()
- import gtk
- import pygtk
- pygtk.require("2.0")
-except ImportError:
- sys.exit(1)
-import pkg.gui.misc as gui_misc
-import pkg.client.api_errors as api_errors
-import pkg.client.bootenv as bootenv
-import pkg.misc
-
-#BE_LIST
-(
-BE_ID,
-BE_MARKED,
-BE_NAME,
-BE_ORIG_NAME,
-BE_DATE_TIME,
-BE_CURRENT_PIXBUF,
-BE_ACTIVE_DEFAULT,
-BE_SIZE,
-BE_EDITABLE
-) = range(9)
-
-class Beadmin:
- def __init__(self, parent):
- self.parent = parent
-
- if not bootenv.BootEnv.libbe_exists():
- msg = _("The <b>libbe</b> library was not "
- "found on your system."
- "\nAll functions for managing Boot Environments are disabled")
- msgbox = gtk.MessageDialog(
- buttons = gtk.BUTTONS_CLOSE,
- flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_INFO,
- message_format = None)
- msgbox.set_markup(msg)
- msgbox.set_title(_("BE management"))
- msgbox.run()
- msgbox.destroy()
- return
-
- self.be_list = \
- gtk.ListStore(
- gobject.TYPE_INT, # BE_ID
- gobject.TYPE_BOOLEAN, # BE_MARKED
- gobject.TYPE_STRING, # BE_NAME
- gobject.TYPE_STRING, # BE_ORIG_NAME
- gobject.TYPE_STRING, # BE_DATE_TIME
- gtk.gdk.Pixbuf, # BE_CURRENT_PIXBUF
- gobject.TYPE_BOOLEAN, # BE_ACTIVE_DEFAULT
- gobject.TYPE_STRING, # BE_SIZE
- gobject.TYPE_BOOLEAN, # BE_EDITABLE
- )
- self.progress_stop_thread = False
- self.initial_active = 0
- self.initial_default = 0
- gladefile = os.path.join(self.parent.application_dir,
- "usr/share/package-manager/packagemanager.ui")
- builder = gtk.Builder()
- builder.add_from_file(gladefile)
- self.w_beadmin_dialog = builder.get_object("beadmin")
- self.w_beadmin_dialog.set_icon(self.parent.window_icon)
- self.w_be_treeview = builder.get_object("betreeview")
- self.w_help_button = builder.get_object("help_bebutton")
- self.w_cancel_button = builder.get_object("cancelbebutton")
- self.w_ok_button = builder.get_object("okbebutton")
- w_active_gtkimage = builder.get_object("activebeimage")
- self.w_progress_dialog = builder.get_object("progressdialog")
- self.w_progress_dialog.connect('delete-event', lambda stub1, stub2: True)
- self.w_progress_dialog.set_icon(self.parent.window_icon)
- self.w_progressinfo_label = builder.get_object("progressinfo")
- progress_button = builder.get_object("progresscancel")
- self.w_progressbar = builder.get_object("progressbar")
- # Dialog reused in the repository.py
- self.w_beconfirmation_dialog = \
- builder.get_object("confirmationdialog")
- self.w_beconfirmation_dialog.set_icon(self.parent.window_icon)
- self.w_beconfirmation_textview = \
- builder.get_object("confirmtext")
- self.w_okbe_button = builder.get_object("ok_conf")
- self.w_cancelbe_button = builder.get_object("cancel_conf")
- self.w_ok_button.set_sensitive(False)
- progress_button.hide()
- self.w_progressbar.set_pulse_step(0.1)
- self.list_filter = self.be_list.filter_new()
- self.w_be_treeview.set_model(self.list_filter)
- self.__init_tree_views()
- self.active_image = gui_misc.get_icon(
- self.parent.icon_theme, "status_checkmark")
- w_active_gtkimage.set_from_pixbuf(self.active_image)
-
- bebuffer = self.w_beconfirmation_textview.get_buffer()
- bebuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
-
- self.__setup_signals()
- sel = self.w_be_treeview.get_selection()
- self.w_cancel_button.grab_focus()
- sel.set_mode(gtk.SELECTION_SINGLE)
- self.w_beconfirmation_dialog.set_title(
- _("Boot Environment Confirmation"))
- gui_misc.set_modal_and_transient(self.w_beadmin_dialog,
- self.parent.w_main_window)
- self.parent.child = self
- self.w_beadmin_dialog.show_all()
- self.w_progress_dialog.set_title(
- _("Loading Boot Environment Information"))
- self.w_progressinfo_label.set_text(
- _("Fetching BE entries..."))
- self.w_progress_dialog.show()
- Thread(target = self.__progress_pulse).start()
- Thread(target = self.__prepare_beadmin_list).start()
-
- def __setup_signals(self):
- signals_table = [
- (self.w_cancel_button, "clicked",
- self.__on_cancel_be_clicked),
- (self.w_ok_button, "clicked",
- self.__on_ok_be_clicked),
- (self.w_help_button, "clicked",
- self.__on_help_bebutton_clicked),
-
- (self.w_cancelbe_button, "clicked",
- self.__on_cancel_be_conf_clicked),
- (self.w_okbe_button, "clicked",
- self.__on_ok_be_conf_clicked),
- (self.w_beconfirmation_dialog, "delete_event",
- self.__on_beconfirmationdialog_delete_event),
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def cleanup(self):
- self.progress_stop_thread = True
- self.__on_beadmin_delete_event(None, None)
-
- def __progress_pulse(self):
- while not self.progress_stop_thread:
- gobject.idle_add(self.w_progressbar.pulse)
- time.sleep(0.1)
- gobject.idle_add(self.w_progress_dialog.hide)
-
- def __prepare_beadmin_list(self):
- be_list = bootenv.BootEnv.get_be_list()
- gobject.idle_add(self.__create_view_with_be, be_list)
- self.progress_stop_thread = True
- return
-
- def __init_tree_views(self):
- model = self.w_be_treeview.get_model()
-
- column = gtk.TreeViewColumn()
- column.set_title("")
- render_pixbuf = gtk.CellRendererPixbuf()
- column.pack_start(render_pixbuf, expand = True)
- column.add_attribute(render_pixbuf, "pixbuf", BE_CURRENT_PIXBUF)
- self.w_be_treeview.append_column(column)
-
- name_renderer = gtk.CellRendererText()
- name_renderer.connect('edited', self.__be_name_edited, model)
- column = gtk.TreeViewColumn(_("Boot Environment"),
- name_renderer, text = BE_NAME)
- column.set_cell_data_func(name_renderer, self.__cell_data_function, None)
- column.set_expand(True)
- if bootenv.BootEnv.check_verify():
- column.add_attribute(name_renderer, "editable",
- BE_EDITABLE)
- self.w_be_treeview.append_column(column)
-
- datetime_renderer = gtk.CellRendererText()
- datetime_renderer.set_property('xalign', 0.0)
- column = gtk.TreeViewColumn(_("Created"), datetime_renderer,
- text = BE_DATE_TIME)
- column.set_cell_data_func(datetime_renderer,
- self.__cell_data_function, None)
- column.set_expand(True)
- self.w_be_treeview.append_column(column)
-
- size_renderer = gtk.CellRendererText()
- size_renderer.set_property('xalign', 1.0)
- column = gtk.TreeViewColumn(_("Size"), size_renderer,
- text = BE_SIZE)
- column.set_cell_data_func(size_renderer, self.__cell_data_function, None)
- column.set_expand(False)
- self.w_be_treeview.append_column(column)
-
- radio_renderer = gtk.CellRendererToggle()
- radio_renderer.connect('toggled', self.__active_pane_default, model)
- column = gtk.TreeViewColumn(_("Active on Reboot"),
- radio_renderer, active = BE_ACTIVE_DEFAULT)
- radio_renderer.set_property("activatable", True)
- radio_renderer.set_property("radio", True)
- column.set_cell_data_func(radio_renderer,
- self.__cell_data_default_function, None)
- column.set_expand(False)
- self.w_be_treeview.append_column(column)
-
- toggle_renderer = gtk.CellRendererToggle()
- toggle_renderer.connect('toggled', self.__active_pane_toggle, model)
- column = gtk.TreeViewColumn(_("Delete"), toggle_renderer,
- active = BE_MARKED)
- toggle_renderer.set_property("activatable", True)
- column.set_cell_data_func(toggle_renderer,
- self.__cell_data_delete_function, None)
- column.set_expand(False)
- self.w_be_treeview.append_column(column)
-
- def __on_help_bebutton_clicked(self, widget):
- if self.parent != None:
- gui_misc.display_help("manage-be")
- else:
- gui_misc.display_help()
-
- def __on_ok_be_clicked(self, widget):
- self.w_progress_dialog.set_title(_("Applying changes"))
- self.w_progressinfo_label.set_text(
- _("Applying changes, please wait ..."))
- if self.w_ok_button.get_property('sensitive') == 0:
- self.progress_stop_thread = True
- self.__on_beadmin_delete_event(None, None)
- return
- Thread(target = self.__activate).start()
-
- def __on_cancel_be_clicked(self, widget):
- self.__on_beadmin_delete_event(None, None)
- return False
-
- def __on_beconfirmationdialog_delete_event(self, widget, event):
- self.__on_cancel_be_conf_clicked(widget)
- return True
-
- def __on_cancel_be_conf_clicked(self, widget):
- self.w_beconfirmation_dialog.hide()
-
- def __on_ok_be_conf_clicked(self, widget):
- self.w_beconfirmation_dialog.hide()
- self.progress_stop_thread = False
- Thread(target = self.__on_progressdialog_progress).start()
- Thread(target = self.__delete_activate_be).start()
-
- def __on_beadmin_delete_event(self, widget, event, stub=None):
- self.parent.child = None
- self.w_beadmin_dialog.destroy()
- return True
-
- def __activate(self):
- active_text = _("Active on reboot\n")
- delete_text = _("Delete\n")
- rename_text = _("Rename\n")
- active = ""
- delete = ""
- rename = {}
- for row in self.be_list:
-
- if row[BE_MARKED]:
- delete += "\t" + row[BE_NAME] + "\n"
- if row[BE_ACTIVE_DEFAULT] == True and row[BE_ID] != \
- self.initial_default:
- active += "\t" + row[BE_NAME] + "\n"
- if row[BE_NAME] != row[BE_ORIG_NAME]:
- rename[row[BE_ORIG_NAME]] = row[BE_NAME]
- textbuf = self.w_beconfirmation_textview.get_buffer()
- textbuf.set_text("")
- textiter = textbuf.get_end_iter()
- if len(active) > 0:
- textbuf.insert_with_tags_by_name(textiter,
- active_text, "bold")
- textbuf.insert_with_tags_by_name(textiter,
- active)
- if len(delete) > 0:
- if len(active) > 0:
- textbuf.insert_with_tags_by_name(textiter,
- "\n")
- textbuf.insert_with_tags_by_name(textiter,
- delete_text, "bold")
- textbuf.insert_with_tags_by_name(textiter,
- delete)
- if len(rename) > 0:
- if len(delete) > 0 or len(active) > 0:
- textbuf.insert_with_tags_by_name(textiter,
- "\n")
- textbuf.insert_with_tags_by_name(textiter,
- rename_text, "bold")
- for orig in rename:
- textbuf.insert_with_tags_by_name(textiter,
- "\t")
- textbuf.insert_with_tags_by_name(textiter,
- orig)
- textbuf.insert_with_tags_by_name(textiter,
- _(" to "), "bold")
- textbuf.insert_with_tags_by_name(textiter,
- rename.get(orig) + "\n")
- self.w_okbe_button.grab_focus()
- gobject.idle_add(self.w_beconfirmation_dialog.show)
- self.progress_stop_thread = True
-
- def __on_progressdialog_progress(self):
- # This needs to be run in gobject.idle_add, otherwise we will get
- # Xlib: unexpected async reply (sequence 0x2db0)!
- gobject.idle_add(self.w_progress_dialog.show)
- while not self.progress_stop_thread:
- gobject.idle_add(self.w_progressbar.pulse)
- time.sleep(0.1)
- gobject.idle_add(self.w_progress_dialog.hide)
-
- def __delete_activate_be(self):
- not_deleted = []
- not_default = None
- not_renamed = {}
- # The while gtk.events_pending():
- # gtk.main_iteration(False)
- # Is not working if we are calling libbe, so it is required
- # To have sleep in few places in this function
- # Remove
- for row in self.be_list:
- if row[BE_MARKED]:
- time.sleep(0.1)
- result = self.__destroy_be(row[BE_NAME])
- if result != 0:
- not_deleted.append(row[BE_NAME])
- # Rename
- for row in self.be_list:
- if row[BE_NAME] != row[BE_ORIG_NAME]:
- time.sleep(0.1)
- result = self.__rename_be(row[BE_ORIG_NAME],
- row[BE_NAME])
- if result != 0:
- not_renamed[row[BE_ORIG_NAME]] = row[BE_NAME]
- # Set active
- for row in self.be_list:
- if row[BE_ACTIVE_DEFAULT] == True and row[BE_ID] != \
- self.initial_default:
- time.sleep(0.1)
- result = self.__set_default_be(row[BE_NAME])
- if result != 0:
- not_default = row[BE_NAME]
- if len(not_deleted) == 0 and not_default == None \
- and len(not_renamed) == 0:
- self.progress_stop_thread = True
- else:
- self.progress_stop_thread = True
- msg = ""
- if not_default:
- msg += _("<b>Couldn't change Active "
- "Boot Environment to:</b>\n") + not_default
- if len(not_deleted) > 0:
- if not_default:
- msg += "\n\n"
- msg += _("<b>Couldn't delete Boot "
- "Environments:</b>\n")
- for row in not_deleted:
- msg += row + "\n"
- if len(not_renamed) > 0:
- if not_default or len(not_deleted):
- msg += "\n"
- msg += _("<b>Couldn't rename Boot "
- "Environments:</b>\n")
- for orig in not_renamed:
- msg += _("%s <b>to</b> %s\n") % (orig, \
- not_renamed.get(orig))
- gobject.idle_add(self.__error_occurred, msg)
- return
- gobject.idle_add(self.__on_cancel_be_clicked, None)
-
- @staticmethod
- def __rename_cell(model, itr, new_name):
- model.set_value(itr, BE_NAME, new_name)
-
- @staticmethod
- def __rename_be(orig_name, new_name):
- return bootenv.BootEnv.rename_be(orig_name, new_name)
-
- def __error_occurred(self, error_msg, reset=True):
- gui_misc.error_occurred(self.w_beadmin_dialog,
- error_msg,
- _("BE error"),
- gtk.MESSAGE_ERROR,
- True)
- if reset:
- self.__on_reset_be()
-
- def __on_reset_be(self):
- self.be_list.clear()
- self.w_progress_dialog.show()
- self.progress_stop_thread = False
- Thread(target = self.__progress_pulse).start()
- Thread(target = self.__prepare_beadmin_list).start()
- self.w_ok_button.set_sensitive(False)
-
- def __active_pane_toggle(self, cell, filtered_path, filtered_model):
- model = filtered_model.get_model()
- path = filtered_model.convert_path_to_child_path(filtered_path)
- itr = model.get_iter(path)
- if itr:
- modified = model.get_value(itr, BE_MARKED)
- # Do not allow to set active if selected for removal
- model.set_value(itr, BE_MARKED, not modified)
- # Do not allow to rename if we are removing be.
- model.set_value(itr, BE_EDITABLE, modified)
- self.__enable_disable_ok()
-
- def __enable_disable_ok(self):
- for row in self.be_list:
- if row[BE_MARKED] == True:
- self.w_ok_button.set_sensitive(True)
- return
- if row[BE_ID] == self.initial_default:
- if row[BE_ACTIVE_DEFAULT] == False:
- self.w_ok_button.set_sensitive(True)
- return
- if row[BE_NAME] != row[BE_ORIG_NAME]:
- self.w_ok_button.set_sensitive(True)
- return
- self.w_ok_button.set_sensitive(False)
- return
-
- def __be_name_edited(self, cell, filtered_path, new_name, filtered_model):
- model = filtered_model.get_model()
- path = filtered_model.convert_path_to_child_path(filtered_path)
- itr = model.get_iter(path)
- if itr:
- if model.get_value(itr, BE_NAME) == new_name:
- return
- if self.__verify_be_name(new_name) != 0:
- return
- self.__rename_cell(model, itr, new_name)
- self.__enable_disable_ok()
- return
-
- #TBD: Notify user if name clash using same logic as Repo Add and warning text
- def __verify_be_name(self, new_name):
- try:
- bootenv.BootEnv.check_be_name(new_name)
- except api_errors.DuplicateBEName:
- pass
- except api_errors.ApiException:
- return -1
- for row in self.be_list:
- if new_name == row[BE_NAME]:
- return -1
- return 0
-
- def __active_pane_default(self, cell, filtered_path, filtered_model):
- model = filtered_model.get_model()
- path = filtered_model.convert_path_to_child_path(filtered_path)
- for row in model:
- row[BE_ACTIVE_DEFAULT] = False
- itr = model.get_iter(path)
- if itr:
- modified = model.get_value(itr, BE_ACTIVE_DEFAULT)
- model.set_value(itr, BE_ACTIVE_DEFAULT, not modified)
- self.__enable_disable_ok()
-
- def __create_view_with_be(self, be_list):
- dates = None
- i = 0
- j = 0
- if len(be_list) == 0:
- msg = _("The <b>libbe</b> library couldn't "
- "prepare list of Boot Environments."
- "\nAll functions for managing Boot Environments are disabled")
- self.__error_occurred(msg, False)
- return
-
- for bee in be_list:
- item = bootenv.BootEnv.split_be_entry(bee)
- if item and item[0]:
- (name, active, active_boot, be_size, be_date) = item
- converted_size = \
- self.__convert_size_of_be_to_string(be_size)
- active_img = None
- if not be_date and j == 0:
- dates = self.__get_dates_of_creation(be_list)
- if dates:
- try:
- date_time = repr(dates[i])[1:-3]
- date_tmp = time.strptime(date_time, \
- "%a %b %d %H:%M %Y")
- date_tmp2 = \
- datetime.datetime(*date_tmp[0:5])
- try:
- date_format = \
- unicode(
- _("%m/%d/%y %H:%M"),
- "utf-8").encode(
- locale.getpreferredencoding())
- except (UnicodeError, LookupError,
- locale.Error):
- date_format = "%F %H:%M"
- date_time = \
- date_tmp2.strftime(date_format)
- i += 1
- except (NameError, ValueError, TypeError):
- date_time = None
- else:
- date_tmp = time.localtime(be_date)
- try:
- date_format = \
- unicode(
- _("%m/%d/%y %H:%M"),
- "utf-8").encode(
- locale.getpreferredencoding())
- except (UnicodeError, LookupError, locale.Error):
- date_format = "%F %H:%M"
- date_time = \
- time.strftime(date_format, date_tmp)
- if active:
- active_img = self.active_image
- self.initial_active = j
- if active_boot:
- self.initial_default = j
- if date_time != None:
- try:
- date_time = unicode(date_time,
- locale.getpreferredencoding()).encode(
- "utf-8")
- except (UnicodeError, LookupError, locale.Error):
- pass
- self.be_list.insert(j, [j, False,
- name, name,
- date_time, active_img,
- active_boot, converted_size, active_img == None])
- j += 1
- self.w_be_treeview.set_cursor(self.initial_active, None,
- start_editing=True)
- self.w_be_treeview.scroll_to_cell(self.initial_active)
-
- @staticmethod
- def __destroy_be(be_name):
- return bootenv.BootEnv.destroy_be(be_name)
-
- @staticmethod
- def __set_default_be(be_name):
- return bootenv.BootEnv.set_default_be(be_name)
-
- def __cell_data_default_function(self, column, renderer, model, itr, data):
- if itr:
- if model.get_value(itr, BE_MARKED):
- self.__set_renderer_active(renderer, False)
- else:
- self.__set_renderer_active(renderer, True)
-
- def __cell_data_delete_function(self, column, renderer, model, itr, data):
- if itr:
- if model.get_value(itr, BE_ACTIVE_DEFAULT) or \
- (self.initial_active == model.get_value(itr, BE_ID)) or \
- (model.get_value(itr, BE_NAME) !=
- model.get_value(itr, BE_ORIG_NAME)):
- self.__set_renderer_active(renderer, False)
- else:
- self.__set_renderer_active(renderer, True)
-
- @staticmethod
- def __set_renderer_active(renderer, active):
- if active:
- renderer.set_property("sensitive", True)
- renderer.set_property("mode", gtk.CELL_RENDERER_MODE_ACTIVATABLE)
- else:
- renderer.set_property("sensitive", False)
- renderer.set_property("mode", gtk.CELL_RENDERER_MODE_INERT)
-
- @staticmethod
- def __get_dates_of_creation(be_list):
- #zfs list -H -o creation rpool/ROOT/opensolaris-1
- cmd = [ "/sbin/zfs", "list", "-H", "-o","creation" ]
- for bee in be_list:
- if bee.get("orig_be_name"):
- name = bee.get("orig_be_name")
- pool = bee.get("orig_be_pool")
- cmd += [pool+"/ROOT/"+name]
- if len(cmd) <= 5:
- return None
- list_of_dates = []
- try:
- proc = subprocess.Popen(cmd, stdout = subprocess.PIPE,
- stderr = subprocess.PIPE,)
- line_out = proc.stdout.readline()
- while line_out:
- list_of_dates.append(line_out)
- line_out = proc.stdout.readline()
- except OSError:
- return list_of_dates
- return list_of_dates
-
- @staticmethod
- def __convert_size_of_be_to_string(be_size):
- if not be_size:
- be_size = 0
- return pkg.misc.bytes_to_str(be_size)
-
- @staticmethod
- def __cell_data_function(column, renderer, model, itr, data):
- if itr:
- if model.get_value(itr, BE_CURRENT_PIXBUF):
- renderer.set_property("weight", pango.WEIGHT_BOLD)
- else:
- renderer.set_property("weight", pango.WEIGHT_NORMAL)
--- a/src/gui/modules/cache.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-#!/usr/bin/python
-#
-# 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.
-#
-
-import os
-import sys
-try:
- import gtk
-except ImportError:
- sys.exit(1)
-from threading import Thread
-import pkg.gui.misc_non_gui as nongui_misc
-
-CACHE_VERSION = 11
-
-class CacheListStores:
- def __init__(self, api_o):
- self.api_o = api_o
-
- def __get_cache_dir(self):
- return nongui_misc.get_cache_dir(self.api_o)
-
- def get_index_timestamp(self):
- return self.api_o.last_modified
-
- def __dump_categories_expanded_dict(self, cat_exp_dict):
- #CED entry: {('opensolaris.org', (6,)): True}
- cache_dir = self.__get_cache_dir()
- if not cache_dir:
- return
- catexs = []
- for key, val in cat_exp_dict.iteritems():
- if not val:
- continue
- name, path = key
- path1 = -1
- if len(path) > 0:
- path1 = path[0]
- catex = {}
- catex["name"] = name
- catex["path1"] = path1
- catexs.append(catex)
-
- nongui_misc.dump_cache_file(
- os.path.join(cache_dir, "pm_cat_exp.cpl"),
- catexs)
-
- def __load_categories_expanded_dict(self, cat_exp_dict):
- cache_dir = self.__get_cache_dir()
- if not cache_dir:
- return
- catexs = nongui_misc.read_cache_file(
- os.path.join(cache_dir, "pm_cat_exp.cpl"))
- for catex in catexs:
- name = catex.get("name")
- path1 = catex.get("path1")
- if path1 != -1:
- cat_exp_dict[name, (path1,)] = True
-
- def dump_categories_expanded_dict(self, cat_exp_dict):
- Thread(target = self.__dump_categories_expanded_dict,
- args = (cat_exp_dict, )).start()
-
- def load_categories_expanded_dict(self, cat_exp_dict):
- Thread(target = self.__load_categories_expanded_dict,
- args = (cat_exp_dict, )).start()
-
- def __dump_categories_active_dict(self, cat_ac_dict):
- cache_dir = self.__get_cache_dir()
- if not cache_dir:
- return
- catacs = []
- for name, path in cat_ac_dict.iteritems():
- path1 = -1
- path2 = -1
- if len(path) == 1:
- path1 = path[0]
- elif len(path) > 1:
- path1 = path[0]
- path2 = path[1]
- catac = {}
- catac["name"] = name
- catac["path1"] = path1
- catac["path2"] = path2
- catacs.append(catac)
-
- nongui_misc.dump_cache_file(
- os.path.join(cache_dir, "pm_cat_ac.cpl"),
- catacs)
-
- def __load_categories_active_dict(self, cat_ac_dict):
- cache_dir = self.__get_cache_dir()
- if not cache_dir:
- return
- catacs = nongui_misc.read_cache_file(
- os.path.join(cache_dir, "pm_cat_ac.cpl"))
- for catac in catacs:
- name = catac.get("name")
- path1 = catac.get("path1")
- path2 = catac.get("path2")
- if path1 != -1 and path2 != -1:
- cat_ac_dict[name] = (path1, path2)
- elif path1 != -1:
- cat_ac_dict[name] = (path1,)
-
- def dump_categories_active_dict(self, cat_ac_dict):
- Thread(target = self.__dump_categories_active_dict,
- args = (cat_ac_dict, )).start()
-
- def load_categories_active_dict(self, cat_ac_dict):
- Thread(target = self.__load_categories_active_dict,
- args = (cat_ac_dict, )).start()
-
- def __dump_search_completion_info(self, completion_list):
- cache_dir = self.__get_cache_dir()
- if not cache_dir:
- return
- texts = []
- for text in completion_list:
- txt = {}
- txt["text"] = text[0]
- texts.append(txt)
- try:
- nongui_misc.dump_cache_file(
- os.path.join(cache_dir, ".__search__completion.cpl"), texts)
- except IOError:
- return
-
- def __load_search_completion_info(self, completion_list):
- cache_dir = self.__get_cache_dir()
- if not cache_dir:
- return
- texts = []
- try:
- texts = nongui_misc.read_cache_file(
- os.path.join(cache_dir, ".__search__completion.cpl"))
- except IOError:
- return gtk.ListStore(str)
-
- txt_count = 0
- for txt in texts:
- txt_val = txt.get("text")
- text = [ txt_val ]
- completion_list.insert(txt_count, text)
- txt_count += 1
-
- def dump_search_completion_info(self, completion_list):
- Thread(target = self.__dump_search_completion_info,
- args = (completion_list, )).start()
-
- def load_search_completion_info(self, completion_list):
- Thread(target = self.__load_search_completion_info,
- args = (completion_list, )).start()
--- a/src/gui/modules/detailspanel.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-import sys
-try:
- import gobject
- import gtk
- import pango
-except ImportError:
- sys.exit(1)
-import pkg.gui.misc as gui_misc
-import pkg.gui.enumerations as enumerations
-import pkg.version as version
-import pkg.client.api as api
-
-class DetailsPanel:
- def __init__(self, parent, builder):
- self.parent = parent
- self.w_generalinfo_textview = \
- builder.get_object("generalinfotextview")
- self.w_generalinfo_textview.get_buffer().create_tag(
- "bold", weight=pango.WEIGHT_BOLD)
- self.w_installedfiles_textview = \
- builder.get_object("installedfilestextview")
- self.w_installedfiles_textview.get_buffer().create_tag(
- "bold", weight=pango.WEIGHT_BOLD)
- self.w_license_textview = \
- builder.get_object("licensetextview")
- self.w_dependencies_textview = \
- builder.get_object("dependenciestextview")
- self.w_versions_name_label = \
- builder.get_object("versions_name_label")
- self.w_versions_label = \
- builder.get_object("versions_label")
- self.w_versions_combobox = \
- builder.get_object("versions_combo")
- self.w_versions_install_button = \
- builder.get_object("versions_install_button")
- self.w_installable_versions_hbox = \
- builder.get_object("installable_versions_hbox")
-
- self.w_dependencies_textview.get_buffer().create_tag(
- "bold", weight=pango.WEIGHT_BOLD)
- self.showing_empty_details = False
- self.versions_list = None
- self.__init_versions_tree_view()
-
- self.w_versions_install_button.connect("clicked",
- self.__on_versions_install_button_clicked)
-
- def __init_versions_tree_view(self):
- cell = gtk.CellRendererText()
- self.w_versions_combobox.pack_start(cell, True)
- self.w_versions_combobox.add_attribute(cell, 'text',
- enumerations.VERSION_DISPLAY_NAME)
-
- def __on_versions_install_button_clicked(self, widget):
- active = self.w_versions_combobox.get_active()
- active_version = self.versions_list[active][enumerations.VERSION_NAME]
- self.parent.install_version(active_version)
-
- def setup_text_signals(self, has_selection_cb, focus_in_cb,
- focus_out_cb):
- self.w_generalinfo_textview.get_buffer().connect(
- "notify::has-selection", has_selection_cb)
- self.w_installedfiles_textview.get_buffer().connect(
- "notify::has-selection", has_selection_cb)
- self.w_dependencies_textview.get_buffer().connect(
- "notify::has-selection", has_selection_cb)
- self.w_license_textview.get_buffer().connect(
- "notify::has-selection", has_selection_cb)
- self.w_generalinfo_textview.connect(
- "focus-in-event", focus_in_cb)
- self.w_installedfiles_textview.connect(
- "focus-in-event", focus_in_cb)
- self.w_dependencies_textview.connect(
- "focus-in-event", focus_in_cb)
- self.w_license_textview.connect(
- "focus-in-event", focus_in_cb)
- self.w_generalinfo_textview.connect(
- "focus-out-event", focus_out_cb)
- self.w_installedfiles_textview.connect(
- "focus-out-event", focus_out_cb)
- self.w_dependencies_textview.connect(
- "focus-out-event", focus_out_cb)
- self.w_license_textview.connect(
- "focus-out-event", focus_out_cb)
-
- def set_fetching_info(self):
- if self.parent.selected_pkg_name == None:
- return
- self.showing_empty_details = False
- self.__show_fetching_package_info()
-
- def __show_fetching_package_info(self):
- instbuffer = self.w_installedfiles_textview.get_buffer()
- infobuffer = self.w_generalinfo_textview.get_buffer()
- fetching_text = _("Fetching information...")
- instbuffer.set_text(fetching_text)
- infobuffer.set_text(fetching_text)
-
- def clear_details(self, info_pkgstem, dependencies_pkgstem, license_pkgstem,
- versions_pkgstem, selected_pkgstem):
- if not info_pkgstem and info_pkgstem != selected_pkgstem:
- self.w_generalinfo_textview.get_buffer().set_text("")
- self.w_installedfiles_textview.get_buffer().set_text("")
- if not dependencies_pkgstem and dependencies_pkgstem != selected_pkgstem:
- self.w_dependencies_textview.get_buffer().set_text("")
- if not license_pkgstem and license_pkgstem != selected_pkgstem:
- self.w_license_textview.get_buffer().set_text("")
- if not versions_pkgstem and versions_pkgstem != selected_pkgstem:
- self.versions_list = None
- self.w_versions_name_label.set_text("")
- self.w_versions_label.set_text("")
- self.w_versions_install_button.set_sensitive(False)
- self.__set_empty_versions_combo()
-
- def set_empty_details(self):
- self.showing_empty_details = True
- self.w_installedfiles_textview.get_buffer().set_text("")
- self.w_dependencies_textview.get_buffer().set_text("")
- self.w_generalinfo_textview.get_buffer().set_text("")
- self.w_license_textview.get_buffer().set_text("")
-
- self.versions_list = None
- self.w_versions_name_label.set_text("")
- self.w_versions_label.set_text("")
- self.w_versions_install_button.set_sensitive(False)
- self.__set_empty_versions_combo()
-
- def __set_empty_versions_combo(self, is_visible=False):
- empty_versions_list = self.__get_new_versions_liststore()
- empty_versions_list.append([0, _("Installable versions... "), "", 0])
- self.w_versions_combobox.set_model(empty_versions_list)
- self.w_versions_combobox.set_active(0)
- self.w_installable_versions_hbox.set_property('visible', is_visible)
-
- def set_fetching_dependencies(self):
- if self.parent.selected_pkg_name == None:
- return
- self.showing_empty_details = False
- dep_buffer = self.w_dependencies_textview.get_buffer()
- fetching_txt = _("Fetching dependencies information...")
- dep_buffer.set_text(fetching_txt)
-
- def set_fetching_license(self):
- if self.parent.selected_pkg_name == None:
- return
- self.showing_empty_details = False
- licbuffer = self.w_license_textview.get_buffer()
- leg_txt = _("Fetching legal information...")
- licbuffer.set_text(leg_txt)
-
- def set_fetching_versions(self):
- if self.parent.selected_pkg_name == None:
- return
- self.showing_empty_details = False
- self.w_versions_name_label.set_text(self.parent.selected_pkg_name)
- fetching_text = _("Fetching information...")
- self.w_versions_label.set_text(fetching_text)
- self.w_versions_install_button.set_sensitive(False)
- self.__set_empty_versions_combo(is_visible=True)
-
- def update_package_dependencies(self, info, dep_info, installed_dep_info,
- installed_icon, not_installed_icon):
- self.__set_dependencies_text(info, dep_info,
- installed_dep_info, installed_icon, not_installed_icon)
-
- def no_dependencies_available(self):
- depbuffer = self.w_dependencies_textview.get_buffer()
- network_str = \
- _("\nThis might be caused by network problem "
- "while accessing the repository.")
- depbuffer.set_text(_(
- "Dependencies info not available for this package...") +
- network_str)
-
- def update_package_info(self, pkg_name, local_info, remote_info,
- root, installed_icon, not_installed_icon, update_available_icon,
- is_all_publishers_installed, pubs_info, renamed_info=None,
- pkg_renamed = False):
- instbuffer = self.w_installedfiles_textview.get_buffer()
- infobuffer = self.w_generalinfo_textview.get_buffer()
-
- if not local_info and not remote_info:
- network_str = \
- _("\nThis might be caused by network problem "
- "while accessing the repository.")
- instbuffer.set_text( \
- _("Files Details not available for this package...") +
- network_str)
- infobuffer.set_text(
- _("Information not available for this package...") +
- network_str)
- return
-
- gui_misc.set_package_details(pkg_name, local_info,
- remote_info, self.w_generalinfo_textview,
- installed_icon, not_installed_icon,
- update_available_icon,
- is_all_publishers_installed, pubs_info, renamed_info, pkg_renamed)
- if not local_info:
- # Package is not installed
- local_info = remote_info
-
- if not remote_info:
- remote_info = local_info
-
- inst_str = ""
- if local_info.dirs:
- for x in local_info.dirs:
- inst_str += ''.join("%s%s\n" % (
- root, x))
- if local_info.files:
- for x in local_info.files:
- inst_str += ''.join("%s%s\n" % (
- root, x))
- if local_info.hardlinks:
- for x in local_info.hardlinks:
- inst_str += ''.join("%s%s\n" % (
- root, x))
- if local_info.links:
- for x in local_info.links:
- inst_str += ''.join("%s%s\n" % (
- root, x))
- self.__set_installedfiles_text(inst_str)
-
- def __set_installedfiles_text(self, text):
- instbuffer = self.w_installedfiles_textview.get_buffer()
- instbuffer.set_text("")
- itr = instbuffer.get_start_iter()
- instbuffer.insert(itr, text)
-
- def __set_dependencies_text(self, info, dep_info, installed_dep_info,
- installed_icon, not_installed_icon):
- gui_misc.set_dependencies_text(self.w_dependencies_textview,
- info, dep_info, installed_dep_info, installed_icon,
- not_installed_icon)
-
- def update_package_license(self, licenses):
- if self.showing_empty_details:
- return
- licbuffer = self.w_license_textview.get_buffer()
- licbuffer.set_text(gui_misc.setup_package_license(licenses))
-
- def update_package_versions(self, versions):
- if self.showing_empty_details:
- return
-
- self.versions_list = self.__get_new_versions_liststore()
- i = 0
- previous_display_version = None
- self.w_versions_label.set_text(_("Not Installed"))
- for (version_str, states) in versions:
- state = gui_misc.get_state_from_states(states)
-
- version_tuple = version.Version.split(version_str)
- version_fmt = gui_misc.get_version_fmt_string()
- display_version = version_fmt % \
- {"version": version_tuple[0][0],
- "build": version_tuple[0][1],
- "branch": version_tuple[0][2]}
- if api.PackageInfo.INSTALLED in states:
- self.w_versions_label.set_text(display_version)
- break
- if (previous_display_version and
- previous_display_version == display_version):
- continue
- previous_display_version = display_version
- self.versions_list.append([i, display_version,
- version_str, state])
- i += 1
- if i > 0:
- self.w_versions_install_button.set_sensitive(True)
- else:
- self.versions_list.clear()
- self.versions_list.append([0, _("No versions available"), "", 0])
- self.w_versions_install_button.set_sensitive(False)
- self.w_versions_combobox.set_model(self.versions_list)
- self.w_versions_combobox.set_active(0)
-
- @staticmethod
- def __get_new_versions_liststore():
- return gtk.ListStore(
- gobject.TYPE_INT, # enumerations.VERSION_ID
- gobject.TYPE_STRING, # enumerations.VERSION_DISPLAY_NAME
- gobject.TYPE_STRING, # enumerations.VERSION_NAME
- gobject.TYPE_INT, # enumerations.VERSION_STATUS
- )
--- a/src/gui/modules/entrystyle.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-#!/usr/bin/python
-#
-# 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 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-import sys
-try:
- import gtk
-except ImportError:
- sys.exit(1)
-import pkg.gui.enumerations as enumerations
-
-SEARCH_TXT_GREY_STYLE = "#757575" #Close to DimGrey
-SEARCH_TXT_BLACK_STYLE = "#000000"
-
-class EntryStyle:
- def __init__(self, entry):
- self.search_txt_fg_style = gtk.gdk.color_parse(SEARCH_TXT_BLACK_STYLE)
- self.entry = entry
- self.entry_embedded_icons_supported = True
- try:
- self.entry.set_property("secondary-icon-stock", None)
- except TypeError:
- self.entry_embedded_icons_supported = False
- self.search_text_style = -1
- self.set_search_text_mode(enumerations.SEARCH_STYLE_PROMPT)
-
- def set_theme_colour(self, page_fg):
- self.search_txt_fg_style = page_fg
- if self.get_text() != None:
- self.set_search_text_mode(enumerations.SEARCH_STYLE_NORMAL)
- else:
- self.set_entry_to_prompt()
-
- def set_search_text_mode(self, style):
- if style == enumerations.SEARCH_STYLE_NORMAL:
- self.entry.modify_text(gtk.STATE_NORMAL, self.search_txt_fg_style)
- if self.search_text_style == enumerations.SEARCH_STYLE_PROMPT or\
- self.entry.get_text() == _("Search (Ctrl-F)"):
- self.entry.set_text("")
- self.search_text_style = enumerations.SEARCH_STYLE_NORMAL
-
- else:
- self.entry.modify_text(gtk.STATE_NORMAL,
- gtk.gdk.color_parse(SEARCH_TXT_GREY_STYLE))
- self.search_text_style = enumerations.SEARCH_STYLE_PROMPT
- self.entry.set_text(_("Search (Ctrl-F)"))
-
- def on_entry_changed(self, widget):
- if widget.get_text_length() > 0 and \
- self.search_text_style != enumerations.SEARCH_STYLE_PROMPT:
- if self.entry_embedded_icons_supported:
- self.entry.set_property("secondary-icon-stock",
- gtk.STOCK_CANCEL)
- self.entry.set_property(
- "secondary-icon-sensitive", True)
- return True
- else:
- if self.entry_embedded_icons_supported:
- self.entry.set_property("secondary-icon-stock",
- None)
- return False
-
- def set_entry_to_prompt(self):
- if self.search_text_style != enumerations.SEARCH_STYLE_PROMPT:
- self.set_search_text_mode(enumerations.SEARCH_STYLE_PROMPT)
-
- def get_text(self):
- if self.search_text_style == enumerations.SEARCH_STYLE_PROMPT or \
- self.entry.get_text_length() == 0:
- return None
-
- txt = self.entry.get_text()
- if len(txt.strip()) == 0:
- self.entry.set_text("")
- return None
- return txt
-
--- a/src/gui/modules/enumerations.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-"""
-This module consists of user readable enumerations for the data models
-used in the IPS GUI
-"""
-
-#Application List
-(
-MARK_COLUMN,
-STATUS_ICON_COLUMN,
-NAME_COLUMN,
-DESCRIPTION_COLUMN,
-STATUS_COLUMN,
-STEM_COLUMN,
-ACTUAL_NAME_COLUMN,
-IS_VISIBLE_COLUMN, # True indicates that the package is visible in ui
-CATEGORY_LIST_COLUMN, # list of categories to which package belongs
-PUBLISHER_COLUMN, # Publisher for this package
-PUBLISHER_PREFIX_COLUMN, # Publisher prefix for this package
-RENAMED_COLUMN, # True indicates this package has been
-) = range(12)
-
-#Categories
-(
-CATEGORY_ID,
-CATEGORY_NAME,
-CATEGORY_VISIBLE_NAME,
-CATEGORY_DESCRIPTION,
-SECTION_LIST_OBJECT, #List with the sections to which category belongs
-CATEGORY_IS_VISIBLE,
-) = range(6)
-
-#Sections
-(
-SECTION_ID,
-SECTION_NAME,
-SECTION_ENABLED,
-) = range(3)
-
-#Filter
-(
-FILTER_ID,
-FILTER_ICON,
-FILTER_NAME,
-) = range(3)
-
-#Filter
-(
-FILTER_ALL,
-FILTER_INSTALLED,
-FILTER_UPDATES,
-FILTER_NOT_INSTALLED,
-FILTER_SEPARATOR,
-FILTER_SELECTED,
-) = range(6)
-
-#Search
-(
-SEARCH_ID,
-SEARCH_ICON,
-SEARCH_NAME,
-) = range(3)
-
-#Repositories switch
-(
-REPOSITORY_ID,
-REPOSITORY_DISPLAY_NAME,
-REPOSITORY_PREFIX,
-REPOSITORY_ALIAS,
-) = range(4)
-
-(
-INSTALL_UPDATE,
-REMOVE,
-IMAGE_UPDATE,
-UPDATE_FACETS
-) = range(4)
-
-# Info Cache entries
-(
-INFO_GENERAL_LABELS,
-INFO_GENERAL_TEXT,
-INFO_INSTALLED_TEXT,
-INFO_DEPEND_INFO,
-INFO_DEPEND_DEPEND_INFO,
-INFO_DEPEND_DEPEND_INSTALLED_INFO
-) = range(6)
-
-# Install/Update/Remove confirmation
-(
-CONFIRM_NAME,
-CONFIRM_PUB,
-CONFIRM_DESC,
-CONFIRM_STATUS,
-CONFIRM_STEM
-) = range(5)
-
-#Repository action
-(
-ADD_PUBLISHER,
-MANAGE_PUBLISHERS
-) = range(2)
-
-# Publisher List in Manage Publishers Dialog
-(
-PUBLISHER_PRIORITY,
-PUBLISHER_PRIORITY_CHANGED,
-PUBLISHER_NAME,
-PUBLISHER_ALIAS,
-PUBLISHER_ENABLED,
-PUBLISHER_STICKY,
-PUBLISHER_OBJECT,
-PUBLISHER_ENABLE_CHANGED,
-PUBLISHER_STICKY_CHANGED,
-PUBLISHER_REMOVED,
-) = range(10)
-
-# Publisher Priority
-(
-PUBLISHER_MOVE_BEFORE,
-PUBLISHER_MOVE_AFTER,
-) = range(2)
-
-# Return values from /usr/lib/pm-checkforupdates
-(
-UPDATES_AVAILABLE,
-NO_UPDATES_AVAILABLE,
-UPDATES_UNDETERMINED
-) = range(3)
-
-# Search Text Style
-(
-SEARCH_STYLE_NORMAL,
-SEARCH_STYLE_PROMPT
-) = range(2)
-
-# Versions
-(
-VERSION_ID,
-VERSION_DISPLAY_NAME,
-VERSION_NAME,
-VERSION_STATUS
-) = range(4)
-
-# Locale List in Preferences Dialog - Language Tab
-(
-LOCALE_NAME, # <language> (territory)
-LOCALE_LANGUAGE, # Display <language> name
-LOCALE_TERRITORY, # Display <territory> name
-LOCALE, # <language>_<territory>(<codeset>)
-LOCALE_SELECTED, # selected
-) = range(5)
-
-# Publisher Certificate List in Modify Publisher Dialog - Certificates Tab
-(
-PUBCERT_ORGANIZATION, # O
-PUBCERT_NAME, # CN
-PUBCERT_STATUS, # Approved or Revoked
-PUBCERT_IPSHASH, # IPS Cert hash
-PUBCERT_PATH, # Path to Cert when added or reinstated
-PUBCERT_XCERT_OBJ, # X509 certificate object
-PUBCERT_NEW, # True if Cert just added, but not yet commited
-) = range(7)
--- a/src/gui/modules/exportconfirm.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-#!/usr/bin/python
-#
-# 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 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-import sys
-import os
-import stat
-import tempfile
-import re
-try:
- import gtk
- import pango
-except ImportError:
- sys.exit(1)
-import pkg.client.api_errors as api_errors
-import pkg.fmri as fmri
-import pkg.gui.misc as gui_misc
-
-class ExportConfirm:
- def __init__(self, builder, window_icon, gconf, parent):
- self.gconf = gconf
- self.parent = parent
- self.parent_window = None
- self.window_icon = window_icon
- self.w_exportconfirm_dialog = \
- builder.get_object("confirmationdialog")
- self.w_exportconfirm_dialog.set_icon(window_icon)
- self.w_confirmok_button = builder.get_object("ok_conf")
- self.w_confirmcancel_button = builder.get_object("cancel_conf")
- self.w_confirmhelp_button = builder.get_object("help_conf")
- self.w_confirm_textview = builder.get_object("confirmtext")
- self.w_confirm_label = builder.get_object("confirm_label")
- w_confirm_image = builder.get_object("confirm_image")
- w_confirm_image.set_from_stock(gtk.STOCK_DIALOG_INFO,
- gtk.ICON_SIZE_DND)
- self.__setup_export_selection_dialog()
- self.selected_pkgs = None
- self.chooser_dialog = None
-
- def set_window_icon(self, window_icon):
- self.window_icon = window_icon
- self.w_exportconfirm_dialog.set_icon(window_icon)
- if self.chooser_dialog:
- self.chooser_dialog.set_icon(window_icon)
-
- def __setup_export_selection_dialog(self):
- infobuffer = self.w_confirm_textview.get_buffer()
- infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
- self.w_exportconfirm_dialog.set_title(_("Export Selections Confirmation"))
- self.w_confirm_label.set_markup(
- _("<b>Export the following to a Web Install .p5i file:</b>"))
- self.w_confirmhelp_button.set_property('visible', True)
-
- def setup_signals(self):
- signals_table = [
- (self.w_exportconfirm_dialog, "delete_event",
- self.__on_confirmation_dialog_delete_event),
- (self.w_confirmhelp_button, "clicked",
- self.__on_confirm_help_button_clicked),
- (self.w_confirmok_button, "clicked",
- self.__on_confirm_proceed_button_clicked),
- (self.w_confirmcancel_button, "clicked",
- self.__on_confirm_cancel_button_clicked),
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def set_modal_and_transient(self, parent_window):
- self.parent_window = parent_window
- gui_misc.set_modal_and_transient(self.w_exportconfirm_dialog,
- parent_window)
-
- def __on_confirmation_dialog_delete_event(self, widget, event):
- self.__on_confirm_cancel_button_clicked(None)
- return True
-
- @staticmethod
- def __on_confirm_help_button_clicked(widget):
- gui_misc.display_help("webinstall-export")
-
- def __on_confirm_cancel_button_clicked(self, widget):
- self.w_exportconfirm_dialog.hide()
-
- def __on_confirm_proceed_button_clicked(self, widget):
- self.w_exportconfirm_dialog.hide()
- self.__export_selections()
-
- def activate(self, selected_pkgs):
- self.selected_pkgs = selected_pkgs
- if self.selected_pkgs == None or len(self.selected_pkgs) == 0:
- return
-
- infobuffer = self.w_confirm_textview.get_buffer()
- infobuffer.set_text("")
- textiter = infobuffer.get_end_iter()
-
- for pub_name, pkgs in self.selected_pkgs.items():
- name = self.parent.get_publisher_name_from_prefix(pub_name)
- if name == pub_name:
- infobuffer.insert_with_tags_by_name(textiter,
- "%s\n" % pub_name, "bold")
- else:
- infobuffer.insert_with_tags_by_name(textiter,
- "%s" % name, "bold")
- infobuffer.insert(textiter, " (%s)\n" % pub_name)
- for pkg in pkgs.keys():
- infobuffer.insert(textiter,
- "\t%s\n" % fmri.extract_pkg_name(pkg))
- self.w_confirmok_button.grab_focus()
- self.w_exportconfirm_dialog.show()
-
- def __export_selections(self):
- filename = self.__get_export_p5i_filename(
- self.gconf.last_export_selection_path)
- if not filename:
- return
- self.gconf.last_export_selection_path = filename
- try:
- fobj = open(filename, 'w')
- api_o = self.parent.get_api_object()
- api_o.write_p5i(fobj, pkg_names=self.selected_pkgs,
- pubs=self.selected_pkgs.keys())
- except IOError, ex:
- err = str(ex)
- self.parent.error_occurred(err, _("Export Selections Error"))
- return
- except api_errors.ApiException, ex:
- fobj.close()
- err = str(ex)
- self.parent.error_occurred(err, _("Export Selections Error"))
- return
- fobj.close()
- os.chmod(filename, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP |
- stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH )
-
- def __get_export_p5i_filename(self, last_export_selection_path):
- filename = None
- chooser = gtk.FileChooserDialog(_("Export Selections"),
- self.parent_window,
- gtk.FILE_CHOOSER_ACTION_SAVE,
- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_SAVE, gtk.RESPONSE_OK))
- chooser.set_icon(self.window_icon)
- self.chooser_dialog = chooser
-
- file_filter = gtk.FileFilter()
- file_filter.set_name(_("p5i Files"))
- file_filter.add_pattern("*.p5i")
- chooser.add_filter(file_filter)
- file_filter = gtk.FileFilter()
- file_filter.set_name(_("All Files"))
- file_filter.add_pattern("*")
- chooser.add_filter(file_filter)
-
- path = tempfile.gettempdir()
- name = _("my_packages")
- if last_export_selection_path and last_export_selection_path != "":
- path, name_plus_ext = os.path.split(last_export_selection_path)
- result = os.path.splitext(name_plus_ext)
- name = result[0]
-
- #Check name
- base_name = None
- m = re.match("(.*)(-\d+)$", name)
- if m == None and os.path.exists(path + os.sep + name + '.p5i'):
- base_name = name
- if m and len(m.groups()) == 2:
- base_name = m.group(1)
- name = name + '.p5i'
- if base_name:
- for i in range(1, 99):
- full_path = path + os.sep + base_name + '-' + \
- str(i) + '.p5i'
- if not os.path.exists(full_path):
- name = base_name + '-' + str(i) + '.p5i'
- break
- chooser.set_current_folder(path)
- chooser.set_current_name(name)
- chooser.set_do_overwrite_confirmation(True)
-
- response = chooser.run()
- if response == gtk.RESPONSE_OK:
- filename = chooser.get_filename()
- self.chooser_dialog = None
- chooser.destroy()
-
- return filename
--- a/src/gui/modules/globalexceptionhandler.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-import sys
-import threading
-import traceback
-from cStringIO import StringIO
-
-try:
- import gobject
- import gtk
- import pango
-except ImportError:
- sys.exit(1)
-import pkg.misc as misc
-import pkg.gui.misc as gui_misc
-
-class GlobalExceptionHandler:
- def __init__(self):
- self.parent = None
- sys.excepthook = self.global_exception_handler
- self.installThreadExcepthook()
-
- def set_parent(self, parent):
- self.parent = parent
-
- def global_exception_handler(self, exctyp, value, tb):
- if self.parent:
- if self.parent.child:
- self.parent.child.cleanup()
- trace = StringIO()
- traceback.print_exception (exctyp, value, tb, None, trace)
- if exctyp is MemoryError:
- gobject.idle_add(self.__display_memory_err)
- else:
- gobject.idle_add(self.__display_unknown_err_ex, trace)
-
- def installThreadExcepthook(self):
- """
- Workaround for sys.excepthook python thread bug from:
- Bug: sys.excepthook doesn't work in threads
- http://bugs.python.org/issue1230540#msg91244
- """
- init_old = threading.Thread.__init__
- def init(self, *ite_args, **ite_kwargs):
- init_old(self, *ite_args, **ite_kwargs)
- run_old = self.run
- def run_with_except_hook(*rweh_args, **rweh_kwargs):
- try:
- run_old(*rweh_args, **rweh_kwargs)
- except (KeyboardInterrupt, SystemExit):
- raise
- except:
- if not sys:
- raise
- sys.excepthook(*sys.exc_info())
- self.run = run_with_except_hook
- threading.Thread.__init__ = init
-
- def __display_memory_err(self):
- try:
- dmsg = misc.out_of_memory()
- msg_stripped = dmsg.replace("\n", " ")
- gui_misc.error_occurred(None, msg_stripped, _("Package Manager"),
- gtk.MESSAGE_ERROR)
- except MemoryError:
- print dmsg
- except Exception:
- pass
- if self.parent:
- self.parent.unhandled_exception_shutdown()
- else:
- sys.exit()
-
- def __display_unknown_err_ex(self, trace):
- try:
- self.__display_unknown_err(trace)
- except MemoryError:
- print trace
- except Exception:
- pass
- if self.parent:
- self.parent.unhandled_exception_shutdown()
- else:
- sys.exit()
-
- def __display_unknown_err(self, trace):
- dmsg = _("An unknown error occurred")
- md = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, message_format=dmsg)
- close_btn = md.add_button(gtk.STOCK_CLOSE, 100)
- md.set_default_response(100)
-
- dmsg = _("Please let the developers know about this problem by "
- "filing a bug together with the error details listed below at:")
- md.format_secondary_text(dmsg)
- md.set_title(_('Unexpected Error'))
-
- uri_btn = gtk.LinkButton(misc.BUG_URI_GUI,
- "defect.opensolaris.org")
- uri_btn.set_relief(gtk.RELIEF_NONE)
- uri_btn.set_size_request(160, -1)
- align = gtk.Alignment(0, 0, 0, 0)
- align.set_padding(0, 0, 56, 0)
- align.add(uri_btn)
-
- textview = gtk.TextView()
- textview.show()
- textview.set_editable(False)
- textview.set_wrap_mode(gtk.WRAP_WORD)
-
- sw = gtk.ScrolledWindow()
- sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- sw.add(textview)
- fr = gtk.Frame()
- fr.set_shadow_type(gtk.SHADOW_IN)
- fr.add(sw)
- ca = md.get_content_area()
- ca.pack_start(align, False, False, 0)
- ca.pack_start(fr)
-
- textbuffer = textview.get_buffer()
- textbuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
- textbuffer.create_tag("level1", left_margin=30, right_margin=10)
- textiter = textbuffer.get_end_iter()
- textbuffer.insert_with_tags_by_name(textiter,
- _("Error details:\n"), "bold")
- textbuffer.insert_with_tags_by_name(textiter, trace.getvalue(), "level1")
- publisher_str = ""
- if self.parent:
- publisher_str = \
- gui_misc.get_publishers_for_output(
- self.parent.get_api_object())
- if publisher_str != "":
- textbuffer.insert_with_tags_by_name(textiter,
- _("\nList of configured publishers:"), "bold")
- textbuffer.insert_with_tags_by_name(
- textiter, publisher_str + "\n", "level1")
-
- if publisher_str == "":
- textbuffer.insert_with_tags_by_name(textiter,
- _("\nPlease include output from:\n"), "bold")
- textbuffer.insert(textiter, "$ pkg publisher\n")
-
- ver = gui_misc.get_version()
- textbuffer.insert_with_tags_by_name(textiter,
- _("\npkg version:\n"), "bold")
- textbuffer.insert_with_tags_by_name(textiter, ver + "\n", "level1")
- md.set_size_request(550, 400)
- md.set_resizable(True)
- close_btn.grab_focus()
- md.show_all()
- md.run()
- md.destroy()
--- a/src/gui/modules/imageinfo.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-#!/usr/bin/python
-#
-# 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 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-import ConfigParser
-import re
-import sys
-import os
-from ConfigParser import ParsingError
-
-class ImageInfo(object):
- """An ImagineInfo object is a collection of information
- about the packages for the Imagine GUI"""
-
- def __init__(self):
- self.categories = {}
-
- def read(self, path):
- """This method reads specified by path file and returns lists of
- categories per package"""
- cpars = self.__get_config_parser(path)
- if cpars:
- for section in cpars.sections():
- self.categories[section] = cpars.get(section, "category")
- return self.categories
-
- def get_pixbuf_image_for_package(self, path, package_name):
- """Method that returns pixbuf field from the file specified by path for
- the given package_name"""
- cpars = self.__get_config_parser(path)
- if cpars:
- for section in cpars.sections():
- if re.match(package_name, section):
- pixbuf = cpars.get(section, "pixbuf")
- return pixbuf
- return None
-
- def add_package(self, path, name, category):
- """Add the package information to the file specified by the path. If the
- package name already exists, than returns False"""
- cpars = self.__get_config_parser(path)
- if cpars:
- for section in cpars.sections():
- if re.match(name, section):
- #This should behave differently, if the repo
- #exists should throw some error
- return False
- cpars.add_section(name)
- cpars.set(name, "category", category)
- file_op = open(path, "w")
- cpars.write(file_op)
- return True
- return False
-
- def remove_package(self, path, name):
- """If exists removes package specified by name from the
- filename specified by path"""
- cpars = self.__get_config_parser(path)
- if cpars:
- for section in cpars.sections():
- if re.match(name, section):
- cpars.remove_section(name)
- file_op = open(path, "w")
- cpars.write(file_op)
-
- @staticmethod
- def __get_config_parser(path):
- """Creates and returns ConfigParser.SafeConfigParser()"""
- cpars = ConfigParser.SafeConfigParser()
- if cpars:
- read_cp = cpars.read(path)
- if read_cp:
- if read_cp[0] != path:
- raise ParsingError
- return cpars
-
- @staticmethod
- def __mkdirs_files(path):
- if not os.path.isdir(os.path.dirname(path)):
- os.makedirs(os.path.dirname(path))
- if not os.path.isfile(path):
- file_op = open(path, "w")
- file_op.close()
-
-if __name__ == "__main__":
- print "Usage:"
- print "./imageinfo.py FILE..."
- sys.exit(0)
--- a/src/gui/modules/installupdate.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1647 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-DEFAULT_CONFIRMATION_WIDTH = 550 # Width & height of single confirmation
-DEFAULT_CONFIRMATION_HEIGHT = 200 # frame. The confirmation dialog may
- # consist of frames for packages to be
- # installed, removed or updated.
-DISPLAY_DELAY = 200 # Delay before updating GUI when
- # displaying download or phase info
-RESET_PACKAGE_DELAY = 2000 # Delay before label text is reset
- # Also used to reset window text during install
-DIALOG_DEFAULT_WIDTH = 450 # Default Width of Progress Dialog
-DIALOG_EXPANDED_DETAILS_HEIGHT = 462 # Height of Progress Dialog when Details expanded
-DIALOG_INSTALL_COLLAPSED_HEIGHT = 242 # Heights of progress dialog when Details
- # collapsed for install, remove and done stages
-DIALOG_REMOVE_COLLAPSED_HEIGHT = 220
-DIALOG_DONE_COLLAPSED_HEIGHT = 126
-
-DIALOG_UM_EXTRA_HEIGHT = 60 # Extra height needed when in UM mode
-DIALOG_RELEASE_NOTE_OFFSET = 34 # Additional space required if displaying
- # Release notes link below Details
-import errno
-import os
-import sys
-import time
-import pango
-import datetime
-import traceback
-from gettext import ngettext
-from threading import Thread
-from threading import Condition
-try:
- import gobject
- import gtk
- import pygtk
- pygtk.require("2.0")
-except ImportError:
- sys.exit(1)
-
-import pkg.gui.progress as progress
-import pkg.misc as misc
-import pkg.client.api as api
-import pkg.client.api_errors as api_errors
-import pkg.gui.beadmin as beadm
-import pkg.gui.uarenamebe as uarenamebe
-import pkg.gui.misc as gui_misc
-import pkg.gui.enumerations as enumerations
-import pkg.gui.pmgconf as pmgconf
-from pkg.client import global_settings
-
-logger = global_settings.logger
-debug = False
-
-class InstallUpdate(progress.GuiProgressTracker):
- def __init__(self, list_of_packages, parent, image_directory,
- action = -1, parent_name = "", pkg_list = None, main_window = None,
- icon_confirm_dialog = None, title = None, web_install = False,
- confirmation_list = None, show_confirmation = False, api_lock = None,
- gconf = None, facets = None):
- if action == -1:
- return
- self.gconf = gconf
- progress.GuiProgressTracker.__init__(self, indent=True)
- if self.gconf == None:
- self.gconf = pmgconf.PMGConf()
- self.retry = False
- self.web_install = web_install
- self.web_updates_list = None
- self.web_install_all_installed = False
- self.parent = parent
- self.api_lock = api_lock
- self.facets = facets
- self.api_o = gui_misc.get_api_object(image_directory,
- self, main_window)
- if self.api_o == None:
- return
- self.parent_name = parent_name
- self.confirmation_list = confirmation_list
- if confirmation_list == None:
- self.confirmation_list = []
- self.show_confirmation = show_confirmation
- if main_window == None:
- self.top_level = True
- else:
- self.top_level = False
- self.ipkg_ipkgui_list = pkg_list
- self.icon_confirm_dialog = icon_confirm_dialog
- self.title = title
- self.w_main_window = main_window
- if self.icon_confirm_dialog == None and self.w_main_window != None:
- self.icon_confirm_dialog = self.w_main_window.get_icon()
-
- gladefile = os.path.join(self.parent.application_dir,
- "usr/share/package-manager/packagemanager.ui")
- builder = gtk.Builder()
- builder.add_from_file(gladefile)
- self.w_dialog = builder.get_object("createplandialog")
- self.original_title = None
- if self.w_main_window:
- self.original_title = self.w_main_window.get_title()
- if self.top_level:
- globals()["DIALOG_INSTALL_COLLAPSED_HEIGHT"] = \
- DIALOG_INSTALL_COLLAPSED_HEIGHT + DIALOG_UM_EXTRA_HEIGHT
- globals()["DIALOG_DONE_COLLAPSED_HEIGHT"] = \
- DIALOG_DONE_COLLAPSED_HEIGHT + DIALOG_UM_EXTRA_HEIGHT
- self.w_dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL)
- self.w_dialog.set_icon(self.icon_confirm_dialog)
- self.w_main_window = self.w_dialog
- self.original_title = _("Update Manager")
- w_icon_um = builder.get_object("icon_um")
- w_icon_um.set_from_pixbuf(self.icon_confirm_dialog)
- else:
- um_vbox = builder.get_object("um_title_vbox")
- um_vbox.set_property("visible", False)
-
- self.license_cv = Condition()
- self.list_of_packages = list_of_packages
- self.accept_license_done = False
- self.action = action
- self.canceling = False
- self.current_stage_name = None
- self.ip = None
- self.ips_update = False
- self.operations_done = False
- self.operations_done_ex = False
- self.prev_ind_phase = None
- self.reboot_needed = False
- self.uarenamebe_o = None
- self.label_text = None
- self.prev_pkg = None
- self.prev_prog = -1
- self.prog = 0
- self.progress_stop_timer_running = False
- self.pylint_stub = None
- self.reset_id = 0
- self.reset_window_id = 0
- self.display_download_id = 0
- self.update_progress_id = 0
- self.stages = {
- 1:[_("Preparing..."), _("Preparation")],
- 2:[_("Downloading..."), _("Download")],
- 3:[_("Installing..."), _("Install")],
- }
- self.current_stage_label_done = self.stages[1][1]
- self.stop_progress_bouncing = False
- self.stopped_bouncing_progress = True
- self.update_list = {}
-
- self.w_confirm_dialog = builder.get_object("confirmdialog")
- self.w_install_expander = \
- builder.get_object("install_expander")
- self.w_install_frame = \
- builder.get_object("install_frame")
- self.w_install_treeview = \
- builder.get_object("install_treeview")
- self.w_update_expander = \
- builder.get_object("update_expander")
- self.w_update_frame = \
- builder.get_object("update_frame")
- self.w_update_treeview = \
- builder.get_object("update_treeview")
- self.w_remove_expander = \
- builder.get_object("remove_expander")
- self.w_remove_frame = \
- builder.get_object("frame3")
- self.w_remove_treeview = \
- builder.get_object("remove_treeview")
- self.w_confirm_ok_button = \
- builder.get_object("confirm_ok_button")
- self.w_confirm_cancel_button = \
- builder.get_object("confirm_cancel_button")
- self.w_confirm_label = \
- builder.get_object("confirmdialog_confirm_label")
- self.w_confirm_donotshow = \
- builder.get_object("confirm_donotshow")
-
- self.w_confirm_dialog.set_icon(self.icon_confirm_dialog)
- gui_misc.set_modal_and_transient(self.w_confirm_dialog,
- self.w_main_window)
-
- self.w_expander = builder.get_object("details_expander")
- self.w_cancel_button = builder.get_object("cancelcreateplan")
- self.w_help_button = builder.get_object("helpcreateplan")
- if self.top_level:
- self.w_help_button.set_property("visible", True)
- else:
- self.w_help_button.set_property("visible", False)
-
- self.w_close_button = builder.get_object("closecreateplan")
- self.w_release_notes = builder.get_object("release_notes")
- self.w_release_notes_link = \
- builder.get_object("ua_release_notes_button")
- self.w_progressbar = builder.get_object("createplanprogress")
- self.w_details_textview = builder.get_object("createplantextview")
-
- self.w_stage2 = builder.get_object("stage2")
- self.w_stages_box = builder.get_object("stages_box")
- self.w_stage1_label = builder.get_object("label_stage1")
- self.w_stage1_icon = builder.get_object("icon_stage1")
- self.w_stage2_label = builder.get_object("label_stage2")
- self.w_stage2_icon = builder.get_object("icon_stage2")
- self.w_stage3_label = builder.get_object("label_stage3")
- self.w_stage3_icon = builder.get_object("icon_stage3")
- self.w_stages_label = builder.get_object("label_stages")
- self.w_stages_icon = builder.get_object("icon_stages")
- self.current_stage_label = self.w_stage1_label
- self.current_stage_icon = self.w_stage1_icon
-
- self.w_stages_label.set_line_wrap(True)
- self.w_stages_label.set_size_request(DIALOG_DEFAULT_WIDTH - 20, -1)
-
- self.done_icon = gui_misc.get_icon(
- self.parent.icon_theme, "progress_checkmark")
- blank_icon = gui_misc.get_icon(
- self.parent.icon_theme, "progress_blank")
-
- checkmark_icon = gui_misc.get_icon(
- self.parent.icon_theme, "pm-check", 24)
-
- self.w_stages_icon.set_from_pixbuf(checkmark_icon)
-
- self.w_stage1_icon.set_from_pixbuf(blank_icon)
- self.w_stage2_icon.set_from_pixbuf(blank_icon)
- self.w_stage3_icon.set_from_pixbuf(blank_icon)
-
- proceed_txt = _("_Proceed")
- gui_misc.change_stockbutton_label(self.w_confirm_ok_button, proceed_txt)
-
- infobuffer = self.w_details_textview.get_buffer()
- infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
- infobuffer.create_tag("level1", left_margin=30, right_margin=10)
- infobuffer.create_tag("level2", left_margin=50, right_margin=10)
-
- self.w_progressbar.set_pulse_step(0.02)
- self.w_release_notes.hide()
-
- self.w_license_dialog = builder.get_object("license_dialog")
- self.w_license_label = builder.get_object("instruction_label")
- self.w_license_text = builder.get_object("textview1")
- self.w_license_accept_checkbutton = \
- builder.get_object("license_accept_checkbutton")
- self.w_license_accept_button = \
- builder.get_object("license_accept_button")
- self.w_license_reject_button = \
- builder.get_object("license_reject_button")
- self.accept_text = gui_misc.get_stockbutton_label_label(
- self.w_license_accept_button)
- gui_misc.change_stockbutton_label(self.w_license_reject_button,
- _("_Reject"))
- self.current_license_no = 0
- self.packages_with_license = None
- self.packages_with_license_result = []
- self.n_licenses = 0
- self.dlg_expanded_details_h = DIALOG_EXPANDED_DETAILS_HEIGHT
- self.dlg_width = DIALOG_DEFAULT_WIDTH
- self.dlg_install_collapsed_h = DIALOG_INSTALL_COLLAPSED_HEIGHT
- self.dlg_remove_collapsed_h = DIALOG_REMOVE_COLLAPSED_HEIGHT
- self.dlg_done_collapsed_h = DIALOG_DONE_COLLAPSED_HEIGHT
-
- self.__setup_signals()
- if not self.top_level:
- gui_misc.set_modal_and_transient(self.w_dialog,
- self.w_main_window)
- self.w_license_dialog.set_icon(self.icon_confirm_dialog)
- gui_misc.set_modal_and_transient(self.w_license_dialog,
- self.w_dialog)
- self.__start_action()
- self.__setup_createplan_dlg_sizes()
-
- def __setup_signals(self):
- signals_table = [
- (self.w_cancel_button, "clicked",
- self.__on_cancelcreateplan_clicked),
- (self.w_close_button, "clicked",
- self.__on_closecreateplan_clicked),
- (self.w_dialog, "delete_event",
- self.__on_createplandialog_delete),
- (self.w_expander, "activate",
- self.__on_details_expander_activate),
- (self.w_help_button, "clicked",
- self.__on_help_button_clicked),
-
- (self.w_license_reject_button, "clicked",
- self.__on_license_reject_button_clicked),
- (self.w_license_accept_button, "clicked",
- self.__on_license_accept_button_clicked),
- (self.w_license_accept_checkbutton, "toggled",
- self.__on_license_accept_checkbutton_toggled),
- (self.w_license_dialog, "delete_event",
- self.__on_license_dialog_delete),
-
- (self.w_confirm_dialog, "delete_event",
- self.__on_confirmdialog_delete_event),
- (self.w_confirm_donotshow, "toggled",
- self.__on_confirm_donotshow_toggled),
- (self.w_confirm_cancel_button, "clicked",
- self.__on_confirm_cancel_button_clicked),
- (self.w_confirm_ok_button, "clicked",
- self.__on_confirm_ok_button_clicked),
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def __setup_createplan_dlg_sizes(self):
- #Get effective screen space available (net of panels and docks)
- #instead of using gtk.gdk.screen_width() and gtk.gdk.screen_height()
- root_win = gtk.gdk.get_default_root_window()
- net_workarea_prop = gtk.gdk.atom_intern('_NET_WORKAREA')
- sw, sh = root_win.property_get(net_workarea_prop)[2][2:4]
- sw -= 28 # Default width of Panel accounts for bottom or side System Panel
- sh -= 28
- scale = gui_misc.get_scale(self.w_details_textview)
-
- if DIALOG_EXPANDED_DETAILS_HEIGHT * scale <= sh:
- self.dlg_expanded_details_h = \
- (int) (DIALOG_EXPANDED_DETAILS_HEIGHT * scale)
- self.dlg_install_collapsed_h = \
- (int) (DIALOG_INSTALL_COLLAPSED_HEIGHT * scale)
- self.dlg_remove_collapsed_h = \
- (int) (DIALOG_REMOVE_COLLAPSED_HEIGHT * scale)
- self.dlg_done_collapsed_h = \
- (int) (DIALOG_DONE_COLLAPSED_HEIGHT * scale)
- else:
- self.dlg_expanded_details_h = sh
- if DIALOG_INSTALL_COLLAPSED_HEIGHT * scale <= sh:
- self.dlg_install_collapsed_h = \
- (int) (DIALOG_INSTALL_COLLAPSED_HEIGHT * scale)
- self.dlg_remove_collapsed_h = \
- (int) (DIALOG_REMOVE_COLLAPSED_HEIGHT * scale)
- self.dlg_done_collapsed_h = \
- (int) (DIALOG_DONE_COLLAPSED_HEIGHT * scale)
- else:
- self.dlg_install_collapsed_h = sh
- if DIALOG_REMOVE_COLLAPSED_HEIGHT * scale <= sh:
- self.dlg_remove_collapsed_h = (int) \
- (DIALOG_REMOVE_COLLAPSED_HEIGHT * scale)
- self.dlg_done_collapsed_h = (int) \
- (DIALOG_DONE_COLLAPSED_HEIGHT * scale)
- else:
- self.dlg_remove_collapsed_h = sh
- if DIALOG_DONE_COLLAPSED_HEIGHT * scale <= sh:
- self.dlg_done_collapsed_h = (int) \
- (DIALOG_DONE_COLLAPSED_HEIGHT * \
- scale)
- else:
- self.dlg_done_collapsed_h = sh
-
- if DIALOG_DEFAULT_WIDTH * scale <= sw:
- self.dlg_width = \
- (int) (DIALOG_DEFAULT_WIDTH * scale)
- else:
- self.dlg_width = sw
-
- if debug:
- print "CreatePlan Dialog Sizes: window", sw, sh, scale, " dlg ", \
- self.dlg_width, self.dlg_expanded_details_h, " coll ", \
- self.dlg_install_collapsed_h, \
- self.dlg_remove_collapsed_h, self.dlg_done_collapsed_h
-
- if self.gconf.details_expanded:
- self.__set_dialog_size(self.dlg_width,
- self.dlg_expanded_details_h)
- else:
- if not (self.w_stage2.flags() & gtk.VISIBLE):
- self.__set_dialog_size(self.dlg_width,
- self.dlg_remove_collapsed_h)
- else:
- self.__set_dialog_size(self.dlg_width,
- self.dlg_install_collapsed_h)
-
- def __start_action(self):
- if self.action == enumerations.REMOVE:
- # For the remove, we are not showing the download stage
- self.stages[3] = [_("Removing..."), _("Remove")]
- self.w_stage3_label.set_text(self.stages[3][1])
- self.w_stage2.hide()
- self.w_dialog.set_title(_("Remove"))
-
- if self.show_confirmation and len(self.confirmation_list) > 0:
- self.w_confirm_dialog.set_title(_("Remove Confirmation"))
- pkgs_no = len(self.confirmation_list)
- remove_text = ngettext(
- "Review the package to be removed",
- "Review the packages to be removed", pkgs_no)
- self.w_confirm_label.set_markup("<b>"+remove_text+"</b>")
-
- self.w_install_expander.hide()
- self.w_update_expander.hide()
- if not self.retry:
- self.__init_confirmation_tree_view(
- self.w_remove_treeview)
- liststore = gtk.ListStore(str, str, str)
- for sel_pkg in self.confirmation_list:
- liststore.append(
- [sel_pkg[enumerations.CONFIRM_NAME],
- sel_pkg[enumerations.CONFIRM_PUB],
- sel_pkg[enumerations.CONFIRM_DESC]])
- liststore.set_default_sort_func(lambda *args: -1)
- liststore.set_sort_column_id(0, gtk.SORT_ASCENDING)
- self.w_remove_treeview.set_model(liststore)
- self.w_remove_expander.set_expanded(True)
- self.w_confirm_ok_button.grab_focus()
- self.w_confirm_dialog.show()
- else:
- self.__proceed_with_stages()
- elif self.action == enumerations.IMAGE_UPDATE:
- if not self.top_level:
- self.w_dialog.set_title(_("Updates"))
- self.__proceed_with_stages()
- elif self.action == enumerations.UPDATE_FACETS:
- if not self.top_level:
- self.w_dialog.set_title(
- _("Update Optional Components"))
- self.__proceed_with_stages()
- else:
- if self.title != None:
- self.w_dialog.set_title(self.title)
- else:
- self.w_dialog.set_title(_("Install/Update"))
-
- if self.show_confirmation and len(self.confirmation_list) > 0:
- self.w_remove_expander.hide()
- to_install = gtk.ListStore(str, str, str)
- to_update = gtk.ListStore(str, str, str)
- for cpk in self.confirmation_list:
- if cpk[enumerations.CONFIRM_STATUS] == \
- api.PackageInfo.UPGRADABLE:
- to_update.append(
- [cpk[enumerations.CONFIRM_NAME],
- cpk[enumerations.CONFIRM_PUB],
- cpk[enumerations.CONFIRM_DESC]])
- else:
- to_install.append(
- [cpk[enumerations.CONFIRM_NAME],
- cpk[enumerations.CONFIRM_PUB],
- cpk[enumerations.CONFIRM_DESC]])
-
- operation_txt = _("Install/Update Confirmation")
- install_text = ngettext(
- "Review the package to be Installed/Updated",
- "Review the packages to be Installed/Updated",
- len(self.confirmation_list))
-
- if len(to_install) == 0:
- operation_txt = _("Updates Confirmation")
- install_text = ngettext(
- "Review the package to be Updated",
- "Review the packages to be Updated",
- len(to_update))
-
- if len(to_update) == 0:
- operation_txt = _("Install Confirmation")
- install_text = ngettext(
- "Review the package to be Installed",
- "Review the packages to be Installed",
- len(to_install))
-
- self.w_confirm_dialog.set_title(operation_txt)
- self.w_confirm_label.set_markup("<b>"+install_text+"</b>")
-
- if len(to_install) > 0:
- self.__init_confirmation_tree_view(
- self.w_install_treeview)
- to_install.set_default_sort_func(lambda *args: -1)
- to_install.set_sort_column_id(0,
- gtk.SORT_ASCENDING)
- self.w_install_treeview.set_model(to_install)
- self.w_install_expander.set_expanded(True)
- else:
- self.w_install_expander.hide()
- if len(to_update) > 0:
- self.__init_confirmation_tree_view(
- self.w_update_treeview)
- to_update.set_default_sort_func(lambda *args: -1)
- to_update.set_sort_column_id(0,
- gtk.SORT_ASCENDING)
- self.w_update_treeview.set_model(to_update)
- self.w_update_expander.set_expanded(True)
- else:
- self.w_update_expander.hide()
- self.w_confirm_ok_button.grab_focus()
- self.w_confirm_dialog.show()
- else:
- self.__proceed_with_stages()
-
- @staticmethod
- def __init_confirmation_tree_view(treeview):
- name_renderer = gtk.CellRendererText()
- name_renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
- column = gtk.TreeViewColumn(_('Name'), name_renderer,
- text = enumerations.CONFIRM_NAME)
- column.set_resizable(True)
- column.set_min_width(150)
- column.set_sort_column_id(0)
- column.set_sort_indicator(True)
- treeview.append_column(column)
- publisher_renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_('Publisher'), publisher_renderer,
- text = enumerations.CONFIRM_PUB)
- column.set_resizable(True)
- column.set_sort_column_id(1)
- column.set_sort_indicator(True)
- treeview.append_column(column)
- summary_renderer = gtk.CellRendererText()
- summary_renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
- column = gtk.TreeViewColumn(_('Summary'), summary_renderer,
- text = enumerations.CONFIRM_DESC)
- column.set_resizable(True)
- column.set_sort_column_id(2)
- column.set_sort_indicator(True)
- treeview.append_column(column)
-
- def __on_confirm_donotshow_toggled(self, widget):
- if self.action == enumerations.REMOVE:
- self.gconf.set_show_remove(not self.gconf.show_remove)
- elif self.action == enumerations.IMAGE_UPDATE:
- self.gconf.set_show_image_update(not self.gconf.show_image_update)
- elif self.action == enumerations.INSTALL_UPDATE:
- self.gconf.set_show_install(not self.gconf.show_install)
-
- def __on_confirm_ok_button_clicked(self, widget):
- if self.action == enumerations.INSTALL_UPDATE or \
- self.action == enumerations.REMOVE:
- self.__on_confirm_cancel_button_clicked(None)
- if self.top_level:
- self.w_main_window = self.w_dialog
- self.__proceed_with_stages()
- else:
- self.w_expander.set_expanded(self.gconf.details_expanded)
- self.w_dialog.show()
- self.__on_confirm_cancel_button_clicked(None)
- self.__proceed_with_stages(continue_operation = True)
-
- def __on_confirmdialog_delete_event(self, widget, event):
- self.__on_confirm_cancel_button_clicked(widget)
- return True
-
- def __on_confirm_cancel_button_clicked(self, widget):
- self.w_confirm_dialog.hide()
- if self.top_level and widget: # User clicked cacnel, widget != None
- gobject.idle_add(self.parent.install_terminated)
-
- def __on_createplandialog_delete(self, widget, event):
- self.__on_cancelcreateplan_clicked(None)
- return True
-
- def __set_dialog_size(self, w, h):
- self.w_dialog.set_size_request(w, h)
- self.w_dialog.resize(w, h)
-
- def __on_details_expander_activate(self, widget):
- collapsed = self.w_expander.get_expanded()
- if collapsed:
- if not (self.w_stages_box.flags() & gtk.VISIBLE):
- self.__set_dialog_size(self.dlg_width,
- self.dlg_done_collapsed_h)
- elif not (self.w_stage2.flags() & gtk.VISIBLE):
- self.__set_dialog_size(self.dlg_width,
- self.dlg_remove_collapsed_h)
- else:
- self.__set_dialog_size(self.dlg_width,
- self.dlg_install_collapsed_h)
- else:
- self.__set_dialog_size(self.dlg_width,
- self.dlg_expanded_details_h)
-
- self.gconf.set_details_expanded(not self.gconf.details_expanded)
-
- def __on_cancelcreateplan_clicked(self, widget):
- '''Handler for signal send by cancel button, which user might press
- during evaluation stage - while the dialog is creating plan'''
- if self.api_o.can_be_canceled() and self.operations_done_ex == False:
- self.canceling = True
- Thread(target = self.api_o.cancel, args = ()).start()
- cancel_txt = _("Canceling...")
- txt = "<b>" + self.current_stage_label_done + " - " \
- + cancel_txt + "</b>"
- gobject.idle_add(self.current_stage_label.set_markup, txt)
- gobject.idle_add(self.current_stage_icon.set_from_stock,
- gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
- gobject.idle_add(self.w_stages_label.set_markup, cancel_txt)
- self.w_cancel_button.set_sensitive(False)
- if self.top_level:
- gobject.idle_add(self.parent.install_terminated)
- if self.operations_done or self.operations_done_ex:
- self.w_dialog.hide()
- if self.web_install:
- if self.operations_done_ex == False and \
- not self.web_install_all_installed:
- gobject.idle_add(self.parent.update_package_list,
- None)
- else:
- gobject.idle_add(self.parent.update_package_list,
- self.web_updates_list)
- return
- if self.top_level:
- gobject.idle_add(self.parent.install_terminated)
- gobject.idle_add(self.parent.update_package_list, None)
-
- def __on_closecreateplan_clicked(self, widget):
- self.w_close_button.hide()
- self.w_dialog.hide()
- buf = self.w_details_textview.get_buffer()
- buf.set_text("")
- self.w_expander.set_expanded(False)
- self.__start_action()
- self.retry = False
- return
-
- def __on_help_button_clicked(self, widget):
- if self.top_level:
- gui_misc.display_help("using_um")
- elif self.action == enumerations.INSTALL_UPDATE:
- gui_misc.display_help("install-pkg")
- elif self.action == enumerations.REMOVE:
- gui_misc.display_help("remove-pkg")
- else:
- gui_misc.display_help("update-pkg")
-
- def __ipkg_ipkgui_uptodate(self):
- if self.ipkg_ipkgui_list == None:
- return True
- for pd in self.api_o.gen_plan_install(self.ipkg_ipkgui_list):
- continue
- upgrade_needed = not self.api_o.planned_nothingtodo(
- li_ignore_all=True)
- return not upgrade_needed
-
- def __proceed_with_stages(self, continue_operation = False):
- if continue_operation == False:
- self.__start_stage_one()
- self.w_expander.set_expanded(self.gconf.details_expanded)
- self.w_dialog.show()
- Thread(target = self.__proceed_with_stages_thread_ex,
- args = (continue_operation, )).start()
-
- def __proceed_with_stages_thread_ex(self, continue_operation = False):
- if self.api_lock:
- self.api_lock.acquire()
- self.__proceed_with_stages_thread_ex_with_lock(continue_operation)
- gui_misc.release_lock(self.api_lock)
-
- def __proceed_with_stages_thread_ex_with_lock(self, continue_operation = False):
- try:
- try:
- if self.action == enumerations.IMAGE_UPDATE and \
- continue_operation == False:
- self.__start_substage(
- _("Ensuring %s is up to date...") %
- self.parent_name,
- bounce_progress=True)
- solaris_image = True
- ips_uptodate = True
- notfound = self.__installed_fmris_from_args(
- [gui_misc.package_name["SUNWipkg"],
- gui_misc.package_name["SUNWcs"]])
- if notfound:
- solaris_image = False
- if solaris_image:
- ips_uptodate = \
- self.__ipkg_ipkgui_uptodate()
- if not ips_uptodate:
- #Do the stuff with installing pkg pkg-gui
- #and restart in the special mode
- self.ips_update = True
- self.__proceed_with_ipkg_thread()
- return
- else:
- gobject.idle_add(
- self.__create_uarenamebe_o)
- self.api_o.reset()
- if continue_operation == False:
- self.__proceed_with_stages_thread()
- else:
- self.__continue_with_stages_thread()
- except (MemoryError, EnvironmentError), __e:
- if isinstance(__e, EnvironmentError) and \
- __e.errno != errno.ENOMEM:
- raise
- msg = misc.out_of_memory()
- self.__g_error_stage(msg)
- return
- except RuntimeError, ex:
- msg = str(ex)
- if msg == "cannot release un-aquired lock":
- logger.error(msg)
- else:
- self.__g_error_stage(msg)
- return
- except api_errors.InventoryException, e:
- msg = _("Inventory exception:\n")
- if e.illegal:
- for i in e.illegal:
- msg += "\tpkg:\t" + i +"\n"
- else:
- msg = "%s" % e
- self.__g_error_stage(msg)
- return
- except api_errors.CatalogRefreshException, e:
- res = gui_misc.get_catalogrefresh_exception_msg(e)
- self.__g_error_stage(res[0])
- return
- except api_errors.TransportError, ex:
- msg = _("Please check the network "
- "connection.\nIs the repository accessible?\n\n"
- "%s") % str(ex)
- self.__g_error_stage(msg)
- return
- except api_errors.InvalidDepotResponseException, e:
- msg = _("\nUnable to contact a valid package depot. "
- "Please check your network settings and "
- "attempt to contact the server using a web "
- "browser.\n\n%s") % str(e)
- self.__g_error_stage(msg)
- return
- except api_errors.IpkgOutOfDateException:
- msg = _("pkg(5) appears to be out of "
- "date and should be updated.\n"
- "Please update %s package") % (
- gui_misc.package_name["SUNWipkg"])
- self.__g_error_stage(msg)
- return
- except api_errors.NonLeafPackageException, nlpe:
- msg = _("Cannot remove:\n\t%s\n"
- "Due to the following packages that "
- "depend on it:\n") % nlpe.fmri.get_name()
- for pkg_a in nlpe.dependents:
- msg += "\t" + pkg_a.get_name() + "\n"
-
- stem = nlpe.fmri.get_pkg_stem()
- self.list_of_packages.remove(stem)
- if self.confirmation_list:
- for item in self.confirmation_list:
- if item[enumerations.CONFIRM_STEM] == stem:
- self.confirmation_list.remove(item)
- break
- if len(self.list_of_packages) > 0:
- if self.w_close_button.get_use_stock():
- label = gui_misc.get_stockbutton_label_label(
- self.w_close_button)
- else:
- label = self.w_close_button.get_label()
- label = label.replace("_", "")
- msg += "\n"
- msg += _("Press %(button)s "
- "button to continue removal without"
- "\n\t%(package)s\n") % \
- {"button": label,
- "package": nlpe.fmri.get_name()}
- self.retry = True
- self.w_close_button.show()
- self.__g_error_stage(msg)
- return
- except api_errors.ProblematicPermissionsIndexException, err:
- msg = str(err)
- msg += _("\nFailure to consistently execute pkg "
- "commands when running %s as a privileged user is "
- "often a source of this problem.") % self.parent_name
- msg += _("\nTo rebuild index, please execute the "
- "following command as a privileged user:")
- msg += _("\n\tpkg rebuild-index")
- self.__g_error_stage(msg)
- return
- except api_errors.CorruptedIndexException:
- msg = _("There was an error during installation. The search "
- "index is corrupted. You might want try to fix this "
- "problem by executing the following command as a "
- "privileged user:\n"
- "\tpkg rebuild-index")
- self.__g_error_stage(msg)
- return
- except api_errors.ImageUpdateOnLiveImageException:
- msg = _("This is a Live Image. The install "
- "operation can't be performed.")
- self.__g_error_stage(msg)
- return
- except api_errors.RebootNeededOnLiveImageException:
- msg = _("The requested operation would affect files that cannot "
- "be modified in the Live Image.\n"
- "Please retry this operation on an alternate boot environment.")
- self.__g_error_stage(msg)
- return
- except api_errors.PlanMissingException:
- msg = _("There was an error during installation.\n"
- "The Plan of the operation is missing and the operation "
- "can't be finished. You might want try to fix this "
- "problem by restarting %s\n") % self.parent_name
- self.__g_error_stage(msg)
- return
- except api_errors.ImageplanStateException:
- msg = _("There was an error during installation.\n"
- "The State of the image is incorrect and the operation "
- "can't be finished. You might want try to fix this "
- "problem by restarting %s\n") % self.parent_name
- self.__g_error_stage(msg)
- return
- except api_errors.CanceledException:
- gobject.idle_add(self.__do_cancel)
- self.stop_bouncing_progress()
- return
- except api_errors.BENamingNotSupported:
- msg = _("Specifying BE Name not supported.\n")
- self.__g_error_stage(msg)
- return
- except api_errors.ApiException, ex:
- msg = str(ex)
- self.__g_error_stage(msg)
- return
- # We do want to prompt user to load BE admin if there is
- # not enough disk space. This error can either come as an
- # error within API exception, see bug #7642 or as a standalone
- # error, that is why we need to check for both situations.
- except EnvironmentError, uex:
- if uex.errno in (errno.EDQUOT, errno.ENOSPC):
- self.__handle_nospace_error()
- else:
- self.__handle_error()
- return
- except api_errors.HistoryStoreException, uex:
- if (isinstance(uex.error, EnvironmentError) and
- uex.error.errno in (errno.EDQUOT, errno.ENOSPC)):
- self.__handle_nospace_error()
- else:
- self.__handle_error()
- return
- except Exception:
- self.__handle_error()
- return
-
- def __reset_window_title(self):
- if self.reset_window_id:
- gobject.source_remove(self.reset_window_id)
- self.reset_window_id = 0
- if self.w_main_window:
- self.w_main_window.set_title(self.original_title)
-
- def __do_cancel(self):
- self.__do_dialog_hide()
-
- def __do_dialog_hide(self):
- self.w_dialog.hide()
- self.__reset_window_title()
-
- def __create_uarenamebe_o(self):
- if self.uarenamebe_o == None:
- self.uarenamebe_o = \
- uarenamebe.RenameBeAfterUpdateAll(
- self.parent, self.icon_confirm_dialog,
- self.w_main_window)
-
- def __handle_nospace_error(self):
- gobject.idle_add(self.__prompt_to_load_beadm)
- gobject.idle_add(self.__do_dialog_hide)
- self.stop_bouncing_progress()
-
- def __handle_error(self):
- traceback_lines = traceback.format_exc().splitlines()
- traceback_str = ""
- for line in traceback_lines:
- traceback_str += line + "\n"
- self.__g_exception_stage(traceback_str)
- sys.exc_clear()
-
- def __proceed_with_ipkg_thread(self):
- self.__start_substage(_("Updating %s") % self.parent_name,
- bounce_progress=True)
- self.__afterplan_information()
- self.prev_pkg = None
- self.__start_substage(_("Downloading..."), bounce_progress=False)
- self.api_o.prepare()
- self.__start_substage(_("Executing..."), bounce_progress=False)
- gobject.idle_add(self.w_cancel_button.set_sensitive, False)
- try:
- self.api_o.execute_plan()
- except api_errors.WrapSuccessfulIndexingException:
- pass
- except api_errors.WrapIndexingException, wex:
- err = _("\n\nDespite the error while indexing, the "
- "image-update, install, or uninstall has completed "
- "successfuly.")
- err = err.replace("\n\n", "")
- err += "\n" + str(wex)
- logger.error(err)
-
- gobject.idle_add(self.__operations_done)
-
- def __proceed_with_stages_thread(self):
- self.__start_substage(None)
- self.label_text = _("Gathering package information, please wait...")
- self.update_label_text(self.label_text)
- self.update_details_text(
- _("Gathering package information") + "\n", "level1")
-
- stuff_todo = self.__plan_stage()
- if stuff_todo:
-
- if (self.action == enumerations.IMAGE_UPDATE and
- self.show_confirmation):
- gobject.idle_add(self.__show_image_update_confirmation)
- else:
- self.__continue_with_stages_thread()
- else:
- if self.web_install:
- gobject.idle_add(self.__operations_done,
- _("All packages already installed."))
- return
-
- if self.action == enumerations.INSTALL_UPDATE:
- done_text = _("No updates necessary")
- elif self.action == enumerations.IMAGE_UPDATE:
- done_text = _("No updates available")
- elif self.action == enumerations.UPDATE_FACETS:
- done_text = _("All features already installed")
- gobject.idle_add(self.__operations_done, done_text)
-
- def __show_image_update_confirmation(self):
- dic_to_update = {}
- dic_to_install = {}
- dic_to_remove = {}
- to_update = gtk.ListStore(str, str, str)
- to_install = gtk.ListStore(str, str, str)
- to_remove = gtk.ListStore(str, str, str)
-
-
- plan_desc = self.api_o.describe()
- if plan_desc == None:
- return
- plan = plan_desc.get_changes()
-
- for pkg_plan in plan:
- orig = pkg_plan[0]
- dest = pkg_plan[1]
- if orig and dest:
- dic_to_update[dest.pkg_stem] = [dest.publisher, None]
- elif not orig and dest:
- dic_to_install[dest.pkg_stem] = [dest.publisher, None]
- elif orig and not dest:
- dic_to_remove[orig.pkg_stem] = [orig.publisher, None]
-
- self.__update_summaries(dic_to_update, dic_to_install, dic_to_remove)
-
- self.__dic_to_liststore(dic_to_update, to_update)
- self.__dic_to_liststore(dic_to_install, to_install)
- self.__dic_to_liststore(dic_to_remove, to_remove)
-
- len_to_update = len(to_update)
- len_to_install = len(to_install)
- len_to_remove = len(to_remove)
-
- if len_to_update == 0 and len_to_install == 0 and len_to_remove == 0:
- # Never show an empty confirmation dialog just proceed
- self.__on_confirm_ok_button_clicked(None)
- return
-
- self.__resize_confirm_frames(len_to_update,
- len_to_install, len_to_remove)
-
- if len_to_update > 0:
- self.__init_confirmation_tree_view(
- self.w_update_treeview)
- to_update.set_default_sort_func(lambda *args: -1)
- to_update.set_sort_column_id(0, gtk.SORT_ASCENDING)
- self.w_update_treeview.set_model(to_update)
- self.w_update_expander.set_expanded(True)
- else:
- self.w_update_expander.hide()
-
- if len_to_install > 0:
- self.__init_confirmation_tree_view(
- self.w_install_treeview)
- to_install.set_default_sort_func(lambda *args: -1)
- to_install.set_sort_column_id(0, gtk.SORT_ASCENDING)
- self.w_install_treeview.set_model(to_install)
- self.w_install_expander.set_expanded(True)
- else:
- self.w_install_expander.hide()
-
- if len_to_remove > 0:
- self.__init_confirmation_tree_view(
- self.w_remove_treeview)
- to_remove.set_default_sort_func(lambda *args: -1)
- to_remove.set_sort_column_id(0, gtk.SORT_ASCENDING)
- self.w_remove_treeview.set_model(to_remove)
- self.w_remove_expander.set_expanded(True)
- else:
- self.w_remove_expander.hide()
-
- no_pkgs = len(to_update) + len(to_install) + len(to_remove)
- operation_txt = _("Updates Confirmation")
- install_text = ngettext(
- "Review the package which will be affected by Updates",
- "Review the packages which will be affected by Updates", no_pkgs)
-
- self.w_confirm_dialog.set_title(operation_txt)
- self.w_confirm_label.set_markup("<b>"+install_text+"</b>")
-
- self.w_confirm_ok_button.grab_focus()
- self.__start_substage(None,
- bounce_progress=False)
- if self.top_level:
- self.__reset_window_title()
- else:
- self.w_dialog.hide()
- self.w_confirm_dialog.show()
-
-
- def __resize_confirm_frames(self, len_to_update, len_to_install, len_to_remove):
- calculated_height = DEFAULT_CONFIRMATION_HEIGHT
-
- if len_to_update > 0 and len_to_remove > 0 and len_to_install > 0:
- calculated_height = (calculated_height/4)*2
- elif (len_to_update > 0 and len_to_remove > 0) or (len_to_update > 0 and
- len_to_install > 0) or (len_to_remove > 0 and len_to_install > 0):
- calculated_height = (calculated_height/3)*2
-
- self.w_install_frame.set_size_request(DEFAULT_CONFIRMATION_WIDTH,
- calculated_height)
- self.w_update_frame.set_size_request(DEFAULT_CONFIRMATION_WIDTH,
- calculated_height)
- self.w_remove_frame.set_size_request(DEFAULT_CONFIRMATION_WIDTH,
- calculated_height)
-
- @staticmethod
- def __dic_to_liststore(dic, liststore):
- for entry in dic:
- liststore.append([entry, dic[entry][0], dic[entry][1]])
-
- def __handle_licenses(self):
- self.packages_with_license = \
- self.__get_packages_for_license_check()
- self.n_licenses = len(self.packages_with_license)
- if self.n_licenses > 0:
- gobject.idle_add(self.__do_ask_license)
- self.license_cv.acquire()
- while not self.accept_license_done:
- self.license_cv.wait()
- gui_misc.release_lock(self.license_cv)
- self.__do_accept_licenses()
- return
-
- def __continue_with_stages_thread(self):
- self.__afterplan_information()
- self.prev_pkg = None
- self.__handle_licenses()
-
- # The api.prepare() mostly is downloading the files so we are
- # Not showing this stage in the main stage dialog. If download
- # is necessary, then we are showing it in the details view
- if not self.action == enumerations.REMOVE:
- self.__start_stage_two()
- self.__start_substage(None,
- bounce_progress=False)
- try:
- self.api_o.prepare()
- except api_errors.PlanLicenseErrors:
- gobject.idle_add(self.__do_dialog_hide)
- if self.top_level:
- gobject.idle_add(self.parent.install_terminated)
- self.stop_bouncing_progress()
- return
- self.__start_stage_three()
- self.__start_substage(None,
- bounce_progress=False)
- gobject.idle_add(self.w_cancel_button.set_sensitive, False)
- try:
- self.api_o.execute_plan()
- except api_errors.WrapSuccessfulIndexingException:
- pass
- except api_errors.WrapIndexingException, wex:
- err = _("\n\nDespite the error while indexing, the "
- "image-update, install, or uninstall has completed "
- "successfuly.")
- err = err.replace("\n\n", "")
- err += "\n" + str(wex)
- logger.error(err)
-
- gobject.idle_add(self.__operations_done)
-
- def __start_stage_one(self):
- self.__start_stage(self.stages.get(1), self.w_stage1_label,
- self.w_stage1_icon)
- self.update_details_text(self.stages.get(1)[0]+"\n", "bold")
-
- def __start_stage_two(self):
- # End previous stage
- self.__end_stage()
- self.__start_stage(self.stages.get(2), self.w_stage2_label,
- self.w_stage2_icon)
- self.update_details_text(self.stages.get(2)[0]+"\n", "bold")
-
- def __start_stage_three(self):
- self.__end_stage()
- self.__start_stage(self.stages.get(3), self.w_stage3_label,
- self.w_stage3_icon)
- self.update_details_text(self.stages.get(3)[0]+"\n", "bold")
-
- def __do_start_stage(self, stage_text, current_stage_label, current_stage_icon):
- self.current_stage_label = current_stage_label
- self.current_stage_icon = current_stage_icon
- self.current_stage_label_done = stage_text[1]
- if self.w_main_window:
- new_title = stage_text[0]
- self.w_main_window.set_title(new_title)
- self.current_stage_label.set_markup("<b>"+stage_text[0]+"</b>")
- self.current_stage_icon.set_from_stock(gtk.STOCK_GO_FORWARD,
- gtk.ICON_SIZE_MENU)
-
- def __start_stage(self, stage_text, current_stage_label, current_stage_icon):
- gobject.idle_add(self.__do_start_stage, stage_text, current_stage_label,
- current_stage_icon)
-
- def __do_end_stage(self):
- self.current_stage_label.set_text(self.current_stage_label_done)
- self.current_stage_icon.set_from_pixbuf(self.done_icon)
- self.__reset_window_title()
-
- def __end_stage(self):
- gobject.idle_add(self.__do_end_stage)
-
- def __g_error_stage(self, msg):
- if msg == None or len(msg) == 0:
- msg = _("No futher information available")
- self.operations_done = True
- self.operations_done_ex = True
- self.stop_bouncing_progress()
- self.update_details_text(_("\nError:\n"), "bold")
- self.update_details_text("%s" % msg, "level1")
- self.update_details_text("\n")
- txt = "<b>" + self.current_stage_label_done + _(" - Failed </b>")
- gobject.idle_add(self.__g_error_stage_setup, txt)
- gobject.idle_add(self.w_dialog.queue_draw)
-
- def __g_error_stage_setup(self, txt):
- self.__reset_window_title()
- if self.action == enumerations.IMAGE_UPDATE:
- info_url = misc.get_release_notes_url()
- if info_url and len(info_url) == 0:
- info_url = gui_misc.RELEASE_URL
- self.w_release_notes.show()
- self.w_release_notes_link.set_uri(info_url)
- self.dlg_expanded_details_h += DIALOG_RELEASE_NOTE_OFFSET * 2
- self.dlg_install_collapsed_h += DIALOG_RELEASE_NOTE_OFFSET
- self.dlg_remove_collapsed_h += DIALOG_RELEASE_NOTE_OFFSET
-
- self.current_stage_label.set_markup(txt)
- self.current_stage_icon.set_from_stock(gtk.STOCK_DIALOG_ERROR,
- gtk.ICON_SIZE_MENU)
- self.w_expander.set_expanded(True)
- self.w_cancel_button.set_sensitive(True)
- self.__set_dialog_size(self.dlg_width, self.dlg_expanded_details_h)
-
- def __g_exception_stage(self, tracebk):
- self.__reset_window_title()
- self.operations_done = True
- self.operations_done_ex = True
- self.stop_bouncing_progress()
- if self.action == enumerations.IMAGE_UPDATE:
- info_url = misc.get_release_notes_url()
- if info_url and len(info_url) == 0:
- info_url = gui_misc.RELEASE_URL
- self.w_release_notes.show()
- self.w_release_notes_link.set_uri(info_url)
- txt = "<b>" + self.current_stage_label_done + _(" - Failed </b>")
- gobject.idle_add(self.current_stage_label.set_markup, txt)
- gobject.idle_add(self.current_stage_icon.set_from_stock,
- gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_MENU)
- msg_1 = _("An unknown error occurred in the %s stage.\n"
- "Please let the developers know about this problem by "
- "filing a bug together with the error details listed below at:\n"
- ) % self.current_stage_name
- msg_2 = "%s\n\n" % misc.BUG_URI_GUI
- self.update_details_text(_("\nError:\n"), "bold")
- self.update_details_text("%s" % msg_1, "level1")
- self.update_details_text("%s" % msg_2, "bold", "level2")
- if tracebk:
- msg = _("Exception traceback:\n")
- self.update_details_text("%s" % msg,
- "bold","level1")
- self.update_details_text("%s\n" % tracebk, "level2")
- else:
- msg = _("No futher information available")
- self.update_details_text("%s\n" % msg, "level2")
- msg_3 = _("pkg version: ")
- self.update_details_text("%s" % msg_3,
- "bold","level1")
- self.update_details_text("%s\n\n" % gui_misc.get_version(), "level2")
- publisher_header = _("List of configured publishers:")
- self.update_details_text("%s" % publisher_header,
- "bold","level1")
- publisher_str = gui_misc.get_publishers_for_output(self.api_o)
- self.update_details_text("%s\n" % publisher_str,
- "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:
- self.update_label_text(text)
- self.update_details_text(text + "\n", "level1")
- if bounce_progress:
- if self.stopped_bouncing_progress:
- self.start_bouncing_progress()
- else:
- self.stop_bouncing_progress()
-
- def update_label_text(self, markup_text):
- gobject.idle_add(self.__stages_label_set_markup, markup_text)
-
- def __stages_label_set_markup(self, markup_text):
- if not self.canceling == True:
- self.w_stages_label.set_markup(markup_text)
-
- def start_bouncing_progress(self):
- self.stop_progress_bouncing = False
- self.stopped_bouncing_progress = False
- Thread(target =
- self.__g_progressdialog_progress_pulse).start()
-
- def __g_progressdialog_progress_pulse(self):
- while not self.stop_progress_bouncing:
- gobject.idle_add(self.w_progressbar.pulse)
- time.sleep(0.1)
- self.stopped_bouncing_progress = True
- gobject.idle_add(self.w_progressbar.set_fraction, 0.0)
-
- def is_progress_bouncing(self):
- return not self.stopped_bouncing_progress
-
- def stop_bouncing_progress(self):
- if self.is_progress_bouncing():
- self.stop_progress_bouncing = True
-
- def update_details_text(self, text, *tags):
- gobject.idle_add(self.__update_details_text, text, *tags)
-
- def __update_details_text(self, text, *tags):
- buf = self.w_details_textview.get_buffer()
- textiter = buf.get_end_iter()
- if tags:
- buf.insert_with_tags_by_name(textiter, text, *tags)
- else:
- buf.insert(textiter, text)
- insert_mark = buf.get_insert()
- self.w_details_textview.scroll_to_mark(insert_mark, 0.0)
-
- def __update_window_title(self, display_string):
- self.w_main_window.set_title(display_string)
-
- def display_download_info(self):
- self.update_progress(self.dl_cur_nbytes, self.dl_goal_nbytes)
- if self.w_main_window:
- progtimes100 = int(self.prog * 100)
- if progtimes100 != self.prev_prog:
- self.prev_prog = progtimes100
- display_string = "%d%% - %s" % (progtimes100,
- self.stages[2][0])
- gobject.idle_add(self.__update_window_title,
- display_string)
- self.__display_download()
-
- def __display_download(self):
- if self.display_download_id == 0:
- self.display_download_id = gobject.timeout_add(DISPLAY_DELAY,
- self.__display_download_text)
-
- def __display_download_text(self):
- self.display_download_id = 0
- size_a_str = ""
- size_b_str = ""
- if self.dl_cur_nbytes >= 0:
- size_a_str = misc.bytes_to_str(self.dl_cur_nbytes)
- if self.dl_goal_nbytes >= 0:
- size_b_str = misc.bytes_to_str(self.dl_goal_nbytes)
- c = _("Downloaded %(current)s of %(total)s") % \
- {"current" : size_a_str,
- "total" : size_b_str}
- self.__stages_label_set_markup(c)
-
- def display_phase_info(self, phase_name, cur_n, goal_n):
- self.update_progress(cur_n, goal_n)
- if self.reset_window_id != 0:
- gobject.source_remove(self.reset_window_id)
- self.reset_window_id = 0
- if self.w_main_window:
- progtimes100 = int(self.prog * 100)
- if progtimes100 != self.prev_prog:
- self.prev_prog = progtimes100
- display_string = _("%(cur)d of %(goal)d - %(name)s") % \
- {"cur": cur_n, "goal": goal_n, \
- "name": phase_name}
- gobject.idle_add(self.__update_window_title,
- display_string)
- self.reset_window_id = gobject.timeout_add(
- RESET_PACKAGE_DELAY,
- self.__do_reset_window_text, phase_name)
-
- def __do_reset_window_text(self, phase_name):
- self.reset_window_id = 0
- self.__update_window_title(phase_name)
-
- def reset_label_text_after_delay(self):
- if self.reset_id != 0:
- gobject.source_remove(self.reset_id)
- self.reset_id = gobject.timeout_add(RESET_PACKAGE_DELAY,
- self.__do_reset_label_text)
-
- def __do_reset_label_text(self):
- self.reset_id = 0
- if self.label_text:
- self.__stages_label_set_markup(self.label_text)
-
- def __update_progress(self):
- self.update_progress_id = 0
- self.w_progressbar.set_fraction(self.prog)
-
- def update_progress(self, current, total):
- self.prog = float(current)/total
- if self.update_progress_id == 0:
- self.update_progress_id = gobject.timeout_add(DISPLAY_DELAY,
- self.__update_progress)
-
- def __plan_stage(self):
- '''Function which plans the image'''
- if self.action == enumerations.INSTALL_UPDATE:
- for pd in self.api_o.gen_plan_install(
- self.list_of_packages, refresh_catalogs=False):
- continue
- elif self.action == enumerations.REMOVE:
- for pd in self.api_o.gen_plan_uninstall(
- self.list_of_packages, noexecute=False):
- continue
- elif self.action == enumerations.IMAGE_UPDATE:
- # we are passing force, since we already checked if the
- # packages are up to date. Create BE if required
- for pd in self.api_o.gen_plan_update(
- refresh_catalogs=False, noexecute=False,
- force=True, be_name=None, new_be=None):
- continue
- self.pylint_stub = self.api_o.solaris_image()
- else:
- assert self.action == enumerations.UPDATE_FACETS
- for pd in self.api_o.gen_plan_change_varcets(
- variants=None, facets=self.facets,
- noexecute=False, be_name=None, new_be=None):
- continue
- return not self.api_o.planned_nothingtodo(li_ignore_all=True)
-
- def __operations_done(self, alternate_done_txt = None):
- self.__reset_window_title()
- self.label_text = 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")
- elif self.action == enumerations.UPDATE_FACETS:
- done_txt = _("Optional components updated successfully")
- if alternate_done_txt != None:
- done_txt = alternate_done_txt
- self.w_stages_box.hide()
- self.w_stages_icon.show()
- self.__stages_label_set_markup("<b>" + done_txt + "</b>")
- self.__update_details_text("\n"+ done_txt, "bold")
- self.w_cancel_button.set_sensitive(True)
- self.w_cancel_button.set_label("gtk-close")
- self.w_cancel_button.grab_focus()
- self.w_progressbar.hide()
- self.stop_bouncing_progress()
- self.operations_done = True
- if not self.gconf.details_expanded:
- self.__set_dialog_size(self.dlg_width, self.dlg_done_collapsed_h)
- if self.parent != None:
- if not self.web_install and not self.ips_update \
- and not self.action == enumerations.IMAGE_UPDATE \
- and not self.action == enumerations.UPDATE_FACETS:
- self.parent.update_package_list(self.update_list)
- if self.web_install:
- if done_txt == \
- _("All packages already installed.") or \
- done_txt == \
- _("Installation completed successfully"):
- self.web_install_all_installed = True
- else:
- self.web_install_all_installed = False
- self.web_updates_list = self.update_list
- if self.ips_update:
- self.w_dialog.hide()
- self.parent.restart_after_ips_update()
- elif self.action == enumerations.IMAGE_UPDATE or \
- self.action == enumerations.UPDATE_FACETS:
- if self.uarenamebe_o:
- be_rename_dialog = \
- self.uarenamebe_o.show_rename_dialog(
- self.update_list)
- if be_rename_dialog == True and not self.top_level:
- self.w_dialog.hide()
-
- def __prompt_to_load_beadm(self):
- msgbox = gtk.MessageDialog(parent = self.w_main_window,
- buttons = gtk.BUTTONS_OK_CANCEL, flags = gtk.DIALOG_MODAL,
- type = gtk.MESSAGE_ERROR,
- message_format = _(
- "Not enough disk space, the selected action cannot "
- "be performed.\n\n"
- "Click OK to manage your existing BEs and free up disk space or "
- "Cancel to cancel the action."))
- msgbox.set_title(_("Not Enough Disk Space"))
- result = msgbox.run()
- msgbox.destroy()
- if result == gtk.RESPONSE_OK:
- beadm.Beadmin(self.parent)
-
- def __afterplan_information(self):
- install_iter = None
- update_iter = None
- remove_iter = None
- plan_desc = self.api_o.describe()
- if plan_desc == None:
- return
- self.reboot_needed = plan_desc.reboot_needed
- plan = plan_desc.get_changes()
- self.update_details_text("\n")
- for pkg_plan in plan:
- origin_fmri = pkg_plan[0]
- destination_fmri = pkg_plan[1]
- if origin_fmri and destination_fmri:
- if not update_iter:
- update_iter = True
- txt = _("Packages To Be Updated:\n")
- self.update_details_text(txt, "bold")
- pkg_a = self.__get_pkgstr_from_pkginfo(destination_fmri)
- self.update_details_text(pkg_a+"\n", "level1")
- elif not origin_fmri and destination_fmri:
- if not install_iter:
- install_iter = True
- txt = _("Packages To Be Installed:\n")
- self.update_details_text(txt, "bold")
- pkg_a = self.__get_pkgstr_from_pkginfo(destination_fmri)
- self.update_details_text(pkg_a+"\n", "level1")
- elif origin_fmri and not destination_fmri:
- if not remove_iter:
- remove_iter = True
- txt = _("Packages To Be Removed:\n")
- self.update_details_text(txt, "bold")
- pkg_a = self.__get_pkgstr_from_pkginfo(origin_fmri)
- self.update_details_text(pkg_a+"\n", "level1")
-
- v = plan_desc.get_varcets()
- if v == None or len(v) == 0:
- self.update_details_text("\n")
- return
- txt = _("Optional components\n")
- self.update_details_text(txt, "bold")
- txt = _("Number of facets set: %s\n" % (len(v)))
- self.update_details_text(txt, "level1")
- for x in v:
- self.update_details_text("%s\n" % x, "level1")
- self.update_details_text("\n")
-
- def __get_pkgstr_from_pkginfo(self, pkginfo):
- dt_str = self.get_datetime(pkginfo.packaging_date)
- if not dt_str:
- dt_str = ""
- s_ver = pkginfo.version
- s_bran = pkginfo.branch
- pkg_name = pkginfo.pkg_stem
- 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:
- version_pref += "%d%s" % (s_ver[l_ver],".")
- l_ver += 1
- version_pref += "%d%s" % (s_ver[l_ver],"-")
- l_ver = 0
- version_suf = ""
- if s_bran != None:
- while l_ver < len(s_bran) -1:
- version_suf += "%d%s" % (s_bran[l_ver],".")
- l_ver += 1
- version_suf += "%d" % s_bran[l_ver]
- pkg_version = version_pref + version_suf + dt_str
- return pkg_name + "@" + pkg_version
-
- def __update_summaries(self, to_update, to_install, to_remove):
- pkgs_table = to_update.keys() + to_install.keys()
- info = None
- try:
- info = self.api_o.info(pkgs_table, False,
- frozenset([api.PackageInfo.SUMMARY,
- api.PackageInfo.IDENTITY]))
- info_r = self.api_o.info(to_remove.keys(), True,
- frozenset([api.PackageInfo.SUMMARY,
- api.PackageInfo.IDENTITY]))
- for info_s in (info.get(0) + info_r.get(0)):
- stem = info_s.pkg_stem
- if stem in to_update:
- to_update[stem][1] = info_s.summary
- elif stem in to_install:
- to_install[stem][1] = info_s.summary
- elif stem in to_remove:
- to_remove[stem][1] = info_s.summary
- except api_errors.ApiException, ex:
- err = str(ex)
- logger.error(err)
- gui_misc.notify_log_error(self.parent)
-
- @staticmethod
- def get_datetime(date_time):
- '''Support function for getting date from the API.'''
- date_tmp = None
- try:
- date_tmp = time.strptime(date_time, "%a %b %d %H:%M:%S %Y")
- except ValueError:
- return None
- if date_tmp:
- date_tmp2 = datetime.datetime(*date_tmp[0:5])
- return date_tmp2.strftime(":%m%d")
- return None
-
- def __installed_fmris_from_args(self, args_f):
- not_found = False
- try:
- res = self.api_o.info(args_f, True,
- frozenset([api.PackageInfo.STATE]))
- if not res or len(res[0]) != len(args_f):
- not_found = True
- except api_errors.ApiException:
- not_found = True
- return not_found
-
- def __do_ask_license(self):
- item = self.packages_with_license[self.current_license_no]
- pfmri = item[0]
- dest = item[2]
- pkg_name = pfmri.get_name()
- lic = dest.get_text()
- if dest.must_accept:
- gui_misc.change_stockbutton_label(self.w_license_accept_button,
- _("A_ccept"))
- self.w_license_label.set_text(
- _("You must accept the terms of the license before "
- "downloading this package."))
- self.w_license_accept_checkbutton.show()
- self.w_license_reject_button.show()
- self.w_license_accept_checkbutton.grab_focus()
- self.w_license_accept_checkbutton.set_active(False)
- self.w_license_accept_button.set_sensitive(False)
- else:
- if self.accept_text != None:
- gui_misc.change_stockbutton_label(
- self.w_license_accept_button,
- self.accept_text)
- self.w_license_label.set_text(
- _("You must view the terms of the license before "
- "downloading this package."))
- self.w_license_accept_checkbutton.hide()
- self.w_license_reject_button.hide()
- self.w_license_accept_button.set_sensitive(True)
- self.w_license_accept_button.grab_focus()
- lic_buffer = self.w_license_text.get_buffer()
- lic_buffer.set_text(lic)
- title = _("%s License") % pkg_name
- self.w_license_dialog.set_title(title)
- self.w_license_dialog.show()
- return
-
- def __do_accept_licenses(self):
- for item, accepted_value in self.packages_with_license_result:
- pfmri = item[0]
- dest = item[2]
- lic = dest.license
- self.api_o.set_plan_license_status(pfmri, lic,
- displayed=True, accepted=accepted_value)
-
- def __get_packages_for_license_check(self):
- pkg_list = []
- plan = self.api_o.describe()
- for item in plan.get_licenses():
- dest = item[2]
- if dest.must_display or dest.must_accept:
- pkg_list.append(item)
- return pkg_list
-
- def __on_license_reject_button_clicked(self, widget):
- self.packages_with_license_result.append(
- (self.packages_with_license[self.current_license_no],
- False))
- self.w_license_dialog.hide()
- self.license_cv.acquire()
- self.accept_license_done = True
- self.license_cv.notify()
- gui_misc.release_lock(self.license_cv)
-
- def __on_license_accept_button_clicked(self, widget):
- result = None
- item = self.packages_with_license[self.current_license_no]
- dest = item[2]
- if dest.must_accept:
- result = True
- self.packages_with_license_result.append(
- (item, result))
- self.w_license_dialog.hide()
- self.current_license_no += 1
- if self.current_license_no < self.n_licenses:
- gobject.idle_add(self.__do_ask_license)
- else:
- self.license_cv.acquire()
- self.accept_license_done = True
- self.license_cv.notify()
- gui_misc.release_lock(self.license_cv)
-
- def __on_license_dialog_delete(self, widget, event):
- if self.w_license_reject_button.get_property('visible'):
- self.__on_license_reject_button_clicked(None)
- else:
- self.__on_license_accept_button_clicked(None)
- return True
-
- def __on_license_accept_checkbutton_toggled(self, widget):
- ret = self.w_license_accept_checkbutton.get_active()
- self.w_license_accept_button.set_sensitive(ret)
--- a/src/gui/modules/misc.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1129 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-SPECIAL_CATEGORIES = ["locale", "plugin"] # We should cut all, but last part of the
- # new name scheme as part of fix for #7037.
- # However we need to have an exception rule
- # where we will cut all but three last parts.
-
-RELEASE_URL = "http://www.opensolaris.org" # Fallback url for release notes if api
- # does not gave us one.
-
-PROP_SIGNATURE_POLICY = "signature-policy"
-PROP_SIGNATURE_REQUIRED_NAMES = "signature-required-names"
-SIG_POLICY_IGNORE = "ignore"
-SIG_POLICY_VERIFY = "verify"
-SIG_POLICY_REQUIRE_SIGNATURES = "require-signatures"
-SIG_POLICY_REQUIRE_NAMES = "require-names"
-
-import gettext
-import locale
-import os
-import sys
-import traceback
-import threading
-try:
- import gobject
- import gnome
- import gtk
- import pango
-except ImportError:
- sys.exit(1)
-import pkg.fmri as fmri
-import pkg.misc as misc
-import pkg.client.api_errors as api_errors
-import pkg.client.api as api
-import pkg.client.publisher as publisher
-from pkg.gui.misc_non_gui import get_api_object as ngao
-from pkg.gui.misc_non_gui import setup_logging as su_logging
-from pkg.gui.misc_non_gui import shutdown_logging as sd_logging
-from pkg.gui.misc_non_gui import get_version as g_version
-from pkg.gui.misc_non_gui import get_os_version_and_build as g_os_version_and_build
-
-from pkg.gui.misc_non_gui import get_log_dir as ge_log_dir
-from pkg.gui.misc_non_gui import get_log_error_ext as ge_log_error_ext
-from pkg.gui.misc_non_gui import get_log_info_ext as ge_log_info_ext
-from pkg.gui.misc_non_gui import get_catalogrefresh_exception_msg as get_msg
-from pkg.gui.misc_non_gui import get_um_name as get_um
-from pkg.gui.misc_non_gui import get_image_path as g_image_path
-from pkg.gui.misc_non_gui import is_frameworkerror as is_frameworke
-
-from pkg.client import global_settings
-
-misc.setlocale(locale.LC_ALL, "")
-gettext.install("pkg", "/usr/share/locale")
-
-PUBCERT_COMMON_NAME = _(" Common Name (CN):")
-PUBCERT_ORGANIZATION = _(" Organization (O):")
-PUBCERT_ORGANIZATIONAL_UNIT = _(" Organizational Unit (OU):")
-
-PKG_CLIENT_NAME_PM = "packagemanager"
-PKG_CLIENT_NAME_WI = "packagemanager-webinstall"
-
-logger = global_settings.logger
-
-# Dictionary which converts old package names to current name.
-package_name = { 'SUNWcs' : 'SUNWcs',
- 'SUNWipkg' : 'package/pkg',
- 'SUNWipkg-gui' : 'package/pkg/package-manager',
- 'SUNWipkg-um' : 'package/pkg/update-manager',
- 'SUNWpython26-notify' : 'library/python-2/python-notify-26' }
-
-def set_signature_policy_names_for_textfield(widget, names):
- txt = ""
- if names != None and len(names) > 0:
- txt = names[0]
- for name in names[1:]:
- txt += ", " + name
- widget.set_text(txt)
-
-def fetch_signature_policy_names_from_textfield(text):
- names = []
- names = __split_ignore_comma_in_quotes(text)
- names = [x.strip(' ') for x in names]
- if len(names) == 1 and names[0] == '':
- del names[0]
- return names
-
-def setup_signature_policy_properties(ignore, verify, req_sigs, req_names, names, orig):
- set_props = {}
- if ignore != orig[SIG_POLICY_IGNORE] and ignore:
- set_props[PROP_SIGNATURE_POLICY] = SIG_POLICY_IGNORE
- elif verify != orig[SIG_POLICY_VERIFY] and verify:
- set_props[PROP_SIGNATURE_POLICY] = SIG_POLICY_VERIFY
- elif req_sigs != orig[SIG_POLICY_REQUIRE_SIGNATURES] and req_sigs:
- set_props[PROP_SIGNATURE_POLICY] = SIG_POLICY_REQUIRE_SIGNATURES
- elif req_names != orig[SIG_POLICY_REQUIRE_NAMES] and req_names:
- set_props[PROP_SIGNATURE_POLICY] = SIG_POLICY_REQUIRE_NAMES
-
- if names != orig[PROP_SIGNATURE_REQUIRED_NAMES]:
- set_props[PROP_SIGNATURE_REQUIRED_NAMES] = names
- return set_props
-
-def create_sig_policy_from_property(prop_sig_pol, prop_sig_req_names):
- names = []
- #Names with embedded commas, the default name separator, need to
- #be quoted to be treated as a single name
- if prop_sig_req_names:
- for name in prop_sig_req_names:
- if name.split(",", 1) == 2:
- names.append("\"%s\"" % name)
- else:
- names.append(name)
- sig_policy = {}
- sig_policy[SIG_POLICY_IGNORE] = False
- sig_policy[SIG_POLICY_VERIFY] = False
- sig_policy[SIG_POLICY_REQUIRE_SIGNATURES] = False
- sig_policy[SIG_POLICY_REQUIRE_NAMES] = False
- sig_policy[PROP_SIGNATURE_REQUIRED_NAMES] = []
-
- if prop_sig_pol == SIG_POLICY_IGNORE:
- sig_policy[SIG_POLICY_IGNORE] = True
- elif prop_sig_pol == SIG_POLICY_VERIFY:
- sig_policy[SIG_POLICY_VERIFY] = True
- elif prop_sig_pol == SIG_POLICY_REQUIRE_SIGNATURES:
- sig_policy[SIG_POLICY_REQUIRE_SIGNATURES] = True
- elif prop_sig_pol == SIG_POLICY_REQUIRE_NAMES:
- sig_policy[SIG_POLICY_REQUIRE_NAMES] = True
- sig_policy[PROP_SIGNATURE_REQUIRED_NAMES] = names
- return sig_policy
-
-def __split_ignore_comma_in_quotes(string):
- split_char = ","
- quote = "'"
- string_split = []
- current_word = ""
- inside_quote = False
- for letter in string:
- if letter == "'" or letter == "\"":
- quote = letter
- current_word += letter
- if inside_quote:
- inside_quote = False
- else:
- inside_quote = True
- elif letter == split_char and not inside_quote:
- if current_word != '':
- string_split.append(current_word)
- current_word = ""
- else:
- current_word += letter
- if current_word != "" and inside_quote:
- current_word += quote
- if current_word != '':
- string_split.append(current_word)
- return string_split
-
-def check_sig_required_names_policy(text, req_names, error_dialog_title):
- if not req_names:
- return True
- names = fetch_signature_policy_names_from_textfield(text)
- if len(names) == 0:
- error_occurred(None,
- _("One or more certificate names must be specified "
- "with this option."),
- error_dialog_title,
- gtk.MESSAGE_INFO)
- return False
- return True
-
-def get_image_path():
- return g_image_path()
-
-def get_version():
- return g_version()
-
-def get_os_version_and_build():
- return g_os_version_and_build()
-
-def get_publishers_for_output(api_o):
- publisher_str = ""
- fmt = "\n%s\t%s\t%s (%s)"
- try:
- pref_pub = api_o.get_highest_ranked_publisher()
- for pub in api_o.get_publishers():
- pstatus = " "
- if pub == pref_pub:
- # Preferred
- pstatus = "P"
- elif pub.disabled:
- # Disabled
- pstatus = "D"
- else:
- # Enabled, but not preferred
- pstatus = "E"
- r = pub.repository
- for uri in r.origins:
- # Origin
- publisher_str += fmt % \
- (pstatus, "O", pub.prefix, uri)
- for uri in r.mirrors:
- # Mirror
- publisher_str += fmt % \
- (pstatus, "M", pub.prefix, uri)
- except api_errors.ApiException:
- pass
- except Exception:
- pass
- return publisher_str
-
-def get_log_dir():
- return ge_log_dir()
-
-def get_log_error_ext():
- return ge_log_error_ext()
-
-def get_log_info_ext():
- return ge_log_info_ext()
-
-def get_pm_name():
- return PKG_CLIENT_NAME_PM
-
-def get_wi_name():
- return PKG_CLIENT_NAME_WI
-
-def get_um_name():
- return get_um()
-
-def is_frameworkerror(err):
- return is_frameworke(err)
-
-def notify_log_error(app):
- if global_settings.client_name == PKG_CLIENT_NAME_PM:
- gobject.idle_add(__notify_log_error, app,
- _("Errors logged: click to view"))
-
-def notify_log_warning(app):
- if global_settings.client_name == PKG_CLIENT_NAME_PM:
- gobject.idle_add(__notify_log_error, app,
- _("Warnings logged: click to view"))
-
-def __notify_log_error(app, msg):
- app.error_logged = True
- app.w_logalert_frame.show()
- app.w_logalert_frame.set_tooltip_text(msg)
-
-def setup_logging():
- return su_logging(global_settings.client_name)
-
-def shutdown_logging():
- sd_logging()
-
-def get_icon(icon_theme, name, size=16):
- try:
- return icon_theme.load_icon(name, size, 0)
- except gobject.GError:
- return None
-
-def init_for_help(application_dir="/"):
- props = { gnome.PARAM_APP_DATADIR : os.path.join(application_dir,
- 'usr/share/package-manager/help') }
- gnome.program_init('package-manager', '0.1', properties=props)
-
-def display_help(help_id=None):
- try:
- if help_id != None:
- gnome.help_display('package-manager', link_id=help_id)
- else:
- gnome.help_display('package-manager')
- except gobject.GError, ex:
- msg = str(ex)
- logger.error(msg)
-
-def add_pkgname_to_dic(dic, name, special_table):
- """Adds the original name of the package to the
- dictionary of names.
-
- 'dic' is the dictionary, which holds all the names
-
- 'name' is the original package name
-
- 'special_table' table with special names. Special name is when the full name
- is part of another name. Example package/name another/package/name. package/name
- is the special name in this situation."""
-
- table = name.split("/")
- if len(table) == 1:
- if table[0] in dic:
- return
- else:
- dic[table[0]] = {}
- table.reverse()
- i = 0
- j = len(table)
- for entry in table:
- dictionary = dic.get(entry)
- if dictionary == None:
- dic[entry] = {}
- i += 1
- dic = dic[entry]
- if i == 0 and j > 1:
- special_table.append(name)
-
-def __is_recursion_gr_then_one(dic):
- if not isinstance(dic, dict):
- return False
- keys = dic.keys()
- if len(keys) == 1:
- return __is_recursion_gr_then_one(dic.get(keys[0]))
- elif len(keys) > 1:
- return True
- else:
- return False
-
-def get_minimal_unique_name(dic, name, special_table):
- name_table = name.split("/")
- len_name_table = len(name_table)
- if len_name_table == 1 and name_table[0] in dic:
- # Special case. The name doesn't contain any "/"
- return name_table[0]
- elif len_name_table == 1:
- return name
- name_table.reverse()
- max_special_level = 0
- for special_name in special_table:
- if name.endswith(special_name):
- level = len(special_name.split("/"))
- if level > max_special_level:
- max_special_level = level
- for special_category in SPECIAL_CATEGORIES:
- found = False
- level = 1
- while level < len_name_table:
- if special_category == name_table[level - 1]:
- found = True
- break
- level += 1
- if found:
- if level > max_special_level:
- max_special_level = level
-
- if len_name_table < max_special_level:
- return name
-
- new_name = []
- i = 0
- for entry in name_table:
- dictionary = dic.get(entry)
- recursion = __is_recursion_gr_then_one(dictionary)
- if dictionary and recursion:
- new_name.append(entry)
- dic = dictionary
- i += 1
- elif dictionary != None:
- new_name.append(entry)
- dic = dictionary
- i += 1
- if i > max_special_level:
- break
- n = ""
- new_name.reverse()
- for part in new_name:
- n += part + "/"
- return n.strip("/")
-
-def release_lock(lock):
- if not lock:
- return
- try:
- lock.release()
- except RuntimeError, ex:
- msg = str(ex)
- logger.error(msg)
- except Exception:
- pass
-
-def get_api_object(img_dir, progtrack, parent_dialog):
- api_o = None
- message = None
- try:
- api_o = ngao(img_dir, progtrack)
- except api_errors.VersionException, ex:
- message = _("Version mismatch: expected version %d, got version %d") % \
- (ex.expected_version, ex.received_version)
- except api_errors.ImageNotFoundException, ex:
- message = _("%s is not an install image") % ex.user_dir
- except api_errors.ImageLockedError, ex:
- message = str(ex)
- except api_errors.ApiException, ex:
- message = _("An unknown error occurred") + "\n\n" + _("Error details:\n")
- message += str(ex)
- except Exception:
- traceback_lines = traceback.format_exc().splitlines()
- traceback_str = ""
- for line in traceback_lines:
- traceback_str += line + "\n"
- message = _("An unknown error occurred")
- if traceback_str != "":
- message += "\n\n" + _("Error details:\n") + traceback_str
- if api_o == None or message != None:
- if message == None:
- message = _("An unknown error occurred")
- raise Exception(message)
- return api_o
-
-def error_occurred(parent, error_msg, msg_title = None,
- msg_type=gtk.MESSAGE_ERROR, use_markup = False):
- msgbox = gtk.MessageDialog(parent =
- parent,
- buttons = gtk.BUTTONS_CLOSE,
- flags = gtk.DIALOG_MODAL,
- type = msg_type,
- message_format = None)
- if use_markup:
- msgbox.set_markup(error_msg)
- else:
- msgbox.set_property('text', error_msg)
- if msg_title != None:
- title = msg_title
- else:
- title = _("Error")
-
- msgbox.set_title(title)
- msgbox.run()
- msgbox.destroy()
-
-def get_version_fmt_string():
- build_str = _("Build")
- return "%(version)s (" + build_str + " %(build)s-%(branch)s)"
-
-def set_dependencies_text(textview, info, dep_info, installed_dep_info,
- installed_icon, not_installed_icon):
- names = []
- states = None
- installed_states = []
- if dep_info != None and len(dep_info.get(0)) >= 0:
- states = dep_info[0]
- if installed_dep_info != None and len(installed_dep_info.get(0)) >= 0:
- installed_states = installed_dep_info[0]
- version_fmt = get_version_fmt_string()
- for x in info.dependencies:
- if states != None and len(states) > 0:
- name = fmri.extract_pkg_name(x)
- found = False
- for state in states:
- if name == state.pkg_stem:
- version = version_fmt % \
- {"version": state.version,
- "build": state.build_release,
- "branch": state.branch}
- found = True
- break
- if not found:
- version = version_fmt % \
- {"version": '0',
- "build": '0',
- "branch": '0'}
- found = False
- for state in installed_states:
- if name == state.fmri.get_name():
- installed_version = version_fmt % \
- {"version": state.version,
- "build": state.build_release,
- "branch": state.branch}
- found = True
- break
- if not found:
- installed_version = (_("(not installed)"))
- names.append((name, version, installed_version,
- found))
- else:
- build_rel = "0"
- pkg_fmri = fmri.PkgFmri(x, build_release=build_rel)
- branch = pkg_fmri.version.branch
- version_stripped = pkg_fmri.get_version().split("-%s"
- % branch)[0]
- version = version_fmt % \
- {"version": version_stripped,
- "build": build_rel,
- "branch": branch}
- names.append((pkg_fmri.pkg_name, version,
- _("(not installed)"), False))
-
- depbuffer = textview.get_buffer()
- depbuffer.set_text("")
- if states == None:
- if len(names) == 0:
- itr = depbuffer.get_iter_at_line(0)
- depbuffer.insert_with_tags_by_name(itr,
- _("None"), "bold")
- else:
- for i in range(0, len(names)):
- itr = depbuffer.get_iter_at_line(i)
- dep_str = "%s\n" % (names[i])
- depbuffer.insert(itr, dep_str)
- return
- style = textview.get_style()
- font_size_in_pango_unit = style.font_desc.get_size()
- font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
- tab_array = pango.TabArray(3, True)
- header = [_("Name"), _("Dependency"), _("Installed Version")]
- max_len = [0, 0]
- for i in range(2):
- depbuffer.set_text("")
- itr = depbuffer.get_iter_at_line(0)
- depbuffer.insert_with_tags_by_name(itr, header[i], "bold")
- max_len[i] = get_textview_width(textview)
-
- depbuffer.set_text("")
- for one_names in names:
- itr = depbuffer.get_iter_at_line(0)
- depbuffer.insert(itr, one_names[i])
- test_len = get_textview_width(textview)
-
- if test_len > max_len[i]:
- max_len[i] = test_len
- depbuffer.set_text("")
-
- tab_array.set_tab(1, pango.TAB_LEFT, max_len[0] + font_size_in_pixel)
- tab_array.set_tab(2, pango.TAB_LEFT,
- max_len[0] + max_len[1] + 2 * font_size_in_pixel)
-
- textview.set_tabs(tab_array)
-
- if len(names) == 0:
- depbuffer.set_text("")
- itr = depbuffer.get_iter_at_line(0)
- depbuffer.insert_with_tags_by_name(itr, _("No dependencies"), "bold")
- return
-
- itr = depbuffer.get_iter_at_line(0)
- header_text = "%s\t%s\t%s\n" % (header[0], header[1], header[2])
- depbuffer.insert_with_tags_by_name(itr, header_text, "bold")
- resized_installed_icon = None
- resized_not_installed_icon = None
- i += 0
- for (name, version, installed_version, is_installed) in names:
- if is_installed:
- if resized_installed_icon == None:
- resized_installed_icon = resize_icon(
- installed_icon,
- font_size_in_pixel)
- icon = resized_installed_icon
- else:
- if resized_not_installed_icon == None:
- resized_not_installed_icon = resize_icon(
- not_installed_icon,
- font_size_in_pixel)
- icon = resized_not_installed_icon
- itr = depbuffer.get_iter_at_line(i + 1)
- dep_str = "%s\t%s\t" % (name, version)
- depbuffer.insert(itr, dep_str)
- end_itr = depbuffer.get_end_iter()
- depbuffer.insert_pixbuf(end_itr, icon)
- depbuffer.insert(end_itr, " %s\n" % installed_version)
- i += 1
-
-def set_package_details(pkg_name, local_info, remote_info, textview,
- installed_icon, not_installed_icon, update_available_icon,
- is_all_publishers_installed=None, pubs_info=None, renamed_info=None,
- pkg_renamed = False):
- installed = True
- has_remote = True
-
- if not local_info:
- # Package is not installed
- local_info = remote_info
- installed = False
-
- if not remote_info:
- remote_info = local_info
- has_remote = False
- installed = True
-
- labs = {}
- labs["name"] = _("Name:")
- labs["summ"] = _("Summary:")
- labs["desc"] = _("Description:")
- labs["size"] = _("Size:")
- labs["cat"] = _("Category:")
- labs["ins"] = _("Installed:")
- labs["available"] = _("Version Available:")
- labs["renamed_to"] = _("Renamed To:")
- labs["lat"] = _("Latest Version:")
- labs["repository"] = _("Publisher:")
-
- summary = _("None")
- if local_info.summary:
- summary = local_info.summary
- description = ""
- if local_info.description:
- description = local_info.description
-
- obsolete_str = ""
- text = {}
- text["name"] = pkg_name
- text["summ"] = summary
- text["desc"] = description
- renamed_to = ""
- if renamed_info != None and \
- len(renamed_info.dependencies) > 0:
- renamed_pkgs = []
- for dep in renamed_info.dependencies:
- if dep.startswith('pkg:/'):
- dep_strs = dep.split('/', 1)
- dep = dep_strs[1]
- renamed_pkgs.append(dep)
- renamed_to += renamed_pkgs[0] + "\n"
- for dep in renamed_pkgs[1:]:
- renamed_to += "\t" + dep + "\n"
- text["renamed_to"] = renamed_to
- if installed:
- if api.PackageInfo.OBSOLETE in local_info.states:
- obsolete_str = _(" (Obsolete)")
- ver_text = _("%(version)s (Build %(build)s-%(branch)s)")
- text["ins"] = ver_text % \
- {"version": local_info.version,
- "build": local_info.build_release,
- "branch": local_info.branch}
- text["ins"] += obsolete_str
- labs["available"] = _("Latest Version:")
- if not same_pkg_versions(local_info, remote_info):
- text["available"] = ver_text % \
- {"version": remote_info.version,
- "build": remote_info.build_release,
- "branch": remote_info.branch}
- elif has_remote:
- text["available"] = _("Not available from this publisher")
- else:
- text["available"] = "No"
- else:
- if api.PackageInfo.OBSOLETE in remote_info.states:
- obsolete_str = _(" (Obsolete)")
- text["ins"] = _("No")
- text["ins"] += obsolete_str
- labs["available"] = _("Latest Version:")
- text["available"] = _(
- "%(version)s (Build %(build)s-%(branch)s)") % \
- {"version": remote_info.version,
- "build": remote_info.build_release,
- "branch": remote_info.branch}
- if local_info.size != 0:
- text["size"] = misc.bytes_to_str(local_info.size)
- else:
- text["size"] = "0"
- categories = _("None")
- if local_info.category_info_list:
- verbose = len(local_info.category_info_list) > 1
- categories = ""
- categories += local_info.category_info_list[0].__str__(verbose)
- if len(local_info.category_info_list) > 1:
- for ci in local_info.category_info_list[1:]:
- categories += ", " + ci.__str__(verbose)
-
- text["cat"] = categories
- pub_name = local_info.publisher
- if pubs_info != None:
- try:
- item = pubs_info[local_info.publisher]
- except KeyError:
- item = None
- if item:
- alias = item[1]
- if alias != None and len(alias) > 0:
- pub_name = "%s (%s)" % (
- alias, local_info.publisher)
- text["repository"] = pub_name
- # pubs_info: dict of publisher disabled status and aliases:
- # pub_info[pub_name][0] = True disabled or False enabled
- # pub_info[pub_name][1] = Alias
- if is_all_publishers_installed and pubs_info != None:
- if local_info.publisher in pubs_info:
- if pubs_info[local_info.publisher][0]:
- text["repository"] = pub_name + \
- _(" (disabled)")
- else:
- text["repository"] = pub_name + _(" (removed)")
- set_package_details_text(labs, text, textview, installed_icon,
- not_installed_icon, update_available_icon, pkg_renamed)
- return (labs, text)
-
-def get_scale(textview):
- scale = 1.0
- if not textview:
- return scale
- style = textview.get_style()
- font_size_in_pango_unit = style.font_desc.get_size()
- font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
- s = gtk.settings_get_default()
- dpi = s.get_property("gtk-xft-dpi") / 1024
-
- # AppFontSize*DPI/72 = Cairo Units
- # DefaultFont=10, Default DPI=96: 10*96/72 = 13.3 Default FontInCairoUnits
- def_font_cunits = 13.3
- app_cunits = round(font_size_in_pixel*dpi/72.0, 1)
- if app_cunits >= def_font_cunits:
- scale = round(
- ((app_cunits - def_font_cunits)/def_font_cunits) + 1, 2)
- return scale
-
-def get_textview_width(textview):
- infobuffer = textview.get_buffer()
- bounds = infobuffer.get_bounds()
- start = textview.get_iter_location(bounds[0])
- end = textview.get_iter_location(bounds[1])
- return end[0] - start[0]
-
-def set_package_details_text(labs, text, textview, installed_icon,
- not_installed_icon, update_available_icon, pkg_renamed):
- style = textview.get_style()
- font_size_in_pango_unit = style.font_desc.get_size()
- font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
- tab_array = pango.TabArray(2, True)
-
- infobuffer = textview.get_buffer()
- infobuffer.set_text("")
- max_test_len = 0
- for lab in labs:
- __add_label_to_generalinfo(infobuffer, 0, labs[lab])
- test_len = get_textview_width(textview)
- if test_len > max_test_len:
- max_test_len = test_len
- infobuffer.set_text("")
- tab_array.set_tab(1, pango.TAB_LEFT, max_test_len + font_size_in_pixel)
- textview.set_tabs(tab_array)
- infobuffer.set_text("")
- i = 0
- __add_line_to_generalinfo(infobuffer, i, labs["name"], text["name"])
- i += 1
- if pkg_renamed:
- i = __add_renamed_line_to_generalinfo(infobuffer, i, labs, text)
- __add_line_to_generalinfo(infobuffer, i, labs["summ"], text["summ"])
- i += 1
- installed = False
- if text["ins"].startswith(_("No")):
- icon = not_installed_icon
- else:
- icon = installed_icon
- installed = True
- __add_line_to_generalinfo(infobuffer, i, labs["ins"],
- text["ins"], icon, font_size_in_pixel)
- i += 1
- if installed:
- if text["available"] != "No":
- __add_line_to_generalinfo(infobuffer, i,
- labs["available"], text["available"],
- update_available_icon, font_size_in_pixel)
- i += 1
- if not pkg_renamed:
- i = __add_renamed_line_to_generalinfo(infobuffer, i,
- labs, text)
- else:
- __add_line_to_generalinfo(infobuffer, i,
- labs["available"], text["available"])
- i += 1
- if text["size"] != "0":
- __add_line_to_generalinfo(infobuffer, i, labs["size"], text["size"])
- i += 1
- __add_line_to_generalinfo(infobuffer, i, labs["cat"], text["cat"])
- i += 1
- __add_line_to_generalinfo(infobuffer, i, labs["repository"],
- text["repository"])
- if len(text["desc"]) > 0:
- i += 1
- __add_label_to_generalinfo(infobuffer, i, labs["desc"] + '\n')
- i += 1
- itr = infobuffer.get_iter_at_line(i)
- infobuffer.insert(itr, text["desc"])
-
-def set_pub_cert_details_text(labs, text, textview, added=False, reinstated=False):
- style = textview.get_style()
- font_size_in_pango_unit = style.font_desc.get_size()
- font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
- tab_array = pango.TabArray(3, True)
-
- infobuffer = textview.get_buffer()
- infobuffer.set_text("")
-
- labs_issuer = {}
- labs_issuer["common_name_to"] = PUBCERT_COMMON_NAME
- labs_issuer["org_to"] = PUBCERT_ORGANIZATION
- labs_issuer["org_unit_to"] = PUBCERT_ORGANIZATIONAL_UNIT
- max_issuer_len = 0
- for lab in labs_issuer:
- __add_label_to_generalinfo(infobuffer, 0, labs_issuer[lab])
- test_len = get_textview_width(textview)
- if test_len > max_issuer_len:
- max_issuer_len = test_len
- infobuffer.set_text("")
-
- max_finger_len = 0
- __add_label_to_generalinfo(infobuffer, 0, labs["fingerprints"])
- max_finger_len = get_textview_width(textview)
- infobuffer.set_text("")
-
- tab_array.set_tab(0, pango.TAB_LEFT, max_finger_len + font_size_in_pixel)
- tab_array.set_tab(1, pango.TAB_LEFT, max_issuer_len + font_size_in_pixel)
- textview.set_tabs(tab_array)
- infobuffer.set_text("")
- i = 0
- __add_label_to_generalinfo(infobuffer, i, labs["issued_to"] + '\n')
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["common_name_to"],
- text["common_name_to"])
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["org_to"], text["org_to"],
- bold_label=False)
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["org_unit_to"],
- text["org_unit_to"])
-
- i += 1
- __add_label_to_generalinfo(infobuffer, i, labs["issued_by"] + '\n')
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["common_name_by"],
- text["common_name_by"])
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["org_by"], text["org_by"])
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["org_unit_by"],
- text["org_unit_by"])
-
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["validity"], "", bold_label=True)
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["issued_on"], text["issued_on"])
-
- i += 1
- __add_label_to_generalinfo(infobuffer, i, labs["fingerprints"] + '\n')
-
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["sha1"], text["sha1"])
- i += 1
- __add_line_to_pub_cert_info(infobuffer, i, labs["md5"], text["md5"])
- i += 1
- if not added and not reinstated:
- __add_line_to_pub_cert_info(infobuffer, i, labs["ips"], text["ips"],
- add_return=False)
- elif added and not reinstated:
- __add_label_to_generalinfo(infobuffer, i,
- _("Note: \t Certificate is marked to be added"))
- elif not added and reinstated:
- __add_label_to_generalinfo(infobuffer, i,
- _("Note: \t Certificate is marked to be reinstated"))
-
-def __add_renamed_line_to_generalinfo(text_buffer, index, labs, text):
- if text["renamed_to"] != "":
- rename_list = text["renamed_to"].split("\n", 1)
- start = ""
- remainder = ""
- if rename_list != None:
- if len(rename_list) > 0:
- start = rename_list[0]
- if len(rename_list) > 1:
- remainder = rename_list[1]
- __add_line_to_generalinfo(text_buffer, index, labs["renamed_to"],
- start)
- index += 1
- if len(remainder) > 0:
- itr = text_buffer.get_iter_at_line(index)
- text_buffer.insert(itr, remainder)
- index += remainder.count("\n")
- return index
-
-def __add_label_to_generalinfo(text_buffer, index, label):
- itr = text_buffer.get_iter_at_line(index)
- text_buffer.insert_with_tags_by_name(itr, label, "bold")
-
-def __add_line_to_generalinfo(text_buffer, index, label, text,
- icon = None, font_size = 1):
- itr = text_buffer.get_iter_at_line(index)
- text_buffer.insert_with_tags_by_name(itr, label, "bold")
- end_itr = text_buffer.get_end_iter()
- if icon == None:
- text_buffer.insert(end_itr, "\t%s\n" % text)
- else:
- resized_icon = resize_icon(icon, font_size)
- text_buffer.insert(end_itr, "\t")
- text_buffer.get_end_iter()
- text_buffer.insert_pixbuf(end_itr, resized_icon)
- text_buffer.insert(end_itr, " %s\n" % text)
-
-def __add_line_to_pub_cert_info(text_buffer, index, label, text,
- bold_label = False, add_return = True):
- tab_str = "\t"
- itr = text_buffer.get_iter_at_line(index)
- if bold_label:
- text_buffer.insert_with_tags_by_name(itr, label, "bold")
- else:
- text_buffer.insert_with_tags_by_name(itr, label, "normal")
- end_itr = text_buffer.get_end_iter()
-
- return_str = ""
- if add_return:
- return_str = "\n"
-
- text_buffer.insert(end_itr, tab_str)
- text_buffer.get_end_iter()
- text_buffer.insert(end_itr, (" %s" + return_str) % text)
-
-def same_pkg_versions(info1, info2):
- if info1 == None or info2 == None:
- return False
-
- return info1.version == info2.version and \
- info1.build_release == info2.build_release and \
- info1.branch == info2.branch
-
-def resize_icon(icon, font_size):
- width = icon.get_width()
- height = icon.get_height()
- return icon.scale_simple(
- (font_size * width) / height,
- font_size,
- gtk.gdk.INTERP_BILINEAR)
-
-def get_pkg_info(app, api_o, pkg_stem, local):
- info = None
- try:
- info = api_o.info([pkg_stem], local,
- api.PackageInfo.ALL_OPTIONS -
- frozenset([api.PackageInfo.LICENSES]))
- except api_errors.ApiException, ex:
- err = str(ex)
- logger.error(err)
- notify_log_error(app)
- return info
-
- pkgs_info = None
- package_info = None
- if info:
- pkgs_info = info[0]
- if pkgs_info:
- package_info = pkgs_info[0]
- if package_info:
- return package_info
- else:
- return None
-
-def restart_system():
- # "init 6" performs reboot in a clean and orderly manner informing
- # the svc.startd daemon of the change in runlevel which subsequently
- # achieves the appropriate milestone and ultimately executes
- # the rc0 kill scripts.
- command = "init 6"
- return os.system(command)
-
-def set_modal_and_transient(top_window, parent_window = None):
- if parent_window:
- top_window.set_transient_for(parent_window)
- top_window.set_modal(True)
-
-def get_catalogrefresh_exception_msg(cre):
- return get_msg(cre)
-
-def __get_stockbutton_label(button):
- # Gtk.Button->Gtk.Alignment->Gtk.HBox->[Gtk.Image, Gtk.Label]
- # Drill into Button widget to get Gtk.Label and set its text
- children = button.get_children()
- if len(children) == 0:
- return None
- align = children[0]
- if not align or not isinstance(align, gtk.Alignment):
- return None
- children = align.get_children()
- if len(children) == 0:
- return None
- hbox = children[0]
- if not hbox or not isinstance(hbox, gtk.HBox):
- return None
- children = hbox.get_children()
- if not (len(children) > 1):
- return None
- button_label = children[1]
- if not button_label or not isinstance(button_label, gtk.Label):
- return None
- return button_label
-
-def get_stockbutton_label_label(button):
- button_label = __get_stockbutton_label(button)
- if button_label != None:
- return button_label.get_label()
- else:
- return None
-
-def change_stockbutton_label(button, text):
- button_label = __get_stockbutton_label(button)
- if button_label != None:
- button_label.set_label(text)
-
-def set_icon_for_button_and_menuitem(icon_name, button=None, menuitem=None):
- icon_source = gtk.IconSource()
- icon_source.set_icon_name(icon_name)
- icon_set = gtk.IconSet()
- icon_set.add_source(icon_source)
- if button:
- image_widget = gtk.image_new_from_icon_set(icon_set,
- gtk.ICON_SIZE_SMALL_TOOLBAR)
- button.set_icon_widget(image_widget)
- if menuitem:
- image_widget = gtk.image_new_from_icon_set(icon_set,
- gtk.ICON_SIZE_MENU)
- menuitem.set_image(image_widget)
-
-def exit_if_no_threads():
- if threading.activeCount() == 1:
- if gtk.main_level() > 0:
- gtk.main_quit()
- sys.exit(0)
- return True
-
-def get_statusbar_label(statusbar):
- sb_frame = None
- sb_hbox = None
- sb_label = None
- children = statusbar.get_children()
- if len(children) > 0:
- sb_frame = children[0]
- if sb_frame and isinstance(sb_frame, gtk.Frame):
- children = sb_frame.get_children()
- if len(children) > 0:
- sb_hbox = children[0]
- if sb_hbox and isinstance(sb_hbox, gtk.HBox):
- children = sb_hbox.get_children()
- if len(children) == 0:
- return None
- sb_label = children[0]
- if sb_label and isinstance(sb_label, gtk.Label):
- return sb_label
- return None
-
-def get_origin_uri(repo):
- if repo == None:
- return None
- origin_uri = repo.origins[0]
- ret_uri = None
- if isinstance(origin_uri, str):
- if len(origin_uri) > 0:
- ret_uri = origin_uri.strip("/")
- elif isinstance(origin_uri, publisher.RepositoryURI):
- uri = origin_uri.uri
- if uri != None and len(uri) > 0:
- ret_uri = uri.strip("/")
- return ret_uri
-
-def get_pkg_stem(pkg_name, pkg_pub=None):
- pkg_str = "pkg:/"
- if pkg_pub == None:
- return_str = "%s%s" % (pkg_str, pkg_name)
- else:
- return_str = "%s/%s/%s" % (pkg_str, pkg_pub, pkg_name)
- return return_str
-
-def get_max_text_length(length_to_check, text, widget):
- if widget == None:
- return 0
- context = widget.get_pango_context()
- metrics = context.get_metrics(context.get_font_description())
- current_length = pango.PIXELS(
- metrics.get_approximate_char_width() * len(text))
- if current_length > length_to_check:
- return current_length
- else:
- return length_to_check
-
-def is_a_textview( widget):
- return widget.class_path().rpartition('.')[2] == "GtkTextView"
-
-def alias_clash(pubs, prefix, alias):
- clash = False
- if alias != None and len(alias) > 0:
- for pub in pubs:
- if pub.disabled:
- continue
- if pub.prefix == prefix:
- continue
- if alias == pub.prefix or alias == pub.alias:
- clash = True
- break
- return clash
-
-def setup_package_license(licenses):
- lic = ""
- lic_u = ""
- if licenses == None:
- lic_u = _("Not available")
- else:
- try:
- for licens in licenses:
- lic += licens.get_text()
- lic += "\n"
- except api_errors.ApiException:
- pass
- try:
- lic_u = unicode(lic, "utf-8")
- except UnicodeDecodeError:
- lic_u = _("License could not be shown "
- "due to conversion problem.")
- return lic_u
-
-def get_state_from_states(states):
- if api.PackageInfo.INSTALLED in states:
- pkg_state = api.PackageInfo.INSTALLED
- if api.PackageInfo.UPGRADABLE in states:
- pkg_state = api.PackageInfo.UPGRADABLE
- else:
- pkg_state = api.PackageInfo.KNOWN
-
- return pkg_state
--- a/src/gui/modules/misc_non_gui.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-import os
-import socket
-import urlparse
-import urllib2
-import cPickle
-import logging
-import logging.handlers
-import platform
-import sys
-
-import pkg
-import pkg.portable as portable
-import pkg.client.api as api
-import pkg.client.api_errors as api_errors
-import pkg.client.transport.exception as transport
-from pkg.client import global_settings
-
-# The current version of the Client API the PM, UM and
-# WebInstall GUIs have been tested against and are known to work with.
-CLIENT_API_VERSION = 68
-LOG_DIR = "/var/tmp"
-LOG_ERROR_EXT = "_error.log"
-LOG_INFO_EXT = "_info.log"
-PKG_CLIENT_NAME_UM = "updatemanager"
-IMAGE_DIRECTORY_DEFAULT = "/" # Image default directory
-IMAGE_DIR_COMMAND = "svcprop -p update/image_dir svc:/application/pkg/update"
-
-
-def get_image_path():
- try:
- image_directory = os.environ["PKG_IMAGE"]
- except KeyError:
- image_directory = \
- os.popen(IMAGE_DIR_COMMAND).readline().rstrip()
- if len(image_directory) == 0:
- image_directory = IMAGE_DIRECTORY_DEFAULT
- return image_directory
-
-def get_log_dir():
- return LOG_DIR
-
-def get_log_error_ext():
- return LOG_ERROR_EXT
-
-def get_log_info_ext():
- return LOG_INFO_EXT
-
-class _LogFilter(logging.Filter):
- def __init__(self, max_level=logging.CRITICAL):
- logging.Filter.__init__(self)
- self.max_level = max_level
-
- def filter(self, record):
- return record.levelno <= self.max_level
-
-def get_version():
- return pkg.VERSION
-
-def get_os_version_and_build():
- os_ver = portable.util.get_os_release()
- os_name = portable.util.get_canonical_os_name()
- if os_name == 'sunos':
- os_ver += " (" + platform.uname()[3] + ")"
- return os_ver
-
-def setup_logging(client_name):
- normal_setup = True
- log_path = os.path.join(LOG_DIR, client_name)
- err_str = ""
-
- infolog_path = log_path + LOG_INFO_EXT
- try:
- info_h = logging.handlers.RotatingFileHandler(infolog_path,
- maxBytes=1000000, backupCount=1)
- except IOError, e:
- err_str = _("WARNING: %s\nUnable to setup log:\n ") % client_name
- err_str += str(e)
- err_str += _("\n All info messages will be logged to stdout")
- normal_setup = False
-
- errlog_path = log_path + LOG_ERROR_EXT
- try:
- err_h = logging.handlers.RotatingFileHandler(errlog_path,
- maxBytes=1000000, backupCount=1)
- except IOError, e:
- if err_str == "":
- err_str = _("WARNING: %s\nUnable to setup log:\n ") % \
- client_name
- else:
- err_str += _("\n ")
- err_str += str(e)
- err_str += _("\n All errors and warnings will be logged to stderr")
- normal_setup = False
-
- if normal_setup:
- log_fmt = logging.Formatter(
- "<b>%(levelname)s:</b> " + client_name + \
- "\n%(asctime)s: %(filename)s: %(module)s: "
- "%(lineno)s:\n%(message)s")
- else:
- if client_name != PKG_CLIENT_NAME_UM and err_str != "":
- print err_str
- log_fmt = logging.Formatter(
- "%(levelname)s: " + client_name + \
- "\n%(asctime)s: %(filename)s: %(module)s: "
- "%(lineno)s:\n%(message)s")
- info_h = logging.StreamHandler(sys.stdout)
- err_h = logging.StreamHandler(sys.stderr)
-
- info_t = _LogFilter(logging.INFO)
- info_h.addFilter(info_t)
- info_h.setFormatter(log_fmt)
- info_h.setLevel(logging.INFO)
- global_settings.info_log_handler = info_h
-
- err_h.setFormatter(log_fmt)
- err_h.setLevel(logging.WARNING)
- global_settings.error_log_handler = err_h
-
- return normal_setup
-
-def shutdown_logging():
- try:
- global_settings.reset_logging()
- logging.shutdown()
- except IOError:
- pass
-
-def get_cache_dir(api_object):
- img = api_object.img
- cache_dir = os.path.join(img.imgdir, "gui_cache")
- try:
- __mkdir(cache_dir)
- except OSError:
- cache_dir = None
- return cache_dir
-
-def __mkdir(directory_path):
- if not os.path.isdir(directory_path):
- os.makedirs(directory_path)
-
-def get_api_object(img_dir, progtrack):
- api_o = None
- api_o = api.ImageInterface(img_dir,
- CLIENT_API_VERSION,
- progtrack, None, global_settings.client_name)
- return api_o
-
-def read_cache_file(file_path):
- data = []
- try:
- fh = open(file_path, 'r')
- data = cPickle.load(fh)
- fh.close()
- except IOError:
- pass
- except:
- pass
- return data
-
-def dump_cache_file(file_path, data):
- try:
- fh = open(file_path,"w")
- cPickle.dump(data, fh, True)
- fh.close()
- except IOError:
- pass
- except:
- pass
-
-def get_um_name():
- return PKG_CLIENT_NAME_UM
-
-def get_catalogrefresh_exception_msg(cre):
- framework_error = False
- if not isinstance(cre, api_errors.CatalogRefreshException):
- return ("", False)
- msg = _("Catalog refresh error:\n")
- if cre.succeeded < cre.total:
- msg += _(
- "Only %(suc)s out of %(tot)s catalogs successfully updated.\n") % \
- {"suc": cre.succeeded, "tot": cre.total}
-
- for pub, err in cre.failed:
- if isinstance(err, urllib2.HTTPError):
- msg += "%s: %s - %s" % \
- (err.filename, err.code, err.msg)
- elif isinstance(err, urllib2.URLError):
- if err.args[0][0] == 8:
- msg += "%s: %s" % \
- (urlparse.urlsplit(
- pub["origin"])[1].split(":")[0],
- err.args[0][1])
- else:
- if isinstance(err.args[0], socket.timeout):
- msg += "%s: %s" % \
- (pub["origin"], "timeout")
- else:
- msg += "%s: %s" % \
- (pub["origin"], err.args[0][1])
- else:
- framework_error = is_frameworkerror(err)
- msg += str(err)
-
- if cre.errmessage:
- msg += cre.errmessage
-
- return (msg, framework_error)
-
-def is_frameworkerror(err):
- if isinstance(err, transport.TransportFailures):
- for exp in err.exceptions:
- if isinstance(exp, transport.TransportFrameworkError) and \
- exp.code == 56:
- return True
- return False
-
--- a/src/gui/modules/parseqs.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-#!/usr/bin/python
-##################################################################################
-# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
-# http://www.python.org/download/releases/2.6.1/license/
-#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation;
-# All Rights Reserved
-#
-# Extraced from urlparse module in Python 2.6.1
-# http://www.python.org/ftp/python/2.6.1/Python-2.6.1.tgz
-# Python-2.6.1/Lib/urlparse.py
-#
-# Modifications:
-# Just extracted parse_qs() and parse_qsl() functions without any modifications
-# Only addition is the urllib import unquote statement
-#
-##################################################################################
-"""
-Parse (absolute and relative) URLs.
-
-See RFC 1808: "Relative Uniform Resource Locators", by R. Fielding,
-UC Irvine, June 1995.
-"""
-
-from urllib import unquote
-
-def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
- """Parse a query given as a string argument.
-
- Arguments:
-
- qs: URL-encoded query string to be parsed
-
- keep_blank_values: flag indicating whether blank values in
- URL encoded queries should be treated as blank strings.
- A true value indicates that blanks should be retained as
- blank strings. The default false value indicates that
- blank values are to be ignored and treated as if they were
- not included.
-
- strict_parsing: flag indicating what to do with parsing errors.
- If false (the default), errors are silently ignored.
- If true, errors raise a ValueError exception.
- """
- dict = {}
- for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
- if name in dict:
- dict[name].append(value)
- else:
- dict[name] = [value]
- return dict
-
-def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
- """Parse a query given as a string argument.
-
- Arguments:
-
- qs: URL-encoded query string to be parsed
-
- keep_blank_values: flag indicating whether blank values in
- URL encoded queries should be treated as blank strings. A
- true value indicates that blanks should be retained as blank
- strings. The default false value indicates that blank values
- are to be ignored and treated as if they were not included.
-
- strict_parsing: flag indicating what to do with parsing errors. If
- false (the default), errors are silently ignored. If true,
- errors raise a ValueError exception.
-
- Returns a list, as G-d intended.
- """
- pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
- r = []
- for name_value in pairs:
- if not name_value and not strict_parsing:
- continue
- nv = name_value.split('=', 1)
- if len(nv) != 2:
- if strict_parsing:
- raise ValueError, "bad query field: %r" % (name_value,)
- # Handle case of a control-name with no equal sign
- if keep_blank_values:
- nv.append('')
- else:
- continue
- if len(nv[1]) or keep_blank_values:
- name = unquote(nv[0].replace('+', ' '))
- value = unquote(nv[1].replace('+', ' '))
- r.append((name, value))
-
- return r
-
--- a/src/gui/modules/pmgconf.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved.
-#
-
-import sys
-try:
- import gconf
- from glib import GError
-except ImportError:
- sys.exit(1)
-
-PACKAGEMANAGER_PREFERENCES = "/apps/packagemanager/preferences"
-MAX_SEARCH_COMPLETION_PREFERENCES = \
- "/apps/packagemanager/preferences/max_search_completion"
-INITIAL_APP_WIDTH_PREFERENCES = "/apps/packagemanager/preferences/initial_app_width"
-INITIAL_APP_HEIGHT_PREFERENCES = "/apps/packagemanager/preferences/initial_app_height"
-INITIAL_APP_HPOS_PREFERENCES = "/apps/packagemanager/preferences/initial_app_hposition"
-INITIAL_APP_VPOS_PREFERENCES = "/apps/packagemanager/preferences/initial_app_vposition"
-INITIAL_SHOW_FILTER_PREFERENCES = "/apps/packagemanager/preferences/initial_show_filter"
-INITIAL_SECTION_PREFERENCES = "/apps/packagemanager/preferences/initial_section"
-LAST_EXPORT_SELECTION_PATH = \
- "/apps/packagemanager/preferences/last_export_selections_path"
-LAST_ADD_PUBCERT_PATH = \
- "/apps/packagemanager/preferences/last_add_pubcert_path"
-SHOW_STARTPAGE_PREFERENCES = "/apps/packagemanager/preferences/show_startpage"
-SHOW_IMAGE_UPDATE_CONFIRMATION = "/apps/packagemanager/preferences/imageupdate_confirm"
-SHOW_INSTALL_CONFIRMATION = "/apps/packagemanager/preferences/install_confirm"
-SHOW_REMOVE_CONFIRMATION = "/apps/packagemanager/preferences/remove_confirm"
-SAVE_STATE_PREFERENCES = "/apps/packagemanager/preferences/save_state"
-START_INSEARCH_PREFERENCES = "/apps/packagemanager/preferences/start_insearch"
-LASTSOURCE_PREFERENCES = "/apps/packagemanager/preferences/lastsource"
-API_SEARCH_ERROR_PREFERENCES = "/apps/packagemanager/preferences/api_search_error"
-DETAILS_EXPANDED_PREFERENCES = "/apps/packagemanager/preferences/details_expanded"
-
-class PMGConf:
- def __init__(self):
- self.client = gconf.client_get_default()
- try:
- self.max_search_completion = \
- self.client.get_int(MAX_SEARCH_COMPLETION_PREFERENCES)
- self.initial_show_filter = \
- self.client.get_int(INITIAL_SHOW_FILTER_PREFERENCES)
- self.initial_section = \
- self.client.get_int(INITIAL_SECTION_PREFERENCES)
- self.last_export_selection_path = \
- self.client.get_string(LAST_EXPORT_SELECTION_PATH)
- self.last_add_pubcert_path = \
- self.client.get_string(LAST_ADD_PUBCERT_PATH)
- self.show_startpage = \
- self.client.get_bool(SHOW_STARTPAGE_PREFERENCES)
- self.save_state = \
- self.client.get_bool(SAVE_STATE_PREFERENCES)
- self.show_image_update = \
- self.client.get_bool(SHOW_IMAGE_UPDATE_CONFIRMATION)
- self.show_install = \
- self.client.get_bool(SHOW_INSTALL_CONFIRMATION)
- self.show_remove = \
- self.client.get_bool(SHOW_REMOVE_CONFIRMATION)
- self.start_insearch = \
- self.client.get_bool(START_INSEARCH_PREFERENCES)
- self.lastsource = \
- self.client.get_string(LASTSOURCE_PREFERENCES)
- self.not_show_repos = \
- self.client.get_string(API_SEARCH_ERROR_PREFERENCES)
- self.initial_app_width = \
- self.client.get_int(INITIAL_APP_WIDTH_PREFERENCES)
- self.initial_app_height = \
- self.client.get_int(INITIAL_APP_HEIGHT_PREFERENCES)
- self.initial_app_hpos = \
- self.client.get_int(INITIAL_APP_HPOS_PREFERENCES)
- self.initial_app_vpos = \
- self.client.get_int(INITIAL_APP_VPOS_PREFERENCES)
- self.client.add_dir(PACKAGEMANAGER_PREFERENCES,
- gconf.CLIENT_PRELOAD_NONE)
- self.client.notify_add(SHOW_IMAGE_UPDATE_CONFIRMATION,
- self.__show_image_update_changed)
- self.client.notify_add(SHOW_INSTALL_CONFIRMATION,
- self.__show_install_changed)
- self.client.notify_add(SHOW_REMOVE_CONFIRMATION,
- self.__show_remove_changed)
- self.client.notify_add(SAVE_STATE_PREFERENCES,
- self.__save_state_changed)
- self.details_expanded = \
- self.client.get_bool(DETAILS_EXPANDED_PREFERENCES)
- except GError:
- # Default values - the same as in the
- # packagemanager-preferences.schemas
- self.max_search_completion = 20
- self.initial_show_filter = 0
- self.initial_section = 2
- self.last_export_selection_path = ""
- self.last_add_pubcert_path = ""
- self.show_startpage = True
- self.show_image_update = True
- self.show_install = True
- self.show_remove = True
- self.save_state = True
- self.start_insearch = True
- self.lastsource = ""
- self.not_show_repos = ""
- self.initial_app_width = 800
- self.initial_app_height = 600
- self.initial_app_hpos = 200
- self.initial_app_vpos = 320
- self.details_expanded = True
- self.show_startpage = False
- self.__fix_initial_values()
-
- def __fix_initial_values(self):
- if self.initial_app_width == -1:
- self.initial_app_width = 800
- if self.initial_app_height == -1:
- self.initial_app_height = 600
- if self.initial_app_hpos == -1:
- self.initial_app_hpos = 200
- if self.initial_app_vpos == -1:
- self.initial_app_vpos = 320
-
- if not self.not_show_repos:
- self.not_show_repos = ""
-
- def set_lastsource(self, value):
- try:
- self.lastsource = value
- self.client.set_string(LASTSOURCE_PREFERENCES, value)
- except GError:
- pass
-
- def set_details_expanded(self, value):
- try:
- self.details_expanded = value
- self.client.set_bool(DETAILS_EXPANDED_PREFERENCES, value)
- except GError:
- pass
-
- def set_start_insearch(self, value):
- try:
- self.start_insearch = value
- self.client.set_bool(START_INSEARCH_PREFERENCES, value)
- except GError:
- pass
-
- def set_show_startpage(self, value):
- try:
- self.show_startpage = value
- self.client.set_bool(SHOW_STARTPAGE_PREFERENCES, value)
- except GError:
- pass
-
- def set_save_state(self, value):
- try:
- self.save_state = value
- self.client.set_bool(SAVE_STATE_PREFERENCES, value)
- except GError:
- pass
-
- def set_show_image_update(self, value):
- try:
- self.show_image_update = value
- self.client.set_bool(SHOW_IMAGE_UPDATE_CONFIRMATION, value)
- except GError:
- pass
-
- def set_show_install(self, value):
- try:
- self.show_install = value
- self.client.set_bool(SHOW_INSTALL_CONFIRMATION, value)
- except GError:
- pass
-
- def set_show_remove(self, value):
- try:
- self.show_remove = value
- self.client.set_bool(SHOW_REMOVE_CONFIRMATION, value)
- except GError:
- pass
-
- def set_not_show_repos(self, value):
- try:
- self.client.set_string(API_SEARCH_ERROR_PREFERENCES, value)
- except GError:
- pass
-
- def save_values(self, pub, start_insearch, width, height, hpos, vpos):
- try:
- if self.last_export_selection_path:
- self.client.set_string(LAST_EXPORT_SELECTION_PATH,
- self.last_export_selection_path)
- if self.last_add_pubcert_path:
- self.client.set_string(LAST_ADD_PUBCERT_PATH,
- self.last_add_pubcert_path)
- self.client.set_string(LASTSOURCE_PREFERENCES, pub)
- self.client.set_bool(START_INSEARCH_PREFERENCES,
- start_insearch)
- self.client.set_int(INITIAL_APP_WIDTH_PREFERENCES, width)
- self.client.set_int(INITIAL_APP_HEIGHT_PREFERENCES, height)
- self.client.set_int(INITIAL_APP_HPOS_PREFERENCES, hpos)
- self.client.set_int(INITIAL_APP_VPOS_PREFERENCES, vpos)
- except GError:
- pass
-
-
- def __save_state_changed(self, client, connection_id, entry, arguments):
- self.save_state = entry.get_value().get_bool()
-
- def __show_image_update_changed(self, client, connection_id, entry, arguments):
- self.show_image_update = entry.get_value().get_bool()
-
- def __show_install_changed(self, client, connection_id, entry, arguments):
- self.show_install = entry.get_value().get_bool()
-
- def __show_remove_changed(self, client, connection_id, entry, arguments):
- self.show_remove = entry.get_value().get_bool()
--- a/src/gui/modules/pmlogging.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-import sys
-import os
-import re
-try:
- import gobject
- import pango
-except ImportError:
- sys.exit(1)
-import pkg.gui.misc as gui_misc
-
-REGEX_BOLD_MARKUP = re.compile(r'^<b>')
-REGEX_STRIP_MARKUP = re.compile(r'<.*?>')
-
-class PMLogging:
- def __init__(self, builder, window_icon, is_normal_logging_setup=True):
- self.is_normal_logging_setup = is_normal_logging_setup
- self.w_view_log_dialog = builder.get_object("view_log_dialog")
- self.w_view_log_dialog.set_icon(window_icon)
- self.w_view_log_dialog.set_title(_("Logs"))
- self.w_log_info_textview = builder.get_object("log_info_textview")
- self.w_log_errors_textview = builder.get_object("log_errors_textview")
-
- infobuffer = self.w_log_info_textview.get_buffer()
- infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
- infobuffer = self.w_log_errors_textview.get_buffer()
- infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
- self.w_log_close_button = builder.get_object("log_close_button")
- self.w_log_clear_button = builder.get_object("log_clear_button")
- self.w_log_help_button = builder.get_object("log_help_button")
-
- def set_window_icon(self, window_icon):
- self.w_view_log_dialog.set_icon(window_icon)
-
- def setup_signals(self):
- signals_table = [
- (self.w_log_close_button, "clicked",
- self.__on_log_close_button_clicked),
- (self.w_log_clear_button, "clicked",
- self.__on_log_clear_button_clicked),
- (self.w_log_help_button, "clicked",
- self.__on_log_help_button_clicked),
- (self.w_view_log_dialog, "delete_event",
- self.__on_log_dialog_delete_event)
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def set_modal_and_transient(self, parent_window):
- gui_misc.set_modal_and_transient(self.w_view_log_dialog,
- parent_window)
-
- @staticmethod
- def __on_log_help_button_clicked(widget):
- gui_misc.display_help("gkiod")
-
- def __on_log_dialog_delete_event(self, widget, event):
- self.__on_log_close_button_clicked(None)
- return True
-
- def __on_log_close_button_clicked(self, widget):
- self.w_view_log_dialog.hide()
-
- def __on_log_clear_button_clicked(self, widget):
- log_dir = gui_misc.get_log_dir()
- ext = gui_misc.get_log_error_ext()
- self.__clear_logs(log_dir, ext)
- ext = gui_misc.get_log_info_ext()
- self.__clear_logs(log_dir, ext)
- gui_misc.shutdown_logging()
- gui_misc.setup_logging()
- self.log_activate()
-
- def __clear_logs(self, log_dir, ext):
- self.__clear_log(os.path.join(log_dir, gui_misc.get_pm_name() + ext))
- self.__clear_log(os.path.join(log_dir, gui_misc.get_wi_name() + ext))
- self.__clear_log(os.path.join(log_dir, gui_misc.get_um_name() + ext))
-
- @staticmethod
- def __clear_log(path):
- try:
- os.unlink(path)
- except OSError:
- pass
-
- def log_activate(self):
- textbuffer_err = self.w_log_errors_textview.get_buffer()
- textbuffer_info = self.w_log_info_textview.get_buffer()
- if self.is_normal_logging_setup:
- textbuffer_err.set_text(_("Loading ..."))
- textbuffer_info.set_text(_("Loading ..."))
- else:
- textbuffer_err.set_text("")
- textbuffer_info.set_text("")
- textiter = textbuffer_err.get_end_iter()
- textbuffer_err.insert_with_tags_by_name(textiter,
- _("Unable to setup log:\n"), "bold")
- textbuffer_err.insert(textiter,
- _("All errors and warnings will be logged to stderr"))
- textiter = textbuffer_info.get_end_iter()
- textbuffer_info.insert_with_tags_by_name(textiter,
- _("Unable to setup log:\n"), "bold")
- textbuffer_info.insert(textiter,
- _("All info messages will be logged to stdout"))
-
- self.w_log_close_button.grab_focus()
- self.w_view_log_dialog.show()
-
- if self.is_normal_logging_setup:
- gobject.idle_add(self.__load_err_view_log)
- gobject.idle_add(self.__load_info_view_log)
-
- def __load_err_view_log(self):
- textbuffer = self.w_log_errors_textview.get_buffer()
- textbuffer.set_text("")
- textiter = textbuffer.get_end_iter()
- log_dir = gui_misc.get_log_dir()
- log_err_ext = gui_misc.get_log_error_ext()
- pm_err_log = os.path.join(log_dir, gui_misc.get_pm_name() + log_err_ext)
- wi_err_log = os.path.join(log_dir, gui_misc.get_wi_name() + log_err_ext)
- um_err_log = os.path.join(log_dir, gui_misc.get_um_name() + log_err_ext)
-
- self.__write_to_view_log(um_err_log,
- textbuffer, textiter, _("None: ") + gui_misc.get_um_name() + "\n")
- self.__write_to_view_log(wi_err_log,
- textbuffer, textiter, _("None: ") + gui_misc.get_wi_name() + "\n")
- self.__write_to_view_log(pm_err_log,
- textbuffer, textiter, _("None: ") + gui_misc.get_pm_name() + "\n")
- gobject.idle_add(self.w_log_errors_textview.scroll_to_iter, textiter,
- 0.0)
-
- def __load_info_view_log(self):
- textbuffer = self.w_log_info_textview.get_buffer()
- textbuffer.set_text("")
- textiter = textbuffer.get_end_iter()
- log_dir = gui_misc.get_log_dir()
- log_info_ext = gui_misc.get_log_info_ext()
- pm_info_log = os.path.join(log_dir, gui_misc.get_pm_name() + log_info_ext)
- wi_info_log = os.path.join(log_dir, gui_misc.get_wi_name() + log_info_ext)
- um_info_log = os.path.join(log_dir, gui_misc.get_um_name() + log_info_ext)
-
- self.__write_to_view_log(um_info_log,
- textbuffer, textiter, _("None: ") + gui_misc.get_um_name() + "\n")
- self.__write_to_view_log(wi_info_log,
- textbuffer, textiter, _("None: ") + gui_misc.get_wi_name() + "\n")
- self.__write_to_view_log(pm_info_log,
- textbuffer, textiter, _("None: ") + gui_misc.get_pm_name() + "\n")
- gobject.idle_add(self.w_log_info_textview.scroll_to_iter, textiter, 0.0)
-
- @staticmethod
- def __write_to_view_log(path, textbuffer, textiter, nomessages):
- infile = None
- try:
- infile = open(path, "r")
- except IOError:
- textbuffer.insert_with_tags_by_name(textiter, nomessages, "bold")
- return
- if infile == None:
- textbuffer.insert_with_tags_by_name(textiter, nomessages, "bold")
- return
-
- lines = infile.readlines()
- if len(lines) == 0:
- textbuffer.insert_with_tags_by_name(textiter, nomessages, "bold")
- return
- for line in lines:
- if re.match(REGEX_BOLD_MARKUP, line):
- line = re.sub(REGEX_STRIP_MARKUP, "", line)
- textbuffer.insert_with_tags_by_name(textiter, line,
- "bold")
- else:
- textbuffer.insert(textiter, line)
- try:
- infile.close()
- except IOError:
- pass
--- a/src/gui/modules/preferences.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,824 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-#
-
-import g11nsvc as g11nsvc
-import re
-import sys
-try:
- import gobject
- gobject.threads_init()
- import gtk
- import pygtk
- pygtk.require("2.0")
-except ImportError:
- sys.exit(1)
-import pkg.client.api_errors as api_errors
-import pkg.client.api as api
-import pkg.gui.misc as gui_misc
-import pkg.gui.enumerations as enumerations
-
-PREFERENCES_NOTEBOOK_GENERAL_PAGE = 0
-PREFERENCES_NOTEBOOK_SIG_POL_PAGE = 1
-PREFERENCES_NOTEBOOK_LANGUAGES_PAGE = 2
-GDK_2BUTTON_PRESS = 5 # gtk.gdk._2BUTTON_PRESS causes pylint warning
-LOCALE_PREFIX = "facet.locale."
-LANG_STAR_SUFFIX = "_*"
-
-ALL_LOCALES = "facet.locale.*"
-ALL_DEVEL = "facet.devel"
-ALL_DOC = "facet.doc.*"
-
-LANG_MATCH = re.compile(r'facet\.locale\.([a-z]{2,3})$')
-LANG_STAR_MATCH = re.compile(r'facet\.locale\.([a-z]{2,3})_\*$')
-LOCALE_MATCH = re.compile(r'facet\.locale\.([a-z]{2,3}_[A-Z]{2,3}.*$)')
-
-SYSTEM_G11LOCALE_MATCH = re.compile(r'^([a-z]{2,3}_[A-Z]{2,3})\.*(.*)$')
-SYSTEM_FACETLOCALE_MATCH = re.compile(r'([a-z]{2,3}_[A-Z]{2,3})\(*(.*?)\)*$')
-
-debug = False
-
-class Preferences:
- def __init__(self, parent, builder, window_icon, gconf):
- self.gconf = gconf
- self.parent = parent
- self.w_preferencesdialog = \
- builder.get_object("preferencesdialog")
- self.w_preferencesdialog.set_icon(window_icon)
- w_startup_label = \
- builder.get_object("startup_label")
- w_startup_label.hide()
- w_startup_hbox = \
- builder.get_object("startup_hbox")
- w_startup_hbox.hide()
- self.w_startpage_checkbutton = \
- builder.get_object("startpage_checkbutton")
- self.w_exit_checkbutton = \
- builder.get_object("exit_checkbutton")
- self.w_confirm_updateall_checkbutton = \
- builder.get_object("confirm_updateall_checkbutton")
- self.w_confirm_install_checkbutton = \
- builder.get_object("confirm_install_checkbutton")
- self.w_confirm_remove_checkbutton = \
- builder.get_object("confirm_remove_checkbutton")
- self.w_help_button = builder.get_object("preferenceshelp")
- self.w_close_button = builder.get_object("preferencesclose")
- self.w_cancel_button = builder.get_object("preferencescancel")
- self.w_languages_all_radiobutton = \
- builder.get_object("lang_install_all_radiobutton")
- self.w_languages_only_radiobutton = \
- builder.get_object("lang_install_only_radiobutton")
- self.w_feature_devel_checkbutton = \
- builder.get_object("feature_devel_checkbutton")
- self.w_feature_doc_checkbutton = \
- builder.get_object("feature_doc_checkbutton")
-
- self.w_locales_treeview = \
- builder.get_object("languages_treeview")
- self.w_preferences_notebook = builder.get_object(
- "preferences_notebook")
- self.w_languages_treeview = builder.get_object(
- "languages_treeview")
-
- self.w_gsig_ignored_radiobutton = builder.get_object(
- "gsig_ignored_radiobutton")
- self.w_gsig_optional_radiobutton = builder.get_object(
- "gsig_optional_but_valid_radiobutton")
- self.w_gsig_valid_radiobutton = builder.get_object(
- "gsig_valid_radiobutton")
- self.w_gsig_name_radiobutton = builder.get_object(
- "gsig_name_radiobutton")
- self.w_gsig_name_entry = builder.get_object(
- "gsig_name_entry")
- self.w_gsig_cert_names_vbox = builder.get_object(
- "gsig_cert_names_vbox")
-
- self.orig_gsig_policy = None
-
- self.watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
- self.orig_lang_locale_count_dict = {}
- self.orig_facets_dict = {}
- self.orig_facet_lang_dict = {}
- self.orig_facet_lang_star_dict = {}
- self.orig_facet_locale_dict = {}
- self.facet_g11_locales_dict = {}
- self.facetlocales_list = []
- self.facets_to_set = {}
- self.locales_setup = False
- self.locales_treeview_selection = []
- self.locales_list = self.__get_locales_liststore()
- self.__init_locales_tree_view(self.locales_list)
- self.__init_locales_list()
-
- def show_signature_policy(self):
- self.w_preferences_notebook.set_current_page(
- PREFERENCES_NOTEBOOK_SIG_POL_PAGE)
- self.w_preferencesdialog.show()
-
- def set_window_icon(self, window_icon):
- self.w_preferencesdialog.set_icon(window_icon)
-
- def setup_signals(self):
- signals_table = [
- (self.w_preferencesdialog, "show",
- self.__on_preferencesdialog_show),
- (self.w_preferencesdialog, "delete_event",
- self.__on_preferencesdialog_delete_event),
- (self.w_help_button, "clicked",
- self.__on_preferenceshelp_clicked),
- (self.w_close_button, "clicked",
- self.__on_preferencesclose_clicked),
- (self.w_cancel_button, "clicked",
- self.__on_preferencescancel_clicked),
- (self.w_languages_all_radiobutton, "toggled",
- self.__on_languages_all_radiobutton_toggled),
- (self.w_preferences_notebook, "switch_page",
- self.__on_notebook_change),
- (self.w_languages_treeview, "button_press_event",
- self.__on_languages_treeview_button_and_key_events),
- (self.w_languages_treeview, "key_press_event",
- self.__on_languages_treeview_button_and_key_events),
-
- (self.w_gsig_ignored_radiobutton, "toggled",
- self.__on_gsig_radiobutton_toggled),
- (self.w_gsig_optional_radiobutton, "toggled",
- self.__on_gsig_radiobutton_toggled),
- (self.w_gsig_valid_radiobutton, "toggled",
- self.__on_gsig_radiobutton_toggled),
- (self.w_gsig_name_radiobutton, "toggled",
- self.__on_gsig_radiobutton_toggled),
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def __on_gsig_radiobutton_toggled(self, widget):
- self.w_gsig_cert_names_vbox.set_sensitive(
- self.w_gsig_name_radiobutton.get_active())
-
- def __update_img_sig_policy_prop(self, set_props):
- try:
- self.parent.get_api_object().img.set_properties(set_props)
- except api_errors.ApiException, e:
- error_msg = str(e)
- msg_title = _("Preferences Error")
- msg_type = gtk.MESSAGE_ERROR
- gui_misc.error_occurred(None, error_msg, msg_title, msg_type)
- return False
- return True
-
- def __update_img_sig_policy(self):
- orig = self.orig_gsig_policy
- ignore = self.w_gsig_ignored_radiobutton.get_active()
- verify = self.w_gsig_optional_radiobutton.get_active()
- req_sigs = self.w_gsig_valid_radiobutton.get_active()
- req_names = self.w_gsig_name_radiobutton.get_active()
- names = gui_misc.fetch_signature_policy_names_from_textfield(
- self.w_gsig_name_entry.get_text())
- if req_names and len(names) == 0:
- return False
- set_props = gui_misc.setup_signature_policy_properties(ignore,
- verify, req_sigs, req_names, names, orig)
- if len(set_props) > 0:
- return self.__update_img_sig_policy_prop(set_props)
- return True
-
- def __prepare_img_signature_policy(self):
- if self.orig_gsig_policy:
- return
- sig_policy = self.__fetch_img_signature_policy()
- self.orig_gsig_policy = sig_policy
- self.w_gsig_ignored_radiobutton.set_active(
- sig_policy[gui_misc.SIG_POLICY_IGNORE])
- self.w_gsig_optional_radiobutton.set_active(
- sig_policy[gui_misc.SIG_POLICY_VERIFY])
- self.w_gsig_valid_radiobutton.set_active(
- sig_policy[gui_misc.SIG_POLICY_REQUIRE_SIGNATURES])
- self.w_gsig_cert_names_vbox.set_sensitive(False)
-
- if sig_policy[gui_misc.SIG_POLICY_REQUIRE_NAMES]:
- self.w_gsig_name_radiobutton.set_active(True)
- self.w_gsig_cert_names_vbox.set_sensitive(True)
-
- names = sig_policy[gui_misc.PROP_SIGNATURE_REQUIRED_NAMES]
- gui_misc.set_signature_policy_names_for_textfield(
- self.w_gsig_name_entry, names)
-
- def __fetch_img_signature_policy(self):
- prop_sig_pol = self.parent.get_api_object().img.get_property(
- gui_misc.PROP_SIGNATURE_POLICY)
- prop_sig_req_names = self.parent.get_api_object().img.get_property(
- gui_misc.PROP_SIGNATURE_REQUIRED_NAMES)
- return gui_misc.create_sig_policy_from_property(
- prop_sig_pol, prop_sig_req_names)
-
- def __on_notebook_change(self, widget, event, pagenum):
- if pagenum == PREFERENCES_NOTEBOOK_LANGUAGES_PAGE:
- self.w_preferencesdialog.window.set_cursor(
- self.watch )
- gobject.idle_add(self.__prepare_locales)
- elif pagenum == PREFERENCES_NOTEBOOK_SIG_POL_PAGE:
- gobject.idle_add(self.__prepare_img_signature_policy)
-
- @staticmethod
- def __get_locales_liststore():
- return gtk.ListStore(
- gobject.TYPE_STRING, # enumerations.LOCALE_NAME
- # - <language> (territory)
- gobject.TYPE_STRING, # enumerations.LOCALE_LANGUAGE
- # - Display <language> name
- gobject.TYPE_STRING, # enumerations.LOCALE_TERRITORY
- # - Display <territory> name
- gobject.TYPE_STRING, # enumerations.LOCALE
- # - <language>_<territory>(code)
- gobject.TYPE_BOOLEAN, # enumerations.LOCALE_SELECTED
- )
-
- def __select_column_clicked(self, data):
- sort_model = self.w_locales_treeview.get_model()
- model = sort_model.get_model()
- iter_next = sort_model.get_iter_first()
- none_selected = True
- all_selected = True
- list_of_paths = []
- while iter_next != None:
- sort_path = sort_model.get_path(iter_next)
- path = sort_model.convert_path_to_child_path(sort_path)
- list_of_paths.append(path)
- app_iter = sort_model.convert_iter_to_child_iter(None,
- iter_next)
- val = model.get_value(app_iter,
- enumerations.LOCALE_SELECTED)
- if val:
- none_selected = False
- else:
- all_selected = False
- iter_next = sort_model.iter_next(iter_next)
-
- some_selected = not all_selected and not none_selected
- select_all = none_selected or some_selected
- for path in list_of_paths:
- app_iter = model.get_iter(path)
- val = model.get_value(app_iter,
- enumerations.LOCALE_SELECTED)
- if select_all and not val:
- model.set_value(app_iter,
- enumerations.LOCALE_SELECTED, True)
- elif not select_all and val:
- model.set_value(app_iter,
- enumerations.LOCALE_SELECTED, False)
-
- @staticmethod
- def __sort_func(treemodel, iter1, iter2, column):
- col_val1 = treemodel.get_value(iter1, column)
- col_val2 = treemodel.get_value(iter2, column)
- ret = cmp(col_val1, col_val2)
- if ret != 0:
- return ret
- if column == enumerations.LOCALE_LANGUAGE:
- ter1 = treemodel.get_value(iter1,
- enumerations.LOCALE_TERRITORY)
- ter2 = treemodel.get_value(iter2,
- enumerations.LOCALE_TERRITORY)
- ret = cmp(ter1, ter2)
- elif column == enumerations.LOCALE_TERRITORY:
- lang1 = treemodel.get_value(iter1,
- enumerations.LOCALE_LANGUAGE)
- lang2 = treemodel.get_value(iter2,
- enumerations.LOCALE_LANGUAGE)
- ret = cmp(lang1, lang2)
- return ret
-
- def __init_locales_tree_view(self, locales_list):
- locales_sort_model = gtk.TreeModelSort(locales_list)
- locales_sort_model.set_sort_column_id(enumerations.LOCALE_LANGUAGE,
- gtk.SORT_ASCENDING)
-
- locales_sort_model.set_sort_func(enumerations.LOCALE_LANGUAGE,
- self.__sort_func,
- enumerations.LOCALE_LANGUAGE)
- locales_sort_model.set_sort_func(enumerations.LOCALE_TERRITORY,
- self.__sort_func,
- enumerations.LOCALE_TERRITORY)
-
- # Selected column - Not sorted
- toggle_renderer = gtk.CellRendererToggle()
- column = gtk.TreeViewColumn("",
- toggle_renderer, active = enumerations.LOCALE_SELECTED)
- column.set_expand(False)
- column.set_clickable(True)
- column.connect('clicked', self.__select_column_clicked)
- select_image = self.parent.get_theme_selection_coloumn_image()
- column.set_widget(select_image)
- self.w_locales_treeview.append_column(column)
-
- # Language column - sort using custom __sort_func()
- lang_renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_("Language"),
- lang_renderer, text = enumerations.LOCALE_LANGUAGE)
- column.set_expand(True)
- column.set_sort_column_id(enumerations.LOCALE_LANGUAGE)
- column.set_sort_indicator(True)
- self.w_locales_treeview.append_column(column)
-
- # Territory column - sort using custom __sort_func()
- ter_renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_("Territory"),
- ter_renderer, text = enumerations.LOCALE_TERRITORY)
- column.set_expand(True)
- column.set_sort_column_id(enumerations.LOCALE_TERRITORY)
- column.set_sort_indicator(True)
- self.w_locales_treeview.append_column(column)
-
- self.w_locales_treeview.get_selection().set_mode(
- gtk.SELECTION_MULTIPLE)
- self.w_locales_treeview.get_selection().connect('changed',
- self.__on_languages_treeview_changed)
- self.w_locales_treeview.set_model(locales_sort_model)
-
- def __init_locales_list(self):
- sorted_model = self.w_locales_treeview.get_model()
- self.w_locales_treeview.set_model(None)
- if not sorted_model:
- return
- model = sorted_model.get_model()
- model.clear()
- model.insert(0, ["", _("Loading ..."), "", "", False])
- self.w_locales_treeview.set_model(sorted_model)
-
- def __prepare_locales(self):
- try:
- if self.locales_setup:
- return
- self.__prepare_locales_list()
- finally:
- self.w_preferencesdialog.window.set_cursor(None)
-
- def __api_get_facets(self):
- facets = {}
- try:
- # XXX facets should be accessible through pkg.client.api
- facets = self.parent.get_api_object().img.get_facets()
- except api_errors.ApiException, ex:
- err = str(ex)
- self.w_preferencesdialog.hide()
- gobject.idle_add(self.parent.error_occurred, err,
- None, gtk.MESSAGE_INFO )
- return facets
-
- @staticmethod
- def __strip_g11system_codeset(g11locale):
- strippedlocale = ""
- m = re.match(SYSTEM_G11LOCALE_MATCH, g11locale)
- #Note: for now strip out system locale (code@locale variant)
- #ignore group(2)
- if m != None and len(m.groups()) == 2:
- strippedlocale = m.group(1)
- return strippedlocale
-
- @staticmethod
- def __facetlocale_to_g11locale(facetlocale):
- g11locale = ""
- m = re.match(SYSTEM_FACETLOCALE_MATCH, facetlocale)
- if m != None and len(m.groups()) == 2:
- g11locale = m.group(1)
- if m.group(2) != '':
- g11locale += "." + m.group(2)
- return g11locale
-
- def __prepare_locales_list(self):
- sorted_model = self.w_locales_treeview.get_model()
- self.w_locales_treeview.set_model(None)
- if not sorted_model:
- return
- # Reset api so we have up to date facet list
- if not self.parent.do_api_reset():
- #do_api_reset fails then it will inform the user
- return
-
- model = sorted_model.get_model()
- self.orig_facets_dict.clear()
- self.orig_facets_dict = self.__api_get_facets()
- self.__setup_optional_components_tab(self.orig_facets_dict)
- self.__process_orig_facets(self.orig_facets_dict)
-
- # Count selected facet locales for each lang
- self.orig_lang_locale_count_dict.clear()
- for locale, selected in self.orig_facet_locale_dict.items():
- lang = locale.split("_")[0]
- if not self.orig_lang_locale_count_dict.has_key(lang):
- self.orig_lang_locale_count_dict[lang] = 0
- if selected:
- self.orig_lang_locale_count_dict[lang] += 1
-
- # Setup locales:
- # Try to fetch available locales from system/locale package
- # using __get_system_locales()
- if self.facet_g11_locales_dict == None or \
- len(self.facet_g11_locales_dict) == 0:
- facetlocales_list = self.__get_system_locales()
- if facetlocales_list == None:
- return
- for facetlocale in facetlocales_list:
- g11locale = self.__facetlocale_to_g11locale(
- facetlocale)
- self.facet_g11_locales_dict[facetlocale] = g11locale
- # Setup locales:
- # If not available fall back and get the locales installed on
- # the system using loc_pop.get_valid_locales() and strip any codeset
- if self.facet_g11_locales_dict == None or \
- len(self.facet_g11_locales_dict) == 0:
- # pylint: disable-msg=E1101
- loc_pop = g11nsvc.G11NSvcLocalePopulate()
- g11locales_list = loc_pop.get_valid_locales()
- for g11locale in g11locales_list:
- strippedlocale = self.__strip_g11system_codeset(
- g11locale)
- facetlocale = strippedlocale
- self.facet_g11_locales_dict[facetlocale] = \
- strippedlocale
- # pylint: disable-msg=E1101
- loc_ops = g11nsvc.G11NSvcLocaleOperations(
- self.facet_g11_locales_dict.values())
-
- # Process facet locales
- locale_list = []
- for facetlocale, g11locale in self.facet_g11_locales_dict.items():
- if g11locale == "C" or g11locale == "POSIX":
- continue
- locale_name = loc_ops.get_locale_desc(g11locale)
- if locale_name == None or locale_name == "" :
- continue
- locale_language = loc_ops.get_language_desc(g11locale)
- locale_territory = loc_ops.get_territory_desc(g11locale)
- locale = facetlocale
- is_latin = g11locale.endswith("latin")
- if is_latin:
- locale_territory += _(" [latin]")
- lang = locale.split("_")[0]
-
- sel_count = 0
- if self.orig_lang_locale_count_dict.has_key(lang):
- sel_count = self.orig_lang_locale_count_dict[lang]
-
- # Precedence order:
- # <lang>_<ter>: <lang>_* e.g. nl_BE: nl_*
- selected = False
- if sel_count == 0:
- if self.orig_facet_lang_star_dict.has_key(
- lang):
- selected = \
- self.orig_facet_lang_star_dict[lang]
- elif self.orig_facet_locale_dict.has_key(locale):
- selected = self.orig_facet_locale_dict[
- locale]
-
- # locale row contains:
- #
- # locale_name = <language> (territory)
- # locale_language = Display <language> name
- # locale_territory = Display <territory> name
- # facetlocale = <language>_<territory>(<codeset>)
- # selected = selected
- locale_row = [locale_name, locale_language,
- locale_territory, facetlocale, selected]
- locale_list.append(locale_row)
- # Sort and setup model
- model.clear()
- i = 0
- locale_list.sort(key=lambda locale_list: locale_list[
- enumerations.LOCALE_LANGUAGE])
- for locale_row in locale_list:
- model.insert(i, locale_row)
- i += 1
- self.w_locales_treeview.set_model(sorted_model)
-
- if debug:
- print "DEBUG loaded facets: ", \
- self.orig_facet_lang_dict, \
- self.orig_facet_lang_star_dict, \
- self.orig_facet_locale_dict
- self.locales_setup = True
-
- def __get_system_locales(self):
- try:
- api_o = self.parent.get_api_object()
- res = api_o.get_pkg_list(
- pkg_list = api.ImageInterface.LIST_INSTALLED,
- patterns = ['system/locale'],
- repos=[],
- raise_unmatched=False, return_fmris=True,
- variants=True )
-
- manifest = None
- for entry in res:
- manifest = api_o.get_manifest(entry[0],
- all_variants=True, repos=[] )
- break
- facets = None
- if manifest != None:
- manifest.gen_actions(())
- facets = manifest.facets
- if debug and facets != None:
- print "DEBUG facets from system/locale:", facets
-
- facetlocales = []
- if facets == None:
- return facetlocales
-
- for facet_key in facets.keys():
- if not facet_key.startswith(LOCALE_PREFIX):
- continue
- m = re.match(LOCALE_MATCH, facet_key)
- if m != None and len(m.groups()) == 1:
- locale = m.group(1)
- facetlocales.append(locale)
- return facetlocales
-
- except api_errors.ApiException, ex:
- err = str(ex)
- self.w_preferencesdialog.hide()
- gobject.idle_add(self.parent.error_occurred, err,
- None, gtk.MESSAGE_INFO )
- return None
-
- def __setup_optional_components_tab(self, facets):
- install_all = self.__is_install_all(facets, ALL_LOCALES)
- self.w_languages_all_radiobutton.set_active(install_all)
- self.w_languages_only_radiobutton.set_active(not install_all)
- self.w_locales_treeview.set_sensitive(not install_all)
-
- install_devel = self.__is_install_all(facets, ALL_DEVEL)
- self.w_feature_devel_checkbutton.set_active(install_devel)
- install_doc = self.__is_install_all(facets, ALL_DOC)
- self.w_feature_doc_checkbutton.set_active(install_doc)
-
- @staticmethod
- def __is_install_all(facets, component_type):
- if facets != None and facets.has_key(component_type):
- return facets[component_type]
- # Default to True if key not present
- return True
-
- def __process_orig_facets(self, facets):
- if debug:
- print "DEBUG orig facets", facets
-
- self.orig_facet_lang_dict.clear()
- self.orig_facet_lang_star_dict.clear()
- self.orig_facet_locale_dict.clear()
-
- # Process facets
- for facet_key in facets.keys():
- val = facets[facet_key]
- if not facet_key.startswith(LOCALE_PREFIX):
- continue
- if facet_key == ALL_LOCALES:
- self.orig_facet_lang_dict[ALL_LOCALES] = val
- continue
- m = re.match(LANG_MATCH, facet_key)
- if m != None and len(m.groups()) == 1:
- lang = m.group(1)
- self.orig_facet_lang_dict[lang] = val
- continue
- m = re.match(LANG_STAR_MATCH, facet_key)
- if m != None and len(m.groups()) == 1:
- lang = m.group(1)
- self.orig_facet_lang_star_dict[lang] = val
- continue
- m = re.match(LOCALE_MATCH, facet_key)
- if m != None and len(m.groups()) == 1:
- locale = m.group(1)
- self.orig_facet_locale_dict[locale] = val
-
- def __dump_locales_list(self):
- self.facets_to_set = self.__api_get_facets()
- install_all = self.w_languages_all_radiobutton.get_active()
- self.facets_to_set[ALL_LOCALES] = install_all
-
- if install_all:
- return
-
- sorted_model = self.w_locales_treeview.get_model()
- if not sorted_model:
- return
- model = sorted_model.get_model()
-
- lang_locale_dict = {}
- lang_locale_count_dict = {}
- for row in model:
- selected = row[enumerations.LOCALE_SELECTED]
- locale = row[enumerations.LOCALE]
- lang = locale.split("_")[0]
-
- if not lang_locale_dict.has_key(lang):
- lang_locale_dict[lang] = {}
- lang_locale_dict[lang][locale] = selected
- if not lang_locale_count_dict.has_key(lang):
- lang_locale_count_dict[lang] = 0
- if selected:
- lang_locale_count_dict[lang] += 1
-
- for lang, locales in lang_locale_dict.items():
- sel_count = lang_locale_count_dict[lang]
- self.__process_locales_to_set(lang, locales, sel_count)
-
- if debug:
- print "DEBUG facets to set:", self.facets_to_set
-
- def __dump_optional_components(self):
- install_devel = self.w_feature_devel_checkbutton.get_active()
- install_doc = self.w_feature_doc_checkbutton.get_active()
-
- if install_devel == False:
- self.facets_to_set[ALL_DEVEL] = False
- elif self.facets_to_set.has_key(ALL_DEVEL):
- del self.facets_to_set[ALL_DEVEL]
-
- if install_doc == False:
- self.facets_to_set[ALL_DOC] = False
- elif self.facets_to_set.has_key(ALL_DOC):
- del self.facets_to_set[ALL_DOC]
-
- def __process_locales_to_set(self, lang, locales, sel_count):
- locales_count = len(locales)
- if locales_count == 0:
- return
-
- # All Selected
- if sel_count == locales_count:
- self.facets_to_set[LOCALE_PREFIX + lang + \
- LANG_STAR_SUFFIX] = True
- self.facets_to_set[LOCALE_PREFIX + lang] = True
- for item in locales.items():
- key = LOCALE_PREFIX + item[0]
- if self.facets_to_set.has_key(key):
- del self.facets_to_set[key]
- # None Selected
- elif sel_count == 0:
- has_orig_star_key = \
- self.orig_facet_lang_star_dict.has_key(lang)
- has_orig_lang_count_key = \
- self.orig_lang_locale_count_dict.has_key(lang)
- # Has the user made a change to get us to the None selected state?
- # If not then just ignore.
- if (has_orig_star_key and
- self.orig_facet_lang_star_dict[lang]) or \
- (has_orig_lang_count_key and
- self.orig_lang_locale_count_dict[lang] > 0):
- if self.facets_to_set.has_key(LOCALE_PREFIX +
- lang + LANG_STAR_SUFFIX):
- del self.facets_to_set[LOCALE_PREFIX +
- lang + LANG_STAR_SUFFIX]
- if self.facets_to_set.has_key(LOCALE_PREFIX +
- lang):
- del self.facets_to_set[LOCALE_PREFIX +
- lang]
-
- for item in locales.items():
- key = LOCALE_PREFIX + item[0]
- if self.facets_to_set.has_key(key):
- del self.facets_to_set[key]
- # Some Selected
- else:
- self.facets_to_set[LOCALE_PREFIX + lang] = True
- star_key = LOCALE_PREFIX + lang + LANG_STAR_SUFFIX
- if self.facets_to_set.has_key(star_key):
- del self.facets_to_set[star_key]
- for locale, val in locales.items():
- key = LOCALE_PREFIX + locale
- if val:
- self.facets_to_set[key] = val
- else:
- if self.facets_to_set.has_key(key):
- del self.facets_to_set[key]
-
- def __on_languages_treeview_button_and_key_events(self,
- treeview, event):
- if event.type == GDK_2BUTTON_PRESS:
- self.__enable_disable()
-
- def __on_languages_treeview_changed(self, treeselection):
- selection = treeselection.get_selected_rows()
- pathlist = selection[1]
- self.locales_treeview_selection = pathlist
- if pathlist != None and len(pathlist) == 1:
- self.__enable_disable()
-
- def __enable_disable(self):
- sorted_model = self.w_locales_treeview.get_model()
- if sorted_model == None:
- return
- model = sorted_model.get_model()
- if len(self.locales_treeview_selection) == 0:
- return
-
- path = self.locales_treeview_selection[0]
- child_path = sorted_model.convert_path_to_child_path(path)
- itr = model.get_iter(child_path)
- selected = model.get_value(itr, enumerations.LOCALE_SELECTED)
- model.set_value(itr, enumerations.LOCALE_SELECTED, not selected)
-
- for path in self.locales_treeview_selection[1:]:
- child_path = sorted_model.convert_path_to_child_path(path)
- itr = model.get_iter(child_path)
- model.set_value(itr, enumerations.LOCALE_SELECTED,
- not selected)
-
- def set_modal_and_transient(self, parent_window):
- gui_misc.set_modal_and_transient(self.w_preferencesdialog,
- parent_window)
-
- def __on_preferencesdialog_delete_event(self, widget, event):
- self.__on_preferencesclose_clicked(None)
- return True
-
- def __on_preferencesdialog_show(self, widget):
- self.orig_gsig_policy = {}
- self.locales_setup = False
-
- pagenum = self.w_preferences_notebook.get_current_page()
- if pagenum == PREFERENCES_NOTEBOOK_LANGUAGES_PAGE:
- self.w_preferencesdialog.window.set_cursor(self.watch)
- gobject.idle_add(self.__prepare_locales)
- elif pagenum == PREFERENCES_NOTEBOOK_SIG_POL_PAGE:
- gobject.idle_add(self.__prepare_img_signature_policy)
- return True
-
- def __on_preferencescancel_clicked(self, widget):
- self.w_preferencesdialog.hide()
-
- def __on_preferencesclose_clicked(self, widget):
- error_dialog_title = _("Preferences")
- text = self.w_gsig_name_entry.get_text()
- req_names = self.w_gsig_name_radiobutton.get_active()
- if not gui_misc.check_sig_required_names_policy(text,
- req_names, error_dialog_title):
- return
- if self.orig_gsig_policy and not self.__update_img_sig_policy():
- return
- self.__dump_locales_list()
- self.__dump_optional_components()
- self.w_preferencesdialog.hide()
- ignore_all_default = len(self.orig_facets_dict) == 0 and \
- len(self.facets_to_set) == 1 \
- and self.facets_to_set.has_key(ALL_LOCALES) and \
- self.facets_to_set[ALL_LOCALES] == True
- if not ignore_all_default and self.orig_facets_dict != {} and \
- self.orig_facets_dict != self.facets_to_set:
- self.parent.update_facets(self.facets_to_set)
- self.gconf.set_show_startpage(
- self.w_startpage_checkbutton.get_active())
- self.gconf.set_save_state(
- self.w_exit_checkbutton.get_active())
- self.gconf.set_show_image_update(
- self.w_confirm_updateall_checkbutton.get_active())
- self.gconf.set_show_install(
- self.w_confirm_install_checkbutton.get_active())
- self.gconf.set_show_remove(
- self.w_confirm_remove_checkbutton.get_active())
-
- def __on_preferenceshelp_clicked(self, widget):
- pagenum = self.w_preferences_notebook.get_current_page()
- if pagenum == PREFERENCES_NOTEBOOK_SIG_POL_PAGE:
- tag = "img-sig-policy"
- else:
- tag = "pkg-mgr-prefs"
- gui_misc.display_help(tag)
-
- def __on_languages_all_radiobutton_toggled(self, widget):
- self.w_locales_treeview.set_sensitive(
- not self.w_languages_all_radiobutton.get_active())
-
- def activate(self):
- self.w_startpage_checkbutton.set_active(
- self.gconf.show_startpage)
- self.w_exit_checkbutton.set_active(self.gconf.save_state)
- self.w_confirm_updateall_checkbutton.set_active(
- self.gconf.show_image_update)
- self.w_confirm_install_checkbutton.set_active(
- self.gconf.show_install)
- self.w_confirm_remove_checkbutton.set_active(
- self.gconf.show_remove)
- self.__setup_optional_components_tab(self.__api_get_facets())
- self.w_preferencesdialog.show()
-
--- a/src/gui/modules/progress.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-MIN_ELEMENTS_BOUNCE = 5 # During indexing the progress will be progressive if
- # the number of indexing elements is greater then this,
- # otherwise it will bounce
-
-from pkg.client.progress import NullProgressTracker
-
-class GuiProgressTracker(NullProgressTracker):
-
- def __init__(self, indent = False):
- NullProgressTracker.__init__(self)
- self.prev_pkg = None
- self.act_phase_last = None
- self.ind_started = False
- self.item_started = False
- self.indent = indent
-
- def cat_output_start(self):
- if self.indent:
- self.update_details_text(_("Retrieving catalog '%s'...\n") % \
- self.cat_cur_catalog, "level1")
- else:
- self.update_details_text(_("Retrieving catalog '%s'...\n") % \
- self.cat_cur_catalog)
- return
-
- def cat_output_done(self):
- return
-
- def cache_cats_output_start(self):
- if self.indent:
- self.update_details_text(_("Caching catalogs ...\n"), "level1")
- else:
- self.update_details_text(_("Caching catalogs ...\n"))
- return
-
- def cache_cats_output_done(self):
- return
-
- def load_cat_cache_output_start(self):
- if self.indent:
- self.update_details_text(_("Loading catalog cache ...\n"),
- "level1")
- else:
- self.update_details_text(_("Loading catalog cache ...\n"))
- return
-
- def load_cat_cache_output_done(self):
- return
-
- def refresh_output_start(self):
- return
-
- def refresh_output_progress(self):
- if self.indent:
- self.update_details_text(
- _("Refreshing catalog %s\n") % self.refresh_cur_pub, "level1")
- else:
- self.update_details_text(
- _("Refreshing catalog %s\n") % self.refresh_cur_pub)
- return
-
- def refresh_output_done(self):
- if self.indent:
- self.update_details_text(
- _("Finished refreshing catalog %s\n") % self.refresh_cur_pub,
- "level1")
- else:
- self.update_details_text(
- _("Finished refreshing catalog %s\n") % self.refresh_cur_pub)
- return
-
- def eval_output_start(self):
- return
-
- def eval_output_progress(self):
- '''Called by progress tracker each time some package was evaluated. The
- call is being done by calling progress tracker evaluate_progress()
- function'''
- if self.prev_pkg != self.eval_cur_fmri:
- self.prev_pkg = self.eval_cur_fmri
- text = _("Evaluating: %s") % self.eval_cur_fmri.get_name()
- self.update_label_text(text)
- self.reset_label_text_after_delay()
-
- def eval_output_done(self):
- return
-
- def ver_output(self):
- return
-
- def ver_output_error(self, actname, errors):
- return
-
- def ver_output_done(self):
- return
-
- def dl_output(self):
- self.display_download_info()
- if self.prev_pkg != self.cur_pkg:
- self.prev_pkg = self.cur_pkg
- self.update_details_text(
- _("Package %d of %d: %s\n") % (self.dl_cur_npkgs+1,
- self.dl_goal_npkgs, self.cur_pkg), "level1")
-
- def dl_output_done(self):
- self.update_details_text("\n")
-
- def act_output(self, force=False):
- if self.act_phase != self.act_phase_last:
- self.act_phase_last = self.act_phase
- self.update_label_text(self.act_phase)
- self.update_details_text("%s\n" % self.act_phase, "level1")
- self.display_phase_info(self.act_phase, self.act_cur_nactions,
- self.act_goal_nactions)
- return
-
- def act_output_done(self):
- return
-
- def ind_output(self, force=False):
- if self.ind_started != self.ind_phase:
- self.ind_started = self.ind_phase
- self.update_label_text(self.ind_phase)
- self.update_details_text(
- "%s\n" % (self.ind_phase), "level1")
- self.__indexing_progress()
-
- def ind_output_done(self):
- self.update_progress(self.ind_cur_nitems, self.ind_goal_nitems)
-
- def __indexing_progress(self):
- self.__generic_progress(self.ind_phase, self.ind_goal_nitems,
- self.ind_cur_nitems)
-
- def __generic_progress(self, phase, goal_nitems, cur_nitems):
- #It doesn't look nice if the progressive is just for few elements
- if goal_nitems > MIN_ELEMENTS_BOUNCE:
- self.display_phase_info(phase, cur_nitems-1, goal_nitems)
- else:
- if not self.is_progress_bouncing():
- self.start_bouncing_progress()
-
- def item_output(self, force=False):
- if self.item_started != self.item_phase:
- self.item_started = self.item_phase
- self.update_label_text(self.item_phase)
- self.update_details_text(
- "%s\n" % (self.item_phase), "level1")
- self.__item_progress()
-
- def __item_progress(self):
- self.__generic_progress(self.item_phase, self.item_goal_nitems,
- self.item_cur_nitems)
-
-
- def item_output_done(self):
- self.update_progress(self.item_cur_nitems, self.item_goal_nitems)
-
- def update_progress(self, current_progress, total_progress):
- raise NotImplementedError("abstract method update_progress() not "
- "implemented in superclass")
-
- def start_bouncing_progress(self):
- raise NotImplementedError("abstract method start_bouncing_progress() "
- "not implemented in superclass")
-
- def is_progress_bouncing(self):
- raise NotImplementedError("abstract method is_progress_bouncing() "
- "not implemented in superclass")
-
- def stop_bouncing_progress(self):
- raise NotImplementedError("abstract method stop_bouncing_progress() "
- "not implemented in superclass")
-
- def display_download_info(self):
- raise NotImplementedError("abstract method display_download_info() "
- "not implemented in superclass")
-
- def display_phase_info(self, phase_name, cur_n, goal_n):
- raise NotImplementedError("abstract method display_phase_info() "
- "not implemented in superclass")
-
- def reset_label_text_after_delay(self):
- raise NotImplementedError(
- "abstract method reset_label_text_after_delay() "
- "not implemented in superclass")
-
- def update_label_text(self, text):
- raise NotImplementedError("abstract method update_label_text() "
- "not implemented in superclass")
-
- def update_details_text(self, text, *tags):
- raise NotImplementedError("abstract method update_details_text() "
- "not implemented in superclass")
-
--- a/src/gui/modules/repository.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3018 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved.
-#
-
-MODIFY_DIALOG_WIDTH_DEFAULT = 580
-MODIFY_DIALOG_SSL_WIDTH_DEFAULT = 490
-
-MODIFY_NOTEBOOK_GENERAL_PAGE = 0
-MODIFY_NOTEBOOK_CERTIFICATE_PAGE = 1
-MODIFY_NOTEBOOK_SIG_POLICY_PAGE = 2
-
-PUBCERT_APPROVED_STR = _("Approved")
-PUBCERT_REVOKED_STR = _("Revoked")
-PUBCERT_NOTSET_HASH = "HASH-NOTSET" #No L10N required
-PUBCERT_NOTAVAILABLE = _("Not available")
-
-import sys
-import os
-import pango
-import datetime
-import tempfile
-import M2Crypto as m2
-import errno
-from threading import Thread
-from gettext import ngettext
-
-try:
- import gobject
- gobject.threads_init()
- import gtk
- import pygtk
- pygtk.require("2.0")
-except ImportError:
- sys.exit(1)
-
-import pkg.client.publisher as publisher
-import pkg.client.api_errors as api_errors
-import pkg.gui.enumerations as enumerations
-import pkg.gui.misc as gui_misc
-import pkg.gui.progress as progress
-from pkg.client import global_settings
-
-logger = global_settings.logger
-
-ERROR_FORMAT = "<span color = \"red\">%s</span>"
-
-class Repository(progress.GuiProgressTracker):
- def __init__(self, parent, image_directory, action = -1,
- webinstall_new = False, main_window = None, gconf = None):
- progress.GuiProgressTracker.__init__(self)
- self.parent = parent
- self.gconf = gconf
- self.action = action
- self.main_window = main_window
- self.api_o = gui_misc.get_api_object(image_directory,
- self, main_window)
- if self.api_o == None:
- return
- self.webinstall_new = webinstall_new
- self.progress_stop_thread = False
- self.repository_selection = None
- self.cancel_progress_thread = False
- self.cancel_function = None
- self.is_alias_valid = True
- self.is_url_valid = False
- self.new_pub = None
- self.priority_changes = []
- self.url_err = None
- self.name_error = None
- self.publisher_info = _("e.g. http://pkg.oracle.com/solaris/release")
- self.publishers_list = None
- self.repository_modify_publisher = None
- self.no_changes = 0
- self.pylintstub = None
- builder = gtk.Builder()
- builder.add_from_file(self.parent.gladefile)
- # Dialog reused in the beadmin.py
- self.w_confirmation_dialog = \
- builder.get_object("confirmationdialog")
- self.w_confirmation_label = \
- builder.get_object("confirm_label")
- self.w_confirmation_dialog.set_icon(self.parent.window_icon)
- self.w_confirmation_textview = \
- builder.get_object("confirmtext")
- self.w_confirm_cancel_btn = builder.get_object("cancel_conf")
- self.w_confirm_ok_btn = builder.get_object("ok_conf")
- confirmbuffer = self.w_confirmation_textview.get_buffer()
- confirmbuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
- self.w_confirmation_dialog.set_title(
- _("Manage Publishers Confirmation"))
- self.w_publishers_treeview = \
- builder.get_object("publishers_treeview")
- self.w_add_publisher_dialog = \
- builder.get_object("add_publisher")
- self.w_add_publisher_dialog.set_icon(self.parent.window_icon)
- self.w_add_error_label = \
- builder.get_object("add_error_label")
- self.w_add_sslerror_label = \
- builder.get_object("add_sslerror_label")
- self.w_publisher_add_button = \
- builder.get_object("add_button")
- self.w_publisher_add_cancel_button = \
- builder.get_object("add_publisher_cancel_button")
- self.w_ssl_box = \
- builder.get_object("ssl_box")
- self.w_add_publisher_alias = \
- builder.get_object("add_publisher_alias")
- self.w_add_pub_label = \
- builder.get_object("add_pub_label")
- self.w_add_pub_instr_label = \
- builder.get_object("add_pub_instr_label")
- self.w_add_publisher_url = \
- builder.get_object("add_publisher_url")
- self.w_cert_entry = \
- builder.get_object("certentry")
- self.w_key_entry = \
- builder.get_object("keyentry")
- self.w_certbrowse_button = \
- builder.get_object("certbrowse")
- self.w_keybrowse_button = \
- builder.get_object("keybrowse")
- self.w_add_pub_help_button = \
- builder.get_object("add_pub_help")
- self.w_publisher_add_button.set_sensitive(False)
- self.w_add_publisher_comp_dialog = \
- builder.get_object("add_publisher_complete")
- self.w_add_image = \
- builder.get_object("add_image")
- self.w_add_publisher_comp_dialog.set_icon(self.parent.window_icon)
- self.w_add_publisher_c_name = \
- builder.get_object("add_publisher_name_c")
- self.w_add_publisher_c_alias = \
- builder.get_object("add_publisher_alias_c")
- self.w_add_publisher_c_alias_l = \
- builder.get_object("add_publisher_alias_l")
- self.w_add_publisher_c_url = \
- builder.get_object("add_publisher_url_c")
- self.w_add_publisher_c_desc = \
- builder.get_object("add_publisher_desc_c")
- self.w_add_publisher_c_desc_l = \
- builder.get_object("add_publisher_desc_l")
- self.w_add_publisher_c_close = \
- builder.get_object("add_publisher_c_close")
- self.w_registration_box = \
- builder.get_object("add_registration_box")
- self.w_registration_link = \
- builder.get_object("registration_button")
- self.w_modify_repository_dialog = \
- builder.get_object("modify_repository")
- self.w_modify_repository_dialog.set_icon(self.parent.window_icon)
- self.w_modkeybrowse = \
- builder.get_object("modkeybrowse")
- self.w_modcertbrowse = \
- builder.get_object("modcertbrowse")
- self.w_addmirror_entry = \
- builder.get_object("addmirror_entry")
- self.w_addorigin_entry = \
- builder.get_object("add_repo")
- self.w_addmirror_button = \
- builder.get_object("addmirror_button")
- self.w_rmmirror_button = \
- builder.get_object("mirrorremove")
- self.w_addorigin_button = \
- builder.get_object("pub_add_repo")
- self.w_rmorigin_button = \
- builder.get_object("pub_remove_repo")
- self.w_modify_pub_alias = \
- builder.get_object("repositorymodifyalias")
- self.w_repositorymodifyok_button = \
- builder.get_object("repositorymodifyok")
- self.w_repositorymodifycancel_button = \
- builder.get_object("repositorymodifycancel")
- self.w_repositorymodifyhelp_button = \
- builder.get_object("modify_repo_help")
- self.modify_repo_mirrors_treeview = \
- builder.get_object("modify_repo_mirrors_treeview")
- self.modify_repo_origins_treeview = \
- builder.get_object("modify_pub_repos_treeview")
- self.w_modmirrerror_label = \
- builder.get_object("modmirrerror_label")
- self.w_modoriginerror_label = \
- builder.get_object("modrepoerror_label")
- self.w_modsslerror_label = \
- builder.get_object("modsslerror_label")
- self.w_repositorymodify_name = \
- builder.get_object("repository_name_label")
- self.w_repositorymodify_registration_link = \
- builder.get_object(
- "repositorymodifyregistrationlinkbutton")
- self.w_repositorymirror_expander = \
- builder.get_object(
- "repositorymodifymirrorsexpander")
- self.w_repositorymodify_registration_box = \
- builder.get_object("modify_registration_box")
- self.w_repositorymodify_key_entry = \
- builder.get_object("modkeyentry")
- self.w_repositorymodify_cert_entry = \
- builder.get_object("modcertentry")
- self.w_manage_publishers_dialog = \
- builder.get_object("manage_publishers")
- self.w_manage_publishers_dialog.set_icon(self.parent.window_icon)
- self.w_manage_publishers_details = \
- builder.get_object("manage_publishers_details")
- self.w_manage_publishers_details.set_wrap_mode(gtk.WRAP_WORD)
- manage_pub_details_buf = self.w_manage_publishers_details.get_buffer()
- manage_pub_details_buf.create_tag("level0", weight=pango.WEIGHT_BOLD)
- self.w_manage_add_btn = builder.get_object("manage_add")
- self.w_manage_ok_btn = builder.get_object("manage_ok")
- self.w_manage_remove_btn = builder.get_object("manage_remove")
- self.w_manage_modify_btn = \
- builder.get_object("manage_modify")
- self.w_manage_up_btn = \
- builder.get_object("manage_move_up")
- self.w_manage_down_btn = \
- builder.get_object("manage_move_down")
- self.w_manage_cancel_btn = \
- builder.get_object("manage_cancel")
- self.w_manage_help_btn = \
- builder.get_object("manage_help")
-
- self.publishers_apply = \
- builder.get_object("publishers_apply")
- self.publishers_apply.set_icon(self.parent.window_icon)
- self.publishers_apply_expander = \
- builder.get_object("apply_expander")
- self.publishers_apply_textview = \
- builder.get_object("apply_textview")
- applybuffer = self.publishers_apply_textview.get_buffer()
- applybuffer.create_tag("level1", left_margin=30, right_margin=10)
- self.publishers_apply_cancel = \
- builder.get_object("apply_cancel")
- self.publishers_apply_progress = \
- builder.get_object("publishers_apply_progress")
-
- self.w_modify_alias_error_label = builder.get_object(
- "mod_alias_error_label")
- self.w_pub_cert_treeview = \
- builder.get_object("pub_certificate_treeview")
- self.w_modify_pub_notebook = builder.get_object(
- "modify_pub_notebook")
- self.w_pub_cert_details_textview = builder.get_object(
- "pub_certificate_details_textview")
- manage_pub_cert_details_buf = \
- self.w_pub_cert_details_textview.get_buffer()
- manage_pub_cert_details_buf.create_tag("level0",
- weight=pango.WEIGHT_BOLD)
- manage_pub_cert_details_buf.create_tag("bold",
- weight=pango.WEIGHT_BOLD)
- manage_pub_cert_details_buf.create_tag("normal",
- weight=pango.WEIGHT_NORMAL)
- self.w_pub_cert_label = \
- builder.get_object("mods_pub_label")
- self.w_pub_cert_add_btn = builder.get_object(
- "pub_certificate_add_button")
- self.w_pub_cert_remove_btn = builder.get_object(
- "pub_certificate_remove_button")
- self.w_pub_cert_revoke_btn = builder.get_object(
- "pub_certificate_revoke_button")
- self.w_pub_cert_reinstate_btn = builder.get_object(
- "pub_certificate_reinstate_button")
-
-
- self.w_pub_sig_ignored_radiobutton = builder.get_object(
- "sig_ignored_radiobutton")
- self.w_pub_sig_optional_radiobutton = builder.get_object(
- "sig_optional_but_valid_radiobutton")
- self.w_pub_sig_valid_radiobutton = builder.get_object(
- "sig_valid_radiobutton")
- self.w_pub_sig_name_radiobutton = builder.get_object(
- "sig_name_radiobutton")
- self.w_pub_sig_name_entry = builder.get_object(
- "sig_name_entry")
- self.w_pub_sig_view_globpol_button = builder.get_object(
- "sig_view_globpol_button")
- self.w_pub_sig_cert_names_vbox = builder.get_object(
- "sig_cert_names_vbox")
-
- checkmark_icon = gui_misc.get_icon(
- self.parent.icon_theme, "pm-check", 24)
-
- self.w_add_image.set_from_pixbuf(checkmark_icon)
-
- self.__setup_signals()
-
- self.publishers_list = self.__get_publishers_liststore()
- self.__init_pubs_tree_view(self.publishers_list)
- self.__init_mirrors_tree_view(self.modify_repo_mirrors_treeview)
- self.__init_origins_tree_view(self.modify_repo_origins_treeview)
-
- self.pub_cert_list = self.__get_pub_cert_liststore()
- self.orig_pub_cert_added_dict = {} # Orig Pub Certs added to model:
- # - key/val: [ips-hash] = status
- self.all_pub_cert_added_dict = {} # New/ Orig Pub Certs added to model
- # - key/val: [sha-hash] = ips-hash
- self.removed_orig_pub_cert_dict = {}# Removed Orig Pub Certs from model
- # - key/val: [sha-hash] = ips-hash
- self.orig_sig_policy = {}
- self.pub_certs_setup = False
-
- if self.action == enumerations.ADD_PUBLISHER:
- gui_misc.set_modal_and_transient(self.w_add_publisher_dialog,
- self.main_window)
- self.__on_manage_add_clicked(None)
- return
- elif self.action == enumerations.MANAGE_PUBLISHERS:
- gui_misc.set_modal_and_transient(self.w_manage_publishers_dialog,
- self.main_window)
- gui_misc.set_modal_and_transient(self.w_confirmation_dialog,
- self.w_manage_publishers_dialog)
- self.__prepare_publisher_list()
- publisher_selection = self.w_publishers_treeview.get_selection()
- publisher_selection.set_mode(gtk.SELECTION_SINGLE)
- publisher_selection.connect("changed",
- self.__on_publisher_selection_changed, None)
- mirrors_selection = \
- self.modify_repo_mirrors_treeview.get_selection()
- mirrors_selection.set_mode(gtk.SELECTION_SINGLE)
- mirrors_selection.connect("changed",
- self.__on_mirror_selection_changed, None)
- origins_selection = \
- self.modify_repo_origins_treeview.get_selection()
- origins_selection.set_mode(gtk.SELECTION_SINGLE)
- origins_selection.connect("changed",
- self.__on_origin_selection_changed, None)
-
- gui_misc.set_modal_and_transient(self.w_add_publisher_dialog,
- self.w_manage_publishers_dialog)
- self.__init_pub_cert_tree_view(self.pub_cert_list)
- self.w_manage_publishers_dialog.show_all()
- return
-
-
- def __setup_signals(self):
- signals_table = [
- (self.w_add_publisher_dialog, "delete_event",
- self.__on_add_publisher_delete_event),
- (self.w_add_publisher_url, "changed",
- self.__on_publisherurl_changed),
- (self.w_add_publisher_url, "activate",
- self.__on_add_publisher_add_clicked),
- (self.w_add_publisher_alias, "changed",
- self.__on_publisheralias_changed),
- (self.w_add_publisher_alias, "activate",
- self.__on_add_publisher_add_clicked),
- (self.w_publisher_add_button, "clicked",
- self.__on_add_publisher_add_clicked),
- (self.w_key_entry, "changed", self.__on_keyentry_changed),
- (self.w_cert_entry, "changed", self.__on_certentry_changed),
- (self.w_publisher_add_cancel_button, "clicked",
- self.__on_add_publisher_cancel_clicked),
- (self.w_keybrowse_button, "clicked",
- self.__on_keybrowse_clicked),
- (self.w_certbrowse_button, "clicked",
- self.__on_certbrowse_clicked),
- (self.w_add_pub_help_button, "clicked",
- self.__on_add_pub_help_clicked),
-
- (self.w_add_publisher_comp_dialog, "delete_event",
- self.__on_add_publisher_complete_delete_event),
- (self.w_add_publisher_c_close, "clicked",
- self.__on_add_publisher_c_close_clicked),
-
- (self.w_manage_publishers_dialog, "delete_event",
- self.__on_manage_publishers_delete_event),
- (self.w_manage_add_btn, "clicked",
- self.__on_manage_add_clicked),
- (self.w_manage_modify_btn, "clicked",
- self.__on_manage_modify_clicked),
- (self.w_manage_remove_btn, "clicked",
- self.__on_manage_remove_clicked),
- (self.w_manage_up_btn, "clicked",
- self.__on_manage_move_up_clicked),
- (self.w_manage_down_btn, "clicked",
- self.__on_manage_move_down_clicked),
- (self.w_manage_cancel_btn, "clicked",
- self.__on_manage_cancel_clicked),
- (self.w_manage_ok_btn, "clicked",
- self.__on_manage_ok_clicked),
- (self.w_manage_help_btn, "clicked",
- self.__on_manage_help_clicked),
-
- (self.w_modify_repository_dialog, "delete_event",
- self.__on_modifydialog_delete_event),
- (self.w_modify_pub_alias, "changed",
- self.__on_modify_pub_alias_changed),
- (self.w_modkeybrowse, "clicked",
- self.__on_modkeybrowse_clicked),
- (self.w_modcertbrowse, "clicked",
- self.__on_modcertbrowse_clicked),
- (self.w_addmirror_entry, "changed",
- self.__on_addmirror_entry_changed),
- (self.w_addorigin_entry, "changed",
- self.__on_addorigin_entry_changed),
- (self.w_addmirror_button, "clicked",
- self.__on_addmirror_button_clicked),
- (self.w_addorigin_button, "clicked",
- self.__on_addorigin_button_clicked),
- (self.w_rmmirror_button, "clicked",
- self.__on_rmmirror_button_clicked),
- (self.w_rmorigin_button, "clicked",
- self.__on_rmorigin_button_clicked),
- (self.w_repositorymodify_key_entry, "changed",
- self.__on_modcertkeyentry_changed),
- (self.w_repositorymodify_cert_entry, "changed",
- self.__on_modcertkeyentry_changed),
- (self.w_repositorymodifyok_button, "clicked",
- self.__on_repositorymodifyok_clicked),
- (self.w_repositorymodifycancel_button, "clicked",
- self.__on_repositorymodifycancel_clicked),
- (self.w_repositorymodifyhelp_button, "clicked",
- self.__on_modify_repo_help_clicked),
-
- (self.w_confirmation_dialog, "delete_event",
- self.__delete_widget_handler_hide),
- (self.w_confirm_cancel_btn, "clicked",
- self.__on_cancel_conf_clicked),
- (self.w_confirm_ok_btn, "clicked",
- self.__on_ok_conf_clicked),
-
- (self.publishers_apply, "delete_event",
- self.__on_publishers_apply_delete_event),
- (self.publishers_apply_cancel, "clicked",
- self.__on_apply_cancel_clicked),
-
- (self.w_pub_cert_add_btn, "clicked",
- self.__on_pub_cert_add_clicked),
- (self.w_pub_cert_remove_btn, "clicked",
- self.__on_pub_cert_remove_clicked),
- (self.w_pub_cert_revoke_btn, "clicked",
- self.__on_pub_cert_revoke_clicked),
- (self.w_pub_cert_reinstate_btn, "clicked",
- self.__on_pub_cert_reinstate_clicked),
- (self.w_modify_pub_notebook, "switch_page",
- self.__on_notebook_change),
-
- (self.w_pub_sig_ignored_radiobutton, "toggled",
- self.__on_pub_sig_radiobutton_toggled),
- (self.w_pub_sig_optional_radiobutton, "toggled",
- self.__on_pub_sig_radiobutton_toggled),
- (self.w_pub_sig_valid_radiobutton, "toggled",
- self.__on_pub_sig_radiobutton_toggled),
- (self.w_pub_sig_name_radiobutton, "toggled",
- self.__on_pub_sig_radiobutton_toggled),
- (self.w_pub_sig_view_globpol_button, "clicked",
- self.__on_pub_sig_view_globpol_clicked),
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def __on_pub_sig_radiobutton_toggled(self, widget):
- self.w_pub_sig_cert_names_vbox.set_sensitive(
- self.w_pub_sig_name_radiobutton.get_active())
-
- def __on_pub_sig_view_globpol_clicked(self, widget):
- #Preferences Dialog is modal so no need to hide the Modify Dialog
- self.parent.preferences.show_signature_policy()
-
- def __update_pub_sig_policy_prop(self, set_props):
- errors = []
- try:
- pub = self.repository_modify_publisher
- if pub != None:
- pub.update_props(set_props=set_props)
- except api_errors.ApiException, e:
- errors.append(("", e))
- return errors
-
- def __update_pub_sig_policy(self):
- errors = []
- orig = self.orig_sig_policy
- if not orig:
- return errors
- ignore = self.w_pub_sig_ignored_radiobutton.get_active()
- verify = self.w_pub_sig_optional_radiobutton.get_active()
- req_sigs = self.w_pub_sig_valid_radiobutton.get_active()
- req_names = self.w_pub_sig_name_radiobutton.get_active()
- names = gui_misc.fetch_signature_policy_names_from_textfield(
- self.w_pub_sig_name_entry.get_text())
- set_props = gui_misc.setup_signature_policy_properties(ignore,
- verify, req_sigs, req_names, names, orig)
- if len(set_props) > 0:
- errors = self.__update_pub_sig_policy_prop(set_props)
- return errors
-
- def __prepare_pub_signature_policy(self):
- if self.orig_sig_policy:
- return
-
- sig_policy = self.__fetch_pub_signature_policy()
- self.orig_sig_policy = sig_policy
- self.w_pub_sig_ignored_radiobutton.set_active(
- sig_policy[gui_misc.SIG_POLICY_IGNORE])
- self.w_pub_sig_optional_radiobutton.set_active(
- sig_policy[gui_misc.SIG_POLICY_VERIFY])
- self.w_pub_sig_valid_radiobutton.set_active(
- sig_policy[gui_misc.SIG_POLICY_REQUIRE_SIGNATURES])
- self.w_pub_sig_cert_names_vbox.set_sensitive(False)
-
- if sig_policy[gui_misc.SIG_POLICY_REQUIRE_NAMES]:
- self.w_pub_sig_name_radiobutton.set_active(True)
- self.w_pub_sig_cert_names_vbox.set_sensitive(True)
-
- names = sig_policy[gui_misc.PROP_SIGNATURE_REQUIRED_NAMES]
- gui_misc.set_signature_policy_names_for_textfield(
- self.w_pub_sig_name_entry, names)
-
- def __fetch_pub_signature_policy(self):
- pub = self.repository_modify_publisher
- prop_sig_pol = pub.signature_policy.name
- prop_sig_req_names = None
- if gui_misc.PROP_SIGNATURE_REQUIRED_NAMES in pub.properties:
- prop_sig_req_names = \
- pub.properties[gui_misc.PROP_SIGNATURE_REQUIRED_NAMES]
- return gui_misc.create_sig_policy_from_property(
- prop_sig_pol, prop_sig_req_names)
-
- def __on_notebook_change(self, widget, event, pagenum):
- if pagenum == MODIFY_NOTEBOOK_CERTIFICATE_PAGE:
- gobject.idle_add(self.__prepare_pub_certs)
- elif pagenum == MODIFY_NOTEBOOK_SIG_POLICY_PAGE:
- gobject.idle_add(self.__prepare_pub_signature_policy)
-
- @staticmethod
- def __get_pub_cert_liststore():
- return gtk.ListStore(
- gobject.TYPE_STRING, # enumerations.PUBCERT_ORGANIZATION
- gobject.TYPE_STRING, # enumerations.PUBCERT_NAME
- gobject.TYPE_STRING, # enumerations.PUBCERT_STATUS
- gobject.TYPE_STRING, # enumerations.PUBCERT_IPSHASH
- gobject.TYPE_STRING, # enumerations.PUBCERT_PATH
- gobject.TYPE_PYOBJECT, # enumerations.PUBCERT_XCERT_OBJ
- gobject.TYPE_BOOLEAN, # enumerations.PUBCERT_NEW
- )
-
- @staticmethod
- def __sort_func(treemodel, iter1, iter2, column):
- col_val1 = treemodel.get_value(iter1, column)
- col_val2 = treemodel.get_value(iter2, column)
- ret = cmp(col_val1, col_val2)
- if ret != 0:
- return ret
- if column == enumerations.PUBCERT_ORGANIZATION:
- name1 = treemodel.get_value(iter1,
- enumerations.PUBCERT_NAME)
- name2 = treemodel.get_value(iter2,
- enumerations.PUBCERT_NAME)
- ret = cmp(name1, name2)
- elif column == enumerations.PUBCERT_NAME:
- org1 = treemodel.get_value(iter1,
- enumerations.PUBCERT_ORGANIZATION)
- org2 = treemodel.get_value(iter2,
- enumerations.PUBCERT_ORGANIZATION)
- ret = cmp(org1, org2)
- return ret
-
- def __init_pub_cert_tree_view(self, pub_cert_list):
- pub_cert_sort_model = gtk.TreeModelSort(pub_cert_list)
- pub_cert_sort_model.set_sort_column_id(enumerations.PUBCERT_ORGANIZATION,
- gtk.SORT_ASCENDING)
-
- pub_cert_sort_model.set_sort_func(enumerations.PUBCERT_ORGANIZATION,
- self.__sort_func,
- enumerations.PUBCERT_ORGANIZATION)
- pub_cert_sort_model.set_sort_func(enumerations.PUBCERT_NAME,
- self.__sort_func,
- enumerations.PUBCERT_NAME)
-
- # Organization column - sort using custom __sort_func()
- org_renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_("Organization"),
- org_renderer, text = enumerations.PUBCERT_ORGANIZATION)
- column.set_expand(False)
- column.set_sort_column_id(enumerations.PUBCERT_ORGANIZATION)
- column.set_sort_indicator(True)
- column.set_resizable(True)
- self.w_pub_cert_treeview.append_column(column)
-
- # Name column - sort using custom __sort_func()
- name_renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_("Name"),
- name_renderer, text = enumerations.PUBCERT_NAME)
- column.set_expand(True)
- column.set_sort_column_id(enumerations.PUBCERT_NAME)
- column.set_sort_indicator(True)
- column.set_resizable(True)
- self.w_pub_cert_treeview.append_column(column)
-
- # Status column
- status_renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_("Status"),
- status_renderer, text = enumerations.PUBCERT_STATUS)
- column.set_expand(False)
- column.set_sort_column_id(enumerations.PUBCERT_STATUS)
- self.w_pub_cert_treeview.append_column(column)
-
- self.w_pub_cert_treeview.get_selection().connect('changed',
- self.__on_pub_cert_treeview_changed)
- self.w_pub_cert_treeview.set_model(pub_cert_sort_model)
-
- @staticmethod
- def __get_pub_display_name(pub):
- display_name = ""
- if not pub:
- return display_name
-
- name = pub.prefix
- alias = pub.alias
- use_name = False
- use_alias = False
- if len(name) > 0:
- use_name = True
- if alias and len(alias) > 0 and alias != name:
- use_alias = True
-
- if use_name and not use_alias:
- display_name = name
- elif use_name and use_alias:
- display_name = "%s (%s)" % (name, alias)
- return display_name
-
- def __prepare_pub_certs(self):
- if self.pub_certs_setup:
- return
-
- pub = self.repository_modify_publisher
- if not pub:
- return
- sorted_model = self.w_pub_cert_treeview.get_model()
- selection = self.w_pub_cert_treeview.get_selection()
- selected_rows = selection.get_selected_rows()
- self.w_pub_cert_treeview.set_model(None)
- if not sorted_model:
- return
- model = sorted_model.get_model()
- if not model:
- return
- model.clear()
-
- self.orig_pub_cert_added_dict.clear()
- self.all_pub_cert_added_dict.clear()
- self.removed_orig_pub_cert_dict.clear()
-
- pub_display_name = self.__get_pub_display_name(pub)
- if pub_display_name != "":
- self.w_pub_cert_label.set_markup(
- _("<b>Certificates for publisher %s</b>") % pub_display_name)
- else:
- self.w_pub_cert_label.set_markup(
- _("<b>Publisher certificates</b>"))
-
- for h in pub.approved_ca_certs:
- self.__add_cert_to_model(model,
- pub.get_cert_by_hash(h), h, PUBCERT_APPROVED_STR)
- for h in pub.revoked_ca_certs:
- self.__add_cert_to_model(model,
- pub.get_cert_by_hash(h), h, PUBCERT_REVOKED_STR)
-
- self.w_pub_cert_treeview.set_model(sorted_model)
- if len(pub.revoked_ca_certs) == 0 and len(pub.approved_ca_certs) == 0:
- self.__set_empty_pub_cert()
- self.pub_certs_setup = True
- return
-
- sel_path = (0,)
- if len(selected_rows) > 1 and len(selected_rows[1]) > 0:
- sel_path = selected_rows[1][0]
- self.__set_pub_cert_selection(sorted_model, sel_path)
- self.pub_certs_setup = True
-
- def __add_cert_to_model(self, model, cert, ips_hash, status, path = "",
- scroll_to=False, new=False):
- pub = self.repository_modify_publisher
- if not cert or not pub:
- return
- i = cert.get_subject()
- organization = PUBCERT_NOTAVAILABLE
- if len(i.get_entries_by_nid(i.nid["O"])) > 0:
- organization = i.get_entries_by_nid(
- i.nid["O"])[0].get_data().as_text()
- name = PUBCERT_NOTAVAILABLE
- if len(i.get_entries_by_nid(i.nid["CN"])) > 0:
- name = i.get_entries_by_nid(
- i.nid["CN"])[0].get_data().as_text()
- if self.all_pub_cert_added_dict.has_key(cert.get_fingerprint('sha1')):
- err = _("The publisher certificate:\n %s\n"
- "has already been added.") % \
- self.__get_cert_display_name(cert)
- gui_misc.error_occurred(None, err,
- _("Modify Publisher - %s") % self.__get_pub_display_name(pub),
- gtk.MESSAGE_INFO)
- return
-
- self.all_pub_cert_added_dict[cert.get_fingerprint('sha1')] = ips_hash
- itr = model.append(
- [organization, name, status, ips_hash, path, cert, new])
- if not new:
- self.orig_pub_cert_added_dict[ips_hash] = status
-
- if scroll_to:
- path = model.get_path(itr)
- sorted_model = self.w_pub_cert_treeview.get_model()
- if not sorted_model:
- return
- sorted_path = sorted_model.convert_child_path_to_path(path)
- self.w_pub_cert_treeview.scroll_to_cell(sorted_path)
- selection = self.w_pub_cert_treeview.get_selection()
- selection.select_path(sorted_path)
-
- def __on_pub_cert_treeview_changed(self, treeselection):
- selection = treeselection.get_selected_rows()
- pathlist = selection[1]
- if not pathlist or len(pathlist) == 0:
- return
- sorted_model = self.w_pub_cert_treeview.get_model()
- if not sorted_model:
- return
- model = sorted_model.get_model()
- path = pathlist[0]
- child_path = sorted_model.convert_path_to_child_path(path)
- self.__enable_disable_pub_cert_buttons(model, child_path)
- self.__set_pub_cert_details(model, child_path)
-
- def __enable_disable_pub_cert_buttons(self, model, path):
- if not model or not path:
- return
- itr = model.get_iter(path)
- status = model.get_value(itr, enumerations.PUBCERT_STATUS)
- new = model.get_value(itr, enumerations.PUBCERT_NEW)
-
- if status == PUBCERT_APPROVED_STR:
- self.w_pub_cert_revoke_btn.set_sensitive(True)
- self.w_pub_cert_reinstate_btn.set_sensitive(False)
- else:
- self.w_pub_cert_revoke_btn.set_sensitive(False)
- self.w_pub_cert_reinstate_btn.set_sensitive(True)
- if new:
- self.w_pub_cert_revoke_btn.set_sensitive(False)
- self.w_pub_cert_reinstate_btn.set_sensitive(False)
- self.w_pub_cert_remove_btn.set_sensitive(True)
-
- def __set_pub_cert_details(self, model, path):
- itr = model.get_iter(path)
- ips_hash = model.get_value(itr, enumerations.PUBCERT_IPSHASH)
- cert = model.get_value(itr, enumerations.PUBCERT_XCERT_OBJ)
- new = model.get_value(itr, enumerations.PUBCERT_NEW)
- if not cert:
- return
- details_buffer = self.w_pub_cert_details_textview.get_buffer()
- details_buffer.set_text("")
- itr = details_buffer.get_end_iter()
-
- labs = {}
- labs["issued_to"] = _("Issued To:")
- labs["common_name_to"] = gui_misc.PUBCERT_COMMON_NAME
- labs["org_to"] = gui_misc.PUBCERT_ORGANIZATION
- labs["org_unit_to"] = gui_misc.PUBCERT_ORGANIZATIONAL_UNIT
- labs["issued_by"] = _("Issued By:")
- labs["common_name_by"] = _(" Common Name (CN):")
- labs["org_by"] = gui_misc.PUBCERT_ORGANIZATION
- labs["org_unit_by"] = gui_misc.PUBCERT_ORGANIZATIONAL_UNIT
- labs["validity"] = _("Validity:")
- labs["issued_on"] = _(" Issued On:")
- labs["fingerprints"] = _("Fingerprints:")
- labs["sha1"] = _(" SHA1:")
- labs["md5"] = _(" MD5:")
- labs["ips"] = _(" IPS:")
-
- text = {}
- text["issued_to"] = ""
- text["common_name_to"] = ""
- text["org_to"] = ""
- text["org_unit_to"] = ""
- text["issued_by"] = ""
- text["common_name_by"] = ""
- text["org_by"] = ""
- text["org_unit_by"] = ""
- text["validity"] = ""
- text["issued_on"] = ""
- text["fingerprints"] = ""
- text["sha1"] = ""
- text["md5"] = ""
- text["ips"] = ""
-
- self._set_cert_issuer(text, cert.get_subject(), "to")
- self._set_cert_issuer(text, cert.get_issuer(), "by")
-
- eo = cert.get_not_after().get_datetime().date().isoformat()
- today = datetime.datetime.today().date().isoformat()
- validity_str = _("Validity:")
- #TBD: may have an issue here in some locales if Validity string
- #is very long then would only need one \t.
- if eo < today:
- validity_str += _("\t\t EXPIRED")
- labs["validity"] = validity_str
-
- io_str = cert.get_not_before().get_datetime().date().strftime("%x")
- eo_str = cert.get_not_after().get_datetime().date().strftime("%x")
- labs["issued_on"] += " " + io_str
- text["issued_on"] = _("Expires On: %s") % eo_str
-
- sha = cert.get_fingerprint('sha1')
- md5 = cert.get_fingerprint('md5')
- text["sha1"] = sha.lower()
- text["md5"] = md5.lower()
- text["ips"] = ips_hash.lower()
-
- added = False
- reinstated = False
- if new:
- if ips_hash == PUBCERT_NOTSET_HASH:
- added = True
- reinstated = False
- else:
- reinstated = True
- added = False
-
- gui_misc.set_pub_cert_details_text(labs, text,
- self.w_pub_cert_details_textview, added, reinstated)
-
- @staticmethod
- def _set_cert_issuer(text, issuer, itype):
- if len(issuer.get_entries_by_nid(issuer.nid["CN"])) > 0:
- text["common_name_" + itype] = issuer.get_entries_by_nid(
- issuer.nid["CN"])[0].get_data().as_text()
- if len(issuer.get_entries_by_nid(issuer.nid["O"])) > 0:
- text["org_" + itype] = issuer.get_entries_by_nid(
- issuer.nid["O"])[0].get_data().as_text()
- if len(issuer.get_entries_by_nid(issuer.nid["OU"])) > 0:
- text["org_unit_" + itype] = issuer.get_entries_by_nid(
- issuer.nid["OU"])[0].get_data().as_text()
- else:
- text["org_unit_" + itype] = PUBCERT_NOTAVAILABLE
-
- def __get_pub_cert_filename(self, title, path = None):
- if path == None or path == "":
- path = tempfile.gettempdir()
- filename = None
- chooser = gtk.FileChooserDialog(title,
- self.w_manage_publishers_dialog,
- gtk.FILE_CHOOSER_ACTION_OPEN,
- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_OK, gtk.RESPONSE_OK))
-
- file_filter = gtk.FileFilter()
- file_filter.set_name(_("Certificate Files"))
- file_filter.add_pattern("*.pem")
- chooser.add_filter(file_filter)
- chooser.set_current_folder(path)
-
- response = chooser.run()
- if response == gtk.RESPONSE_OK:
- filename = chooser.get_filename()
- chooser.destroy()
-
- if filename != None:
- info = os.path.split(filename)
- self.gconf.last_add_pubcert_path = info[0]
- return filename
-
- def __on_pub_cert_add_clicked(self, widget):
- filename = self.__get_pub_cert_filename(
- _("Add Publisher Certificate"),
- self.gconf.last_add_pubcert_path)
- if filename == None:
- return
- try:
- cert = self.__get_new_cert(filename)
- sha = cert.get_fingerprint('sha1')
- ips_hash = PUBCERT_NOTSET_HASH
- status = PUBCERT_APPROVED_STR
- new = True
- #Restore orig cert if it was already added but just removed
- if self.removed_orig_pub_cert_dict.has_key(sha):
- ips_hash = self.removed_orig_pub_cert_dict[sha]
- status = self.orig_pub_cert_added_dict[ips_hash]
- filename = ""
- new = False
- del self.removed_orig_pub_cert_dict[sha]
- sorted_model = self.w_pub_cert_treeview.get_model()
- if not sorted_model:
- return
- model = sorted_model.get_model()
- self.__add_cert_to_model(model, cert, ips_hash, status,
- path=filename, scroll_to=True, new=new)
- except api_errors.ApiException, e:
- self.__show_errors([("", e)])
- return
-
- @staticmethod
- def __get_new_cert(filename):
- cert = None
- try:
- with open(filename, "rb") as fh:
- s = fh.read()
- except EnvironmentError, e:
- if e.errno == errno.ENOENT:
- raise api_errors.MissingFileArgumentException(
- filename)
- elif e.errno == errno.EACCES:
- raise api_errors.PermissionsException(
- filename)
- raise api_errors.ApiException(e)
- try:
- cert = m2.X509.load_cert_string(s)
- except m2.X509.X509Error, e:
- raise api_errors.BadFileFormat(_("The file:\n"
- " %s\nwas expected to be a PEM certificate but it "
- "could not be read.") % filename)
- return cert
-
- def __on_pub_cert_reinstate_clicked(self, widget):
- itr, sorted_model = self.__get_selected_pub_cert_itr_model()
- if not itr or not sorted_model:
- return
- model = sorted_model.get_model()
- child_itr = sorted_model.convert_iter_to_child_iter(None, itr)
-
- ips_hash = model.get_value(child_itr, enumerations.PUBCERT_IPSHASH)
- orig_status = ""
- if self.orig_pub_cert_added_dict.has_key(ips_hash):
- orig_status = self.orig_pub_cert_added_dict[ips_hash]
- else:
- #Should not be able to reinstate new cert, only existing ones
- return
- #Originally approved so just reset as there is nothing to do
- if orig_status == PUBCERT_APPROVED_STR:
- model.set_value(child_itr,
- enumerations.PUBCERT_STATUS,
- PUBCERT_APPROVED_STR)
- self.__set_pub_cert_details(model,
- model.get_path(child_itr))
- self.__enable_disable_pub_cert_buttons(model,
- model.get_path(child_itr))
- return
-
- filename = self.__get_pub_cert_filename(
- _("Reinstate Publisher Certificate"),
- self.gconf.last_add_pubcert_path)
- if filename == None:
- return
-
- #Check the old cert and new ones match according to the sha fingerprint
- cert = model.get_value(child_itr, enumerations.PUBCERT_XCERT_OBJ)
- new_cert = self.__get_new_cert(filename)
- if cert == None or new_cert == None:
- #Must have exisitng cert and new one to reinstate
- return
- orig_sha = cert.get_fingerprint('sha1')
- new_sha = new_cert.get_fingerprint('sha1')
- if orig_sha != new_sha:
- pub = self.repository_modify_publisher
- if not pub:
- return
- gui_misc.error_occurred(None,
- _("To reinstate the publisher certificate:\n %s\n"
- "the original certificate file must be selected.") %
- self.__get_cert_display_name(cert),
- _("Modify Publisher - %s") % self.__get_pub_display_name(pub),
- gtk.MESSAGE_INFO)
- return
- #Update model of existing cert which is to be reinstated by
- #re-adding the cert as new
- model.set_value(child_itr, enumerations.PUBCERT_STATUS,
- PUBCERT_APPROVED_STR)
- model.set_value(child_itr, enumerations.PUBCERT_PATH, filename)
- model.set_value(child_itr, enumerations.PUBCERT_XCERT_OBJ, new_cert)
- model.set_value(child_itr, enumerations.PUBCERT_NEW, True)
- self.__set_pub_cert_details(model, model.get_path(child_itr))
- self.__enable_disable_pub_cert_buttons(model,
- model.get_path(child_itr))
-
- @staticmethod
- def __get_cert_display_name(cert):
- cert_display_name = ""
- if cert == None:
- return cert_display_name
- issuer = cert.get_subject()
- cn = "-"
- org = "-"
- ou = "-"
- if len(issuer.get_entries_by_nid(issuer.nid["CN"])) > 0:
- cn = issuer.get_entries_by_nid(
- issuer.nid["CN"])[0].get_data().as_text()
- if len(issuer.get_entries_by_nid(issuer.nid["O"])) > 0:
- org = issuer.get_entries_by_nid(
- issuer.nid["O"])[0].get_data().as_text()
- if len(issuer.get_entries_by_nid(issuer.nid["OU"])) > 0:
- ou = issuer.get_entries_by_nid(
- issuer.nid["OU"])[0].get_data().as_text()
- else:
- ou = PUBCERT_NOTAVAILABLE
-
- if ou != PUBCERT_NOTAVAILABLE:
- cert_display_name = \
- "%s (CN) %s (O) %s (OU)" % (cn, org, ou) #No l10n required
- else:
- cert_display_name = "%s (CN) %s (O)" % (cn, org)#No l10n required
- return cert_display_name
-
- def __on_pub_cert_revoke_clicked(self, widget):
- selection = self.w_pub_cert_treeview.get_selection()
- if not selection:
- return
- selected_rows = selection.get_selected_rows()
- if not selected_rows or len(selected_rows) < 2:
- return
- pathlist = selected_rows[1]
- if not pathlist or len(pathlist) == 0:
- return
- path = pathlist[0]
- self.__revoked(None, path)
-
-
- def __revoked(self, cell, sorted_path):
- sorted_model = self.w_pub_cert_treeview.get_model()
- if not sorted_model:
- return
- model = sorted_model.get_model()
- path = sorted_model.convert_path_to_child_path(sorted_path)
- itr = model.get_iter(path)
- if not itr:
- return
- status = model.get_value(itr, enumerations.PUBCERT_STATUS)
- if status == PUBCERT_APPROVED_STR:
- model.set_value(itr, enumerations.PUBCERT_STATUS,
- PUBCERT_REVOKED_STR)
- self.__enable_disable_pub_cert_buttons(model, path)
- self.__set_pub_cert_details(model, path)
-
- def __on_pub_cert_remove_clicked(self, widget):
- itr, sorted_model = self.__get_selected_pub_cert_itr_model()
- if not itr or not sorted_model:
- return
- sel_path = sorted_model.get_path(itr)
- model = sorted_model.get_model()
- child_itr = sorted_model.convert_iter_to_child_iter(None, itr)
-
- cert = model.get_value(child_itr, enumerations.PUBCERT_XCERT_OBJ)
- if self.all_pub_cert_added_dict.has_key(cert.get_fingerprint('sha1')):
- del self.all_pub_cert_added_dict[cert.get_fingerprint('sha1')]
-
- new = model.get_value(child_itr, enumerations.PUBCERT_NEW)
- if not new:
- sha = cert.get_fingerprint('sha1')
- ips_hash = model.get_value(child_itr,
- enumerations.PUBCERT_IPSHASH)
- self.removed_orig_pub_cert_dict[sha] = ips_hash
-
- model.remove(child_itr)
- self.__set_pub_cert_selection(sorted_model, sel_path)
-
- def __set_pub_cert_selection(self, sorted_model, sel_path):
- len_smodel = len(sorted_model)
- if len_smodel == 0:
- self.__set_empty_pub_cert()
- return
- if len_smodel <= sel_path[0]:
- sel_path = (len_smodel - 1,)
- if sel_path[0] < 0:
- sel_path = (0,)
-
- self.w_pub_cert_treeview.scroll_to_cell(sel_path)
- selection = self.w_pub_cert_treeview.get_selection()
- selection.select_path(sel_path)
-
- def __set_empty_pub_cert(self):
- details_buffer = self.w_pub_cert_details_textview.get_buffer()
- details_buffer.set_text("")
- self.w_pub_cert_remove_btn.set_sensitive(False)
- self.w_pub_cert_revoke_btn.set_sensitive(False)
- self.w_pub_cert_reinstate_btn.set_sensitive(False)
-
- def __get_selected_pub_cert_itr_model(self):
- return self.__get_fitr_model_from_tree(self.w_pub_cert_treeview)
-
- def __update_pub_certs(self):
- errors = []
- sorted_model = self.w_pub_cert_treeview.get_model()
- if not sorted_model:
- return errors
- model = sorted_model.get_model()
- if not model:
- return errors
-
- updated_pub_cert_dict = {}
- add_pub_cert_dict = {}
- iter_next = sorted_model.get_iter_first()
- while iter_next != None:
- itr = sorted_model.convert_iter_to_child_iter(None, iter_next)
- ips_hash = model.get_value(itr, enumerations.PUBCERT_IPSHASH)
- status = model.get_value(itr, enumerations.PUBCERT_STATUS)
- path = model.get_value(itr, enumerations.PUBCERT_PATH)
- new = model.get_value(itr, enumerations.PUBCERT_NEW)
- #Both new and reinstated certs treated as new and to be added
- if new:
- add_pub_cert_dict[path] = True
- else:
- updated_pub_cert_dict[ips_hash] = status
- iter_next = sorted_model.iter_next(iter_next)
- for ips_hash, status in self.orig_pub_cert_added_dict.items():
- if not updated_pub_cert_dict.has_key(ips_hash):
- errors += self.__remove_pub_cert_for_publisher(ips_hash)
- elif status != updated_pub_cert_dict[ips_hash] and \
- updated_pub_cert_dict[ips_hash] == PUBCERT_REVOKED_STR:
- errors += self.__revoke_pub_cert_for_publisher(ips_hash)
- # Add and reinstate pub certs for publisher
- for path in add_pub_cert_dict.keys():
- errors += self.__add_pub_cert_to_publisher(path)
-
- return errors
-
- def __add_pub_cert_to_publisher(self, path):
- errors = []
- try:
- with open(path, "rb") as fh:
- s = fh.read()
- except EnvironmentError, e:
- if e.errno == errno.ENOENT:
- errors.append(("",
- api_errors.MissingFileArgumentException(path)))
- elif e.errno == errno.EACCES:
- errors.append(("", api_errors.PermissionsException(path)))
- else:
- errors.append(("", e))
- try:
- pub = self.repository_modify_publisher
- if pub != None:
- pub.approve_ca_cert(s)
- except api_errors.ApiException, e:
- errors.append(("", e))
- return errors
-
- def __revoke_pub_cert_for_publisher(self, ips_hash):
- errors = []
- try:
- pub = self.repository_modify_publisher
- if pub != None:
- pub.revoke_ca_cert(ips_hash)
- except api_errors.ApiException, e:
- errors.append(("", e))
- return errors
-
- def __remove_pub_cert_for_publisher(self, ips_hash):
- errors = []
- try:
- pub = self.repository_modify_publisher
- if pub != None:
- pub.unset_ca_cert(ips_hash)
- except api_errors.ApiException, e:
- errors.append(("", e))
- return errors
-
- def __init_pubs_tree_view(self, publishers_list):
- publishers_list_filter = publishers_list.filter_new()
- publishers_list_sort = gtk.TreeModelSort(publishers_list_filter)
- publishers_list_sort.set_sort_column_id(
- enumerations.PUBLISHER_PRIORITY_CHANGED, gtk.SORT_ASCENDING)
- # Name column
- name_renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_("Publisher"),
- name_renderer, text = enumerations.PUBLISHER_NAME)
- column.set_expand(True)
- self.w_publishers_treeview.append_column(column)
- # Alias column
- alias_renderer = gtk.CellRendererText()
- alias_renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
- column = gtk.TreeViewColumn(_("Alias"),
- alias_renderer, text = enumerations.PUBLISHER_ALIAS)
- column.set_expand(True)
- self.w_publishers_treeview.append_column(column)
- # Enabled column
- toggle_renderer = gtk.CellRendererToggle()
- column = gtk.TreeViewColumn(_("Enabled"),
- toggle_renderer, active = enumerations.PUBLISHER_ENABLED)
- toggle_renderer.set_property("activatable", True)
- column.set_expand(False)
- toggle_renderer.connect('toggled', self.__enable_disable)
- column.set_cell_data_func(toggle_renderer,
- self.__toggle_data_function, None)
- self.w_publishers_treeview.append_column(column)
- # Sticky column
- toggle_renderer = gtk.CellRendererToggle()
- column = gtk.TreeViewColumn(_("Sticky"),
- toggle_renderer, active = enumerations.PUBLISHER_STICKY)
- toggle_renderer.set_property("activatable", True)
- column.set_expand(False)
- toggle_renderer.connect('toggled', self.__sticky_unsticky)
- column.set_cell_data_func(toggle_renderer,
- self.__toggle_data_function, None)
- self.w_publishers_treeview.append_column(column)
- publishers_list_filter.set_visible_func(self.__publishers_filter)
- self.w_publishers_treeview.set_model(publishers_list_sort)
-
- def __prepare_publisher_list(self, restore_changes = False):
- sorted_model = self.w_publishers_treeview.get_model()
- selection = self.w_publishers_treeview.get_selection()
- selected_rows = selection.get_selected_rows()
- self.w_publishers_treeview.set_model(None)
- try:
- pubs = self.api_o.get_publishers(duplicate=True)
- except api_errors.ApiException, e:
- self.__show_errors([("", e)])
- return
- if not sorted_model:
- return
- filtered_model = sorted_model.get_model()
- model = filtered_model.get_model()
-
- if restore_changes == False:
- self.no_changes = 0
- self.priority_changes = []
- model.clear()
-
- j = 0
- for pub in pubs:
- name = pub.prefix
- alias = pub.alias
- # BUG: alias should be either "None" or None.
- # in the list it's "None", but when adding pub it's None
- if not alias or len(alias) == 0 or alias == "None":
- alias = name
- publisher_row = [j, j, name, alias, not pub.disabled,
- pub.sticky, pub, False, False, False]
- model.insert(j, publisher_row)
- j += 1
- else:
- j = 0
- for publisher_row in model:
- pub = pubs[j]
- name = pub.prefix
- alias = pub.alias
- if not alias or len(alias) == 0 or alias == "None":
- alias = name
- publisher_row[enumerations.PUBLISHER_ALIAS] = alias
- publisher_row[enumerations.PUBLISHER_OBJECT] = pub
- j += 1
- # We handle here the case where a publisher was added
- if self.new_pub:
- pub = self.new_pub
- name = pub.prefix
- alias = pub.alias
- if not alias or len(alias) == 0 or alias == "None":
- alias = name
- publisher_row = [j, j, name, alias, not pub.disabled,
- pub.sticky, pub, False, False, False]
- model.insert(j, publisher_row)
-
- self.w_publishers_treeview.set_model(sorted_model)
- if len(sorted_model) == 0:
- self.__set_empty_pub_list()
-
- if restore_changes:
- if self.new_pub:
- self.__select_last_publisher()
- self.new_pub = None
- else:
- # We do have gtk.SELECTION_SINGLE mode, so if exists, we are
- # interested only in the first selected path.
- if len(selected_rows) > 1 and len(selected_rows[1]) > 0:
- self.w_publishers_treeview.scroll_to_cell(
- selected_rows[1][0])
- selection.select_path(selected_rows[1][0])
-
- def __set_empty_pub_list(self):
- details_buffer = self.w_manage_publishers_details.get_buffer()
- details_buffer.set_text("")
- self.w_manage_modify_btn.set_sensitive(False)
- self.w_manage_remove_btn.set_sensitive(False)
- self.w_manage_up_btn.set_sensitive(False)
- self.w_manage_down_btn.set_sensitive(False)
-
- def __select_last_publisher(self):
- sorted_model = self.w_publishers_treeview.get_model()
- itr = sorted_model.get_iter_first()
- next_itr = sorted_model.iter_next(itr)
- while next_itr != None:
- itr = next_itr
- next_itr = sorted_model.iter_next(itr)
- path = sorted_model.get_path(itr)
- self.w_publishers_treeview.scroll_to_cell(path)
- self.w_publishers_treeview.get_selection().select_path(path)
-
- def __validate_url(self, url_widget, w_ssl_key = None, w_ssl_cert = None):
- self.__validate_url_generic(url_widget, self.w_add_error_label,
- self.w_publisher_add_button, self.is_alias_valid,
- w_ssl_label=self.w_add_sslerror_label,
- w_ssl_key=w_ssl_key, w_ssl_cert=w_ssl_cert)
-
- def __validate_url_generic(self, w_url_text, w_error_label, w_action_button,
- alias_valid = False, function = None, w_ssl_label = None,
- w_ssl_key = None, w_ssl_cert = None):
- ssl_key = None
- ssl_cert = None
- ssl_error = None
- ssl_valid = True
- url = w_url_text.get_text()
- self.is_url_valid, self.url_err = self.__is_url_valid(url)
- if not self.webinstall_new:
- self.__reset_error_label()
- if w_ssl_label:
- w_ssl_label.set_sensitive(False)
- w_ssl_label.show()
- valid_url = False
- valid_func = True
- if self.is_url_valid:
- if alias_valid:
- valid_url = True
- else:
- if self.name_error != None:
- self.__show_error_label_with_format(w_error_label,
- self.name_error)
- else:
- if self.url_err != None:
- self.__show_error_label_with_format(w_error_label,
- self.url_err)
- if w_ssl_key != None and w_ssl_cert != None:
- if w_ssl_key:
- ssl_key = w_ssl_key.get_text()
- if w_ssl_cert:
- ssl_cert = w_ssl_cert.get_text()
- ssl_valid, ssl_error = self.__validate_ssl_key_cert(url, ssl_key,
- ssl_cert, ignore_ssl_check_for_not_https=True)
- self.__update_repository_dialog_width(ssl_error)
- if ssl_error != None and w_ssl_label:
- self.__show_error_label_with_format(w_ssl_label,
- ssl_error)
- elif w_ssl_label:
- w_ssl_label.hide()
- if function != None:
- valid_func = function()
- w_action_button.set_sensitive(valid_url and valid_func and ssl_valid)
-
- def __validate_alias_addpub(self, ok_btn, name_widget, url_widget, error_label,
- function = None):
- valid_btn = False
- valid_func = True
- name = name_widget.get_text()
- self.is_alias_valid = self.__is_alias_valid(name)
- self.__reset_error_label()
- if self.is_alias_valid:
- if (self.is_url_valid):
- valid_btn = True
- else:
- if self.url_err == None:
- self.__validate_url(url_widget,
- w_ssl_key=self.w_key_entry,
- w_ssl_cert=self.w_cert_entry)
- if self.url_err != None:
- self.__show_error_label_with_format(error_label,
- self.url_err)
- else:
- if self.name_error != None:
- self.__show_error_label_with_format(error_label,
- self.name_error)
- if function != None:
- valid_func = function()
- ok_btn.set_sensitive(valid_btn and valid_func)
-
- def __is_alias_valid(self, name):
- self.name_error = None
- if len(name) == 0:
- return True
- try:
- publisher.Publisher(prefix=name)
- except api_errors.BadPublisherPrefix, e:
- self.name_error = _("Alias contains invalid characters")
- return False
- try:
- self.api_o.get_publisher(prefix=name)
- self.name_error = _("Alias already in use")
- return False
- except api_errors.UnknownPublisher, e:
- return True
- except api_errors.ApiException, e:
- self.__show_errors([("", e)])
- return False
-
- def __get_selected_publisher_itr_model(self):
- itr, sorted_model = self.__get_fitr_model_from_tree(
- self.w_publishers_treeview)
- if itr == None or sorted_model == None:
- return (None, None)
- sorted_path = sorted_model.get_path(itr)
- filter_path = sorted_model.convert_path_to_child_path(sorted_path)
- filter_model = sorted_model.get_model()
- path = filter_model.convert_path_to_child_path(filter_path)
- model = filter_model.get_model()
- itr = model.get_iter(path)
- return (itr, model)
-
- def __get_selected_mirror_itr_model(self):
- return self.__get_fitr_model_from_tree(\
- self.modify_repo_mirrors_treeview)
-
- def __get_selected_origin_itr_model(self):
- return self.__get_fitr_model_from_tree(\
- self.modify_repo_origins_treeview)
-
- def __modify_publisher_dialog(self, pub):
- self.orig_sig_policy = {}
- self.pub_certs_setup = False
-
- gui_misc.set_modal_and_transient(self.w_modify_repository_dialog,
- self.w_manage_publishers_dialog)
- try:
- self.repository_modify_publisher = self.api_o.get_publisher(
- prefix=pub.prefix, alias=pub.prefix, duplicate=True)
- except api_errors.ApiException, e:
- self.__show_errors([("", e)])
- return
- updated_modify_repository = self.__update_modify_repository_dialog(True,
- True, True, True)
-
- self.w_modify_repository_dialog.set_size_request(
- MODIFY_DIALOG_WIDTH_DEFAULT, -1)
-
- if updated_modify_repository:
- self.w_modify_repository_dialog.set_title(
- _("Modify Publisher - %s") %
- self.__get_pub_display_name(pub))
- self.w_modify_repository_dialog.show_all()
-
- pagenum = self.w_modify_pub_notebook.get_current_page()
- if pagenum == MODIFY_NOTEBOOK_CERTIFICATE_PAGE:
- gobject.idle_add(self.__prepare_pub_certs)
- elif pagenum == MODIFY_NOTEBOOK_SIG_POLICY_PAGE:
- gobject.idle_add(self.__prepare_pub_signature_policy)
-
- def __update_repository_dialog_width(self, ssl_error):
- if ssl_error == None:
- self.w_modify_repository_dialog.set_size_request(
- MODIFY_DIALOG_WIDTH_DEFAULT, -1)
- return
-
- style = self.w_repositorymodify_name.get_style()
- font_size_in_pango_unit = style.font_desc.get_size()
- font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
- ssl_error_len = len(unicode(ssl_error)) * font_size_in_pixel
- if ssl_error_len > MODIFY_DIALOG_SSL_WIDTH_DEFAULT:
- new_dialog_width = ssl_error_len * \
- (float(MODIFY_DIALOG_WIDTH_DEFAULT)/
- MODIFY_DIALOG_SSL_WIDTH_DEFAULT)
- self.w_modify_repository_dialog.set_size_request(
- int(new_dialog_width), -1)
- else:
- self.w_modify_repository_dialog.set_size_request(
- MODIFY_DIALOG_WIDTH_DEFAULT, -1)
-
- def __update_modify_repository_dialog(self, update_alias=False,
- update_mirrors=False, update_origins=False, update_ssl=False):
- if not self.repository_modify_publisher:
- return False
- pub = self.repository_modify_publisher
- selected_repo = pub.repository
- prefix = ""
- ssl_cert = ""
- ssl_key = ""
-
- if pub.prefix and len(pub.prefix) > 0:
- prefix = pub.prefix
- self.w_repositorymodify_name.set_text(prefix)
-
- if update_alias:
- alias = ""
- if pub.alias and len(pub.alias) > 0 \
- and pub.alias != "None":
- alias = pub.alias
- self.w_modify_pub_alias.set_text(alias)
-
- if update_mirrors or update_ssl:
- if update_mirrors:
- insert_count = 0
- mirrors_list = self.__get_mirrors_origins_liststore()
- for mirror in selected_repo.mirrors:
- if mirror.ssl_cert:
- ssl_cert = mirror.ssl_cert
- if mirror.ssl_key:
- ssl_key = mirror.ssl_key
- if update_mirrors:
- mirror_uri = [mirror.uri]
- mirrors_list.insert(insert_count, mirror_uri)
- insert_count += 1
- if update_mirrors:
- self.modify_repo_mirrors_treeview.set_model(mirrors_list)
- if len(selected_repo.mirrors) > 0:
- self.w_repositorymirror_expander.set_expanded(
- True)
- else:
- self.w_repositorymirror_expander.set_expanded(
- False)
-
- if update_origins or update_ssl:
- if update_origins:
- insert_count = 0
- origins_list = self.__get_mirrors_origins_liststore()
- for origin in selected_repo.origins:
- if origin.ssl_cert:
- ssl_cert = origin.ssl_cert
- if origin.ssl_key:
- ssl_key = origin.ssl_key
- if update_origins:
- origin_uri = [origin.uri]
- origins_list.insert(insert_count, origin_uri)
- insert_count += 1
- if update_origins:
- self.modify_repo_origins_treeview.set_model(origins_list)
-
- reg_uri = self.__get_registration_uri(selected_repo)
- if reg_uri != None:
- self.w_repositorymodify_registration_link.set_uri(
- reg_uri)
- self.w_repositorymodify_registration_box.show()
- else:
- self.w_repositorymodify_registration_box.hide()
-
- if update_ssl:
- self.w_repositorymodify_cert_entry.set_text(ssl_cert)
- self.w_repositorymodify_key_entry.set_text(ssl_key)
- return True
-
- def __add_mirror(self, new_mirror):
- pub = self.repository_modify_publisher
- repo = pub.repository
- try:
- repo.add_mirror(new_mirror)
- self.w_addmirror_entry.set_text("")
- except api_errors.ApiException, e:
- self.__show_errors([(pub, e)])
- self.__update_modify_repository_dialog(update_mirrors=True)
-
- def __rm_mirror(self):
- itr, model = self.__get_selected_mirror_itr_model()
- remove_mirror = None
- if itr and model:
- remove_mirror = model.get_value(itr, 0)
- pub = self.repository_modify_publisher
- repo = pub.repository
- try:
- repo.remove_mirror(remove_mirror)
- except api_errors.ApiException, e:
- self.__show_errors([(pub, e)])
- self.__update_modify_repository_dialog(update_mirrors=True)
-
- def __add_origin(self, new_origin):
- pub = self.repository_modify_publisher
- repo = pub.repository
- try:
- repo.add_origin(new_origin)
- self.w_addorigin_entry.set_text("")
- except api_errors.ApiException, e:
- self.__show_errors([(pub, e)])
- self.__update_modify_repository_dialog(update_origins=True)
-
- def __rm_origin(self):
- itr, model = self.__get_selected_origin_itr_model()
- remove_origin = None
- if itr and model:
- remove_origin = model.get_value(itr, 0)
- pub = self.repository_modify_publisher
- repo = pub.repository
- try:
- repo.remove_origin(remove_origin)
- except api_errors.ApiException, e:
- self.__show_errors([(pub, e)])
- self.__update_modify_repository_dialog(update_origins=True)
-
- def __sticky_unsticky(self, cell, sorted_path):
- sorted_model = self.w_publishers_treeview.get_model()
- filtered_path = sorted_model.convert_path_to_child_path(sorted_path)
- filtered_model = sorted_model.get_model()
- path = filtered_model.convert_path_to_child_path(filtered_path)
- model = filtered_model.get_model()
- itr = model.get_iter(path)
- if itr == None:
- return
- pub = model.get_value(itr, enumerations.PUBLISHER_OBJECT)
- if pub.sys_pub:
- return
- is_sticky = model.get_value(itr, enumerations.PUBLISHER_STICKY)
- changed = model.get_value(itr, enumerations.PUBLISHER_STICKY_CHANGED)
- model.set_value(itr, enumerations.PUBLISHER_STICKY, not is_sticky)
- model.set_value(itr, enumerations.PUBLISHER_STICKY_CHANGED, not changed)
-
- def __enable_disable(self, cell, sorted_path):
- sorted_model = self.w_publishers_treeview.get_model()
- filtered_path = sorted_model.convert_path_to_child_path(sorted_path)
- filtered_model = sorted_model.get_model()
- path = filtered_model.convert_path_to_child_path(filtered_path)
- model = filtered_model.get_model()
- itr = model.get_iter(path)
- if itr == None:
- self.w_manage_modify_btn.set_sensitive(False)
- self.w_manage_remove_btn.set_sensitive(False)
- self.w_manage_up_btn.set_sensitive(False)
- self.w_manage_down_btn.set_sensitive(False)
- return
- pub = model.get_value(itr, enumerations.PUBLISHER_OBJECT)
- if pub.sys_pub:
- return
- enabled = model.get_value(itr, enumerations.PUBLISHER_ENABLED)
- changed = model.get_value(itr, enumerations.PUBLISHER_ENABLE_CHANGED)
- model.set_value(itr, enumerations.PUBLISHER_ENABLED, not enabled)
- model.set_value(itr, enumerations.PUBLISHER_ENABLE_CHANGED, not changed)
- self.__enable_disable_updown_btn(itr, model)
-
- @staticmethod
- def __is_at_least_one_entry(treeview):
- model = treeview.get_model()
- if len(model) >= 1:
- return True
- return False
-
- def __enable_disable_remove_modify_btn(self, itr, model):
- if itr == None:
- self.w_manage_modify_btn.set_sensitive(False)
- self.w_manage_remove_btn.set_sensitive(False)
- self.w_manage_up_btn.set_sensitive(False)
- self.w_manage_down_btn.set_sensitive(False)
- return
- remove_val = False
- modify_val = False
- if self.__is_at_least_one_entry(self.w_publishers_treeview):
- remove_val = True
- modify_val = True
- pub = model.get_value(itr,
- enumerations.PUBLISHER_OBJECT)
- if pub.sys_pub:
- remove_val = False
- modify_val = False
- self.w_manage_modify_btn.set_sensitive(modify_val)
- self.w_manage_remove_btn.set_sensitive(remove_val)
-
- def __enable_disable_updown_btn(self, itr, model):
- up_enabled = True
- down_enabled = True
- sorted_size = len(self.w_publishers_treeview.get_model())
-
- if itr:
- current_priority = model.get_value(itr,
- enumerations.PUBLISHER_PRIORITY_CHANGED)
- is_sys_pub = model.get_value(itr,
- enumerations.PUBLISHER_OBJECT).sys_pub
- next_sys_pub = False
- prev_sys_pub = False
- path = model.get_path(itr)
- next_itr = model.iter_next(itr)
- if next_itr:
- next_pub = model.get_value(next_itr,
- enumerations.PUBLISHER_OBJECT)
- if next_pub.sys_pub:
- next_sys_pub = True
- if path[0] > 0:
- prev_path = (path[0] - 1,)
- prev_itr = model.get_iter(prev_path)
- prev_pub = model.get_value(prev_itr,
- enumerations.PUBLISHER_OBJECT)
- if prev_pub.sys_pub:
- prev_sys_pub = True
-
- if current_priority == sorted_size - 1:
- down_enabled = False
- elif current_priority == 0:
- up_enabled = False
-
- if sorted_size == 1:
- up_enabled = False
- down_enabled = False
- else:
- if next_sys_pub or is_sys_pub:
- down_enabled = False
- if prev_sys_pub or is_sys_pub:
- up_enabled = False
- self.w_manage_up_btn.set_sensitive(up_enabled)
- self.w_manage_down_btn.set_sensitive(down_enabled)
-
- def __do_add_repository(self, alias=None, url=None, ssl_key=None, ssl_cert=None,
- pub=None):
- self.publishers_apply.set_title(_("Adding Publisher"))
- if self.webinstall_new:
- self.__run_with_prog_in_thread(self.__add_repository,
- self.main_window, self.__stop, None, None, ssl_key,
- ssl_cert, self.repository_modify_publisher)
- else:
- self.__run_with_prog_in_thread(self.__add_repository,
- self.w_add_publisher_dialog, self.__stop, alias,
- url, ssl_key, ssl_cert, pub)
-
- def __stop(self):
- if self.cancel_progress_thread == False:
- self.__update_details_text(_("Canceling...\n"))
- self.cancel_progress_thread = True
- self.publishers_apply_cancel.set_sensitive(False)
-
- def __add_repository(self, alias=None, origin_url=None, ssl_key=None,
- ssl_cert=None, pub=None):
- errors = []
- if pub == None:
- if self.__check_publisher_exists(self.api_o, alias,
- origin_url):
- self.progress_stop_thread = True
- return
- pub, repo, new_pub = self.__setup_publisher_from_uri(
- alias, origin_url, ssl_key, ssl_cert)
- if pub == None:
- self.progress_stop_thread = True
- return
- else:
- repo = pub.repository
- new_pub = True
- name = pub.prefix
- errors_ssl = self.__update_ssl_creds(pub, repo, ssl_cert, ssl_key)
- errors_update = []
- try:
- errors_update = self.__update_publisher(pub,
- new_publisher=new_pub)
- except api_errors.UnknownRepositoryPublishers, e:
- if len(e.known) > 0:
- pub, repo, new_pub = self.__get_or_create_pub_with_url(
- self.api_o, e.known[0], origin_url)
- if new_pub:
- errors_ssl = self.__update_ssl_creds(pub, repo,
- ssl_cert, ssl_key)
- pub.alias = name
- errors_update = self.__update_publisher(pub,
- new_publisher=new_pub,
- raise_unknownpubex=False)
- else:
- self.progress_stop_thread = True
- return
- else:
- errors_update.append((pub, e))
- errors += errors_ssl
- errors += errors_update
- if self.cancel_progress_thread:
- try:
- self.__g_update_details_text(
- _("Removing publisher %s\n") % name)
- self.api_o.remove_publisher(prefix=name,
- alias=name)
- self.__g_update_details_text(
- _("Publisher %s succesfully removed\n") % name)
- except api_errors.ApiException, e:
- errors.append((pub, e))
- self.progress_stop_thread = True
- else:
- self.progress_stop_thread = True
- if len(errors) > 0:
- gobject.idle_add(self.__show_errors, errors)
- elif not self.webinstall_new:
- gobject.idle_add(self.__afteradd_confirmation, pub)
- self.progress_stop_thread = True
- gobject.idle_add(
- self.__g_on_add_publisher_delete_event,
- self.w_add_publisher_dialog, None)
- elif self.webinstall_new:
- gobject.idle_add(
- self.__g_on_add_publisher_delete_event,
- self.w_add_publisher_dialog, None)
- gobject.idle_add(self.parent.reload_packages)
-
- def __update_publisher(self, pub, new_publisher=False, raise_unknownpubex=True):
- errors = []
- try:
- if new_publisher:
- self.__g_update_details_text(
- _("Adding publisher %s\n") % pub.prefix)
- self.api_o.add_publisher(pub)
- self.no_changes += 1
- else:
- self.__g_update_details_text(
- _("Updating publisher %s\n") % pub.prefix)
- self.api_o.update_publisher(pub)
- self.no_changes += 1
- if new_publisher:
- self.__g_update_details_text(
- _("Publisher %s succesfully added\n") % pub.prefix)
- else:
- self.__g_update_details_text(
- _("Publisher %s succesfully updated\n") % pub.prefix)
- except api_errors.UnknownRepositoryPublishers, e:
- if raise_unknownpubex:
- raise e
- else:
- errors.append((pub, e))
- except api_errors.ApiException, e:
- errors.append((pub, e))
- return errors
-
- def __afteradd_confirmation(self, pub):
- self.new_pub = pub
- repo = pub.repository
- origin = repo.origins[0]
- # Descriptions not available at the moment
- self.w_add_publisher_c_desc.hide()
- self.w_add_publisher_c_desc_l.hide()
- self.w_add_publisher_c_name.set_text(pub.prefix)
- if pub.alias and len(pub.alias) > 0:
- self.w_add_publisher_c_alias.set_text(pub.alias)
- else:
- self.w_add_publisher_c_alias.hide()
- self.w_add_publisher_c_alias_l.hide()
- self.w_add_publisher_c_url.set_text(origin.uri)
- self.w_add_publisher_comp_dialog.show()
-
- def __prepare_confirmation_dialog(self):
- disable = ""
- enable = ""
- sticky = ""
- unsticky = ""
- delete = ""
- priority_change = ""
- disable_no = 0
- enable_no = 0
- sticky_no = 0
- unsticky_no = 0
- delete_no = 0
- not_removed = []
- removed_priorities = []
- priority_changed = []
- for row in self.publishers_list:
- pub_name = row[enumerations.PUBLISHER_NAME]
- if row[enumerations.PUBLISHER_REMOVED]:
- delete += "\t" + pub_name + "\n"
- delete_no += 1
- removed_priorities.append(
- row[enumerations.PUBLISHER_PRIORITY])
- else:
- if row[enumerations.PUBLISHER_ENABLE_CHANGED]:
- to_enable = row[enumerations.PUBLISHER_ENABLED]
- if not to_enable:
- disable += "\t" + pub_name + "\n"
- disable_no += 1
- else:
- enable += "\t" + pub_name + "\n"
- enable_no += 1
- if row[enumerations.PUBLISHER_STICKY_CHANGED]:
- to_sticky = row[enumerations.PUBLISHER_STICKY]
- if not to_sticky:
- unsticky += "\t" + pub_name + "\n"
- unsticky_no += 1
- else:
- sticky += "\t" + pub_name + "\n"
- sticky_no += 1
- not_removed.append(row)
-
- for pub in not_removed:
- if not self.__check_if_ignore(pub, removed_priorities):
- pub_name = pub[enumerations.PUBLISHER_NAME]
- pri = pub[enumerations.PUBLISHER_PRIORITY_CHANGED]
- priority_changed.append([pri, pub_name])
-
- if disable_no == 0 and enable_no == 0 and delete_no == 0 and \
- sticky_no == 0 and unsticky_no == 0 and \
- len(priority_changed) == 0:
- self.__on_manage_cancel_clicked(None)
- return
-
- priority_changed.sort()
- for pri, pub_name in priority_changed:
- priority_change += "\t" + str(pri+1) + \
- " - " + pub_name + "\n"
-
- textbuf = self.w_confirmation_textview.get_buffer()
- textbuf.set_text("")
- textiter = textbuf.get_end_iter()
-
- disable_text = ngettext("Disable Publisher:\n",
- "Disable Publishers:\n", disable_no)
- enable_text = ngettext("Enable Publisher:\n",
- "Enable Publishers:\n", enable_no)
- delete_text = ngettext("Remove Publisher:\n",
- "Remove Publishers:\n", delete_no)
- sticky_text = ngettext("Set sticky Publisher:\n",
- "Set sticky Publishers:\n", delete_no)
- unsticky_text = ngettext("Unset sticky Publisher:\n",
- "Unset sticky Publishers:\n", delete_no)
- priority_text = _("Change Priorities:\n")
-
- confirm_no = delete_no + enable_no + disable_no + sticky_no + \
- unsticky_no
- confirm_text = ngettext("Apply the following change:",
- "Apply the following changes:", confirm_no)
-
- self.w_confirmation_label.set_markup("<b>" + confirm_text + "</b>")
-
- if len(delete) > 0:
- textbuf.insert_with_tags_by_name(textiter,
- delete_text, "bold")
- textbuf.insert_with_tags_by_name(textiter,
- delete)
- if len(disable) > 0:
- if len(delete) > 0:
- textbuf.insert_with_tags_by_name(textiter,
- "\n")
- textbuf.insert_with_tags_by_name(textiter,
- disable_text, "bold")
- textbuf.insert_with_tags_by_name(textiter,
- disable)
- if len(enable) > 0:
- if len(delete) > 0 or len(disable) > 0:
- textbuf.insert_with_tags_by_name(textiter,
- "\n")
- textbuf.insert_with_tags_by_name(textiter,
- enable_text, "bold")
- textbuf.insert_with_tags_by_name(textiter,
- enable)
- if len(sticky) > 0:
- if len(delete) > 0 or len(disable) > 0 or len(enable) > 0:
- textbuf.insert_with_tags_by_name(textiter,
- "\n")
- textbuf.insert_with_tags_by_name(textiter,
- sticky_text, "bold")
- textbuf.insert_with_tags_by_name(textiter,
- sticky)
- if len(unsticky) > 0:
- if len(delete) > 0 or len(disable) > 0 or \
- len(enable) > 0 or len(sticky) > 0:
- textbuf.insert_with_tags_by_name(textiter,
- "\n")
- textbuf.insert_with_tags_by_name(textiter,
- unsticky_text, "bold")
- textbuf.insert_with_tags_by_name(textiter,
- unsticky)
- if len(priority_change) > 0:
- if len(delete) > 0 or len(disable) or len(enable) > 0:
- textbuf.insert_with_tags_by_name(textiter,
- "\n")
- textbuf.insert_with_tags_by_name(textiter,
- priority_text, "bold")
- textbuf.insert_with_tags_by_name(textiter,
- priority_change)
-
- self.w_confirm_cancel_btn.grab_focus()
- self.w_confirmation_dialog.show_all()
-
- def __proceed_enable_disable(self, pub_names, to_enable):
- errors = []
-
- gobject.idle_add(self.publishers_apply_expander.set_expanded, True)
- for name in pub_names.keys():
- try:
- pub = self.api_o.get_publisher(name,
- duplicate = True)
- if pub.disabled == (not to_enable):
- continue
- pub.disabled = not to_enable
- self.no_changes += 1
- enable_text = _("Disabling")
- if to_enable:
- enable_text = _("Enabling")
-
- details_text = \
- _("%(enable)s publisher %(name)s\n")
- self.__g_update_details_text(details_text %
- {"enable" : enable_text, "name" : name})
- self.api_o.update_publisher(pub)
- except api_errors.ApiException, e:
- errors.append(pub, e)
- self.progress_stop_thread = True
- gobject.idle_add(self.publishers_apply_expander.set_expanded, False)
- if len(errors) > 0:
- gobject.idle_add(self.__show_errors, errors)
- else:
- gobject.idle_add(self.parent.reload_packages, False)
-
- def __proceed_after_confirmation(self):
- errors = []
-
- image_lock_err = False
- for row in self.priority_changes:
- try:
- if row[1] == None or row[2] == None:
- continue
- pub1 = self.api_o.get_publisher(row[1],
- duplicate=True)
- pub2 = self.api_o.get_publisher(row[2],
- duplicate=True)
- if row[0] == enumerations.PUBLISHER_MOVE_BEFORE:
- self.api_o.update_publisher(pub1,
- search_before=pub2.prefix)
- else:
- self.api_o.update_publisher(pub1,
- search_after=pub2.prefix)
- self.no_changes += 1
- self.__g_update_details_text(
- _("Changing priority for publisher %s\n")
- % row[1])
- except api_errors.ImageLockedError, e:
- self.no_changes = 0
- if not image_lock_err:
- errors.append((row[1], e))
- image_lock_err = True
- except api_errors.ApiException, e:
- errors.append((row[1], e))
-
- for row in self.publishers_list:
- name = row[enumerations.PUBLISHER_NAME]
- try:
- if row[enumerations.PUBLISHER_REMOVED]:
- self.no_changes += 1
- self.__g_update_details_text(
- _("Removing publisher %s\n") % name)
- self.api_o.remove_publisher(prefix=name,
- alias=name)
- self.__g_update_details_text(
- _("Publisher %s succesfully removed\n")
- % name)
- elif row[enumerations.PUBLISHER_ENABLE_CHANGED] or \
- row[enumerations.PUBLISHER_STICKY_CHANGED]:
- self.__do_changes_for_row(row, name)
- except api_errors.ImageLockedError, e:
- self.no_changes = 0
- if not image_lock_err:
- errors.append(
- (row[enumerations.PUBLISHER_OBJECT], e))
- image_lock_err = True
- except api_errors.ApiException, e:
- errors.append((row[enumerations.PUBLISHER_OBJECT], e))
- self.progress_stop_thread = True
- if len(errors) > 0:
- gobject.idle_add(self.__show_errors, errors)
- else:
- gobject.idle_add(self.__after_confirmation)
-
- def __do_changes_for_row(self, row, name):
- pub = self.api_o.get_publisher(name, duplicate = True)
- if row[enumerations.PUBLISHER_ENABLE_CHANGED]:
- to_enable = row[enumerations.PUBLISHER_ENABLED]
- pub.disabled = not to_enable
- if row[enumerations.PUBLISHER_STICKY_CHANGED]:
- sticky = row[enumerations.PUBLISHER_STICKY]
- pub.sticky = sticky
- self.no_changes += 1
- update_text = _("Updating")
- details_text = _("%(update)s publisher %(name)s\n")
- self.__g_update_details_text(details_text %
- {"update" : update_text, "name" : name})
- self.api_o.update_publisher(pub)
-
- def __after_confirmation(self):
- self.__on_manage_publishers_delete_event(
- self.w_manage_publishers_dialog, None)
- return False
-
- def __proceed_modifyrepo_ok(self):
- errors = []
- alias = self.w_modify_pub_alias.get_text()
- ssl_key = self.w_repositorymodify_key_entry.get_text()
- ssl_cert = self.w_repositorymodify_cert_entry.get_text()
- pub = self.repository_modify_publisher
- repo = pub.repository
- missing_ssl = False
- try:
- prefix = pub.prefix
- mirrors = repo.mirrors
- origins = repo.origins
- self.api_o.reset()
- self.repository_modify_publisher = self.api_o.get_publisher(
- prefix=prefix, alias=prefix, duplicate=True)
- pub = self.repository_modify_publisher
- repo = pub.repository
- repo.mirrors = mirrors
- repo.origins = origins
- if pub.alias != alias:
- pub.alias = alias
- errors += self.__update_ssl_creds(pub, repo, ssl_cert, ssl_key)
- errors += self.__update_pub_certs()
- errors += self.__update_pub_sig_policy()
- errors += self.__update_publisher(pub, new_publisher=False)
- except api_errors.ApiException, e:
- errors.append((pub, e))
- self.progress_stop_thread = True
- if len(errors) > 0:
- missing_ssl = self.__is_missing_ssl_creds(pub, ssl_key, ssl_cert)
- gobject.idle_add(self.__show_errors, errors, missing_ssl)
- else:
- gobject.idle_add(self.__g_delete_widget_handler_hide,
- self.w_modify_repository_dialog, None)
- if self.action == enumerations.MANAGE_PUBLISHERS:
- gobject.idle_add(self.__prepare_publisher_list, True)
- self.no_changes += 1
-
- @staticmethod
- def __is_missing_ssl_creds(pub, ssl_key, ssl_cert):
- repo = pub.repository
- if ssl_key and len(ssl_key) > 0 and ssl_cert and len(ssl_cert) > 0:
- return False
- for uri in repo.origins:
- print uri
- if uri.scheme in publisher.SSL_SCHEMES:
- return True
- for uri in repo.mirrors:
- if uri.scheme in publisher.SSL_SCHEMES:
- return True
- return False
-
- def __run_with_prog_in_thread(self, func, parent_window = None,
- cancel_func = None, *f_args):
- self.progress_stop_thread = False
- self.cancel_progress_thread = False
- if cancel_func == None:
- self.publishers_apply_cancel.set_sensitive(False)
- else:
- self.publishers_apply_cancel.set_sensitive(True)
- gui_misc.set_modal_and_transient(self.publishers_apply, parent_window)
- self.publishers_apply_textview.get_buffer().set_text("")
- self.publishers_apply.show_all()
- self.cancel_function = cancel_func
- gobject.timeout_add(100, self.__progress_pulse)
- Thread(target = func, args = f_args).start()
-
- def __progress_pulse(self):
- if not self.progress_stop_thread:
- self.publishers_apply_progress.pulse()
- return True
- else:
- self.publishers_apply.hide()
- return False
-
- def __g_update_details_text(self, text, *tags):
- gobject.idle_add(self.__update_details_text, text, *tags)
-
- def __update_details_text(self, text, *tags):
- buf = self.publishers_apply_textview.get_buffer()
- textiter = buf.get_end_iter()
- if tags:
- buf.insert_with_tags_by_name(textiter, text, *tags)
- else:
- buf.insert(textiter, text)
- self.publishers_apply_textview.scroll_to_iter(textiter, 0.0)
-
- # Signal handlers
- def __on_publisher_selection_changed(self, selection, widget):
- itr, model = self.__get_selected_publisher_itr_model()
- if itr and model:
- self.__enable_disable_updown_btn(itr, model)
- self.__enable_disable_remove_modify_btn(itr, model)
- self.__update_publisher_details(
- model.get_value(itr, enumerations.PUBLISHER_OBJECT),
- self.w_manage_publishers_details)
-
- def __on_mirror_selection_changed(self, selection, widget):
- model_itr = selection.get_selected()
- if model_itr[1]:
- self.w_rmmirror_button.set_sensitive(True)
- else:
- self.w_rmmirror_button.set_sensitive(False)
-
- def __on_origin_selection_changed(self, selection, widget):
- model_itr = selection.get_selected()
- if model_itr[1] and \
- self.__is_at_least_one_entry(self.modify_repo_origins_treeview):
- self.w_rmorigin_button.set_sensitive(True)
- else:
- self.w_rmorigin_button.set_sensitive(False)
-
- def __g_on_add_publisher_delete_event(self, widget, event):
- self.__on_add_publisher_delete_event(widget, event)
- return False
-
- def __on_add_publisher_delete_event(self, widget, event):
- self.w_add_publisher_url.set_text("")
- self.w_add_publisher_alias.set_text("")
- self.__delete_widget_handler_hide(widget, event)
- return True
-
- def __on_add_publisher_complete_delete_event(self, widget, event):
- if self.no_changes > 0:
- self.parent.reload_packages()
- if self.action == enumerations.MANAGE_PUBLISHERS:
- self.__prepare_publisher_list(True)
- self.__delete_widget_handler_hide(widget, event)
- return True
-
- def __on_publisherurl_changed(self, widget):
- url = widget.get_text()
- if self.__is_ssl_scheme(url):
- self.w_ssl_box.show()
- else:
- self.w_ssl_box.hide()
- self.__validate_url(widget,
- w_ssl_key=self.w_key_entry, w_ssl_cert=self.w_cert_entry)
-
- def __on_certentry_changed(self, widget):
- self.__validate_url_generic(self.w_add_publisher_url,
- self.w_add_error_label, self.w_publisher_add_button,
- self.is_alias_valid, w_ssl_label=self.w_add_sslerror_label,
- w_ssl_key=self.w_key_entry, w_ssl_cert=widget)
-
- def __on_keyentry_changed(self, widget):
- self.__validate_url_generic(self.w_add_publisher_url,
- self.w_add_error_label, self.w_publisher_add_button,
- self.is_alias_valid, w_ssl_label=self.w_add_sslerror_label,
- w_ssl_key=widget, w_ssl_cert=self.w_cert_entry)
-
- def __on_modcertkeyentry_changed(self, widget):
- self.__on_addorigin_entry_changed(None)
- self.__on_addmirror_entry_changed(None)
- ssl_key = self.w_repositorymodify_key_entry.get_text()
- ssl_cert = self.w_repositorymodify_cert_entry.get_text()
- ssl_valid, ssl_error = self.__validate_ssl_key_cert(None,
- ssl_key, ssl_cert)
- self.__update_repository_dialog_width(ssl_error)
- self.w_repositorymodifyok_button.set_sensitive(True)
- if ssl_valid == False and (len(ssl_key) > 0 or len(ssl_cert) > 0):
- self.w_repositorymodifyok_button.set_sensitive(False)
- if ssl_error != None:
- self.__show_error_label_with_format(
- self.w_modsslerror_label, ssl_error)
- else:
- self.w_modsslerror_label.set_text("")
- return
- self.w_modsslerror_label.set_text("")
-
- def __on_addmirror_entry_changed(self, widget):
- uri_list_model = self.modify_repo_mirrors_treeview.get_model()
- self.__validate_mirror_origin_url(self.w_addmirror_entry.get_text(),
- self.w_addmirror_button, self.w_modmirrerror_label, uri_list_model)
-
- def __on_addorigin_entry_changed(self, widget):
- uri_list_model = self.modify_repo_origins_treeview.get_model()
- self.__validate_mirror_origin_url(self.w_addorigin_entry.get_text(),
- self.w_addorigin_button, self.w_modoriginerror_label, uri_list_model)
-
- def __validate_mirror_origin_url(self, url, add_button, error_label,
- uri_list_model):
- url_error = None
- is_url_valid, url_error = self.__is_url_valid(url)
- add_button.set_sensitive(False)
- error_label.set_sensitive(False)
- error_label.set_markup(self.publisher_info)
- if len(url) <= 4:
- if is_url_valid == False and url_error != None:
- self.__show_error_label_with_format(
- error_label, url_error)
- return
-
- for uri_row in uri_list_model:
- origin_url = uri_row[0].strip("/")
- if origin_url.strip("/") == url.strip("/"):
- url_error = _("URI already added")
- self.__show_error_label_with_format(
- error_label, url_error)
- return
-
- if is_url_valid == False:
- if url_error != None:
- self.__show_error_label_with_format(error_label,
- url_error)
- return
- add_button.set_sensitive(True)
-
- def __is_ssl_specified(self):
- ssl_key = self.w_repositorymodify_key_entry.get_text()
- ssl_cert = self.w_repositorymodify_cert_entry.get_text()
- if len(ssl_key) > 0 or len(ssl_cert) > 0:
- return True
- return False
-
- def __on_publisheralias_changed(self, widget):
- error_label = self.w_add_error_label
- url_widget = self.w_add_publisher_url
- ok_btn = self.w_publisher_add_button
- self.__validate_alias_addpub(ok_btn, widget, url_widget, error_label)
-
- def __on_modify_pub_alias_changed(self, widget):
- error_label = self.w_modify_alias_error_label
- ok_btn = self.w_repositorymodifyok_button
- name = widget.get_text()
- self.is_alias_valid = self.__is_alias_valid(name)
- if not self.is_alias_valid and self.name_error != None:
- self.__show_error_label_with_format(error_label,
- self.name_error)
- ok_btn.set_sensitive(False)
- else:
- error_label.set_text("")
- ok_btn.set_sensitive(True)
-
- def __on_add_publisher_add_clicked(self, widget):
- if self.w_publisher_add_button.get_property('sensitive') == 0:
- return
- alias = self.w_add_publisher_alias.get_text()
- if len(alias) == 0:
- alias = None
- url = self.w_add_publisher_url.get_text()
- ssl_key = self.w_key_entry.get_text()
- ssl_cert = self.w_cert_entry.get_text()
- if not self.__is_ssl_scheme(url) or not \
- (ssl_key and ssl_cert and os.path.isfile(ssl_cert) and
- os.path.isfile(ssl_key)):
- ssl_key = None
- ssl_cert = None
- self.__do_add_repository(alias, url, ssl_key, ssl_cert)
-
- def __on_apply_cancel_clicked(self, widget):
- if self.cancel_function:
- self.cancel_function()
-
- def __on_add_publisher_cancel_clicked(self, widget):
- self.__on_add_publisher_delete_event(
- self.w_add_publisher_dialog, None)
-
- def __on_modkeybrowse_clicked(self, widget):
- self.__keybrowse(self.w_modify_repository_dialog,
- self.w_repositorymodify_key_entry,
- self.w_repositorymodify_cert_entry)
-
- def __on_modcertbrowse_clicked(self, widget):
- self.__certbrowse(self.w_modify_repository_dialog,
- self.w_repositorymodify_cert_entry)
-
- def __on_keybrowse_clicked(self, widget):
- self.__keybrowse(self.w_add_publisher_dialog,
- self.w_key_entry, self.w_cert_entry)
-
- def __on_certbrowse_clicked(self, widget):
- self.__certbrowse(self.w_add_publisher_dialog,
- self.w_cert_entry)
-
- def __on_add_publisher_c_close_clicked(self, widget):
- self.__on_add_publisher_complete_delete_event(
- self.w_add_publisher_comp_dialog, None)
-
- def __on_manage_publishers_delete_event(self, widget, event):
- self.__delete_widget_handler_hide(widget, event)
- if self.no_changes > 0:
- self.parent.reload_packages()
- return True
-
- def __g_delete_widget_handler_hide(self, widget, event):
- self.__delete_widget_handler_hide(widget, event)
- return False
-
- def __on_manage_add_clicked(self, widget):
- self.w_add_publisher_url.grab_focus()
- self.w_registration_box.hide()
- self.__reset_error_label()
- self.w_add_publisher_dialog.show_all()
-
- def __reset_error_label(self):
- self.w_add_error_label.set_markup(self.publisher_info)
- self.w_add_error_label.set_sensitive(False)
- self.w_add_error_label.show()
-
- def __on_manage_modify_clicked(self, widget):
- itr, model = self.__get_selected_publisher_itr_model()
- if itr and model:
- pub = model.get_value(itr, enumerations.PUBLISHER_OBJECT)
- self.__modify_publisher_dialog(pub)
-
- def __on_manage_remove_clicked(self, widget):
- itr, model = self.__get_selected_publisher_itr_model()
- tsel = self.w_publishers_treeview.get_selection()
- selection = tsel.get_selected()
- sel_itr = selection[1]
- sorted_model = selection[0]
- sorted_path = sorted_model.get_path(sel_itr)
- if itr and model:
- current_priority = model.get_value(itr,
- enumerations.PUBLISHER_PRIORITY_CHANGED)
- model.set_value(itr, enumerations.PUBLISHER_REMOVED, True)
- for element in model:
- if element[enumerations.PUBLISHER_PRIORITY_CHANGED] > \
- current_priority:
- element[
- enumerations.PUBLISHER_PRIORITY_CHANGED] -= 1
- tsel.select_path(sorted_path)
- if not tsel.path_is_selected(sorted_path):
- row = sorted_path[0]-1
- if row >= 0:
- tsel.select_path((row,))
- if len(sorted_model) == 0:
- self.__set_empty_pub_list()
-
- def __on_manage_move_up_clicked(self, widget):
- before_name = None
- itr, model = self.__get_selected_publisher_itr_model()
- current_priority = model.get_value(itr,
- enumerations.PUBLISHER_PRIORITY_CHANGED)
- current_name = model.get_value(itr, enumerations.PUBLISHER_NAME)
- for element in model:
- if current_priority == \
- element[enumerations.PUBLISHER_PRIORITY_CHANGED]:
- element[
- enumerations.PUBLISHER_PRIORITY_CHANGED] -= 1
- elif element[enumerations.PUBLISHER_PRIORITY_CHANGED] \
- == current_priority - 1 :
- before_name = element[enumerations.PUBLISHER_NAME]
- element[
- enumerations.PUBLISHER_PRIORITY_CHANGED] += 1
- self.priority_changes.append([enumerations.PUBLISHER_MOVE_BEFORE,
- current_name, before_name])
- self.__enable_disable_updown_btn(itr, model)
- self.__move_to_cursor()
-
- def __move_to_cursor(self):
- itr, model = self.__get_fitr_model_from_tree(self.w_publishers_treeview)
- if itr and model:
- path = model.get_path(itr)
- self.w_publishers_treeview.scroll_to_cell(path)
-
- def __on_manage_move_down_clicked(self, widget):
- after_name = None
- itr, model = self.__get_selected_publisher_itr_model()
- current_priority = model.get_value(itr,
- enumerations.PUBLISHER_PRIORITY_CHANGED)
- current_name = model.get_value(itr, enumerations.PUBLISHER_NAME)
- for element in model:
- if current_priority == \
- element[enumerations.PUBLISHER_PRIORITY_CHANGED]:
- element[
- enumerations.PUBLISHER_PRIORITY_CHANGED] += 1
- elif element[enumerations.PUBLISHER_PRIORITY_CHANGED] \
- == current_priority + 1 :
- after_name = element[enumerations.PUBLISHER_NAME]
- element[
- enumerations.PUBLISHER_PRIORITY_CHANGED] -= 1
- self.priority_changes.append([enumerations.PUBLISHER_MOVE_AFTER,
- current_name, after_name])
- self.__enable_disable_updown_btn(itr, model)
- self.__move_to_cursor()
-
- def __on_manage_cancel_clicked(self, widget):
- self.__on_manage_publishers_delete_event(
- self.w_manage_publishers_dialog, None)
-
- def __on_manage_ok_clicked(self, widget):
- self.__prepare_confirmation_dialog()
-
- def __on_publishers_apply_delete_event(self, widget, event):
- self.__on_apply_cancel_clicked(None)
- return True
-
- def __on_addmirror_button_clicked(self, widget):
- if self.w_addmirror_button.get_property('sensitive') == 0:
- return
- new_mirror = self.w_addmirror_entry.get_text()
- self.__add_mirror(new_mirror)
-
- def __on_addorigin_button_clicked(self, widget):
- if self.w_addorigin_button.get_property('sensitive') == 0:
- return
- new_origin = self.w_addorigin_entry.get_text()
- self.__add_origin(new_origin)
-
- def __on_rmmirror_button_clicked(self, widget):
- self.__rm_mirror()
-
- def __on_rmorigin_button_clicked(self, widget):
- self.__rm_origin()
-
- def __on_repositorymodifyok_clicked(self, widget):
- pub = self.repository_modify_publisher
- if pub == None:
- return
- error_dialog_title = _("Modify Publisher - %s") % \
- self.__get_pub_display_name(pub)
- text = self.w_pub_sig_name_entry.get_text()
- req_names = self.w_pub_sig_name_radiobutton.get_active()
- if not gui_misc.check_sig_required_names_policy(text,
- req_names, error_dialog_title):
- return
-
- self.publishers_apply.set_title(_("Applying Changes"))
- self.__run_with_prog_in_thread(self.__proceed_modifyrepo_ok)
-
- def __on_modifydialog_delete_event(self, widget, event):
- if self.w_repositorymodifyok_button.get_sensitive():
- self.__on_repositorymodifyok_clicked(None)
- elif not self.is_alias_valid and self.name_error:
- pub = self.repository_modify_publisher
- gui_misc.error_occurred(None, self.name_error,
- _("Modify Publisher - %s") %
- self.__get_pub_display_name(pub),
- gtk.MESSAGE_INFO)
- return True
-
- def __on_repositorymodifycancel_clicked(self, widget):
- self.__delete_widget_handler_hide(
- self.w_modify_repository_dialog, None)
-
- def __on_cancel_conf_clicked(self, widget):
- self.__delete_widget_handler_hide(
- self.w_confirmation_dialog, None)
-
- def __on_ok_conf_clicked(self, widget):
- self.w_confirmation_dialog.hide()
- self.publishers_apply.set_title(_("Applying Changes"))
- self.__run_with_prog_in_thread(self.__proceed_after_confirmation,
- self.w_manage_publishers_dialog)
-
-#-----------------------------------------------------------------------------#
-# Static Methods
-#-----------------------------------------------------------------------------#
- @staticmethod
- def __check_if_ignore(pub, removed_list):
- """If we remove a publisher from our model, the priorities of
- subsequent publishers are decremented. We need to ignore the
- priority changes caused solely by publisher(s) removal.
- This function returns True if the priority change for a publisher
- is due to publisher(s) removal or False otherwise."""
- priority_sum = 0
- priority = pub[enumerations.PUBLISHER_PRIORITY]
- priority_changed = pub[enumerations.PUBLISHER_PRIORITY_CHANGED]
- for num in removed_list:
- if num < priority:
- priority_sum += 1
- return (priority == priority_changed + priority_sum)
-
- @staticmethod
- def __on_add_pub_help_clicked(widget):
- gui_misc.display_help("add-publisher")
-
- @staticmethod
- def __on_manage_help_clicked(widget):
- gui_misc.display_help("manage-publisher")
-
- def __on_modify_repo_help_clicked(self, widget):
- pagenum = self.w_modify_pub_notebook.get_current_page()
- if pagenum == MODIFY_NOTEBOOK_GENERAL_PAGE:
- tag = "modify-publisher"
- elif pagenum == MODIFY_NOTEBOOK_CERTIFICATE_PAGE:
- tag = "manage-certs"
- else:
- tag = "pub-sig-policy"
- gui_misc.display_help(tag)
-
- @staticmethod
- def __update_publisher_details(pub, details_view):
- if pub == None:
- return
- details_buffer = details_view.get_buffer()
- details_buffer.set_text("")
- uri_itr = details_buffer.get_start_iter()
- repo = pub.repository
- num = len(repo.origins)
- if pub.sys_pub:
- details_buffer.insert_with_tags_by_name(uri_itr,
- _("System Publisher"),
- "level0")
- sys_pub_str = _("Cannot be modified or removed.")
- details_buffer.insert(uri_itr, "\n%s\n" % sys_pub_str)
- origin_txt = ngettext("Origin:\n", "Origins:\n", num)
- details_buffer.insert_with_tags_by_name(uri_itr,
- origin_txt, "level0")
- uri_itr = details_buffer.get_end_iter()
- for origin in repo.origins:
- details_buffer.insert(uri_itr, "%s\n" % str(origin))
-
- def __show_errors(self, errors, missing_ssl = False):
- error_msg = ""
- crerr = ""
- msg_type = gtk.MESSAGE_ERROR
- framework_error = False
-
- msg_title = _("Publisher Error")
- for err in errors:
- if isinstance(err[1], api_errors.CatalogRefreshException):
- res = gui_misc.get_catalogrefresh_exception_msg(err[1])
- crerr = res[0]
- framework_error = res[1]
- logger.error(crerr)
- gui_misc.notify_log_error(self.parent)
- else:
- error_msg += str(err[1])
- error_msg += "\n\n"
- # If the only error is a CatalogRefreshException, which we
- # normally just log but do not display to the user, then
- # display it to the user.
- if error_msg == "":
- error_msg = crerr
- error_msg += "\n"
- if framework_error and missing_ssl:
- error_msg += _("Note: this may may be the result "
- "of specifying a https Origin, "
- "but no SSL key and certificate.\n")
- elif missing_ssl:
- error_msg += _("Note: this error may be the result of "
- "specifing a https URI, "
- "but no SSL key and certificate.\n")
- if error_msg != "":
- gui_misc.error_occurred(None, error_msg, msg_title, msg_type)
-
- @staticmethod
- def __keybrowse(w_parent, key_entry, cert_entry):
- chooser = gtk.FileChooserDialog(
- title=_("Specify SSL Key File"),
- parent = w_parent,
- action=gtk.FILE_CHOOSER_ACTION_OPEN,
- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_OPEN, gtk.RESPONSE_OK))
- chooser.set_default_response(gtk.RESPONSE_OK)
- chooser.set_transient_for(w_parent)
- chooser.set_modal(True)
- response = chooser.run()
- if response == gtk.RESPONSE_OK:
- key = chooser.get_filename()
- key_entry.set_text(key)
- cert = key.replace("key", "certificate")
- if key != cert and \
- cert_entry.get_text() == "":
- if os.path.isfile(cert):
- cert_entry.set_text(cert)
- chooser.destroy()
-
- @staticmethod
- def __certbrowse(w_parent, cert_entry):
- chooser = gtk.FileChooserDialog(
- title=_("Specify SSL Certificate File"),
- parent = w_parent,
- action=gtk.FILE_CHOOSER_ACTION_OPEN,
- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_OPEN, gtk.RESPONSE_OK))
- chooser.set_default_response(gtk.RESPONSE_OK)
- chooser.set_transient_for(w_parent)
- chooser.set_modal(True)
- response = chooser.run()
- if response == gtk.RESPONSE_OK:
- cert_entry.set_text(
- chooser.get_filename())
- chooser.destroy()
-
- @staticmethod
- def __delete_widget_handler_hide(widget, event):
- widget.hide()
- return True
-
- def __check_publisher_exists(self, api_o, name, origin_url):
- try:
- pub = api_o.get_publisher(prefix=name, alias=name,
- duplicate=True)
- raise URIExistingPublisher(origin_url, pub)
- except api_errors.UnknownPublisher:
- return False
- except api_errors.ApiException, e:
- gobject.idle_add(self.__show_errors, [(name, e)])
- return True
-
- def __setup_publisher_from_uri(self, alias, origin_url, ssl_key, ssl_cert):
- try:
- self.api_o.reset()
- repo = publisher.RepositoryURI(origin_url,
- ssl_key = ssl_key, ssl_cert = ssl_cert)
- pubs = self.api_o.get_publisherdata(repo=repo)
- if not pubs:
- raise NoPublishersForURI(origin_url)
- src_pub = sorted(pubs)[0]
- #For now only handling single Pub per Origin
- if len(pubs) > 1:
- if self.webinstall_new:
- client_name = _("Web Install")
- else:
- client_name = _("Package Manager")
- user_image_root = ""
- if self.parent.image_directory != "/":
- user_image_root = "-R " + \
- self.parent.image_directory + " "
- logger.warning(
- _("Origin URI: %(origin_url)s"
- "\nhas %(number_pubs)d publishers associated with it.\n"
- "%(client_name)s will attempt to add the first "
- "publisher, %(pub_name)s.\n"
- "To add the remaining publishers use the command:\n"
- "'pkg %(user_image_root)sset-publisher "
- "-p %(origin_url)s'") %
- {"origin_url": origin_url,
- "number_pubs": len(pubs),
- "client_name": client_name,
- "pub_name": src_pub.prefix,
- "user_image_root": user_image_root,
- })
- if not self.webinstall_new:
- gui_misc.notify_log_warning(self.parent)
- src_repo = src_pub.repository
- add_origins = []
- if not src_repo or not src_repo.origins:
- add_origins.append(origin_url)
- repo = src_pub.repository
- if not repo:
- repo = publisher.Repository()
- src_pub.repository = repo
- for url in add_origins:
- repo.add_origin(url)
- return (src_pub, repo, True)
- except api_errors.ApiException, e:
- if self.__is_ssl_scheme(origin_url) and \
- ((not ssl_key or len(ssl_key) == 0) or \
- (not ssl_cert or len(ssl_cert) == 0)) and \
- gui_misc.is_frameworkerror(e):
- ssl_missing = True
- else:
- ssl_missing = False
- gobject.idle_add(self.__show_errors, [(alias, e)], ssl_missing)
- return (None, None, False)
-
- def __get_or_create_pub_with_url(self, api_o, name, origin_url):
- new_pub = False
- repo = None
- pub = None
- try:
- pub = api_o.get_publisher(prefix=name, alias=name,
- duplicate=True)
- raise URIExistingPublisher(origin_url, pub)
- except api_errors.UnknownPublisher:
- repo = publisher.Repository()
- # We need to specify a name when creating a publisher
- # object. It does not matter if it is wrong as the
- # __update_publisher() call in __add_repository() will
- # fail and it is dealt with there.
- if name == None:
- name = "None"
- pub = publisher.Publisher(name, repository=repo)
- new_pub = True
- # This part is copied from "def publisher_set(img, args)"
- # from the client.py as the publisher API is not ready yet.
- if not repo.origins:
- repo.add_origin(origin_url)
- origin = repo.origins[0]
- else:
- origin = repo.origins[0]
- origin.uri = origin_url
- except api_errors.ApiException, e:
- gobject.idle_add(self.__show_errors, [(name, e)])
- return (pub, repo, new_pub)
-
- @staticmethod
- def __update_ssl_creds(pub, repo, ssl_cert, ssl_key):
- errors = []
- # Assume the user wanted to update the ssl_cert or ssl_key
- # information for *all* of the currently selected
- # repository's origins and mirrors.
- try:
- for uri in repo.origins:
- if uri.scheme not in publisher.SSL_SCHEMES:
- continue
- uri.ssl_cert = ssl_cert
- uri.ssl_key = ssl_key
- for uri in repo.mirrors:
- if uri.scheme not in publisher.SSL_SCHEMES:
- continue
- uri.ssl_cert = ssl_cert
- uri.ssl_key = ssl_key
- except api_errors.ApiException, e:
- errors.append((pub, e))
- return errors
-
- @staticmethod
- def __get_fitr_model_from_tree(treeview):
- tsel = treeview.get_selection()
- selection = tsel.get_selected()
- itr = selection[1]
- if itr == None:
- return (None, None)
- model = selection[0]
- return (itr, model)
-
- @staticmethod
- def __show_error_label_with_format(w_label, error_string):
- error_str = ERROR_FORMAT % error_string
- w_label.set_markup(error_str)
- w_label.set_sensitive(True)
- w_label.show()
-
- def __is_url_valid(self, url):
- url_error = None
- if len(url) == 0:
- return False, url_error
- try:
- publisher.RepositoryURI(url)
- return True, url_error
- except api_errors.PublisherError:
- # Check whether the user has started typing a valid URL.
- # If he has we do not display an error message.
- valid_start = False
- for val in publisher.SUPPORTED_SCHEMES:
- check_str = "%s://" % val
- if check_str.startswith(url):
- valid_start = True
- break
- if valid_start:
- url_error = None
- else:
- url_error = _("URI is not valid")
- return False, url_error
- except api_errors.ApiException, e:
- self.__show_errors([("", e)])
- return False, url_error
-
- def __validate_ssl_key_cert(self, origin_url, ssl_key, ssl_cert,
- ignore_ssl_check_for_not_https = False):
- '''The SSL Cert and SSL Key may be valid and contain no error'''
- ssl_error = None
- ssl_valid = True
- if origin_url and not self.__is_ssl_scheme(origin_url):
- if ignore_ssl_check_for_not_https:
- return ssl_valid, ssl_error
- if (ssl_key != None and len(ssl_key) != 0) or \
- (ssl_cert != None and len(ssl_cert) != 0):
- ssl_error = _("SSL should not be specified")
- ssl_valid = False
- elif (ssl_key == None or len(ssl_key) == 0) or \
- (ssl_cert == None or len(ssl_cert) == 0):
- ssl_valid = True
- elif origin_url == None or self.__is_ssl_scheme(origin_url):
- if (ssl_key == None or len(ssl_key) == 0) or \
- (ssl_cert == None or len(ssl_cert) == 0):
- # Key and Cert need not be specified
- ssl_valid = True
- elif not os.path.isfile(ssl_key):
- ssl_error = _("SSL Key not found at specified location")
- ssl_valid = False
- elif not os.path.isfile(ssl_cert):
- ssl_error = \
- _("SSL Certificate not found at specified location")
- ssl_valid = False
- return ssl_valid, ssl_error
-
- @staticmethod
- def __is_ssl_scheme(uri):
- ret_val = False
- for val in publisher.SSL_SCHEMES:
- if uri.startswith(val):
- ret_val = True
- break
- return ret_val
-
- @staticmethod
- def __init_mirrors_tree_view(treeview):
- # URI column - 0
- uri_renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_("Mirror URI"),
- uri_renderer, text = 0)
- column.set_expand(True)
- treeview.append_column(column)
-
- @staticmethod
- def __init_origins_tree_view(treeview):
- # URI column - 0
- uri_renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn(_("Origin URI"),
- uri_renderer, text = 0)
- column.set_expand(True)
- treeview.append_column(column)
-
- @staticmethod
- def __get_publishers_liststore():
- return gtk.ListStore(
- gobject.TYPE_INT, # enumerations.PUBLISHER_PRIORITY
- gobject.TYPE_INT, # enumerations.PUBLISHER_PRIORITY_CHANGED
- gobject.TYPE_STRING, # enumerations.PUBLISHER_NAME
- gobject.TYPE_STRING, # enumerations.PUBLISHER_ALIAS
- gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_ENABLED
- gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_STICKY
- gobject.TYPE_PYOBJECT, # enumerations.PUBLISHER_OBJECT
- gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_ENABLE_CHANGED
- gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_STICKY_CHANGED
- gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_REMOVED
- )
-
- @staticmethod
- def __get_mirrors_origins_liststore():
- return gtk.ListStore(
- gobject.TYPE_STRING, # name
- )
-
- @staticmethod
- def __publishers_filter(model, itr):
- return not model.get_value(itr, enumerations.PUBLISHER_REMOVED)
-
- @staticmethod
- def __toggle_data_function(column, renderer, model, itr, data):
- if itr:
- # Do not allow to remove the publisher if it is a system
- # publisher
- val = True
- pub = model.get_value(itr,
- enumerations.PUBLISHER_OBJECT)
- if pub.sys_pub:
- val = False
- renderer.set_property("sensitive", val)
-
- @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
-
-#-----------------------------------------------------------------------------#
-# Public Methods
-#-----------------------------------------------------------------------------#
- def webinstall_new_pub(self, parent, pub = None):
- if pub == None:
- return
- self.repository_modify_publisher = pub
- repo = pub.repository
- origin_uri = ""
- if repo != None and repo.origins != None and len(repo.origins) > 0:
- origin_uri = repo.origins[0].uri
- if origin_uri != None and self.__is_ssl_scheme(origin_uri):
- gui_misc.set_modal_and_transient(self.w_add_publisher_dialog,
- parent)
- self.main_window = self.w_add_publisher_dialog
- self.__on_manage_add_clicked(None)
- self.w_add_publisher_url.set_text(origin_uri)
- self.w_add_publisher_alias.set_text(pub.alias)
- self.w_add_pub_label.hide()
- self.w_add_pub_instr_label.hide()
- self.w_add_publisher_url.set_sensitive(False)
- self.w_add_publisher_alias.set_sensitive(False)
- reg_uri = self.__get_registration_uri(repo)
- if reg_uri == None or len(reg_uri) == 0:
- reg_uri = origin_uri
- self.w_registration_link.set_uri(reg_uri)
- self.w_registration_box.show()
- self.w_ssl_box.show()
- self.__validate_url(self.w_add_publisher_url,
- w_ssl_key=self.w_key_entry, w_ssl_cert=self.w_cert_entry)
- self.w_add_error_label.hide()
- else:
- self.main_window = parent
- self.w_ssl_box.hide()
- self.__do_add_repository()
-
- def webinstall_enable_disable_pubs(self, parent, pub_names, to_enable):
- if pub_names == None:
- return
- num = len(pub_names)
- if to_enable:
- msg = ngettext("Enabling Publisher", "Enabling Publishers", num)
- else:
- msg = ngettext("Disabling Publisher", "Disabling Publishers", num)
- self.publishers_apply.set_title(msg)
-
- self.__run_with_prog_in_thread(self.__proceed_enable_disable,
- parent, None, pub_names, to_enable)
-
- def update_label_text(self, markup_text):
- self.__g_update_details_text(markup_text)
-
- def update_details_text(self, text, *tags):
- self.__g_update_details_text(text, *tags)
-
- def update_progress(self, current_progress, total_progress):
- pass
-
- def start_bouncing_progress(self):
- pass
-
- def is_progress_bouncing(self):
- self.pylintstub = self
- return True
-
- def stop_bouncing_progress(self):
- pass
-
- def display_download_info(self):
- pass
-
- def display_phase_info(self, phase_name, cur_n, goal_n):
- pass
-
- def reset_label_text_after_delay(self):
- pass
-
-class URIExistingPublisher(api_errors.ApiException):
- def __init__(self, uri, pub):
- api_errors.ApiException.__init__(self)
- self.uri = uri
- self.pub = pub
-
- def __str__(self):
- return _("The URI '%(uri)s' points to a publisher "
- "'%(publisher)s' which already exists "
- "on the system.") % { "uri": self.uri,
- "publisher": self.pub }
-
-class NoPublishersForURI(api_errors.ApiException):
- def __init__(self, uri):
- api_errors.ApiException.__init__(self)
- self.uri = uri
-
- def __str__(self):
- return _("There are no publishers associated with the URI "
- "'%s'.") % self.uri
--- a/src/gui/modules/searcherror.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-#!/usr/bin/python
-#
-# 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 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-import sys
-try:
- import pango
-except ImportError:
- sys.exit(1)
-import pkg.gui.misc as gui_misc
-
-class SearchError:
- def __init__(self, builder, gconf, parent):
- self.gconf = gconf
- self.parent = parent
- self.api_search_error_dialog = \
- builder.get_object("api_search_error")
- self.api_search_error_textview = \
- builder.get_object("api_search_error_text")
- self.api_search_checkbox = \
- builder.get_object("api_search_checkbox")
- self.api_search_button = \
- builder.get_object("api_search_button")
- infobuffer = self.api_search_error_textview.get_buffer()
- infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
- self.pylintstub = None
-
- def setup_signals(self):
- signals_table = [
- (self.api_search_checkbox, "toggled",
- self.__on_api_search_checkbox_toggled),
- (self.api_search_button, "clicked",
- self.__on_api_search_button_clicked),
- (self.api_search_error_dialog, "delete_event",
- self.__on_api_search_error_delete_event)
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def set_modal_and_transient(self, parent_window):
- gui_misc.set_modal_and_transient(self.api_search_error_dialog,
- parent_window)
-
- def __on_api_search_error_delete_event(self, widget, event):
- self.__on_api_search_button_clicked(None)
-
- def __on_api_search_button_clicked(self, widget):
- self.api_search_error_dialog.hide()
-
- def __on_api_search_checkbox_toggled(self, widget):
- active = self.api_search_checkbox.get_active()
-
- repos = self.parent.get_current_repos_with_search_errors()
- if len(repos) > 0:
- if active:
- for pub, err_type, err_str in repos:
- if pub not in self.gconf.not_show_repos:
- self.gconf.not_show_repos += pub + ","
- self.pylintstub = err_type
- self.pylintstub = err_str
- else:
- for pub, err_type, err_str in repos:
- self.gconf.not_show_repos = \
- self.gconf.not_show_repos.replace(
- pub + ",", "")
- self.gconf.set_not_show_repos(self.gconf.not_show_repos)
-
- def display_search_errors(self, show_all):
- repos = self.parent.get_current_repos_with_search_errors()
- infobuffer = self.api_search_error_textview.get_buffer()
- infobuffer.set_text("")
- textiter = infobuffer.get_end_iter()
- for pub, err_type, err_str in repos:
-
- if show_all or (pub not in self.gconf.not_show_repos):
- infobuffer.insert_with_tags_by_name(textiter,
- "%(pub)s (%(err_type)s)\n" % {"pub": pub,
- "err_type": err_type}, "bold")
- infobuffer.insert(textiter, "%s\n" % (err_str))
-
- self.api_search_checkbox.set_active(False)
- self.api_search_error_dialog.show()
- self.api_search_button.grab_focus()
-
--- a/src/gui/modules/startpage.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,769 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-import os
-import sys
-import urllib
-import urlparse
-import locale
-import re
-from gettext import ngettext
-
-try:
- import gtkhtml2
- import gtk
-except ImportError:
- sys.exit(1)
-import pkg.gui.misc as gui_misc
-import pkg.gui.parseqs as parseqs
-from pkg.client import global_settings
-import pkg.gui.enumerations as enumerations
-import pkg.gui.repository as repository
-
-logger = global_settings.logger
-
-(
-DISPLAY_LINK,
-CLICK_LINK,
-) = range(2)
-
-# Load Start Page from lang dir if available
-START_PAGE_CACHE_LANG_BASE = "var/pkg/gui_cache/startpagebase/%s/%s"
-START_PAGE_LANG_BASE = "usr/share/package-manager/data/startpagebase/%s/%s"
-START_PAGE_HOME = "startpage.html" # Default page
-START_PAGE_IMAGES_BASE = "/usr/share/package-manager/data/startpagebase/C"
-
-# StartPage Action support for url's on StartPage pages
-PM_ACTION = 'pm-action' # Action field for StartPage url's
-
-# Internal Example: <a href="pm?pm-action=internal&uri=top_picks.html">
-ACTION_INTERNAL = 'internal' # Internal Action value: pm-action=internal
-INTERNAL_URI = 'uri' # Internal field: uri to navigate to in StartPage
- # without protocol scheme specified
-INTERNAL_SEARCH = 'search' # Internal field: search support page action
-INTERNAL_SEARCH_VIEW_RESULTS = "view_recent_search"
- # Internal field: view recent search results
-INTERNAL_SEARCH_VIEW_PUB ="view_pub_packages" # Internal field: view publishers packages
-INTERNAL_SEARCH_VIEW_ALL = "view_all_packages_filter" # Internal field: change to View
- # All Packages
-INTERNAL_SEARCH_ALL_PUBS_PAGE = "search_all_publishers_page"
- #Internal field: go to search all publishers page
-INTERNAL_SEARCH_ALL_PUBS = "search_all_publishers" #Internal field: search all publishers
-INTERNAL_SEARCH_ALL_PUBS_INSTALLED = "search_all_publishers_installed"
- #Internal field: search all publishers installed
-INTERNAL_SEARCH_HELP = "search_help" # Internal field: display search help
-
-INTERNAL_SEARCH_MNG_PUBS = "search_mng_pubs"
- # Internal field: display Manage Publishers dialog
-
-FONTSIZE_H3_DEFAULT = 16 # Default H3 font size when display web page
-FONTSIZE_BODY_DEFAULT = 10 # Default Body font size when display web page
-
-# External Example: <a href="pm?pm-action=external&uri=www.opensolaris.com">
-ACTION_EXTERNAL = 'external' # External Action value: pm-action=external
-EXTERNAL_URI = 'uri' # External field: uri to navigate to in external
- # default browser without protocol scheme specified
-EXTERNAL_PROTOCOL = 'protocol' # External field: optional protocol scheme,
- # defaults to http
-DEFAULT_PROTOCOL = 'http'
-
-# Theme: use High Contrast or Inverse images for HCI and HC themes, specified by prefix
-INFORMATION_TABLE_HEADER = (
- "<table border='0' cellpadding='3' style='table-layout:fixed' >"
- "<TR><TD><IMG SRC = '%(base)s/%(prefix)sdialog-information.png' "
- "style='border-style: none' "
- )
-HIGH_CONTRAST_PREFIX = "hc_"
-HIGH_CONTRAST_INV_PREFIX = "hci_"
-
-debug = False
-
-class StartPage:
- def __init__(self, parent, application_dir):
- self.application_dir = application_dir
- self.current_url = None
- self.document = None
- self.lang = None
- self.lang_root = None
- self.cached_internal_stream = ""
- self.opener = None
- self.parent = parent
- self.start_page_uri = ""
- self.view = None
- self.page_bg = "#ffff"
- self.page_fg = "#0000"
- self.image_prefix = ""
- s = gtk.settings_get_default()
- self.theme_name = s.get_property("gtk-theme-name")
- self.font_scale = 1.0
- self.h3_fontsize = FONTSIZE_H3_DEFAULT
- self.body_fontsize = FONTSIZE_BODY_DEFAULT
- self.show_start_page = False
-
- def setup_startpage(self, show_page = True):
- self.opener = urllib.FancyURLopener()
- self.document = gtkhtml2.Document()
- self.document.connect('request_url', self.__request_url)
- self.document.connect('link_clicked', self.__handle_link)
- self.document.clear()
-
- self.view = gtkhtml2.View()
- self.view.set_document(self.document)
- self.view.connect('request_object', self.__request_object)
- self.view.connect('on_url', self.__on_url)
- self.view.connect('style-set', self.__style_set)
- try:
- result = locale.getlocale(locale.LC_CTYPE)
- self.lang = result[0]
- except locale.Error:
- self.lang = "C"
- if self.lang == None or self.lang == "":
- self.lang = "C"
- self.lang_root = self.lang.split('_')[0]
- # Load Start Page to setup base URL to allow loading images in other pages
- self.load_startpage(show_page)
-
- # Theme: on Theme change setup bg and fg colours and prefix for loading pages
- def __style_set(self, widget, style, data=None):
- self.font_scale = gui_misc.get_scale(
- self.parent.detailspanel.w_generalinfo_textview)
- if self.font_scale < 1.0:
- self.font_scale = 1.0
-
- self.h3_fontsize = \
- int(round(FONTSIZE_H3_DEFAULT * self.font_scale))
- self.body_fontsize = \
- int(round(FONTSIZE_BODY_DEFAULT * self.font_scale))
-
- s = gtk.settings_get_default()
- self.theme_name = s.get_property("gtk-theme-name")
-
- style = self.parent.w_application_treeview.get_style().copy()
- self.page_bg = style.bg[gtk.STATE_NORMAL]
- self.page_fg = style.fg[gtk.STATE_NORMAL]
-
- self.image_prefix = ""
- if self.theme_name == "HighContrastInverse" or \
- self.theme_name == "HighContrastLargePrintInverse":
- self.image_prefix = HIGH_CONTRAST_INV_PREFIX
- elif self.theme_name == "HighContrast" or \
- self.theme_name == "HighContrastLargePrint":
- self.image_prefix = HIGH_CONTRAST_PREFIX
-
- self.handle_resize()
-
- def load_startpage(self, show = True):
- self.show_start_page = show
- if not show:
- return
- self.cached_internal_stream = ""
- if self.__load_startpage_locale(START_PAGE_CACHE_LANG_BASE):
- return
- if self.__load_startpage_locale(START_PAGE_LANG_BASE):
- return
- self.link_load_error(self.start_page_uri)
-
- # Stub handler required by GtkHtml widget
- def __request_object(self, *vargs):
- pass
-
- def __load_startpage_locale(self, start_page_lang_base):
- self.start_page_uri = os.path.join(self.application_dir,
- start_page_lang_base % (self.lang, START_PAGE_HOME))
- if self.__load_internal_uri(self.document, self.start_page_uri):
- return True
-
- if self.lang_root != None and self.lang_root != self.lang:
- self.start_page_uri = os.path.join(self.application_dir,
- start_page_lang_base % (self.lang_root, START_PAGE_HOME))
- if self.__load_internal_uri(self.document, self.start_page_uri):
- return True
-
- self.start_page_uri = os.path.join(self.application_dir,
- start_page_lang_base % ("C", START_PAGE_HOME))
- if self.__load_internal_uri(self.document, self.start_page_uri):
- return True
- return False
-
- # Stub handler required by GtkHtml widget or widget will assert
- def __stream_cancel(self, *vargs):
- pass
-
- def __load_internal_uri(self, document, link):
- self.parent.update_statusbar_message(_("Loading... %s") % link)
- try:
- f = self.__open_url(link)
- except (IOError, OSError):
- self.parent.update_statusbar_message(_("Stopped"))
- return False
- self.current_url = self.__resolve_uri(link)
-
- self.document.clear()
- headers = f.info()
- mime = headers.getheader('Content-type').split(';')[0]
- if mime:
- self.document.open_stream(mime)
- else:
- self.document.open_stream('text/plain')
-
- text = f.read()
- # Theme: use current Theme's bg and fg colours in internally loaded uri
- text = text.replace('<body>',
- "<body fgcolor='%s' bgcolor='%s'>" % (self.page_fg, self.page_bg))
-
- # Theme: setup Start Page for current Theme
- if link.endswith(START_PAGE_HOME):
- text = self.__process_startpage(text)
- self.document.write_stream(text)
- self.document.close_stream()
- self.parent.update_statusbar_message(_("Done"))
- return True
-
- # Theme: setup Start Page for the current Theme
- def __process_startpage(self, text):
- # Strip background and all style colors for High Contrast, Inverse and
- # Low Contrast Themes
- if self.theme_name.startswith("HighContrast") or \
- self.theme_name.startswith("LowContrast"):
- text = re.sub("background-color: #\w+; ", "", text)
- text = re.sub('style="background-color: #\w+"', "", text)
- text = re.sub("color: #\w+;", "", text)
- if self.font_scale > 1.0:
- text = re.sub("font-size: 20pt;",
- "font-size: %dpx;" % int(round(20 * self.font_scale)), text)
- text = re.sub("font-size: 15px;",
- "font-size: %dpx;" % int(round(15 * self.font_scale)), text)
- text = re.sub("font-size: 14px;",
- "font-size: %dpx;" % int(round(14 * self.font_scale)), text)
- text = re.sub('width="125"',
- 'width="%d"' % int(round(125 * self.font_scale)), text)
-
- # Use High Contrast and Inverse images for HC and HCI themes
- if self.image_prefix != "":
- text = re.sub("/\w*install.png",
- "/" + self.image_prefix + "install.png", text)
- # OpenSolaris icon renders poorly on Low Contrast and dark nimbus themes
- # replace with text link
- if self.theme_name.startswith("LowContrast") or \
- self.theme_name == "dark-nimbus":
- text = re.sub(
- '<td><a href="http://www.opensolaris.com">'
- '<IMG SRC = "opensolaris.png" align="right"/></a></td>',
- '<td align="right"><a href="http://www.opensolaris.com">'
- 'OpenSolaris... </a></td>', text)
- elif self.image_prefix != "":
- text = re.sub(
- "opensolaris.png",
- self.image_prefix + "opensolaris.png", text)
- return text
-
- def __request_url(self, document, url, stream):
- try:
- f = self.__open_url(url)
- except (IOError, OSError), err:
- logger.error(str(err))
- gui_misc.notify_log_error(self.parent)
- return
- stream.set_cancel_func(self.__stream_cancel)
- stream.write(f.read())
-
- def __handle_link(self, document, link, handle_what = CLICK_LINK):
- query_dict = self.__urlparse_qs(link)
-
- action = None
- if query_dict.has_key(PM_ACTION):
- action = query_dict[PM_ACTION][0]
- elif handle_what == DISPLAY_LINK:
- return link
-
- search_action = None
- if action == ACTION_INTERNAL:
- if query_dict.has_key(INTERNAL_SEARCH):
- search_action = query_dict[INTERNAL_SEARCH][0]
-
- s1, e1 = self.parent.get_start_end_strings()
-
- # Browse a Publisher
- if search_action and search_action.find(INTERNAL_SEARCH_VIEW_PUB) > -1:
- pub = re.findall(r'<b>(.*)<\/b>', search_action)[0]
- if handle_what == DISPLAY_LINK:
- pub_name = \
- self.parent.get_publisher_display_name_from_prefix(
- pub)
- return _("View packages in %(s1)s%(pub)s%(e1)s") % \
- {"s1": s1, "pub": \
- pub_name, "e1": e1}
- self.parent.browse_publisher(pub)
- return
-
- # Go to Search in All Publishers page
- if search_action and search_action == INTERNAL_SEARCH_ALL_PUBS_PAGE:
- if handle_what == DISPLAY_LINK:
- return _("Go to Search %(s1)sAll Publishers%(e1)s page")\
- % {"s1": s1, "e1": e1}
- self.parent.pm_setup_search_all_page()
- return
-
- # Search in All Publishers
- if search_action and search_action == INTERNAL_SEARCH_ALL_PUBS:
- if handle_what == DISPLAY_LINK:
- return _("Search within %(s1)sAll Publishers%(e1)s") % \
- {"s1": s1, "e1": e1}
- self.parent.handle_search_all_publishers()
- return
-
- # Change view to All Publishers (Installed)
- if search_action and search_action == INTERNAL_SEARCH_ALL_PUBS_INSTALLED:
- if handle_what == DISPLAY_LINK:
- return _("View %(s1)sAll Installed Packages%(e1)s") % \
- {"s1": s1, "e1": e1}
- self.parent.handle_view_all_publishers_installed()
- return
- # Launch Search Help
- if search_action and search_action == INTERNAL_SEARCH_HELP:
- if handle_what == DISPLAY_LINK:
- return _("Display %(s1)sSearch Help%(e1)s") % \
- {"s1": s1, "e1": e1}
- self.parent.update_statusbar_message(
- _("Loading %(s1)sSearch Help%(e1)s ...") %
- {"s1": s1, "e1": e1})
- gui_misc.display_help("search-pkg")
- return
-
- if search_action and search_action == INTERNAL_SEARCH_MNG_PUBS:
- if handle_what == DISPLAY_LINK:
- return _("Display %(s1)sManage Publishers%(e1)s") % \
- {"s1": s1, "e1": e1}
- self.parent.update_statusbar_message(
- _("Loading %(s1)sManage Publishers%(e1)s ...") %
- {"s1": s1, "e1": e1})
-
- repository.Repository(self.parent,
- self.parent.image_directory,
- action=enumerations.MANAGE_PUBLISHERS,
- main_window = self.parent.w_main_window,
- gconf = self.parent.gconf)
- return
-
- # View Recent Search Results
- if search_action and \
- search_action.find(INTERNAL_SEARCH_VIEW_RESULTS) > -1:
- recent_search = \
- re.findall(r'<span>(.*)<\/span>', search_action)[0]
- if handle_what == DISPLAY_LINK:
- return _("View results for %s") % recent_search
- self.parent.goto_recent_search(recent_search)
- return
-
- # Change View to All Packages
- if search_action and search_action == INTERNAL_SEARCH_VIEW_ALL:
- if handle_what == DISPLAY_LINK:
- return _("Change View to %(s1)sAll Packages%(e1)s") % \
- {"s1": s1, "e1": e1}
- self.parent.set_view_all_packages()
- return
- # Internal Browse
- if action == ACTION_INTERNAL:
- if query_dict.has_key(INTERNAL_URI):
- int_uri = query_dict[INTERNAL_URI][0]
- if handle_what == DISPLAY_LINK:
- return int_uri
- else:
- if handle_what == CLICK_LINK:
- self.link_load_error(
- _("No URI specified"))
- return
- if handle_what == CLICK_LINK and \
- not self.__load_internal_uri(document, int_uri):
- self.link_load_error(int_uri)
- return
- # External browse
- elif action == ACTION_EXTERNAL:
- if query_dict.has_key(EXTERNAL_URI):
- ext_uri = query_dict[EXTERNAL_URI][0]
- else:
- if handle_what == CLICK_LINK:
- self.link_load_error(
- _("No URI specified"))
- return
- if query_dict.has_key(EXTERNAL_PROTOCOL):
- protocol = query_dict[EXTERNAL_PROTOCOL][0]
- else:
- protocol = DEFAULT_PROTOCOL
-
- if handle_what == DISPLAY_LINK:
- return protocol + "://" + ext_uri
- self.parent.open_link(protocol + "://" + ext_uri)
- return
- elif handle_what == DISPLAY_LINK:
- return None
- elif action == None:
- if link and link.endswith(".p5i"):
- self.parent.invoke_webinstall(link)
- return
- self.parent.open_link(link)
- return
- # Handle empty and unsupported actions
- elif action == "":
- self.link_load_error(_("Empty Action not supported"))
- return
- elif action != None:
- self.link_load_error(
- _("Action not supported: %s") % action)
- return
-
- def __on_url(self, view, link):
- # Handle mouse over events on links and reset when not on link
- if link == None or link == "":
- self.parent.update_statusbar()
- else:
- display_link = self.__handle_link(None, link, DISPLAY_LINK)
- if display_link != None:
- self.parent.update_statusbar_message(display_link)
- else:
- self.parent.update_statusbar()
-
- def __open_url(self, url):
- uri = self.__resolve_uri(url)
- return self.opener.open(uri)
-
- def __resolve_uri(self, uri):
- if self.__is_relative_to_server(uri) and self.current_url != uri:
- return urlparse.urljoin(self.current_url, uri)
- return uri
-
- @staticmethod
- def __is_relative_to_server(url):
- parts = urlparse.urlparse(url)
- if parts[0] or parts[1]:
- return 0
- return 1
-
- def __load_internal_page(self, text =""):
- self.cached_internal_stream = text
- self.document.clear()
- self.view.show()
- self.document.open_stream('text/html')
- # Theme: use Theme's bg and fg colours in loaded internal page
-
- display = ("<html><head><meta http-equiv='Content-Type' "
- "content='text/html; charset=UTF-8'></head>"
- "<style>h3 {font-size:%(h3_fs)dpt}</style>"
- "<style>body {font-size:%(body_fs)dpt}</style><body "
- "fgcolor='%(fg)s' bgcolor='%(bg)s'>%(text)s</body></html>" %
- {"h3_fs": self.h3_fontsize, "body_fs": self.body_fontsize,
- "fg": self.page_fg, "bg": self.page_bg, "text": text})
-
- self.document.write_stream(display)
- self.document.close_stream()
-
- def load_blank(self):
- self.__load_internal_page()
-
- def handle_resize(self):
- if self.cached_internal_stream == "":
- if self.show_start_page:
- self.load_startpage()
- return
- # Theme: setup images for current Theme in self.cached_internal_stream
- # before reloading
- self.cached_internal_stream = re.sub(
- "/\w*dialog-information.png",
- "/" + self.image_prefix + "dialog-information.png",
- self.cached_internal_stream)
- self.cached_internal_stream = re.sub(
- "/\w*dialog-warning.png",
- "/" + self.image_prefix + "dialog-warning.png",
- self.cached_internal_stream)
-
- self.__load_internal_page(self.cached_internal_stream)
-
- def setup_search_all_no_pubs_page(self):
- tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
- "prefix": self.image_prefix}
- tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
- "</TD><TD><h3><b>Search All Publishers</b></h3><TD></TD>"
- "</TR><TR><TD></TD><TD> There is nothing to search as there are no "
- "configured or enabled publishers.</TD></TR>"
- )
-
- tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
- "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
- "<TR><TD></TD><TD<TD>"
- )
-
- tbl_body += _("<li style='padding-left:7px'>"
- "Add or enable publishers: <a href='pm?pm-action=internal&search="
- "%s'>Manage Publishers</a></li></TD></TR>") % INTERNAL_SEARCH_MNG_PUBS
- tbl_footer = "</table>"
- self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
-
-
- def setup_search_all_page(self, publisher_list, publisher_all):
- if not publisher_list:
- self.setup_search_all_no_pubs_page()
- return
- tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
- "prefix": self.image_prefix}
- tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
- "</TD><TD><h3><b>Search All Publishers</b></h3><TD></TD></TR>"
- "<TR><TD></TD><TD> Use the Search field to search for packages "
- "within the following Publishers:</TD></TR>"
- )
- tbl_body = "<TR><TD></TD><TD>"
- pub_browse_list = ""
- for (prefix, pub_alias) in publisher_list:
- if pub_alias != None and len(pub_alias) > 0:
- pub_name = "%s (%s)" % (pub_alias, prefix)
- else:
- pub_name = prefix
-
- tbl_body += "<li style='padding-left:7px'>%s</li>" % pub_name
- pub_browse_list += "<li style='padding-left:7px'><a href="
- pub_browse_list += "'pm?pm-action=internal&search=%s" % \
- INTERNAL_SEARCH_VIEW_PUB
- if pub_alias != None and len(pub_alias) > 0:
- name = pub_alias
- else:
- name = pub_name
- pub_browse_list += " <b>%s</b>'>%s</a></li>" % \
- (prefix, name)
- tbl_body += "<TD></TD></TR>"
- tbl_body += _("<TR><TD></TD><TD></TD></TR>"
- "<TR><TD></TD><TD>Click on the Publishers below to view their list "
- "of packages:</TD></TR>"
- )
- tbl_body += "<TR><TD></TD><TD>"
- tbl_body += pub_browse_list
- tbl_body += "<TD></TD></TR>"
-
- pub_browse_all = "<li style='padding-left:7px'><a href="
- pub_browse_all += "'pm?pm-action=internal&search=%s" % \
- INTERNAL_SEARCH_VIEW_PUB
- pub_browse_all += " <b>%s</b>'>%s</a></li>" % \
- (publisher_all, publisher_all)
- tbl_body += _("<TR><TD></TD><TD></TD></TR>"
- "<TR><TD></TD><TD>Click on the link below to view the full list "
- "of packages:</TD></TR>"
- )
- tbl_body += "<TR><TD></TD><TD>"
- tbl_body += pub_browse_all
- tbl_body += "<TD></TD></TR>"
- tbl_footer = "</table>"
- self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
-
- def setup_search_installed_page(self, text):
- tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
- "prefix": self.image_prefix}
- tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
- "</TD><TD><h3><b>Search in All Installed Packages</b></h3><TD></TD>"
- "</TR><TR><TD></TD><TD> Search is <b>not</b> supported in "
- "All Installed Packages.</TD></TR>"
- )
-
- tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
- "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
- "<TR><TD></TD><TD<TD>"
- )
-
- tbl_body += _("<li style='padding-left:7px'>Return to view "
- "All Installed Packages <a href='pm?pm-action=internal&search="
- "%s'>(Installed)</a></li>") % INTERNAL_SEARCH_ALL_PUBS_INSTALLED
- tbl_body += _("<li style='padding-left:7px'>Search for <b>%(text)s"
- "</b> using All Publishers <a href='pm?pm-action=internal&search="
- "%(all_pubs)s'>(Search)</a></li>") % \
- {"text": text, "all_pubs": INTERNAL_SEARCH_ALL_PUBS}
-
- tbl_body += _("<li style='padding-left:7px'>"
- "See <a href='pm?pm-action=internal&search="
- "%s'>Search Help</a></li></TD></TR>") % INTERNAL_SEARCH_HELP
- tbl_footer = "</table>"
- self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
-
- def setup_search_zero_results_page(self, name, text, is_all_publishers):
- tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
- "prefix": self.image_prefix}
- tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
- "</TD><TD><h3><b>Search Results</b></h3><TD></TD></TR>"
- "<TR><TD></TD><TD>No packages found in <b>%(pub)s</b> "
- "matching <b>%(text)s</b></TD></TR>") % {"pub": name, "text": text}
-
- tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
- "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
- "<TR><TD></TD><TD<TD>"
- "<li style='padding-left:7px'>Check your spelling</li>"
- "<li style='padding-left:7px'>Try new search terms</li>"
- )
- if not is_all_publishers:
- tbl_body += _("<li style='padding-left:7px'>Search for <b>"
- "%(text)s</b> within <a href='pm?pm-action=internal&search="
- "%(all_pubs)s'>All Publishers</a></li>") % \
- {"text": text, "all_pubs": INTERNAL_SEARCH_ALL_PUBS}
-
- tbl_body += _("<li style='padding-left:7px'>"
- "See <a href='pm?pm-action=internal&search="
- "%s'>Search Help</a></li></TD></TR>") % INTERNAL_SEARCH_HELP
- tbl_footer = "</table>"
- self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
-
- def setup_recent_search_page(self, searches_list):
- tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
- "prefix": self.image_prefix}
- tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
- "</TD><TD><h3><b>Recent Searches</b></h3><TD></TD></TR>"
- "<TR><TD></TD><TD> Access stored results from recent searches "
- "in this session.</TD></TR>"
- )
- tbl_body = "<TR><TD></TD><TD>"
- search_list = ""
- for search in searches_list:
- search_list += "<li style='padding-left:7px'>%s: <a href=" % \
- search
- search_list += "'pm?pm-action=internal&search=%s" % \
- INTERNAL_SEARCH_VIEW_RESULTS
- search_list += " <span>%s</span>'>" % search
- search_list += _("results")
- search_list += "</a></li>"
-
- if len(searches_list) > 0:
- tbl_body += "<TR><TD></TD><TD></TD></TR><TR><TD></TD><TD>"
- tbl_body += ngettext(
- "Click on the search results link below to view the stored "
- "results:", "Click on one of the search results links below "
- "to view the stored results:",
- len(searches_list)
- )
- tbl_body += "</TD></TR><TR><TD></TD><TD>"
- tbl_body += search_list
- tbl_body += "<TD></TD></TR>"
- tbl_footer = "</table>"
- self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
-
- def setup_zero_filtered_results_page(self, length_visible_list, filter_desc):
- tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
- "prefix": self.image_prefix}
- tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
- "</TD><TD><h3><b>View Packages</b></h3><TD></TD></TR><TR><TD></TD>"
- "<TD>")
- tbl_header += ngettext(
- "There is one package in this category, "
- "however it is not visible in the selected View:\n"
- "<li style='padding-left:7px'><b>%s</b></li>",
- "There are a number of packages in this category, "
- "however they are not visible in the selected View:\n"
- "<li style='padding-left:7px'><b>%s</b></li>",
- length_visible_list) % filter_desc
- tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
- "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
- "<TR><TD></TD><TD<TD>"
- )
- tbl_body += _("<li style='padding-left:7px'>"
- "<a href='pm?pm-action=internal&"
- "search=%s'>Change View to All Packages</a></li>") % \
- INTERNAL_SEARCH_VIEW_ALL
- tbl_footer = "</TD></TR></table>"
- self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
-
- def setup_search_zero_filtered_results_page(self, text, num, filter_desc):
- tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
- "prefix": self.image_prefix}
- tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
- "</TD><TD><h3><b>Search Results</b></h3><TD></TD></TR><TR><TD></TD>"
- "<TD>")
- tbl_header += ngettext(
- "Found <b>%(num)s</b> package matching <b>%(text)s</b> "
- "in All Packages, however it is not listed in the "
- "<b>%(filter)s</b> View.",
- "Found <b>%(num)s</b> packages matching <b>%(text)s</b> "
- "in All Packages, however they are not listed in the "
- "<b>%(filter)s</b> View.", num) % {"num": num, "text": text,
- "filter": filter_desc}
-
- tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
- "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
- "<TR><TD></TD><TD<TD>"
- )
- tbl_body += _("<li style='padding-left:7px'>"
- "<a href='pm?pm-action=internal&"
- "search=%s'>Change View to All Packages</a></li>") % \
- INTERNAL_SEARCH_VIEW_ALL
- tbl_footer = "</TD></TR></table>"
- self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
-
- def setup_search_wildcard_page(self):
- tbl_header = _(
- "<table border='0' cellpadding='3' style='table-layout:fixed' >"
- "<TR><TD><IMG SRC = '%(base)s/%(prefix)sdialog-warning.png' "
- "style='border-style: "
- "none' alt='[Warning]' title='Warning' ALIGN='bottom'></TD>"
- "<TD><h3><b>Search Warning</b></h3><TD></TD></TR>"
- "<TR><TD></TD><TD>Search using only the wildcard character, "
- "<b>*</b>, is not supported in All Publishers</TD></TR>"
- ) % {"base": START_PAGE_IMAGES_BASE, "prefix": self.image_prefix}
- tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
- "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
- "<TR><TD></TD><TD<TD>"
- "<li style='padding-left:7px'>Try new search terms</li>"
- )
- tbl_body += _("<li style='padding-left:7px'>"
- "Return to <a href='pm?pm-action=internal&search="
- "%s'>Search All Publishers</a></li>") \
- % INTERNAL_SEARCH_ALL_PUBS_PAGE
- tbl_body += _("<li style='padding-left:7px'>"
- "See <a href='pm?pm-action=internal&search="
- "%s'>Search Help</a></li></TD></TR>") % INTERNAL_SEARCH_HELP
- tbl_footer = "</table>"
- self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
-
- def link_load_error(self, link):
- tbl_header = _(
- "<table border='0' cellpadding='3' style='table-layout:fixed' >"
- "<TR><TD><a href='stub'></a>"
- "<IMG SRC = '%(base)s/%(prefix)sdialog-warning.png' "
- "style='border-style: "
- "none' alt='[Warning]' title='Warning' ALIGN='bottom'>"
- "</TD><TD><h3><b>Warning</b></h3><TD></TD></TR>"
- "<TR><TD></TD><TD>Unable to load the following URI: </TD></TR>"
- ) % {"base": START_PAGE_IMAGES_BASE, "prefix": self.image_prefix}
- tbl_body = "<TR><TD></TD><TD<TD>"
- tbl_body +="<li style='padding-left:7px'>%s</li></TD></TR>" % (link)
- tbl_body += _("<TR><TD></TD><TD<TD></TD>"
- "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
- "<TR><TD></TD><TD<TD>"
- )
- tbl_body += _("<li style='padding-left:7px'>"
- "Return to <a href='pm?pm-action=internal&uri="
- "%s'>Start Page</a></li></TD></TR>") % START_PAGE_HOME
- tbl_footer = "</table>"
- self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
-
- @staticmethod
- def __urlparse_qs(url, keep_blank_values=0, strict_parsing=0):
- scheme, netloc, url, params, querystring, fragment = urlparse.urlparse(
- url)
- if debug:
- print ("Query: scheme %s, netloc %s, url %s, params %s,"
- "querystring %s, fragment %s"
- % (scheme, netloc, url, params, querystring, fragment))
- return parseqs.parse_qs(querystring)
--- a/src/gui/modules/uarenamebe.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,341 +0,0 @@
-#!/usr/bin/python
-#
-# 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-import pkg.gui.misc as gui_misc
-import os
-import pkg.misc as misc
-import pkg.client.api_errors as api_errors
-import pkg.client.bootenv as bootenv
-from threading import Thread
-import time
-
-try:
- import gobject
- import gtk
- import pygtk
- pygtk.require("2.0")
-except ImportError:
- import sys
- sys.exit(1)
-
-VALID_BE_NAME = 0
-INVALID_BE_NAME = -1
-DUPLICATE_BE_NAME = -2
-ACTIVATED_BE_NAME = -3 #If the be was not changed by the user
-ERROR_FORMAT = "<span color = \"red\">%s</span>"
-
-class RenameBeAfterUpdateAll:
- def __init__(self, parent, dialog_icon, parent_window):
- if not bootenv.BootEnv.libbe_exists():
- msg = _("The <b>libbe</b> library was not "
- "found on your system.")
- msgbox = gtk.MessageDialog(
- buttons = gtk.BUTTONS_CLOSE,
- flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_INFO,
- message_format = None)
- msgbox.set_markup(msg)
- msgbox.set_title(_("Rename BE"))
- msgbox.run()
- msgbox.destroy()
- return
-
- # Before performing update all (image-update) task, we are storing
- # the active on reboot be name. If the be name after update is different
- # it means that new BE was created and we can show BE rename dialog
- # otherwise we can show update completed dialog.
- # Also we need to store original BE name to work-around the bug: 6472202
- self.active_be_before_update_all = self.__get_activated_be_name()
-
- self.parent = parent
- self.stop_progress_bouncing = False
- self.stopped_bouncing_progress = True
- builder = gtk.Builder()
- gladefile = os.path.join(self.parent.application_dir,
- "usr/share/package-manager/packagemanager.ui")
- builder.add_from_file(gladefile)
-
- self.w_ua_completed_dialog = \
- builder.get_object("ua_completed_dialog")
- self.w_ua_be_entry = \
- builder.get_object("ua_be_entry")
- self.w_ua_release_notes_button = \
- builder.get_object("release_notes_button")
- self.w_be_error_label = \
- builder.get_object("be_error_label")
- self.w_ua_help_button = \
- builder.get_object("ua_help_button")
- self.w_ua_restart_later_button = \
- builder.get_object("ua_restart_later_button")
- self.w_ua_restart_now_button = \
- builder.get_object("ua_restart_now_button")
- self.w_ua_ok_image = \
- builder.get_object("ua_ok_image")
- self.w_ua_whats_this_button = \
- builder.get_object("ua_whats_this_button")
- self.w_ua_whats_this_button.set_tooltip_text(_(
- "A boot environment (BE) contains the operating\n"
- "system image and updated packages. The\n"
- "system will boot into the new BE on restart."))
-
- self.w_progress_dialog = builder.get_object("progressdialog")
- self.w_progressinfo_label = builder.get_object("progressinfo")
- self.w_progress_cancel = builder.get_object("progresscancel")
- self.w_progressbar = builder.get_object("progressbar")
- self.w_progress_dialog.connect('delete-event', lambda stub1, stub2: True)
- self.w_progress_cancel.set_sensitive(False)
-
- self.w_progress_dialog.set_title(_("Rename BE"))
- self.w_progressinfo_label.set_text(_("Renaming BE, please wait..."))
-
- self.w_progress_dialog.set_icon(dialog_icon)
- self.w_ua_completed_dialog.set_icon(dialog_icon)
-
- checkmark_icon = gui_misc.get_icon(
- self.parent.icon_theme, "pm-check", 24)
-
- self.w_ua_ok_image.set_from_pixbuf(checkmark_icon)
-
- gui_misc.set_modal_and_transient(self.w_progress_dialog, parent_window)
- gui_misc.set_modal_and_transient(self.w_ua_completed_dialog,
- parent_window)
-
- self.__setup_signals()
-
- def __setup_signals(self):
- signals_table = [
- (self.w_ua_help_button, "clicked",
- self.__on_ua_help_button_clicked),
- (self.w_ua_restart_later_button, "clicked",
- self.__on_ua_restart_later_button_clicked),
- (self.w_ua_restart_now_button, "clicked",
- self.__on_ua_restart_now_button_clicked),
- (self.w_ua_completed_dialog, "delete_event",
- self.__on_ua_completed_dialog_delete_event),
- (self.w_ua_be_entry, "changed",
- self.__on_ua_be_entry_changed),
- (self.w_ua_whats_this_button, "clicked",
- self.__on_ua_whats_this_button_clicked),
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def show_rename_dialog(self, updated_packages_list):
- '''Returns False if no BE rename is needed'''
- orig_name = self.__get_activated_be_name()
- if orig_name == self.active_be_before_update_all:
- self.w_ua_completed_dialog.hide()
- self.parent.update_package_list(updated_packages_list)
- return False
- else:
- self.__set_release_notes_url()
- self.__setup_be_name()
- self.w_ua_completed_dialog.show_all()
- return True
-
- def __set_release_notes_url(self):
- info_url = misc.get_release_notes_url()
- if info_url and len(info_url) == 0:
- info_url = gui_misc.RELEASE_URL
- self.w_ua_release_notes_button.set_uri(info_url)
-
- def __on_ua_restart_later_button_clicked(self, widget):
- self.__proceed_after_update()
-
- def __on_ua_restart_now_button_clicked(self, widget):
- self.__proceed_after_update(True)
-
- def __on_ua_whats_this_button_clicked(self, widget):
- msgbox = gtk.MessageDialog(parent = self.w_ua_completed_dialog,
- buttons = gtk.BUTTONS_CLOSE,
- flags = gtk.DIALOG_MODAL,
- type = gtk.MESSAGE_INFO,
- message_format = None)
- msgbox.set_property('text',
- _(self.w_ua_whats_this_button.get_tooltip_text()))
- title = _("Update All")
-
- msgbox.set_title(title)
- msgbox.run()
- msgbox.destroy()
-
- @staticmethod
- def __on_ua_completed_dialog_delete_event(widget, event):
- return True
-
- def __proceed_after_update(self, reboot=False):
- orig_name = self.__get_activated_be_name()
- new_name = self.w_ua_be_entry.get_text()
- Thread(target = self.__set_be_name,
- args = (orig_name, new_name, reboot)).start()
- self.w_ua_completed_dialog.hide()
-
- def __set_be_name(self, orig_name, new_name, reboot):
- ret_code = self.__verify_be_name(new_name)
- be_rename_code = 0
- if ret_code != ACTIVATED_BE_NAME:
- self.__start_bouncing_progress()
- be_rename_code = self.__rename_be(orig_name, new_name)
- if be_rename_code != 0:
- # Workaround for bug: 6472202
- # If the rename didn't work for the first time, we should:
- # - Activate current BE - active_name
- # - Rename the BE orig_name to BE new_name
- # - Activate the BE new_name
- active_name = self.__get_active_be_name()
- workaround_code = self.__workaround_for_6472202(
- active_name, orig_name, new_name)
- if workaround_code != 0:
- gobject.idle_add(self.__g_be_rename_problem_dialog,
- new_name, orig_name)
- if reboot:
- ret = gui_misc.restart_system()
- if ret != 0:
- gobject.idle_add(self.__g_be_reboot_problem_dialog)
- else:
- gobject.idle_add(self.parent.shutdown_after_image_update)
- self.__stop_bouncing_progress()
- gobject.idle_add(self.parent.shutdown_after_image_update, False)
-
- @staticmethod
- def __g_be_rename_problem_dialog(new_name, orig_name):
- msg_type = gtk.MESSAGE_INFO
- error_msg = _("Could not change the BE name to:\n\t"
- "%s\n\nThe following name will be used instead:"
- "\n\t%s" % (new_name, orig_name))
- msg_title = _("BE Name")
- gui_misc.error_occurred(None, error_msg, msg_title, msg_type)
-
- @staticmethod
- def __g_be_reboot_problem_dialog():
- msg_type = gtk.MESSAGE_ERROR
- error_msg = _("Could not restart the system."
- "\nPlease restart the system manually.")
- msg_title = _("Restart Error")
- gui_misc.error_occurred(None, error_msg, msg_title, msg_type)
-
- def __on_ua_be_entry_changed(self, widget):
- if len(widget.get_text()) == 0:
- self.w_be_error_label.hide()
- self.__set_buttons_state(False)
- return
- ret_code = self.__verify_be_name(widget.get_text())
- if ret_code == ACTIVATED_BE_NAME:
- self.__set_buttons_state(True)
- self.w_be_error_label.hide()
- elif ret_code == DUPLICATE_BE_NAME:
- self.__set_buttons_state(False)
- error_string = _("This name already exists.")
- error = ERROR_FORMAT % error_string
- self.w_be_error_label.set_markup(error)
- self.w_be_error_label.show()
- elif ret_code == INVALID_BE_NAME:
- self.__set_buttons_state(False)
- error_string = _("BE name contains invalid character.")
- error = ERROR_FORMAT % error_string
- self.w_be_error_label.set_markup(error)
- self.w_be_error_label.show()
- else:
- self.__set_buttons_state(True)
- self.w_be_error_label.hide()
-
- def __set_buttons_state(self, sensitive=False):
- self.w_ua_restart_later_button.set_sensitive(sensitive)
- self.w_ua_restart_now_button.set_sensitive(sensitive)
-
- def __setup_be_name(self):
- proposed_name = self.__get_activated_be_name()
- self.w_ua_be_entry.set_text(proposed_name)
-
- def __verify_be_name(self, new_name):
- try:
- bootenv.BootEnv.check_be_name(new_name)
- except api_errors.DuplicateBEName:
- if new_name == self.__get_activated_be_name():
- return ACTIVATED_BE_NAME
- else:
- return DUPLICATE_BE_NAME
- except api_errors.ApiException:
- return INVALID_BE_NAME
- return VALID_BE_NAME
-
- @staticmethod
- def __get_activated_be_name():
- try:
- name = bootenv.BootEnv.get_activated_be_name()
- except api_errors.ApiException:
- name = ""
- return name
-
- @staticmethod
- def __get_active_be_name():
- try:
- name = bootenv.BootEnv.get_active_be_name()
- except api_errors.ApiException:
- name = ""
- return name
-
- def __start_bouncing_progress(self):
- self.stop_progress_bouncing = False
- self.stopped_bouncing_progress = False
- gobject.idle_add(self.w_progress_dialog.show)
- Thread(target =
- self.__g_progressdialog_progress_pulse).start()
-
- def __stop_bouncing_progress(self):
- if self.__is_progress_bouncing():
- self.stop_progress_bouncing = True
-
- def __g_progressdialog_progress_pulse(self):
- while not self.stop_progress_bouncing:
- gobject.idle_add(self.w_progressbar.pulse)
- time.sleep(0.1)
- self.stopped_bouncing_progress = True
- gobject.idle_add(self.w_progress_dialog.hide)
-
- def __is_progress_bouncing(self):
- return not self.stopped_bouncing_progress
-
- @staticmethod
- def __rename_be(orig_name, new_name):
- # The rename operation is i/o intensive, so the gui
- # progress is not responsive. This will allow to show the
- # gui progress.
- time.sleep(0.2)
- return bootenv.BootEnv.rename_be(orig_name, new_name)
-
- @staticmethod
- def __workaround_for_6472202(active_name, orig_name, new_name):
- ret_code = 0
- ret_code = bootenv.BootEnv.set_default_be(active_name)
- if ret_code == 0:
- ret_code = bootenv.BootEnv.rename_be(orig_name, new_name)
- if ret_code == 0:
- ret_code = bootenv.BootEnv.set_default_be(new_name)
- else:
- bootenv.BootEnv.set_default_be(orig_name)
- return ret_code
-
- @staticmethod
- def __on_ua_help_button_clicked(widget):
- gui_misc.display_help("intro-be")
--- a/src/gui/modules/versioninfo.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,254 +0,0 @@
-#!/usr/bin/python
-#
-# 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 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-import sys
-try:
- import gobject
- import pango
-except ImportError:
- sys.exit(1)
-import pkg.gui.misc as gui_misc
-
-class VersionInfo:
- def __init__(self, builder, parent):
- self.parent = parent
- self.w_version_info_dialog = \
- builder.get_object("version_info_dialog")
- self.w_info_name_label = builder.get_object("info_name")
- self.w_info_installed_label = builder.get_object(
- "info_installed")
- self.w_info_installable_label = builder.get_object(
- "info_installable")
- self.w_info_installable_prefix_label = builder.get_object(
- "info_installable_label")
- self.w_info_ok_button = builder.get_object("info_ok_button")
- self.w_info_help_button = builder.get_object("info_help_button")
- self.w_info_expander = builder.get_object(
- "version_info_expander")
- self.w_info_textview = builder.get_object("infotextview")
- infobuffer = self.w_info_textview.get_buffer()
- infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
-
- def setup_signals(self):
- signals_table = [
- (self.w_info_ok_button, "clicked",
- self.__on_info_ok_button_clicked),
- (self.w_info_help_button, "clicked",
- self.__on_info_help_button_clicked),
- (self.w_version_info_dialog, "delete_event",
- self.__on_version_info_dialog_delete_event)
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def set_modal_and_transient(self, parent_window):
- gui_misc.set_modal_and_transient(self.w_version_info_dialog,
- parent_window)
-
- def get_info(self, pkg_stem, name):
- api_o = self.parent.get_api_object()
- local_info = gui_misc.get_pkg_info(self.parent, api_o, pkg_stem, True)
- remote_info = gui_misc.get_pkg_info(self.parent, api_o, pkg_stem, False)
- if self.parent.check_exiting():
- return False
-
- plan_pkg = None
-
- installed_only = False
- if local_info:
- if gui_misc.same_pkg_versions(local_info, remote_info):
- installed_only = True
-
- if not installed_only:
- install_update_list = []
- stuff_to_do = False
- install_update_list.append(pkg_stem)
- for pd in api_o.gen_plan_install(install_update_list,
- refresh_catalogs=False):
- continue
- stuff_to_do = not api_o.planned_nothingtodo()
- if stuff_to_do:
- plan_desc = api_o.describe()
- if plan_desc == None:
- return
- plan = plan_desc.get_changes()
- plan_pkg = None
- for pkg_plan in plan:
- if name == pkg_plan[1].pkg_stem:
- plan_pkg = pkg_plan[1]
- break
- if plan_pkg == None:
- return True
- gobject.idle_add(self.__after_get_info, local_info, remote_info,
- plan_pkg, name)
- return False
-
- def __hide_pkg_version_details(self):
- self.w_info_expander.hide()
- self.w_version_info_dialog.set_size_request(-1, -1)
-
-
- def __after_get_info(self, local_info, remote_info, plan_pkg, name):
- if self.parent.check_exiting():
- return
- self.w_info_name_label.set_text(name)
- installable_fmt = \
- _("%(version)s (Build %(build)s-%(branch)s)")
- installed_label = ""
- installable_label = ""
- installable_prefix_label = _("<b>Installable Version:</b>")
-
- if local_info:
- # Installed
- installable_prefix_label = _("<b>Upgradeable Version:</b>")
- yes_text = _("Yes, %(version)s (Build %(build)s-%(branch)s)")
- installed_label = yes_text % \
- {"version": local_info.version,
- "build": local_info.build_release,
- "branch": local_info.branch}
- if gui_misc.same_pkg_versions(local_info, remote_info):
- # Installed and up to date
- installable_label = \
- _("Installed package is up-to-date")
- self.__hide_pkg_version_details()
- else:
- if plan_pkg == None:
- # Installed with later version but can't upgrade
- # Upgradeable Version: None
- installable_label = _("None")
- self.__setup_version_info_details(name,
- remote_info.version,
- remote_info.build_release,
- remote_info.branch, False)
- else:
- # Installed with later version and can upgrade to
- # Upgradeable Version: <version>
- # Upgradeable == Latest Version
- if gui_misc.same_pkg_versions(plan_pkg,
- remote_info):
- installable_label = installable_fmt % \
- {"version": plan_pkg.version,
- "build": plan_pkg.build_release,
- "branch": plan_pkg.branch}
- self.__hide_pkg_version_details()
- else:
- # Installed with later version and can upgrade
- # Upgradeable Version: <version>
- # but NOT to the Latest Version
- installable_label = installable_fmt % \
- {"version": plan_pkg.version,
- "build": plan_pkg.build_release,
- "branch": plan_pkg.branch}
-
- self.__setup_version_info_details(name,
- remote_info.version,
- remote_info.build_release,
- remote_info.branch, False)
- else:
- # Not Installed
- installed_label = _("No")
- if plan_pkg:
- # Not installed with later version available to install
- # Installable: <version>
- # Installable == Latest Version
- if gui_misc.same_pkg_versions(plan_pkg, remote_info):
- installable_label = installable_fmt % \
- {"version": plan_pkg.version,
- "build": plan_pkg.build_release,
- "branch": plan_pkg.branch}
- self.__hide_pkg_version_details()
- else:
- # Not installed with later version available
- # Installable: <version>
- # but NOT to the Latest Version
- installable_label = installable_fmt % \
- {"version": plan_pkg.version,
- "build": plan_pkg.build_release,
- "branch": plan_pkg.branch}
-
- self.__setup_version_info_details(name,
- remote_info.version,
- remote_info.build_release,
- remote_info.branch, True)
- else:
- # Not Installed with later version and can't install
- # Installable Version: None
- installable_label = _("None")
- self.__setup_version_info_details(name,
- remote_info.version,
- remote_info.build_release,
- remote_info.branch, True)
-
- self.w_info_installed_label.set_text(installed_label)
- self.w_info_installable_label.set_text(installable_label)
- self.w_info_installable_prefix_label.set_markup(installable_prefix_label)
- self.w_info_ok_button.grab_focus()
- self.w_version_info_dialog.show()
- self.parent.unset_busy_cursor()
-
- def __setup_version_info_details(self, name, version, build_release, branch,
- to_be_installed):
- installable_fmt = \
- _("%(version)s (Build %(build)s-%(branch)s)")
- if to_be_installed:
- expander_fmt = _(
- "The latest version of %s cannot be installed."
- )
- else:
- expander_fmt = _(
- "Cannot upgrade to the latest version of %s."
- )
- installable_exp = installable_fmt % \
- {"version": version,
- "build": build_release,
- "branch": branch}
- expander_text = installable_exp + "\n\n"
- expander_text += expander_fmt % name
-
- # Ensure we have enough room for the Details message
- # without requiring a scrollbar
- self.w_info_textview.set_size_request(484, 95)
- self.w_info_expander.set_expanded(True)
- self.w_info_expander.show()
-
- details_buff = self.w_info_textview.get_buffer()
- details_buff.set_text("")
- itr = details_buff.get_iter_at_line(0)
- details_buff.insert_with_tags_by_name(itr,
- _("Latest Version: "), "bold")
- details_buff.insert(itr, expander_text)
-
- def __on_info_ok_button_clicked(self, widget):
- self.w_version_info_dialog.hide()
-
- @staticmethod
- def __on_info_help_button_clicked(widget):
- gui_misc.display_help("package-version")
-
- def __on_version_info_dialog_delete_event(self, widget, event):
- self.__on_info_ok_button_clicked(None)
- return True
-
-
--- a/src/gui/modules/webinstall.py Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,493 +0,0 @@
-#!/usr/bin/python
-#
-# 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 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-# Location for themable icons
-ICON_LOCATION = "usr/share/package-manager/icons"
-
-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.gui.progress as progress
-import pkg.client.api_errors as api_errors
-import pkg.gui.installupdate as installupdate
-import pkg.gui.enumerations as enumerations
-import pkg.gui.repository as repository
-import pkg.fmri as fmri
-import pkg.client.publisher as publisher
-from pkg.client import global_settings
-from gettext import ngettext
-logger = global_settings.logger
-
-debug = False
-
-class Webinstall:
- def __init__(self, image_dir):
- global_settings.client_name = gui_misc.get_wi_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", os.path.join(
- self.application_dir,
- "usr/share/locale"))
- module.textdomain("pkg")
- gui_misc.init_for_help(self.application_dir)
- self.pub_pkg_list = None
- self.pr = progress.NullProgressTracker()
- self.pub_new_tasks = []
- self.pkg_install_tasks = []
- self.icon_theme = gtk.icon_theme_get_default()
- icon_location = os.path.join(self.application_dir, ICON_LOCATION)
- self.icon_theme.append_search_path(icon_location)
- self.param = None
- self.disabled_pubs = {}
- self.repo_gui = None
- self.first_run = True
-
- # Webinstall Dialog
- builder = gtk.Builder()
- self.gladefile = os.path.join(self.application_dir,
- "usr/share/package-manager/packagemanager.ui")
- builder.add_from_file(self.gladefile)
- self.w_webinstall_dialog = \
- builder.get_object("webinstalldialog")
-
- self.w_webinstall_proceed = \
- builder.get_object("proceed_button")
- self.w_webinstall_cancel = \
- builder.get_object("cancel_button")
- self.w_webinstall_help = \
- builder.get_object("help_button")
- self.w_webinstall_close = \
- builder.get_object("close_button")
- self.w_webinstall_proceed_label = \
- builder.get_object("proceed_new_repo_label")
- self.w_webinstall_toplabel = \
- builder.get_object("webinstall_toplabel")
- self.w_webinstall_frame = \
- builder.get_object("webinstall_frame")
- self.w_webinstall_image = \
- builder.get_object("pkgimage")
- self.window_icon = gui_misc.get_icon(self.icon_theme,
- 'packagemanager', 48)
- self.w_webinstall_image.set_from_pixbuf(self.window_icon)
- self.w_webinstall_info_label = \
- builder.get_object("label19")
-
- self.w_webinstall_textview = \
- builder.get_object("webinstall_textview")
- infobuffer = self.w_webinstall_textview.get_buffer()
- infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
- infobuffer.create_tag("disabled", foreground="#757575") #Close to DimGrey
-
- self.__setup_signals()
-
- self.w_webinstall_dialog.set_icon(self.window_icon)
- self.api_o = gui_misc.get_api_object(self.image_dir, self.pr,
- self.w_webinstall_dialog)
- gui_misc.setup_logging()
-
- def __setup_signals(self):
- signals_table = [
- (self.w_webinstall_dialog, "destroy_event",
- self.__on_webinstall_dialog_close),
- (self.w_webinstall_dialog, "close",
- self.__on_webinstall_dialog_close),
- (self.w_webinstall_dialog, "delete_event",
- self.__on_webinstall_dialog_close),
- (self.w_webinstall_cancel, "clicked",
- self.__on_cancel_button_clicked),
- (self.w_webinstall_close, "clicked",
- self.__on_cancel_button_clicked),
- (self.w_webinstall_help, "clicked",
- self.__on_help_button_clicked),
- (self.w_webinstall_proceed, "clicked",
- self.__on_proceed_button_clicked),
- ]
- for widget, signal_name, callback in signals_table:
- widget.connect(signal_name, callback)
-
- def __output_new_pub_tasks(self, infobuffer, textiter, num_tasks):
- if num_tasks == 0:
- return
- msg = ngettext(
- "\n Add New Publisher\n", "\n Add New Publishers\n", num_tasks)
- infobuffer.insert_with_tags_by_name(textiter, msg, "bold")
- self.__output_pub_tasks(infobuffer, textiter, self.pub_new_tasks)
-
- def __nothing_todo(self, infobuffer, textiter):
- self.w_webinstall_proceed.hide()
- self.w_webinstall_cancel.hide()
- self.w_webinstall_frame.hide()
- self.w_webinstall_toplabel.set_text(
- _("All specified publishers are already on the system."))
- self.w_webinstall_close.show()
- self.w_webinstall_close.grab_focus()
-
- def __output_pub_tasks(self, 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.repository
- if repo != None and repo.origins != None and \
- len(repo.origins) > 0:
- infobuffer.insert(textiter,
- _(" (%s)\n") % repo.origins[0].uri)
- else:
- infobuffer.insert(textiter,
- _(" (No origin specified in the p5i file)\n"))
- self.w_webinstall_proceed.hide()
- msg = _("Publishers can <b>only</b> be added"
- " if they have an origin specified.")
- self.w_webinstall_proceed_label.set_markup(msg)
-
- def __output_pkg_install_tasks(self, infobuffer, textiter, num_tasks):
- if num_tasks == 0:
- return
- msg = ngettext(
- "\n Install Package\n", "\n Install Packages\n", num_tasks)
- infobuffer.insert_with_tags_by_name(textiter, msg, "bold")
- for entry in self.pkg_install_tasks:
- pub_info = entry[0]
- packages = entry[1]
- if len(packages) > 0:
- if self.disabled_pubs and \
- pub_info.prefix in self.disabled_pubs:
- infobuffer.insert_with_tags_by_name(textiter,
- _("\t%s (disabled)\n") % pub_info.prefix,
- "bold", "disabled")
- else:
- infobuffer.insert_with_tags_by_name(textiter,
- "\t%s\n" % pub_info.prefix, "bold")
- for pkg in packages:
- infobuffer.insert(textiter,
- "\t\t%s\n" % fmri.extract_pkg_name(pkg))
-
- def process_param(self, param=None):
- if param == None or self.api_o == None:
- self.w_webinstall_proceed.set_sensitive(False)
- self.w_webinstall_cancel.grab_focus()
- return
- self.param = param
- self.pub_pkg_list = self.api_parse_publisher_info()
- 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 = 0
- for entry in self.pkg_install_tasks:
- packages = entry[1]
- num_install_tasks += len(packages)
-
- 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_dialog.present()
- self.w_webinstall_dialog.resize(450, 100)
- return
- else:
- gui_misc.change_stockbutton_label(self.w_webinstall_proceed,
- _("_Proceed"))
- self.w_webinstall_dialog.show_all()
- self.w_webinstall_dialog.resize(450, 370)
-
- 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:
- msg = ngettext(
- "Click Proceed <b>only</b> if you trust this new "
- "publisher ",
- "Click Proceed <b>only</b> if you trust these new "
- "publishers ",
- num_new_pub)
- self.w_webinstall_proceed_label.set_markup(msg)
-
- def __on_webinstall_dialog_close(self, widget, param=None):
- self.__exit_app()
-
- def __on_cancel_button_clicked(self, widget):
- self.__exit_app()
-
- @staticmethod
- def __on_help_button_clicked(widget):
- gui_misc.display_help("webinstall")
-
- def __exit_app(self, be_name = None):
- gui_misc.shutdown_logging()
- 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:
- continue
-
- repo = pub_info.repository
-
- pub_registered = self.__is_publisher_registered(pub_info.prefix)
- if pub_registered and packages != None and len(packages) > 0 and \
- self.__check_publisher_disabled(pub_info.prefix):
- self.disabled_pubs[pub_info.prefix] = True
-
- if not pub_registered:
- if repo and repo.origins and \
- repo.origins[0] != None and \
- repo.origins[0].scheme in publisher.SSL_SCHEMES:
-
- #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
- if len(self.pub_new_tasks) > 0 or len(self.disabled_pubs) > 0 and \
- self.repo_gui == None:
- self.repo_gui = repository.Repository(self, self.image_dir,
- webinstall_new=True, main_window = self.w_webinstall_dialog)
-
- def __check_publisher_disabled(self, name):
- try:
- if self.api_o == None:
- return
- try:
- pub = self.api_o.get_publisher(name)
- if pub != None and pub.disabled:
- return True
- except api_errors.UnknownPublisher:
- return False
- except api_errors.PublisherError, ex:
- gobject.idle_add(gui_misc.error_occurred,
- self.w_webinstall_dialog,
- str(ex),
- _("Publisher Error"))
- except api_errors.ApiException, ex:
- gobject.idle_add(gui_misc.error_occurred,
- self.w_webinstall_dialog,
- str(ex), _("Web Installer Error"))
- return False
-
- def __disabled_pubs_info(self, disabled_pubs):
- if len(disabled_pubs) == 0:
- return
- num = len(disabled_pubs)
- msg = ngettext(
- "The following publisher is disabled:\n",
- "The following publishers are disabled:\n", num)
-
- for pub in disabled_pubs:
- msg += _("\t<b>%s</b>\n") % pub
-
- msg += ngettext(
- "\nClicking OK will enable the publisher before proceeding with "
- "install. On completion it will be disabled again.",
- "\nClicking OK will enable the publishers before proceeding with "
- "install.\nOn completion they will be disabled again.",
- num)
-
- msgbox = gtk.MessageDialog(
- parent = self.w_webinstall_dialog,
- buttons = gtk.BUTTONS_OK_CANCEL,
- flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_INFO,
- message_format = None)
- msgbox.set_markup(msg)
- title = ngettext("Disabled Publisher", "Disabled Publishers",
- len(disabled_pubs))
- msgbox.set_title(title)
- msgbox.set_default_response(gtk.RESPONSE_OK)
-
- response = msgbox.run()
- if response == gtk.RESPONSE_OK:
- gobject.idle_add(self.__proceed)
- msgbox.destroy()
- return
-
- 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(gui_misc.error_occurred,
- self.w_webinstall_dialog,
- str(ex), _("Publisher Error"))
- except api_errors.ApiException, ex:
- gobject.idle_add(gui_misc.error_occurred,
- self.w_webinstall_dialog,
- str(ex), _("Web Installer Error"))
- return False
-
- def __on_proceed_button_clicked(self, widget):
- if not self.first_run:
- try:
- self.api_o.reset()
- except api_errors.ApiException, ex:
- gobject.idle_add(gui_misc.error_occurred,
- self.w_webinstall_dialog,
- str(ex), _("Web Installer Error"))
- return
- self.pub_pkg_list = self.api_parse_publisher_info()
- self.__create_task_lists()
- else:
- self.first_run = False
- if self.disabled_pubs and len(self.disabled_pubs) > 0:
- self.__disabled_pubs_info(self.disabled_pubs)
- else:
- self.__proceed()
-
- def __proceed(self):
- if len(self.disabled_pubs) > 0 and self.repo_gui:
- self.repo_gui.webinstall_enable_disable_pubs(
- self.w_webinstall_dialog, self.disabled_pubs, True)
- return
- 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[0]
- if debug:
- print("Add New Publisher:\n\tName: %s" % pub.prefix)
- repo = pub.repository
- if repo != None and repo.origins != None and \
- len(repo.origins) > 0:
- print("\tURL: %s" % repo.origins[0].uri)
-
- repo = pub.repository
- if repo and len(repo.origins) > 0 and self.repo_gui:
- self.repo_gui.webinstall_new_pub(self.w_webinstall_dialog, pub)
- else:
- msg = _("Failed to add %s.\n") % pub
- msg += _("No URI specified")
- gui_misc.error_occurred(
- self.w_webinstall_dialog,
- msg, _("Publisher Error"))
-
- # Publisher Callback
- # invoked at end of adding a publisher and enabling/disabling a set of publishers
- def reload_packages(self, added_pub=True):
- if len(self.pub_new_tasks) > 0:
- if added_pub:
- self.pub_new_tasks.pop(0)
- if len(self.pub_new_tasks) > 0:
- self.__add_new_pub()
- return
-
- if len(self.pkg_install_tasks) > 0:
- self.api_o = gui_misc.get_api_object(self.image_dir, self.pr,
- self.w_webinstall_dialog)
- 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
- 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)
- if debug:
- print "Install Packages: %s" % all_package_stems
-
- installupdate.InstallUpdate(all_package_stems, self, self.image_dir,
- action = enumerations.INSTALL_UPDATE,
- parent_name = _("Package Manager"),
- main_window = self.w_webinstall_dialog,
- web_install = True)
-
- def process_pkg_stems(self, pub_info, packages):
- if not self.__is_publisher_registered(pub_info.prefix):
- return []
- pkg_stem = "pkg://" + pub_info.prefix + "/"
- packages_with_stem = []
- for pkg in packages:
- if pkg.startswith(pkg_stem):
- packages_with_stem.append(pkg)
- else:
- 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):
- if update_list == None:
- return
- self.pkg_install_tasks = []
- if len(self.disabled_pubs) > 0 and self.repo_gui:
- gobject.idle_add(self.repo_gui.webinstall_enable_disable_pubs,
- self.w_webinstall_dialog, self.disabled_pubs, False)
- return
- self.__exit_app()
-
- def api_parse_publisher_info(self):
- '''<path to mimetype file|origin_url>
- returns list of publisher and package list tuples'''
- try:
- return self.api_o.parse_p5i(location=self.param)
- except api_errors.ApiException, ex:
- msg = str(ex)
- print _("Web Installer Error: %s") % (msg)
- sys.exit(1)
- return None
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/__init__.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+#
+# 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.
+#
+
+__all__ = ['installupdate', 'enumerations', \
+ 'repository', 'imageinfo', 'beadmin', 'cache', \
+ 'uarenamebe']
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/beadmin.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,632 @@
+#!/usr/bin/python
+#
+# 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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+import sys
+import os
+import pango
+import time
+import datetime
+import locale
+import pkg.pkgsubprocess as subprocess
+from threading import Thread
+
+try:
+ import gobject
+ gobject.threads_init()
+ import gtk
+ import pygtk
+ pygtk.require("2.0")
+except ImportError:
+ sys.exit(1)
+import pkg.gui.misc as gui_misc
+import pkg.client.api_errors as api_errors
+import pkg.client.bootenv as bootenv
+import pkg.misc
+
+#BE_LIST
+(
+BE_ID,
+BE_MARKED,
+BE_NAME,
+BE_ORIG_NAME,
+BE_DATE_TIME,
+BE_CURRENT_PIXBUF,
+BE_ACTIVE_DEFAULT,
+BE_SIZE,
+BE_EDITABLE
+) = range(9)
+
+class Beadmin:
+ def __init__(self, parent):
+ self.parent = parent
+
+ if not bootenv.BootEnv.libbe_exists():
+ msg = _("The <b>libbe</b> library was not "
+ "found on your system."
+ "\nAll functions for managing Boot Environments are disabled")
+ msgbox = gtk.MessageDialog(
+ buttons = gtk.BUTTONS_CLOSE,
+ flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_INFO,
+ message_format = None)
+ msgbox.set_markup(msg)
+ msgbox.set_title(_("BE management"))
+ msgbox.run()
+ msgbox.destroy()
+ return
+
+ self.be_list = \
+ gtk.ListStore(
+ gobject.TYPE_INT, # BE_ID
+ gobject.TYPE_BOOLEAN, # BE_MARKED
+ gobject.TYPE_STRING, # BE_NAME
+ gobject.TYPE_STRING, # BE_ORIG_NAME
+ gobject.TYPE_STRING, # BE_DATE_TIME
+ gtk.gdk.Pixbuf, # BE_CURRENT_PIXBUF
+ gobject.TYPE_BOOLEAN, # BE_ACTIVE_DEFAULT
+ gobject.TYPE_STRING, # BE_SIZE
+ gobject.TYPE_BOOLEAN, # BE_EDITABLE
+ )
+ self.progress_stop_thread = False
+ self.initial_active = 0
+ self.initial_default = 0
+ gladefile = os.path.join(self.parent.application_dir,
+ "usr/share/package-manager/packagemanager.ui")
+ builder = gtk.Builder()
+ builder.add_from_file(gladefile)
+ self.w_beadmin_dialog = builder.get_object("beadmin")
+ self.w_beadmin_dialog.set_icon(self.parent.window_icon)
+ self.w_be_treeview = builder.get_object("betreeview")
+ self.w_help_button = builder.get_object("help_bebutton")
+ self.w_cancel_button = builder.get_object("cancelbebutton")
+ self.w_ok_button = builder.get_object("okbebutton")
+ w_active_gtkimage = builder.get_object("activebeimage")
+ self.w_progress_dialog = builder.get_object("progressdialog")
+ self.w_progress_dialog.connect('delete-event', lambda stub1, stub2: True)
+ self.w_progress_dialog.set_icon(self.parent.window_icon)
+ self.w_progressinfo_label = builder.get_object("progressinfo")
+ progress_button = builder.get_object("progresscancel")
+ self.w_progressbar = builder.get_object("progressbar")
+ # Dialog reused in the repository.py
+ self.w_beconfirmation_dialog = \
+ builder.get_object("confirmationdialog")
+ self.w_beconfirmation_dialog.set_icon(self.parent.window_icon)
+ self.w_beconfirmation_textview = \
+ builder.get_object("confirmtext")
+ self.w_okbe_button = builder.get_object("ok_conf")
+ self.w_cancelbe_button = builder.get_object("cancel_conf")
+ self.w_ok_button.set_sensitive(False)
+ progress_button.hide()
+ self.w_progressbar.set_pulse_step(0.1)
+ self.list_filter = self.be_list.filter_new()
+ self.w_be_treeview.set_model(self.list_filter)
+ self.__init_tree_views()
+ self.active_image = gui_misc.get_icon(
+ self.parent.icon_theme, "status_checkmark")
+ w_active_gtkimage.set_from_pixbuf(self.active_image)
+
+ bebuffer = self.w_beconfirmation_textview.get_buffer()
+ bebuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+
+ self.__setup_signals()
+ sel = self.w_be_treeview.get_selection()
+ self.w_cancel_button.grab_focus()
+ sel.set_mode(gtk.SELECTION_SINGLE)
+ self.w_beconfirmation_dialog.set_title(
+ _("Boot Environment Confirmation"))
+ gui_misc.set_modal_and_transient(self.w_beadmin_dialog,
+ self.parent.w_main_window)
+ self.parent.child = self
+ self.w_beadmin_dialog.show_all()
+ self.w_progress_dialog.set_title(
+ _("Loading Boot Environment Information"))
+ self.w_progressinfo_label.set_text(
+ _("Fetching BE entries..."))
+ self.w_progress_dialog.show()
+ Thread(target = self.__progress_pulse).start()
+ Thread(target = self.__prepare_beadmin_list).start()
+
+ def __setup_signals(self):
+ signals_table = [
+ (self.w_cancel_button, "clicked",
+ self.__on_cancel_be_clicked),
+ (self.w_ok_button, "clicked",
+ self.__on_ok_be_clicked),
+ (self.w_help_button, "clicked",
+ self.__on_help_bebutton_clicked),
+
+ (self.w_cancelbe_button, "clicked",
+ self.__on_cancel_be_conf_clicked),
+ (self.w_okbe_button, "clicked",
+ self.__on_ok_be_conf_clicked),
+ (self.w_beconfirmation_dialog, "delete_event",
+ self.__on_beconfirmationdialog_delete_event),
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def cleanup(self):
+ self.progress_stop_thread = True
+ self.__on_beadmin_delete_event(None, None)
+
+ def __progress_pulse(self):
+ while not self.progress_stop_thread:
+ gobject.idle_add(self.w_progressbar.pulse)
+ time.sleep(0.1)
+ gobject.idle_add(self.w_progress_dialog.hide)
+
+ def __prepare_beadmin_list(self):
+ be_list = bootenv.BootEnv.get_be_list()
+ gobject.idle_add(self.__create_view_with_be, be_list)
+ self.progress_stop_thread = True
+ return
+
+ def __init_tree_views(self):
+ model = self.w_be_treeview.get_model()
+
+ column = gtk.TreeViewColumn()
+ column.set_title("")
+ render_pixbuf = gtk.CellRendererPixbuf()
+ column.pack_start(render_pixbuf, expand = True)
+ column.add_attribute(render_pixbuf, "pixbuf", BE_CURRENT_PIXBUF)
+ self.w_be_treeview.append_column(column)
+
+ name_renderer = gtk.CellRendererText()
+ name_renderer.connect('edited', self.__be_name_edited, model)
+ column = gtk.TreeViewColumn(_("Boot Environment"),
+ name_renderer, text = BE_NAME)
+ column.set_cell_data_func(name_renderer, self.__cell_data_function, None)
+ column.set_expand(True)
+ if bootenv.BootEnv.check_verify():
+ column.add_attribute(name_renderer, "editable",
+ BE_EDITABLE)
+ self.w_be_treeview.append_column(column)
+
+ datetime_renderer = gtk.CellRendererText()
+ datetime_renderer.set_property('xalign', 0.0)
+ column = gtk.TreeViewColumn(_("Created"), datetime_renderer,
+ text = BE_DATE_TIME)
+ column.set_cell_data_func(datetime_renderer,
+ self.__cell_data_function, None)
+ column.set_expand(True)
+ self.w_be_treeview.append_column(column)
+
+ size_renderer = gtk.CellRendererText()
+ size_renderer.set_property('xalign', 1.0)
+ column = gtk.TreeViewColumn(_("Size"), size_renderer,
+ text = BE_SIZE)
+ column.set_cell_data_func(size_renderer, self.__cell_data_function, None)
+ column.set_expand(False)
+ self.w_be_treeview.append_column(column)
+
+ radio_renderer = gtk.CellRendererToggle()
+ radio_renderer.connect('toggled', self.__active_pane_default, model)
+ column = gtk.TreeViewColumn(_("Active on Reboot"),
+ radio_renderer, active = BE_ACTIVE_DEFAULT)
+ radio_renderer.set_property("activatable", True)
+ radio_renderer.set_property("radio", True)
+ column.set_cell_data_func(radio_renderer,
+ self.__cell_data_default_function, None)
+ column.set_expand(False)
+ self.w_be_treeview.append_column(column)
+
+ toggle_renderer = gtk.CellRendererToggle()
+ toggle_renderer.connect('toggled', self.__active_pane_toggle, model)
+ column = gtk.TreeViewColumn(_("Delete"), toggle_renderer,
+ active = BE_MARKED)
+ toggle_renderer.set_property("activatable", True)
+ column.set_cell_data_func(toggle_renderer,
+ self.__cell_data_delete_function, None)
+ column.set_expand(False)
+ self.w_be_treeview.append_column(column)
+
+ def __on_help_bebutton_clicked(self, widget):
+ if self.parent != None:
+ gui_misc.display_help("manage-be")
+ else:
+ gui_misc.display_help()
+
+ def __on_ok_be_clicked(self, widget):
+ self.w_progress_dialog.set_title(_("Applying changes"))
+ self.w_progressinfo_label.set_text(
+ _("Applying changes, please wait ..."))
+ if self.w_ok_button.get_property('sensitive') == 0:
+ self.progress_stop_thread = True
+ self.__on_beadmin_delete_event(None, None)
+ return
+ Thread(target = self.__activate).start()
+
+ def __on_cancel_be_clicked(self, widget):
+ self.__on_beadmin_delete_event(None, None)
+ return False
+
+ def __on_beconfirmationdialog_delete_event(self, widget, event):
+ self.__on_cancel_be_conf_clicked(widget)
+ return True
+
+ def __on_cancel_be_conf_clicked(self, widget):
+ self.w_beconfirmation_dialog.hide()
+
+ def __on_ok_be_conf_clicked(self, widget):
+ self.w_beconfirmation_dialog.hide()
+ self.progress_stop_thread = False
+ Thread(target = self.__on_progressdialog_progress).start()
+ Thread(target = self.__delete_activate_be).start()
+
+ def __on_beadmin_delete_event(self, widget, event, stub=None):
+ self.parent.child = None
+ self.w_beadmin_dialog.destroy()
+ return True
+
+ def __activate(self):
+ active_text = _("Active on reboot\n")
+ delete_text = _("Delete\n")
+ rename_text = _("Rename\n")
+ active = ""
+ delete = ""
+ rename = {}
+ for row in self.be_list:
+
+ if row[BE_MARKED]:
+ delete += "\t" + row[BE_NAME] + "\n"
+ if row[BE_ACTIVE_DEFAULT] == True and row[BE_ID] != \
+ self.initial_default:
+ active += "\t" + row[BE_NAME] + "\n"
+ if row[BE_NAME] != row[BE_ORIG_NAME]:
+ rename[row[BE_ORIG_NAME]] = row[BE_NAME]
+ textbuf = self.w_beconfirmation_textview.get_buffer()
+ textbuf.set_text("")
+ textiter = textbuf.get_end_iter()
+ if len(active) > 0:
+ textbuf.insert_with_tags_by_name(textiter,
+ active_text, "bold")
+ textbuf.insert_with_tags_by_name(textiter,
+ active)
+ if len(delete) > 0:
+ if len(active) > 0:
+ textbuf.insert_with_tags_by_name(textiter,
+ "\n")
+ textbuf.insert_with_tags_by_name(textiter,
+ delete_text, "bold")
+ textbuf.insert_with_tags_by_name(textiter,
+ delete)
+ if len(rename) > 0:
+ if len(delete) > 0 or len(active) > 0:
+ textbuf.insert_with_tags_by_name(textiter,
+ "\n")
+ textbuf.insert_with_tags_by_name(textiter,
+ rename_text, "bold")
+ for orig in rename:
+ textbuf.insert_with_tags_by_name(textiter,
+ "\t")
+ textbuf.insert_with_tags_by_name(textiter,
+ orig)
+ textbuf.insert_with_tags_by_name(textiter,
+ _(" to "), "bold")
+ textbuf.insert_with_tags_by_name(textiter,
+ rename.get(orig) + "\n")
+ self.w_okbe_button.grab_focus()
+ gobject.idle_add(self.w_beconfirmation_dialog.show)
+ self.progress_stop_thread = True
+
+ def __on_progressdialog_progress(self):
+ # This needs to be run in gobject.idle_add, otherwise we will get
+ # Xlib: unexpected async reply (sequence 0x2db0)!
+ gobject.idle_add(self.w_progress_dialog.show)
+ while not self.progress_stop_thread:
+ gobject.idle_add(self.w_progressbar.pulse)
+ time.sleep(0.1)
+ gobject.idle_add(self.w_progress_dialog.hide)
+
+ def __delete_activate_be(self):
+ not_deleted = []
+ not_default = None
+ not_renamed = {}
+ # The while gtk.events_pending():
+ # gtk.main_iteration(False)
+ # Is not working if we are calling libbe, so it is required
+ # To have sleep in few places in this function
+ # Remove
+ for row in self.be_list:
+ if row[BE_MARKED]:
+ time.sleep(0.1)
+ result = self.__destroy_be(row[BE_NAME])
+ if result != 0:
+ not_deleted.append(row[BE_NAME])
+ # Rename
+ for row in self.be_list:
+ if row[BE_NAME] != row[BE_ORIG_NAME]:
+ time.sleep(0.1)
+ result = self.__rename_be(row[BE_ORIG_NAME],
+ row[BE_NAME])
+ if result != 0:
+ not_renamed[row[BE_ORIG_NAME]] = row[BE_NAME]
+ # Set active
+ for row in self.be_list:
+ if row[BE_ACTIVE_DEFAULT] == True and row[BE_ID] != \
+ self.initial_default:
+ time.sleep(0.1)
+ result = self.__set_default_be(row[BE_NAME])
+ if result != 0:
+ not_default = row[BE_NAME]
+ if len(not_deleted) == 0 and not_default == None \
+ and len(not_renamed) == 0:
+ self.progress_stop_thread = True
+ else:
+ self.progress_stop_thread = True
+ msg = ""
+ if not_default:
+ msg += _("<b>Couldn't change Active "
+ "Boot Environment to:</b>\n") + not_default
+ if len(not_deleted) > 0:
+ if not_default:
+ msg += "\n\n"
+ msg += _("<b>Couldn't delete Boot "
+ "Environments:</b>\n")
+ for row in not_deleted:
+ msg += row + "\n"
+ if len(not_renamed) > 0:
+ if not_default or len(not_deleted):
+ msg += "\n"
+ msg += _("<b>Couldn't rename Boot "
+ "Environments:</b>\n")
+ for orig in not_renamed:
+ msg += _("%s <b>to</b> %s\n") % (orig, \
+ not_renamed.get(orig))
+ gobject.idle_add(self.__error_occurred, msg)
+ return
+ gobject.idle_add(self.__on_cancel_be_clicked, None)
+
+ @staticmethod
+ def __rename_cell(model, itr, new_name):
+ model.set_value(itr, BE_NAME, new_name)
+
+ @staticmethod
+ def __rename_be(orig_name, new_name):
+ return bootenv.BootEnv.rename_be(orig_name, new_name)
+
+ def __error_occurred(self, error_msg, reset=True):
+ gui_misc.error_occurred(self.w_beadmin_dialog,
+ error_msg,
+ _("BE error"),
+ gtk.MESSAGE_ERROR,
+ True)
+ if reset:
+ self.__on_reset_be()
+
+ def __on_reset_be(self):
+ self.be_list.clear()
+ self.w_progress_dialog.show()
+ self.progress_stop_thread = False
+ Thread(target = self.__progress_pulse).start()
+ Thread(target = self.__prepare_beadmin_list).start()
+ self.w_ok_button.set_sensitive(False)
+
+ def __active_pane_toggle(self, cell, filtered_path, filtered_model):
+ model = filtered_model.get_model()
+ path = filtered_model.convert_path_to_child_path(filtered_path)
+ itr = model.get_iter(path)
+ if itr:
+ modified = model.get_value(itr, BE_MARKED)
+ # Do not allow to set active if selected for removal
+ model.set_value(itr, BE_MARKED, not modified)
+ # Do not allow to rename if we are removing be.
+ model.set_value(itr, BE_EDITABLE, modified)
+ self.__enable_disable_ok()
+
+ def __enable_disable_ok(self):
+ for row in self.be_list:
+ if row[BE_MARKED] == True:
+ self.w_ok_button.set_sensitive(True)
+ return
+ if row[BE_ID] == self.initial_default:
+ if row[BE_ACTIVE_DEFAULT] == False:
+ self.w_ok_button.set_sensitive(True)
+ return
+ if row[BE_NAME] != row[BE_ORIG_NAME]:
+ self.w_ok_button.set_sensitive(True)
+ return
+ self.w_ok_button.set_sensitive(False)
+ return
+
+ def __be_name_edited(self, cell, filtered_path, new_name, filtered_model):
+ model = filtered_model.get_model()
+ path = filtered_model.convert_path_to_child_path(filtered_path)
+ itr = model.get_iter(path)
+ if itr:
+ if model.get_value(itr, BE_NAME) == new_name:
+ return
+ if self.__verify_be_name(new_name) != 0:
+ return
+ self.__rename_cell(model, itr, new_name)
+ self.__enable_disable_ok()
+ return
+
+ #TBD: Notify user if name clash using same logic as Repo Add and warning text
+ def __verify_be_name(self, new_name):
+ try:
+ bootenv.BootEnv.check_be_name(new_name)
+ except api_errors.DuplicateBEName:
+ pass
+ except api_errors.ApiException:
+ return -1
+ for row in self.be_list:
+ if new_name == row[BE_NAME]:
+ return -1
+ return 0
+
+ def __active_pane_default(self, cell, filtered_path, filtered_model):
+ model = filtered_model.get_model()
+ path = filtered_model.convert_path_to_child_path(filtered_path)
+ for row in model:
+ row[BE_ACTIVE_DEFAULT] = False
+ itr = model.get_iter(path)
+ if itr:
+ modified = model.get_value(itr, BE_ACTIVE_DEFAULT)
+ model.set_value(itr, BE_ACTIVE_DEFAULT, not modified)
+ self.__enable_disable_ok()
+
+ def __create_view_with_be(self, be_list):
+ dates = None
+ i = 0
+ j = 0
+ if len(be_list) == 0:
+ msg = _("The <b>libbe</b> library couldn't "
+ "prepare list of Boot Environments."
+ "\nAll functions for managing Boot Environments are disabled")
+ self.__error_occurred(msg, False)
+ return
+
+ for bee in be_list:
+ item = bootenv.BootEnv.split_be_entry(bee)
+ if item and item[0]:
+ (name, active, active_boot, be_size, be_date) = item
+ converted_size = \
+ self.__convert_size_of_be_to_string(be_size)
+ active_img = None
+ if not be_date and j == 0:
+ dates = self.__get_dates_of_creation(be_list)
+ if dates:
+ try:
+ date_time = repr(dates[i])[1:-3]
+ date_tmp = time.strptime(date_time, \
+ "%a %b %d %H:%M %Y")
+ date_tmp2 = \
+ datetime.datetime(*date_tmp[0:5])
+ try:
+ date_format = \
+ unicode(
+ _("%m/%d/%y %H:%M"),
+ "utf-8").encode(
+ locale.getpreferredencoding())
+ except (UnicodeError, LookupError,
+ locale.Error):
+ date_format = "%F %H:%M"
+ date_time = \
+ date_tmp2.strftime(date_format)
+ i += 1
+ except (NameError, ValueError, TypeError):
+ date_time = None
+ else:
+ date_tmp = time.localtime(be_date)
+ try:
+ date_format = \
+ unicode(
+ _("%m/%d/%y %H:%M"),
+ "utf-8").encode(
+ locale.getpreferredencoding())
+ except (UnicodeError, LookupError, locale.Error):
+ date_format = "%F %H:%M"
+ date_time = \
+ time.strftime(date_format, date_tmp)
+ if active:
+ active_img = self.active_image
+ self.initial_active = j
+ if active_boot:
+ self.initial_default = j
+ if date_time != None:
+ try:
+ date_time = unicode(date_time,
+ locale.getpreferredencoding()).encode(
+ "utf-8")
+ except (UnicodeError, LookupError, locale.Error):
+ pass
+ self.be_list.insert(j, [j, False,
+ name, name,
+ date_time, active_img,
+ active_boot, converted_size, active_img == None])
+ j += 1
+ self.w_be_treeview.set_cursor(self.initial_active, None,
+ start_editing=True)
+ self.w_be_treeview.scroll_to_cell(self.initial_active)
+
+ @staticmethod
+ def __destroy_be(be_name):
+ return bootenv.BootEnv.destroy_be(be_name)
+
+ @staticmethod
+ def __set_default_be(be_name):
+ return bootenv.BootEnv.set_default_be(be_name)
+
+ def __cell_data_default_function(self, column, renderer, model, itr, data):
+ if itr:
+ if model.get_value(itr, BE_MARKED):
+ self.__set_renderer_active(renderer, False)
+ else:
+ self.__set_renderer_active(renderer, True)
+
+ def __cell_data_delete_function(self, column, renderer, model, itr, data):
+ if itr:
+ if model.get_value(itr, BE_ACTIVE_DEFAULT) or \
+ (self.initial_active == model.get_value(itr, BE_ID)) or \
+ (model.get_value(itr, BE_NAME) !=
+ model.get_value(itr, BE_ORIG_NAME)):
+ self.__set_renderer_active(renderer, False)
+ else:
+ self.__set_renderer_active(renderer, True)
+
+ @staticmethod
+ def __set_renderer_active(renderer, active):
+ if active:
+ renderer.set_property("sensitive", True)
+ renderer.set_property("mode", gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+ else:
+ renderer.set_property("sensitive", False)
+ renderer.set_property("mode", gtk.CELL_RENDERER_MODE_INERT)
+
+ @staticmethod
+ def __get_dates_of_creation(be_list):
+ #zfs list -H -o creation rpool/ROOT/opensolaris-1
+ cmd = [ "/sbin/zfs", "list", "-H", "-o","creation" ]
+ for bee in be_list:
+ if bee.get("orig_be_name"):
+ name = bee.get("orig_be_name")
+ pool = bee.get("orig_be_pool")
+ cmd += [pool+"/ROOT/"+name]
+ if len(cmd) <= 5:
+ return None
+ list_of_dates = []
+ try:
+ proc = subprocess.Popen(cmd, stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE,)
+ line_out = proc.stdout.readline()
+ while line_out:
+ list_of_dates.append(line_out)
+ line_out = proc.stdout.readline()
+ except OSError:
+ return list_of_dates
+ return list_of_dates
+
+ @staticmethod
+ def __convert_size_of_be_to_string(be_size):
+ if not be_size:
+ be_size = 0
+ return pkg.misc.bytes_to_str(be_size)
+
+ @staticmethod
+ def __cell_data_function(column, renderer, model, itr, data):
+ if itr:
+ if model.get_value(itr, BE_CURRENT_PIXBUF):
+ renderer.set_property("weight", pango.WEIGHT_BOLD)
+ else:
+ renderer.set_property("weight", pango.WEIGHT_NORMAL)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/cache.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,174 @@
+#!/usr/bin/python
+#
+# 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.
+#
+
+import os
+import sys
+try:
+ import gtk
+except ImportError:
+ sys.exit(1)
+from threading import Thread
+import pkg.gui.misc_non_gui as nongui_misc
+
+CACHE_VERSION = 11
+
+class CacheListStores:
+ def __init__(self, api_o):
+ self.api_o = api_o
+
+ def __get_cache_dir(self):
+ return nongui_misc.get_cache_dir(self.api_o)
+
+ def get_index_timestamp(self):
+ return self.api_o.last_modified
+
+ def __dump_categories_expanded_dict(self, cat_exp_dict):
+ #CED entry: {('opensolaris.org', (6,)): True}
+ cache_dir = self.__get_cache_dir()
+ if not cache_dir:
+ return
+ catexs = []
+ for key, val in cat_exp_dict.iteritems():
+ if not val:
+ continue
+ name, path = key
+ path1 = -1
+ if len(path) > 0:
+ path1 = path[0]
+ catex = {}
+ catex["name"] = name
+ catex["path1"] = path1
+ catexs.append(catex)
+
+ nongui_misc.dump_cache_file(
+ os.path.join(cache_dir, "pm_cat_exp.cpl"),
+ catexs)
+
+ def __load_categories_expanded_dict(self, cat_exp_dict):
+ cache_dir = self.__get_cache_dir()
+ if not cache_dir:
+ return
+ catexs = nongui_misc.read_cache_file(
+ os.path.join(cache_dir, "pm_cat_exp.cpl"))
+ for catex in catexs:
+ name = catex.get("name")
+ path1 = catex.get("path1")
+ if path1 != -1:
+ cat_exp_dict[name, (path1,)] = True
+
+ def dump_categories_expanded_dict(self, cat_exp_dict):
+ Thread(target = self.__dump_categories_expanded_dict,
+ args = (cat_exp_dict, )).start()
+
+ def load_categories_expanded_dict(self, cat_exp_dict):
+ Thread(target = self.__load_categories_expanded_dict,
+ args = (cat_exp_dict, )).start()
+
+ def __dump_categories_active_dict(self, cat_ac_dict):
+ cache_dir = self.__get_cache_dir()
+ if not cache_dir:
+ return
+ catacs = []
+ for name, path in cat_ac_dict.iteritems():
+ path1 = -1
+ path2 = -1
+ if len(path) == 1:
+ path1 = path[0]
+ elif len(path) > 1:
+ path1 = path[0]
+ path2 = path[1]
+ catac = {}
+ catac["name"] = name
+ catac["path1"] = path1
+ catac["path2"] = path2
+ catacs.append(catac)
+
+ nongui_misc.dump_cache_file(
+ os.path.join(cache_dir, "pm_cat_ac.cpl"),
+ catacs)
+
+ def __load_categories_active_dict(self, cat_ac_dict):
+ cache_dir = self.__get_cache_dir()
+ if not cache_dir:
+ return
+ catacs = nongui_misc.read_cache_file(
+ os.path.join(cache_dir, "pm_cat_ac.cpl"))
+ for catac in catacs:
+ name = catac.get("name")
+ path1 = catac.get("path1")
+ path2 = catac.get("path2")
+ if path1 != -1 and path2 != -1:
+ cat_ac_dict[name] = (path1, path2)
+ elif path1 != -1:
+ cat_ac_dict[name] = (path1,)
+
+ def dump_categories_active_dict(self, cat_ac_dict):
+ Thread(target = self.__dump_categories_active_dict,
+ args = (cat_ac_dict, )).start()
+
+ def load_categories_active_dict(self, cat_ac_dict):
+ Thread(target = self.__load_categories_active_dict,
+ args = (cat_ac_dict, )).start()
+
+ def __dump_search_completion_info(self, completion_list):
+ cache_dir = self.__get_cache_dir()
+ if not cache_dir:
+ return
+ texts = []
+ for text in completion_list:
+ txt = {}
+ txt["text"] = text[0]
+ texts.append(txt)
+ try:
+ nongui_misc.dump_cache_file(
+ os.path.join(cache_dir, ".__search__completion.cpl"), texts)
+ except IOError:
+ return
+
+ def __load_search_completion_info(self, completion_list):
+ cache_dir = self.__get_cache_dir()
+ if not cache_dir:
+ return
+ texts = []
+ try:
+ texts = nongui_misc.read_cache_file(
+ os.path.join(cache_dir, ".__search__completion.cpl"))
+ except IOError:
+ return gtk.ListStore(str)
+
+ txt_count = 0
+ for txt in texts:
+ txt_val = txt.get("text")
+ text = [ txt_val ]
+ completion_list.insert(txt_count, text)
+ txt_count += 1
+
+ def dump_search_completion_info(self, completion_list):
+ Thread(target = self.__dump_search_completion_info,
+ args = (completion_list, )).start()
+
+ def load_search_completion_info(self, completion_list):
+ Thread(target = self.__load_search_completion_info,
+ args = (completion_list, )).start()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/detailspanel.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,310 @@
+#!/usr/bin/python
+#
+# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+import sys
+try:
+ import gobject
+ import gtk
+ import pango
+except ImportError:
+ sys.exit(1)
+import pkg.gui.misc as gui_misc
+import pkg.gui.enumerations as enumerations
+import pkg.version as version
+import pkg.client.api as api
+
+class DetailsPanel:
+ def __init__(self, parent, builder):
+ self.parent = parent
+ self.w_generalinfo_textview = \
+ builder.get_object("generalinfotextview")
+ self.w_generalinfo_textview.get_buffer().create_tag(
+ "bold", weight=pango.WEIGHT_BOLD)
+ self.w_installedfiles_textview = \
+ builder.get_object("installedfilestextview")
+ self.w_installedfiles_textview.get_buffer().create_tag(
+ "bold", weight=pango.WEIGHT_BOLD)
+ self.w_license_textview = \
+ builder.get_object("licensetextview")
+ self.w_dependencies_textview = \
+ builder.get_object("dependenciestextview")
+ self.w_versions_name_label = \
+ builder.get_object("versions_name_label")
+ self.w_versions_label = \
+ builder.get_object("versions_label")
+ self.w_versions_combobox = \
+ builder.get_object("versions_combo")
+ self.w_versions_install_button = \
+ builder.get_object("versions_install_button")
+ self.w_installable_versions_hbox = \
+ builder.get_object("installable_versions_hbox")
+
+ self.w_dependencies_textview.get_buffer().create_tag(
+ "bold", weight=pango.WEIGHT_BOLD)
+ self.showing_empty_details = False
+ self.versions_list = None
+ self.__init_versions_tree_view()
+
+ self.w_versions_install_button.connect("clicked",
+ self.__on_versions_install_button_clicked)
+
+ def __init_versions_tree_view(self):
+ cell = gtk.CellRendererText()
+ self.w_versions_combobox.pack_start(cell, True)
+ self.w_versions_combobox.add_attribute(cell, 'text',
+ enumerations.VERSION_DISPLAY_NAME)
+
+ def __on_versions_install_button_clicked(self, widget):
+ active = self.w_versions_combobox.get_active()
+ active_version = self.versions_list[active][enumerations.VERSION_NAME]
+ self.parent.install_version(active_version)
+
+ def setup_text_signals(self, has_selection_cb, focus_in_cb,
+ focus_out_cb):
+ self.w_generalinfo_textview.get_buffer().connect(
+ "notify::has-selection", has_selection_cb)
+ self.w_installedfiles_textview.get_buffer().connect(
+ "notify::has-selection", has_selection_cb)
+ self.w_dependencies_textview.get_buffer().connect(
+ "notify::has-selection", has_selection_cb)
+ self.w_license_textview.get_buffer().connect(
+ "notify::has-selection", has_selection_cb)
+ self.w_generalinfo_textview.connect(
+ "focus-in-event", focus_in_cb)
+ self.w_installedfiles_textview.connect(
+ "focus-in-event", focus_in_cb)
+ self.w_dependencies_textview.connect(
+ "focus-in-event", focus_in_cb)
+ self.w_license_textview.connect(
+ "focus-in-event", focus_in_cb)
+ self.w_generalinfo_textview.connect(
+ "focus-out-event", focus_out_cb)
+ self.w_installedfiles_textview.connect(
+ "focus-out-event", focus_out_cb)
+ self.w_dependencies_textview.connect(
+ "focus-out-event", focus_out_cb)
+ self.w_license_textview.connect(
+ "focus-out-event", focus_out_cb)
+
+ def set_fetching_info(self):
+ if self.parent.selected_pkg_name == None:
+ return
+ self.showing_empty_details = False
+ self.__show_fetching_package_info()
+
+ def __show_fetching_package_info(self):
+ instbuffer = self.w_installedfiles_textview.get_buffer()
+ infobuffer = self.w_generalinfo_textview.get_buffer()
+ fetching_text = _("Fetching information...")
+ instbuffer.set_text(fetching_text)
+ infobuffer.set_text(fetching_text)
+
+ def clear_details(self, info_pkgstem, dependencies_pkgstem, license_pkgstem,
+ versions_pkgstem, selected_pkgstem):
+ if not info_pkgstem and info_pkgstem != selected_pkgstem:
+ self.w_generalinfo_textview.get_buffer().set_text("")
+ self.w_installedfiles_textview.get_buffer().set_text("")
+ if not dependencies_pkgstem and dependencies_pkgstem != selected_pkgstem:
+ self.w_dependencies_textview.get_buffer().set_text("")
+ if not license_pkgstem and license_pkgstem != selected_pkgstem:
+ self.w_license_textview.get_buffer().set_text("")
+ if not versions_pkgstem and versions_pkgstem != selected_pkgstem:
+ self.versions_list = None
+ self.w_versions_name_label.set_text("")
+ self.w_versions_label.set_text("")
+ self.w_versions_install_button.set_sensitive(False)
+ self.__set_empty_versions_combo()
+
+ def set_empty_details(self):
+ self.showing_empty_details = True
+ self.w_installedfiles_textview.get_buffer().set_text("")
+ self.w_dependencies_textview.get_buffer().set_text("")
+ self.w_generalinfo_textview.get_buffer().set_text("")
+ self.w_license_textview.get_buffer().set_text("")
+
+ self.versions_list = None
+ self.w_versions_name_label.set_text("")
+ self.w_versions_label.set_text("")
+ self.w_versions_install_button.set_sensitive(False)
+ self.__set_empty_versions_combo()
+
+ def __set_empty_versions_combo(self, is_visible=False):
+ empty_versions_list = self.__get_new_versions_liststore()
+ empty_versions_list.append([0, _("Installable versions... "), "", 0])
+ self.w_versions_combobox.set_model(empty_versions_list)
+ self.w_versions_combobox.set_active(0)
+ self.w_installable_versions_hbox.set_property('visible', is_visible)
+
+ def set_fetching_dependencies(self):
+ if self.parent.selected_pkg_name == None:
+ return
+ self.showing_empty_details = False
+ dep_buffer = self.w_dependencies_textview.get_buffer()
+ fetching_txt = _("Fetching dependencies information...")
+ dep_buffer.set_text(fetching_txt)
+
+ def set_fetching_license(self):
+ if self.parent.selected_pkg_name == None:
+ return
+ self.showing_empty_details = False
+ licbuffer = self.w_license_textview.get_buffer()
+ leg_txt = _("Fetching legal information...")
+ licbuffer.set_text(leg_txt)
+
+ def set_fetching_versions(self):
+ if self.parent.selected_pkg_name == None:
+ return
+ self.showing_empty_details = False
+ self.w_versions_name_label.set_text(self.parent.selected_pkg_name)
+ fetching_text = _("Fetching information...")
+ self.w_versions_label.set_text(fetching_text)
+ self.w_versions_install_button.set_sensitive(False)
+ self.__set_empty_versions_combo(is_visible=True)
+
+ def update_package_dependencies(self, info, dep_info, installed_dep_info,
+ installed_icon, not_installed_icon):
+ self.__set_dependencies_text(info, dep_info,
+ installed_dep_info, installed_icon, not_installed_icon)
+
+ def no_dependencies_available(self):
+ depbuffer = self.w_dependencies_textview.get_buffer()
+ network_str = \
+ _("\nThis might be caused by network problem "
+ "while accessing the repository.")
+ depbuffer.set_text(_(
+ "Dependencies info not available for this package...") +
+ network_str)
+
+ def update_package_info(self, pkg_name, local_info, remote_info,
+ root, installed_icon, not_installed_icon, update_available_icon,
+ is_all_publishers_installed, pubs_info, renamed_info=None,
+ pkg_renamed = False):
+ instbuffer = self.w_installedfiles_textview.get_buffer()
+ infobuffer = self.w_generalinfo_textview.get_buffer()
+
+ if not local_info and not remote_info:
+ network_str = \
+ _("\nThis might be caused by network problem "
+ "while accessing the repository.")
+ instbuffer.set_text( \
+ _("Files Details not available for this package...") +
+ network_str)
+ infobuffer.set_text(
+ _("Information not available for this package...") +
+ network_str)
+ return
+
+ gui_misc.set_package_details(pkg_name, local_info,
+ remote_info, self.w_generalinfo_textview,
+ installed_icon, not_installed_icon,
+ update_available_icon,
+ is_all_publishers_installed, pubs_info, renamed_info, pkg_renamed)
+ if not local_info:
+ # Package is not installed
+ local_info = remote_info
+
+ if not remote_info:
+ remote_info = local_info
+
+ inst_str = ""
+ if local_info.dirs:
+ for x in local_info.dirs:
+ inst_str += ''.join("%s%s\n" % (
+ root, x))
+ if local_info.files:
+ for x in local_info.files:
+ inst_str += ''.join("%s%s\n" % (
+ root, x))
+ if local_info.hardlinks:
+ for x in local_info.hardlinks:
+ inst_str += ''.join("%s%s\n" % (
+ root, x))
+ if local_info.links:
+ for x in local_info.links:
+ inst_str += ''.join("%s%s\n" % (
+ root, x))
+ self.__set_installedfiles_text(inst_str)
+
+ def __set_installedfiles_text(self, text):
+ instbuffer = self.w_installedfiles_textview.get_buffer()
+ instbuffer.set_text("")
+ itr = instbuffer.get_start_iter()
+ instbuffer.insert(itr, text)
+
+ def __set_dependencies_text(self, info, dep_info, installed_dep_info,
+ installed_icon, not_installed_icon):
+ gui_misc.set_dependencies_text(self.w_dependencies_textview,
+ info, dep_info, installed_dep_info, installed_icon,
+ not_installed_icon)
+
+ def update_package_license(self, licenses):
+ if self.showing_empty_details:
+ return
+ licbuffer = self.w_license_textview.get_buffer()
+ licbuffer.set_text(gui_misc.setup_package_license(licenses))
+
+ def update_package_versions(self, versions):
+ if self.showing_empty_details:
+ return
+
+ self.versions_list = self.__get_new_versions_liststore()
+ i = 0
+ previous_display_version = None
+ self.w_versions_label.set_text(_("Not Installed"))
+ for (version_str, states) in versions:
+ state = gui_misc.get_state_from_states(states)
+
+ version_tuple = version.Version.split(version_str)
+ version_fmt = gui_misc.get_version_fmt_string()
+ display_version = version_fmt % \
+ {"version": version_tuple[0][0],
+ "build": version_tuple[0][1],
+ "branch": version_tuple[0][2]}
+ if api.PackageInfo.INSTALLED in states:
+ self.w_versions_label.set_text(display_version)
+ break
+ if (previous_display_version and
+ previous_display_version == display_version):
+ continue
+ previous_display_version = display_version
+ self.versions_list.append([i, display_version,
+ version_str, state])
+ i += 1
+ if i > 0:
+ self.w_versions_install_button.set_sensitive(True)
+ else:
+ self.versions_list.clear()
+ self.versions_list.append([0, _("No versions available"), "", 0])
+ self.w_versions_install_button.set_sensitive(False)
+ self.w_versions_combobox.set_model(self.versions_list)
+ self.w_versions_combobox.set_active(0)
+
+ @staticmethod
+ def __get_new_versions_liststore():
+ return gtk.ListStore(
+ gobject.TYPE_INT, # enumerations.VERSION_ID
+ gobject.TYPE_STRING, # enumerations.VERSION_DISPLAY_NAME
+ gobject.TYPE_STRING, # enumerations.VERSION_NAME
+ gobject.TYPE_INT, # enumerations.VERSION_STATUS
+ )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/entrystyle.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,98 @@
+#!/usr/bin/python
+#
+# 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 2010 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+import sys
+try:
+ import gtk
+except ImportError:
+ sys.exit(1)
+import pkg.gui.enumerations as enumerations
+
+SEARCH_TXT_GREY_STYLE = "#757575" #Close to DimGrey
+SEARCH_TXT_BLACK_STYLE = "#000000"
+
+class EntryStyle:
+ def __init__(self, entry):
+ self.search_txt_fg_style = gtk.gdk.color_parse(SEARCH_TXT_BLACK_STYLE)
+ self.entry = entry
+ self.entry_embedded_icons_supported = True
+ try:
+ self.entry.set_property("secondary-icon-stock", None)
+ except TypeError:
+ self.entry_embedded_icons_supported = False
+ self.search_text_style = -1
+ self.set_search_text_mode(enumerations.SEARCH_STYLE_PROMPT)
+
+ def set_theme_colour(self, page_fg):
+ self.search_txt_fg_style = page_fg
+ if self.get_text() != None:
+ self.set_search_text_mode(enumerations.SEARCH_STYLE_NORMAL)
+ else:
+ self.set_entry_to_prompt()
+
+ def set_search_text_mode(self, style):
+ if style == enumerations.SEARCH_STYLE_NORMAL:
+ self.entry.modify_text(gtk.STATE_NORMAL, self.search_txt_fg_style)
+ if self.search_text_style == enumerations.SEARCH_STYLE_PROMPT or\
+ self.entry.get_text() == _("Search (Ctrl-F)"):
+ self.entry.set_text("")
+ self.search_text_style = enumerations.SEARCH_STYLE_NORMAL
+
+ else:
+ self.entry.modify_text(gtk.STATE_NORMAL,
+ gtk.gdk.color_parse(SEARCH_TXT_GREY_STYLE))
+ self.search_text_style = enumerations.SEARCH_STYLE_PROMPT
+ self.entry.set_text(_("Search (Ctrl-F)"))
+
+ def on_entry_changed(self, widget):
+ if widget.get_text_length() > 0 and \
+ self.search_text_style != enumerations.SEARCH_STYLE_PROMPT:
+ if self.entry_embedded_icons_supported:
+ self.entry.set_property("secondary-icon-stock",
+ gtk.STOCK_CANCEL)
+ self.entry.set_property(
+ "secondary-icon-sensitive", True)
+ return True
+ else:
+ if self.entry_embedded_icons_supported:
+ self.entry.set_property("secondary-icon-stock",
+ None)
+ return False
+
+ def set_entry_to_prompt(self):
+ if self.search_text_style != enumerations.SEARCH_STYLE_PROMPT:
+ self.set_search_text_mode(enumerations.SEARCH_STYLE_PROMPT)
+
+ def get_text(self):
+ if self.search_text_style == enumerations.SEARCH_STYLE_PROMPT or \
+ self.entry.get_text_length() == 0:
+ return None
+
+ txt = self.entry.get_text()
+ if len(txt.strip()) == 0:
+ self.entry.set_text("")
+ return None
+ return txt
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/enumerations.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+#
+# 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 (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+#
+
+"""
+This module consists of user readable enumerations for the data models
+used in the IPS GUI
+"""
+
+#Application List
+(
+MARK_COLUMN,
+STATUS_ICON_COLUMN,
+NAME_COLUMN,
+DESCRIPTION_COLUMN,
+STATUS_COLUMN,
+STEM_COLUMN,
+ACTUAL_NAME_COLUMN,
+IS_VISIBLE_COLUMN, # True indicates that the package is visible in ui
+CATEGORY_LIST_COLUMN, # list of categories to which package belongs
+PUBLISHER_COLUMN, # Publisher for this package
+PUBLISHER_PREFIX_COLUMN, # Publisher prefix for this package
+RENAMED_COLUMN, # True indicates this package has been
+) = range(12)
+
+#Categories
+(
+CATEGORY_ID,
+CATEGORY_NAME,
+CATEGORY_VISIBLE_NAME,
+CATEGORY_DESCRIPTION,
+SECTION_LIST_OBJECT, #List with the sections to which category belongs
+CATEGORY_IS_VISIBLE,
+) = range(6)
+
+#Sections
+(
+SECTION_ID,
+SECTION_NAME,
+SECTION_ENABLED,
+) = range(3)
+
+#Filter
+(
+FILTER_ID,
+FILTER_ICON,
+FILTER_NAME,
+) = range(3)
+
+#Filter
+(
+FILTER_ALL,
+FILTER_INSTALLED,
+FILTER_UPDATES,
+FILTER_NOT_INSTALLED,
+FILTER_SEPARATOR,
+FILTER_SELECTED,
+) = range(6)
+
+#Search
+(
+SEARCH_ID,
+SEARCH_ICON,
+SEARCH_NAME,
+) = range(3)
+
+#Repositories switch
+(
+REPOSITORY_ID,
+REPOSITORY_DISPLAY_NAME,
+REPOSITORY_PREFIX,
+REPOSITORY_ALIAS,
+) = range(4)
+
+(
+INSTALL_UPDATE,
+REMOVE,
+IMAGE_UPDATE,
+UPDATE_FACETS
+) = range(4)
+
+# Info Cache entries
+(
+INFO_GENERAL_LABELS,
+INFO_GENERAL_TEXT,
+INFO_INSTALLED_TEXT,
+INFO_DEPEND_INFO,
+INFO_DEPEND_DEPEND_INFO,
+INFO_DEPEND_DEPEND_INSTALLED_INFO
+) = range(6)
+
+# Install/Update/Remove confirmation
+(
+CONFIRM_NAME,
+CONFIRM_PUB,
+CONFIRM_DESC,
+CONFIRM_STATUS,
+CONFIRM_STEM
+) = range(5)
+
+#Repository action
+(
+ADD_PUBLISHER,
+MANAGE_PUBLISHERS
+) = range(2)
+
+# Publisher List in Manage Publishers Dialog
+(
+PUBLISHER_PRIORITY,
+PUBLISHER_PRIORITY_CHANGED,
+PUBLISHER_NAME,
+PUBLISHER_ALIAS,
+PUBLISHER_ENABLED,
+PUBLISHER_STICKY,
+PUBLISHER_OBJECT,
+PUBLISHER_ENABLE_CHANGED,
+PUBLISHER_STICKY_CHANGED,
+PUBLISHER_REMOVED,
+) = range(10)
+
+# Publisher Priority
+(
+PUBLISHER_MOVE_BEFORE,
+PUBLISHER_MOVE_AFTER,
+) = range(2)
+
+# Return values from /usr/lib/pm-checkforupdates
+(
+UPDATES_AVAILABLE,
+NO_UPDATES_AVAILABLE,
+UPDATES_UNDETERMINED
+) = range(3)
+
+# Search Text Style
+(
+SEARCH_STYLE_NORMAL,
+SEARCH_STYLE_PROMPT
+) = range(2)
+
+# Versions
+(
+VERSION_ID,
+VERSION_DISPLAY_NAME,
+VERSION_NAME,
+VERSION_STATUS
+) = range(4)
+
+# Locale List in Preferences Dialog - Language Tab
+(
+LOCALE_NAME, # <language> (territory)
+LOCALE_LANGUAGE, # Display <language> name
+LOCALE_TERRITORY, # Display <territory> name
+LOCALE, # <language>_<territory>(<codeset>)
+LOCALE_SELECTED, # selected
+) = range(5)
+
+# Publisher Certificate List in Modify Publisher Dialog - Certificates Tab
+(
+PUBCERT_ORGANIZATION, # O
+PUBCERT_NAME, # CN
+PUBCERT_STATUS, # Approved or Revoked
+PUBCERT_IPSHASH, # IPS Cert hash
+PUBCERT_PATH, # Path to Cert when added or reinstated
+PUBCERT_XCERT_OBJ, # X509 certificate object
+PUBCERT_NEW, # True if Cert just added, but not yet commited
+) = range(7)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/exportconfirm.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,208 @@
+#!/usr/bin/python
+#
+# 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 2010 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+import sys
+import os
+import stat
+import tempfile
+import re
+try:
+ import gtk
+ import pango
+except ImportError:
+ sys.exit(1)
+import pkg.client.api_errors as api_errors
+import pkg.fmri as fmri
+import pkg.gui.misc as gui_misc
+
+class ExportConfirm:
+ def __init__(self, builder, window_icon, gconf, parent):
+ self.gconf = gconf
+ self.parent = parent
+ self.parent_window = None
+ self.window_icon = window_icon
+ self.w_exportconfirm_dialog = \
+ builder.get_object("confirmationdialog")
+ self.w_exportconfirm_dialog.set_icon(window_icon)
+ self.w_confirmok_button = builder.get_object("ok_conf")
+ self.w_confirmcancel_button = builder.get_object("cancel_conf")
+ self.w_confirmhelp_button = builder.get_object("help_conf")
+ self.w_confirm_textview = builder.get_object("confirmtext")
+ self.w_confirm_label = builder.get_object("confirm_label")
+ w_confirm_image = builder.get_object("confirm_image")
+ w_confirm_image.set_from_stock(gtk.STOCK_DIALOG_INFO,
+ gtk.ICON_SIZE_DND)
+ self.__setup_export_selection_dialog()
+ self.selected_pkgs = None
+ self.chooser_dialog = None
+
+ def set_window_icon(self, window_icon):
+ self.window_icon = window_icon
+ self.w_exportconfirm_dialog.set_icon(window_icon)
+ if self.chooser_dialog:
+ self.chooser_dialog.set_icon(window_icon)
+
+ def __setup_export_selection_dialog(self):
+ infobuffer = self.w_confirm_textview.get_buffer()
+ infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+ self.w_exportconfirm_dialog.set_title(_("Export Selections Confirmation"))
+ self.w_confirm_label.set_markup(
+ _("<b>Export the following to a Web Install .p5i file:</b>"))
+ self.w_confirmhelp_button.set_property('visible', True)
+
+ def setup_signals(self):
+ signals_table = [
+ (self.w_exportconfirm_dialog, "delete_event",
+ self.__on_confirmation_dialog_delete_event),
+ (self.w_confirmhelp_button, "clicked",
+ self.__on_confirm_help_button_clicked),
+ (self.w_confirmok_button, "clicked",
+ self.__on_confirm_proceed_button_clicked),
+ (self.w_confirmcancel_button, "clicked",
+ self.__on_confirm_cancel_button_clicked),
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def set_modal_and_transient(self, parent_window):
+ self.parent_window = parent_window
+ gui_misc.set_modal_and_transient(self.w_exportconfirm_dialog,
+ parent_window)
+
+ def __on_confirmation_dialog_delete_event(self, widget, event):
+ self.__on_confirm_cancel_button_clicked(None)
+ return True
+
+ @staticmethod
+ def __on_confirm_help_button_clicked(widget):
+ gui_misc.display_help("webinstall-export")
+
+ def __on_confirm_cancel_button_clicked(self, widget):
+ self.w_exportconfirm_dialog.hide()
+
+ def __on_confirm_proceed_button_clicked(self, widget):
+ self.w_exportconfirm_dialog.hide()
+ self.__export_selections()
+
+ def activate(self, selected_pkgs):
+ self.selected_pkgs = selected_pkgs
+ if self.selected_pkgs == None or len(self.selected_pkgs) == 0:
+ return
+
+ infobuffer = self.w_confirm_textview.get_buffer()
+ infobuffer.set_text("")
+ textiter = infobuffer.get_end_iter()
+
+ for pub_name, pkgs in self.selected_pkgs.items():
+ name = self.parent.get_publisher_name_from_prefix(pub_name)
+ if name == pub_name:
+ infobuffer.insert_with_tags_by_name(textiter,
+ "%s\n" % pub_name, "bold")
+ else:
+ infobuffer.insert_with_tags_by_name(textiter,
+ "%s" % name, "bold")
+ infobuffer.insert(textiter, " (%s)\n" % pub_name)
+ for pkg in pkgs.keys():
+ infobuffer.insert(textiter,
+ "\t%s\n" % fmri.extract_pkg_name(pkg))
+ self.w_confirmok_button.grab_focus()
+ self.w_exportconfirm_dialog.show()
+
+ def __export_selections(self):
+ filename = self.__get_export_p5i_filename(
+ self.gconf.last_export_selection_path)
+ if not filename:
+ return
+ self.gconf.last_export_selection_path = filename
+ try:
+ fobj = open(filename, 'w')
+ api_o = self.parent.get_api_object()
+ api_o.write_p5i(fobj, pkg_names=self.selected_pkgs,
+ pubs=self.selected_pkgs.keys())
+ except IOError, ex:
+ err = str(ex)
+ self.parent.error_occurred(err, _("Export Selections Error"))
+ return
+ except api_errors.ApiException, ex:
+ fobj.close()
+ err = str(ex)
+ self.parent.error_occurred(err, _("Export Selections Error"))
+ return
+ fobj.close()
+ os.chmod(filename, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP |
+ stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH )
+
+ def __get_export_p5i_filename(self, last_export_selection_path):
+ filename = None
+ chooser = gtk.FileChooserDialog(_("Export Selections"),
+ self.parent_window,
+ gtk.FILE_CHOOSER_ACTION_SAVE,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+ chooser.set_icon(self.window_icon)
+ self.chooser_dialog = chooser
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name(_("p5i Files"))
+ file_filter.add_pattern("*.p5i")
+ chooser.add_filter(file_filter)
+ file_filter = gtk.FileFilter()
+ file_filter.set_name(_("All Files"))
+ file_filter.add_pattern("*")
+ chooser.add_filter(file_filter)
+
+ path = tempfile.gettempdir()
+ name = _("my_packages")
+ if last_export_selection_path and last_export_selection_path != "":
+ path, name_plus_ext = os.path.split(last_export_selection_path)
+ result = os.path.splitext(name_plus_ext)
+ name = result[0]
+
+ #Check name
+ base_name = None
+ m = re.match("(.*)(-\d+)$", name)
+ if m == None and os.path.exists(path + os.sep + name + '.p5i'):
+ base_name = name
+ if m and len(m.groups()) == 2:
+ base_name = m.group(1)
+ name = name + '.p5i'
+ if base_name:
+ for i in range(1, 99):
+ full_path = path + os.sep + base_name + '-' + \
+ str(i) + '.p5i'
+ if not os.path.exists(full_path):
+ name = base_name + '-' + str(i) + '.p5i'
+ break
+ chooser.set_current_folder(path)
+ chooser.set_current_name(name)
+ chooser.set_do_overwrite_confirmation(True)
+
+ response = chooser.run()
+ if response == gtk.RESPONSE_OK:
+ filename = chooser.get_filename()
+ self.chooser_dialog = None
+ chooser.destroy()
+
+ return filename
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/globalexceptionhandler.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,174 @@
+#!/usr/bin/python
+#
+# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+import sys
+import threading
+import traceback
+from cStringIO import StringIO
+
+try:
+ import gobject
+ import gtk
+ import pango
+except ImportError:
+ sys.exit(1)
+import pkg.misc as misc
+import pkg.gui.misc as gui_misc
+
+class GlobalExceptionHandler:
+ def __init__(self):
+ self.parent = None
+ sys.excepthook = self.global_exception_handler
+ self.installThreadExcepthook()
+
+ def set_parent(self, parent):
+ self.parent = parent
+
+ def global_exception_handler(self, exctyp, value, tb):
+ if self.parent:
+ if self.parent.child:
+ self.parent.child.cleanup()
+ trace = StringIO()
+ traceback.print_exception (exctyp, value, tb, None, trace)
+ if exctyp is MemoryError:
+ gobject.idle_add(self.__display_memory_err)
+ else:
+ gobject.idle_add(self.__display_unknown_err_ex, trace)
+
+ def installThreadExcepthook(self):
+ """
+ Workaround for sys.excepthook python thread bug from:
+ Bug: sys.excepthook doesn't work in threads
+ http://bugs.python.org/issue1230540#msg91244
+ """
+ init_old = threading.Thread.__init__
+ def init(self, *ite_args, **ite_kwargs):
+ init_old(self, *ite_args, **ite_kwargs)
+ run_old = self.run
+ def run_with_except_hook(*rweh_args, **rweh_kwargs):
+ try:
+ run_old(*rweh_args, **rweh_kwargs)
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except:
+ if not sys:
+ raise
+ sys.excepthook(*sys.exc_info())
+ self.run = run_with_except_hook
+ threading.Thread.__init__ = init
+
+ def __display_memory_err(self):
+ try:
+ dmsg = misc.out_of_memory()
+ msg_stripped = dmsg.replace("\n", " ")
+ gui_misc.error_occurred(None, msg_stripped, _("Package Manager"),
+ gtk.MESSAGE_ERROR)
+ except MemoryError:
+ print dmsg
+ except Exception:
+ pass
+ if self.parent:
+ self.parent.unhandled_exception_shutdown()
+ else:
+ sys.exit()
+
+ def __display_unknown_err_ex(self, trace):
+ try:
+ self.__display_unknown_err(trace)
+ except MemoryError:
+ print trace
+ except Exception:
+ pass
+ if self.parent:
+ self.parent.unhandled_exception_shutdown()
+ else:
+ sys.exit()
+
+ def __display_unknown_err(self, trace):
+ dmsg = _("An unknown error occurred")
+ md = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, message_format=dmsg)
+ close_btn = md.add_button(gtk.STOCK_CLOSE, 100)
+ md.set_default_response(100)
+
+ dmsg = _("Please let the developers know about this problem by "
+ "filing a bug together with the error details listed below at:")
+ md.format_secondary_text(dmsg)
+ md.set_title(_('Unexpected Error'))
+
+ uri_btn = gtk.LinkButton(misc.BUG_URI_GUI,
+ "defect.opensolaris.org")
+ uri_btn.set_relief(gtk.RELIEF_NONE)
+ uri_btn.set_size_request(160, -1)
+ align = gtk.Alignment(0, 0, 0, 0)
+ align.set_padding(0, 0, 56, 0)
+ align.add(uri_btn)
+
+ textview = gtk.TextView()
+ textview.show()
+ textview.set_editable(False)
+ textview.set_wrap_mode(gtk.WRAP_WORD)
+
+ sw = gtk.ScrolledWindow()
+ sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ sw.add(textview)
+ fr = gtk.Frame()
+ fr.set_shadow_type(gtk.SHADOW_IN)
+ fr.add(sw)
+ ca = md.get_content_area()
+ ca.pack_start(align, False, False, 0)
+ ca.pack_start(fr)
+
+ textbuffer = textview.get_buffer()
+ textbuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+ textbuffer.create_tag("level1", left_margin=30, right_margin=10)
+ textiter = textbuffer.get_end_iter()
+ textbuffer.insert_with_tags_by_name(textiter,
+ _("Error details:\n"), "bold")
+ textbuffer.insert_with_tags_by_name(textiter, trace.getvalue(), "level1")
+ publisher_str = ""
+ if self.parent:
+ publisher_str = \
+ gui_misc.get_publishers_for_output(
+ self.parent.get_api_object())
+ if publisher_str != "":
+ textbuffer.insert_with_tags_by_name(textiter,
+ _("\nList of configured publishers:"), "bold")
+ textbuffer.insert_with_tags_by_name(
+ textiter, publisher_str + "\n", "level1")
+
+ if publisher_str == "":
+ textbuffer.insert_with_tags_by_name(textiter,
+ _("\nPlease include output from:\n"), "bold")
+ textbuffer.insert(textiter, "$ pkg publisher\n")
+
+ ver = gui_misc.get_version()
+ textbuffer.insert_with_tags_by_name(textiter,
+ _("\npkg version:\n"), "bold")
+ textbuffer.insert_with_tags_by_name(textiter, ver + "\n", "level1")
+ md.set_size_request(550, 400)
+ md.set_resizable(True)
+ close_btn.grab_focus()
+ md.show_all()
+ md.run()
+ md.destroy()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/imageinfo.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+#
+# 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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+import ConfigParser
+import re
+import sys
+import os
+from ConfigParser import ParsingError
+
+class ImageInfo(object):
+ """An ImagineInfo object is a collection of information
+ about the packages for the Imagine GUI"""
+
+ def __init__(self):
+ self.categories = {}
+
+ def read(self, path):
+ """This method reads specified by path file and returns lists of
+ categories per package"""
+ cpars = self.__get_config_parser(path)
+ if cpars:
+ for section in cpars.sections():
+ self.categories[section] = cpars.get(section, "category")
+ return self.categories
+
+ def get_pixbuf_image_for_package(self, path, package_name):
+ """Method that returns pixbuf field from the file specified by path for
+ the given package_name"""
+ cpars = self.__get_config_parser(path)
+ if cpars:
+ for section in cpars.sections():
+ if re.match(package_name, section):
+ pixbuf = cpars.get(section, "pixbuf")
+ return pixbuf
+ return None
+
+ def add_package(self, path, name, category):
+ """Add the package information to the file specified by the path. If the
+ package name already exists, than returns False"""
+ cpars = self.__get_config_parser(path)
+ if cpars:
+ for section in cpars.sections():
+ if re.match(name, section):
+ #This should behave differently, if the repo
+ #exists should throw some error
+ return False
+ cpars.add_section(name)
+ cpars.set(name, "category", category)
+ file_op = open(path, "w")
+ cpars.write(file_op)
+ return True
+ return False
+
+ def remove_package(self, path, name):
+ """If exists removes package specified by name from the
+ filename specified by path"""
+ cpars = self.__get_config_parser(path)
+ if cpars:
+ for section in cpars.sections():
+ if re.match(name, section):
+ cpars.remove_section(name)
+ file_op = open(path, "w")
+ cpars.write(file_op)
+
+ @staticmethod
+ def __get_config_parser(path):
+ """Creates and returns ConfigParser.SafeConfigParser()"""
+ cpars = ConfigParser.SafeConfigParser()
+ if cpars:
+ read_cp = cpars.read(path)
+ if read_cp:
+ if read_cp[0] != path:
+ raise ParsingError
+ return cpars
+
+ @staticmethod
+ def __mkdirs_files(path):
+ if not os.path.isdir(os.path.dirname(path)):
+ os.makedirs(os.path.dirname(path))
+ if not os.path.isfile(path):
+ file_op = open(path, "w")
+ file_op.close()
+
+if __name__ == "__main__":
+ print "Usage:"
+ print "./imageinfo.py FILE..."
+ sys.exit(0)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/installupdate.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,1647 @@
+#!/usr/bin/python
+#
+# 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 (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+#
+
+DEFAULT_CONFIRMATION_WIDTH = 550 # Width & height of single confirmation
+DEFAULT_CONFIRMATION_HEIGHT = 200 # frame. The confirmation dialog may
+ # consist of frames for packages to be
+ # installed, removed or updated.
+DISPLAY_DELAY = 200 # Delay before updating GUI when
+ # displaying download or phase info
+RESET_PACKAGE_DELAY = 2000 # Delay before label text is reset
+ # Also used to reset window text during install
+DIALOG_DEFAULT_WIDTH = 450 # Default Width of Progress Dialog
+DIALOG_EXPANDED_DETAILS_HEIGHT = 462 # Height of Progress Dialog when Details expanded
+DIALOG_INSTALL_COLLAPSED_HEIGHT = 242 # Heights of progress dialog when Details
+ # collapsed for install, remove and done stages
+DIALOG_REMOVE_COLLAPSED_HEIGHT = 220
+DIALOG_DONE_COLLAPSED_HEIGHT = 126
+
+DIALOG_UM_EXTRA_HEIGHT = 60 # Extra height needed when in UM mode
+DIALOG_RELEASE_NOTE_OFFSET = 34 # Additional space required if displaying
+ # Release notes link below Details
+import errno
+import os
+import sys
+import time
+import pango
+import datetime
+import traceback
+from gettext import ngettext
+from threading import Thread
+from threading import Condition
+try:
+ import gobject
+ import gtk
+ import pygtk
+ pygtk.require("2.0")
+except ImportError:
+ sys.exit(1)
+
+import pkg.gui.progress as progress
+import pkg.misc as misc
+import pkg.client.api as api
+import pkg.client.api_errors as api_errors
+import pkg.gui.beadmin as beadm
+import pkg.gui.uarenamebe as uarenamebe
+import pkg.gui.misc as gui_misc
+import pkg.gui.enumerations as enumerations
+import pkg.gui.pmgconf as pmgconf
+from pkg.client import global_settings
+
+logger = global_settings.logger
+debug = False
+
+class InstallUpdate(progress.GuiProgressTracker):
+ def __init__(self, list_of_packages, parent, image_directory,
+ action = -1, parent_name = "", pkg_list = None, main_window = None,
+ icon_confirm_dialog = None, title = None, web_install = False,
+ confirmation_list = None, show_confirmation = False, api_lock = None,
+ gconf = None, facets = None):
+ if action == -1:
+ return
+ self.gconf = gconf
+ progress.GuiProgressTracker.__init__(self, indent=True)
+ if self.gconf == None:
+ self.gconf = pmgconf.PMGConf()
+ self.retry = False
+ self.web_install = web_install
+ self.web_updates_list = None
+ self.web_install_all_installed = False
+ self.parent = parent
+ self.api_lock = api_lock
+ self.facets = facets
+ self.api_o = gui_misc.get_api_object(image_directory,
+ self, main_window)
+ if self.api_o == None:
+ return
+ self.parent_name = parent_name
+ self.confirmation_list = confirmation_list
+ if confirmation_list == None:
+ self.confirmation_list = []
+ self.show_confirmation = show_confirmation
+ if main_window == None:
+ self.top_level = True
+ else:
+ self.top_level = False
+ self.ipkg_ipkgui_list = pkg_list
+ self.icon_confirm_dialog = icon_confirm_dialog
+ self.title = title
+ self.w_main_window = main_window
+ if self.icon_confirm_dialog == None and self.w_main_window != None:
+ self.icon_confirm_dialog = self.w_main_window.get_icon()
+
+ gladefile = os.path.join(self.parent.application_dir,
+ "usr/share/package-manager/packagemanager.ui")
+ builder = gtk.Builder()
+ builder.add_from_file(gladefile)
+ self.w_dialog = builder.get_object("createplandialog")
+ self.original_title = None
+ if self.w_main_window:
+ self.original_title = self.w_main_window.get_title()
+ if self.top_level:
+ globals()["DIALOG_INSTALL_COLLAPSED_HEIGHT"] = \
+ DIALOG_INSTALL_COLLAPSED_HEIGHT + DIALOG_UM_EXTRA_HEIGHT
+ globals()["DIALOG_DONE_COLLAPSED_HEIGHT"] = \
+ DIALOG_DONE_COLLAPSED_HEIGHT + DIALOG_UM_EXTRA_HEIGHT
+ self.w_dialog.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL)
+ self.w_dialog.set_icon(self.icon_confirm_dialog)
+ self.w_main_window = self.w_dialog
+ self.original_title = _("Update Manager")
+ w_icon_um = builder.get_object("icon_um")
+ w_icon_um.set_from_pixbuf(self.icon_confirm_dialog)
+ else:
+ um_vbox = builder.get_object("um_title_vbox")
+ um_vbox.set_property("visible", False)
+
+ self.license_cv = Condition()
+ self.list_of_packages = list_of_packages
+ self.accept_license_done = False
+ self.action = action
+ self.canceling = False
+ self.current_stage_name = None
+ self.ip = None
+ self.ips_update = False
+ self.operations_done = False
+ self.operations_done_ex = False
+ self.prev_ind_phase = None
+ self.reboot_needed = False
+ self.uarenamebe_o = None
+ self.label_text = None
+ self.prev_pkg = None
+ self.prev_prog = -1
+ self.prog = 0
+ self.progress_stop_timer_running = False
+ self.pylint_stub = None
+ self.reset_id = 0
+ self.reset_window_id = 0
+ self.display_download_id = 0
+ self.update_progress_id = 0
+ self.stages = {
+ 1:[_("Preparing..."), _("Preparation")],
+ 2:[_("Downloading..."), _("Download")],
+ 3:[_("Installing..."), _("Install")],
+ }
+ self.current_stage_label_done = self.stages[1][1]
+ self.stop_progress_bouncing = False
+ self.stopped_bouncing_progress = True
+ self.update_list = {}
+
+ self.w_confirm_dialog = builder.get_object("confirmdialog")
+ self.w_install_expander = \
+ builder.get_object("install_expander")
+ self.w_install_frame = \
+ builder.get_object("install_frame")
+ self.w_install_treeview = \
+ builder.get_object("install_treeview")
+ self.w_update_expander = \
+ builder.get_object("update_expander")
+ self.w_update_frame = \
+ builder.get_object("update_frame")
+ self.w_update_treeview = \
+ builder.get_object("update_treeview")
+ self.w_remove_expander = \
+ builder.get_object("remove_expander")
+ self.w_remove_frame = \
+ builder.get_object("frame3")
+ self.w_remove_treeview = \
+ builder.get_object("remove_treeview")
+ self.w_confirm_ok_button = \
+ builder.get_object("confirm_ok_button")
+ self.w_confirm_cancel_button = \
+ builder.get_object("confirm_cancel_button")
+ self.w_confirm_label = \
+ builder.get_object("confirmdialog_confirm_label")
+ self.w_confirm_donotshow = \
+ builder.get_object("confirm_donotshow")
+
+ self.w_confirm_dialog.set_icon(self.icon_confirm_dialog)
+ gui_misc.set_modal_and_transient(self.w_confirm_dialog,
+ self.w_main_window)
+
+ self.w_expander = builder.get_object("details_expander")
+ self.w_cancel_button = builder.get_object("cancelcreateplan")
+ self.w_help_button = builder.get_object("helpcreateplan")
+ if self.top_level:
+ self.w_help_button.set_property("visible", True)
+ else:
+ self.w_help_button.set_property("visible", False)
+
+ self.w_close_button = builder.get_object("closecreateplan")
+ self.w_release_notes = builder.get_object("release_notes")
+ self.w_release_notes_link = \
+ builder.get_object("ua_release_notes_button")
+ self.w_progressbar = builder.get_object("createplanprogress")
+ self.w_details_textview = builder.get_object("createplantextview")
+
+ self.w_stage2 = builder.get_object("stage2")
+ self.w_stages_box = builder.get_object("stages_box")
+ self.w_stage1_label = builder.get_object("label_stage1")
+ self.w_stage1_icon = builder.get_object("icon_stage1")
+ self.w_stage2_label = builder.get_object("label_stage2")
+ self.w_stage2_icon = builder.get_object("icon_stage2")
+ self.w_stage3_label = builder.get_object("label_stage3")
+ self.w_stage3_icon = builder.get_object("icon_stage3")
+ self.w_stages_label = builder.get_object("label_stages")
+ self.w_stages_icon = builder.get_object("icon_stages")
+ self.current_stage_label = self.w_stage1_label
+ self.current_stage_icon = self.w_stage1_icon
+
+ self.w_stages_label.set_line_wrap(True)
+ self.w_stages_label.set_size_request(DIALOG_DEFAULT_WIDTH - 20, -1)
+
+ self.done_icon = gui_misc.get_icon(
+ self.parent.icon_theme, "progress_checkmark")
+ blank_icon = gui_misc.get_icon(
+ self.parent.icon_theme, "progress_blank")
+
+ checkmark_icon = gui_misc.get_icon(
+ self.parent.icon_theme, "pm-check", 24)
+
+ self.w_stages_icon.set_from_pixbuf(checkmark_icon)
+
+ self.w_stage1_icon.set_from_pixbuf(blank_icon)
+ self.w_stage2_icon.set_from_pixbuf(blank_icon)
+ self.w_stage3_icon.set_from_pixbuf(blank_icon)
+
+ proceed_txt = _("_Proceed")
+ gui_misc.change_stockbutton_label(self.w_confirm_ok_button, proceed_txt)
+
+ infobuffer = self.w_details_textview.get_buffer()
+ infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+ infobuffer.create_tag("level1", left_margin=30, right_margin=10)
+ infobuffer.create_tag("level2", left_margin=50, right_margin=10)
+
+ self.w_progressbar.set_pulse_step(0.02)
+ self.w_release_notes.hide()
+
+ self.w_license_dialog = builder.get_object("license_dialog")
+ self.w_license_label = builder.get_object("instruction_label")
+ self.w_license_text = builder.get_object("textview1")
+ self.w_license_accept_checkbutton = \
+ builder.get_object("license_accept_checkbutton")
+ self.w_license_accept_button = \
+ builder.get_object("license_accept_button")
+ self.w_license_reject_button = \
+ builder.get_object("license_reject_button")
+ self.accept_text = gui_misc.get_stockbutton_label_label(
+ self.w_license_accept_button)
+ gui_misc.change_stockbutton_label(self.w_license_reject_button,
+ _("_Reject"))
+ self.current_license_no = 0
+ self.packages_with_license = None
+ self.packages_with_license_result = []
+ self.n_licenses = 0
+ self.dlg_expanded_details_h = DIALOG_EXPANDED_DETAILS_HEIGHT
+ self.dlg_width = DIALOG_DEFAULT_WIDTH
+ self.dlg_install_collapsed_h = DIALOG_INSTALL_COLLAPSED_HEIGHT
+ self.dlg_remove_collapsed_h = DIALOG_REMOVE_COLLAPSED_HEIGHT
+ self.dlg_done_collapsed_h = DIALOG_DONE_COLLAPSED_HEIGHT
+
+ self.__setup_signals()
+ if not self.top_level:
+ gui_misc.set_modal_and_transient(self.w_dialog,
+ self.w_main_window)
+ self.w_license_dialog.set_icon(self.icon_confirm_dialog)
+ gui_misc.set_modal_and_transient(self.w_license_dialog,
+ self.w_dialog)
+ self.__start_action()
+ self.__setup_createplan_dlg_sizes()
+
+ def __setup_signals(self):
+ signals_table = [
+ (self.w_cancel_button, "clicked",
+ self.__on_cancelcreateplan_clicked),
+ (self.w_close_button, "clicked",
+ self.__on_closecreateplan_clicked),
+ (self.w_dialog, "delete_event",
+ self.__on_createplandialog_delete),
+ (self.w_expander, "activate",
+ self.__on_details_expander_activate),
+ (self.w_help_button, "clicked",
+ self.__on_help_button_clicked),
+
+ (self.w_license_reject_button, "clicked",
+ self.__on_license_reject_button_clicked),
+ (self.w_license_accept_button, "clicked",
+ self.__on_license_accept_button_clicked),
+ (self.w_license_accept_checkbutton, "toggled",
+ self.__on_license_accept_checkbutton_toggled),
+ (self.w_license_dialog, "delete_event",
+ self.__on_license_dialog_delete),
+
+ (self.w_confirm_dialog, "delete_event",
+ self.__on_confirmdialog_delete_event),
+ (self.w_confirm_donotshow, "toggled",
+ self.__on_confirm_donotshow_toggled),
+ (self.w_confirm_cancel_button, "clicked",
+ self.__on_confirm_cancel_button_clicked),
+ (self.w_confirm_ok_button, "clicked",
+ self.__on_confirm_ok_button_clicked),
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def __setup_createplan_dlg_sizes(self):
+ #Get effective screen space available (net of panels and docks)
+ #instead of using gtk.gdk.screen_width() and gtk.gdk.screen_height()
+ root_win = gtk.gdk.get_default_root_window()
+ net_workarea_prop = gtk.gdk.atom_intern('_NET_WORKAREA')
+ sw, sh = root_win.property_get(net_workarea_prop)[2][2:4]
+ sw -= 28 # Default width of Panel accounts for bottom or side System Panel
+ sh -= 28
+ scale = gui_misc.get_scale(self.w_details_textview)
+
+ if DIALOG_EXPANDED_DETAILS_HEIGHT * scale <= sh:
+ self.dlg_expanded_details_h = \
+ (int) (DIALOG_EXPANDED_DETAILS_HEIGHT * scale)
+ self.dlg_install_collapsed_h = \
+ (int) (DIALOG_INSTALL_COLLAPSED_HEIGHT * scale)
+ self.dlg_remove_collapsed_h = \
+ (int) (DIALOG_REMOVE_COLLAPSED_HEIGHT * scale)
+ self.dlg_done_collapsed_h = \
+ (int) (DIALOG_DONE_COLLAPSED_HEIGHT * scale)
+ else:
+ self.dlg_expanded_details_h = sh
+ if DIALOG_INSTALL_COLLAPSED_HEIGHT * scale <= sh:
+ self.dlg_install_collapsed_h = \
+ (int) (DIALOG_INSTALL_COLLAPSED_HEIGHT * scale)
+ self.dlg_remove_collapsed_h = \
+ (int) (DIALOG_REMOVE_COLLAPSED_HEIGHT * scale)
+ self.dlg_done_collapsed_h = \
+ (int) (DIALOG_DONE_COLLAPSED_HEIGHT * scale)
+ else:
+ self.dlg_install_collapsed_h = sh
+ if DIALOG_REMOVE_COLLAPSED_HEIGHT * scale <= sh:
+ self.dlg_remove_collapsed_h = (int) \
+ (DIALOG_REMOVE_COLLAPSED_HEIGHT * scale)
+ self.dlg_done_collapsed_h = (int) \
+ (DIALOG_DONE_COLLAPSED_HEIGHT * scale)
+ else:
+ self.dlg_remove_collapsed_h = sh
+ if DIALOG_DONE_COLLAPSED_HEIGHT * scale <= sh:
+ self.dlg_done_collapsed_h = (int) \
+ (DIALOG_DONE_COLLAPSED_HEIGHT * \
+ scale)
+ else:
+ self.dlg_done_collapsed_h = sh
+
+ if DIALOG_DEFAULT_WIDTH * scale <= sw:
+ self.dlg_width = \
+ (int) (DIALOG_DEFAULT_WIDTH * scale)
+ else:
+ self.dlg_width = sw
+
+ if debug:
+ print "CreatePlan Dialog Sizes: window", sw, sh, scale, " dlg ", \
+ self.dlg_width, self.dlg_expanded_details_h, " coll ", \
+ self.dlg_install_collapsed_h, \
+ self.dlg_remove_collapsed_h, self.dlg_done_collapsed_h
+
+ if self.gconf.details_expanded:
+ self.__set_dialog_size(self.dlg_width,
+ self.dlg_expanded_details_h)
+ else:
+ if not (self.w_stage2.flags() & gtk.VISIBLE):
+ self.__set_dialog_size(self.dlg_width,
+ self.dlg_remove_collapsed_h)
+ else:
+ self.__set_dialog_size(self.dlg_width,
+ self.dlg_install_collapsed_h)
+
+ def __start_action(self):
+ if self.action == enumerations.REMOVE:
+ # For the remove, we are not showing the download stage
+ self.stages[3] = [_("Removing..."), _("Remove")]
+ self.w_stage3_label.set_text(self.stages[3][1])
+ self.w_stage2.hide()
+ self.w_dialog.set_title(_("Remove"))
+
+ if self.show_confirmation and len(self.confirmation_list) > 0:
+ self.w_confirm_dialog.set_title(_("Remove Confirmation"))
+ pkgs_no = len(self.confirmation_list)
+ remove_text = ngettext(
+ "Review the package to be removed",
+ "Review the packages to be removed", pkgs_no)
+ self.w_confirm_label.set_markup("<b>"+remove_text+"</b>")
+
+ self.w_install_expander.hide()
+ self.w_update_expander.hide()
+ if not self.retry:
+ self.__init_confirmation_tree_view(
+ self.w_remove_treeview)
+ liststore = gtk.ListStore(str, str, str)
+ for sel_pkg in self.confirmation_list:
+ liststore.append(
+ [sel_pkg[enumerations.CONFIRM_NAME],
+ sel_pkg[enumerations.CONFIRM_PUB],
+ sel_pkg[enumerations.CONFIRM_DESC]])
+ liststore.set_default_sort_func(lambda *args: -1)
+ liststore.set_sort_column_id(0, gtk.SORT_ASCENDING)
+ self.w_remove_treeview.set_model(liststore)
+ self.w_remove_expander.set_expanded(True)
+ self.w_confirm_ok_button.grab_focus()
+ self.w_confirm_dialog.show()
+ else:
+ self.__proceed_with_stages()
+ elif self.action == enumerations.IMAGE_UPDATE:
+ if not self.top_level:
+ self.w_dialog.set_title(_("Updates"))
+ self.__proceed_with_stages()
+ elif self.action == enumerations.UPDATE_FACETS:
+ if not self.top_level:
+ self.w_dialog.set_title(
+ _("Update Optional Components"))
+ self.__proceed_with_stages()
+ else:
+ if self.title != None:
+ self.w_dialog.set_title(self.title)
+ else:
+ self.w_dialog.set_title(_("Install/Update"))
+
+ if self.show_confirmation and len(self.confirmation_list) > 0:
+ self.w_remove_expander.hide()
+ to_install = gtk.ListStore(str, str, str)
+ to_update = gtk.ListStore(str, str, str)
+ for cpk in self.confirmation_list:
+ if cpk[enumerations.CONFIRM_STATUS] == \
+ api.PackageInfo.UPGRADABLE:
+ to_update.append(
+ [cpk[enumerations.CONFIRM_NAME],
+ cpk[enumerations.CONFIRM_PUB],
+ cpk[enumerations.CONFIRM_DESC]])
+ else:
+ to_install.append(
+ [cpk[enumerations.CONFIRM_NAME],
+ cpk[enumerations.CONFIRM_PUB],
+ cpk[enumerations.CONFIRM_DESC]])
+
+ operation_txt = _("Install/Update Confirmation")
+ install_text = ngettext(
+ "Review the package to be Installed/Updated",
+ "Review the packages to be Installed/Updated",
+ len(self.confirmation_list))
+
+ if len(to_install) == 0:
+ operation_txt = _("Updates Confirmation")
+ install_text = ngettext(
+ "Review the package to be Updated",
+ "Review the packages to be Updated",
+ len(to_update))
+
+ if len(to_update) == 0:
+ operation_txt = _("Install Confirmation")
+ install_text = ngettext(
+ "Review the package to be Installed",
+ "Review the packages to be Installed",
+ len(to_install))
+
+ self.w_confirm_dialog.set_title(operation_txt)
+ self.w_confirm_label.set_markup("<b>"+install_text+"</b>")
+
+ if len(to_install) > 0:
+ self.__init_confirmation_tree_view(
+ self.w_install_treeview)
+ to_install.set_default_sort_func(lambda *args: -1)
+ to_install.set_sort_column_id(0,
+ gtk.SORT_ASCENDING)
+ self.w_install_treeview.set_model(to_install)
+ self.w_install_expander.set_expanded(True)
+ else:
+ self.w_install_expander.hide()
+ if len(to_update) > 0:
+ self.__init_confirmation_tree_view(
+ self.w_update_treeview)
+ to_update.set_default_sort_func(lambda *args: -1)
+ to_update.set_sort_column_id(0,
+ gtk.SORT_ASCENDING)
+ self.w_update_treeview.set_model(to_update)
+ self.w_update_expander.set_expanded(True)
+ else:
+ self.w_update_expander.hide()
+ self.w_confirm_ok_button.grab_focus()
+ self.w_confirm_dialog.show()
+ else:
+ self.__proceed_with_stages()
+
+ @staticmethod
+ def __init_confirmation_tree_view(treeview):
+ name_renderer = gtk.CellRendererText()
+ name_renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
+ column = gtk.TreeViewColumn(_('Name'), name_renderer,
+ text = enumerations.CONFIRM_NAME)
+ column.set_resizable(True)
+ column.set_min_width(150)
+ column.set_sort_column_id(0)
+ column.set_sort_indicator(True)
+ treeview.append_column(column)
+ publisher_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_('Publisher'), publisher_renderer,
+ text = enumerations.CONFIRM_PUB)
+ column.set_resizable(True)
+ column.set_sort_column_id(1)
+ column.set_sort_indicator(True)
+ treeview.append_column(column)
+ summary_renderer = gtk.CellRendererText()
+ summary_renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
+ column = gtk.TreeViewColumn(_('Summary'), summary_renderer,
+ text = enumerations.CONFIRM_DESC)
+ column.set_resizable(True)
+ column.set_sort_column_id(2)
+ column.set_sort_indicator(True)
+ treeview.append_column(column)
+
+ def __on_confirm_donotshow_toggled(self, widget):
+ if self.action == enumerations.REMOVE:
+ self.gconf.set_show_remove(not self.gconf.show_remove)
+ elif self.action == enumerations.IMAGE_UPDATE:
+ self.gconf.set_show_image_update(not self.gconf.show_image_update)
+ elif self.action == enumerations.INSTALL_UPDATE:
+ self.gconf.set_show_install(not self.gconf.show_install)
+
+ def __on_confirm_ok_button_clicked(self, widget):
+ if self.action == enumerations.INSTALL_UPDATE or \
+ self.action == enumerations.REMOVE:
+ self.__on_confirm_cancel_button_clicked(None)
+ if self.top_level:
+ self.w_main_window = self.w_dialog
+ self.__proceed_with_stages()
+ else:
+ self.w_expander.set_expanded(self.gconf.details_expanded)
+ self.w_dialog.show()
+ self.__on_confirm_cancel_button_clicked(None)
+ self.__proceed_with_stages(continue_operation = True)
+
+ def __on_confirmdialog_delete_event(self, widget, event):
+ self.__on_confirm_cancel_button_clicked(widget)
+ return True
+
+ def __on_confirm_cancel_button_clicked(self, widget):
+ self.w_confirm_dialog.hide()
+ if self.top_level and widget: # User clicked cacnel, widget != None
+ gobject.idle_add(self.parent.install_terminated)
+
+ def __on_createplandialog_delete(self, widget, event):
+ self.__on_cancelcreateplan_clicked(None)
+ return True
+
+ def __set_dialog_size(self, w, h):
+ self.w_dialog.set_size_request(w, h)
+ self.w_dialog.resize(w, h)
+
+ def __on_details_expander_activate(self, widget):
+ collapsed = self.w_expander.get_expanded()
+ if collapsed:
+ if not (self.w_stages_box.flags() & gtk.VISIBLE):
+ self.__set_dialog_size(self.dlg_width,
+ self.dlg_done_collapsed_h)
+ elif not (self.w_stage2.flags() & gtk.VISIBLE):
+ self.__set_dialog_size(self.dlg_width,
+ self.dlg_remove_collapsed_h)
+ else:
+ self.__set_dialog_size(self.dlg_width,
+ self.dlg_install_collapsed_h)
+ else:
+ self.__set_dialog_size(self.dlg_width,
+ self.dlg_expanded_details_h)
+
+ self.gconf.set_details_expanded(not self.gconf.details_expanded)
+
+ def __on_cancelcreateplan_clicked(self, widget):
+ '''Handler for signal send by cancel button, which user might press
+ during evaluation stage - while the dialog is creating plan'''
+ if self.api_o.can_be_canceled() and self.operations_done_ex == False:
+ self.canceling = True
+ Thread(target = self.api_o.cancel, args = ()).start()
+ cancel_txt = _("Canceling...")
+ txt = "<b>" + self.current_stage_label_done + " - " \
+ + cancel_txt + "</b>"
+ gobject.idle_add(self.current_stage_label.set_markup, txt)
+ gobject.idle_add(self.current_stage_icon.set_from_stock,
+ gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
+ gobject.idle_add(self.w_stages_label.set_markup, cancel_txt)
+ self.w_cancel_button.set_sensitive(False)
+ if self.top_level:
+ gobject.idle_add(self.parent.install_terminated)
+ if self.operations_done or self.operations_done_ex:
+ self.w_dialog.hide()
+ if self.web_install:
+ if self.operations_done_ex == False and \
+ not self.web_install_all_installed:
+ gobject.idle_add(self.parent.update_package_list,
+ None)
+ else:
+ gobject.idle_add(self.parent.update_package_list,
+ self.web_updates_list)
+ return
+ if self.top_level:
+ gobject.idle_add(self.parent.install_terminated)
+ gobject.idle_add(self.parent.update_package_list, None)
+
+ def __on_closecreateplan_clicked(self, widget):
+ self.w_close_button.hide()
+ self.w_dialog.hide()
+ buf = self.w_details_textview.get_buffer()
+ buf.set_text("")
+ self.w_expander.set_expanded(False)
+ self.__start_action()
+ self.retry = False
+ return
+
+ def __on_help_button_clicked(self, widget):
+ if self.top_level:
+ gui_misc.display_help("using_um")
+ elif self.action == enumerations.INSTALL_UPDATE:
+ gui_misc.display_help("install-pkg")
+ elif self.action == enumerations.REMOVE:
+ gui_misc.display_help("remove-pkg")
+ else:
+ gui_misc.display_help("update-pkg")
+
+ def __ipkg_ipkgui_uptodate(self):
+ if self.ipkg_ipkgui_list == None:
+ return True
+ for pd in self.api_o.gen_plan_install(self.ipkg_ipkgui_list):
+ continue
+ upgrade_needed = not self.api_o.planned_nothingtodo(
+ li_ignore_all=True)
+ return not upgrade_needed
+
+ def __proceed_with_stages(self, continue_operation = False):
+ if continue_operation == False:
+ self.__start_stage_one()
+ self.w_expander.set_expanded(self.gconf.details_expanded)
+ self.w_dialog.show()
+ Thread(target = self.__proceed_with_stages_thread_ex,
+ args = (continue_operation, )).start()
+
+ def __proceed_with_stages_thread_ex(self, continue_operation = False):
+ if self.api_lock:
+ self.api_lock.acquire()
+ self.__proceed_with_stages_thread_ex_with_lock(continue_operation)
+ gui_misc.release_lock(self.api_lock)
+
+ def __proceed_with_stages_thread_ex_with_lock(self, continue_operation = False):
+ try:
+ try:
+ if self.action == enumerations.IMAGE_UPDATE and \
+ continue_operation == False:
+ self.__start_substage(
+ _("Ensuring %s is up to date...") %
+ self.parent_name,
+ bounce_progress=True)
+ solaris_image = True
+ ips_uptodate = True
+ notfound = self.__installed_fmris_from_args(
+ [gui_misc.package_name["SUNWipkg"],
+ gui_misc.package_name["SUNWcs"]])
+ if notfound:
+ solaris_image = False
+ if solaris_image:
+ ips_uptodate = \
+ self.__ipkg_ipkgui_uptodate()
+ if not ips_uptodate:
+ #Do the stuff with installing pkg pkg-gui
+ #and restart in the special mode
+ self.ips_update = True
+ self.__proceed_with_ipkg_thread()
+ return
+ else:
+ gobject.idle_add(
+ self.__create_uarenamebe_o)
+ self.api_o.reset()
+ if continue_operation == False:
+ self.__proceed_with_stages_thread()
+ else:
+ self.__continue_with_stages_thread()
+ except (MemoryError, EnvironmentError), __e:
+ if isinstance(__e, EnvironmentError) and \
+ __e.errno != errno.ENOMEM:
+ raise
+ msg = misc.out_of_memory()
+ self.__g_error_stage(msg)
+ return
+ except RuntimeError, ex:
+ msg = str(ex)
+ if msg == "cannot release un-aquired lock":
+ logger.error(msg)
+ else:
+ self.__g_error_stage(msg)
+ return
+ except api_errors.InventoryException, e:
+ msg = _("Inventory exception:\n")
+ if e.illegal:
+ for i in e.illegal:
+ msg += "\tpkg:\t" + i +"\n"
+ else:
+ msg = "%s" % e
+ self.__g_error_stage(msg)
+ return
+ except api_errors.CatalogRefreshException, e:
+ res = gui_misc.get_catalogrefresh_exception_msg(e)
+ self.__g_error_stage(res[0])
+ return
+ except api_errors.TransportError, ex:
+ msg = _("Please check the network "
+ "connection.\nIs the repository accessible?\n\n"
+ "%s") % str(ex)
+ self.__g_error_stage(msg)
+ return
+ except api_errors.InvalidDepotResponseException, e:
+ msg = _("\nUnable to contact a valid package depot. "
+ "Please check your network settings and "
+ "attempt to contact the server using a web "
+ "browser.\n\n%s") % str(e)
+ self.__g_error_stage(msg)
+ return
+ except api_errors.IpkgOutOfDateException:
+ msg = _("pkg(5) appears to be out of "
+ "date and should be updated.\n"
+ "Please update %s package") % (
+ gui_misc.package_name["SUNWipkg"])
+ self.__g_error_stage(msg)
+ return
+ except api_errors.NonLeafPackageException, nlpe:
+ msg = _("Cannot remove:\n\t%s\n"
+ "Due to the following packages that "
+ "depend on it:\n") % nlpe.fmri.get_name()
+ for pkg_a in nlpe.dependents:
+ msg += "\t" + pkg_a.get_name() + "\n"
+
+ stem = nlpe.fmri.get_pkg_stem()
+ self.list_of_packages.remove(stem)
+ if self.confirmation_list:
+ for item in self.confirmation_list:
+ if item[enumerations.CONFIRM_STEM] == stem:
+ self.confirmation_list.remove(item)
+ break
+ if len(self.list_of_packages) > 0:
+ if self.w_close_button.get_use_stock():
+ label = gui_misc.get_stockbutton_label_label(
+ self.w_close_button)
+ else:
+ label = self.w_close_button.get_label()
+ label = label.replace("_", "")
+ msg += "\n"
+ msg += _("Press %(button)s "
+ "button to continue removal without"
+ "\n\t%(package)s\n") % \
+ {"button": label,
+ "package": nlpe.fmri.get_name()}
+ self.retry = True
+ self.w_close_button.show()
+ self.__g_error_stage(msg)
+ return
+ except api_errors.ProblematicPermissionsIndexException, err:
+ msg = str(err)
+ msg += _("\nFailure to consistently execute pkg "
+ "commands when running %s as a privileged user is "
+ "often a source of this problem.") % self.parent_name
+ msg += _("\nTo rebuild index, please execute the "
+ "following command as a privileged user:")
+ msg += _("\n\tpkg rebuild-index")
+ self.__g_error_stage(msg)
+ return
+ except api_errors.CorruptedIndexException:
+ msg = _("There was an error during installation. The search "
+ "index is corrupted. You might want try to fix this "
+ "problem by executing the following command as a "
+ "privileged user:\n"
+ "\tpkg rebuild-index")
+ self.__g_error_stage(msg)
+ return
+ except api_errors.ImageUpdateOnLiveImageException:
+ msg = _("This is a Live Image. The install "
+ "operation can't be performed.")
+ self.__g_error_stage(msg)
+ return
+ except api_errors.RebootNeededOnLiveImageException:
+ msg = _("The requested operation would affect files that cannot "
+ "be modified in the Live Image.\n"
+ "Please retry this operation on an alternate boot environment.")
+ self.__g_error_stage(msg)
+ return
+ except api_errors.PlanMissingException:
+ msg = _("There was an error during installation.\n"
+ "The Plan of the operation is missing and the operation "
+ "can't be finished. You might want try to fix this "
+ "problem by restarting %s\n") % self.parent_name
+ self.__g_error_stage(msg)
+ return
+ except api_errors.ImageplanStateException:
+ msg = _("There was an error during installation.\n"
+ "The State of the image is incorrect and the operation "
+ "can't be finished. You might want try to fix this "
+ "problem by restarting %s\n") % self.parent_name
+ self.__g_error_stage(msg)
+ return
+ except api_errors.CanceledException:
+ gobject.idle_add(self.__do_cancel)
+ self.stop_bouncing_progress()
+ return
+ except api_errors.BENamingNotSupported:
+ msg = _("Specifying BE Name not supported.\n")
+ self.__g_error_stage(msg)
+ return
+ except api_errors.ApiException, ex:
+ msg = str(ex)
+ self.__g_error_stage(msg)
+ return
+ # We do want to prompt user to load BE admin if there is
+ # not enough disk space. This error can either come as an
+ # error within API exception, see bug #7642 or as a standalone
+ # error, that is why we need to check for both situations.
+ except EnvironmentError, uex:
+ if uex.errno in (errno.EDQUOT, errno.ENOSPC):
+ self.__handle_nospace_error()
+ else:
+ self.__handle_error()
+ return
+ except api_errors.HistoryStoreException, uex:
+ if (isinstance(uex.error, EnvironmentError) and
+ uex.error.errno in (errno.EDQUOT, errno.ENOSPC)):
+ self.__handle_nospace_error()
+ else:
+ self.__handle_error()
+ return
+ except Exception:
+ self.__handle_error()
+ return
+
+ def __reset_window_title(self):
+ if self.reset_window_id:
+ gobject.source_remove(self.reset_window_id)
+ self.reset_window_id = 0
+ if self.w_main_window:
+ self.w_main_window.set_title(self.original_title)
+
+ def __do_cancel(self):
+ self.__do_dialog_hide()
+
+ def __do_dialog_hide(self):
+ self.w_dialog.hide()
+ self.__reset_window_title()
+
+ def __create_uarenamebe_o(self):
+ if self.uarenamebe_o == None:
+ self.uarenamebe_o = \
+ uarenamebe.RenameBeAfterUpdateAll(
+ self.parent, self.icon_confirm_dialog,
+ self.w_main_window)
+
+ def __handle_nospace_error(self):
+ gobject.idle_add(self.__prompt_to_load_beadm)
+ gobject.idle_add(self.__do_dialog_hide)
+ self.stop_bouncing_progress()
+
+ def __handle_error(self):
+ traceback_lines = traceback.format_exc().splitlines()
+ traceback_str = ""
+ for line in traceback_lines:
+ traceback_str += line + "\n"
+ self.__g_exception_stage(traceback_str)
+ sys.exc_clear()
+
+ def __proceed_with_ipkg_thread(self):
+ self.__start_substage(_("Updating %s") % self.parent_name,
+ bounce_progress=True)
+ self.__afterplan_information()
+ self.prev_pkg = None
+ self.__start_substage(_("Downloading..."), bounce_progress=False)
+ self.api_o.prepare()
+ self.__start_substage(_("Executing..."), bounce_progress=False)
+ gobject.idle_add(self.w_cancel_button.set_sensitive, False)
+ try:
+ self.api_o.execute_plan()
+ except api_errors.WrapSuccessfulIndexingException:
+ pass
+ except api_errors.WrapIndexingException, wex:
+ err = _("\n\nDespite the error while indexing, the "
+ "image-update, install, or uninstall has completed "
+ "successfuly.")
+ err = err.replace("\n\n", "")
+ err += "\n" + str(wex)
+ logger.error(err)
+
+ gobject.idle_add(self.__operations_done)
+
+ def __proceed_with_stages_thread(self):
+ self.__start_substage(None)
+ self.label_text = _("Gathering package information, please wait...")
+ self.update_label_text(self.label_text)
+ self.update_details_text(
+ _("Gathering package information") + "\n", "level1")
+
+ stuff_todo = self.__plan_stage()
+ if stuff_todo:
+
+ if (self.action == enumerations.IMAGE_UPDATE and
+ self.show_confirmation):
+ gobject.idle_add(self.__show_image_update_confirmation)
+ else:
+ self.__continue_with_stages_thread()
+ else:
+ if self.web_install:
+ gobject.idle_add(self.__operations_done,
+ _("All packages already installed."))
+ return
+
+ if self.action == enumerations.INSTALL_UPDATE:
+ done_text = _("No updates necessary")
+ elif self.action == enumerations.IMAGE_UPDATE:
+ done_text = _("No updates available")
+ elif self.action == enumerations.UPDATE_FACETS:
+ done_text = _("All features already installed")
+ gobject.idle_add(self.__operations_done, done_text)
+
+ def __show_image_update_confirmation(self):
+ dic_to_update = {}
+ dic_to_install = {}
+ dic_to_remove = {}
+ to_update = gtk.ListStore(str, str, str)
+ to_install = gtk.ListStore(str, str, str)
+ to_remove = gtk.ListStore(str, str, str)
+
+
+ plan_desc = self.api_o.describe()
+ if plan_desc == None:
+ return
+ plan = plan_desc.get_changes()
+
+ for pkg_plan in plan:
+ orig = pkg_plan[0]
+ dest = pkg_plan[1]
+ if orig and dest:
+ dic_to_update[dest.pkg_stem] = [dest.publisher, None]
+ elif not orig and dest:
+ dic_to_install[dest.pkg_stem] = [dest.publisher, None]
+ elif orig and not dest:
+ dic_to_remove[orig.pkg_stem] = [orig.publisher, None]
+
+ self.__update_summaries(dic_to_update, dic_to_install, dic_to_remove)
+
+ self.__dic_to_liststore(dic_to_update, to_update)
+ self.__dic_to_liststore(dic_to_install, to_install)
+ self.__dic_to_liststore(dic_to_remove, to_remove)
+
+ len_to_update = len(to_update)
+ len_to_install = len(to_install)
+ len_to_remove = len(to_remove)
+
+ if len_to_update == 0 and len_to_install == 0 and len_to_remove == 0:
+ # Never show an empty confirmation dialog just proceed
+ self.__on_confirm_ok_button_clicked(None)
+ return
+
+ self.__resize_confirm_frames(len_to_update,
+ len_to_install, len_to_remove)
+
+ if len_to_update > 0:
+ self.__init_confirmation_tree_view(
+ self.w_update_treeview)
+ to_update.set_default_sort_func(lambda *args: -1)
+ to_update.set_sort_column_id(0, gtk.SORT_ASCENDING)
+ self.w_update_treeview.set_model(to_update)
+ self.w_update_expander.set_expanded(True)
+ else:
+ self.w_update_expander.hide()
+
+ if len_to_install > 0:
+ self.__init_confirmation_tree_view(
+ self.w_install_treeview)
+ to_install.set_default_sort_func(lambda *args: -1)
+ to_install.set_sort_column_id(0, gtk.SORT_ASCENDING)
+ self.w_install_treeview.set_model(to_install)
+ self.w_install_expander.set_expanded(True)
+ else:
+ self.w_install_expander.hide()
+
+ if len_to_remove > 0:
+ self.__init_confirmation_tree_view(
+ self.w_remove_treeview)
+ to_remove.set_default_sort_func(lambda *args: -1)
+ to_remove.set_sort_column_id(0, gtk.SORT_ASCENDING)
+ self.w_remove_treeview.set_model(to_remove)
+ self.w_remove_expander.set_expanded(True)
+ else:
+ self.w_remove_expander.hide()
+
+ no_pkgs = len(to_update) + len(to_install) + len(to_remove)
+ operation_txt = _("Updates Confirmation")
+ install_text = ngettext(
+ "Review the package which will be affected by Updates",
+ "Review the packages which will be affected by Updates", no_pkgs)
+
+ self.w_confirm_dialog.set_title(operation_txt)
+ self.w_confirm_label.set_markup("<b>"+install_text+"</b>")
+
+ self.w_confirm_ok_button.grab_focus()
+ self.__start_substage(None,
+ bounce_progress=False)
+ if self.top_level:
+ self.__reset_window_title()
+ else:
+ self.w_dialog.hide()
+ self.w_confirm_dialog.show()
+
+
+ def __resize_confirm_frames(self, len_to_update, len_to_install, len_to_remove):
+ calculated_height = DEFAULT_CONFIRMATION_HEIGHT
+
+ if len_to_update > 0 and len_to_remove > 0 and len_to_install > 0:
+ calculated_height = (calculated_height/4)*2
+ elif (len_to_update > 0 and len_to_remove > 0) or (len_to_update > 0 and
+ len_to_install > 0) or (len_to_remove > 0 and len_to_install > 0):
+ calculated_height = (calculated_height/3)*2
+
+ self.w_install_frame.set_size_request(DEFAULT_CONFIRMATION_WIDTH,
+ calculated_height)
+ self.w_update_frame.set_size_request(DEFAULT_CONFIRMATION_WIDTH,
+ calculated_height)
+ self.w_remove_frame.set_size_request(DEFAULT_CONFIRMATION_WIDTH,
+ calculated_height)
+
+ @staticmethod
+ def __dic_to_liststore(dic, liststore):
+ for entry in dic:
+ liststore.append([entry, dic[entry][0], dic[entry][1]])
+
+ def __handle_licenses(self):
+ self.packages_with_license = \
+ self.__get_packages_for_license_check()
+ self.n_licenses = len(self.packages_with_license)
+ if self.n_licenses > 0:
+ gobject.idle_add(self.__do_ask_license)
+ self.license_cv.acquire()
+ while not self.accept_license_done:
+ self.license_cv.wait()
+ gui_misc.release_lock(self.license_cv)
+ self.__do_accept_licenses()
+ return
+
+ def __continue_with_stages_thread(self):
+ self.__afterplan_information()
+ self.prev_pkg = None
+ self.__handle_licenses()
+
+ # The api.prepare() mostly is downloading the files so we are
+ # Not showing this stage in the main stage dialog. If download
+ # is necessary, then we are showing it in the details view
+ if not self.action == enumerations.REMOVE:
+ self.__start_stage_two()
+ self.__start_substage(None,
+ bounce_progress=False)
+ try:
+ self.api_o.prepare()
+ except api_errors.PlanLicenseErrors:
+ gobject.idle_add(self.__do_dialog_hide)
+ if self.top_level:
+ gobject.idle_add(self.parent.install_terminated)
+ self.stop_bouncing_progress()
+ return
+ self.__start_stage_three()
+ self.__start_substage(None,
+ bounce_progress=False)
+ gobject.idle_add(self.w_cancel_button.set_sensitive, False)
+ try:
+ self.api_o.execute_plan()
+ except api_errors.WrapSuccessfulIndexingException:
+ pass
+ except api_errors.WrapIndexingException, wex:
+ err = _("\n\nDespite the error while indexing, the "
+ "image-update, install, or uninstall has completed "
+ "successfuly.")
+ err = err.replace("\n\n", "")
+ err += "\n" + str(wex)
+ logger.error(err)
+
+ gobject.idle_add(self.__operations_done)
+
+ def __start_stage_one(self):
+ self.__start_stage(self.stages.get(1), self.w_stage1_label,
+ self.w_stage1_icon)
+ self.update_details_text(self.stages.get(1)[0]+"\n", "bold")
+
+ def __start_stage_two(self):
+ # End previous stage
+ self.__end_stage()
+ self.__start_stage(self.stages.get(2), self.w_stage2_label,
+ self.w_stage2_icon)
+ self.update_details_text(self.stages.get(2)[0]+"\n", "bold")
+
+ def __start_stage_three(self):
+ self.__end_stage()
+ self.__start_stage(self.stages.get(3), self.w_stage3_label,
+ self.w_stage3_icon)
+ self.update_details_text(self.stages.get(3)[0]+"\n", "bold")
+
+ def __do_start_stage(self, stage_text, current_stage_label, current_stage_icon):
+ self.current_stage_label = current_stage_label
+ self.current_stage_icon = current_stage_icon
+ self.current_stage_label_done = stage_text[1]
+ if self.w_main_window:
+ new_title = stage_text[0]
+ self.w_main_window.set_title(new_title)
+ self.current_stage_label.set_markup("<b>"+stage_text[0]+"</b>")
+ self.current_stage_icon.set_from_stock(gtk.STOCK_GO_FORWARD,
+ gtk.ICON_SIZE_MENU)
+
+ def __start_stage(self, stage_text, current_stage_label, current_stage_icon):
+ gobject.idle_add(self.__do_start_stage, stage_text, current_stage_label,
+ current_stage_icon)
+
+ def __do_end_stage(self):
+ self.current_stage_label.set_text(self.current_stage_label_done)
+ self.current_stage_icon.set_from_pixbuf(self.done_icon)
+ self.__reset_window_title()
+
+ def __end_stage(self):
+ gobject.idle_add(self.__do_end_stage)
+
+ def __g_error_stage(self, msg):
+ if msg == None or len(msg) == 0:
+ msg = _("No futher information available")
+ self.operations_done = True
+ self.operations_done_ex = True
+ self.stop_bouncing_progress()
+ self.update_details_text(_("\nError:\n"), "bold")
+ self.update_details_text("%s" % msg, "level1")
+ self.update_details_text("\n")
+ txt = "<b>" + self.current_stage_label_done + _(" - Failed </b>")
+ gobject.idle_add(self.__g_error_stage_setup, txt)
+ gobject.idle_add(self.w_dialog.queue_draw)
+
+ def __g_error_stage_setup(self, txt):
+ self.__reset_window_title()
+ if self.action == enumerations.IMAGE_UPDATE:
+ info_url = misc.get_release_notes_url()
+ if info_url and len(info_url) == 0:
+ info_url = gui_misc.RELEASE_URL
+ self.w_release_notes.show()
+ self.w_release_notes_link.set_uri(info_url)
+ self.dlg_expanded_details_h += DIALOG_RELEASE_NOTE_OFFSET * 2
+ self.dlg_install_collapsed_h += DIALOG_RELEASE_NOTE_OFFSET
+ self.dlg_remove_collapsed_h += DIALOG_RELEASE_NOTE_OFFSET
+
+ self.current_stage_label.set_markup(txt)
+ self.current_stage_icon.set_from_stock(gtk.STOCK_DIALOG_ERROR,
+ gtk.ICON_SIZE_MENU)
+ self.w_expander.set_expanded(True)
+ self.w_cancel_button.set_sensitive(True)
+ self.__set_dialog_size(self.dlg_width, self.dlg_expanded_details_h)
+
+ def __g_exception_stage(self, tracebk):
+ self.__reset_window_title()
+ self.operations_done = True
+ self.operations_done_ex = True
+ self.stop_bouncing_progress()
+ if self.action == enumerations.IMAGE_UPDATE:
+ info_url = misc.get_release_notes_url()
+ if info_url and len(info_url) == 0:
+ info_url = gui_misc.RELEASE_URL
+ self.w_release_notes.show()
+ self.w_release_notes_link.set_uri(info_url)
+ txt = "<b>" + self.current_stage_label_done + _(" - Failed </b>")
+ gobject.idle_add(self.current_stage_label.set_markup, txt)
+ gobject.idle_add(self.current_stage_icon.set_from_stock,
+ gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_MENU)
+ msg_1 = _("An unknown error occurred in the %s stage.\n"
+ "Please let the developers know about this problem by "
+ "filing a bug together with the error details listed below at:\n"
+ ) % self.current_stage_name
+ msg_2 = "%s\n\n" % misc.BUG_URI_GUI
+ self.update_details_text(_("\nError:\n"), "bold")
+ self.update_details_text("%s" % msg_1, "level1")
+ self.update_details_text("%s" % msg_2, "bold", "level2")
+ if tracebk:
+ msg = _("Exception traceback:\n")
+ self.update_details_text("%s" % msg,
+ "bold","level1")
+ self.update_details_text("%s\n" % tracebk, "level2")
+ else:
+ msg = _("No futher information available")
+ self.update_details_text("%s\n" % msg, "level2")
+ msg_3 = _("pkg version: ")
+ self.update_details_text("%s" % msg_3,
+ "bold","level1")
+ self.update_details_text("%s\n\n" % gui_misc.get_version(), "level2")
+ publisher_header = _("List of configured publishers:")
+ self.update_details_text("%s" % publisher_header,
+ "bold","level1")
+ publisher_str = gui_misc.get_publishers_for_output(self.api_o)
+ self.update_details_text("%s\n" % publisher_str,
+ "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:
+ self.update_label_text(text)
+ self.update_details_text(text + "\n", "level1")
+ if bounce_progress:
+ if self.stopped_bouncing_progress:
+ self.start_bouncing_progress()
+ else:
+ self.stop_bouncing_progress()
+
+ def update_label_text(self, markup_text):
+ gobject.idle_add(self.__stages_label_set_markup, markup_text)
+
+ def __stages_label_set_markup(self, markup_text):
+ if not self.canceling == True:
+ self.w_stages_label.set_markup(markup_text)
+
+ def start_bouncing_progress(self):
+ self.stop_progress_bouncing = False
+ self.stopped_bouncing_progress = False
+ Thread(target =
+ self.__g_progressdialog_progress_pulse).start()
+
+ def __g_progressdialog_progress_pulse(self):
+ while not self.stop_progress_bouncing:
+ gobject.idle_add(self.w_progressbar.pulse)
+ time.sleep(0.1)
+ self.stopped_bouncing_progress = True
+ gobject.idle_add(self.w_progressbar.set_fraction, 0.0)
+
+ def is_progress_bouncing(self):
+ return not self.stopped_bouncing_progress
+
+ def stop_bouncing_progress(self):
+ if self.is_progress_bouncing():
+ self.stop_progress_bouncing = True
+
+ def update_details_text(self, text, *tags):
+ gobject.idle_add(self.__update_details_text, text, *tags)
+
+ def __update_details_text(self, text, *tags):
+ buf = self.w_details_textview.get_buffer()
+ textiter = buf.get_end_iter()
+ if tags:
+ buf.insert_with_tags_by_name(textiter, text, *tags)
+ else:
+ buf.insert(textiter, text)
+ insert_mark = buf.get_insert()
+ self.w_details_textview.scroll_to_mark(insert_mark, 0.0)
+
+ def __update_window_title(self, display_string):
+ self.w_main_window.set_title(display_string)
+
+ def display_download_info(self):
+ self.update_progress(self.dl_cur_nbytes, self.dl_goal_nbytes)
+ if self.w_main_window:
+ progtimes100 = int(self.prog * 100)
+ if progtimes100 != self.prev_prog:
+ self.prev_prog = progtimes100
+ display_string = "%d%% - %s" % (progtimes100,
+ self.stages[2][0])
+ gobject.idle_add(self.__update_window_title,
+ display_string)
+ self.__display_download()
+
+ def __display_download(self):
+ if self.display_download_id == 0:
+ self.display_download_id = gobject.timeout_add(DISPLAY_DELAY,
+ self.__display_download_text)
+
+ def __display_download_text(self):
+ self.display_download_id = 0
+ size_a_str = ""
+ size_b_str = ""
+ if self.dl_cur_nbytes >= 0:
+ size_a_str = misc.bytes_to_str(self.dl_cur_nbytes)
+ if self.dl_goal_nbytes >= 0:
+ size_b_str = misc.bytes_to_str(self.dl_goal_nbytes)
+ c = _("Downloaded %(current)s of %(total)s") % \
+ {"current" : size_a_str,
+ "total" : size_b_str}
+ self.__stages_label_set_markup(c)
+
+ def display_phase_info(self, phase_name, cur_n, goal_n):
+ self.update_progress(cur_n, goal_n)
+ if self.reset_window_id != 0:
+ gobject.source_remove(self.reset_window_id)
+ self.reset_window_id = 0
+ if self.w_main_window:
+ progtimes100 = int(self.prog * 100)
+ if progtimes100 != self.prev_prog:
+ self.prev_prog = progtimes100
+ display_string = _("%(cur)d of %(goal)d - %(name)s") % \
+ {"cur": cur_n, "goal": goal_n, \
+ "name": phase_name}
+ gobject.idle_add(self.__update_window_title,
+ display_string)
+ self.reset_window_id = gobject.timeout_add(
+ RESET_PACKAGE_DELAY,
+ self.__do_reset_window_text, phase_name)
+
+ def __do_reset_window_text(self, phase_name):
+ self.reset_window_id = 0
+ self.__update_window_title(phase_name)
+
+ def reset_label_text_after_delay(self):
+ if self.reset_id != 0:
+ gobject.source_remove(self.reset_id)
+ self.reset_id = gobject.timeout_add(RESET_PACKAGE_DELAY,
+ self.__do_reset_label_text)
+
+ def __do_reset_label_text(self):
+ self.reset_id = 0
+ if self.label_text:
+ self.__stages_label_set_markup(self.label_text)
+
+ def __update_progress(self):
+ self.update_progress_id = 0
+ self.w_progressbar.set_fraction(self.prog)
+
+ def update_progress(self, current, total):
+ self.prog = float(current)/total
+ if self.update_progress_id == 0:
+ self.update_progress_id = gobject.timeout_add(DISPLAY_DELAY,
+ self.__update_progress)
+
+ def __plan_stage(self):
+ '''Function which plans the image'''
+ if self.action == enumerations.INSTALL_UPDATE:
+ for pd in self.api_o.gen_plan_install(
+ self.list_of_packages, refresh_catalogs=False):
+ continue
+ elif self.action == enumerations.REMOVE:
+ for pd in self.api_o.gen_plan_uninstall(
+ self.list_of_packages, noexecute=False):
+ continue
+ elif self.action == enumerations.IMAGE_UPDATE:
+ # we are passing force, since we already checked if the
+ # packages are up to date. Create BE if required
+ for pd in self.api_o.gen_plan_update(
+ refresh_catalogs=False, noexecute=False,
+ force=True, be_name=None, new_be=None):
+ continue
+ self.pylint_stub = self.api_o.solaris_image()
+ else:
+ assert self.action == enumerations.UPDATE_FACETS
+ for pd in self.api_o.gen_plan_change_varcets(
+ variants=None, facets=self.facets,
+ noexecute=False, be_name=None, new_be=None):
+ continue
+ return not self.api_o.planned_nothingtodo(li_ignore_all=True)
+
+ def __operations_done(self, alternate_done_txt = None):
+ self.__reset_window_title()
+ self.label_text = 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")
+ elif self.action == enumerations.UPDATE_FACETS:
+ done_txt = _("Optional components updated successfully")
+ if alternate_done_txt != None:
+ done_txt = alternate_done_txt
+ self.w_stages_box.hide()
+ self.w_stages_icon.show()
+ self.__stages_label_set_markup("<b>" + done_txt + "</b>")
+ self.__update_details_text("\n"+ done_txt, "bold")
+ self.w_cancel_button.set_sensitive(True)
+ self.w_cancel_button.set_label("gtk-close")
+ self.w_cancel_button.grab_focus()
+ self.w_progressbar.hide()
+ self.stop_bouncing_progress()
+ self.operations_done = True
+ if not self.gconf.details_expanded:
+ self.__set_dialog_size(self.dlg_width, self.dlg_done_collapsed_h)
+ if self.parent != None:
+ if not self.web_install and not self.ips_update \
+ and not self.action == enumerations.IMAGE_UPDATE \
+ and not self.action == enumerations.UPDATE_FACETS:
+ self.parent.update_package_list(self.update_list)
+ if self.web_install:
+ if done_txt == \
+ _("All packages already installed.") or \
+ done_txt == \
+ _("Installation completed successfully"):
+ self.web_install_all_installed = True
+ else:
+ self.web_install_all_installed = False
+ self.web_updates_list = self.update_list
+ if self.ips_update:
+ self.w_dialog.hide()
+ self.parent.restart_after_ips_update()
+ elif self.action == enumerations.IMAGE_UPDATE or \
+ self.action == enumerations.UPDATE_FACETS:
+ if self.uarenamebe_o:
+ be_rename_dialog = \
+ self.uarenamebe_o.show_rename_dialog(
+ self.update_list)
+ if be_rename_dialog == True and not self.top_level:
+ self.w_dialog.hide()
+
+ def __prompt_to_load_beadm(self):
+ msgbox = gtk.MessageDialog(parent = self.w_main_window,
+ buttons = gtk.BUTTONS_OK_CANCEL, flags = gtk.DIALOG_MODAL,
+ type = gtk.MESSAGE_ERROR,
+ message_format = _(
+ "Not enough disk space, the selected action cannot "
+ "be performed.\n\n"
+ "Click OK to manage your existing BEs and free up disk space or "
+ "Cancel to cancel the action."))
+ msgbox.set_title(_("Not Enough Disk Space"))
+ result = msgbox.run()
+ msgbox.destroy()
+ if result == gtk.RESPONSE_OK:
+ beadm.Beadmin(self.parent)
+
+ def __afterplan_information(self):
+ install_iter = None
+ update_iter = None
+ remove_iter = None
+ plan_desc = self.api_o.describe()
+ if plan_desc == None:
+ return
+ self.reboot_needed = plan_desc.reboot_needed
+ plan = plan_desc.get_changes()
+ self.update_details_text("\n")
+ for pkg_plan in plan:
+ origin_fmri = pkg_plan[0]
+ destination_fmri = pkg_plan[1]
+ if origin_fmri and destination_fmri:
+ if not update_iter:
+ update_iter = True
+ txt = _("Packages To Be Updated:\n")
+ self.update_details_text(txt, "bold")
+ pkg_a = self.__get_pkgstr_from_pkginfo(destination_fmri)
+ self.update_details_text(pkg_a+"\n", "level1")
+ elif not origin_fmri and destination_fmri:
+ if not install_iter:
+ install_iter = True
+ txt = _("Packages To Be Installed:\n")
+ self.update_details_text(txt, "bold")
+ pkg_a = self.__get_pkgstr_from_pkginfo(destination_fmri)
+ self.update_details_text(pkg_a+"\n", "level1")
+ elif origin_fmri and not destination_fmri:
+ if not remove_iter:
+ remove_iter = True
+ txt = _("Packages To Be Removed:\n")
+ self.update_details_text(txt, "bold")
+ pkg_a = self.__get_pkgstr_from_pkginfo(origin_fmri)
+ self.update_details_text(pkg_a+"\n", "level1")
+
+ v = plan_desc.get_varcets()
+ if v == None or len(v) == 0:
+ self.update_details_text("\n")
+ return
+ txt = _("Optional components\n")
+ self.update_details_text(txt, "bold")
+ txt = _("Number of facets set: %s\n" % (len(v)))
+ self.update_details_text(txt, "level1")
+ for x in v:
+ self.update_details_text("%s\n" % x, "level1")
+ self.update_details_text("\n")
+
+ def __get_pkgstr_from_pkginfo(self, pkginfo):
+ dt_str = self.get_datetime(pkginfo.packaging_date)
+ if not dt_str:
+ dt_str = ""
+ s_ver = pkginfo.version
+ s_bran = pkginfo.branch
+ pkg_name = pkginfo.pkg_stem
+ 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:
+ version_pref += "%d%s" % (s_ver[l_ver],".")
+ l_ver += 1
+ version_pref += "%d%s" % (s_ver[l_ver],"-")
+ l_ver = 0
+ version_suf = ""
+ if s_bran != None:
+ while l_ver < len(s_bran) -1:
+ version_suf += "%d%s" % (s_bran[l_ver],".")
+ l_ver += 1
+ version_suf += "%d" % s_bran[l_ver]
+ pkg_version = version_pref + version_suf + dt_str
+ return pkg_name + "@" + pkg_version
+
+ def __update_summaries(self, to_update, to_install, to_remove):
+ pkgs_table = to_update.keys() + to_install.keys()
+ info = None
+ try:
+ info = self.api_o.info(pkgs_table, False,
+ frozenset([api.PackageInfo.SUMMARY,
+ api.PackageInfo.IDENTITY]))
+ info_r = self.api_o.info(to_remove.keys(), True,
+ frozenset([api.PackageInfo.SUMMARY,
+ api.PackageInfo.IDENTITY]))
+ for info_s in (info.get(0) + info_r.get(0)):
+ stem = info_s.pkg_stem
+ if stem in to_update:
+ to_update[stem][1] = info_s.summary
+ elif stem in to_install:
+ to_install[stem][1] = info_s.summary
+ elif stem in to_remove:
+ to_remove[stem][1] = info_s.summary
+ except api_errors.ApiException, ex:
+ err = str(ex)
+ logger.error(err)
+ gui_misc.notify_log_error(self.parent)
+
+ @staticmethod
+ def get_datetime(date_time):
+ '''Support function for getting date from the API.'''
+ date_tmp = None
+ try:
+ date_tmp = time.strptime(date_time, "%a %b %d %H:%M:%S %Y")
+ except ValueError:
+ return None
+ if date_tmp:
+ date_tmp2 = datetime.datetime(*date_tmp[0:5])
+ return date_tmp2.strftime(":%m%d")
+ return None
+
+ def __installed_fmris_from_args(self, args_f):
+ not_found = False
+ try:
+ res = self.api_o.info(args_f, True,
+ frozenset([api.PackageInfo.STATE]))
+ if not res or len(res[0]) != len(args_f):
+ not_found = True
+ except api_errors.ApiException:
+ not_found = True
+ return not_found
+
+ def __do_ask_license(self):
+ item = self.packages_with_license[self.current_license_no]
+ pfmri = item[0]
+ dest = item[2]
+ pkg_name = pfmri.get_name()
+ lic = dest.get_text()
+ if dest.must_accept:
+ gui_misc.change_stockbutton_label(self.w_license_accept_button,
+ _("A_ccept"))
+ self.w_license_label.set_text(
+ _("You must accept the terms of the license before "
+ "downloading this package."))
+ self.w_license_accept_checkbutton.show()
+ self.w_license_reject_button.show()
+ self.w_license_accept_checkbutton.grab_focus()
+ self.w_license_accept_checkbutton.set_active(False)
+ self.w_license_accept_button.set_sensitive(False)
+ else:
+ if self.accept_text != None:
+ gui_misc.change_stockbutton_label(
+ self.w_license_accept_button,
+ self.accept_text)
+ self.w_license_label.set_text(
+ _("You must view the terms of the license before "
+ "downloading this package."))
+ self.w_license_accept_checkbutton.hide()
+ self.w_license_reject_button.hide()
+ self.w_license_accept_button.set_sensitive(True)
+ self.w_license_accept_button.grab_focus()
+ lic_buffer = self.w_license_text.get_buffer()
+ lic_buffer.set_text(lic)
+ title = _("%s License") % pkg_name
+ self.w_license_dialog.set_title(title)
+ self.w_license_dialog.show()
+ return
+
+ def __do_accept_licenses(self):
+ for item, accepted_value in self.packages_with_license_result:
+ pfmri = item[0]
+ dest = item[2]
+ lic = dest.license
+ self.api_o.set_plan_license_status(pfmri, lic,
+ displayed=True, accepted=accepted_value)
+
+ def __get_packages_for_license_check(self):
+ pkg_list = []
+ plan = self.api_o.describe()
+ for item in plan.get_licenses():
+ dest = item[2]
+ if dest.must_display or dest.must_accept:
+ pkg_list.append(item)
+ return pkg_list
+
+ def __on_license_reject_button_clicked(self, widget):
+ self.packages_with_license_result.append(
+ (self.packages_with_license[self.current_license_no],
+ False))
+ self.w_license_dialog.hide()
+ self.license_cv.acquire()
+ self.accept_license_done = True
+ self.license_cv.notify()
+ gui_misc.release_lock(self.license_cv)
+
+ def __on_license_accept_button_clicked(self, widget):
+ result = None
+ item = self.packages_with_license[self.current_license_no]
+ dest = item[2]
+ if dest.must_accept:
+ result = True
+ self.packages_with_license_result.append(
+ (item, result))
+ self.w_license_dialog.hide()
+ self.current_license_no += 1
+ if self.current_license_no < self.n_licenses:
+ gobject.idle_add(self.__do_ask_license)
+ else:
+ self.license_cv.acquire()
+ self.accept_license_done = True
+ self.license_cv.notify()
+ gui_misc.release_lock(self.license_cv)
+
+ def __on_license_dialog_delete(self, widget, event):
+ if self.w_license_reject_button.get_property('visible'):
+ self.__on_license_reject_button_clicked(None)
+ else:
+ self.__on_license_accept_button_clicked(None)
+ return True
+
+ def __on_license_accept_checkbutton_toggled(self, widget):
+ ret = self.w_license_accept_checkbutton.get_active()
+ self.w_license_accept_button.set_sensitive(ret)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/misc.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,1129 @@
+#!/usr/bin/python
+#
+# 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 (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+#
+
+SPECIAL_CATEGORIES = ["locale", "plugin"] # We should cut all, but last part of the
+ # new name scheme as part of fix for #7037.
+ # However we need to have an exception rule
+ # where we will cut all but three last parts.
+
+RELEASE_URL = "http://www.opensolaris.org" # Fallback url for release notes if api
+ # does not gave us one.
+
+PROP_SIGNATURE_POLICY = "signature-policy"
+PROP_SIGNATURE_REQUIRED_NAMES = "signature-required-names"
+SIG_POLICY_IGNORE = "ignore"
+SIG_POLICY_VERIFY = "verify"
+SIG_POLICY_REQUIRE_SIGNATURES = "require-signatures"
+SIG_POLICY_REQUIRE_NAMES = "require-names"
+
+import gettext
+import locale
+import os
+import sys
+import traceback
+import threading
+try:
+ import gobject
+ import gnome
+ import gtk
+ import pango
+except ImportError:
+ sys.exit(1)
+import pkg.fmri as fmri
+import pkg.misc as misc
+import pkg.client.api_errors as api_errors
+import pkg.client.api as api
+import pkg.client.publisher as publisher
+from pkg.gui.misc_non_gui import get_api_object as ngao
+from pkg.gui.misc_non_gui import setup_logging as su_logging
+from pkg.gui.misc_non_gui import shutdown_logging as sd_logging
+from pkg.gui.misc_non_gui import get_version as g_version
+from pkg.gui.misc_non_gui import get_os_version_and_build as g_os_version_and_build
+
+from pkg.gui.misc_non_gui import get_log_dir as ge_log_dir
+from pkg.gui.misc_non_gui import get_log_error_ext as ge_log_error_ext
+from pkg.gui.misc_non_gui import get_log_info_ext as ge_log_info_ext
+from pkg.gui.misc_non_gui import get_catalogrefresh_exception_msg as get_msg
+from pkg.gui.misc_non_gui import get_um_name as get_um
+from pkg.gui.misc_non_gui import get_image_path as g_image_path
+from pkg.gui.misc_non_gui import is_frameworkerror as is_frameworke
+
+from pkg.client import global_settings
+
+misc.setlocale(locale.LC_ALL, "")
+gettext.install("pkg", "/usr/share/locale")
+
+PUBCERT_COMMON_NAME = _(" Common Name (CN):")
+PUBCERT_ORGANIZATION = _(" Organization (O):")
+PUBCERT_ORGANIZATIONAL_UNIT = _(" Organizational Unit (OU):")
+
+PKG_CLIENT_NAME_PM = "packagemanager"
+PKG_CLIENT_NAME_WI = "packagemanager-webinstall"
+
+logger = global_settings.logger
+
+# Dictionary which converts old package names to current name.
+package_name = { 'SUNWcs' : 'SUNWcs',
+ 'SUNWipkg' : 'package/pkg',
+ 'SUNWipkg-gui' : 'package/pkg/package-manager',
+ 'SUNWipkg-um' : 'package/pkg/update-manager',
+ 'SUNWpython26-notify' : 'library/python-2/python-notify-26' }
+
+def set_signature_policy_names_for_textfield(widget, names):
+ txt = ""
+ if names != None and len(names) > 0:
+ txt = names[0]
+ for name in names[1:]:
+ txt += ", " + name
+ widget.set_text(txt)
+
+def fetch_signature_policy_names_from_textfield(text):
+ names = []
+ names = __split_ignore_comma_in_quotes(text)
+ names = [x.strip(' ') for x in names]
+ if len(names) == 1 and names[0] == '':
+ del names[0]
+ return names
+
+def setup_signature_policy_properties(ignore, verify, req_sigs, req_names, names, orig):
+ set_props = {}
+ if ignore != orig[SIG_POLICY_IGNORE] and ignore:
+ set_props[PROP_SIGNATURE_POLICY] = SIG_POLICY_IGNORE
+ elif verify != orig[SIG_POLICY_VERIFY] and verify:
+ set_props[PROP_SIGNATURE_POLICY] = SIG_POLICY_VERIFY
+ elif req_sigs != orig[SIG_POLICY_REQUIRE_SIGNATURES] and req_sigs:
+ set_props[PROP_SIGNATURE_POLICY] = SIG_POLICY_REQUIRE_SIGNATURES
+ elif req_names != orig[SIG_POLICY_REQUIRE_NAMES] and req_names:
+ set_props[PROP_SIGNATURE_POLICY] = SIG_POLICY_REQUIRE_NAMES
+
+ if names != orig[PROP_SIGNATURE_REQUIRED_NAMES]:
+ set_props[PROP_SIGNATURE_REQUIRED_NAMES] = names
+ return set_props
+
+def create_sig_policy_from_property(prop_sig_pol, prop_sig_req_names):
+ names = []
+ #Names with embedded commas, the default name separator, need to
+ #be quoted to be treated as a single name
+ if prop_sig_req_names:
+ for name in prop_sig_req_names:
+ if name.split(",", 1) == 2:
+ names.append("\"%s\"" % name)
+ else:
+ names.append(name)
+ sig_policy = {}
+ sig_policy[SIG_POLICY_IGNORE] = False
+ sig_policy[SIG_POLICY_VERIFY] = False
+ sig_policy[SIG_POLICY_REQUIRE_SIGNATURES] = False
+ sig_policy[SIG_POLICY_REQUIRE_NAMES] = False
+ sig_policy[PROP_SIGNATURE_REQUIRED_NAMES] = []
+
+ if prop_sig_pol == SIG_POLICY_IGNORE:
+ sig_policy[SIG_POLICY_IGNORE] = True
+ elif prop_sig_pol == SIG_POLICY_VERIFY:
+ sig_policy[SIG_POLICY_VERIFY] = True
+ elif prop_sig_pol == SIG_POLICY_REQUIRE_SIGNATURES:
+ sig_policy[SIG_POLICY_REQUIRE_SIGNATURES] = True
+ elif prop_sig_pol == SIG_POLICY_REQUIRE_NAMES:
+ sig_policy[SIG_POLICY_REQUIRE_NAMES] = True
+ sig_policy[PROP_SIGNATURE_REQUIRED_NAMES] = names
+ return sig_policy
+
+def __split_ignore_comma_in_quotes(string):
+ split_char = ","
+ quote = "'"
+ string_split = []
+ current_word = ""
+ inside_quote = False
+ for letter in string:
+ if letter == "'" or letter == "\"":
+ quote = letter
+ current_word += letter
+ if inside_quote:
+ inside_quote = False
+ else:
+ inside_quote = True
+ elif letter == split_char and not inside_quote:
+ if current_word != '':
+ string_split.append(current_word)
+ current_word = ""
+ else:
+ current_word += letter
+ if current_word != "" and inside_quote:
+ current_word += quote
+ if current_word != '':
+ string_split.append(current_word)
+ return string_split
+
+def check_sig_required_names_policy(text, req_names, error_dialog_title):
+ if not req_names:
+ return True
+ names = fetch_signature_policy_names_from_textfield(text)
+ if len(names) == 0:
+ error_occurred(None,
+ _("One or more certificate names must be specified "
+ "with this option."),
+ error_dialog_title,
+ gtk.MESSAGE_INFO)
+ return False
+ return True
+
+def get_image_path():
+ return g_image_path()
+
+def get_version():
+ return g_version()
+
+def get_os_version_and_build():
+ return g_os_version_and_build()
+
+def get_publishers_for_output(api_o):
+ publisher_str = ""
+ fmt = "\n%s\t%s\t%s (%s)"
+ try:
+ pref_pub = api_o.get_highest_ranked_publisher()
+ for pub in api_o.get_publishers():
+ pstatus = " "
+ if pub == pref_pub:
+ # Preferred
+ pstatus = "P"
+ elif pub.disabled:
+ # Disabled
+ pstatus = "D"
+ else:
+ # Enabled, but not preferred
+ pstatus = "E"
+ r = pub.repository
+ for uri in r.origins:
+ # Origin
+ publisher_str += fmt % \
+ (pstatus, "O", pub.prefix, uri)
+ for uri in r.mirrors:
+ # Mirror
+ publisher_str += fmt % \
+ (pstatus, "M", pub.prefix, uri)
+ except api_errors.ApiException:
+ pass
+ except Exception:
+ pass
+ return publisher_str
+
+def get_log_dir():
+ return ge_log_dir()
+
+def get_log_error_ext():
+ return ge_log_error_ext()
+
+def get_log_info_ext():
+ return ge_log_info_ext()
+
+def get_pm_name():
+ return PKG_CLIENT_NAME_PM
+
+def get_wi_name():
+ return PKG_CLIENT_NAME_WI
+
+def get_um_name():
+ return get_um()
+
+def is_frameworkerror(err):
+ return is_frameworke(err)
+
+def notify_log_error(app):
+ if global_settings.client_name == PKG_CLIENT_NAME_PM:
+ gobject.idle_add(__notify_log_error, app,
+ _("Errors logged: click to view"))
+
+def notify_log_warning(app):
+ if global_settings.client_name == PKG_CLIENT_NAME_PM:
+ gobject.idle_add(__notify_log_error, app,
+ _("Warnings logged: click to view"))
+
+def __notify_log_error(app, msg):
+ app.error_logged = True
+ app.w_logalert_frame.show()
+ app.w_logalert_frame.set_tooltip_text(msg)
+
+def setup_logging():
+ return su_logging(global_settings.client_name)
+
+def shutdown_logging():
+ sd_logging()
+
+def get_icon(icon_theme, name, size=16):
+ try:
+ return icon_theme.load_icon(name, size, 0)
+ except gobject.GError:
+ return None
+
+def init_for_help(application_dir="/"):
+ props = { gnome.PARAM_APP_DATADIR : os.path.join(application_dir,
+ 'usr/share/package-manager/help') }
+ gnome.program_init('package-manager', '0.1', properties=props)
+
+def display_help(help_id=None):
+ try:
+ if help_id != None:
+ gnome.help_display('package-manager', link_id=help_id)
+ else:
+ gnome.help_display('package-manager')
+ except gobject.GError, ex:
+ msg = str(ex)
+ logger.error(msg)
+
+def add_pkgname_to_dic(dic, name, special_table):
+ """Adds the original name of the package to the
+ dictionary of names.
+
+ 'dic' is the dictionary, which holds all the names
+
+ 'name' is the original package name
+
+ 'special_table' table with special names. Special name is when the full name
+ is part of another name. Example package/name another/package/name. package/name
+ is the special name in this situation."""
+
+ table = name.split("/")
+ if len(table) == 1:
+ if table[0] in dic:
+ return
+ else:
+ dic[table[0]] = {}
+ table.reverse()
+ i = 0
+ j = len(table)
+ for entry in table:
+ dictionary = dic.get(entry)
+ if dictionary == None:
+ dic[entry] = {}
+ i += 1
+ dic = dic[entry]
+ if i == 0 and j > 1:
+ special_table.append(name)
+
+def __is_recursion_gr_then_one(dic):
+ if not isinstance(dic, dict):
+ return False
+ keys = dic.keys()
+ if len(keys) == 1:
+ return __is_recursion_gr_then_one(dic.get(keys[0]))
+ elif len(keys) > 1:
+ return True
+ else:
+ return False
+
+def get_minimal_unique_name(dic, name, special_table):
+ name_table = name.split("/")
+ len_name_table = len(name_table)
+ if len_name_table == 1 and name_table[0] in dic:
+ # Special case. The name doesn't contain any "/"
+ return name_table[0]
+ elif len_name_table == 1:
+ return name
+ name_table.reverse()
+ max_special_level = 0
+ for special_name in special_table:
+ if name.endswith(special_name):
+ level = len(special_name.split("/"))
+ if level > max_special_level:
+ max_special_level = level
+ for special_category in SPECIAL_CATEGORIES:
+ found = False
+ level = 1
+ while level < len_name_table:
+ if special_category == name_table[level - 1]:
+ found = True
+ break
+ level += 1
+ if found:
+ if level > max_special_level:
+ max_special_level = level
+
+ if len_name_table < max_special_level:
+ return name
+
+ new_name = []
+ i = 0
+ for entry in name_table:
+ dictionary = dic.get(entry)
+ recursion = __is_recursion_gr_then_one(dictionary)
+ if dictionary and recursion:
+ new_name.append(entry)
+ dic = dictionary
+ i += 1
+ elif dictionary != None:
+ new_name.append(entry)
+ dic = dictionary
+ i += 1
+ if i > max_special_level:
+ break
+ n = ""
+ new_name.reverse()
+ for part in new_name:
+ n += part + "/"
+ return n.strip("/")
+
+def release_lock(lock):
+ if not lock:
+ return
+ try:
+ lock.release()
+ except RuntimeError, ex:
+ msg = str(ex)
+ logger.error(msg)
+ except Exception:
+ pass
+
+def get_api_object(img_dir, progtrack, parent_dialog):
+ api_o = None
+ message = None
+ try:
+ api_o = ngao(img_dir, progtrack)
+ except api_errors.VersionException, ex:
+ message = _("Version mismatch: expected version %d, got version %d") % \
+ (ex.expected_version, ex.received_version)
+ except api_errors.ImageNotFoundException, ex:
+ message = _("%s is not an install image") % ex.user_dir
+ except api_errors.ImageLockedError, ex:
+ message = str(ex)
+ except api_errors.ApiException, ex:
+ message = _("An unknown error occurred") + "\n\n" + _("Error details:\n")
+ message += str(ex)
+ except Exception:
+ traceback_lines = traceback.format_exc().splitlines()
+ traceback_str = ""
+ for line in traceback_lines:
+ traceback_str += line + "\n"
+ message = _("An unknown error occurred")
+ if traceback_str != "":
+ message += "\n\n" + _("Error details:\n") + traceback_str
+ if api_o == None or message != None:
+ if message == None:
+ message = _("An unknown error occurred")
+ raise Exception(message)
+ return api_o
+
+def error_occurred(parent, error_msg, msg_title = None,
+ msg_type=gtk.MESSAGE_ERROR, use_markup = False):
+ msgbox = gtk.MessageDialog(parent =
+ parent,
+ buttons = gtk.BUTTONS_CLOSE,
+ flags = gtk.DIALOG_MODAL,
+ type = msg_type,
+ message_format = None)
+ if use_markup:
+ msgbox.set_markup(error_msg)
+ else:
+ msgbox.set_property('text', error_msg)
+ if msg_title != None:
+ title = msg_title
+ else:
+ title = _("Error")
+
+ msgbox.set_title(title)
+ msgbox.run()
+ msgbox.destroy()
+
+def get_version_fmt_string():
+ build_str = _("Build")
+ return "%(version)s (" + build_str + " %(build)s-%(branch)s)"
+
+def set_dependencies_text(textview, info, dep_info, installed_dep_info,
+ installed_icon, not_installed_icon):
+ names = []
+ states = None
+ installed_states = []
+ if dep_info != None and len(dep_info.get(0)) >= 0:
+ states = dep_info[0]
+ if installed_dep_info != None and len(installed_dep_info.get(0)) >= 0:
+ installed_states = installed_dep_info[0]
+ version_fmt = get_version_fmt_string()
+ for x in info.dependencies:
+ if states != None and len(states) > 0:
+ name = fmri.extract_pkg_name(x)
+ found = False
+ for state in states:
+ if name == state.pkg_stem:
+ version = version_fmt % \
+ {"version": state.version,
+ "build": state.build_release,
+ "branch": state.branch}
+ found = True
+ break
+ if not found:
+ version = version_fmt % \
+ {"version": '0',
+ "build": '0',
+ "branch": '0'}
+ found = False
+ for state in installed_states:
+ if name == state.fmri.get_name():
+ installed_version = version_fmt % \
+ {"version": state.version,
+ "build": state.build_release,
+ "branch": state.branch}
+ found = True
+ break
+ if not found:
+ installed_version = (_("(not installed)"))
+ names.append((name, version, installed_version,
+ found))
+ else:
+ build_rel = "0"
+ pkg_fmri = fmri.PkgFmri(x, build_release=build_rel)
+ branch = pkg_fmri.version.branch
+ version_stripped = pkg_fmri.get_version().split("-%s"
+ % branch)[0]
+ version = version_fmt % \
+ {"version": version_stripped,
+ "build": build_rel,
+ "branch": branch}
+ names.append((pkg_fmri.pkg_name, version,
+ _("(not installed)"), False))
+
+ depbuffer = textview.get_buffer()
+ depbuffer.set_text("")
+ if states == None:
+ if len(names) == 0:
+ itr = depbuffer.get_iter_at_line(0)
+ depbuffer.insert_with_tags_by_name(itr,
+ _("None"), "bold")
+ else:
+ for i in range(0, len(names)):
+ itr = depbuffer.get_iter_at_line(i)
+ dep_str = "%s\n" % (names[i])
+ depbuffer.insert(itr, dep_str)
+ return
+ style = textview.get_style()
+ font_size_in_pango_unit = style.font_desc.get_size()
+ font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
+ tab_array = pango.TabArray(3, True)
+ header = [_("Name"), _("Dependency"), _("Installed Version")]
+ max_len = [0, 0]
+ for i in range(2):
+ depbuffer.set_text("")
+ itr = depbuffer.get_iter_at_line(0)
+ depbuffer.insert_with_tags_by_name(itr, header[i], "bold")
+ max_len[i] = get_textview_width(textview)
+
+ depbuffer.set_text("")
+ for one_names in names:
+ itr = depbuffer.get_iter_at_line(0)
+ depbuffer.insert(itr, one_names[i])
+ test_len = get_textview_width(textview)
+
+ if test_len > max_len[i]:
+ max_len[i] = test_len
+ depbuffer.set_text("")
+
+ tab_array.set_tab(1, pango.TAB_LEFT, max_len[0] + font_size_in_pixel)
+ tab_array.set_tab(2, pango.TAB_LEFT,
+ max_len[0] + max_len[1] + 2 * font_size_in_pixel)
+
+ textview.set_tabs(tab_array)
+
+ if len(names) == 0:
+ depbuffer.set_text("")
+ itr = depbuffer.get_iter_at_line(0)
+ depbuffer.insert_with_tags_by_name(itr, _("No dependencies"), "bold")
+ return
+
+ itr = depbuffer.get_iter_at_line(0)
+ header_text = "%s\t%s\t%s\n" % (header[0], header[1], header[2])
+ depbuffer.insert_with_tags_by_name(itr, header_text, "bold")
+ resized_installed_icon = None
+ resized_not_installed_icon = None
+ i += 0
+ for (name, version, installed_version, is_installed) in names:
+ if is_installed:
+ if resized_installed_icon == None:
+ resized_installed_icon = resize_icon(
+ installed_icon,
+ font_size_in_pixel)
+ icon = resized_installed_icon
+ else:
+ if resized_not_installed_icon == None:
+ resized_not_installed_icon = resize_icon(
+ not_installed_icon,
+ font_size_in_pixel)
+ icon = resized_not_installed_icon
+ itr = depbuffer.get_iter_at_line(i + 1)
+ dep_str = "%s\t%s\t" % (name, version)
+ depbuffer.insert(itr, dep_str)
+ end_itr = depbuffer.get_end_iter()
+ depbuffer.insert_pixbuf(end_itr, icon)
+ depbuffer.insert(end_itr, " %s\n" % installed_version)
+ i += 1
+
+def set_package_details(pkg_name, local_info, remote_info, textview,
+ installed_icon, not_installed_icon, update_available_icon,
+ is_all_publishers_installed=None, pubs_info=None, renamed_info=None,
+ pkg_renamed = False):
+ installed = True
+ has_remote = True
+
+ if not local_info:
+ # Package is not installed
+ local_info = remote_info
+ installed = False
+
+ if not remote_info:
+ remote_info = local_info
+ has_remote = False
+ installed = True
+
+ labs = {}
+ labs["name"] = _("Name:")
+ labs["summ"] = _("Summary:")
+ labs["desc"] = _("Description:")
+ labs["size"] = _("Size:")
+ labs["cat"] = _("Category:")
+ labs["ins"] = _("Installed:")
+ labs["available"] = _("Version Available:")
+ labs["renamed_to"] = _("Renamed To:")
+ labs["lat"] = _("Latest Version:")
+ labs["repository"] = _("Publisher:")
+
+ summary = _("None")
+ if local_info.summary:
+ summary = local_info.summary
+ description = ""
+ if local_info.description:
+ description = local_info.description
+
+ obsolete_str = ""
+ text = {}
+ text["name"] = pkg_name
+ text["summ"] = summary
+ text["desc"] = description
+ renamed_to = ""
+ if renamed_info != None and \
+ len(renamed_info.dependencies) > 0:
+ renamed_pkgs = []
+ for dep in renamed_info.dependencies:
+ if dep.startswith('pkg:/'):
+ dep_strs = dep.split('/', 1)
+ dep = dep_strs[1]
+ renamed_pkgs.append(dep)
+ renamed_to += renamed_pkgs[0] + "\n"
+ for dep in renamed_pkgs[1:]:
+ renamed_to += "\t" + dep + "\n"
+ text["renamed_to"] = renamed_to
+ if installed:
+ if api.PackageInfo.OBSOLETE in local_info.states:
+ obsolete_str = _(" (Obsolete)")
+ ver_text = _("%(version)s (Build %(build)s-%(branch)s)")
+ text["ins"] = ver_text % \
+ {"version": local_info.version,
+ "build": local_info.build_release,
+ "branch": local_info.branch}
+ text["ins"] += obsolete_str
+ labs["available"] = _("Latest Version:")
+ if not same_pkg_versions(local_info, remote_info):
+ text["available"] = ver_text % \
+ {"version": remote_info.version,
+ "build": remote_info.build_release,
+ "branch": remote_info.branch}
+ elif has_remote:
+ text["available"] = _("Not available from this publisher")
+ else:
+ text["available"] = "No"
+ else:
+ if api.PackageInfo.OBSOLETE in remote_info.states:
+ obsolete_str = _(" (Obsolete)")
+ text["ins"] = _("No")
+ text["ins"] += obsolete_str
+ labs["available"] = _("Latest Version:")
+ text["available"] = _(
+ "%(version)s (Build %(build)s-%(branch)s)") % \
+ {"version": remote_info.version,
+ "build": remote_info.build_release,
+ "branch": remote_info.branch}
+ if local_info.size != 0:
+ text["size"] = misc.bytes_to_str(local_info.size)
+ else:
+ text["size"] = "0"
+ categories = _("None")
+ if local_info.category_info_list:
+ verbose = len(local_info.category_info_list) > 1
+ categories = ""
+ categories += local_info.category_info_list[0].__str__(verbose)
+ if len(local_info.category_info_list) > 1:
+ for ci in local_info.category_info_list[1:]:
+ categories += ", " + ci.__str__(verbose)
+
+ text["cat"] = categories
+ pub_name = local_info.publisher
+ if pubs_info != None:
+ try:
+ item = pubs_info[local_info.publisher]
+ except KeyError:
+ item = None
+ if item:
+ alias = item[1]
+ if alias != None and len(alias) > 0:
+ pub_name = "%s (%s)" % (
+ alias, local_info.publisher)
+ text["repository"] = pub_name
+ # pubs_info: dict of publisher disabled status and aliases:
+ # pub_info[pub_name][0] = True disabled or False enabled
+ # pub_info[pub_name][1] = Alias
+ if is_all_publishers_installed and pubs_info != None:
+ if local_info.publisher in pubs_info:
+ if pubs_info[local_info.publisher][0]:
+ text["repository"] = pub_name + \
+ _(" (disabled)")
+ else:
+ text["repository"] = pub_name + _(" (removed)")
+ set_package_details_text(labs, text, textview, installed_icon,
+ not_installed_icon, update_available_icon, pkg_renamed)
+ return (labs, text)
+
+def get_scale(textview):
+ scale = 1.0
+ if not textview:
+ return scale
+ style = textview.get_style()
+ font_size_in_pango_unit = style.font_desc.get_size()
+ font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
+ s = gtk.settings_get_default()
+ dpi = s.get_property("gtk-xft-dpi") / 1024
+
+ # AppFontSize*DPI/72 = Cairo Units
+ # DefaultFont=10, Default DPI=96: 10*96/72 = 13.3 Default FontInCairoUnits
+ def_font_cunits = 13.3
+ app_cunits = round(font_size_in_pixel*dpi/72.0, 1)
+ if app_cunits >= def_font_cunits:
+ scale = round(
+ ((app_cunits - def_font_cunits)/def_font_cunits) + 1, 2)
+ return scale
+
+def get_textview_width(textview):
+ infobuffer = textview.get_buffer()
+ bounds = infobuffer.get_bounds()
+ start = textview.get_iter_location(bounds[0])
+ end = textview.get_iter_location(bounds[1])
+ return end[0] - start[0]
+
+def set_package_details_text(labs, text, textview, installed_icon,
+ not_installed_icon, update_available_icon, pkg_renamed):
+ style = textview.get_style()
+ font_size_in_pango_unit = style.font_desc.get_size()
+ font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
+ tab_array = pango.TabArray(2, True)
+
+ infobuffer = textview.get_buffer()
+ infobuffer.set_text("")
+ max_test_len = 0
+ for lab in labs:
+ __add_label_to_generalinfo(infobuffer, 0, labs[lab])
+ test_len = get_textview_width(textview)
+ if test_len > max_test_len:
+ max_test_len = test_len
+ infobuffer.set_text("")
+ tab_array.set_tab(1, pango.TAB_LEFT, max_test_len + font_size_in_pixel)
+ textview.set_tabs(tab_array)
+ infobuffer.set_text("")
+ i = 0
+ __add_line_to_generalinfo(infobuffer, i, labs["name"], text["name"])
+ i += 1
+ if pkg_renamed:
+ i = __add_renamed_line_to_generalinfo(infobuffer, i, labs, text)
+ __add_line_to_generalinfo(infobuffer, i, labs["summ"], text["summ"])
+ i += 1
+ installed = False
+ if text["ins"].startswith(_("No")):
+ icon = not_installed_icon
+ else:
+ icon = installed_icon
+ installed = True
+ __add_line_to_generalinfo(infobuffer, i, labs["ins"],
+ text["ins"], icon, font_size_in_pixel)
+ i += 1
+ if installed:
+ if text["available"] != "No":
+ __add_line_to_generalinfo(infobuffer, i,
+ labs["available"], text["available"],
+ update_available_icon, font_size_in_pixel)
+ i += 1
+ if not pkg_renamed:
+ i = __add_renamed_line_to_generalinfo(infobuffer, i,
+ labs, text)
+ else:
+ __add_line_to_generalinfo(infobuffer, i,
+ labs["available"], text["available"])
+ i += 1
+ if text["size"] != "0":
+ __add_line_to_generalinfo(infobuffer, i, labs["size"], text["size"])
+ i += 1
+ __add_line_to_generalinfo(infobuffer, i, labs["cat"], text["cat"])
+ i += 1
+ __add_line_to_generalinfo(infobuffer, i, labs["repository"],
+ text["repository"])
+ if len(text["desc"]) > 0:
+ i += 1
+ __add_label_to_generalinfo(infobuffer, i, labs["desc"] + '\n')
+ i += 1
+ itr = infobuffer.get_iter_at_line(i)
+ infobuffer.insert(itr, text["desc"])
+
+def set_pub_cert_details_text(labs, text, textview, added=False, reinstated=False):
+ style = textview.get_style()
+ font_size_in_pango_unit = style.font_desc.get_size()
+ font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
+ tab_array = pango.TabArray(3, True)
+
+ infobuffer = textview.get_buffer()
+ infobuffer.set_text("")
+
+ labs_issuer = {}
+ labs_issuer["common_name_to"] = PUBCERT_COMMON_NAME
+ labs_issuer["org_to"] = PUBCERT_ORGANIZATION
+ labs_issuer["org_unit_to"] = PUBCERT_ORGANIZATIONAL_UNIT
+ max_issuer_len = 0
+ for lab in labs_issuer:
+ __add_label_to_generalinfo(infobuffer, 0, labs_issuer[lab])
+ test_len = get_textview_width(textview)
+ if test_len > max_issuer_len:
+ max_issuer_len = test_len
+ infobuffer.set_text("")
+
+ max_finger_len = 0
+ __add_label_to_generalinfo(infobuffer, 0, labs["fingerprints"])
+ max_finger_len = get_textview_width(textview)
+ infobuffer.set_text("")
+
+ tab_array.set_tab(0, pango.TAB_LEFT, max_finger_len + font_size_in_pixel)
+ tab_array.set_tab(1, pango.TAB_LEFT, max_issuer_len + font_size_in_pixel)
+ textview.set_tabs(tab_array)
+ infobuffer.set_text("")
+ i = 0
+ __add_label_to_generalinfo(infobuffer, i, labs["issued_to"] + '\n')
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["common_name_to"],
+ text["common_name_to"])
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["org_to"], text["org_to"],
+ bold_label=False)
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["org_unit_to"],
+ text["org_unit_to"])
+
+ i += 1
+ __add_label_to_generalinfo(infobuffer, i, labs["issued_by"] + '\n')
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["common_name_by"],
+ text["common_name_by"])
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["org_by"], text["org_by"])
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["org_unit_by"],
+ text["org_unit_by"])
+
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["validity"], "", bold_label=True)
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["issued_on"], text["issued_on"])
+
+ i += 1
+ __add_label_to_generalinfo(infobuffer, i, labs["fingerprints"] + '\n')
+
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["sha1"], text["sha1"])
+ i += 1
+ __add_line_to_pub_cert_info(infobuffer, i, labs["md5"], text["md5"])
+ i += 1
+ if not added and not reinstated:
+ __add_line_to_pub_cert_info(infobuffer, i, labs["ips"], text["ips"],
+ add_return=False)
+ elif added and not reinstated:
+ __add_label_to_generalinfo(infobuffer, i,
+ _("Note: \t Certificate is marked to be added"))
+ elif not added and reinstated:
+ __add_label_to_generalinfo(infobuffer, i,
+ _("Note: \t Certificate is marked to be reinstated"))
+
+def __add_renamed_line_to_generalinfo(text_buffer, index, labs, text):
+ if text["renamed_to"] != "":
+ rename_list = text["renamed_to"].split("\n", 1)
+ start = ""
+ remainder = ""
+ if rename_list != None:
+ if len(rename_list) > 0:
+ start = rename_list[0]
+ if len(rename_list) > 1:
+ remainder = rename_list[1]
+ __add_line_to_generalinfo(text_buffer, index, labs["renamed_to"],
+ start)
+ index += 1
+ if len(remainder) > 0:
+ itr = text_buffer.get_iter_at_line(index)
+ text_buffer.insert(itr, remainder)
+ index += remainder.count("\n")
+ return index
+
+def __add_label_to_generalinfo(text_buffer, index, label):
+ itr = text_buffer.get_iter_at_line(index)
+ text_buffer.insert_with_tags_by_name(itr, label, "bold")
+
+def __add_line_to_generalinfo(text_buffer, index, label, text,
+ icon = None, font_size = 1):
+ itr = text_buffer.get_iter_at_line(index)
+ text_buffer.insert_with_tags_by_name(itr, label, "bold")
+ end_itr = text_buffer.get_end_iter()
+ if icon == None:
+ text_buffer.insert(end_itr, "\t%s\n" % text)
+ else:
+ resized_icon = resize_icon(icon, font_size)
+ text_buffer.insert(end_itr, "\t")
+ text_buffer.get_end_iter()
+ text_buffer.insert_pixbuf(end_itr, resized_icon)
+ text_buffer.insert(end_itr, " %s\n" % text)
+
+def __add_line_to_pub_cert_info(text_buffer, index, label, text,
+ bold_label = False, add_return = True):
+ tab_str = "\t"
+ itr = text_buffer.get_iter_at_line(index)
+ if bold_label:
+ text_buffer.insert_with_tags_by_name(itr, label, "bold")
+ else:
+ text_buffer.insert_with_tags_by_name(itr, label, "normal")
+ end_itr = text_buffer.get_end_iter()
+
+ return_str = ""
+ if add_return:
+ return_str = "\n"
+
+ text_buffer.insert(end_itr, tab_str)
+ text_buffer.get_end_iter()
+ text_buffer.insert(end_itr, (" %s" + return_str) % text)
+
+def same_pkg_versions(info1, info2):
+ if info1 == None or info2 == None:
+ return False
+
+ return info1.version == info2.version and \
+ info1.build_release == info2.build_release and \
+ info1.branch == info2.branch
+
+def resize_icon(icon, font_size):
+ width = icon.get_width()
+ height = icon.get_height()
+ return icon.scale_simple(
+ (font_size * width) / height,
+ font_size,
+ gtk.gdk.INTERP_BILINEAR)
+
+def get_pkg_info(app, api_o, pkg_stem, local):
+ info = None
+ try:
+ info = api_o.info([pkg_stem], local,
+ api.PackageInfo.ALL_OPTIONS -
+ frozenset([api.PackageInfo.LICENSES]))
+ except api_errors.ApiException, ex:
+ err = str(ex)
+ logger.error(err)
+ notify_log_error(app)
+ return info
+
+ pkgs_info = None
+ package_info = None
+ if info:
+ pkgs_info = info[0]
+ if pkgs_info:
+ package_info = pkgs_info[0]
+ if package_info:
+ return package_info
+ else:
+ return None
+
+def restart_system():
+ # "init 6" performs reboot in a clean and orderly manner informing
+ # the svc.startd daemon of the change in runlevel which subsequently
+ # achieves the appropriate milestone and ultimately executes
+ # the rc0 kill scripts.
+ command = "init 6"
+ return os.system(command)
+
+def set_modal_and_transient(top_window, parent_window = None):
+ if parent_window:
+ top_window.set_transient_for(parent_window)
+ top_window.set_modal(True)
+
+def get_catalogrefresh_exception_msg(cre):
+ return get_msg(cre)
+
+def __get_stockbutton_label(button):
+ # Gtk.Button->Gtk.Alignment->Gtk.HBox->[Gtk.Image, Gtk.Label]
+ # Drill into Button widget to get Gtk.Label and set its text
+ children = button.get_children()
+ if len(children) == 0:
+ return None
+ align = children[0]
+ if not align or not isinstance(align, gtk.Alignment):
+ return None
+ children = align.get_children()
+ if len(children) == 0:
+ return None
+ hbox = children[0]
+ if not hbox or not isinstance(hbox, gtk.HBox):
+ return None
+ children = hbox.get_children()
+ if not (len(children) > 1):
+ return None
+ button_label = children[1]
+ if not button_label or not isinstance(button_label, gtk.Label):
+ return None
+ return button_label
+
+def get_stockbutton_label_label(button):
+ button_label = __get_stockbutton_label(button)
+ if button_label != None:
+ return button_label.get_label()
+ else:
+ return None
+
+def change_stockbutton_label(button, text):
+ button_label = __get_stockbutton_label(button)
+ if button_label != None:
+ button_label.set_label(text)
+
+def set_icon_for_button_and_menuitem(icon_name, button=None, menuitem=None):
+ icon_source = gtk.IconSource()
+ icon_source.set_icon_name(icon_name)
+ icon_set = gtk.IconSet()
+ icon_set.add_source(icon_source)
+ if button:
+ image_widget = gtk.image_new_from_icon_set(icon_set,
+ gtk.ICON_SIZE_SMALL_TOOLBAR)
+ button.set_icon_widget(image_widget)
+ if menuitem:
+ image_widget = gtk.image_new_from_icon_set(icon_set,
+ gtk.ICON_SIZE_MENU)
+ menuitem.set_image(image_widget)
+
+def exit_if_no_threads():
+ if threading.activeCount() == 1:
+ if gtk.main_level() > 0:
+ gtk.main_quit()
+ sys.exit(0)
+ return True
+
+def get_statusbar_label(statusbar):
+ sb_frame = None
+ sb_hbox = None
+ sb_label = None
+ children = statusbar.get_children()
+ if len(children) > 0:
+ sb_frame = children[0]
+ if sb_frame and isinstance(sb_frame, gtk.Frame):
+ children = sb_frame.get_children()
+ if len(children) > 0:
+ sb_hbox = children[0]
+ if sb_hbox and isinstance(sb_hbox, gtk.HBox):
+ children = sb_hbox.get_children()
+ if len(children) == 0:
+ return None
+ sb_label = children[0]
+ if sb_label and isinstance(sb_label, gtk.Label):
+ return sb_label
+ return None
+
+def get_origin_uri(repo):
+ if repo == None:
+ return None
+ origin_uri = repo.origins[0]
+ ret_uri = None
+ if isinstance(origin_uri, str):
+ if len(origin_uri) > 0:
+ ret_uri = origin_uri.strip("/")
+ elif isinstance(origin_uri, publisher.RepositoryURI):
+ uri = origin_uri.uri
+ if uri != None and len(uri) > 0:
+ ret_uri = uri.strip("/")
+ return ret_uri
+
+def get_pkg_stem(pkg_name, pkg_pub=None):
+ pkg_str = "pkg:/"
+ if pkg_pub == None:
+ return_str = "%s%s" % (pkg_str, pkg_name)
+ else:
+ return_str = "%s/%s/%s" % (pkg_str, pkg_pub, pkg_name)
+ return return_str
+
+def get_max_text_length(length_to_check, text, widget):
+ if widget == None:
+ return 0
+ context = widget.get_pango_context()
+ metrics = context.get_metrics(context.get_font_description())
+ current_length = pango.PIXELS(
+ metrics.get_approximate_char_width() * len(text))
+ if current_length > length_to_check:
+ return current_length
+ else:
+ return length_to_check
+
+def is_a_textview( widget):
+ return widget.class_path().rpartition('.')[2] == "GtkTextView"
+
+def alias_clash(pubs, prefix, alias):
+ clash = False
+ if alias != None and len(alias) > 0:
+ for pub in pubs:
+ if pub.disabled:
+ continue
+ if pub.prefix == prefix:
+ continue
+ if alias == pub.prefix or alias == pub.alias:
+ clash = True
+ break
+ return clash
+
+def setup_package_license(licenses):
+ lic = ""
+ lic_u = ""
+ if licenses == None:
+ lic_u = _("Not available")
+ else:
+ try:
+ for licens in licenses:
+ lic += licens.get_text()
+ lic += "\n"
+ except api_errors.ApiException:
+ pass
+ try:
+ lic_u = unicode(lic, "utf-8")
+ except UnicodeDecodeError:
+ lic_u = _("License could not be shown "
+ "due to conversion problem.")
+ return lic_u
+
+def get_state_from_states(states):
+ if api.PackageInfo.INSTALLED in states:
+ pkg_state = api.PackageInfo.INSTALLED
+ if api.PackageInfo.UPGRADABLE in states:
+ pkg_state = api.PackageInfo.UPGRADABLE
+ else:
+ pkg_state = api.PackageInfo.KNOWN
+
+ return pkg_state
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/misc_non_gui.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,241 @@
+#!/usr/bin/python
+#
+# 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 (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+#
+
+import os
+import socket
+import urlparse
+import urllib2
+import cPickle
+import logging
+import logging.handlers
+import platform
+import sys
+
+import pkg
+import pkg.portable as portable
+import pkg.client.api as api
+import pkg.client.api_errors as api_errors
+import pkg.client.transport.exception as transport
+from pkg.client import global_settings
+
+# The current version of the Client API the PM, UM and
+# WebInstall GUIs have been tested against and are known to work with.
+CLIENT_API_VERSION = 68
+LOG_DIR = "/var/tmp"
+LOG_ERROR_EXT = "_error.log"
+LOG_INFO_EXT = "_info.log"
+PKG_CLIENT_NAME_UM = "updatemanager"
+IMAGE_DIRECTORY_DEFAULT = "/" # Image default directory
+IMAGE_DIR_COMMAND = "svcprop -p update/image_dir svc:/application/pkg/update"
+
+
+def get_image_path():
+ try:
+ image_directory = os.environ["PKG_IMAGE"]
+ except KeyError:
+ image_directory = \
+ os.popen(IMAGE_DIR_COMMAND).readline().rstrip()
+ if len(image_directory) == 0:
+ image_directory = IMAGE_DIRECTORY_DEFAULT
+ return image_directory
+
+def get_log_dir():
+ return LOG_DIR
+
+def get_log_error_ext():
+ return LOG_ERROR_EXT
+
+def get_log_info_ext():
+ return LOG_INFO_EXT
+
+class _LogFilter(logging.Filter):
+ def __init__(self, max_level=logging.CRITICAL):
+ logging.Filter.__init__(self)
+ self.max_level = max_level
+
+ def filter(self, record):
+ return record.levelno <= self.max_level
+
+def get_version():
+ return pkg.VERSION
+
+def get_os_version_and_build():
+ os_ver = portable.util.get_os_release()
+ os_name = portable.util.get_canonical_os_name()
+ if os_name == 'sunos':
+ os_ver += " (" + platform.uname()[3] + ")"
+ return os_ver
+
+def setup_logging(client_name):
+ normal_setup = True
+ log_path = os.path.join(LOG_DIR, client_name)
+ err_str = ""
+
+ infolog_path = log_path + LOG_INFO_EXT
+ try:
+ info_h = logging.handlers.RotatingFileHandler(infolog_path,
+ maxBytes=1000000, backupCount=1)
+ except IOError, e:
+ err_str = _("WARNING: %s\nUnable to setup log:\n ") % client_name
+ err_str += str(e)
+ err_str += _("\n All info messages will be logged to stdout")
+ normal_setup = False
+
+ errlog_path = log_path + LOG_ERROR_EXT
+ try:
+ err_h = logging.handlers.RotatingFileHandler(errlog_path,
+ maxBytes=1000000, backupCount=1)
+ except IOError, e:
+ if err_str == "":
+ err_str = _("WARNING: %s\nUnable to setup log:\n ") % \
+ client_name
+ else:
+ err_str += _("\n ")
+ err_str += str(e)
+ err_str += _("\n All errors and warnings will be logged to stderr")
+ normal_setup = False
+
+ if normal_setup:
+ log_fmt = logging.Formatter(
+ "<b>%(levelname)s:</b> " + client_name + \
+ "\n%(asctime)s: %(filename)s: %(module)s: "
+ "%(lineno)s:\n%(message)s")
+ else:
+ if client_name != PKG_CLIENT_NAME_UM and err_str != "":
+ print err_str
+ log_fmt = logging.Formatter(
+ "%(levelname)s: " + client_name + \
+ "\n%(asctime)s: %(filename)s: %(module)s: "
+ "%(lineno)s:\n%(message)s")
+ info_h = logging.StreamHandler(sys.stdout)
+ err_h = logging.StreamHandler(sys.stderr)
+
+ info_t = _LogFilter(logging.INFO)
+ info_h.addFilter(info_t)
+ info_h.setFormatter(log_fmt)
+ info_h.setLevel(logging.INFO)
+ global_settings.info_log_handler = info_h
+
+ err_h.setFormatter(log_fmt)
+ err_h.setLevel(logging.WARNING)
+ global_settings.error_log_handler = err_h
+
+ return normal_setup
+
+def shutdown_logging():
+ try:
+ global_settings.reset_logging()
+ logging.shutdown()
+ except IOError:
+ pass
+
+def get_cache_dir(api_object):
+ img = api_object.img
+ cache_dir = os.path.join(img.imgdir, "gui_cache")
+ try:
+ __mkdir(cache_dir)
+ except OSError:
+ cache_dir = None
+ return cache_dir
+
+def __mkdir(directory_path):
+ if not os.path.isdir(directory_path):
+ os.makedirs(directory_path)
+
+def get_api_object(img_dir, progtrack):
+ api_o = None
+ api_o = api.ImageInterface(img_dir,
+ CLIENT_API_VERSION,
+ progtrack, None, global_settings.client_name)
+ return api_o
+
+def read_cache_file(file_path):
+ data = []
+ try:
+ fh = open(file_path, 'r')
+ data = cPickle.load(fh)
+ fh.close()
+ except IOError:
+ pass
+ except:
+ pass
+ return data
+
+def dump_cache_file(file_path, data):
+ try:
+ fh = open(file_path,"w")
+ cPickle.dump(data, fh, True)
+ fh.close()
+ except IOError:
+ pass
+ except:
+ pass
+
+def get_um_name():
+ return PKG_CLIENT_NAME_UM
+
+def get_catalogrefresh_exception_msg(cre):
+ framework_error = False
+ if not isinstance(cre, api_errors.CatalogRefreshException):
+ return ("", False)
+ msg = _("Catalog refresh error:\n")
+ if cre.succeeded < cre.total:
+ msg += _(
+ "Only %(suc)s out of %(tot)s catalogs successfully updated.\n") % \
+ {"suc": cre.succeeded, "tot": cre.total}
+
+ for pub, err in cre.failed:
+ if isinstance(err, urllib2.HTTPError):
+ msg += "%s: %s - %s" % \
+ (err.filename, err.code, err.msg)
+ elif isinstance(err, urllib2.URLError):
+ if err.args[0][0] == 8:
+ msg += "%s: %s" % \
+ (urlparse.urlsplit(
+ pub["origin"])[1].split(":")[0],
+ err.args[0][1])
+ else:
+ if isinstance(err.args[0], socket.timeout):
+ msg += "%s: %s" % \
+ (pub["origin"], "timeout")
+ else:
+ msg += "%s: %s" % \
+ (pub["origin"], err.args[0][1])
+ else:
+ framework_error = is_frameworkerror(err)
+ msg += str(err)
+
+ if cre.errmessage:
+ msg += cre.errmessage
+
+ return (msg, framework_error)
+
+def is_frameworkerror(err):
+ if isinstance(err, transport.TransportFailures):
+ for exp in err.exceptions:
+ if isinstance(exp, transport.TransportFrameworkError) and \
+ exp.code == 56:
+ return True
+ return False
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/parseqs.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,92 @@
+#!/usr/bin/python
+##################################################################################
+# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+# http://www.python.org/download/releases/2.6.1/license/
+#
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation;
+# All Rights Reserved
+#
+# Extraced from urlparse module in Python 2.6.1
+# http://www.python.org/ftp/python/2.6.1/Python-2.6.1.tgz
+# Python-2.6.1/Lib/urlparse.py
+#
+# Modifications:
+# Just extracted parse_qs() and parse_qsl() functions without any modifications
+# Only addition is the urllib import unquote statement
+#
+##################################################################################
+"""
+Parse (absolute and relative) URLs.
+
+See RFC 1808: "Relative Uniform Resource Locators", by R. Fielding,
+UC Irvine, June 1995.
+"""
+
+from urllib import unquote
+
+def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
+ """Parse a query given as a string argument.
+
+ Arguments:
+
+ qs: URL-encoded query string to be parsed
+
+ keep_blank_values: flag indicating whether blank values in
+ URL encoded queries should be treated as blank strings.
+ A true value indicates that blanks should be retained as
+ blank strings. The default false value indicates that
+ blank values are to be ignored and treated as if they were
+ not included.
+
+ strict_parsing: flag indicating what to do with parsing errors.
+ If false (the default), errors are silently ignored.
+ If true, errors raise a ValueError exception.
+ """
+ dict = {}
+ for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
+ if name in dict:
+ dict[name].append(value)
+ else:
+ dict[name] = [value]
+ return dict
+
+def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
+ """Parse a query given as a string argument.
+
+ Arguments:
+
+ qs: URL-encoded query string to be parsed
+
+ keep_blank_values: flag indicating whether blank values in
+ URL encoded queries should be treated as blank strings. A
+ true value indicates that blanks should be retained as blank
+ strings. The default false value indicates that blank values
+ are to be ignored and treated as if they were not included.
+
+ strict_parsing: flag indicating what to do with parsing errors. If
+ false (the default), errors are silently ignored. If true,
+ errors raise a ValueError exception.
+
+ Returns a list, as G-d intended.
+ """
+ pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
+ r = []
+ for name_value in pairs:
+ if not name_value and not strict_parsing:
+ continue
+ nv = name_value.split('=', 1)
+ if len(nv) != 2:
+ if strict_parsing:
+ raise ValueError, "bad query field: %r" % (name_value,)
+ # Handle case of a control-name with no equal sign
+ if keep_blank_values:
+ nv.append('')
+ else:
+ continue
+ if len(nv[1]) or keep_blank_values:
+ name = unquote(nv[0].replace('+', ' '))
+ value = unquote(nv[1].replace('+', ' '))
+ r.append((name, value))
+
+ return r
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/pmgconf.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,233 @@
+#!/usr/bin/python
+#
+# 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 (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved.
+#
+
+import sys
+try:
+ import gconf
+ from glib import GError
+except ImportError:
+ sys.exit(1)
+
+PACKAGEMANAGER_PREFERENCES = "/apps/packagemanager/preferences"
+MAX_SEARCH_COMPLETION_PREFERENCES = \
+ "/apps/packagemanager/preferences/max_search_completion"
+INITIAL_APP_WIDTH_PREFERENCES = "/apps/packagemanager/preferences/initial_app_width"
+INITIAL_APP_HEIGHT_PREFERENCES = "/apps/packagemanager/preferences/initial_app_height"
+INITIAL_APP_HPOS_PREFERENCES = "/apps/packagemanager/preferences/initial_app_hposition"
+INITIAL_APP_VPOS_PREFERENCES = "/apps/packagemanager/preferences/initial_app_vposition"
+INITIAL_SHOW_FILTER_PREFERENCES = "/apps/packagemanager/preferences/initial_show_filter"
+INITIAL_SECTION_PREFERENCES = "/apps/packagemanager/preferences/initial_section"
+LAST_EXPORT_SELECTION_PATH = \
+ "/apps/packagemanager/preferences/last_export_selections_path"
+LAST_ADD_PUBCERT_PATH = \
+ "/apps/packagemanager/preferences/last_add_pubcert_path"
+SHOW_STARTPAGE_PREFERENCES = "/apps/packagemanager/preferences/show_startpage"
+SHOW_IMAGE_UPDATE_CONFIRMATION = "/apps/packagemanager/preferences/imageupdate_confirm"
+SHOW_INSTALL_CONFIRMATION = "/apps/packagemanager/preferences/install_confirm"
+SHOW_REMOVE_CONFIRMATION = "/apps/packagemanager/preferences/remove_confirm"
+SAVE_STATE_PREFERENCES = "/apps/packagemanager/preferences/save_state"
+START_INSEARCH_PREFERENCES = "/apps/packagemanager/preferences/start_insearch"
+LASTSOURCE_PREFERENCES = "/apps/packagemanager/preferences/lastsource"
+API_SEARCH_ERROR_PREFERENCES = "/apps/packagemanager/preferences/api_search_error"
+DETAILS_EXPANDED_PREFERENCES = "/apps/packagemanager/preferences/details_expanded"
+
+class PMGConf:
+ def __init__(self):
+ self.client = gconf.client_get_default()
+ try:
+ self.max_search_completion = \
+ self.client.get_int(MAX_SEARCH_COMPLETION_PREFERENCES)
+ self.initial_show_filter = \
+ self.client.get_int(INITIAL_SHOW_FILTER_PREFERENCES)
+ self.initial_section = \
+ self.client.get_int(INITIAL_SECTION_PREFERENCES)
+ self.last_export_selection_path = \
+ self.client.get_string(LAST_EXPORT_SELECTION_PATH)
+ self.last_add_pubcert_path = \
+ self.client.get_string(LAST_ADD_PUBCERT_PATH)
+ self.show_startpage = \
+ self.client.get_bool(SHOW_STARTPAGE_PREFERENCES)
+ self.save_state = \
+ self.client.get_bool(SAVE_STATE_PREFERENCES)
+ self.show_image_update = \
+ self.client.get_bool(SHOW_IMAGE_UPDATE_CONFIRMATION)
+ self.show_install = \
+ self.client.get_bool(SHOW_INSTALL_CONFIRMATION)
+ self.show_remove = \
+ self.client.get_bool(SHOW_REMOVE_CONFIRMATION)
+ self.start_insearch = \
+ self.client.get_bool(START_INSEARCH_PREFERENCES)
+ self.lastsource = \
+ self.client.get_string(LASTSOURCE_PREFERENCES)
+ self.not_show_repos = \
+ self.client.get_string(API_SEARCH_ERROR_PREFERENCES)
+ self.initial_app_width = \
+ self.client.get_int(INITIAL_APP_WIDTH_PREFERENCES)
+ self.initial_app_height = \
+ self.client.get_int(INITIAL_APP_HEIGHT_PREFERENCES)
+ self.initial_app_hpos = \
+ self.client.get_int(INITIAL_APP_HPOS_PREFERENCES)
+ self.initial_app_vpos = \
+ self.client.get_int(INITIAL_APP_VPOS_PREFERENCES)
+ self.client.add_dir(PACKAGEMANAGER_PREFERENCES,
+ gconf.CLIENT_PRELOAD_NONE)
+ self.client.notify_add(SHOW_IMAGE_UPDATE_CONFIRMATION,
+ self.__show_image_update_changed)
+ self.client.notify_add(SHOW_INSTALL_CONFIRMATION,
+ self.__show_install_changed)
+ self.client.notify_add(SHOW_REMOVE_CONFIRMATION,
+ self.__show_remove_changed)
+ self.client.notify_add(SAVE_STATE_PREFERENCES,
+ self.__save_state_changed)
+ self.details_expanded = \
+ self.client.get_bool(DETAILS_EXPANDED_PREFERENCES)
+ except GError:
+ # Default values - the same as in the
+ # packagemanager-preferences.schemas
+ self.max_search_completion = 20
+ self.initial_show_filter = 0
+ self.initial_section = 2
+ self.last_export_selection_path = ""
+ self.last_add_pubcert_path = ""
+ self.show_startpage = True
+ self.show_image_update = True
+ self.show_install = True
+ self.show_remove = True
+ self.save_state = True
+ self.start_insearch = True
+ self.lastsource = ""
+ self.not_show_repos = ""
+ self.initial_app_width = 800
+ self.initial_app_height = 600
+ self.initial_app_hpos = 200
+ self.initial_app_vpos = 320
+ self.details_expanded = True
+ self.show_startpage = False
+ self.__fix_initial_values()
+
+ def __fix_initial_values(self):
+ if self.initial_app_width == -1:
+ self.initial_app_width = 800
+ if self.initial_app_height == -1:
+ self.initial_app_height = 600
+ if self.initial_app_hpos == -1:
+ self.initial_app_hpos = 200
+ if self.initial_app_vpos == -1:
+ self.initial_app_vpos = 320
+
+ if not self.not_show_repos:
+ self.not_show_repos = ""
+
+ def set_lastsource(self, value):
+ try:
+ self.lastsource = value
+ self.client.set_string(LASTSOURCE_PREFERENCES, value)
+ except GError:
+ pass
+
+ def set_details_expanded(self, value):
+ try:
+ self.details_expanded = value
+ self.client.set_bool(DETAILS_EXPANDED_PREFERENCES, value)
+ except GError:
+ pass
+
+ def set_start_insearch(self, value):
+ try:
+ self.start_insearch = value
+ self.client.set_bool(START_INSEARCH_PREFERENCES, value)
+ except GError:
+ pass
+
+ def set_show_startpage(self, value):
+ try:
+ self.show_startpage = value
+ self.client.set_bool(SHOW_STARTPAGE_PREFERENCES, value)
+ except GError:
+ pass
+
+ def set_save_state(self, value):
+ try:
+ self.save_state = value
+ self.client.set_bool(SAVE_STATE_PREFERENCES, value)
+ except GError:
+ pass
+
+ def set_show_image_update(self, value):
+ try:
+ self.show_image_update = value
+ self.client.set_bool(SHOW_IMAGE_UPDATE_CONFIRMATION, value)
+ except GError:
+ pass
+
+ def set_show_install(self, value):
+ try:
+ self.show_install = value
+ self.client.set_bool(SHOW_INSTALL_CONFIRMATION, value)
+ except GError:
+ pass
+
+ def set_show_remove(self, value):
+ try:
+ self.show_remove = value
+ self.client.set_bool(SHOW_REMOVE_CONFIRMATION, value)
+ except GError:
+ pass
+
+ def set_not_show_repos(self, value):
+ try:
+ self.client.set_string(API_SEARCH_ERROR_PREFERENCES, value)
+ except GError:
+ pass
+
+ def save_values(self, pub, start_insearch, width, height, hpos, vpos):
+ try:
+ if self.last_export_selection_path:
+ self.client.set_string(LAST_EXPORT_SELECTION_PATH,
+ self.last_export_selection_path)
+ if self.last_add_pubcert_path:
+ self.client.set_string(LAST_ADD_PUBCERT_PATH,
+ self.last_add_pubcert_path)
+ self.client.set_string(LASTSOURCE_PREFERENCES, pub)
+ self.client.set_bool(START_INSEARCH_PREFERENCES,
+ start_insearch)
+ self.client.set_int(INITIAL_APP_WIDTH_PREFERENCES, width)
+ self.client.set_int(INITIAL_APP_HEIGHT_PREFERENCES, height)
+ self.client.set_int(INITIAL_APP_HPOS_PREFERENCES, hpos)
+ self.client.set_int(INITIAL_APP_VPOS_PREFERENCES, vpos)
+ except GError:
+ pass
+
+
+ def __save_state_changed(self, client, connection_id, entry, arguments):
+ self.save_state = entry.get_value().get_bool()
+
+ def __show_image_update_changed(self, client, connection_id, entry, arguments):
+ self.show_image_update = entry.get_value().get_bool()
+
+ def __show_install_changed(self, client, connection_id, entry, arguments):
+ self.show_install = entry.get_value().get_bool()
+
+ def __show_remove_changed(self, client, connection_id, entry, arguments):
+ self.show_remove = entry.get_value().get_bool()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/pmlogging.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,199 @@
+#!/usr/bin/python
+#
+# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+import sys
+import os
+import re
+try:
+ import gobject
+ import pango
+except ImportError:
+ sys.exit(1)
+import pkg.gui.misc as gui_misc
+
+REGEX_BOLD_MARKUP = re.compile(r'^<b>')
+REGEX_STRIP_MARKUP = re.compile(r'<.*?>')
+
+class PMLogging:
+ def __init__(self, builder, window_icon, is_normal_logging_setup=True):
+ self.is_normal_logging_setup = is_normal_logging_setup
+ self.w_view_log_dialog = builder.get_object("view_log_dialog")
+ self.w_view_log_dialog.set_icon(window_icon)
+ self.w_view_log_dialog.set_title(_("Logs"))
+ self.w_log_info_textview = builder.get_object("log_info_textview")
+ self.w_log_errors_textview = builder.get_object("log_errors_textview")
+
+ infobuffer = self.w_log_info_textview.get_buffer()
+ infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+ infobuffer = self.w_log_errors_textview.get_buffer()
+ infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+ self.w_log_close_button = builder.get_object("log_close_button")
+ self.w_log_clear_button = builder.get_object("log_clear_button")
+ self.w_log_help_button = builder.get_object("log_help_button")
+
+ def set_window_icon(self, window_icon):
+ self.w_view_log_dialog.set_icon(window_icon)
+
+ def setup_signals(self):
+ signals_table = [
+ (self.w_log_close_button, "clicked",
+ self.__on_log_close_button_clicked),
+ (self.w_log_clear_button, "clicked",
+ self.__on_log_clear_button_clicked),
+ (self.w_log_help_button, "clicked",
+ self.__on_log_help_button_clicked),
+ (self.w_view_log_dialog, "delete_event",
+ self.__on_log_dialog_delete_event)
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def set_modal_and_transient(self, parent_window):
+ gui_misc.set_modal_and_transient(self.w_view_log_dialog,
+ parent_window)
+
+ @staticmethod
+ def __on_log_help_button_clicked(widget):
+ gui_misc.display_help("gkiod")
+
+ def __on_log_dialog_delete_event(self, widget, event):
+ self.__on_log_close_button_clicked(None)
+ return True
+
+ def __on_log_close_button_clicked(self, widget):
+ self.w_view_log_dialog.hide()
+
+ def __on_log_clear_button_clicked(self, widget):
+ log_dir = gui_misc.get_log_dir()
+ ext = gui_misc.get_log_error_ext()
+ self.__clear_logs(log_dir, ext)
+ ext = gui_misc.get_log_info_ext()
+ self.__clear_logs(log_dir, ext)
+ gui_misc.shutdown_logging()
+ gui_misc.setup_logging()
+ self.log_activate()
+
+ def __clear_logs(self, log_dir, ext):
+ self.__clear_log(os.path.join(log_dir, gui_misc.get_pm_name() + ext))
+ self.__clear_log(os.path.join(log_dir, gui_misc.get_wi_name() + ext))
+ self.__clear_log(os.path.join(log_dir, gui_misc.get_um_name() + ext))
+
+ @staticmethod
+ def __clear_log(path):
+ try:
+ os.unlink(path)
+ except OSError:
+ pass
+
+ def log_activate(self):
+ textbuffer_err = self.w_log_errors_textview.get_buffer()
+ textbuffer_info = self.w_log_info_textview.get_buffer()
+ if self.is_normal_logging_setup:
+ textbuffer_err.set_text(_("Loading ..."))
+ textbuffer_info.set_text(_("Loading ..."))
+ else:
+ textbuffer_err.set_text("")
+ textbuffer_info.set_text("")
+ textiter = textbuffer_err.get_end_iter()
+ textbuffer_err.insert_with_tags_by_name(textiter,
+ _("Unable to setup log:\n"), "bold")
+ textbuffer_err.insert(textiter,
+ _("All errors and warnings will be logged to stderr"))
+ textiter = textbuffer_info.get_end_iter()
+ textbuffer_info.insert_with_tags_by_name(textiter,
+ _("Unable to setup log:\n"), "bold")
+ textbuffer_info.insert(textiter,
+ _("All info messages will be logged to stdout"))
+
+ self.w_log_close_button.grab_focus()
+ self.w_view_log_dialog.show()
+
+ if self.is_normal_logging_setup:
+ gobject.idle_add(self.__load_err_view_log)
+ gobject.idle_add(self.__load_info_view_log)
+
+ def __load_err_view_log(self):
+ textbuffer = self.w_log_errors_textview.get_buffer()
+ textbuffer.set_text("")
+ textiter = textbuffer.get_end_iter()
+ log_dir = gui_misc.get_log_dir()
+ log_err_ext = gui_misc.get_log_error_ext()
+ pm_err_log = os.path.join(log_dir, gui_misc.get_pm_name() + log_err_ext)
+ wi_err_log = os.path.join(log_dir, gui_misc.get_wi_name() + log_err_ext)
+ um_err_log = os.path.join(log_dir, gui_misc.get_um_name() + log_err_ext)
+
+ self.__write_to_view_log(um_err_log,
+ textbuffer, textiter, _("None: ") + gui_misc.get_um_name() + "\n")
+ self.__write_to_view_log(wi_err_log,
+ textbuffer, textiter, _("None: ") + gui_misc.get_wi_name() + "\n")
+ self.__write_to_view_log(pm_err_log,
+ textbuffer, textiter, _("None: ") + gui_misc.get_pm_name() + "\n")
+ gobject.idle_add(self.w_log_errors_textview.scroll_to_iter, textiter,
+ 0.0)
+
+ def __load_info_view_log(self):
+ textbuffer = self.w_log_info_textview.get_buffer()
+ textbuffer.set_text("")
+ textiter = textbuffer.get_end_iter()
+ log_dir = gui_misc.get_log_dir()
+ log_info_ext = gui_misc.get_log_info_ext()
+ pm_info_log = os.path.join(log_dir, gui_misc.get_pm_name() + log_info_ext)
+ wi_info_log = os.path.join(log_dir, gui_misc.get_wi_name() + log_info_ext)
+ um_info_log = os.path.join(log_dir, gui_misc.get_um_name() + log_info_ext)
+
+ self.__write_to_view_log(um_info_log,
+ textbuffer, textiter, _("None: ") + gui_misc.get_um_name() + "\n")
+ self.__write_to_view_log(wi_info_log,
+ textbuffer, textiter, _("None: ") + gui_misc.get_wi_name() + "\n")
+ self.__write_to_view_log(pm_info_log,
+ textbuffer, textiter, _("None: ") + gui_misc.get_pm_name() + "\n")
+ gobject.idle_add(self.w_log_info_textview.scroll_to_iter, textiter, 0.0)
+
+ @staticmethod
+ def __write_to_view_log(path, textbuffer, textiter, nomessages):
+ infile = None
+ try:
+ infile = open(path, "r")
+ except IOError:
+ textbuffer.insert_with_tags_by_name(textiter, nomessages, "bold")
+ return
+ if infile == None:
+ textbuffer.insert_with_tags_by_name(textiter, nomessages, "bold")
+ return
+
+ lines = infile.readlines()
+ if len(lines) == 0:
+ textbuffer.insert_with_tags_by_name(textiter, nomessages, "bold")
+ return
+ for line in lines:
+ if re.match(REGEX_BOLD_MARKUP, line):
+ line = re.sub(REGEX_STRIP_MARKUP, "", line)
+ textbuffer.insert_with_tags_by_name(textiter, line,
+ "bold")
+ else:
+ textbuffer.insert(textiter, line)
+ try:
+ infile.close()
+ except IOError:
+ pass
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/preferences.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,824 @@
+#!/usr/bin/python
+#
+# 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 (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+#
+
+import g11nsvc as g11nsvc
+import re
+import sys
+try:
+ import gobject
+ gobject.threads_init()
+ import gtk
+ import pygtk
+ pygtk.require("2.0")
+except ImportError:
+ sys.exit(1)
+import pkg.client.api_errors as api_errors
+import pkg.client.api as api
+import pkg.gui.misc as gui_misc
+import pkg.gui.enumerations as enumerations
+
+PREFERENCES_NOTEBOOK_GENERAL_PAGE = 0
+PREFERENCES_NOTEBOOK_SIG_POL_PAGE = 1
+PREFERENCES_NOTEBOOK_LANGUAGES_PAGE = 2
+GDK_2BUTTON_PRESS = 5 # gtk.gdk._2BUTTON_PRESS causes pylint warning
+LOCALE_PREFIX = "facet.locale."
+LANG_STAR_SUFFIX = "_*"
+
+ALL_LOCALES = "facet.locale.*"
+ALL_DEVEL = "facet.devel"
+ALL_DOC = "facet.doc.*"
+
+LANG_MATCH = re.compile(r'facet\.locale\.([a-z]{2,3})$')
+LANG_STAR_MATCH = re.compile(r'facet\.locale\.([a-z]{2,3})_\*$')
+LOCALE_MATCH = re.compile(r'facet\.locale\.([a-z]{2,3}_[A-Z]{2,3}.*$)')
+
+SYSTEM_G11LOCALE_MATCH = re.compile(r'^([a-z]{2,3}_[A-Z]{2,3})\.*(.*)$')
+SYSTEM_FACETLOCALE_MATCH = re.compile(r'([a-z]{2,3}_[A-Z]{2,3})\(*(.*?)\)*$')
+
+debug = False
+
+class Preferences:
+ def __init__(self, parent, builder, window_icon, gconf):
+ self.gconf = gconf
+ self.parent = parent
+ self.w_preferencesdialog = \
+ builder.get_object("preferencesdialog")
+ self.w_preferencesdialog.set_icon(window_icon)
+ w_startup_label = \
+ builder.get_object("startup_label")
+ w_startup_label.hide()
+ w_startup_hbox = \
+ builder.get_object("startup_hbox")
+ w_startup_hbox.hide()
+ self.w_startpage_checkbutton = \
+ builder.get_object("startpage_checkbutton")
+ self.w_exit_checkbutton = \
+ builder.get_object("exit_checkbutton")
+ self.w_confirm_updateall_checkbutton = \
+ builder.get_object("confirm_updateall_checkbutton")
+ self.w_confirm_install_checkbutton = \
+ builder.get_object("confirm_install_checkbutton")
+ self.w_confirm_remove_checkbutton = \
+ builder.get_object("confirm_remove_checkbutton")
+ self.w_help_button = builder.get_object("preferenceshelp")
+ self.w_close_button = builder.get_object("preferencesclose")
+ self.w_cancel_button = builder.get_object("preferencescancel")
+ self.w_languages_all_radiobutton = \
+ builder.get_object("lang_install_all_radiobutton")
+ self.w_languages_only_radiobutton = \
+ builder.get_object("lang_install_only_radiobutton")
+ self.w_feature_devel_checkbutton = \
+ builder.get_object("feature_devel_checkbutton")
+ self.w_feature_doc_checkbutton = \
+ builder.get_object("feature_doc_checkbutton")
+
+ self.w_locales_treeview = \
+ builder.get_object("languages_treeview")
+ self.w_preferences_notebook = builder.get_object(
+ "preferences_notebook")
+ self.w_languages_treeview = builder.get_object(
+ "languages_treeview")
+
+ self.w_gsig_ignored_radiobutton = builder.get_object(
+ "gsig_ignored_radiobutton")
+ self.w_gsig_optional_radiobutton = builder.get_object(
+ "gsig_optional_but_valid_radiobutton")
+ self.w_gsig_valid_radiobutton = builder.get_object(
+ "gsig_valid_radiobutton")
+ self.w_gsig_name_radiobutton = builder.get_object(
+ "gsig_name_radiobutton")
+ self.w_gsig_name_entry = builder.get_object(
+ "gsig_name_entry")
+ self.w_gsig_cert_names_vbox = builder.get_object(
+ "gsig_cert_names_vbox")
+
+ self.orig_gsig_policy = None
+
+ self.watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
+ self.orig_lang_locale_count_dict = {}
+ self.orig_facets_dict = {}
+ self.orig_facet_lang_dict = {}
+ self.orig_facet_lang_star_dict = {}
+ self.orig_facet_locale_dict = {}
+ self.facet_g11_locales_dict = {}
+ self.facetlocales_list = []
+ self.facets_to_set = {}
+ self.locales_setup = False
+ self.locales_treeview_selection = []
+ self.locales_list = self.__get_locales_liststore()
+ self.__init_locales_tree_view(self.locales_list)
+ self.__init_locales_list()
+
+ def show_signature_policy(self):
+ self.w_preferences_notebook.set_current_page(
+ PREFERENCES_NOTEBOOK_SIG_POL_PAGE)
+ self.w_preferencesdialog.show()
+
+ def set_window_icon(self, window_icon):
+ self.w_preferencesdialog.set_icon(window_icon)
+
+ def setup_signals(self):
+ signals_table = [
+ (self.w_preferencesdialog, "show",
+ self.__on_preferencesdialog_show),
+ (self.w_preferencesdialog, "delete_event",
+ self.__on_preferencesdialog_delete_event),
+ (self.w_help_button, "clicked",
+ self.__on_preferenceshelp_clicked),
+ (self.w_close_button, "clicked",
+ self.__on_preferencesclose_clicked),
+ (self.w_cancel_button, "clicked",
+ self.__on_preferencescancel_clicked),
+ (self.w_languages_all_radiobutton, "toggled",
+ self.__on_languages_all_radiobutton_toggled),
+ (self.w_preferences_notebook, "switch_page",
+ self.__on_notebook_change),
+ (self.w_languages_treeview, "button_press_event",
+ self.__on_languages_treeview_button_and_key_events),
+ (self.w_languages_treeview, "key_press_event",
+ self.__on_languages_treeview_button_and_key_events),
+
+ (self.w_gsig_ignored_radiobutton, "toggled",
+ self.__on_gsig_radiobutton_toggled),
+ (self.w_gsig_optional_radiobutton, "toggled",
+ self.__on_gsig_radiobutton_toggled),
+ (self.w_gsig_valid_radiobutton, "toggled",
+ self.__on_gsig_radiobutton_toggled),
+ (self.w_gsig_name_radiobutton, "toggled",
+ self.__on_gsig_radiobutton_toggled),
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def __on_gsig_radiobutton_toggled(self, widget):
+ self.w_gsig_cert_names_vbox.set_sensitive(
+ self.w_gsig_name_radiobutton.get_active())
+
+ def __update_img_sig_policy_prop(self, set_props):
+ try:
+ self.parent.get_api_object().img.set_properties(set_props)
+ except api_errors.ApiException, e:
+ error_msg = str(e)
+ msg_title = _("Preferences Error")
+ msg_type = gtk.MESSAGE_ERROR
+ gui_misc.error_occurred(None, error_msg, msg_title, msg_type)
+ return False
+ return True
+
+ def __update_img_sig_policy(self):
+ orig = self.orig_gsig_policy
+ ignore = self.w_gsig_ignored_radiobutton.get_active()
+ verify = self.w_gsig_optional_radiobutton.get_active()
+ req_sigs = self.w_gsig_valid_radiobutton.get_active()
+ req_names = self.w_gsig_name_radiobutton.get_active()
+ names = gui_misc.fetch_signature_policy_names_from_textfield(
+ self.w_gsig_name_entry.get_text())
+ if req_names and len(names) == 0:
+ return False
+ set_props = gui_misc.setup_signature_policy_properties(ignore,
+ verify, req_sigs, req_names, names, orig)
+ if len(set_props) > 0:
+ return self.__update_img_sig_policy_prop(set_props)
+ return True
+
+ def __prepare_img_signature_policy(self):
+ if self.orig_gsig_policy:
+ return
+ sig_policy = self.__fetch_img_signature_policy()
+ self.orig_gsig_policy = sig_policy
+ self.w_gsig_ignored_radiobutton.set_active(
+ sig_policy[gui_misc.SIG_POLICY_IGNORE])
+ self.w_gsig_optional_radiobutton.set_active(
+ sig_policy[gui_misc.SIG_POLICY_VERIFY])
+ self.w_gsig_valid_radiobutton.set_active(
+ sig_policy[gui_misc.SIG_POLICY_REQUIRE_SIGNATURES])
+ self.w_gsig_cert_names_vbox.set_sensitive(False)
+
+ if sig_policy[gui_misc.SIG_POLICY_REQUIRE_NAMES]:
+ self.w_gsig_name_radiobutton.set_active(True)
+ self.w_gsig_cert_names_vbox.set_sensitive(True)
+
+ names = sig_policy[gui_misc.PROP_SIGNATURE_REQUIRED_NAMES]
+ gui_misc.set_signature_policy_names_for_textfield(
+ self.w_gsig_name_entry, names)
+
+ def __fetch_img_signature_policy(self):
+ prop_sig_pol = self.parent.get_api_object().img.get_property(
+ gui_misc.PROP_SIGNATURE_POLICY)
+ prop_sig_req_names = self.parent.get_api_object().img.get_property(
+ gui_misc.PROP_SIGNATURE_REQUIRED_NAMES)
+ return gui_misc.create_sig_policy_from_property(
+ prop_sig_pol, prop_sig_req_names)
+
+ def __on_notebook_change(self, widget, event, pagenum):
+ if pagenum == PREFERENCES_NOTEBOOK_LANGUAGES_PAGE:
+ self.w_preferencesdialog.window.set_cursor(
+ self.watch )
+ gobject.idle_add(self.__prepare_locales)
+ elif pagenum == PREFERENCES_NOTEBOOK_SIG_POL_PAGE:
+ gobject.idle_add(self.__prepare_img_signature_policy)
+
+ @staticmethod
+ def __get_locales_liststore():
+ return gtk.ListStore(
+ gobject.TYPE_STRING, # enumerations.LOCALE_NAME
+ # - <language> (territory)
+ gobject.TYPE_STRING, # enumerations.LOCALE_LANGUAGE
+ # - Display <language> name
+ gobject.TYPE_STRING, # enumerations.LOCALE_TERRITORY
+ # - Display <territory> name
+ gobject.TYPE_STRING, # enumerations.LOCALE
+ # - <language>_<territory>(code)
+ gobject.TYPE_BOOLEAN, # enumerations.LOCALE_SELECTED
+ )
+
+ def __select_column_clicked(self, data):
+ sort_model = self.w_locales_treeview.get_model()
+ model = sort_model.get_model()
+ iter_next = sort_model.get_iter_first()
+ none_selected = True
+ all_selected = True
+ list_of_paths = []
+ while iter_next != None:
+ sort_path = sort_model.get_path(iter_next)
+ path = sort_model.convert_path_to_child_path(sort_path)
+ list_of_paths.append(path)
+ app_iter = sort_model.convert_iter_to_child_iter(None,
+ iter_next)
+ val = model.get_value(app_iter,
+ enumerations.LOCALE_SELECTED)
+ if val:
+ none_selected = False
+ else:
+ all_selected = False
+ iter_next = sort_model.iter_next(iter_next)
+
+ some_selected = not all_selected and not none_selected
+ select_all = none_selected or some_selected
+ for path in list_of_paths:
+ app_iter = model.get_iter(path)
+ val = model.get_value(app_iter,
+ enumerations.LOCALE_SELECTED)
+ if select_all and not val:
+ model.set_value(app_iter,
+ enumerations.LOCALE_SELECTED, True)
+ elif not select_all and val:
+ model.set_value(app_iter,
+ enumerations.LOCALE_SELECTED, False)
+
+ @staticmethod
+ def __sort_func(treemodel, iter1, iter2, column):
+ col_val1 = treemodel.get_value(iter1, column)
+ col_val2 = treemodel.get_value(iter2, column)
+ ret = cmp(col_val1, col_val2)
+ if ret != 0:
+ return ret
+ if column == enumerations.LOCALE_LANGUAGE:
+ ter1 = treemodel.get_value(iter1,
+ enumerations.LOCALE_TERRITORY)
+ ter2 = treemodel.get_value(iter2,
+ enumerations.LOCALE_TERRITORY)
+ ret = cmp(ter1, ter2)
+ elif column == enumerations.LOCALE_TERRITORY:
+ lang1 = treemodel.get_value(iter1,
+ enumerations.LOCALE_LANGUAGE)
+ lang2 = treemodel.get_value(iter2,
+ enumerations.LOCALE_LANGUAGE)
+ ret = cmp(lang1, lang2)
+ return ret
+
+ def __init_locales_tree_view(self, locales_list):
+ locales_sort_model = gtk.TreeModelSort(locales_list)
+ locales_sort_model.set_sort_column_id(enumerations.LOCALE_LANGUAGE,
+ gtk.SORT_ASCENDING)
+
+ locales_sort_model.set_sort_func(enumerations.LOCALE_LANGUAGE,
+ self.__sort_func,
+ enumerations.LOCALE_LANGUAGE)
+ locales_sort_model.set_sort_func(enumerations.LOCALE_TERRITORY,
+ self.__sort_func,
+ enumerations.LOCALE_TERRITORY)
+
+ # Selected column - Not sorted
+ toggle_renderer = gtk.CellRendererToggle()
+ column = gtk.TreeViewColumn("",
+ toggle_renderer, active = enumerations.LOCALE_SELECTED)
+ column.set_expand(False)
+ column.set_clickable(True)
+ column.connect('clicked', self.__select_column_clicked)
+ select_image = self.parent.get_theme_selection_coloumn_image()
+ column.set_widget(select_image)
+ self.w_locales_treeview.append_column(column)
+
+ # Language column - sort using custom __sort_func()
+ lang_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_("Language"),
+ lang_renderer, text = enumerations.LOCALE_LANGUAGE)
+ column.set_expand(True)
+ column.set_sort_column_id(enumerations.LOCALE_LANGUAGE)
+ column.set_sort_indicator(True)
+ self.w_locales_treeview.append_column(column)
+
+ # Territory column - sort using custom __sort_func()
+ ter_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_("Territory"),
+ ter_renderer, text = enumerations.LOCALE_TERRITORY)
+ column.set_expand(True)
+ column.set_sort_column_id(enumerations.LOCALE_TERRITORY)
+ column.set_sort_indicator(True)
+ self.w_locales_treeview.append_column(column)
+
+ self.w_locales_treeview.get_selection().set_mode(
+ gtk.SELECTION_MULTIPLE)
+ self.w_locales_treeview.get_selection().connect('changed',
+ self.__on_languages_treeview_changed)
+ self.w_locales_treeview.set_model(locales_sort_model)
+
+ def __init_locales_list(self):
+ sorted_model = self.w_locales_treeview.get_model()
+ self.w_locales_treeview.set_model(None)
+ if not sorted_model:
+ return
+ model = sorted_model.get_model()
+ model.clear()
+ model.insert(0, ["", _("Loading ..."), "", "", False])
+ self.w_locales_treeview.set_model(sorted_model)
+
+ def __prepare_locales(self):
+ try:
+ if self.locales_setup:
+ return
+ self.__prepare_locales_list()
+ finally:
+ self.w_preferencesdialog.window.set_cursor(None)
+
+ def __api_get_facets(self):
+ facets = {}
+ try:
+ # XXX facets should be accessible through pkg.client.api
+ facets = self.parent.get_api_object().img.get_facets()
+ except api_errors.ApiException, ex:
+ err = str(ex)
+ self.w_preferencesdialog.hide()
+ gobject.idle_add(self.parent.error_occurred, err,
+ None, gtk.MESSAGE_INFO )
+ return facets
+
+ @staticmethod
+ def __strip_g11system_codeset(g11locale):
+ strippedlocale = ""
+ m = re.match(SYSTEM_G11LOCALE_MATCH, g11locale)
+ #Note: for now strip out system locale (code@locale variant)
+ #ignore group(2)
+ if m != None and len(m.groups()) == 2:
+ strippedlocale = m.group(1)
+ return strippedlocale
+
+ @staticmethod
+ def __facetlocale_to_g11locale(facetlocale):
+ g11locale = ""
+ m = re.match(SYSTEM_FACETLOCALE_MATCH, facetlocale)
+ if m != None and len(m.groups()) == 2:
+ g11locale = m.group(1)
+ if m.group(2) != '':
+ g11locale += "." + m.group(2)
+ return g11locale
+
+ def __prepare_locales_list(self):
+ sorted_model = self.w_locales_treeview.get_model()
+ self.w_locales_treeview.set_model(None)
+ if not sorted_model:
+ return
+ # Reset api so we have up to date facet list
+ if not self.parent.do_api_reset():
+ #do_api_reset fails then it will inform the user
+ return
+
+ model = sorted_model.get_model()
+ self.orig_facets_dict.clear()
+ self.orig_facets_dict = self.__api_get_facets()
+ self.__setup_optional_components_tab(self.orig_facets_dict)
+ self.__process_orig_facets(self.orig_facets_dict)
+
+ # Count selected facet locales for each lang
+ self.orig_lang_locale_count_dict.clear()
+ for locale, selected in self.orig_facet_locale_dict.items():
+ lang = locale.split("_")[0]
+ if not self.orig_lang_locale_count_dict.has_key(lang):
+ self.orig_lang_locale_count_dict[lang] = 0
+ if selected:
+ self.orig_lang_locale_count_dict[lang] += 1
+
+ # Setup locales:
+ # Try to fetch available locales from system/locale package
+ # using __get_system_locales()
+ if self.facet_g11_locales_dict == None or \
+ len(self.facet_g11_locales_dict) == 0:
+ facetlocales_list = self.__get_system_locales()
+ if facetlocales_list == None:
+ return
+ for facetlocale in facetlocales_list:
+ g11locale = self.__facetlocale_to_g11locale(
+ facetlocale)
+ self.facet_g11_locales_dict[facetlocale] = g11locale
+ # Setup locales:
+ # If not available fall back and get the locales installed on
+ # the system using loc_pop.get_valid_locales() and strip any codeset
+ if self.facet_g11_locales_dict == None or \
+ len(self.facet_g11_locales_dict) == 0:
+ # pylint: disable-msg=E1101
+ loc_pop = g11nsvc.G11NSvcLocalePopulate()
+ g11locales_list = loc_pop.get_valid_locales()
+ for g11locale in g11locales_list:
+ strippedlocale = self.__strip_g11system_codeset(
+ g11locale)
+ facetlocale = strippedlocale
+ self.facet_g11_locales_dict[facetlocale] = \
+ strippedlocale
+ # pylint: disable-msg=E1101
+ loc_ops = g11nsvc.G11NSvcLocaleOperations(
+ self.facet_g11_locales_dict.values())
+
+ # Process facet locales
+ locale_list = []
+ for facetlocale, g11locale in self.facet_g11_locales_dict.items():
+ if g11locale == "C" or g11locale == "POSIX":
+ continue
+ locale_name = loc_ops.get_locale_desc(g11locale)
+ if locale_name == None or locale_name == "" :
+ continue
+ locale_language = loc_ops.get_language_desc(g11locale)
+ locale_territory = loc_ops.get_territory_desc(g11locale)
+ locale = facetlocale
+ is_latin = g11locale.endswith("latin")
+ if is_latin:
+ locale_territory += _(" [latin]")
+ lang = locale.split("_")[0]
+
+ sel_count = 0
+ if self.orig_lang_locale_count_dict.has_key(lang):
+ sel_count = self.orig_lang_locale_count_dict[lang]
+
+ # Precedence order:
+ # <lang>_<ter>: <lang>_* e.g. nl_BE: nl_*
+ selected = False
+ if sel_count == 0:
+ if self.orig_facet_lang_star_dict.has_key(
+ lang):
+ selected = \
+ self.orig_facet_lang_star_dict[lang]
+ elif self.orig_facet_locale_dict.has_key(locale):
+ selected = self.orig_facet_locale_dict[
+ locale]
+
+ # locale row contains:
+ #
+ # locale_name = <language> (territory)
+ # locale_language = Display <language> name
+ # locale_territory = Display <territory> name
+ # facetlocale = <language>_<territory>(<codeset>)
+ # selected = selected
+ locale_row = [locale_name, locale_language,
+ locale_territory, facetlocale, selected]
+ locale_list.append(locale_row)
+ # Sort and setup model
+ model.clear()
+ i = 0
+ locale_list.sort(key=lambda locale_list: locale_list[
+ enumerations.LOCALE_LANGUAGE])
+ for locale_row in locale_list:
+ model.insert(i, locale_row)
+ i += 1
+ self.w_locales_treeview.set_model(sorted_model)
+
+ if debug:
+ print "DEBUG loaded facets: ", \
+ self.orig_facet_lang_dict, \
+ self.orig_facet_lang_star_dict, \
+ self.orig_facet_locale_dict
+ self.locales_setup = True
+
+ def __get_system_locales(self):
+ try:
+ api_o = self.parent.get_api_object()
+ res = api_o.get_pkg_list(
+ pkg_list = api.ImageInterface.LIST_INSTALLED,
+ patterns = ['system/locale'],
+ repos=[],
+ raise_unmatched=False, return_fmris=True,
+ variants=True )
+
+ manifest = None
+ for entry in res:
+ manifest = api_o.get_manifest(entry[0],
+ all_variants=True, repos=[] )
+ break
+ facets = None
+ if manifest != None:
+ manifest.gen_actions(())
+ facets = manifest.facets
+ if debug and facets != None:
+ print "DEBUG facets from system/locale:", facets
+
+ facetlocales = []
+ if facets == None:
+ return facetlocales
+
+ for facet_key in facets.keys():
+ if not facet_key.startswith(LOCALE_PREFIX):
+ continue
+ m = re.match(LOCALE_MATCH, facet_key)
+ if m != None and len(m.groups()) == 1:
+ locale = m.group(1)
+ facetlocales.append(locale)
+ return facetlocales
+
+ except api_errors.ApiException, ex:
+ err = str(ex)
+ self.w_preferencesdialog.hide()
+ gobject.idle_add(self.parent.error_occurred, err,
+ None, gtk.MESSAGE_INFO )
+ return None
+
+ def __setup_optional_components_tab(self, facets):
+ install_all = self.__is_install_all(facets, ALL_LOCALES)
+ self.w_languages_all_radiobutton.set_active(install_all)
+ self.w_languages_only_radiobutton.set_active(not install_all)
+ self.w_locales_treeview.set_sensitive(not install_all)
+
+ install_devel = self.__is_install_all(facets, ALL_DEVEL)
+ self.w_feature_devel_checkbutton.set_active(install_devel)
+ install_doc = self.__is_install_all(facets, ALL_DOC)
+ self.w_feature_doc_checkbutton.set_active(install_doc)
+
+ @staticmethod
+ def __is_install_all(facets, component_type):
+ if facets != None and facets.has_key(component_type):
+ return facets[component_type]
+ # Default to True if key not present
+ return True
+
+ def __process_orig_facets(self, facets):
+ if debug:
+ print "DEBUG orig facets", facets
+
+ self.orig_facet_lang_dict.clear()
+ self.orig_facet_lang_star_dict.clear()
+ self.orig_facet_locale_dict.clear()
+
+ # Process facets
+ for facet_key in facets.keys():
+ val = facets[facet_key]
+ if not facet_key.startswith(LOCALE_PREFIX):
+ continue
+ if facet_key == ALL_LOCALES:
+ self.orig_facet_lang_dict[ALL_LOCALES] = val
+ continue
+ m = re.match(LANG_MATCH, facet_key)
+ if m != None and len(m.groups()) == 1:
+ lang = m.group(1)
+ self.orig_facet_lang_dict[lang] = val
+ continue
+ m = re.match(LANG_STAR_MATCH, facet_key)
+ if m != None and len(m.groups()) == 1:
+ lang = m.group(1)
+ self.orig_facet_lang_star_dict[lang] = val
+ continue
+ m = re.match(LOCALE_MATCH, facet_key)
+ if m != None and len(m.groups()) == 1:
+ locale = m.group(1)
+ self.orig_facet_locale_dict[locale] = val
+
+ def __dump_locales_list(self):
+ self.facets_to_set = self.__api_get_facets()
+ install_all = self.w_languages_all_radiobutton.get_active()
+ self.facets_to_set[ALL_LOCALES] = install_all
+
+ if install_all:
+ return
+
+ sorted_model = self.w_locales_treeview.get_model()
+ if not sorted_model:
+ return
+ model = sorted_model.get_model()
+
+ lang_locale_dict = {}
+ lang_locale_count_dict = {}
+ for row in model:
+ selected = row[enumerations.LOCALE_SELECTED]
+ locale = row[enumerations.LOCALE]
+ lang = locale.split("_")[0]
+
+ if not lang_locale_dict.has_key(lang):
+ lang_locale_dict[lang] = {}
+ lang_locale_dict[lang][locale] = selected
+ if not lang_locale_count_dict.has_key(lang):
+ lang_locale_count_dict[lang] = 0
+ if selected:
+ lang_locale_count_dict[lang] += 1
+
+ for lang, locales in lang_locale_dict.items():
+ sel_count = lang_locale_count_dict[lang]
+ self.__process_locales_to_set(lang, locales, sel_count)
+
+ if debug:
+ print "DEBUG facets to set:", self.facets_to_set
+
+ def __dump_optional_components(self):
+ install_devel = self.w_feature_devel_checkbutton.get_active()
+ install_doc = self.w_feature_doc_checkbutton.get_active()
+
+ if install_devel == False:
+ self.facets_to_set[ALL_DEVEL] = False
+ elif self.facets_to_set.has_key(ALL_DEVEL):
+ del self.facets_to_set[ALL_DEVEL]
+
+ if install_doc == False:
+ self.facets_to_set[ALL_DOC] = False
+ elif self.facets_to_set.has_key(ALL_DOC):
+ del self.facets_to_set[ALL_DOC]
+
+ def __process_locales_to_set(self, lang, locales, sel_count):
+ locales_count = len(locales)
+ if locales_count == 0:
+ return
+
+ # All Selected
+ if sel_count == locales_count:
+ self.facets_to_set[LOCALE_PREFIX + lang + \
+ LANG_STAR_SUFFIX] = True
+ self.facets_to_set[LOCALE_PREFIX + lang] = True
+ for item in locales.items():
+ key = LOCALE_PREFIX + item[0]
+ if self.facets_to_set.has_key(key):
+ del self.facets_to_set[key]
+ # None Selected
+ elif sel_count == 0:
+ has_orig_star_key = \
+ self.orig_facet_lang_star_dict.has_key(lang)
+ has_orig_lang_count_key = \
+ self.orig_lang_locale_count_dict.has_key(lang)
+ # Has the user made a change to get us to the None selected state?
+ # If not then just ignore.
+ if (has_orig_star_key and
+ self.orig_facet_lang_star_dict[lang]) or \
+ (has_orig_lang_count_key and
+ self.orig_lang_locale_count_dict[lang] > 0):
+ if self.facets_to_set.has_key(LOCALE_PREFIX +
+ lang + LANG_STAR_SUFFIX):
+ del self.facets_to_set[LOCALE_PREFIX +
+ lang + LANG_STAR_SUFFIX]
+ if self.facets_to_set.has_key(LOCALE_PREFIX +
+ lang):
+ del self.facets_to_set[LOCALE_PREFIX +
+ lang]
+
+ for item in locales.items():
+ key = LOCALE_PREFIX + item[0]
+ if self.facets_to_set.has_key(key):
+ del self.facets_to_set[key]
+ # Some Selected
+ else:
+ self.facets_to_set[LOCALE_PREFIX + lang] = True
+ star_key = LOCALE_PREFIX + lang + LANG_STAR_SUFFIX
+ if self.facets_to_set.has_key(star_key):
+ del self.facets_to_set[star_key]
+ for locale, val in locales.items():
+ key = LOCALE_PREFIX + locale
+ if val:
+ self.facets_to_set[key] = val
+ else:
+ if self.facets_to_set.has_key(key):
+ del self.facets_to_set[key]
+
+ def __on_languages_treeview_button_and_key_events(self,
+ treeview, event):
+ if event.type == GDK_2BUTTON_PRESS:
+ self.__enable_disable()
+
+ def __on_languages_treeview_changed(self, treeselection):
+ selection = treeselection.get_selected_rows()
+ pathlist = selection[1]
+ self.locales_treeview_selection = pathlist
+ if pathlist != None and len(pathlist) == 1:
+ self.__enable_disable()
+
+ def __enable_disable(self):
+ sorted_model = self.w_locales_treeview.get_model()
+ if sorted_model == None:
+ return
+ model = sorted_model.get_model()
+ if len(self.locales_treeview_selection) == 0:
+ return
+
+ path = self.locales_treeview_selection[0]
+ child_path = sorted_model.convert_path_to_child_path(path)
+ itr = model.get_iter(child_path)
+ selected = model.get_value(itr, enumerations.LOCALE_SELECTED)
+ model.set_value(itr, enumerations.LOCALE_SELECTED, not selected)
+
+ for path in self.locales_treeview_selection[1:]:
+ child_path = sorted_model.convert_path_to_child_path(path)
+ itr = model.get_iter(child_path)
+ model.set_value(itr, enumerations.LOCALE_SELECTED,
+ not selected)
+
+ def set_modal_and_transient(self, parent_window):
+ gui_misc.set_modal_and_transient(self.w_preferencesdialog,
+ parent_window)
+
+ def __on_preferencesdialog_delete_event(self, widget, event):
+ self.__on_preferencesclose_clicked(None)
+ return True
+
+ def __on_preferencesdialog_show(self, widget):
+ self.orig_gsig_policy = {}
+ self.locales_setup = False
+
+ pagenum = self.w_preferences_notebook.get_current_page()
+ if pagenum == PREFERENCES_NOTEBOOK_LANGUAGES_PAGE:
+ self.w_preferencesdialog.window.set_cursor(self.watch)
+ gobject.idle_add(self.__prepare_locales)
+ elif pagenum == PREFERENCES_NOTEBOOK_SIG_POL_PAGE:
+ gobject.idle_add(self.__prepare_img_signature_policy)
+ return True
+
+ def __on_preferencescancel_clicked(self, widget):
+ self.w_preferencesdialog.hide()
+
+ def __on_preferencesclose_clicked(self, widget):
+ error_dialog_title = _("Preferences")
+ text = self.w_gsig_name_entry.get_text()
+ req_names = self.w_gsig_name_radiobutton.get_active()
+ if not gui_misc.check_sig_required_names_policy(text,
+ req_names, error_dialog_title):
+ return
+ if self.orig_gsig_policy and not self.__update_img_sig_policy():
+ return
+ self.__dump_locales_list()
+ self.__dump_optional_components()
+ self.w_preferencesdialog.hide()
+ ignore_all_default = len(self.orig_facets_dict) == 0 and \
+ len(self.facets_to_set) == 1 \
+ and self.facets_to_set.has_key(ALL_LOCALES) and \
+ self.facets_to_set[ALL_LOCALES] == True
+ if not ignore_all_default and self.orig_facets_dict != {} and \
+ self.orig_facets_dict != self.facets_to_set:
+ self.parent.update_facets(self.facets_to_set)
+ self.gconf.set_show_startpage(
+ self.w_startpage_checkbutton.get_active())
+ self.gconf.set_save_state(
+ self.w_exit_checkbutton.get_active())
+ self.gconf.set_show_image_update(
+ self.w_confirm_updateall_checkbutton.get_active())
+ self.gconf.set_show_install(
+ self.w_confirm_install_checkbutton.get_active())
+ self.gconf.set_show_remove(
+ self.w_confirm_remove_checkbutton.get_active())
+
+ def __on_preferenceshelp_clicked(self, widget):
+ pagenum = self.w_preferences_notebook.get_current_page()
+ if pagenum == PREFERENCES_NOTEBOOK_SIG_POL_PAGE:
+ tag = "img-sig-policy"
+ else:
+ tag = "pkg-mgr-prefs"
+ gui_misc.display_help(tag)
+
+ def __on_languages_all_radiobutton_toggled(self, widget):
+ self.w_locales_treeview.set_sensitive(
+ not self.w_languages_all_radiobutton.get_active())
+
+ def activate(self):
+ self.w_startpage_checkbutton.set_active(
+ self.gconf.show_startpage)
+ self.w_exit_checkbutton.set_active(self.gconf.save_state)
+ self.w_confirm_updateall_checkbutton.set_active(
+ self.gconf.show_image_update)
+ self.w_confirm_install_checkbutton.set_active(
+ self.gconf.show_install)
+ self.w_confirm_remove_checkbutton.set_active(
+ self.gconf.show_remove)
+ self.__setup_optional_components_tab(self.__api_get_facets())
+ self.w_preferencesdialog.show()
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/progress.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,221 @@
+#!/usr/bin/python
+#
+# 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+MIN_ELEMENTS_BOUNCE = 5 # During indexing the progress will be progressive if
+ # the number of indexing elements is greater then this,
+ # otherwise it will bounce
+
+from pkg.client.progress import NullProgressTracker
+
+class GuiProgressTracker(NullProgressTracker):
+
+ def __init__(self, indent = False):
+ NullProgressTracker.__init__(self)
+ self.prev_pkg = None
+ self.act_phase_last = None
+ self.ind_started = False
+ self.item_started = False
+ self.indent = indent
+
+ def cat_output_start(self):
+ if self.indent:
+ self.update_details_text(_("Retrieving catalog '%s'...\n") % \
+ self.cat_cur_catalog, "level1")
+ else:
+ self.update_details_text(_("Retrieving catalog '%s'...\n") % \
+ self.cat_cur_catalog)
+ return
+
+ def cat_output_done(self):
+ return
+
+ def cache_cats_output_start(self):
+ if self.indent:
+ self.update_details_text(_("Caching catalogs ...\n"), "level1")
+ else:
+ self.update_details_text(_("Caching catalogs ...\n"))
+ return
+
+ def cache_cats_output_done(self):
+ return
+
+ def load_cat_cache_output_start(self):
+ if self.indent:
+ self.update_details_text(_("Loading catalog cache ...\n"),
+ "level1")
+ else:
+ self.update_details_text(_("Loading catalog cache ...\n"))
+ return
+
+ def load_cat_cache_output_done(self):
+ return
+
+ def refresh_output_start(self):
+ return
+
+ def refresh_output_progress(self):
+ if self.indent:
+ self.update_details_text(
+ _("Refreshing catalog %s\n") % self.refresh_cur_pub, "level1")
+ else:
+ self.update_details_text(
+ _("Refreshing catalog %s\n") % self.refresh_cur_pub)
+ return
+
+ def refresh_output_done(self):
+ if self.indent:
+ self.update_details_text(
+ _("Finished refreshing catalog %s\n") % self.refresh_cur_pub,
+ "level1")
+ else:
+ self.update_details_text(
+ _("Finished refreshing catalog %s\n") % self.refresh_cur_pub)
+ return
+
+ def eval_output_start(self):
+ return
+
+ def eval_output_progress(self):
+ '''Called by progress tracker each time some package was evaluated. The
+ call is being done by calling progress tracker evaluate_progress()
+ function'''
+ if self.prev_pkg != self.eval_cur_fmri:
+ self.prev_pkg = self.eval_cur_fmri
+ text = _("Evaluating: %s") % self.eval_cur_fmri.get_name()
+ self.update_label_text(text)
+ self.reset_label_text_after_delay()
+
+ def eval_output_done(self):
+ return
+
+ def ver_output(self):
+ return
+
+ def ver_output_error(self, actname, errors):
+ return
+
+ def ver_output_done(self):
+ return
+
+ def dl_output(self):
+ self.display_download_info()
+ if self.prev_pkg != self.cur_pkg:
+ self.prev_pkg = self.cur_pkg
+ self.update_details_text(
+ _("Package %d of %d: %s\n") % (self.dl_cur_npkgs+1,
+ self.dl_goal_npkgs, self.cur_pkg), "level1")
+
+ def dl_output_done(self):
+ self.update_details_text("\n")
+
+ def act_output(self, force=False):
+ if self.act_phase != self.act_phase_last:
+ self.act_phase_last = self.act_phase
+ self.update_label_text(self.act_phase)
+ self.update_details_text("%s\n" % self.act_phase, "level1")
+ self.display_phase_info(self.act_phase, self.act_cur_nactions,
+ self.act_goal_nactions)
+ return
+
+ def act_output_done(self):
+ return
+
+ def ind_output(self, force=False):
+ if self.ind_started != self.ind_phase:
+ self.ind_started = self.ind_phase
+ self.update_label_text(self.ind_phase)
+ self.update_details_text(
+ "%s\n" % (self.ind_phase), "level1")
+ self.__indexing_progress()
+
+ def ind_output_done(self):
+ self.update_progress(self.ind_cur_nitems, self.ind_goal_nitems)
+
+ def __indexing_progress(self):
+ self.__generic_progress(self.ind_phase, self.ind_goal_nitems,
+ self.ind_cur_nitems)
+
+ def __generic_progress(self, phase, goal_nitems, cur_nitems):
+ #It doesn't look nice if the progressive is just for few elements
+ if goal_nitems > MIN_ELEMENTS_BOUNCE:
+ self.display_phase_info(phase, cur_nitems-1, goal_nitems)
+ else:
+ if not self.is_progress_bouncing():
+ self.start_bouncing_progress()
+
+ def item_output(self, force=False):
+ if self.item_started != self.item_phase:
+ self.item_started = self.item_phase
+ self.update_label_text(self.item_phase)
+ self.update_details_text(
+ "%s\n" % (self.item_phase), "level1")
+ self.__item_progress()
+
+ def __item_progress(self):
+ self.__generic_progress(self.item_phase, self.item_goal_nitems,
+ self.item_cur_nitems)
+
+
+ def item_output_done(self):
+ self.update_progress(self.item_cur_nitems, self.item_goal_nitems)
+
+ def update_progress(self, current_progress, total_progress):
+ raise NotImplementedError("abstract method update_progress() not "
+ "implemented in superclass")
+
+ def start_bouncing_progress(self):
+ raise NotImplementedError("abstract method start_bouncing_progress() "
+ "not implemented in superclass")
+
+ def is_progress_bouncing(self):
+ raise NotImplementedError("abstract method is_progress_bouncing() "
+ "not implemented in superclass")
+
+ def stop_bouncing_progress(self):
+ raise NotImplementedError("abstract method stop_bouncing_progress() "
+ "not implemented in superclass")
+
+ def display_download_info(self):
+ raise NotImplementedError("abstract method display_download_info() "
+ "not implemented in superclass")
+
+ def display_phase_info(self, phase_name, cur_n, goal_n):
+ raise NotImplementedError("abstract method display_phase_info() "
+ "not implemented in superclass")
+
+ def reset_label_text_after_delay(self):
+ raise NotImplementedError(
+ "abstract method reset_label_text_after_delay() "
+ "not implemented in superclass")
+
+ def update_label_text(self, text):
+ raise NotImplementedError("abstract method update_label_text() "
+ "not implemented in superclass")
+
+ def update_details_text(self, text, *tags):
+ raise NotImplementedError("abstract method update_details_text() "
+ "not implemented in superclass")
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/repository.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,3018 @@
+#!/usr/bin/python
+#
+# 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 (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved.
+#
+
+MODIFY_DIALOG_WIDTH_DEFAULT = 580
+MODIFY_DIALOG_SSL_WIDTH_DEFAULT = 490
+
+MODIFY_NOTEBOOK_GENERAL_PAGE = 0
+MODIFY_NOTEBOOK_CERTIFICATE_PAGE = 1
+MODIFY_NOTEBOOK_SIG_POLICY_PAGE = 2
+
+PUBCERT_APPROVED_STR = _("Approved")
+PUBCERT_REVOKED_STR = _("Revoked")
+PUBCERT_NOTSET_HASH = "HASH-NOTSET" #No L10N required
+PUBCERT_NOTAVAILABLE = _("Not available")
+
+import sys
+import os
+import pango
+import datetime
+import tempfile
+import M2Crypto as m2
+import errno
+from threading import Thread
+from gettext import ngettext
+
+try:
+ import gobject
+ gobject.threads_init()
+ import gtk
+ import pygtk
+ pygtk.require("2.0")
+except ImportError:
+ sys.exit(1)
+
+import pkg.client.publisher as publisher
+import pkg.client.api_errors as api_errors
+import pkg.gui.enumerations as enumerations
+import pkg.gui.misc as gui_misc
+import pkg.gui.progress as progress
+from pkg.client import global_settings
+
+logger = global_settings.logger
+
+ERROR_FORMAT = "<span color = \"red\">%s</span>"
+
+class Repository(progress.GuiProgressTracker):
+ def __init__(self, parent, image_directory, action = -1,
+ webinstall_new = False, main_window = None, gconf = None):
+ progress.GuiProgressTracker.__init__(self)
+ self.parent = parent
+ self.gconf = gconf
+ self.action = action
+ self.main_window = main_window
+ self.api_o = gui_misc.get_api_object(image_directory,
+ self, main_window)
+ if self.api_o == None:
+ return
+ self.webinstall_new = webinstall_new
+ self.progress_stop_thread = False
+ self.repository_selection = None
+ self.cancel_progress_thread = False
+ self.cancel_function = None
+ self.is_alias_valid = True
+ self.is_url_valid = False
+ self.new_pub = None
+ self.priority_changes = []
+ self.url_err = None
+ self.name_error = None
+ self.publisher_info = _("e.g. http://pkg.oracle.com/solaris/release")
+ self.publishers_list = None
+ self.repository_modify_publisher = None
+ self.no_changes = 0
+ self.pylintstub = None
+ builder = gtk.Builder()
+ builder.add_from_file(self.parent.gladefile)
+ # Dialog reused in the beadmin.py
+ self.w_confirmation_dialog = \
+ builder.get_object("confirmationdialog")
+ self.w_confirmation_label = \
+ builder.get_object("confirm_label")
+ self.w_confirmation_dialog.set_icon(self.parent.window_icon)
+ self.w_confirmation_textview = \
+ builder.get_object("confirmtext")
+ self.w_confirm_cancel_btn = builder.get_object("cancel_conf")
+ self.w_confirm_ok_btn = builder.get_object("ok_conf")
+ confirmbuffer = self.w_confirmation_textview.get_buffer()
+ confirmbuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+ self.w_confirmation_dialog.set_title(
+ _("Manage Publishers Confirmation"))
+ self.w_publishers_treeview = \
+ builder.get_object("publishers_treeview")
+ self.w_add_publisher_dialog = \
+ builder.get_object("add_publisher")
+ self.w_add_publisher_dialog.set_icon(self.parent.window_icon)
+ self.w_add_error_label = \
+ builder.get_object("add_error_label")
+ self.w_add_sslerror_label = \
+ builder.get_object("add_sslerror_label")
+ self.w_publisher_add_button = \
+ builder.get_object("add_button")
+ self.w_publisher_add_cancel_button = \
+ builder.get_object("add_publisher_cancel_button")
+ self.w_ssl_box = \
+ builder.get_object("ssl_box")
+ self.w_add_publisher_alias = \
+ builder.get_object("add_publisher_alias")
+ self.w_add_pub_label = \
+ builder.get_object("add_pub_label")
+ self.w_add_pub_instr_label = \
+ builder.get_object("add_pub_instr_label")
+ self.w_add_publisher_url = \
+ builder.get_object("add_publisher_url")
+ self.w_cert_entry = \
+ builder.get_object("certentry")
+ self.w_key_entry = \
+ builder.get_object("keyentry")
+ self.w_certbrowse_button = \
+ builder.get_object("certbrowse")
+ self.w_keybrowse_button = \
+ builder.get_object("keybrowse")
+ self.w_add_pub_help_button = \
+ builder.get_object("add_pub_help")
+ self.w_publisher_add_button.set_sensitive(False)
+ self.w_add_publisher_comp_dialog = \
+ builder.get_object("add_publisher_complete")
+ self.w_add_image = \
+ builder.get_object("add_image")
+ self.w_add_publisher_comp_dialog.set_icon(self.parent.window_icon)
+ self.w_add_publisher_c_name = \
+ builder.get_object("add_publisher_name_c")
+ self.w_add_publisher_c_alias = \
+ builder.get_object("add_publisher_alias_c")
+ self.w_add_publisher_c_alias_l = \
+ builder.get_object("add_publisher_alias_l")
+ self.w_add_publisher_c_url = \
+ builder.get_object("add_publisher_url_c")
+ self.w_add_publisher_c_desc = \
+ builder.get_object("add_publisher_desc_c")
+ self.w_add_publisher_c_desc_l = \
+ builder.get_object("add_publisher_desc_l")
+ self.w_add_publisher_c_close = \
+ builder.get_object("add_publisher_c_close")
+ self.w_registration_box = \
+ builder.get_object("add_registration_box")
+ self.w_registration_link = \
+ builder.get_object("registration_button")
+ self.w_modify_repository_dialog = \
+ builder.get_object("modify_repository")
+ self.w_modify_repository_dialog.set_icon(self.parent.window_icon)
+ self.w_modkeybrowse = \
+ builder.get_object("modkeybrowse")
+ self.w_modcertbrowse = \
+ builder.get_object("modcertbrowse")
+ self.w_addmirror_entry = \
+ builder.get_object("addmirror_entry")
+ self.w_addorigin_entry = \
+ builder.get_object("add_repo")
+ self.w_addmirror_button = \
+ builder.get_object("addmirror_button")
+ self.w_rmmirror_button = \
+ builder.get_object("mirrorremove")
+ self.w_addorigin_button = \
+ builder.get_object("pub_add_repo")
+ self.w_rmorigin_button = \
+ builder.get_object("pub_remove_repo")
+ self.w_modify_pub_alias = \
+ builder.get_object("repositorymodifyalias")
+ self.w_repositorymodifyok_button = \
+ builder.get_object("repositorymodifyok")
+ self.w_repositorymodifycancel_button = \
+ builder.get_object("repositorymodifycancel")
+ self.w_repositorymodifyhelp_button = \
+ builder.get_object("modify_repo_help")
+ self.modify_repo_mirrors_treeview = \
+ builder.get_object("modify_repo_mirrors_treeview")
+ self.modify_repo_origins_treeview = \
+ builder.get_object("modify_pub_repos_treeview")
+ self.w_modmirrerror_label = \
+ builder.get_object("modmirrerror_label")
+ self.w_modoriginerror_label = \
+ builder.get_object("modrepoerror_label")
+ self.w_modsslerror_label = \
+ builder.get_object("modsslerror_label")
+ self.w_repositorymodify_name = \
+ builder.get_object("repository_name_label")
+ self.w_repositorymodify_registration_link = \
+ builder.get_object(
+ "repositorymodifyregistrationlinkbutton")
+ self.w_repositorymirror_expander = \
+ builder.get_object(
+ "repositorymodifymirrorsexpander")
+ self.w_repositorymodify_registration_box = \
+ builder.get_object("modify_registration_box")
+ self.w_repositorymodify_key_entry = \
+ builder.get_object("modkeyentry")
+ self.w_repositorymodify_cert_entry = \
+ builder.get_object("modcertentry")
+ self.w_manage_publishers_dialog = \
+ builder.get_object("manage_publishers")
+ self.w_manage_publishers_dialog.set_icon(self.parent.window_icon)
+ self.w_manage_publishers_details = \
+ builder.get_object("manage_publishers_details")
+ self.w_manage_publishers_details.set_wrap_mode(gtk.WRAP_WORD)
+ manage_pub_details_buf = self.w_manage_publishers_details.get_buffer()
+ manage_pub_details_buf.create_tag("level0", weight=pango.WEIGHT_BOLD)
+ self.w_manage_add_btn = builder.get_object("manage_add")
+ self.w_manage_ok_btn = builder.get_object("manage_ok")
+ self.w_manage_remove_btn = builder.get_object("manage_remove")
+ self.w_manage_modify_btn = \
+ builder.get_object("manage_modify")
+ self.w_manage_up_btn = \
+ builder.get_object("manage_move_up")
+ self.w_manage_down_btn = \
+ builder.get_object("manage_move_down")
+ self.w_manage_cancel_btn = \
+ builder.get_object("manage_cancel")
+ self.w_manage_help_btn = \
+ builder.get_object("manage_help")
+
+ self.publishers_apply = \
+ builder.get_object("publishers_apply")
+ self.publishers_apply.set_icon(self.parent.window_icon)
+ self.publishers_apply_expander = \
+ builder.get_object("apply_expander")
+ self.publishers_apply_textview = \
+ builder.get_object("apply_textview")
+ applybuffer = self.publishers_apply_textview.get_buffer()
+ applybuffer.create_tag("level1", left_margin=30, right_margin=10)
+ self.publishers_apply_cancel = \
+ builder.get_object("apply_cancel")
+ self.publishers_apply_progress = \
+ builder.get_object("publishers_apply_progress")
+
+ self.w_modify_alias_error_label = builder.get_object(
+ "mod_alias_error_label")
+ self.w_pub_cert_treeview = \
+ builder.get_object("pub_certificate_treeview")
+ self.w_modify_pub_notebook = builder.get_object(
+ "modify_pub_notebook")
+ self.w_pub_cert_details_textview = builder.get_object(
+ "pub_certificate_details_textview")
+ manage_pub_cert_details_buf = \
+ self.w_pub_cert_details_textview.get_buffer()
+ manage_pub_cert_details_buf.create_tag("level0",
+ weight=pango.WEIGHT_BOLD)
+ manage_pub_cert_details_buf.create_tag("bold",
+ weight=pango.WEIGHT_BOLD)
+ manage_pub_cert_details_buf.create_tag("normal",
+ weight=pango.WEIGHT_NORMAL)
+ self.w_pub_cert_label = \
+ builder.get_object("mods_pub_label")
+ self.w_pub_cert_add_btn = builder.get_object(
+ "pub_certificate_add_button")
+ self.w_pub_cert_remove_btn = builder.get_object(
+ "pub_certificate_remove_button")
+ self.w_pub_cert_revoke_btn = builder.get_object(
+ "pub_certificate_revoke_button")
+ self.w_pub_cert_reinstate_btn = builder.get_object(
+ "pub_certificate_reinstate_button")
+
+
+ self.w_pub_sig_ignored_radiobutton = builder.get_object(
+ "sig_ignored_radiobutton")
+ self.w_pub_sig_optional_radiobutton = builder.get_object(
+ "sig_optional_but_valid_radiobutton")
+ self.w_pub_sig_valid_radiobutton = builder.get_object(
+ "sig_valid_radiobutton")
+ self.w_pub_sig_name_radiobutton = builder.get_object(
+ "sig_name_radiobutton")
+ self.w_pub_sig_name_entry = builder.get_object(
+ "sig_name_entry")
+ self.w_pub_sig_view_globpol_button = builder.get_object(
+ "sig_view_globpol_button")
+ self.w_pub_sig_cert_names_vbox = builder.get_object(
+ "sig_cert_names_vbox")
+
+ checkmark_icon = gui_misc.get_icon(
+ self.parent.icon_theme, "pm-check", 24)
+
+ self.w_add_image.set_from_pixbuf(checkmark_icon)
+
+ self.__setup_signals()
+
+ self.publishers_list = self.__get_publishers_liststore()
+ self.__init_pubs_tree_view(self.publishers_list)
+ self.__init_mirrors_tree_view(self.modify_repo_mirrors_treeview)
+ self.__init_origins_tree_view(self.modify_repo_origins_treeview)
+
+ self.pub_cert_list = self.__get_pub_cert_liststore()
+ self.orig_pub_cert_added_dict = {} # Orig Pub Certs added to model:
+ # - key/val: [ips-hash] = status
+ self.all_pub_cert_added_dict = {} # New/ Orig Pub Certs added to model
+ # - key/val: [sha-hash] = ips-hash
+ self.removed_orig_pub_cert_dict = {}# Removed Orig Pub Certs from model
+ # - key/val: [sha-hash] = ips-hash
+ self.orig_sig_policy = {}
+ self.pub_certs_setup = False
+
+ if self.action == enumerations.ADD_PUBLISHER:
+ gui_misc.set_modal_and_transient(self.w_add_publisher_dialog,
+ self.main_window)
+ self.__on_manage_add_clicked(None)
+ return
+ elif self.action == enumerations.MANAGE_PUBLISHERS:
+ gui_misc.set_modal_and_transient(self.w_manage_publishers_dialog,
+ self.main_window)
+ gui_misc.set_modal_and_transient(self.w_confirmation_dialog,
+ self.w_manage_publishers_dialog)
+ self.__prepare_publisher_list()
+ publisher_selection = self.w_publishers_treeview.get_selection()
+ publisher_selection.set_mode(gtk.SELECTION_SINGLE)
+ publisher_selection.connect("changed",
+ self.__on_publisher_selection_changed, None)
+ mirrors_selection = \
+ self.modify_repo_mirrors_treeview.get_selection()
+ mirrors_selection.set_mode(gtk.SELECTION_SINGLE)
+ mirrors_selection.connect("changed",
+ self.__on_mirror_selection_changed, None)
+ origins_selection = \
+ self.modify_repo_origins_treeview.get_selection()
+ origins_selection.set_mode(gtk.SELECTION_SINGLE)
+ origins_selection.connect("changed",
+ self.__on_origin_selection_changed, None)
+
+ gui_misc.set_modal_and_transient(self.w_add_publisher_dialog,
+ self.w_manage_publishers_dialog)
+ self.__init_pub_cert_tree_view(self.pub_cert_list)
+ self.w_manage_publishers_dialog.show_all()
+ return
+
+
+ def __setup_signals(self):
+ signals_table = [
+ (self.w_add_publisher_dialog, "delete_event",
+ self.__on_add_publisher_delete_event),
+ (self.w_add_publisher_url, "changed",
+ self.__on_publisherurl_changed),
+ (self.w_add_publisher_url, "activate",
+ self.__on_add_publisher_add_clicked),
+ (self.w_add_publisher_alias, "changed",
+ self.__on_publisheralias_changed),
+ (self.w_add_publisher_alias, "activate",
+ self.__on_add_publisher_add_clicked),
+ (self.w_publisher_add_button, "clicked",
+ self.__on_add_publisher_add_clicked),
+ (self.w_key_entry, "changed", self.__on_keyentry_changed),
+ (self.w_cert_entry, "changed", self.__on_certentry_changed),
+ (self.w_publisher_add_cancel_button, "clicked",
+ self.__on_add_publisher_cancel_clicked),
+ (self.w_keybrowse_button, "clicked",
+ self.__on_keybrowse_clicked),
+ (self.w_certbrowse_button, "clicked",
+ self.__on_certbrowse_clicked),
+ (self.w_add_pub_help_button, "clicked",
+ self.__on_add_pub_help_clicked),
+
+ (self.w_add_publisher_comp_dialog, "delete_event",
+ self.__on_add_publisher_complete_delete_event),
+ (self.w_add_publisher_c_close, "clicked",
+ self.__on_add_publisher_c_close_clicked),
+
+ (self.w_manage_publishers_dialog, "delete_event",
+ self.__on_manage_publishers_delete_event),
+ (self.w_manage_add_btn, "clicked",
+ self.__on_manage_add_clicked),
+ (self.w_manage_modify_btn, "clicked",
+ self.__on_manage_modify_clicked),
+ (self.w_manage_remove_btn, "clicked",
+ self.__on_manage_remove_clicked),
+ (self.w_manage_up_btn, "clicked",
+ self.__on_manage_move_up_clicked),
+ (self.w_manage_down_btn, "clicked",
+ self.__on_manage_move_down_clicked),
+ (self.w_manage_cancel_btn, "clicked",
+ self.__on_manage_cancel_clicked),
+ (self.w_manage_ok_btn, "clicked",
+ self.__on_manage_ok_clicked),
+ (self.w_manage_help_btn, "clicked",
+ self.__on_manage_help_clicked),
+
+ (self.w_modify_repository_dialog, "delete_event",
+ self.__on_modifydialog_delete_event),
+ (self.w_modify_pub_alias, "changed",
+ self.__on_modify_pub_alias_changed),
+ (self.w_modkeybrowse, "clicked",
+ self.__on_modkeybrowse_clicked),
+ (self.w_modcertbrowse, "clicked",
+ self.__on_modcertbrowse_clicked),
+ (self.w_addmirror_entry, "changed",
+ self.__on_addmirror_entry_changed),
+ (self.w_addorigin_entry, "changed",
+ self.__on_addorigin_entry_changed),
+ (self.w_addmirror_button, "clicked",
+ self.__on_addmirror_button_clicked),
+ (self.w_addorigin_button, "clicked",
+ self.__on_addorigin_button_clicked),
+ (self.w_rmmirror_button, "clicked",
+ self.__on_rmmirror_button_clicked),
+ (self.w_rmorigin_button, "clicked",
+ self.__on_rmorigin_button_clicked),
+ (self.w_repositorymodify_key_entry, "changed",
+ self.__on_modcertkeyentry_changed),
+ (self.w_repositorymodify_cert_entry, "changed",
+ self.__on_modcertkeyentry_changed),
+ (self.w_repositorymodifyok_button, "clicked",
+ self.__on_repositorymodifyok_clicked),
+ (self.w_repositorymodifycancel_button, "clicked",
+ self.__on_repositorymodifycancel_clicked),
+ (self.w_repositorymodifyhelp_button, "clicked",
+ self.__on_modify_repo_help_clicked),
+
+ (self.w_confirmation_dialog, "delete_event",
+ self.__delete_widget_handler_hide),
+ (self.w_confirm_cancel_btn, "clicked",
+ self.__on_cancel_conf_clicked),
+ (self.w_confirm_ok_btn, "clicked",
+ self.__on_ok_conf_clicked),
+
+ (self.publishers_apply, "delete_event",
+ self.__on_publishers_apply_delete_event),
+ (self.publishers_apply_cancel, "clicked",
+ self.__on_apply_cancel_clicked),
+
+ (self.w_pub_cert_add_btn, "clicked",
+ self.__on_pub_cert_add_clicked),
+ (self.w_pub_cert_remove_btn, "clicked",
+ self.__on_pub_cert_remove_clicked),
+ (self.w_pub_cert_revoke_btn, "clicked",
+ self.__on_pub_cert_revoke_clicked),
+ (self.w_pub_cert_reinstate_btn, "clicked",
+ self.__on_pub_cert_reinstate_clicked),
+ (self.w_modify_pub_notebook, "switch_page",
+ self.__on_notebook_change),
+
+ (self.w_pub_sig_ignored_radiobutton, "toggled",
+ self.__on_pub_sig_radiobutton_toggled),
+ (self.w_pub_sig_optional_radiobutton, "toggled",
+ self.__on_pub_sig_radiobutton_toggled),
+ (self.w_pub_sig_valid_radiobutton, "toggled",
+ self.__on_pub_sig_radiobutton_toggled),
+ (self.w_pub_sig_name_radiobutton, "toggled",
+ self.__on_pub_sig_radiobutton_toggled),
+ (self.w_pub_sig_view_globpol_button, "clicked",
+ self.__on_pub_sig_view_globpol_clicked),
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def __on_pub_sig_radiobutton_toggled(self, widget):
+ self.w_pub_sig_cert_names_vbox.set_sensitive(
+ self.w_pub_sig_name_radiobutton.get_active())
+
+ def __on_pub_sig_view_globpol_clicked(self, widget):
+ #Preferences Dialog is modal so no need to hide the Modify Dialog
+ self.parent.preferences.show_signature_policy()
+
+ def __update_pub_sig_policy_prop(self, set_props):
+ errors = []
+ try:
+ pub = self.repository_modify_publisher
+ if pub != None:
+ pub.update_props(set_props=set_props)
+ except api_errors.ApiException, e:
+ errors.append(("", e))
+ return errors
+
+ def __update_pub_sig_policy(self):
+ errors = []
+ orig = self.orig_sig_policy
+ if not orig:
+ return errors
+ ignore = self.w_pub_sig_ignored_radiobutton.get_active()
+ verify = self.w_pub_sig_optional_radiobutton.get_active()
+ req_sigs = self.w_pub_sig_valid_radiobutton.get_active()
+ req_names = self.w_pub_sig_name_radiobutton.get_active()
+ names = gui_misc.fetch_signature_policy_names_from_textfield(
+ self.w_pub_sig_name_entry.get_text())
+ set_props = gui_misc.setup_signature_policy_properties(ignore,
+ verify, req_sigs, req_names, names, orig)
+ if len(set_props) > 0:
+ errors = self.__update_pub_sig_policy_prop(set_props)
+ return errors
+
+ def __prepare_pub_signature_policy(self):
+ if self.orig_sig_policy:
+ return
+
+ sig_policy = self.__fetch_pub_signature_policy()
+ self.orig_sig_policy = sig_policy
+ self.w_pub_sig_ignored_radiobutton.set_active(
+ sig_policy[gui_misc.SIG_POLICY_IGNORE])
+ self.w_pub_sig_optional_radiobutton.set_active(
+ sig_policy[gui_misc.SIG_POLICY_VERIFY])
+ self.w_pub_sig_valid_radiobutton.set_active(
+ sig_policy[gui_misc.SIG_POLICY_REQUIRE_SIGNATURES])
+ self.w_pub_sig_cert_names_vbox.set_sensitive(False)
+
+ if sig_policy[gui_misc.SIG_POLICY_REQUIRE_NAMES]:
+ self.w_pub_sig_name_radiobutton.set_active(True)
+ self.w_pub_sig_cert_names_vbox.set_sensitive(True)
+
+ names = sig_policy[gui_misc.PROP_SIGNATURE_REQUIRED_NAMES]
+ gui_misc.set_signature_policy_names_for_textfield(
+ self.w_pub_sig_name_entry, names)
+
+ def __fetch_pub_signature_policy(self):
+ pub = self.repository_modify_publisher
+ prop_sig_pol = pub.signature_policy.name
+ prop_sig_req_names = None
+ if gui_misc.PROP_SIGNATURE_REQUIRED_NAMES in pub.properties:
+ prop_sig_req_names = \
+ pub.properties[gui_misc.PROP_SIGNATURE_REQUIRED_NAMES]
+ return gui_misc.create_sig_policy_from_property(
+ prop_sig_pol, prop_sig_req_names)
+
+ def __on_notebook_change(self, widget, event, pagenum):
+ if pagenum == MODIFY_NOTEBOOK_CERTIFICATE_PAGE:
+ gobject.idle_add(self.__prepare_pub_certs)
+ elif pagenum == MODIFY_NOTEBOOK_SIG_POLICY_PAGE:
+ gobject.idle_add(self.__prepare_pub_signature_policy)
+
+ @staticmethod
+ def __get_pub_cert_liststore():
+ return gtk.ListStore(
+ gobject.TYPE_STRING, # enumerations.PUBCERT_ORGANIZATION
+ gobject.TYPE_STRING, # enumerations.PUBCERT_NAME
+ gobject.TYPE_STRING, # enumerations.PUBCERT_STATUS
+ gobject.TYPE_STRING, # enumerations.PUBCERT_IPSHASH
+ gobject.TYPE_STRING, # enumerations.PUBCERT_PATH
+ gobject.TYPE_PYOBJECT, # enumerations.PUBCERT_XCERT_OBJ
+ gobject.TYPE_BOOLEAN, # enumerations.PUBCERT_NEW
+ )
+
+ @staticmethod
+ def __sort_func(treemodel, iter1, iter2, column):
+ col_val1 = treemodel.get_value(iter1, column)
+ col_val2 = treemodel.get_value(iter2, column)
+ ret = cmp(col_val1, col_val2)
+ if ret != 0:
+ return ret
+ if column == enumerations.PUBCERT_ORGANIZATION:
+ name1 = treemodel.get_value(iter1,
+ enumerations.PUBCERT_NAME)
+ name2 = treemodel.get_value(iter2,
+ enumerations.PUBCERT_NAME)
+ ret = cmp(name1, name2)
+ elif column == enumerations.PUBCERT_NAME:
+ org1 = treemodel.get_value(iter1,
+ enumerations.PUBCERT_ORGANIZATION)
+ org2 = treemodel.get_value(iter2,
+ enumerations.PUBCERT_ORGANIZATION)
+ ret = cmp(org1, org2)
+ return ret
+
+ def __init_pub_cert_tree_view(self, pub_cert_list):
+ pub_cert_sort_model = gtk.TreeModelSort(pub_cert_list)
+ pub_cert_sort_model.set_sort_column_id(enumerations.PUBCERT_ORGANIZATION,
+ gtk.SORT_ASCENDING)
+
+ pub_cert_sort_model.set_sort_func(enumerations.PUBCERT_ORGANIZATION,
+ self.__sort_func,
+ enumerations.PUBCERT_ORGANIZATION)
+ pub_cert_sort_model.set_sort_func(enumerations.PUBCERT_NAME,
+ self.__sort_func,
+ enumerations.PUBCERT_NAME)
+
+ # Organization column - sort using custom __sort_func()
+ org_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_("Organization"),
+ org_renderer, text = enumerations.PUBCERT_ORGANIZATION)
+ column.set_expand(False)
+ column.set_sort_column_id(enumerations.PUBCERT_ORGANIZATION)
+ column.set_sort_indicator(True)
+ column.set_resizable(True)
+ self.w_pub_cert_treeview.append_column(column)
+
+ # Name column - sort using custom __sort_func()
+ name_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_("Name"),
+ name_renderer, text = enumerations.PUBCERT_NAME)
+ column.set_expand(True)
+ column.set_sort_column_id(enumerations.PUBCERT_NAME)
+ column.set_sort_indicator(True)
+ column.set_resizable(True)
+ self.w_pub_cert_treeview.append_column(column)
+
+ # Status column
+ status_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_("Status"),
+ status_renderer, text = enumerations.PUBCERT_STATUS)
+ column.set_expand(False)
+ column.set_sort_column_id(enumerations.PUBCERT_STATUS)
+ self.w_pub_cert_treeview.append_column(column)
+
+ self.w_pub_cert_treeview.get_selection().connect('changed',
+ self.__on_pub_cert_treeview_changed)
+ self.w_pub_cert_treeview.set_model(pub_cert_sort_model)
+
+ @staticmethod
+ def __get_pub_display_name(pub):
+ display_name = ""
+ if not pub:
+ return display_name
+
+ name = pub.prefix
+ alias = pub.alias
+ use_name = False
+ use_alias = False
+ if len(name) > 0:
+ use_name = True
+ if alias and len(alias) > 0 and alias != name:
+ use_alias = True
+
+ if use_name and not use_alias:
+ display_name = name
+ elif use_name and use_alias:
+ display_name = "%s (%s)" % (name, alias)
+ return display_name
+
+ def __prepare_pub_certs(self):
+ if self.pub_certs_setup:
+ return
+
+ pub = self.repository_modify_publisher
+ if not pub:
+ return
+ sorted_model = self.w_pub_cert_treeview.get_model()
+ selection = self.w_pub_cert_treeview.get_selection()
+ selected_rows = selection.get_selected_rows()
+ self.w_pub_cert_treeview.set_model(None)
+ if not sorted_model:
+ return
+ model = sorted_model.get_model()
+ if not model:
+ return
+ model.clear()
+
+ self.orig_pub_cert_added_dict.clear()
+ self.all_pub_cert_added_dict.clear()
+ self.removed_orig_pub_cert_dict.clear()
+
+ pub_display_name = self.__get_pub_display_name(pub)
+ if pub_display_name != "":
+ self.w_pub_cert_label.set_markup(
+ _("<b>Certificates for publisher %s</b>") % pub_display_name)
+ else:
+ self.w_pub_cert_label.set_markup(
+ _("<b>Publisher certificates</b>"))
+
+ for h in pub.approved_ca_certs:
+ self.__add_cert_to_model(model,
+ pub.get_cert_by_hash(h), h, PUBCERT_APPROVED_STR)
+ for h in pub.revoked_ca_certs:
+ self.__add_cert_to_model(model,
+ pub.get_cert_by_hash(h), h, PUBCERT_REVOKED_STR)
+
+ self.w_pub_cert_treeview.set_model(sorted_model)
+ if len(pub.revoked_ca_certs) == 0 and len(pub.approved_ca_certs) == 0:
+ self.__set_empty_pub_cert()
+ self.pub_certs_setup = True
+ return
+
+ sel_path = (0,)
+ if len(selected_rows) > 1 and len(selected_rows[1]) > 0:
+ sel_path = selected_rows[1][0]
+ self.__set_pub_cert_selection(sorted_model, sel_path)
+ self.pub_certs_setup = True
+
+ def __add_cert_to_model(self, model, cert, ips_hash, status, path = "",
+ scroll_to=False, new=False):
+ pub = self.repository_modify_publisher
+ if not cert or not pub:
+ return
+ i = cert.get_subject()
+ organization = PUBCERT_NOTAVAILABLE
+ if len(i.get_entries_by_nid(i.nid["O"])) > 0:
+ organization = i.get_entries_by_nid(
+ i.nid["O"])[0].get_data().as_text()
+ name = PUBCERT_NOTAVAILABLE
+ if len(i.get_entries_by_nid(i.nid["CN"])) > 0:
+ name = i.get_entries_by_nid(
+ i.nid["CN"])[0].get_data().as_text()
+ if self.all_pub_cert_added_dict.has_key(cert.get_fingerprint('sha1')):
+ err = _("The publisher certificate:\n %s\n"
+ "has already been added.") % \
+ self.__get_cert_display_name(cert)
+ gui_misc.error_occurred(None, err,
+ _("Modify Publisher - %s") % self.__get_pub_display_name(pub),
+ gtk.MESSAGE_INFO)
+ return
+
+ self.all_pub_cert_added_dict[cert.get_fingerprint('sha1')] = ips_hash
+ itr = model.append(
+ [organization, name, status, ips_hash, path, cert, new])
+ if not new:
+ self.orig_pub_cert_added_dict[ips_hash] = status
+
+ if scroll_to:
+ path = model.get_path(itr)
+ sorted_model = self.w_pub_cert_treeview.get_model()
+ if not sorted_model:
+ return
+ sorted_path = sorted_model.convert_child_path_to_path(path)
+ self.w_pub_cert_treeview.scroll_to_cell(sorted_path)
+ selection = self.w_pub_cert_treeview.get_selection()
+ selection.select_path(sorted_path)
+
+ def __on_pub_cert_treeview_changed(self, treeselection):
+ selection = treeselection.get_selected_rows()
+ pathlist = selection[1]
+ if not pathlist or len(pathlist) == 0:
+ return
+ sorted_model = self.w_pub_cert_treeview.get_model()
+ if not sorted_model:
+ return
+ model = sorted_model.get_model()
+ path = pathlist[0]
+ child_path = sorted_model.convert_path_to_child_path(path)
+ self.__enable_disable_pub_cert_buttons(model, child_path)
+ self.__set_pub_cert_details(model, child_path)
+
+ def __enable_disable_pub_cert_buttons(self, model, path):
+ if not model or not path:
+ return
+ itr = model.get_iter(path)
+ status = model.get_value(itr, enumerations.PUBCERT_STATUS)
+ new = model.get_value(itr, enumerations.PUBCERT_NEW)
+
+ if status == PUBCERT_APPROVED_STR:
+ self.w_pub_cert_revoke_btn.set_sensitive(True)
+ self.w_pub_cert_reinstate_btn.set_sensitive(False)
+ else:
+ self.w_pub_cert_revoke_btn.set_sensitive(False)
+ self.w_pub_cert_reinstate_btn.set_sensitive(True)
+ if new:
+ self.w_pub_cert_revoke_btn.set_sensitive(False)
+ self.w_pub_cert_reinstate_btn.set_sensitive(False)
+ self.w_pub_cert_remove_btn.set_sensitive(True)
+
+ def __set_pub_cert_details(self, model, path):
+ itr = model.get_iter(path)
+ ips_hash = model.get_value(itr, enumerations.PUBCERT_IPSHASH)
+ cert = model.get_value(itr, enumerations.PUBCERT_XCERT_OBJ)
+ new = model.get_value(itr, enumerations.PUBCERT_NEW)
+ if not cert:
+ return
+ details_buffer = self.w_pub_cert_details_textview.get_buffer()
+ details_buffer.set_text("")
+ itr = details_buffer.get_end_iter()
+
+ labs = {}
+ labs["issued_to"] = _("Issued To:")
+ labs["common_name_to"] = gui_misc.PUBCERT_COMMON_NAME
+ labs["org_to"] = gui_misc.PUBCERT_ORGANIZATION
+ labs["org_unit_to"] = gui_misc.PUBCERT_ORGANIZATIONAL_UNIT
+ labs["issued_by"] = _("Issued By:")
+ labs["common_name_by"] = _(" Common Name (CN):")
+ labs["org_by"] = gui_misc.PUBCERT_ORGANIZATION
+ labs["org_unit_by"] = gui_misc.PUBCERT_ORGANIZATIONAL_UNIT
+ labs["validity"] = _("Validity:")
+ labs["issued_on"] = _(" Issued On:")
+ labs["fingerprints"] = _("Fingerprints:")
+ labs["sha1"] = _(" SHA1:")
+ labs["md5"] = _(" MD5:")
+ labs["ips"] = _(" IPS:")
+
+ text = {}
+ text["issued_to"] = ""
+ text["common_name_to"] = ""
+ text["org_to"] = ""
+ text["org_unit_to"] = ""
+ text["issued_by"] = ""
+ text["common_name_by"] = ""
+ text["org_by"] = ""
+ text["org_unit_by"] = ""
+ text["validity"] = ""
+ text["issued_on"] = ""
+ text["fingerprints"] = ""
+ text["sha1"] = ""
+ text["md5"] = ""
+ text["ips"] = ""
+
+ self._set_cert_issuer(text, cert.get_subject(), "to")
+ self._set_cert_issuer(text, cert.get_issuer(), "by")
+
+ eo = cert.get_not_after().get_datetime().date().isoformat()
+ today = datetime.datetime.today().date().isoformat()
+ validity_str = _("Validity:")
+ #TBD: may have an issue here in some locales if Validity string
+ #is very long then would only need one \t.
+ if eo < today:
+ validity_str += _("\t\t EXPIRED")
+ labs["validity"] = validity_str
+
+ io_str = cert.get_not_before().get_datetime().date().strftime("%x")
+ eo_str = cert.get_not_after().get_datetime().date().strftime("%x")
+ labs["issued_on"] += " " + io_str
+ text["issued_on"] = _("Expires On: %s") % eo_str
+
+ sha = cert.get_fingerprint('sha1')
+ md5 = cert.get_fingerprint('md5')
+ text["sha1"] = sha.lower()
+ text["md5"] = md5.lower()
+ text["ips"] = ips_hash.lower()
+
+ added = False
+ reinstated = False
+ if new:
+ if ips_hash == PUBCERT_NOTSET_HASH:
+ added = True
+ reinstated = False
+ else:
+ reinstated = True
+ added = False
+
+ gui_misc.set_pub_cert_details_text(labs, text,
+ self.w_pub_cert_details_textview, added, reinstated)
+
+ @staticmethod
+ def _set_cert_issuer(text, issuer, itype):
+ if len(issuer.get_entries_by_nid(issuer.nid["CN"])) > 0:
+ text["common_name_" + itype] = issuer.get_entries_by_nid(
+ issuer.nid["CN"])[0].get_data().as_text()
+ if len(issuer.get_entries_by_nid(issuer.nid["O"])) > 0:
+ text["org_" + itype] = issuer.get_entries_by_nid(
+ issuer.nid["O"])[0].get_data().as_text()
+ if len(issuer.get_entries_by_nid(issuer.nid["OU"])) > 0:
+ text["org_unit_" + itype] = issuer.get_entries_by_nid(
+ issuer.nid["OU"])[0].get_data().as_text()
+ else:
+ text["org_unit_" + itype] = PUBCERT_NOTAVAILABLE
+
+ def __get_pub_cert_filename(self, title, path = None):
+ if path == None or path == "":
+ path = tempfile.gettempdir()
+ filename = None
+ chooser = gtk.FileChooserDialog(title,
+ self.w_manage_publishers_dialog,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
+ (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OK, gtk.RESPONSE_OK))
+
+ file_filter = gtk.FileFilter()
+ file_filter.set_name(_("Certificate Files"))
+ file_filter.add_pattern("*.pem")
+ chooser.add_filter(file_filter)
+ chooser.set_current_folder(path)
+
+ response = chooser.run()
+ if response == gtk.RESPONSE_OK:
+ filename = chooser.get_filename()
+ chooser.destroy()
+
+ if filename != None:
+ info = os.path.split(filename)
+ self.gconf.last_add_pubcert_path = info[0]
+ return filename
+
+ def __on_pub_cert_add_clicked(self, widget):
+ filename = self.__get_pub_cert_filename(
+ _("Add Publisher Certificate"),
+ self.gconf.last_add_pubcert_path)
+ if filename == None:
+ return
+ try:
+ cert = self.__get_new_cert(filename)
+ sha = cert.get_fingerprint('sha1')
+ ips_hash = PUBCERT_NOTSET_HASH
+ status = PUBCERT_APPROVED_STR
+ new = True
+ #Restore orig cert if it was already added but just removed
+ if self.removed_orig_pub_cert_dict.has_key(sha):
+ ips_hash = self.removed_orig_pub_cert_dict[sha]
+ status = self.orig_pub_cert_added_dict[ips_hash]
+ filename = ""
+ new = False
+ del self.removed_orig_pub_cert_dict[sha]
+ sorted_model = self.w_pub_cert_treeview.get_model()
+ if not sorted_model:
+ return
+ model = sorted_model.get_model()
+ self.__add_cert_to_model(model, cert, ips_hash, status,
+ path=filename, scroll_to=True, new=new)
+ except api_errors.ApiException, e:
+ self.__show_errors([("", e)])
+ return
+
+ @staticmethod
+ def __get_new_cert(filename):
+ cert = None
+ try:
+ with open(filename, "rb") as fh:
+ s = fh.read()
+ except EnvironmentError, e:
+ if e.errno == errno.ENOENT:
+ raise api_errors.MissingFileArgumentException(
+ filename)
+ elif e.errno == errno.EACCES:
+ raise api_errors.PermissionsException(
+ filename)
+ raise api_errors.ApiException(e)
+ try:
+ cert = m2.X509.load_cert_string(s)
+ except m2.X509.X509Error, e:
+ raise api_errors.BadFileFormat(_("The file:\n"
+ " %s\nwas expected to be a PEM certificate but it "
+ "could not be read.") % filename)
+ return cert
+
+ def __on_pub_cert_reinstate_clicked(self, widget):
+ itr, sorted_model = self.__get_selected_pub_cert_itr_model()
+ if not itr or not sorted_model:
+ return
+ model = sorted_model.get_model()
+ child_itr = sorted_model.convert_iter_to_child_iter(None, itr)
+
+ ips_hash = model.get_value(child_itr, enumerations.PUBCERT_IPSHASH)
+ orig_status = ""
+ if self.orig_pub_cert_added_dict.has_key(ips_hash):
+ orig_status = self.orig_pub_cert_added_dict[ips_hash]
+ else:
+ #Should not be able to reinstate new cert, only existing ones
+ return
+ #Originally approved so just reset as there is nothing to do
+ if orig_status == PUBCERT_APPROVED_STR:
+ model.set_value(child_itr,
+ enumerations.PUBCERT_STATUS,
+ PUBCERT_APPROVED_STR)
+ self.__set_pub_cert_details(model,
+ model.get_path(child_itr))
+ self.__enable_disable_pub_cert_buttons(model,
+ model.get_path(child_itr))
+ return
+
+ filename = self.__get_pub_cert_filename(
+ _("Reinstate Publisher Certificate"),
+ self.gconf.last_add_pubcert_path)
+ if filename == None:
+ return
+
+ #Check the old cert and new ones match according to the sha fingerprint
+ cert = model.get_value(child_itr, enumerations.PUBCERT_XCERT_OBJ)
+ new_cert = self.__get_new_cert(filename)
+ if cert == None or new_cert == None:
+ #Must have exisitng cert and new one to reinstate
+ return
+ orig_sha = cert.get_fingerprint('sha1')
+ new_sha = new_cert.get_fingerprint('sha1')
+ if orig_sha != new_sha:
+ pub = self.repository_modify_publisher
+ if not pub:
+ return
+ gui_misc.error_occurred(None,
+ _("To reinstate the publisher certificate:\n %s\n"
+ "the original certificate file must be selected.") %
+ self.__get_cert_display_name(cert),
+ _("Modify Publisher - %s") % self.__get_pub_display_name(pub),
+ gtk.MESSAGE_INFO)
+ return
+ #Update model of existing cert which is to be reinstated by
+ #re-adding the cert as new
+ model.set_value(child_itr, enumerations.PUBCERT_STATUS,
+ PUBCERT_APPROVED_STR)
+ model.set_value(child_itr, enumerations.PUBCERT_PATH, filename)
+ model.set_value(child_itr, enumerations.PUBCERT_XCERT_OBJ, new_cert)
+ model.set_value(child_itr, enumerations.PUBCERT_NEW, True)
+ self.__set_pub_cert_details(model, model.get_path(child_itr))
+ self.__enable_disable_pub_cert_buttons(model,
+ model.get_path(child_itr))
+
+ @staticmethod
+ def __get_cert_display_name(cert):
+ cert_display_name = ""
+ if cert == None:
+ return cert_display_name
+ issuer = cert.get_subject()
+ cn = "-"
+ org = "-"
+ ou = "-"
+ if len(issuer.get_entries_by_nid(issuer.nid["CN"])) > 0:
+ cn = issuer.get_entries_by_nid(
+ issuer.nid["CN"])[0].get_data().as_text()
+ if len(issuer.get_entries_by_nid(issuer.nid["O"])) > 0:
+ org = issuer.get_entries_by_nid(
+ issuer.nid["O"])[0].get_data().as_text()
+ if len(issuer.get_entries_by_nid(issuer.nid["OU"])) > 0:
+ ou = issuer.get_entries_by_nid(
+ issuer.nid["OU"])[0].get_data().as_text()
+ else:
+ ou = PUBCERT_NOTAVAILABLE
+
+ if ou != PUBCERT_NOTAVAILABLE:
+ cert_display_name = \
+ "%s (CN) %s (O) %s (OU)" % (cn, org, ou) #No l10n required
+ else:
+ cert_display_name = "%s (CN) %s (O)" % (cn, org)#No l10n required
+ return cert_display_name
+
+ def __on_pub_cert_revoke_clicked(self, widget):
+ selection = self.w_pub_cert_treeview.get_selection()
+ if not selection:
+ return
+ selected_rows = selection.get_selected_rows()
+ if not selected_rows or len(selected_rows) < 2:
+ return
+ pathlist = selected_rows[1]
+ if not pathlist or len(pathlist) == 0:
+ return
+ path = pathlist[0]
+ self.__revoked(None, path)
+
+
+ def __revoked(self, cell, sorted_path):
+ sorted_model = self.w_pub_cert_treeview.get_model()
+ if not sorted_model:
+ return
+ model = sorted_model.get_model()
+ path = sorted_model.convert_path_to_child_path(sorted_path)
+ itr = model.get_iter(path)
+ if not itr:
+ return
+ status = model.get_value(itr, enumerations.PUBCERT_STATUS)
+ if status == PUBCERT_APPROVED_STR:
+ model.set_value(itr, enumerations.PUBCERT_STATUS,
+ PUBCERT_REVOKED_STR)
+ self.__enable_disable_pub_cert_buttons(model, path)
+ self.__set_pub_cert_details(model, path)
+
+ def __on_pub_cert_remove_clicked(self, widget):
+ itr, sorted_model = self.__get_selected_pub_cert_itr_model()
+ if not itr or not sorted_model:
+ return
+ sel_path = sorted_model.get_path(itr)
+ model = sorted_model.get_model()
+ child_itr = sorted_model.convert_iter_to_child_iter(None, itr)
+
+ cert = model.get_value(child_itr, enumerations.PUBCERT_XCERT_OBJ)
+ if self.all_pub_cert_added_dict.has_key(cert.get_fingerprint('sha1')):
+ del self.all_pub_cert_added_dict[cert.get_fingerprint('sha1')]
+
+ new = model.get_value(child_itr, enumerations.PUBCERT_NEW)
+ if not new:
+ sha = cert.get_fingerprint('sha1')
+ ips_hash = model.get_value(child_itr,
+ enumerations.PUBCERT_IPSHASH)
+ self.removed_orig_pub_cert_dict[sha] = ips_hash
+
+ model.remove(child_itr)
+ self.__set_pub_cert_selection(sorted_model, sel_path)
+
+ def __set_pub_cert_selection(self, sorted_model, sel_path):
+ len_smodel = len(sorted_model)
+ if len_smodel == 0:
+ self.__set_empty_pub_cert()
+ return
+ if len_smodel <= sel_path[0]:
+ sel_path = (len_smodel - 1,)
+ if sel_path[0] < 0:
+ sel_path = (0,)
+
+ self.w_pub_cert_treeview.scroll_to_cell(sel_path)
+ selection = self.w_pub_cert_treeview.get_selection()
+ selection.select_path(sel_path)
+
+ def __set_empty_pub_cert(self):
+ details_buffer = self.w_pub_cert_details_textview.get_buffer()
+ details_buffer.set_text("")
+ self.w_pub_cert_remove_btn.set_sensitive(False)
+ self.w_pub_cert_revoke_btn.set_sensitive(False)
+ self.w_pub_cert_reinstate_btn.set_sensitive(False)
+
+ def __get_selected_pub_cert_itr_model(self):
+ return self.__get_fitr_model_from_tree(self.w_pub_cert_treeview)
+
+ def __update_pub_certs(self):
+ errors = []
+ sorted_model = self.w_pub_cert_treeview.get_model()
+ if not sorted_model:
+ return errors
+ model = sorted_model.get_model()
+ if not model:
+ return errors
+
+ updated_pub_cert_dict = {}
+ add_pub_cert_dict = {}
+ iter_next = sorted_model.get_iter_first()
+ while iter_next != None:
+ itr = sorted_model.convert_iter_to_child_iter(None, iter_next)
+ ips_hash = model.get_value(itr, enumerations.PUBCERT_IPSHASH)
+ status = model.get_value(itr, enumerations.PUBCERT_STATUS)
+ path = model.get_value(itr, enumerations.PUBCERT_PATH)
+ new = model.get_value(itr, enumerations.PUBCERT_NEW)
+ #Both new and reinstated certs treated as new and to be added
+ if new:
+ add_pub_cert_dict[path] = True
+ else:
+ updated_pub_cert_dict[ips_hash] = status
+ iter_next = sorted_model.iter_next(iter_next)
+ for ips_hash, status in self.orig_pub_cert_added_dict.items():
+ if not updated_pub_cert_dict.has_key(ips_hash):
+ errors += self.__remove_pub_cert_for_publisher(ips_hash)
+ elif status != updated_pub_cert_dict[ips_hash] and \
+ updated_pub_cert_dict[ips_hash] == PUBCERT_REVOKED_STR:
+ errors += self.__revoke_pub_cert_for_publisher(ips_hash)
+ # Add and reinstate pub certs for publisher
+ for path in add_pub_cert_dict.keys():
+ errors += self.__add_pub_cert_to_publisher(path)
+
+ return errors
+
+ def __add_pub_cert_to_publisher(self, path):
+ errors = []
+ try:
+ with open(path, "rb") as fh:
+ s = fh.read()
+ except EnvironmentError, e:
+ if e.errno == errno.ENOENT:
+ errors.append(("",
+ api_errors.MissingFileArgumentException(path)))
+ elif e.errno == errno.EACCES:
+ errors.append(("", api_errors.PermissionsException(path)))
+ else:
+ errors.append(("", e))
+ try:
+ pub = self.repository_modify_publisher
+ if pub != None:
+ pub.approve_ca_cert(s)
+ except api_errors.ApiException, e:
+ errors.append(("", e))
+ return errors
+
+ def __revoke_pub_cert_for_publisher(self, ips_hash):
+ errors = []
+ try:
+ pub = self.repository_modify_publisher
+ if pub != None:
+ pub.revoke_ca_cert(ips_hash)
+ except api_errors.ApiException, e:
+ errors.append(("", e))
+ return errors
+
+ def __remove_pub_cert_for_publisher(self, ips_hash):
+ errors = []
+ try:
+ pub = self.repository_modify_publisher
+ if pub != None:
+ pub.unset_ca_cert(ips_hash)
+ except api_errors.ApiException, e:
+ errors.append(("", e))
+ return errors
+
+ def __init_pubs_tree_view(self, publishers_list):
+ publishers_list_filter = publishers_list.filter_new()
+ publishers_list_sort = gtk.TreeModelSort(publishers_list_filter)
+ publishers_list_sort.set_sort_column_id(
+ enumerations.PUBLISHER_PRIORITY_CHANGED, gtk.SORT_ASCENDING)
+ # Name column
+ name_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_("Publisher"),
+ name_renderer, text = enumerations.PUBLISHER_NAME)
+ column.set_expand(True)
+ self.w_publishers_treeview.append_column(column)
+ # Alias column
+ alias_renderer = gtk.CellRendererText()
+ alias_renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
+ column = gtk.TreeViewColumn(_("Alias"),
+ alias_renderer, text = enumerations.PUBLISHER_ALIAS)
+ column.set_expand(True)
+ self.w_publishers_treeview.append_column(column)
+ # Enabled column
+ toggle_renderer = gtk.CellRendererToggle()
+ column = gtk.TreeViewColumn(_("Enabled"),
+ toggle_renderer, active = enumerations.PUBLISHER_ENABLED)
+ toggle_renderer.set_property("activatable", True)
+ column.set_expand(False)
+ toggle_renderer.connect('toggled', self.__enable_disable)
+ column.set_cell_data_func(toggle_renderer,
+ self.__toggle_data_function, None)
+ self.w_publishers_treeview.append_column(column)
+ # Sticky column
+ toggle_renderer = gtk.CellRendererToggle()
+ column = gtk.TreeViewColumn(_("Sticky"),
+ toggle_renderer, active = enumerations.PUBLISHER_STICKY)
+ toggle_renderer.set_property("activatable", True)
+ column.set_expand(False)
+ toggle_renderer.connect('toggled', self.__sticky_unsticky)
+ column.set_cell_data_func(toggle_renderer,
+ self.__toggle_data_function, None)
+ self.w_publishers_treeview.append_column(column)
+ publishers_list_filter.set_visible_func(self.__publishers_filter)
+ self.w_publishers_treeview.set_model(publishers_list_sort)
+
+ def __prepare_publisher_list(self, restore_changes = False):
+ sorted_model = self.w_publishers_treeview.get_model()
+ selection = self.w_publishers_treeview.get_selection()
+ selected_rows = selection.get_selected_rows()
+ self.w_publishers_treeview.set_model(None)
+ try:
+ pubs = self.api_o.get_publishers(duplicate=True)
+ except api_errors.ApiException, e:
+ self.__show_errors([("", e)])
+ return
+ if not sorted_model:
+ return
+ filtered_model = sorted_model.get_model()
+ model = filtered_model.get_model()
+
+ if restore_changes == False:
+ self.no_changes = 0
+ self.priority_changes = []
+ model.clear()
+
+ j = 0
+ for pub in pubs:
+ name = pub.prefix
+ alias = pub.alias
+ # BUG: alias should be either "None" or None.
+ # in the list it's "None", but when adding pub it's None
+ if not alias or len(alias) == 0 or alias == "None":
+ alias = name
+ publisher_row = [j, j, name, alias, not pub.disabled,
+ pub.sticky, pub, False, False, False]
+ model.insert(j, publisher_row)
+ j += 1
+ else:
+ j = 0
+ for publisher_row in model:
+ pub = pubs[j]
+ name = pub.prefix
+ alias = pub.alias
+ if not alias or len(alias) == 0 or alias == "None":
+ alias = name
+ publisher_row[enumerations.PUBLISHER_ALIAS] = alias
+ publisher_row[enumerations.PUBLISHER_OBJECT] = pub
+ j += 1
+ # We handle here the case where a publisher was added
+ if self.new_pub:
+ pub = self.new_pub
+ name = pub.prefix
+ alias = pub.alias
+ if not alias or len(alias) == 0 or alias == "None":
+ alias = name
+ publisher_row = [j, j, name, alias, not pub.disabled,
+ pub.sticky, pub, False, False, False]
+ model.insert(j, publisher_row)
+
+ self.w_publishers_treeview.set_model(sorted_model)
+ if len(sorted_model) == 0:
+ self.__set_empty_pub_list()
+
+ if restore_changes:
+ if self.new_pub:
+ self.__select_last_publisher()
+ self.new_pub = None
+ else:
+ # We do have gtk.SELECTION_SINGLE mode, so if exists, we are
+ # interested only in the first selected path.
+ if len(selected_rows) > 1 and len(selected_rows[1]) > 0:
+ self.w_publishers_treeview.scroll_to_cell(
+ selected_rows[1][0])
+ selection.select_path(selected_rows[1][0])
+
+ def __set_empty_pub_list(self):
+ details_buffer = self.w_manage_publishers_details.get_buffer()
+ details_buffer.set_text("")
+ self.w_manage_modify_btn.set_sensitive(False)
+ self.w_manage_remove_btn.set_sensitive(False)
+ self.w_manage_up_btn.set_sensitive(False)
+ self.w_manage_down_btn.set_sensitive(False)
+
+ def __select_last_publisher(self):
+ sorted_model = self.w_publishers_treeview.get_model()
+ itr = sorted_model.get_iter_first()
+ next_itr = sorted_model.iter_next(itr)
+ while next_itr != None:
+ itr = next_itr
+ next_itr = sorted_model.iter_next(itr)
+ path = sorted_model.get_path(itr)
+ self.w_publishers_treeview.scroll_to_cell(path)
+ self.w_publishers_treeview.get_selection().select_path(path)
+
+ def __validate_url(self, url_widget, w_ssl_key = None, w_ssl_cert = None):
+ self.__validate_url_generic(url_widget, self.w_add_error_label,
+ self.w_publisher_add_button, self.is_alias_valid,
+ w_ssl_label=self.w_add_sslerror_label,
+ w_ssl_key=w_ssl_key, w_ssl_cert=w_ssl_cert)
+
+ def __validate_url_generic(self, w_url_text, w_error_label, w_action_button,
+ alias_valid = False, function = None, w_ssl_label = None,
+ w_ssl_key = None, w_ssl_cert = None):
+ ssl_key = None
+ ssl_cert = None
+ ssl_error = None
+ ssl_valid = True
+ url = w_url_text.get_text()
+ self.is_url_valid, self.url_err = self.__is_url_valid(url)
+ if not self.webinstall_new:
+ self.__reset_error_label()
+ if w_ssl_label:
+ w_ssl_label.set_sensitive(False)
+ w_ssl_label.show()
+ valid_url = False
+ valid_func = True
+ if self.is_url_valid:
+ if alias_valid:
+ valid_url = True
+ else:
+ if self.name_error != None:
+ self.__show_error_label_with_format(w_error_label,
+ self.name_error)
+ else:
+ if self.url_err != None:
+ self.__show_error_label_with_format(w_error_label,
+ self.url_err)
+ if w_ssl_key != None and w_ssl_cert != None:
+ if w_ssl_key:
+ ssl_key = w_ssl_key.get_text()
+ if w_ssl_cert:
+ ssl_cert = w_ssl_cert.get_text()
+ ssl_valid, ssl_error = self.__validate_ssl_key_cert(url, ssl_key,
+ ssl_cert, ignore_ssl_check_for_not_https=True)
+ self.__update_repository_dialog_width(ssl_error)
+ if ssl_error != None and w_ssl_label:
+ self.__show_error_label_with_format(w_ssl_label,
+ ssl_error)
+ elif w_ssl_label:
+ w_ssl_label.hide()
+ if function != None:
+ valid_func = function()
+ w_action_button.set_sensitive(valid_url and valid_func and ssl_valid)
+
+ def __validate_alias_addpub(self, ok_btn, name_widget, url_widget, error_label,
+ function = None):
+ valid_btn = False
+ valid_func = True
+ name = name_widget.get_text()
+ self.is_alias_valid = self.__is_alias_valid(name)
+ self.__reset_error_label()
+ if self.is_alias_valid:
+ if (self.is_url_valid):
+ valid_btn = True
+ else:
+ if self.url_err == None:
+ self.__validate_url(url_widget,
+ w_ssl_key=self.w_key_entry,
+ w_ssl_cert=self.w_cert_entry)
+ if self.url_err != None:
+ self.__show_error_label_with_format(error_label,
+ self.url_err)
+ else:
+ if self.name_error != None:
+ self.__show_error_label_with_format(error_label,
+ self.name_error)
+ if function != None:
+ valid_func = function()
+ ok_btn.set_sensitive(valid_btn and valid_func)
+
+ def __is_alias_valid(self, name):
+ self.name_error = None
+ if len(name) == 0:
+ return True
+ try:
+ publisher.Publisher(prefix=name)
+ except api_errors.BadPublisherPrefix, e:
+ self.name_error = _("Alias contains invalid characters")
+ return False
+ try:
+ self.api_o.get_publisher(prefix=name)
+ self.name_error = _("Alias already in use")
+ return False
+ except api_errors.UnknownPublisher, e:
+ return True
+ except api_errors.ApiException, e:
+ self.__show_errors([("", e)])
+ return False
+
+ def __get_selected_publisher_itr_model(self):
+ itr, sorted_model = self.__get_fitr_model_from_tree(
+ self.w_publishers_treeview)
+ if itr == None or sorted_model == None:
+ return (None, None)
+ sorted_path = sorted_model.get_path(itr)
+ filter_path = sorted_model.convert_path_to_child_path(sorted_path)
+ filter_model = sorted_model.get_model()
+ path = filter_model.convert_path_to_child_path(filter_path)
+ model = filter_model.get_model()
+ itr = model.get_iter(path)
+ return (itr, model)
+
+ def __get_selected_mirror_itr_model(self):
+ return self.__get_fitr_model_from_tree(\
+ self.modify_repo_mirrors_treeview)
+
+ def __get_selected_origin_itr_model(self):
+ return self.__get_fitr_model_from_tree(\
+ self.modify_repo_origins_treeview)
+
+ def __modify_publisher_dialog(self, pub):
+ self.orig_sig_policy = {}
+ self.pub_certs_setup = False
+
+ gui_misc.set_modal_and_transient(self.w_modify_repository_dialog,
+ self.w_manage_publishers_dialog)
+ try:
+ self.repository_modify_publisher = self.api_o.get_publisher(
+ prefix=pub.prefix, alias=pub.prefix, duplicate=True)
+ except api_errors.ApiException, e:
+ self.__show_errors([("", e)])
+ return
+ updated_modify_repository = self.__update_modify_repository_dialog(True,
+ True, True, True)
+
+ self.w_modify_repository_dialog.set_size_request(
+ MODIFY_DIALOG_WIDTH_DEFAULT, -1)
+
+ if updated_modify_repository:
+ self.w_modify_repository_dialog.set_title(
+ _("Modify Publisher - %s") %
+ self.__get_pub_display_name(pub))
+ self.w_modify_repository_dialog.show_all()
+
+ pagenum = self.w_modify_pub_notebook.get_current_page()
+ if pagenum == MODIFY_NOTEBOOK_CERTIFICATE_PAGE:
+ gobject.idle_add(self.__prepare_pub_certs)
+ elif pagenum == MODIFY_NOTEBOOK_SIG_POLICY_PAGE:
+ gobject.idle_add(self.__prepare_pub_signature_policy)
+
+ def __update_repository_dialog_width(self, ssl_error):
+ if ssl_error == None:
+ self.w_modify_repository_dialog.set_size_request(
+ MODIFY_DIALOG_WIDTH_DEFAULT, -1)
+ return
+
+ style = self.w_repositorymodify_name.get_style()
+ font_size_in_pango_unit = style.font_desc.get_size()
+ font_size_in_pixel = font_size_in_pango_unit / pango.SCALE
+ ssl_error_len = len(unicode(ssl_error)) * font_size_in_pixel
+ if ssl_error_len > MODIFY_DIALOG_SSL_WIDTH_DEFAULT:
+ new_dialog_width = ssl_error_len * \
+ (float(MODIFY_DIALOG_WIDTH_DEFAULT)/
+ MODIFY_DIALOG_SSL_WIDTH_DEFAULT)
+ self.w_modify_repository_dialog.set_size_request(
+ int(new_dialog_width), -1)
+ else:
+ self.w_modify_repository_dialog.set_size_request(
+ MODIFY_DIALOG_WIDTH_DEFAULT, -1)
+
+ def __update_modify_repository_dialog(self, update_alias=False,
+ update_mirrors=False, update_origins=False, update_ssl=False):
+ if not self.repository_modify_publisher:
+ return False
+ pub = self.repository_modify_publisher
+ selected_repo = pub.repository
+ prefix = ""
+ ssl_cert = ""
+ ssl_key = ""
+
+ if pub.prefix and len(pub.prefix) > 0:
+ prefix = pub.prefix
+ self.w_repositorymodify_name.set_text(prefix)
+
+ if update_alias:
+ alias = ""
+ if pub.alias and len(pub.alias) > 0 \
+ and pub.alias != "None":
+ alias = pub.alias
+ self.w_modify_pub_alias.set_text(alias)
+
+ if update_mirrors or update_ssl:
+ if update_mirrors:
+ insert_count = 0
+ mirrors_list = self.__get_mirrors_origins_liststore()
+ for mirror in selected_repo.mirrors:
+ if mirror.ssl_cert:
+ ssl_cert = mirror.ssl_cert
+ if mirror.ssl_key:
+ ssl_key = mirror.ssl_key
+ if update_mirrors:
+ mirror_uri = [mirror.uri]
+ mirrors_list.insert(insert_count, mirror_uri)
+ insert_count += 1
+ if update_mirrors:
+ self.modify_repo_mirrors_treeview.set_model(mirrors_list)
+ if len(selected_repo.mirrors) > 0:
+ self.w_repositorymirror_expander.set_expanded(
+ True)
+ else:
+ self.w_repositorymirror_expander.set_expanded(
+ False)
+
+ if update_origins or update_ssl:
+ if update_origins:
+ insert_count = 0
+ origins_list = self.__get_mirrors_origins_liststore()
+ for origin in selected_repo.origins:
+ if origin.ssl_cert:
+ ssl_cert = origin.ssl_cert
+ if origin.ssl_key:
+ ssl_key = origin.ssl_key
+ if update_origins:
+ origin_uri = [origin.uri]
+ origins_list.insert(insert_count, origin_uri)
+ insert_count += 1
+ if update_origins:
+ self.modify_repo_origins_treeview.set_model(origins_list)
+
+ reg_uri = self.__get_registration_uri(selected_repo)
+ if reg_uri != None:
+ self.w_repositorymodify_registration_link.set_uri(
+ reg_uri)
+ self.w_repositorymodify_registration_box.show()
+ else:
+ self.w_repositorymodify_registration_box.hide()
+
+ if update_ssl:
+ self.w_repositorymodify_cert_entry.set_text(ssl_cert)
+ self.w_repositorymodify_key_entry.set_text(ssl_key)
+ return True
+
+ def __add_mirror(self, new_mirror):
+ pub = self.repository_modify_publisher
+ repo = pub.repository
+ try:
+ repo.add_mirror(new_mirror)
+ self.w_addmirror_entry.set_text("")
+ except api_errors.ApiException, e:
+ self.__show_errors([(pub, e)])
+ self.__update_modify_repository_dialog(update_mirrors=True)
+
+ def __rm_mirror(self):
+ itr, model = self.__get_selected_mirror_itr_model()
+ remove_mirror = None
+ if itr and model:
+ remove_mirror = model.get_value(itr, 0)
+ pub = self.repository_modify_publisher
+ repo = pub.repository
+ try:
+ repo.remove_mirror(remove_mirror)
+ except api_errors.ApiException, e:
+ self.__show_errors([(pub, e)])
+ self.__update_modify_repository_dialog(update_mirrors=True)
+
+ def __add_origin(self, new_origin):
+ pub = self.repository_modify_publisher
+ repo = pub.repository
+ try:
+ repo.add_origin(new_origin)
+ self.w_addorigin_entry.set_text("")
+ except api_errors.ApiException, e:
+ self.__show_errors([(pub, e)])
+ self.__update_modify_repository_dialog(update_origins=True)
+
+ def __rm_origin(self):
+ itr, model = self.__get_selected_origin_itr_model()
+ remove_origin = None
+ if itr and model:
+ remove_origin = model.get_value(itr, 0)
+ pub = self.repository_modify_publisher
+ repo = pub.repository
+ try:
+ repo.remove_origin(remove_origin)
+ except api_errors.ApiException, e:
+ self.__show_errors([(pub, e)])
+ self.__update_modify_repository_dialog(update_origins=True)
+
+ def __sticky_unsticky(self, cell, sorted_path):
+ sorted_model = self.w_publishers_treeview.get_model()
+ filtered_path = sorted_model.convert_path_to_child_path(sorted_path)
+ filtered_model = sorted_model.get_model()
+ path = filtered_model.convert_path_to_child_path(filtered_path)
+ model = filtered_model.get_model()
+ itr = model.get_iter(path)
+ if itr == None:
+ return
+ pub = model.get_value(itr, enumerations.PUBLISHER_OBJECT)
+ if pub.sys_pub:
+ return
+ is_sticky = model.get_value(itr, enumerations.PUBLISHER_STICKY)
+ changed = model.get_value(itr, enumerations.PUBLISHER_STICKY_CHANGED)
+ model.set_value(itr, enumerations.PUBLISHER_STICKY, not is_sticky)
+ model.set_value(itr, enumerations.PUBLISHER_STICKY_CHANGED, not changed)
+
+ def __enable_disable(self, cell, sorted_path):
+ sorted_model = self.w_publishers_treeview.get_model()
+ filtered_path = sorted_model.convert_path_to_child_path(sorted_path)
+ filtered_model = sorted_model.get_model()
+ path = filtered_model.convert_path_to_child_path(filtered_path)
+ model = filtered_model.get_model()
+ itr = model.get_iter(path)
+ if itr == None:
+ self.w_manage_modify_btn.set_sensitive(False)
+ self.w_manage_remove_btn.set_sensitive(False)
+ self.w_manage_up_btn.set_sensitive(False)
+ self.w_manage_down_btn.set_sensitive(False)
+ return
+ pub = model.get_value(itr, enumerations.PUBLISHER_OBJECT)
+ if pub.sys_pub:
+ return
+ enabled = model.get_value(itr, enumerations.PUBLISHER_ENABLED)
+ changed = model.get_value(itr, enumerations.PUBLISHER_ENABLE_CHANGED)
+ model.set_value(itr, enumerations.PUBLISHER_ENABLED, not enabled)
+ model.set_value(itr, enumerations.PUBLISHER_ENABLE_CHANGED, not changed)
+ self.__enable_disable_updown_btn(itr, model)
+
+ @staticmethod
+ def __is_at_least_one_entry(treeview):
+ model = treeview.get_model()
+ if len(model) >= 1:
+ return True
+ return False
+
+ def __enable_disable_remove_modify_btn(self, itr, model):
+ if itr == None:
+ self.w_manage_modify_btn.set_sensitive(False)
+ self.w_manage_remove_btn.set_sensitive(False)
+ self.w_manage_up_btn.set_sensitive(False)
+ self.w_manage_down_btn.set_sensitive(False)
+ return
+ remove_val = False
+ modify_val = False
+ if self.__is_at_least_one_entry(self.w_publishers_treeview):
+ remove_val = True
+ modify_val = True
+ pub = model.get_value(itr,
+ enumerations.PUBLISHER_OBJECT)
+ if pub.sys_pub:
+ remove_val = False
+ modify_val = False
+ self.w_manage_modify_btn.set_sensitive(modify_val)
+ self.w_manage_remove_btn.set_sensitive(remove_val)
+
+ def __enable_disable_updown_btn(self, itr, model):
+ up_enabled = True
+ down_enabled = True
+ sorted_size = len(self.w_publishers_treeview.get_model())
+
+ if itr:
+ current_priority = model.get_value(itr,
+ enumerations.PUBLISHER_PRIORITY_CHANGED)
+ is_sys_pub = model.get_value(itr,
+ enumerations.PUBLISHER_OBJECT).sys_pub
+ next_sys_pub = False
+ prev_sys_pub = False
+ path = model.get_path(itr)
+ next_itr = model.iter_next(itr)
+ if next_itr:
+ next_pub = model.get_value(next_itr,
+ enumerations.PUBLISHER_OBJECT)
+ if next_pub.sys_pub:
+ next_sys_pub = True
+ if path[0] > 0:
+ prev_path = (path[0] - 1,)
+ prev_itr = model.get_iter(prev_path)
+ prev_pub = model.get_value(prev_itr,
+ enumerations.PUBLISHER_OBJECT)
+ if prev_pub.sys_pub:
+ prev_sys_pub = True
+
+ if current_priority == sorted_size - 1:
+ down_enabled = False
+ elif current_priority == 0:
+ up_enabled = False
+
+ if sorted_size == 1:
+ up_enabled = False
+ down_enabled = False
+ else:
+ if next_sys_pub or is_sys_pub:
+ down_enabled = False
+ if prev_sys_pub or is_sys_pub:
+ up_enabled = False
+ self.w_manage_up_btn.set_sensitive(up_enabled)
+ self.w_manage_down_btn.set_sensitive(down_enabled)
+
+ def __do_add_repository(self, alias=None, url=None, ssl_key=None, ssl_cert=None,
+ pub=None):
+ self.publishers_apply.set_title(_("Adding Publisher"))
+ if self.webinstall_new:
+ self.__run_with_prog_in_thread(self.__add_repository,
+ self.main_window, self.__stop, None, None, ssl_key,
+ ssl_cert, self.repository_modify_publisher)
+ else:
+ self.__run_with_prog_in_thread(self.__add_repository,
+ self.w_add_publisher_dialog, self.__stop, alias,
+ url, ssl_key, ssl_cert, pub)
+
+ def __stop(self):
+ if self.cancel_progress_thread == False:
+ self.__update_details_text(_("Canceling...\n"))
+ self.cancel_progress_thread = True
+ self.publishers_apply_cancel.set_sensitive(False)
+
+ def __add_repository(self, alias=None, origin_url=None, ssl_key=None,
+ ssl_cert=None, pub=None):
+ errors = []
+ if pub == None:
+ if self.__check_publisher_exists(self.api_o, alias,
+ origin_url):
+ self.progress_stop_thread = True
+ return
+ pub, repo, new_pub = self.__setup_publisher_from_uri(
+ alias, origin_url, ssl_key, ssl_cert)
+ if pub == None:
+ self.progress_stop_thread = True
+ return
+ else:
+ repo = pub.repository
+ new_pub = True
+ name = pub.prefix
+ errors_ssl = self.__update_ssl_creds(pub, repo, ssl_cert, ssl_key)
+ errors_update = []
+ try:
+ errors_update = self.__update_publisher(pub,
+ new_publisher=new_pub)
+ except api_errors.UnknownRepositoryPublishers, e:
+ if len(e.known) > 0:
+ pub, repo, new_pub = self.__get_or_create_pub_with_url(
+ self.api_o, e.known[0], origin_url)
+ if new_pub:
+ errors_ssl = self.__update_ssl_creds(pub, repo,
+ ssl_cert, ssl_key)
+ pub.alias = name
+ errors_update = self.__update_publisher(pub,
+ new_publisher=new_pub,
+ raise_unknownpubex=False)
+ else:
+ self.progress_stop_thread = True
+ return
+ else:
+ errors_update.append((pub, e))
+ errors += errors_ssl
+ errors += errors_update
+ if self.cancel_progress_thread:
+ try:
+ self.__g_update_details_text(
+ _("Removing publisher %s\n") % name)
+ self.api_o.remove_publisher(prefix=name,
+ alias=name)
+ self.__g_update_details_text(
+ _("Publisher %s succesfully removed\n") % name)
+ except api_errors.ApiException, e:
+ errors.append((pub, e))
+ self.progress_stop_thread = True
+ else:
+ self.progress_stop_thread = True
+ if len(errors) > 0:
+ gobject.idle_add(self.__show_errors, errors)
+ elif not self.webinstall_new:
+ gobject.idle_add(self.__afteradd_confirmation, pub)
+ self.progress_stop_thread = True
+ gobject.idle_add(
+ self.__g_on_add_publisher_delete_event,
+ self.w_add_publisher_dialog, None)
+ elif self.webinstall_new:
+ gobject.idle_add(
+ self.__g_on_add_publisher_delete_event,
+ self.w_add_publisher_dialog, None)
+ gobject.idle_add(self.parent.reload_packages)
+
+ def __update_publisher(self, pub, new_publisher=False, raise_unknownpubex=True):
+ errors = []
+ try:
+ if new_publisher:
+ self.__g_update_details_text(
+ _("Adding publisher %s\n") % pub.prefix)
+ self.api_o.add_publisher(pub)
+ self.no_changes += 1
+ else:
+ self.__g_update_details_text(
+ _("Updating publisher %s\n") % pub.prefix)
+ self.api_o.update_publisher(pub)
+ self.no_changes += 1
+ if new_publisher:
+ self.__g_update_details_text(
+ _("Publisher %s succesfully added\n") % pub.prefix)
+ else:
+ self.__g_update_details_text(
+ _("Publisher %s succesfully updated\n") % pub.prefix)
+ except api_errors.UnknownRepositoryPublishers, e:
+ if raise_unknownpubex:
+ raise e
+ else:
+ errors.append((pub, e))
+ except api_errors.ApiException, e:
+ errors.append((pub, e))
+ return errors
+
+ def __afteradd_confirmation(self, pub):
+ self.new_pub = pub
+ repo = pub.repository
+ origin = repo.origins[0]
+ # Descriptions not available at the moment
+ self.w_add_publisher_c_desc.hide()
+ self.w_add_publisher_c_desc_l.hide()
+ self.w_add_publisher_c_name.set_text(pub.prefix)
+ if pub.alias and len(pub.alias) > 0:
+ self.w_add_publisher_c_alias.set_text(pub.alias)
+ else:
+ self.w_add_publisher_c_alias.hide()
+ self.w_add_publisher_c_alias_l.hide()
+ self.w_add_publisher_c_url.set_text(origin.uri)
+ self.w_add_publisher_comp_dialog.show()
+
+ def __prepare_confirmation_dialog(self):
+ disable = ""
+ enable = ""
+ sticky = ""
+ unsticky = ""
+ delete = ""
+ priority_change = ""
+ disable_no = 0
+ enable_no = 0
+ sticky_no = 0
+ unsticky_no = 0
+ delete_no = 0
+ not_removed = []
+ removed_priorities = []
+ priority_changed = []
+ for row in self.publishers_list:
+ pub_name = row[enumerations.PUBLISHER_NAME]
+ if row[enumerations.PUBLISHER_REMOVED]:
+ delete += "\t" + pub_name + "\n"
+ delete_no += 1
+ removed_priorities.append(
+ row[enumerations.PUBLISHER_PRIORITY])
+ else:
+ if row[enumerations.PUBLISHER_ENABLE_CHANGED]:
+ to_enable = row[enumerations.PUBLISHER_ENABLED]
+ if not to_enable:
+ disable += "\t" + pub_name + "\n"
+ disable_no += 1
+ else:
+ enable += "\t" + pub_name + "\n"
+ enable_no += 1
+ if row[enumerations.PUBLISHER_STICKY_CHANGED]:
+ to_sticky = row[enumerations.PUBLISHER_STICKY]
+ if not to_sticky:
+ unsticky += "\t" + pub_name + "\n"
+ unsticky_no += 1
+ else:
+ sticky += "\t" + pub_name + "\n"
+ sticky_no += 1
+ not_removed.append(row)
+
+ for pub in not_removed:
+ if not self.__check_if_ignore(pub, removed_priorities):
+ pub_name = pub[enumerations.PUBLISHER_NAME]
+ pri = pub[enumerations.PUBLISHER_PRIORITY_CHANGED]
+ priority_changed.append([pri, pub_name])
+
+ if disable_no == 0 and enable_no == 0 and delete_no == 0 and \
+ sticky_no == 0 and unsticky_no == 0 and \
+ len(priority_changed) == 0:
+ self.__on_manage_cancel_clicked(None)
+ return
+
+ priority_changed.sort()
+ for pri, pub_name in priority_changed:
+ priority_change += "\t" + str(pri+1) + \
+ " - " + pub_name + "\n"
+
+ textbuf = self.w_confirmation_textview.get_buffer()
+ textbuf.set_text("")
+ textiter = textbuf.get_end_iter()
+
+ disable_text = ngettext("Disable Publisher:\n",
+ "Disable Publishers:\n", disable_no)
+ enable_text = ngettext("Enable Publisher:\n",
+ "Enable Publishers:\n", enable_no)
+ delete_text = ngettext("Remove Publisher:\n",
+ "Remove Publishers:\n", delete_no)
+ sticky_text = ngettext("Set sticky Publisher:\n",
+ "Set sticky Publishers:\n", delete_no)
+ unsticky_text = ngettext("Unset sticky Publisher:\n",
+ "Unset sticky Publishers:\n", delete_no)
+ priority_text = _("Change Priorities:\n")
+
+ confirm_no = delete_no + enable_no + disable_no + sticky_no + \
+ unsticky_no
+ confirm_text = ngettext("Apply the following change:",
+ "Apply the following changes:", confirm_no)
+
+ self.w_confirmation_label.set_markup("<b>" + confirm_text + "</b>")
+
+ if len(delete) > 0:
+ textbuf.insert_with_tags_by_name(textiter,
+ delete_text, "bold")
+ textbuf.insert_with_tags_by_name(textiter,
+ delete)
+ if len(disable) > 0:
+ if len(delete) > 0:
+ textbuf.insert_with_tags_by_name(textiter,
+ "\n")
+ textbuf.insert_with_tags_by_name(textiter,
+ disable_text, "bold")
+ textbuf.insert_with_tags_by_name(textiter,
+ disable)
+ if len(enable) > 0:
+ if len(delete) > 0 or len(disable) > 0:
+ textbuf.insert_with_tags_by_name(textiter,
+ "\n")
+ textbuf.insert_with_tags_by_name(textiter,
+ enable_text, "bold")
+ textbuf.insert_with_tags_by_name(textiter,
+ enable)
+ if len(sticky) > 0:
+ if len(delete) > 0 or len(disable) > 0 or len(enable) > 0:
+ textbuf.insert_with_tags_by_name(textiter,
+ "\n")
+ textbuf.insert_with_tags_by_name(textiter,
+ sticky_text, "bold")
+ textbuf.insert_with_tags_by_name(textiter,
+ sticky)
+ if len(unsticky) > 0:
+ if len(delete) > 0 or len(disable) > 0 or \
+ len(enable) > 0 or len(sticky) > 0:
+ textbuf.insert_with_tags_by_name(textiter,
+ "\n")
+ textbuf.insert_with_tags_by_name(textiter,
+ unsticky_text, "bold")
+ textbuf.insert_with_tags_by_name(textiter,
+ unsticky)
+ if len(priority_change) > 0:
+ if len(delete) > 0 or len(disable) or len(enable) > 0:
+ textbuf.insert_with_tags_by_name(textiter,
+ "\n")
+ textbuf.insert_with_tags_by_name(textiter,
+ priority_text, "bold")
+ textbuf.insert_with_tags_by_name(textiter,
+ priority_change)
+
+ self.w_confirm_cancel_btn.grab_focus()
+ self.w_confirmation_dialog.show_all()
+
+ def __proceed_enable_disable(self, pub_names, to_enable):
+ errors = []
+
+ gobject.idle_add(self.publishers_apply_expander.set_expanded, True)
+ for name in pub_names.keys():
+ try:
+ pub = self.api_o.get_publisher(name,
+ duplicate = True)
+ if pub.disabled == (not to_enable):
+ continue
+ pub.disabled = not to_enable
+ self.no_changes += 1
+ enable_text = _("Disabling")
+ if to_enable:
+ enable_text = _("Enabling")
+
+ details_text = \
+ _("%(enable)s publisher %(name)s\n")
+ self.__g_update_details_text(details_text %
+ {"enable" : enable_text, "name" : name})
+ self.api_o.update_publisher(pub)
+ except api_errors.ApiException, e:
+ errors.append(pub, e)
+ self.progress_stop_thread = True
+ gobject.idle_add(self.publishers_apply_expander.set_expanded, False)
+ if len(errors) > 0:
+ gobject.idle_add(self.__show_errors, errors)
+ else:
+ gobject.idle_add(self.parent.reload_packages, False)
+
+ def __proceed_after_confirmation(self):
+ errors = []
+
+ image_lock_err = False
+ for row in self.priority_changes:
+ try:
+ if row[1] == None or row[2] == None:
+ continue
+ pub1 = self.api_o.get_publisher(row[1],
+ duplicate=True)
+ pub2 = self.api_o.get_publisher(row[2],
+ duplicate=True)
+ if row[0] == enumerations.PUBLISHER_MOVE_BEFORE:
+ self.api_o.update_publisher(pub1,
+ search_before=pub2.prefix)
+ else:
+ self.api_o.update_publisher(pub1,
+ search_after=pub2.prefix)
+ self.no_changes += 1
+ self.__g_update_details_text(
+ _("Changing priority for publisher %s\n")
+ % row[1])
+ except api_errors.ImageLockedError, e:
+ self.no_changes = 0
+ if not image_lock_err:
+ errors.append((row[1], e))
+ image_lock_err = True
+ except api_errors.ApiException, e:
+ errors.append((row[1], e))
+
+ for row in self.publishers_list:
+ name = row[enumerations.PUBLISHER_NAME]
+ try:
+ if row[enumerations.PUBLISHER_REMOVED]:
+ self.no_changes += 1
+ self.__g_update_details_text(
+ _("Removing publisher %s\n") % name)
+ self.api_o.remove_publisher(prefix=name,
+ alias=name)
+ self.__g_update_details_text(
+ _("Publisher %s succesfully removed\n")
+ % name)
+ elif row[enumerations.PUBLISHER_ENABLE_CHANGED] or \
+ row[enumerations.PUBLISHER_STICKY_CHANGED]:
+ self.__do_changes_for_row(row, name)
+ except api_errors.ImageLockedError, e:
+ self.no_changes = 0
+ if not image_lock_err:
+ errors.append(
+ (row[enumerations.PUBLISHER_OBJECT], e))
+ image_lock_err = True
+ except api_errors.ApiException, e:
+ errors.append((row[enumerations.PUBLISHER_OBJECT], e))
+ self.progress_stop_thread = True
+ if len(errors) > 0:
+ gobject.idle_add(self.__show_errors, errors)
+ else:
+ gobject.idle_add(self.__after_confirmation)
+
+ def __do_changes_for_row(self, row, name):
+ pub = self.api_o.get_publisher(name, duplicate = True)
+ if row[enumerations.PUBLISHER_ENABLE_CHANGED]:
+ to_enable = row[enumerations.PUBLISHER_ENABLED]
+ pub.disabled = not to_enable
+ if row[enumerations.PUBLISHER_STICKY_CHANGED]:
+ sticky = row[enumerations.PUBLISHER_STICKY]
+ pub.sticky = sticky
+ self.no_changes += 1
+ update_text = _("Updating")
+ details_text = _("%(update)s publisher %(name)s\n")
+ self.__g_update_details_text(details_text %
+ {"update" : update_text, "name" : name})
+ self.api_o.update_publisher(pub)
+
+ def __after_confirmation(self):
+ self.__on_manage_publishers_delete_event(
+ self.w_manage_publishers_dialog, None)
+ return False
+
+ def __proceed_modifyrepo_ok(self):
+ errors = []
+ alias = self.w_modify_pub_alias.get_text()
+ ssl_key = self.w_repositorymodify_key_entry.get_text()
+ ssl_cert = self.w_repositorymodify_cert_entry.get_text()
+ pub = self.repository_modify_publisher
+ repo = pub.repository
+ missing_ssl = False
+ try:
+ prefix = pub.prefix
+ mirrors = repo.mirrors
+ origins = repo.origins
+ self.api_o.reset()
+ self.repository_modify_publisher = self.api_o.get_publisher(
+ prefix=prefix, alias=prefix, duplicate=True)
+ pub = self.repository_modify_publisher
+ repo = pub.repository
+ repo.mirrors = mirrors
+ repo.origins = origins
+ if pub.alias != alias:
+ pub.alias = alias
+ errors += self.__update_ssl_creds(pub, repo, ssl_cert, ssl_key)
+ errors += self.__update_pub_certs()
+ errors += self.__update_pub_sig_policy()
+ errors += self.__update_publisher(pub, new_publisher=False)
+ except api_errors.ApiException, e:
+ errors.append((pub, e))
+ self.progress_stop_thread = True
+ if len(errors) > 0:
+ missing_ssl = self.__is_missing_ssl_creds(pub, ssl_key, ssl_cert)
+ gobject.idle_add(self.__show_errors, errors, missing_ssl)
+ else:
+ gobject.idle_add(self.__g_delete_widget_handler_hide,
+ self.w_modify_repository_dialog, None)
+ if self.action == enumerations.MANAGE_PUBLISHERS:
+ gobject.idle_add(self.__prepare_publisher_list, True)
+ self.no_changes += 1
+
+ @staticmethod
+ def __is_missing_ssl_creds(pub, ssl_key, ssl_cert):
+ repo = pub.repository
+ if ssl_key and len(ssl_key) > 0 and ssl_cert and len(ssl_cert) > 0:
+ return False
+ for uri in repo.origins:
+ print uri
+ if uri.scheme in publisher.SSL_SCHEMES:
+ return True
+ for uri in repo.mirrors:
+ if uri.scheme in publisher.SSL_SCHEMES:
+ return True
+ return False
+
+ def __run_with_prog_in_thread(self, func, parent_window = None,
+ cancel_func = None, *f_args):
+ self.progress_stop_thread = False
+ self.cancel_progress_thread = False
+ if cancel_func == None:
+ self.publishers_apply_cancel.set_sensitive(False)
+ else:
+ self.publishers_apply_cancel.set_sensitive(True)
+ gui_misc.set_modal_and_transient(self.publishers_apply, parent_window)
+ self.publishers_apply_textview.get_buffer().set_text("")
+ self.publishers_apply.show_all()
+ self.cancel_function = cancel_func
+ gobject.timeout_add(100, self.__progress_pulse)
+ Thread(target = func, args = f_args).start()
+
+ def __progress_pulse(self):
+ if not self.progress_stop_thread:
+ self.publishers_apply_progress.pulse()
+ return True
+ else:
+ self.publishers_apply.hide()
+ return False
+
+ def __g_update_details_text(self, text, *tags):
+ gobject.idle_add(self.__update_details_text, text, *tags)
+
+ def __update_details_text(self, text, *tags):
+ buf = self.publishers_apply_textview.get_buffer()
+ textiter = buf.get_end_iter()
+ if tags:
+ buf.insert_with_tags_by_name(textiter, text, *tags)
+ else:
+ buf.insert(textiter, text)
+ self.publishers_apply_textview.scroll_to_iter(textiter, 0.0)
+
+ # Signal handlers
+ def __on_publisher_selection_changed(self, selection, widget):
+ itr, model = self.__get_selected_publisher_itr_model()
+ if itr and model:
+ self.__enable_disable_updown_btn(itr, model)
+ self.__enable_disable_remove_modify_btn(itr, model)
+ self.__update_publisher_details(
+ model.get_value(itr, enumerations.PUBLISHER_OBJECT),
+ self.w_manage_publishers_details)
+
+ def __on_mirror_selection_changed(self, selection, widget):
+ model_itr = selection.get_selected()
+ if model_itr[1]:
+ self.w_rmmirror_button.set_sensitive(True)
+ else:
+ self.w_rmmirror_button.set_sensitive(False)
+
+ def __on_origin_selection_changed(self, selection, widget):
+ model_itr = selection.get_selected()
+ if model_itr[1] and \
+ self.__is_at_least_one_entry(self.modify_repo_origins_treeview):
+ self.w_rmorigin_button.set_sensitive(True)
+ else:
+ self.w_rmorigin_button.set_sensitive(False)
+
+ def __g_on_add_publisher_delete_event(self, widget, event):
+ self.__on_add_publisher_delete_event(widget, event)
+ return False
+
+ def __on_add_publisher_delete_event(self, widget, event):
+ self.w_add_publisher_url.set_text("")
+ self.w_add_publisher_alias.set_text("")
+ self.__delete_widget_handler_hide(widget, event)
+ return True
+
+ def __on_add_publisher_complete_delete_event(self, widget, event):
+ if self.no_changes > 0:
+ self.parent.reload_packages()
+ if self.action == enumerations.MANAGE_PUBLISHERS:
+ self.__prepare_publisher_list(True)
+ self.__delete_widget_handler_hide(widget, event)
+ return True
+
+ def __on_publisherurl_changed(self, widget):
+ url = widget.get_text()
+ if self.__is_ssl_scheme(url):
+ self.w_ssl_box.show()
+ else:
+ self.w_ssl_box.hide()
+ self.__validate_url(widget,
+ w_ssl_key=self.w_key_entry, w_ssl_cert=self.w_cert_entry)
+
+ def __on_certentry_changed(self, widget):
+ self.__validate_url_generic(self.w_add_publisher_url,
+ self.w_add_error_label, self.w_publisher_add_button,
+ self.is_alias_valid, w_ssl_label=self.w_add_sslerror_label,
+ w_ssl_key=self.w_key_entry, w_ssl_cert=widget)
+
+ def __on_keyentry_changed(self, widget):
+ self.__validate_url_generic(self.w_add_publisher_url,
+ self.w_add_error_label, self.w_publisher_add_button,
+ self.is_alias_valid, w_ssl_label=self.w_add_sslerror_label,
+ w_ssl_key=widget, w_ssl_cert=self.w_cert_entry)
+
+ def __on_modcertkeyentry_changed(self, widget):
+ self.__on_addorigin_entry_changed(None)
+ self.__on_addmirror_entry_changed(None)
+ ssl_key = self.w_repositorymodify_key_entry.get_text()
+ ssl_cert = self.w_repositorymodify_cert_entry.get_text()
+ ssl_valid, ssl_error = self.__validate_ssl_key_cert(None,
+ ssl_key, ssl_cert)
+ self.__update_repository_dialog_width(ssl_error)
+ self.w_repositorymodifyok_button.set_sensitive(True)
+ if ssl_valid == False and (len(ssl_key) > 0 or len(ssl_cert) > 0):
+ self.w_repositorymodifyok_button.set_sensitive(False)
+ if ssl_error != None:
+ self.__show_error_label_with_format(
+ self.w_modsslerror_label, ssl_error)
+ else:
+ self.w_modsslerror_label.set_text("")
+ return
+ self.w_modsslerror_label.set_text("")
+
+ def __on_addmirror_entry_changed(self, widget):
+ uri_list_model = self.modify_repo_mirrors_treeview.get_model()
+ self.__validate_mirror_origin_url(self.w_addmirror_entry.get_text(),
+ self.w_addmirror_button, self.w_modmirrerror_label, uri_list_model)
+
+ def __on_addorigin_entry_changed(self, widget):
+ uri_list_model = self.modify_repo_origins_treeview.get_model()
+ self.__validate_mirror_origin_url(self.w_addorigin_entry.get_text(),
+ self.w_addorigin_button, self.w_modoriginerror_label, uri_list_model)
+
+ def __validate_mirror_origin_url(self, url, add_button, error_label,
+ uri_list_model):
+ url_error = None
+ is_url_valid, url_error = self.__is_url_valid(url)
+ add_button.set_sensitive(False)
+ error_label.set_sensitive(False)
+ error_label.set_markup(self.publisher_info)
+ if len(url) <= 4:
+ if is_url_valid == False and url_error != None:
+ self.__show_error_label_with_format(
+ error_label, url_error)
+ return
+
+ for uri_row in uri_list_model:
+ origin_url = uri_row[0].strip("/")
+ if origin_url.strip("/") == url.strip("/"):
+ url_error = _("URI already added")
+ self.__show_error_label_with_format(
+ error_label, url_error)
+ return
+
+ if is_url_valid == False:
+ if url_error != None:
+ self.__show_error_label_with_format(error_label,
+ url_error)
+ return
+ add_button.set_sensitive(True)
+
+ def __is_ssl_specified(self):
+ ssl_key = self.w_repositorymodify_key_entry.get_text()
+ ssl_cert = self.w_repositorymodify_cert_entry.get_text()
+ if len(ssl_key) > 0 or len(ssl_cert) > 0:
+ return True
+ return False
+
+ def __on_publisheralias_changed(self, widget):
+ error_label = self.w_add_error_label
+ url_widget = self.w_add_publisher_url
+ ok_btn = self.w_publisher_add_button
+ self.__validate_alias_addpub(ok_btn, widget, url_widget, error_label)
+
+ def __on_modify_pub_alias_changed(self, widget):
+ error_label = self.w_modify_alias_error_label
+ ok_btn = self.w_repositorymodifyok_button
+ name = widget.get_text()
+ self.is_alias_valid = self.__is_alias_valid(name)
+ if not self.is_alias_valid and self.name_error != None:
+ self.__show_error_label_with_format(error_label,
+ self.name_error)
+ ok_btn.set_sensitive(False)
+ else:
+ error_label.set_text("")
+ ok_btn.set_sensitive(True)
+
+ def __on_add_publisher_add_clicked(self, widget):
+ if self.w_publisher_add_button.get_property('sensitive') == 0:
+ return
+ alias = self.w_add_publisher_alias.get_text()
+ if len(alias) == 0:
+ alias = None
+ url = self.w_add_publisher_url.get_text()
+ ssl_key = self.w_key_entry.get_text()
+ ssl_cert = self.w_cert_entry.get_text()
+ if not self.__is_ssl_scheme(url) or not \
+ (ssl_key and ssl_cert and os.path.isfile(ssl_cert) and
+ os.path.isfile(ssl_key)):
+ ssl_key = None
+ ssl_cert = None
+ self.__do_add_repository(alias, url, ssl_key, ssl_cert)
+
+ def __on_apply_cancel_clicked(self, widget):
+ if self.cancel_function:
+ self.cancel_function()
+
+ def __on_add_publisher_cancel_clicked(self, widget):
+ self.__on_add_publisher_delete_event(
+ self.w_add_publisher_dialog, None)
+
+ def __on_modkeybrowse_clicked(self, widget):
+ self.__keybrowse(self.w_modify_repository_dialog,
+ self.w_repositorymodify_key_entry,
+ self.w_repositorymodify_cert_entry)
+
+ def __on_modcertbrowse_clicked(self, widget):
+ self.__certbrowse(self.w_modify_repository_dialog,
+ self.w_repositorymodify_cert_entry)
+
+ def __on_keybrowse_clicked(self, widget):
+ self.__keybrowse(self.w_add_publisher_dialog,
+ self.w_key_entry, self.w_cert_entry)
+
+ def __on_certbrowse_clicked(self, widget):
+ self.__certbrowse(self.w_add_publisher_dialog,
+ self.w_cert_entry)
+
+ def __on_add_publisher_c_close_clicked(self, widget):
+ self.__on_add_publisher_complete_delete_event(
+ self.w_add_publisher_comp_dialog, None)
+
+ def __on_manage_publishers_delete_event(self, widget, event):
+ self.__delete_widget_handler_hide(widget, event)
+ if self.no_changes > 0:
+ self.parent.reload_packages()
+ return True
+
+ def __g_delete_widget_handler_hide(self, widget, event):
+ self.__delete_widget_handler_hide(widget, event)
+ return False
+
+ def __on_manage_add_clicked(self, widget):
+ self.w_add_publisher_url.grab_focus()
+ self.w_registration_box.hide()
+ self.__reset_error_label()
+ self.w_add_publisher_dialog.show_all()
+
+ def __reset_error_label(self):
+ self.w_add_error_label.set_markup(self.publisher_info)
+ self.w_add_error_label.set_sensitive(False)
+ self.w_add_error_label.show()
+
+ def __on_manage_modify_clicked(self, widget):
+ itr, model = self.__get_selected_publisher_itr_model()
+ if itr and model:
+ pub = model.get_value(itr, enumerations.PUBLISHER_OBJECT)
+ self.__modify_publisher_dialog(pub)
+
+ def __on_manage_remove_clicked(self, widget):
+ itr, model = self.__get_selected_publisher_itr_model()
+ tsel = self.w_publishers_treeview.get_selection()
+ selection = tsel.get_selected()
+ sel_itr = selection[1]
+ sorted_model = selection[0]
+ sorted_path = sorted_model.get_path(sel_itr)
+ if itr and model:
+ current_priority = model.get_value(itr,
+ enumerations.PUBLISHER_PRIORITY_CHANGED)
+ model.set_value(itr, enumerations.PUBLISHER_REMOVED, True)
+ for element in model:
+ if element[enumerations.PUBLISHER_PRIORITY_CHANGED] > \
+ current_priority:
+ element[
+ enumerations.PUBLISHER_PRIORITY_CHANGED] -= 1
+ tsel.select_path(sorted_path)
+ if not tsel.path_is_selected(sorted_path):
+ row = sorted_path[0]-1
+ if row >= 0:
+ tsel.select_path((row,))
+ if len(sorted_model) == 0:
+ self.__set_empty_pub_list()
+
+ def __on_manage_move_up_clicked(self, widget):
+ before_name = None
+ itr, model = self.__get_selected_publisher_itr_model()
+ current_priority = model.get_value(itr,
+ enumerations.PUBLISHER_PRIORITY_CHANGED)
+ current_name = model.get_value(itr, enumerations.PUBLISHER_NAME)
+ for element in model:
+ if current_priority == \
+ element[enumerations.PUBLISHER_PRIORITY_CHANGED]:
+ element[
+ enumerations.PUBLISHER_PRIORITY_CHANGED] -= 1
+ elif element[enumerations.PUBLISHER_PRIORITY_CHANGED] \
+ == current_priority - 1 :
+ before_name = element[enumerations.PUBLISHER_NAME]
+ element[
+ enumerations.PUBLISHER_PRIORITY_CHANGED] += 1
+ self.priority_changes.append([enumerations.PUBLISHER_MOVE_BEFORE,
+ current_name, before_name])
+ self.__enable_disable_updown_btn(itr, model)
+ self.__move_to_cursor()
+
+ def __move_to_cursor(self):
+ itr, model = self.__get_fitr_model_from_tree(self.w_publishers_treeview)
+ if itr and model:
+ path = model.get_path(itr)
+ self.w_publishers_treeview.scroll_to_cell(path)
+
+ def __on_manage_move_down_clicked(self, widget):
+ after_name = None
+ itr, model = self.__get_selected_publisher_itr_model()
+ current_priority = model.get_value(itr,
+ enumerations.PUBLISHER_PRIORITY_CHANGED)
+ current_name = model.get_value(itr, enumerations.PUBLISHER_NAME)
+ for element in model:
+ if current_priority == \
+ element[enumerations.PUBLISHER_PRIORITY_CHANGED]:
+ element[
+ enumerations.PUBLISHER_PRIORITY_CHANGED] += 1
+ elif element[enumerations.PUBLISHER_PRIORITY_CHANGED] \
+ == current_priority + 1 :
+ after_name = element[enumerations.PUBLISHER_NAME]
+ element[
+ enumerations.PUBLISHER_PRIORITY_CHANGED] -= 1
+ self.priority_changes.append([enumerations.PUBLISHER_MOVE_AFTER,
+ current_name, after_name])
+ self.__enable_disable_updown_btn(itr, model)
+ self.__move_to_cursor()
+
+ def __on_manage_cancel_clicked(self, widget):
+ self.__on_manage_publishers_delete_event(
+ self.w_manage_publishers_dialog, None)
+
+ def __on_manage_ok_clicked(self, widget):
+ self.__prepare_confirmation_dialog()
+
+ def __on_publishers_apply_delete_event(self, widget, event):
+ self.__on_apply_cancel_clicked(None)
+ return True
+
+ def __on_addmirror_button_clicked(self, widget):
+ if self.w_addmirror_button.get_property('sensitive') == 0:
+ return
+ new_mirror = self.w_addmirror_entry.get_text()
+ self.__add_mirror(new_mirror)
+
+ def __on_addorigin_button_clicked(self, widget):
+ if self.w_addorigin_button.get_property('sensitive') == 0:
+ return
+ new_origin = self.w_addorigin_entry.get_text()
+ self.__add_origin(new_origin)
+
+ def __on_rmmirror_button_clicked(self, widget):
+ self.__rm_mirror()
+
+ def __on_rmorigin_button_clicked(self, widget):
+ self.__rm_origin()
+
+ def __on_repositorymodifyok_clicked(self, widget):
+ pub = self.repository_modify_publisher
+ if pub == None:
+ return
+ error_dialog_title = _("Modify Publisher - %s") % \
+ self.__get_pub_display_name(pub)
+ text = self.w_pub_sig_name_entry.get_text()
+ req_names = self.w_pub_sig_name_radiobutton.get_active()
+ if not gui_misc.check_sig_required_names_policy(text,
+ req_names, error_dialog_title):
+ return
+
+ self.publishers_apply.set_title(_("Applying Changes"))
+ self.__run_with_prog_in_thread(self.__proceed_modifyrepo_ok)
+
+ def __on_modifydialog_delete_event(self, widget, event):
+ if self.w_repositorymodifyok_button.get_sensitive():
+ self.__on_repositorymodifyok_clicked(None)
+ elif not self.is_alias_valid and self.name_error:
+ pub = self.repository_modify_publisher
+ gui_misc.error_occurred(None, self.name_error,
+ _("Modify Publisher - %s") %
+ self.__get_pub_display_name(pub),
+ gtk.MESSAGE_INFO)
+ return True
+
+ def __on_repositorymodifycancel_clicked(self, widget):
+ self.__delete_widget_handler_hide(
+ self.w_modify_repository_dialog, None)
+
+ def __on_cancel_conf_clicked(self, widget):
+ self.__delete_widget_handler_hide(
+ self.w_confirmation_dialog, None)
+
+ def __on_ok_conf_clicked(self, widget):
+ self.w_confirmation_dialog.hide()
+ self.publishers_apply.set_title(_("Applying Changes"))
+ self.__run_with_prog_in_thread(self.__proceed_after_confirmation,
+ self.w_manage_publishers_dialog)
+
+#-----------------------------------------------------------------------------#
+# Static Methods
+#-----------------------------------------------------------------------------#
+ @staticmethod
+ def __check_if_ignore(pub, removed_list):
+ """If we remove a publisher from our model, the priorities of
+ subsequent publishers are decremented. We need to ignore the
+ priority changes caused solely by publisher(s) removal.
+ This function returns True if the priority change for a publisher
+ is due to publisher(s) removal or False otherwise."""
+ priority_sum = 0
+ priority = pub[enumerations.PUBLISHER_PRIORITY]
+ priority_changed = pub[enumerations.PUBLISHER_PRIORITY_CHANGED]
+ for num in removed_list:
+ if num < priority:
+ priority_sum += 1
+ return (priority == priority_changed + priority_sum)
+
+ @staticmethod
+ def __on_add_pub_help_clicked(widget):
+ gui_misc.display_help("add-publisher")
+
+ @staticmethod
+ def __on_manage_help_clicked(widget):
+ gui_misc.display_help("manage-publisher")
+
+ def __on_modify_repo_help_clicked(self, widget):
+ pagenum = self.w_modify_pub_notebook.get_current_page()
+ if pagenum == MODIFY_NOTEBOOK_GENERAL_PAGE:
+ tag = "modify-publisher"
+ elif pagenum == MODIFY_NOTEBOOK_CERTIFICATE_PAGE:
+ tag = "manage-certs"
+ else:
+ tag = "pub-sig-policy"
+ gui_misc.display_help(tag)
+
+ @staticmethod
+ def __update_publisher_details(pub, details_view):
+ if pub == None:
+ return
+ details_buffer = details_view.get_buffer()
+ details_buffer.set_text("")
+ uri_itr = details_buffer.get_start_iter()
+ repo = pub.repository
+ num = len(repo.origins)
+ if pub.sys_pub:
+ details_buffer.insert_with_tags_by_name(uri_itr,
+ _("System Publisher"),
+ "level0")
+ sys_pub_str = _("Cannot be modified or removed.")
+ details_buffer.insert(uri_itr, "\n%s\n" % sys_pub_str)
+ origin_txt = ngettext("Origin:\n", "Origins:\n", num)
+ details_buffer.insert_with_tags_by_name(uri_itr,
+ origin_txt, "level0")
+ uri_itr = details_buffer.get_end_iter()
+ for origin in repo.origins:
+ details_buffer.insert(uri_itr, "%s\n" % str(origin))
+
+ def __show_errors(self, errors, missing_ssl = False):
+ error_msg = ""
+ crerr = ""
+ msg_type = gtk.MESSAGE_ERROR
+ framework_error = False
+
+ msg_title = _("Publisher Error")
+ for err in errors:
+ if isinstance(err[1], api_errors.CatalogRefreshException):
+ res = gui_misc.get_catalogrefresh_exception_msg(err[1])
+ crerr = res[0]
+ framework_error = res[1]
+ logger.error(crerr)
+ gui_misc.notify_log_error(self.parent)
+ else:
+ error_msg += str(err[1])
+ error_msg += "\n\n"
+ # If the only error is a CatalogRefreshException, which we
+ # normally just log but do not display to the user, then
+ # display it to the user.
+ if error_msg == "":
+ error_msg = crerr
+ error_msg += "\n"
+ if framework_error and missing_ssl:
+ error_msg += _("Note: this may may be the result "
+ "of specifying a https Origin, "
+ "but no SSL key and certificate.\n")
+ elif missing_ssl:
+ error_msg += _("Note: this error may be the result of "
+ "specifing a https URI, "
+ "but no SSL key and certificate.\n")
+ if error_msg != "":
+ gui_misc.error_occurred(None, error_msg, msg_title, msg_type)
+
+ @staticmethod
+ def __keybrowse(w_parent, key_entry, cert_entry):
+ chooser = gtk.FileChooserDialog(
+ title=_("Specify SSL Key File"),
+ parent = w_parent,
+ action=gtk.FILE_CHOOSER_ACTION_OPEN,
+ buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+ chooser.set_default_response(gtk.RESPONSE_OK)
+ chooser.set_transient_for(w_parent)
+ chooser.set_modal(True)
+ response = chooser.run()
+ if response == gtk.RESPONSE_OK:
+ key = chooser.get_filename()
+ key_entry.set_text(key)
+ cert = key.replace("key", "certificate")
+ if key != cert and \
+ cert_entry.get_text() == "":
+ if os.path.isfile(cert):
+ cert_entry.set_text(cert)
+ chooser.destroy()
+
+ @staticmethod
+ def __certbrowse(w_parent, cert_entry):
+ chooser = gtk.FileChooserDialog(
+ title=_("Specify SSL Certificate File"),
+ parent = w_parent,
+ action=gtk.FILE_CHOOSER_ACTION_OPEN,
+ buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+ gtk.STOCK_OPEN, gtk.RESPONSE_OK))
+ chooser.set_default_response(gtk.RESPONSE_OK)
+ chooser.set_transient_for(w_parent)
+ chooser.set_modal(True)
+ response = chooser.run()
+ if response == gtk.RESPONSE_OK:
+ cert_entry.set_text(
+ chooser.get_filename())
+ chooser.destroy()
+
+ @staticmethod
+ def __delete_widget_handler_hide(widget, event):
+ widget.hide()
+ return True
+
+ def __check_publisher_exists(self, api_o, name, origin_url):
+ try:
+ pub = api_o.get_publisher(prefix=name, alias=name,
+ duplicate=True)
+ raise URIExistingPublisher(origin_url, pub)
+ except api_errors.UnknownPublisher:
+ return False
+ except api_errors.ApiException, e:
+ gobject.idle_add(self.__show_errors, [(name, e)])
+ return True
+
+ def __setup_publisher_from_uri(self, alias, origin_url, ssl_key, ssl_cert):
+ try:
+ self.api_o.reset()
+ repo = publisher.RepositoryURI(origin_url,
+ ssl_key = ssl_key, ssl_cert = ssl_cert)
+ pubs = self.api_o.get_publisherdata(repo=repo)
+ if not pubs:
+ raise NoPublishersForURI(origin_url)
+ src_pub = sorted(pubs)[0]
+ #For now only handling single Pub per Origin
+ if len(pubs) > 1:
+ if self.webinstall_new:
+ client_name = _("Web Install")
+ else:
+ client_name = _("Package Manager")
+ user_image_root = ""
+ if self.parent.image_directory != "/":
+ user_image_root = "-R " + \
+ self.parent.image_directory + " "
+ logger.warning(
+ _("Origin URI: %(origin_url)s"
+ "\nhas %(number_pubs)d publishers associated with it.\n"
+ "%(client_name)s will attempt to add the first "
+ "publisher, %(pub_name)s.\n"
+ "To add the remaining publishers use the command:\n"
+ "'pkg %(user_image_root)sset-publisher "
+ "-p %(origin_url)s'") %
+ {"origin_url": origin_url,
+ "number_pubs": len(pubs),
+ "client_name": client_name,
+ "pub_name": src_pub.prefix,
+ "user_image_root": user_image_root,
+ })
+ if not self.webinstall_new:
+ gui_misc.notify_log_warning(self.parent)
+ src_repo = src_pub.repository
+ add_origins = []
+ if not src_repo or not src_repo.origins:
+ add_origins.append(origin_url)
+ repo = src_pub.repository
+ if not repo:
+ repo = publisher.Repository()
+ src_pub.repository = repo
+ for url in add_origins:
+ repo.add_origin(url)
+ return (src_pub, repo, True)
+ except api_errors.ApiException, e:
+ if self.__is_ssl_scheme(origin_url) and \
+ ((not ssl_key or len(ssl_key) == 0) or \
+ (not ssl_cert or len(ssl_cert) == 0)) and \
+ gui_misc.is_frameworkerror(e):
+ ssl_missing = True
+ else:
+ ssl_missing = False
+ gobject.idle_add(self.__show_errors, [(alias, e)], ssl_missing)
+ return (None, None, False)
+
+ def __get_or_create_pub_with_url(self, api_o, name, origin_url):
+ new_pub = False
+ repo = None
+ pub = None
+ try:
+ pub = api_o.get_publisher(prefix=name, alias=name,
+ duplicate=True)
+ raise URIExistingPublisher(origin_url, pub)
+ except api_errors.UnknownPublisher:
+ repo = publisher.Repository()
+ # We need to specify a name when creating a publisher
+ # object. It does not matter if it is wrong as the
+ # __update_publisher() call in __add_repository() will
+ # fail and it is dealt with there.
+ if name == None:
+ name = "None"
+ pub = publisher.Publisher(name, repository=repo)
+ new_pub = True
+ # This part is copied from "def publisher_set(img, args)"
+ # from the client.py as the publisher API is not ready yet.
+ if not repo.origins:
+ repo.add_origin(origin_url)
+ origin = repo.origins[0]
+ else:
+ origin = repo.origins[0]
+ origin.uri = origin_url
+ except api_errors.ApiException, e:
+ gobject.idle_add(self.__show_errors, [(name, e)])
+ return (pub, repo, new_pub)
+
+ @staticmethod
+ def __update_ssl_creds(pub, repo, ssl_cert, ssl_key):
+ errors = []
+ # Assume the user wanted to update the ssl_cert or ssl_key
+ # information for *all* of the currently selected
+ # repository's origins and mirrors.
+ try:
+ for uri in repo.origins:
+ if uri.scheme not in publisher.SSL_SCHEMES:
+ continue
+ uri.ssl_cert = ssl_cert
+ uri.ssl_key = ssl_key
+ for uri in repo.mirrors:
+ if uri.scheme not in publisher.SSL_SCHEMES:
+ continue
+ uri.ssl_cert = ssl_cert
+ uri.ssl_key = ssl_key
+ except api_errors.ApiException, e:
+ errors.append((pub, e))
+ return errors
+
+ @staticmethod
+ def __get_fitr_model_from_tree(treeview):
+ tsel = treeview.get_selection()
+ selection = tsel.get_selected()
+ itr = selection[1]
+ if itr == None:
+ return (None, None)
+ model = selection[0]
+ return (itr, model)
+
+ @staticmethod
+ def __show_error_label_with_format(w_label, error_string):
+ error_str = ERROR_FORMAT % error_string
+ w_label.set_markup(error_str)
+ w_label.set_sensitive(True)
+ w_label.show()
+
+ def __is_url_valid(self, url):
+ url_error = None
+ if len(url) == 0:
+ return False, url_error
+ try:
+ publisher.RepositoryURI(url)
+ return True, url_error
+ except api_errors.PublisherError:
+ # Check whether the user has started typing a valid URL.
+ # If he has we do not display an error message.
+ valid_start = False
+ for val in publisher.SUPPORTED_SCHEMES:
+ check_str = "%s://" % val
+ if check_str.startswith(url):
+ valid_start = True
+ break
+ if valid_start:
+ url_error = None
+ else:
+ url_error = _("URI is not valid")
+ return False, url_error
+ except api_errors.ApiException, e:
+ self.__show_errors([("", e)])
+ return False, url_error
+
+ def __validate_ssl_key_cert(self, origin_url, ssl_key, ssl_cert,
+ ignore_ssl_check_for_not_https = False):
+ '''The SSL Cert and SSL Key may be valid and contain no error'''
+ ssl_error = None
+ ssl_valid = True
+ if origin_url and not self.__is_ssl_scheme(origin_url):
+ if ignore_ssl_check_for_not_https:
+ return ssl_valid, ssl_error
+ if (ssl_key != None and len(ssl_key) != 0) or \
+ (ssl_cert != None and len(ssl_cert) != 0):
+ ssl_error = _("SSL should not be specified")
+ ssl_valid = False
+ elif (ssl_key == None or len(ssl_key) == 0) or \
+ (ssl_cert == None or len(ssl_cert) == 0):
+ ssl_valid = True
+ elif origin_url == None or self.__is_ssl_scheme(origin_url):
+ if (ssl_key == None or len(ssl_key) == 0) or \
+ (ssl_cert == None or len(ssl_cert) == 0):
+ # Key and Cert need not be specified
+ ssl_valid = True
+ elif not os.path.isfile(ssl_key):
+ ssl_error = _("SSL Key not found at specified location")
+ ssl_valid = False
+ elif not os.path.isfile(ssl_cert):
+ ssl_error = \
+ _("SSL Certificate not found at specified location")
+ ssl_valid = False
+ return ssl_valid, ssl_error
+
+ @staticmethod
+ def __is_ssl_scheme(uri):
+ ret_val = False
+ for val in publisher.SSL_SCHEMES:
+ if uri.startswith(val):
+ ret_val = True
+ break
+ return ret_val
+
+ @staticmethod
+ def __init_mirrors_tree_view(treeview):
+ # URI column - 0
+ uri_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_("Mirror URI"),
+ uri_renderer, text = 0)
+ column.set_expand(True)
+ treeview.append_column(column)
+
+ @staticmethod
+ def __init_origins_tree_view(treeview):
+ # URI column - 0
+ uri_renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn(_("Origin URI"),
+ uri_renderer, text = 0)
+ column.set_expand(True)
+ treeview.append_column(column)
+
+ @staticmethod
+ def __get_publishers_liststore():
+ return gtk.ListStore(
+ gobject.TYPE_INT, # enumerations.PUBLISHER_PRIORITY
+ gobject.TYPE_INT, # enumerations.PUBLISHER_PRIORITY_CHANGED
+ gobject.TYPE_STRING, # enumerations.PUBLISHER_NAME
+ gobject.TYPE_STRING, # enumerations.PUBLISHER_ALIAS
+ gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_ENABLED
+ gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_STICKY
+ gobject.TYPE_PYOBJECT, # enumerations.PUBLISHER_OBJECT
+ gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_ENABLE_CHANGED
+ gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_STICKY_CHANGED
+ gobject.TYPE_BOOLEAN, # enumerations.PUBLISHER_REMOVED
+ )
+
+ @staticmethod
+ def __get_mirrors_origins_liststore():
+ return gtk.ListStore(
+ gobject.TYPE_STRING, # name
+ )
+
+ @staticmethod
+ def __publishers_filter(model, itr):
+ return not model.get_value(itr, enumerations.PUBLISHER_REMOVED)
+
+ @staticmethod
+ def __toggle_data_function(column, renderer, model, itr, data):
+ if itr:
+ # Do not allow to remove the publisher if it is a system
+ # publisher
+ val = True
+ pub = model.get_value(itr,
+ enumerations.PUBLISHER_OBJECT)
+ if pub.sys_pub:
+ val = False
+ renderer.set_property("sensitive", val)
+
+ @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
+
+#-----------------------------------------------------------------------------#
+# Public Methods
+#-----------------------------------------------------------------------------#
+ def webinstall_new_pub(self, parent, pub = None):
+ if pub == None:
+ return
+ self.repository_modify_publisher = pub
+ repo = pub.repository
+ origin_uri = ""
+ if repo != None and repo.origins != None and len(repo.origins) > 0:
+ origin_uri = repo.origins[0].uri
+ if origin_uri != None and self.__is_ssl_scheme(origin_uri):
+ gui_misc.set_modal_and_transient(self.w_add_publisher_dialog,
+ parent)
+ self.main_window = self.w_add_publisher_dialog
+ self.__on_manage_add_clicked(None)
+ self.w_add_publisher_url.set_text(origin_uri)
+ self.w_add_publisher_alias.set_text(pub.alias)
+ self.w_add_pub_label.hide()
+ self.w_add_pub_instr_label.hide()
+ self.w_add_publisher_url.set_sensitive(False)
+ self.w_add_publisher_alias.set_sensitive(False)
+ reg_uri = self.__get_registration_uri(repo)
+ if reg_uri == None or len(reg_uri) == 0:
+ reg_uri = origin_uri
+ self.w_registration_link.set_uri(reg_uri)
+ self.w_registration_box.show()
+ self.w_ssl_box.show()
+ self.__validate_url(self.w_add_publisher_url,
+ w_ssl_key=self.w_key_entry, w_ssl_cert=self.w_cert_entry)
+ self.w_add_error_label.hide()
+ else:
+ self.main_window = parent
+ self.w_ssl_box.hide()
+ self.__do_add_repository()
+
+ def webinstall_enable_disable_pubs(self, parent, pub_names, to_enable):
+ if pub_names == None:
+ return
+ num = len(pub_names)
+ if to_enable:
+ msg = ngettext("Enabling Publisher", "Enabling Publishers", num)
+ else:
+ msg = ngettext("Disabling Publisher", "Disabling Publishers", num)
+ self.publishers_apply.set_title(msg)
+
+ self.__run_with_prog_in_thread(self.__proceed_enable_disable,
+ parent, None, pub_names, to_enable)
+
+ def update_label_text(self, markup_text):
+ self.__g_update_details_text(markup_text)
+
+ def update_details_text(self, text, *tags):
+ self.__g_update_details_text(text, *tags)
+
+ def update_progress(self, current_progress, total_progress):
+ pass
+
+ def start_bouncing_progress(self):
+ pass
+
+ def is_progress_bouncing(self):
+ self.pylintstub = self
+ return True
+
+ def stop_bouncing_progress(self):
+ pass
+
+ def display_download_info(self):
+ pass
+
+ def display_phase_info(self, phase_name, cur_n, goal_n):
+ pass
+
+ def reset_label_text_after_delay(self):
+ pass
+
+class URIExistingPublisher(api_errors.ApiException):
+ def __init__(self, uri, pub):
+ api_errors.ApiException.__init__(self)
+ self.uri = uri
+ self.pub = pub
+
+ def __str__(self):
+ return _("The URI '%(uri)s' points to a publisher "
+ "'%(publisher)s' which already exists "
+ "on the system.") % { "uri": self.uri,
+ "publisher": self.pub }
+
+class NoPublishersForURI(api_errors.ApiException):
+ def __init__(self, uri):
+ api_errors.ApiException.__init__(self)
+ self.uri = uri
+
+ def __str__(self):
+ return _("There are no publishers associated with the URI "
+ "'%s'.") % self.uri
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/searcherror.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,105 @@
+#!/usr/bin/python
+#
+# 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 2010 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+import sys
+try:
+ import pango
+except ImportError:
+ sys.exit(1)
+import pkg.gui.misc as gui_misc
+
+class SearchError:
+ def __init__(self, builder, gconf, parent):
+ self.gconf = gconf
+ self.parent = parent
+ self.api_search_error_dialog = \
+ builder.get_object("api_search_error")
+ self.api_search_error_textview = \
+ builder.get_object("api_search_error_text")
+ self.api_search_checkbox = \
+ builder.get_object("api_search_checkbox")
+ self.api_search_button = \
+ builder.get_object("api_search_button")
+ infobuffer = self.api_search_error_textview.get_buffer()
+ infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+ self.pylintstub = None
+
+ def setup_signals(self):
+ signals_table = [
+ (self.api_search_checkbox, "toggled",
+ self.__on_api_search_checkbox_toggled),
+ (self.api_search_button, "clicked",
+ self.__on_api_search_button_clicked),
+ (self.api_search_error_dialog, "delete_event",
+ self.__on_api_search_error_delete_event)
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def set_modal_and_transient(self, parent_window):
+ gui_misc.set_modal_and_transient(self.api_search_error_dialog,
+ parent_window)
+
+ def __on_api_search_error_delete_event(self, widget, event):
+ self.__on_api_search_button_clicked(None)
+
+ def __on_api_search_button_clicked(self, widget):
+ self.api_search_error_dialog.hide()
+
+ def __on_api_search_checkbox_toggled(self, widget):
+ active = self.api_search_checkbox.get_active()
+
+ repos = self.parent.get_current_repos_with_search_errors()
+ if len(repos) > 0:
+ if active:
+ for pub, err_type, err_str in repos:
+ if pub not in self.gconf.not_show_repos:
+ self.gconf.not_show_repos += pub + ","
+ self.pylintstub = err_type
+ self.pylintstub = err_str
+ else:
+ for pub, err_type, err_str in repos:
+ self.gconf.not_show_repos = \
+ self.gconf.not_show_repos.replace(
+ pub + ",", "")
+ self.gconf.set_not_show_repos(self.gconf.not_show_repos)
+
+ def display_search_errors(self, show_all):
+ repos = self.parent.get_current_repos_with_search_errors()
+ infobuffer = self.api_search_error_textview.get_buffer()
+ infobuffer.set_text("")
+ textiter = infobuffer.get_end_iter()
+ for pub, err_type, err_str in repos:
+
+ if show_all or (pub not in self.gconf.not_show_repos):
+ infobuffer.insert_with_tags_by_name(textiter,
+ "%(pub)s (%(err_type)s)\n" % {"pub": pub,
+ "err_type": err_type}, "bold")
+ infobuffer.insert(textiter, "%s\n" % (err_str))
+
+ self.api_search_checkbox.set_active(False)
+ self.api_search_error_dialog.show()
+ self.api_search_button.grab_focus()
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/startpage.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,769 @@
+#!/usr/bin/python
+#
+# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+import os
+import sys
+import urllib
+import urlparse
+import locale
+import re
+from gettext import ngettext
+
+try:
+ import gtkhtml2
+ import gtk
+except ImportError:
+ sys.exit(1)
+import pkg.gui.misc as gui_misc
+import pkg.gui.parseqs as parseqs
+from pkg.client import global_settings
+import pkg.gui.enumerations as enumerations
+import pkg.gui.repository as repository
+
+logger = global_settings.logger
+
+(
+DISPLAY_LINK,
+CLICK_LINK,
+) = range(2)
+
+# Load Start Page from lang dir if available
+START_PAGE_CACHE_LANG_BASE = "var/pkg/gui_cache/startpagebase/%s/%s"
+START_PAGE_LANG_BASE = "usr/share/package-manager/data/startpagebase/%s/%s"
+START_PAGE_HOME = "startpage.html" # Default page
+START_PAGE_IMAGES_BASE = "/usr/share/package-manager/data/startpagebase/C"
+
+# StartPage Action support for url's on StartPage pages
+PM_ACTION = 'pm-action' # Action field for StartPage url's
+
+# Internal Example: <a href="pm?pm-action=internal&uri=top_picks.html">
+ACTION_INTERNAL = 'internal' # Internal Action value: pm-action=internal
+INTERNAL_URI = 'uri' # Internal field: uri to navigate to in StartPage
+ # without protocol scheme specified
+INTERNAL_SEARCH = 'search' # Internal field: search support page action
+INTERNAL_SEARCH_VIEW_RESULTS = "view_recent_search"
+ # Internal field: view recent search results
+INTERNAL_SEARCH_VIEW_PUB ="view_pub_packages" # Internal field: view publishers packages
+INTERNAL_SEARCH_VIEW_ALL = "view_all_packages_filter" # Internal field: change to View
+ # All Packages
+INTERNAL_SEARCH_ALL_PUBS_PAGE = "search_all_publishers_page"
+ #Internal field: go to search all publishers page
+INTERNAL_SEARCH_ALL_PUBS = "search_all_publishers" #Internal field: search all publishers
+INTERNAL_SEARCH_ALL_PUBS_INSTALLED = "search_all_publishers_installed"
+ #Internal field: search all publishers installed
+INTERNAL_SEARCH_HELP = "search_help" # Internal field: display search help
+
+INTERNAL_SEARCH_MNG_PUBS = "search_mng_pubs"
+ # Internal field: display Manage Publishers dialog
+
+FONTSIZE_H3_DEFAULT = 16 # Default H3 font size when display web page
+FONTSIZE_BODY_DEFAULT = 10 # Default Body font size when display web page
+
+# External Example: <a href="pm?pm-action=external&uri=www.opensolaris.com">
+ACTION_EXTERNAL = 'external' # External Action value: pm-action=external
+EXTERNAL_URI = 'uri' # External field: uri to navigate to in external
+ # default browser without protocol scheme specified
+EXTERNAL_PROTOCOL = 'protocol' # External field: optional protocol scheme,
+ # defaults to http
+DEFAULT_PROTOCOL = 'http'
+
+# Theme: use High Contrast or Inverse images for HCI and HC themes, specified by prefix
+INFORMATION_TABLE_HEADER = (
+ "<table border='0' cellpadding='3' style='table-layout:fixed' >"
+ "<TR><TD><IMG SRC = '%(base)s/%(prefix)sdialog-information.png' "
+ "style='border-style: none' "
+ )
+HIGH_CONTRAST_PREFIX = "hc_"
+HIGH_CONTRAST_INV_PREFIX = "hci_"
+
+debug = False
+
+class StartPage:
+ def __init__(self, parent, application_dir):
+ self.application_dir = application_dir
+ self.current_url = None
+ self.document = None
+ self.lang = None
+ self.lang_root = None
+ self.cached_internal_stream = ""
+ self.opener = None
+ self.parent = parent
+ self.start_page_uri = ""
+ self.view = None
+ self.page_bg = "#ffff"
+ self.page_fg = "#0000"
+ self.image_prefix = ""
+ s = gtk.settings_get_default()
+ self.theme_name = s.get_property("gtk-theme-name")
+ self.font_scale = 1.0
+ self.h3_fontsize = FONTSIZE_H3_DEFAULT
+ self.body_fontsize = FONTSIZE_BODY_DEFAULT
+ self.show_start_page = False
+
+ def setup_startpage(self, show_page = True):
+ self.opener = urllib.FancyURLopener()
+ self.document = gtkhtml2.Document()
+ self.document.connect('request_url', self.__request_url)
+ self.document.connect('link_clicked', self.__handle_link)
+ self.document.clear()
+
+ self.view = gtkhtml2.View()
+ self.view.set_document(self.document)
+ self.view.connect('request_object', self.__request_object)
+ self.view.connect('on_url', self.__on_url)
+ self.view.connect('style-set', self.__style_set)
+ try:
+ result = locale.getlocale(locale.LC_CTYPE)
+ self.lang = result[0]
+ except locale.Error:
+ self.lang = "C"
+ if self.lang == None or self.lang == "":
+ self.lang = "C"
+ self.lang_root = self.lang.split('_')[0]
+ # Load Start Page to setup base URL to allow loading images in other pages
+ self.load_startpage(show_page)
+
+ # Theme: on Theme change setup bg and fg colours and prefix for loading pages
+ def __style_set(self, widget, style, data=None):
+ self.font_scale = gui_misc.get_scale(
+ self.parent.detailspanel.w_generalinfo_textview)
+ if self.font_scale < 1.0:
+ self.font_scale = 1.0
+
+ self.h3_fontsize = \
+ int(round(FONTSIZE_H3_DEFAULT * self.font_scale))
+ self.body_fontsize = \
+ int(round(FONTSIZE_BODY_DEFAULT * self.font_scale))
+
+ s = gtk.settings_get_default()
+ self.theme_name = s.get_property("gtk-theme-name")
+
+ style = self.parent.w_application_treeview.get_style().copy()
+ self.page_bg = style.bg[gtk.STATE_NORMAL]
+ self.page_fg = style.fg[gtk.STATE_NORMAL]
+
+ self.image_prefix = ""
+ if self.theme_name == "HighContrastInverse" or \
+ self.theme_name == "HighContrastLargePrintInverse":
+ self.image_prefix = HIGH_CONTRAST_INV_PREFIX
+ elif self.theme_name == "HighContrast" or \
+ self.theme_name == "HighContrastLargePrint":
+ self.image_prefix = HIGH_CONTRAST_PREFIX
+
+ self.handle_resize()
+
+ def load_startpage(self, show = True):
+ self.show_start_page = show
+ if not show:
+ return
+ self.cached_internal_stream = ""
+ if self.__load_startpage_locale(START_PAGE_CACHE_LANG_BASE):
+ return
+ if self.__load_startpage_locale(START_PAGE_LANG_BASE):
+ return
+ self.link_load_error(self.start_page_uri)
+
+ # Stub handler required by GtkHtml widget
+ def __request_object(self, *vargs):
+ pass
+
+ def __load_startpage_locale(self, start_page_lang_base):
+ self.start_page_uri = os.path.join(self.application_dir,
+ start_page_lang_base % (self.lang, START_PAGE_HOME))
+ if self.__load_internal_uri(self.document, self.start_page_uri):
+ return True
+
+ if self.lang_root != None and self.lang_root != self.lang:
+ self.start_page_uri = os.path.join(self.application_dir,
+ start_page_lang_base % (self.lang_root, START_PAGE_HOME))
+ if self.__load_internal_uri(self.document, self.start_page_uri):
+ return True
+
+ self.start_page_uri = os.path.join(self.application_dir,
+ start_page_lang_base % ("C", START_PAGE_HOME))
+ if self.__load_internal_uri(self.document, self.start_page_uri):
+ return True
+ return False
+
+ # Stub handler required by GtkHtml widget or widget will assert
+ def __stream_cancel(self, *vargs):
+ pass
+
+ def __load_internal_uri(self, document, link):
+ self.parent.update_statusbar_message(_("Loading... %s") % link)
+ try:
+ f = self.__open_url(link)
+ except (IOError, OSError):
+ self.parent.update_statusbar_message(_("Stopped"))
+ return False
+ self.current_url = self.__resolve_uri(link)
+
+ self.document.clear()
+ headers = f.info()
+ mime = headers.getheader('Content-type').split(';')[0]
+ if mime:
+ self.document.open_stream(mime)
+ else:
+ self.document.open_stream('text/plain')
+
+ text = f.read()
+ # Theme: use current Theme's bg and fg colours in internally loaded uri
+ text = text.replace('<body>',
+ "<body fgcolor='%s' bgcolor='%s'>" % (self.page_fg, self.page_bg))
+
+ # Theme: setup Start Page for current Theme
+ if link.endswith(START_PAGE_HOME):
+ text = self.__process_startpage(text)
+ self.document.write_stream(text)
+ self.document.close_stream()
+ self.parent.update_statusbar_message(_("Done"))
+ return True
+
+ # Theme: setup Start Page for the current Theme
+ def __process_startpage(self, text):
+ # Strip background and all style colors for High Contrast, Inverse and
+ # Low Contrast Themes
+ if self.theme_name.startswith("HighContrast") or \
+ self.theme_name.startswith("LowContrast"):
+ text = re.sub("background-color: #\w+; ", "", text)
+ text = re.sub('style="background-color: #\w+"', "", text)
+ text = re.sub("color: #\w+;", "", text)
+ if self.font_scale > 1.0:
+ text = re.sub("font-size: 20pt;",
+ "font-size: %dpx;" % int(round(20 * self.font_scale)), text)
+ text = re.sub("font-size: 15px;",
+ "font-size: %dpx;" % int(round(15 * self.font_scale)), text)
+ text = re.sub("font-size: 14px;",
+ "font-size: %dpx;" % int(round(14 * self.font_scale)), text)
+ text = re.sub('width="125"',
+ 'width="%d"' % int(round(125 * self.font_scale)), text)
+
+ # Use High Contrast and Inverse images for HC and HCI themes
+ if self.image_prefix != "":
+ text = re.sub("/\w*install.png",
+ "/" + self.image_prefix + "install.png", text)
+ # OpenSolaris icon renders poorly on Low Contrast and dark nimbus themes
+ # replace with text link
+ if self.theme_name.startswith("LowContrast") or \
+ self.theme_name == "dark-nimbus":
+ text = re.sub(
+ '<td><a href="http://www.opensolaris.com">'
+ '<IMG SRC = "opensolaris.png" align="right"/></a></td>',
+ '<td align="right"><a href="http://www.opensolaris.com">'
+ 'OpenSolaris... </a></td>', text)
+ elif self.image_prefix != "":
+ text = re.sub(
+ "opensolaris.png",
+ self.image_prefix + "opensolaris.png", text)
+ return text
+
+ def __request_url(self, document, url, stream):
+ try:
+ f = self.__open_url(url)
+ except (IOError, OSError), err:
+ logger.error(str(err))
+ gui_misc.notify_log_error(self.parent)
+ return
+ stream.set_cancel_func(self.__stream_cancel)
+ stream.write(f.read())
+
+ def __handle_link(self, document, link, handle_what = CLICK_LINK):
+ query_dict = self.__urlparse_qs(link)
+
+ action = None
+ if query_dict.has_key(PM_ACTION):
+ action = query_dict[PM_ACTION][0]
+ elif handle_what == DISPLAY_LINK:
+ return link
+
+ search_action = None
+ if action == ACTION_INTERNAL:
+ if query_dict.has_key(INTERNAL_SEARCH):
+ search_action = query_dict[INTERNAL_SEARCH][0]
+
+ s1, e1 = self.parent.get_start_end_strings()
+
+ # Browse a Publisher
+ if search_action and search_action.find(INTERNAL_SEARCH_VIEW_PUB) > -1:
+ pub = re.findall(r'<b>(.*)<\/b>', search_action)[0]
+ if handle_what == DISPLAY_LINK:
+ pub_name = \
+ self.parent.get_publisher_display_name_from_prefix(
+ pub)
+ return _("View packages in %(s1)s%(pub)s%(e1)s") % \
+ {"s1": s1, "pub": \
+ pub_name, "e1": e1}
+ self.parent.browse_publisher(pub)
+ return
+
+ # Go to Search in All Publishers page
+ if search_action and search_action == INTERNAL_SEARCH_ALL_PUBS_PAGE:
+ if handle_what == DISPLAY_LINK:
+ return _("Go to Search %(s1)sAll Publishers%(e1)s page")\
+ % {"s1": s1, "e1": e1}
+ self.parent.pm_setup_search_all_page()
+ return
+
+ # Search in All Publishers
+ if search_action and search_action == INTERNAL_SEARCH_ALL_PUBS:
+ if handle_what == DISPLAY_LINK:
+ return _("Search within %(s1)sAll Publishers%(e1)s") % \
+ {"s1": s1, "e1": e1}
+ self.parent.handle_search_all_publishers()
+ return
+
+ # Change view to All Publishers (Installed)
+ if search_action and search_action == INTERNAL_SEARCH_ALL_PUBS_INSTALLED:
+ if handle_what == DISPLAY_LINK:
+ return _("View %(s1)sAll Installed Packages%(e1)s") % \
+ {"s1": s1, "e1": e1}
+ self.parent.handle_view_all_publishers_installed()
+ return
+ # Launch Search Help
+ if search_action and search_action == INTERNAL_SEARCH_HELP:
+ if handle_what == DISPLAY_LINK:
+ return _("Display %(s1)sSearch Help%(e1)s") % \
+ {"s1": s1, "e1": e1}
+ self.parent.update_statusbar_message(
+ _("Loading %(s1)sSearch Help%(e1)s ...") %
+ {"s1": s1, "e1": e1})
+ gui_misc.display_help("search-pkg")
+ return
+
+ if search_action and search_action == INTERNAL_SEARCH_MNG_PUBS:
+ if handle_what == DISPLAY_LINK:
+ return _("Display %(s1)sManage Publishers%(e1)s") % \
+ {"s1": s1, "e1": e1}
+ self.parent.update_statusbar_message(
+ _("Loading %(s1)sManage Publishers%(e1)s ...") %
+ {"s1": s1, "e1": e1})
+
+ repository.Repository(self.parent,
+ self.parent.image_directory,
+ action=enumerations.MANAGE_PUBLISHERS,
+ main_window = self.parent.w_main_window,
+ gconf = self.parent.gconf)
+ return
+
+ # View Recent Search Results
+ if search_action and \
+ search_action.find(INTERNAL_SEARCH_VIEW_RESULTS) > -1:
+ recent_search = \
+ re.findall(r'<span>(.*)<\/span>', search_action)[0]
+ if handle_what == DISPLAY_LINK:
+ return _("View results for %s") % recent_search
+ self.parent.goto_recent_search(recent_search)
+ return
+
+ # Change View to All Packages
+ if search_action and search_action == INTERNAL_SEARCH_VIEW_ALL:
+ if handle_what == DISPLAY_LINK:
+ return _("Change View to %(s1)sAll Packages%(e1)s") % \
+ {"s1": s1, "e1": e1}
+ self.parent.set_view_all_packages()
+ return
+ # Internal Browse
+ if action == ACTION_INTERNAL:
+ if query_dict.has_key(INTERNAL_URI):
+ int_uri = query_dict[INTERNAL_URI][0]
+ if handle_what == DISPLAY_LINK:
+ return int_uri
+ else:
+ if handle_what == CLICK_LINK:
+ self.link_load_error(
+ _("No URI specified"))
+ return
+ if handle_what == CLICK_LINK and \
+ not self.__load_internal_uri(document, int_uri):
+ self.link_load_error(int_uri)
+ return
+ # External browse
+ elif action == ACTION_EXTERNAL:
+ if query_dict.has_key(EXTERNAL_URI):
+ ext_uri = query_dict[EXTERNAL_URI][0]
+ else:
+ if handle_what == CLICK_LINK:
+ self.link_load_error(
+ _("No URI specified"))
+ return
+ if query_dict.has_key(EXTERNAL_PROTOCOL):
+ protocol = query_dict[EXTERNAL_PROTOCOL][0]
+ else:
+ protocol = DEFAULT_PROTOCOL
+
+ if handle_what == DISPLAY_LINK:
+ return protocol + "://" + ext_uri
+ self.parent.open_link(protocol + "://" + ext_uri)
+ return
+ elif handle_what == DISPLAY_LINK:
+ return None
+ elif action == None:
+ if link and link.endswith(".p5i"):
+ self.parent.invoke_webinstall(link)
+ return
+ self.parent.open_link(link)
+ return
+ # Handle empty and unsupported actions
+ elif action == "":
+ self.link_load_error(_("Empty Action not supported"))
+ return
+ elif action != None:
+ self.link_load_error(
+ _("Action not supported: %s") % action)
+ return
+
+ def __on_url(self, view, link):
+ # Handle mouse over events on links and reset when not on link
+ if link == None or link == "":
+ self.parent.update_statusbar()
+ else:
+ display_link = self.__handle_link(None, link, DISPLAY_LINK)
+ if display_link != None:
+ self.parent.update_statusbar_message(display_link)
+ else:
+ self.parent.update_statusbar()
+
+ def __open_url(self, url):
+ uri = self.__resolve_uri(url)
+ return self.opener.open(uri)
+
+ def __resolve_uri(self, uri):
+ if self.__is_relative_to_server(uri) and self.current_url != uri:
+ return urlparse.urljoin(self.current_url, uri)
+ return uri
+
+ @staticmethod
+ def __is_relative_to_server(url):
+ parts = urlparse.urlparse(url)
+ if parts[0] or parts[1]:
+ return 0
+ return 1
+
+ def __load_internal_page(self, text =""):
+ self.cached_internal_stream = text
+ self.document.clear()
+ self.view.show()
+ self.document.open_stream('text/html')
+ # Theme: use Theme's bg and fg colours in loaded internal page
+
+ display = ("<html><head><meta http-equiv='Content-Type' "
+ "content='text/html; charset=UTF-8'></head>"
+ "<style>h3 {font-size:%(h3_fs)dpt}</style>"
+ "<style>body {font-size:%(body_fs)dpt}</style><body "
+ "fgcolor='%(fg)s' bgcolor='%(bg)s'>%(text)s</body></html>" %
+ {"h3_fs": self.h3_fontsize, "body_fs": self.body_fontsize,
+ "fg": self.page_fg, "bg": self.page_bg, "text": text})
+
+ self.document.write_stream(display)
+ self.document.close_stream()
+
+ def load_blank(self):
+ self.__load_internal_page()
+
+ def handle_resize(self):
+ if self.cached_internal_stream == "":
+ if self.show_start_page:
+ self.load_startpage()
+ return
+ # Theme: setup images for current Theme in self.cached_internal_stream
+ # before reloading
+ self.cached_internal_stream = re.sub(
+ "/\w*dialog-information.png",
+ "/" + self.image_prefix + "dialog-information.png",
+ self.cached_internal_stream)
+ self.cached_internal_stream = re.sub(
+ "/\w*dialog-warning.png",
+ "/" + self.image_prefix + "dialog-warning.png",
+ self.cached_internal_stream)
+
+ self.__load_internal_page(self.cached_internal_stream)
+
+ def setup_search_all_no_pubs_page(self):
+ tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
+ "prefix": self.image_prefix}
+ tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
+ "</TD><TD><h3><b>Search All Publishers</b></h3><TD></TD>"
+ "</TR><TR><TD></TD><TD> There is nothing to search as there are no "
+ "configured or enabled publishers.</TD></TR>"
+ )
+
+ tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
+ "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
+ "<TR><TD></TD><TD<TD>"
+ )
+
+ tbl_body += _("<li style='padding-left:7px'>"
+ "Add or enable publishers: <a href='pm?pm-action=internal&search="
+ "%s'>Manage Publishers</a></li></TD></TR>") % INTERNAL_SEARCH_MNG_PUBS
+ tbl_footer = "</table>"
+ self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
+
+
+ def setup_search_all_page(self, publisher_list, publisher_all):
+ if not publisher_list:
+ self.setup_search_all_no_pubs_page()
+ return
+ tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
+ "prefix": self.image_prefix}
+ tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
+ "</TD><TD><h3><b>Search All Publishers</b></h3><TD></TD></TR>"
+ "<TR><TD></TD><TD> Use the Search field to search for packages "
+ "within the following Publishers:</TD></TR>"
+ )
+ tbl_body = "<TR><TD></TD><TD>"
+ pub_browse_list = ""
+ for (prefix, pub_alias) in publisher_list:
+ if pub_alias != None and len(pub_alias) > 0:
+ pub_name = "%s (%s)" % (pub_alias, prefix)
+ else:
+ pub_name = prefix
+
+ tbl_body += "<li style='padding-left:7px'>%s</li>" % pub_name
+ pub_browse_list += "<li style='padding-left:7px'><a href="
+ pub_browse_list += "'pm?pm-action=internal&search=%s" % \
+ INTERNAL_SEARCH_VIEW_PUB
+ if pub_alias != None and len(pub_alias) > 0:
+ name = pub_alias
+ else:
+ name = pub_name
+ pub_browse_list += " <b>%s</b>'>%s</a></li>" % \
+ (prefix, name)
+ tbl_body += "<TD></TD></TR>"
+ tbl_body += _("<TR><TD></TD><TD></TD></TR>"
+ "<TR><TD></TD><TD>Click on the Publishers below to view their list "
+ "of packages:</TD></TR>"
+ )
+ tbl_body += "<TR><TD></TD><TD>"
+ tbl_body += pub_browse_list
+ tbl_body += "<TD></TD></TR>"
+
+ pub_browse_all = "<li style='padding-left:7px'><a href="
+ pub_browse_all += "'pm?pm-action=internal&search=%s" % \
+ INTERNAL_SEARCH_VIEW_PUB
+ pub_browse_all += " <b>%s</b>'>%s</a></li>" % \
+ (publisher_all, publisher_all)
+ tbl_body += _("<TR><TD></TD><TD></TD></TR>"
+ "<TR><TD></TD><TD>Click on the link below to view the full list "
+ "of packages:</TD></TR>"
+ )
+ tbl_body += "<TR><TD></TD><TD>"
+ tbl_body += pub_browse_all
+ tbl_body += "<TD></TD></TR>"
+ tbl_footer = "</table>"
+ self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
+
+ def setup_search_installed_page(self, text):
+ tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
+ "prefix": self.image_prefix}
+ tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
+ "</TD><TD><h3><b>Search in All Installed Packages</b></h3><TD></TD>"
+ "</TR><TR><TD></TD><TD> Search is <b>not</b> supported in "
+ "All Installed Packages.</TD></TR>"
+ )
+
+ tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
+ "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
+ "<TR><TD></TD><TD<TD>"
+ )
+
+ tbl_body += _("<li style='padding-left:7px'>Return to view "
+ "All Installed Packages <a href='pm?pm-action=internal&search="
+ "%s'>(Installed)</a></li>") % INTERNAL_SEARCH_ALL_PUBS_INSTALLED
+ tbl_body += _("<li style='padding-left:7px'>Search for <b>%(text)s"
+ "</b> using All Publishers <a href='pm?pm-action=internal&search="
+ "%(all_pubs)s'>(Search)</a></li>") % \
+ {"text": text, "all_pubs": INTERNAL_SEARCH_ALL_PUBS}
+
+ tbl_body += _("<li style='padding-left:7px'>"
+ "See <a href='pm?pm-action=internal&search="
+ "%s'>Search Help</a></li></TD></TR>") % INTERNAL_SEARCH_HELP
+ tbl_footer = "</table>"
+ self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
+
+ def setup_search_zero_results_page(self, name, text, is_all_publishers):
+ tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
+ "prefix": self.image_prefix}
+ tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
+ "</TD><TD><h3><b>Search Results</b></h3><TD></TD></TR>"
+ "<TR><TD></TD><TD>No packages found in <b>%(pub)s</b> "
+ "matching <b>%(text)s</b></TD></TR>") % {"pub": name, "text": text}
+
+ tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
+ "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
+ "<TR><TD></TD><TD<TD>"
+ "<li style='padding-left:7px'>Check your spelling</li>"
+ "<li style='padding-left:7px'>Try new search terms</li>"
+ )
+ if not is_all_publishers:
+ tbl_body += _("<li style='padding-left:7px'>Search for <b>"
+ "%(text)s</b> within <a href='pm?pm-action=internal&search="
+ "%(all_pubs)s'>All Publishers</a></li>") % \
+ {"text": text, "all_pubs": INTERNAL_SEARCH_ALL_PUBS}
+
+ tbl_body += _("<li style='padding-left:7px'>"
+ "See <a href='pm?pm-action=internal&search="
+ "%s'>Search Help</a></li></TD></TR>") % INTERNAL_SEARCH_HELP
+ tbl_footer = "</table>"
+ self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
+
+ def setup_recent_search_page(self, searches_list):
+ tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
+ "prefix": self.image_prefix}
+ tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
+ "</TD><TD><h3><b>Recent Searches</b></h3><TD></TD></TR>"
+ "<TR><TD></TD><TD> Access stored results from recent searches "
+ "in this session.</TD></TR>"
+ )
+ tbl_body = "<TR><TD></TD><TD>"
+ search_list = ""
+ for search in searches_list:
+ search_list += "<li style='padding-left:7px'>%s: <a href=" % \
+ search
+ search_list += "'pm?pm-action=internal&search=%s" % \
+ INTERNAL_SEARCH_VIEW_RESULTS
+ search_list += " <span>%s</span>'>" % search
+ search_list += _("results")
+ search_list += "</a></li>"
+
+ if len(searches_list) > 0:
+ tbl_body += "<TR><TD></TD><TD></TD></TR><TR><TD></TD><TD>"
+ tbl_body += ngettext(
+ "Click on the search results link below to view the stored "
+ "results:", "Click on one of the search results links below "
+ "to view the stored results:",
+ len(searches_list)
+ )
+ tbl_body += "</TD></TR><TR><TD></TD><TD>"
+ tbl_body += search_list
+ tbl_body += "<TD></TD></TR>"
+ tbl_footer = "</table>"
+ self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
+
+ def setup_zero_filtered_results_page(self, length_visible_list, filter_desc):
+ tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
+ "prefix": self.image_prefix}
+ tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
+ "</TD><TD><h3><b>View Packages</b></h3><TD></TD></TR><TR><TD></TD>"
+ "<TD>")
+ tbl_header += ngettext(
+ "There is one package in this category, "
+ "however it is not visible in the selected View:\n"
+ "<li style='padding-left:7px'><b>%s</b></li>",
+ "There are a number of packages in this category, "
+ "however they are not visible in the selected View:\n"
+ "<li style='padding-left:7px'><b>%s</b></li>",
+ length_visible_list) % filter_desc
+ tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
+ "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
+ "<TR><TD></TD><TD<TD>"
+ )
+ tbl_body += _("<li style='padding-left:7px'>"
+ "<a href='pm?pm-action=internal&"
+ "search=%s'>Change View to All Packages</a></li>") % \
+ INTERNAL_SEARCH_VIEW_ALL
+ tbl_footer = "</TD></TR></table>"
+ self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
+
+ def setup_search_zero_filtered_results_page(self, text, num, filter_desc):
+ tbl_header = INFORMATION_TABLE_HEADER % {"base": START_PAGE_IMAGES_BASE,
+ "prefix": self.image_prefix}
+ tbl_header += _("alt='[Information]' title='Information' ALIGN='bottom'>"
+ "</TD><TD><h3><b>Search Results</b></h3><TD></TD></TR><TR><TD></TD>"
+ "<TD>")
+ tbl_header += ngettext(
+ "Found <b>%(num)s</b> package matching <b>%(text)s</b> "
+ "in All Packages, however it is not listed in the "
+ "<b>%(filter)s</b> View.",
+ "Found <b>%(num)s</b> packages matching <b>%(text)s</b> "
+ "in All Packages, however they are not listed in the "
+ "<b>%(filter)s</b> View.", num) % {"num": num, "text": text,
+ "filter": filter_desc}
+
+ tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
+ "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
+ "<TR><TD></TD><TD<TD>"
+ )
+ tbl_body += _("<li style='padding-left:7px'>"
+ "<a href='pm?pm-action=internal&"
+ "search=%s'>Change View to All Packages</a></li>") % \
+ INTERNAL_SEARCH_VIEW_ALL
+ tbl_footer = "</TD></TR></table>"
+ self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
+
+ def setup_search_wildcard_page(self):
+ tbl_header = _(
+ "<table border='0' cellpadding='3' style='table-layout:fixed' >"
+ "<TR><TD><IMG SRC = '%(base)s/%(prefix)sdialog-warning.png' "
+ "style='border-style: "
+ "none' alt='[Warning]' title='Warning' ALIGN='bottom'></TD>"
+ "<TD><h3><b>Search Warning</b></h3><TD></TD></TR>"
+ "<TR><TD></TD><TD>Search using only the wildcard character, "
+ "<b>*</b>, is not supported in All Publishers</TD></TR>"
+ ) % {"base": START_PAGE_IMAGES_BASE, "prefix": self.image_prefix}
+ tbl_body = _("<TR><TD></TD><TD<TD></TD></TR><TR><TD></TD><TD<TD></TD>"
+ "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
+ "<TR><TD></TD><TD<TD>"
+ "<li style='padding-left:7px'>Try new search terms</li>"
+ )
+ tbl_body += _("<li style='padding-left:7px'>"
+ "Return to <a href='pm?pm-action=internal&search="
+ "%s'>Search All Publishers</a></li>") \
+ % INTERNAL_SEARCH_ALL_PUBS_PAGE
+ tbl_body += _("<li style='padding-left:7px'>"
+ "See <a href='pm?pm-action=internal&search="
+ "%s'>Search Help</a></li></TD></TR>") % INTERNAL_SEARCH_HELP
+ tbl_footer = "</table>"
+ self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
+
+ def link_load_error(self, link):
+ tbl_header = _(
+ "<table border='0' cellpadding='3' style='table-layout:fixed' >"
+ "<TR><TD><a href='stub'></a>"
+ "<IMG SRC = '%(base)s/%(prefix)sdialog-warning.png' "
+ "style='border-style: "
+ "none' alt='[Warning]' title='Warning' ALIGN='bottom'>"
+ "</TD><TD><h3><b>Warning</b></h3><TD></TD></TR>"
+ "<TR><TD></TD><TD>Unable to load the following URI: </TD></TR>"
+ ) % {"base": START_PAGE_IMAGES_BASE, "prefix": self.image_prefix}
+ tbl_body = "<TR><TD></TD><TD<TD>"
+ tbl_body +="<li style='padding-left:7px'>%s</li></TD></TR>" % (link)
+ tbl_body += _("<TR><TD></TD><TD<TD></TD>"
+ "</TR><TR><TD></TD><TD<TD><b>Suggestions:</b><br></TD></TR>"
+ "<TR><TD></TD><TD<TD>"
+ )
+ tbl_body += _("<li style='padding-left:7px'>"
+ "Return to <a href='pm?pm-action=internal&uri="
+ "%s'>Start Page</a></li></TD></TR>") % START_PAGE_HOME
+ tbl_footer = "</table>"
+ self.__load_internal_page(tbl_header + tbl_body + tbl_footer)
+
+ @staticmethod
+ def __urlparse_qs(url, keep_blank_values=0, strict_parsing=0):
+ scheme, netloc, url, params, querystring, fragment = urlparse.urlparse(
+ url)
+ if debug:
+ print ("Query: scheme %s, netloc %s, url %s, params %s,"
+ "querystring %s, fragment %s"
+ % (scheme, netloc, url, params, querystring, fragment))
+ return parseqs.parse_qs(querystring)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/uarenamebe.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,341 @@
+#!/usr/bin/python
+#
+# 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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+import pkg.gui.misc as gui_misc
+import os
+import pkg.misc as misc
+import pkg.client.api_errors as api_errors
+import pkg.client.bootenv as bootenv
+from threading import Thread
+import time
+
+try:
+ import gobject
+ import gtk
+ import pygtk
+ pygtk.require("2.0")
+except ImportError:
+ import sys
+ sys.exit(1)
+
+VALID_BE_NAME = 0
+INVALID_BE_NAME = -1
+DUPLICATE_BE_NAME = -2
+ACTIVATED_BE_NAME = -3 #If the be was not changed by the user
+ERROR_FORMAT = "<span color = \"red\">%s</span>"
+
+class RenameBeAfterUpdateAll:
+ def __init__(self, parent, dialog_icon, parent_window):
+ if not bootenv.BootEnv.libbe_exists():
+ msg = _("The <b>libbe</b> library was not "
+ "found on your system.")
+ msgbox = gtk.MessageDialog(
+ buttons = gtk.BUTTONS_CLOSE,
+ flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_INFO,
+ message_format = None)
+ msgbox.set_markup(msg)
+ msgbox.set_title(_("Rename BE"))
+ msgbox.run()
+ msgbox.destroy()
+ return
+
+ # Before performing update all (image-update) task, we are storing
+ # the active on reboot be name. If the be name after update is different
+ # it means that new BE was created and we can show BE rename dialog
+ # otherwise we can show update completed dialog.
+ # Also we need to store original BE name to work-around the bug: 6472202
+ self.active_be_before_update_all = self.__get_activated_be_name()
+
+ self.parent = parent
+ self.stop_progress_bouncing = False
+ self.stopped_bouncing_progress = True
+ builder = gtk.Builder()
+ gladefile = os.path.join(self.parent.application_dir,
+ "usr/share/package-manager/packagemanager.ui")
+ builder.add_from_file(gladefile)
+
+ self.w_ua_completed_dialog = \
+ builder.get_object("ua_completed_dialog")
+ self.w_ua_be_entry = \
+ builder.get_object("ua_be_entry")
+ self.w_ua_release_notes_button = \
+ builder.get_object("release_notes_button")
+ self.w_be_error_label = \
+ builder.get_object("be_error_label")
+ self.w_ua_help_button = \
+ builder.get_object("ua_help_button")
+ self.w_ua_restart_later_button = \
+ builder.get_object("ua_restart_later_button")
+ self.w_ua_restart_now_button = \
+ builder.get_object("ua_restart_now_button")
+ self.w_ua_ok_image = \
+ builder.get_object("ua_ok_image")
+ self.w_ua_whats_this_button = \
+ builder.get_object("ua_whats_this_button")
+ self.w_ua_whats_this_button.set_tooltip_text(_(
+ "A boot environment (BE) contains the operating\n"
+ "system image and updated packages. The\n"
+ "system will boot into the new BE on restart."))
+
+ self.w_progress_dialog = builder.get_object("progressdialog")
+ self.w_progressinfo_label = builder.get_object("progressinfo")
+ self.w_progress_cancel = builder.get_object("progresscancel")
+ self.w_progressbar = builder.get_object("progressbar")
+ self.w_progress_dialog.connect('delete-event', lambda stub1, stub2: True)
+ self.w_progress_cancel.set_sensitive(False)
+
+ self.w_progress_dialog.set_title(_("Rename BE"))
+ self.w_progressinfo_label.set_text(_("Renaming BE, please wait..."))
+
+ self.w_progress_dialog.set_icon(dialog_icon)
+ self.w_ua_completed_dialog.set_icon(dialog_icon)
+
+ checkmark_icon = gui_misc.get_icon(
+ self.parent.icon_theme, "pm-check", 24)
+
+ self.w_ua_ok_image.set_from_pixbuf(checkmark_icon)
+
+ gui_misc.set_modal_and_transient(self.w_progress_dialog, parent_window)
+ gui_misc.set_modal_and_transient(self.w_ua_completed_dialog,
+ parent_window)
+
+ self.__setup_signals()
+
+ def __setup_signals(self):
+ signals_table = [
+ (self.w_ua_help_button, "clicked",
+ self.__on_ua_help_button_clicked),
+ (self.w_ua_restart_later_button, "clicked",
+ self.__on_ua_restart_later_button_clicked),
+ (self.w_ua_restart_now_button, "clicked",
+ self.__on_ua_restart_now_button_clicked),
+ (self.w_ua_completed_dialog, "delete_event",
+ self.__on_ua_completed_dialog_delete_event),
+ (self.w_ua_be_entry, "changed",
+ self.__on_ua_be_entry_changed),
+ (self.w_ua_whats_this_button, "clicked",
+ self.__on_ua_whats_this_button_clicked),
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def show_rename_dialog(self, updated_packages_list):
+ '''Returns False if no BE rename is needed'''
+ orig_name = self.__get_activated_be_name()
+ if orig_name == self.active_be_before_update_all:
+ self.w_ua_completed_dialog.hide()
+ self.parent.update_package_list(updated_packages_list)
+ return False
+ else:
+ self.__set_release_notes_url()
+ self.__setup_be_name()
+ self.w_ua_completed_dialog.show_all()
+ return True
+
+ def __set_release_notes_url(self):
+ info_url = misc.get_release_notes_url()
+ if info_url and len(info_url) == 0:
+ info_url = gui_misc.RELEASE_URL
+ self.w_ua_release_notes_button.set_uri(info_url)
+
+ def __on_ua_restart_later_button_clicked(self, widget):
+ self.__proceed_after_update()
+
+ def __on_ua_restart_now_button_clicked(self, widget):
+ self.__proceed_after_update(True)
+
+ def __on_ua_whats_this_button_clicked(self, widget):
+ msgbox = gtk.MessageDialog(parent = self.w_ua_completed_dialog,
+ buttons = gtk.BUTTONS_CLOSE,
+ flags = gtk.DIALOG_MODAL,
+ type = gtk.MESSAGE_INFO,
+ message_format = None)
+ msgbox.set_property('text',
+ _(self.w_ua_whats_this_button.get_tooltip_text()))
+ title = _("Update All")
+
+ msgbox.set_title(title)
+ msgbox.run()
+ msgbox.destroy()
+
+ @staticmethod
+ def __on_ua_completed_dialog_delete_event(widget, event):
+ return True
+
+ def __proceed_after_update(self, reboot=False):
+ orig_name = self.__get_activated_be_name()
+ new_name = self.w_ua_be_entry.get_text()
+ Thread(target = self.__set_be_name,
+ args = (orig_name, new_name, reboot)).start()
+ self.w_ua_completed_dialog.hide()
+
+ def __set_be_name(self, orig_name, new_name, reboot):
+ ret_code = self.__verify_be_name(new_name)
+ be_rename_code = 0
+ if ret_code != ACTIVATED_BE_NAME:
+ self.__start_bouncing_progress()
+ be_rename_code = self.__rename_be(orig_name, new_name)
+ if be_rename_code != 0:
+ # Workaround for bug: 6472202
+ # If the rename didn't work for the first time, we should:
+ # - Activate current BE - active_name
+ # - Rename the BE orig_name to BE new_name
+ # - Activate the BE new_name
+ active_name = self.__get_active_be_name()
+ workaround_code = self.__workaround_for_6472202(
+ active_name, orig_name, new_name)
+ if workaround_code != 0:
+ gobject.idle_add(self.__g_be_rename_problem_dialog,
+ new_name, orig_name)
+ if reboot:
+ ret = gui_misc.restart_system()
+ if ret != 0:
+ gobject.idle_add(self.__g_be_reboot_problem_dialog)
+ else:
+ gobject.idle_add(self.parent.shutdown_after_image_update)
+ self.__stop_bouncing_progress()
+ gobject.idle_add(self.parent.shutdown_after_image_update, False)
+
+ @staticmethod
+ def __g_be_rename_problem_dialog(new_name, orig_name):
+ msg_type = gtk.MESSAGE_INFO
+ error_msg = _("Could not change the BE name to:\n\t"
+ "%s\n\nThe following name will be used instead:"
+ "\n\t%s" % (new_name, orig_name))
+ msg_title = _("BE Name")
+ gui_misc.error_occurred(None, error_msg, msg_title, msg_type)
+
+ @staticmethod
+ def __g_be_reboot_problem_dialog():
+ msg_type = gtk.MESSAGE_ERROR
+ error_msg = _("Could not restart the system."
+ "\nPlease restart the system manually.")
+ msg_title = _("Restart Error")
+ gui_misc.error_occurred(None, error_msg, msg_title, msg_type)
+
+ def __on_ua_be_entry_changed(self, widget):
+ if len(widget.get_text()) == 0:
+ self.w_be_error_label.hide()
+ self.__set_buttons_state(False)
+ return
+ ret_code = self.__verify_be_name(widget.get_text())
+ if ret_code == ACTIVATED_BE_NAME:
+ self.__set_buttons_state(True)
+ self.w_be_error_label.hide()
+ elif ret_code == DUPLICATE_BE_NAME:
+ self.__set_buttons_state(False)
+ error_string = _("This name already exists.")
+ error = ERROR_FORMAT % error_string
+ self.w_be_error_label.set_markup(error)
+ self.w_be_error_label.show()
+ elif ret_code == INVALID_BE_NAME:
+ self.__set_buttons_state(False)
+ error_string = _("BE name contains invalid character.")
+ error = ERROR_FORMAT % error_string
+ self.w_be_error_label.set_markup(error)
+ self.w_be_error_label.show()
+ else:
+ self.__set_buttons_state(True)
+ self.w_be_error_label.hide()
+
+ def __set_buttons_state(self, sensitive=False):
+ self.w_ua_restart_later_button.set_sensitive(sensitive)
+ self.w_ua_restart_now_button.set_sensitive(sensitive)
+
+ def __setup_be_name(self):
+ proposed_name = self.__get_activated_be_name()
+ self.w_ua_be_entry.set_text(proposed_name)
+
+ def __verify_be_name(self, new_name):
+ try:
+ bootenv.BootEnv.check_be_name(new_name)
+ except api_errors.DuplicateBEName:
+ if new_name == self.__get_activated_be_name():
+ return ACTIVATED_BE_NAME
+ else:
+ return DUPLICATE_BE_NAME
+ except api_errors.ApiException:
+ return INVALID_BE_NAME
+ return VALID_BE_NAME
+
+ @staticmethod
+ def __get_activated_be_name():
+ try:
+ name = bootenv.BootEnv.get_activated_be_name()
+ except api_errors.ApiException:
+ name = ""
+ return name
+
+ @staticmethod
+ def __get_active_be_name():
+ try:
+ name = bootenv.BootEnv.get_active_be_name()
+ except api_errors.ApiException:
+ name = ""
+ return name
+
+ def __start_bouncing_progress(self):
+ self.stop_progress_bouncing = False
+ self.stopped_bouncing_progress = False
+ gobject.idle_add(self.w_progress_dialog.show)
+ Thread(target =
+ self.__g_progressdialog_progress_pulse).start()
+
+ def __stop_bouncing_progress(self):
+ if self.__is_progress_bouncing():
+ self.stop_progress_bouncing = True
+
+ def __g_progressdialog_progress_pulse(self):
+ while not self.stop_progress_bouncing:
+ gobject.idle_add(self.w_progressbar.pulse)
+ time.sleep(0.1)
+ self.stopped_bouncing_progress = True
+ gobject.idle_add(self.w_progress_dialog.hide)
+
+ def __is_progress_bouncing(self):
+ return not self.stopped_bouncing_progress
+
+ @staticmethod
+ def __rename_be(orig_name, new_name):
+ # The rename operation is i/o intensive, so the gui
+ # progress is not responsive. This will allow to show the
+ # gui progress.
+ time.sleep(0.2)
+ return bootenv.BootEnv.rename_be(orig_name, new_name)
+
+ @staticmethod
+ def __workaround_for_6472202(active_name, orig_name, new_name):
+ ret_code = 0
+ ret_code = bootenv.BootEnv.set_default_be(active_name)
+ if ret_code == 0:
+ ret_code = bootenv.BootEnv.rename_be(orig_name, new_name)
+ if ret_code == 0:
+ ret_code = bootenv.BootEnv.set_default_be(new_name)
+ else:
+ bootenv.BootEnv.set_default_be(orig_name)
+ return ret_code
+
+ @staticmethod
+ def __on_ua_help_button_clicked(widget):
+ gui_misc.display_help("intro-be")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/versioninfo.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,254 @@
+#!/usr/bin/python
+#
+# 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 2010 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+import sys
+try:
+ import gobject
+ import pango
+except ImportError:
+ sys.exit(1)
+import pkg.gui.misc as gui_misc
+
+class VersionInfo:
+ def __init__(self, builder, parent):
+ self.parent = parent
+ self.w_version_info_dialog = \
+ builder.get_object("version_info_dialog")
+ self.w_info_name_label = builder.get_object("info_name")
+ self.w_info_installed_label = builder.get_object(
+ "info_installed")
+ self.w_info_installable_label = builder.get_object(
+ "info_installable")
+ self.w_info_installable_prefix_label = builder.get_object(
+ "info_installable_label")
+ self.w_info_ok_button = builder.get_object("info_ok_button")
+ self.w_info_help_button = builder.get_object("info_help_button")
+ self.w_info_expander = builder.get_object(
+ "version_info_expander")
+ self.w_info_textview = builder.get_object("infotextview")
+ infobuffer = self.w_info_textview.get_buffer()
+ infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+
+ def setup_signals(self):
+ signals_table = [
+ (self.w_info_ok_button, "clicked",
+ self.__on_info_ok_button_clicked),
+ (self.w_info_help_button, "clicked",
+ self.__on_info_help_button_clicked),
+ (self.w_version_info_dialog, "delete_event",
+ self.__on_version_info_dialog_delete_event)
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def set_modal_and_transient(self, parent_window):
+ gui_misc.set_modal_and_transient(self.w_version_info_dialog,
+ parent_window)
+
+ def get_info(self, pkg_stem, name):
+ api_o = self.parent.get_api_object()
+ local_info = gui_misc.get_pkg_info(self.parent, api_o, pkg_stem, True)
+ remote_info = gui_misc.get_pkg_info(self.parent, api_o, pkg_stem, False)
+ if self.parent.check_exiting():
+ return False
+
+ plan_pkg = None
+
+ installed_only = False
+ if local_info:
+ if gui_misc.same_pkg_versions(local_info, remote_info):
+ installed_only = True
+
+ if not installed_only:
+ install_update_list = []
+ stuff_to_do = False
+ install_update_list.append(pkg_stem)
+ for pd in api_o.gen_plan_install(install_update_list,
+ refresh_catalogs=False):
+ continue
+ stuff_to_do = not api_o.planned_nothingtodo()
+ if stuff_to_do:
+ plan_desc = api_o.describe()
+ if plan_desc == None:
+ return
+ plan = plan_desc.get_changes()
+ plan_pkg = None
+ for pkg_plan in plan:
+ if name == pkg_plan[1].pkg_stem:
+ plan_pkg = pkg_plan[1]
+ break
+ if plan_pkg == None:
+ return True
+ gobject.idle_add(self.__after_get_info, local_info, remote_info,
+ plan_pkg, name)
+ return False
+
+ def __hide_pkg_version_details(self):
+ self.w_info_expander.hide()
+ self.w_version_info_dialog.set_size_request(-1, -1)
+
+
+ def __after_get_info(self, local_info, remote_info, plan_pkg, name):
+ if self.parent.check_exiting():
+ return
+ self.w_info_name_label.set_text(name)
+ installable_fmt = \
+ _("%(version)s (Build %(build)s-%(branch)s)")
+ installed_label = ""
+ installable_label = ""
+ installable_prefix_label = _("<b>Installable Version:</b>")
+
+ if local_info:
+ # Installed
+ installable_prefix_label = _("<b>Upgradeable Version:</b>")
+ yes_text = _("Yes, %(version)s (Build %(build)s-%(branch)s)")
+ installed_label = yes_text % \
+ {"version": local_info.version,
+ "build": local_info.build_release,
+ "branch": local_info.branch}
+ if gui_misc.same_pkg_versions(local_info, remote_info):
+ # Installed and up to date
+ installable_label = \
+ _("Installed package is up-to-date")
+ self.__hide_pkg_version_details()
+ else:
+ if plan_pkg == None:
+ # Installed with later version but can't upgrade
+ # Upgradeable Version: None
+ installable_label = _("None")
+ self.__setup_version_info_details(name,
+ remote_info.version,
+ remote_info.build_release,
+ remote_info.branch, False)
+ else:
+ # Installed with later version and can upgrade to
+ # Upgradeable Version: <version>
+ # Upgradeable == Latest Version
+ if gui_misc.same_pkg_versions(plan_pkg,
+ remote_info):
+ installable_label = installable_fmt % \
+ {"version": plan_pkg.version,
+ "build": plan_pkg.build_release,
+ "branch": plan_pkg.branch}
+ self.__hide_pkg_version_details()
+ else:
+ # Installed with later version and can upgrade
+ # Upgradeable Version: <version>
+ # but NOT to the Latest Version
+ installable_label = installable_fmt % \
+ {"version": plan_pkg.version,
+ "build": plan_pkg.build_release,
+ "branch": plan_pkg.branch}
+
+ self.__setup_version_info_details(name,
+ remote_info.version,
+ remote_info.build_release,
+ remote_info.branch, False)
+ else:
+ # Not Installed
+ installed_label = _("No")
+ if plan_pkg:
+ # Not installed with later version available to install
+ # Installable: <version>
+ # Installable == Latest Version
+ if gui_misc.same_pkg_versions(plan_pkg, remote_info):
+ installable_label = installable_fmt % \
+ {"version": plan_pkg.version,
+ "build": plan_pkg.build_release,
+ "branch": plan_pkg.branch}
+ self.__hide_pkg_version_details()
+ else:
+ # Not installed with later version available
+ # Installable: <version>
+ # but NOT to the Latest Version
+ installable_label = installable_fmt % \
+ {"version": plan_pkg.version,
+ "build": plan_pkg.build_release,
+ "branch": plan_pkg.branch}
+
+ self.__setup_version_info_details(name,
+ remote_info.version,
+ remote_info.build_release,
+ remote_info.branch, True)
+ else:
+ # Not Installed with later version and can't install
+ # Installable Version: None
+ installable_label = _("None")
+ self.__setup_version_info_details(name,
+ remote_info.version,
+ remote_info.build_release,
+ remote_info.branch, True)
+
+ self.w_info_installed_label.set_text(installed_label)
+ self.w_info_installable_label.set_text(installable_label)
+ self.w_info_installable_prefix_label.set_markup(installable_prefix_label)
+ self.w_info_ok_button.grab_focus()
+ self.w_version_info_dialog.show()
+ self.parent.unset_busy_cursor()
+
+ def __setup_version_info_details(self, name, version, build_release, branch,
+ to_be_installed):
+ installable_fmt = \
+ _("%(version)s (Build %(build)s-%(branch)s)")
+ if to_be_installed:
+ expander_fmt = _(
+ "The latest version of %s cannot be installed."
+ )
+ else:
+ expander_fmt = _(
+ "Cannot upgrade to the latest version of %s."
+ )
+ installable_exp = installable_fmt % \
+ {"version": version,
+ "build": build_release,
+ "branch": branch}
+ expander_text = installable_exp + "\n\n"
+ expander_text += expander_fmt % name
+
+ # Ensure we have enough room for the Details message
+ # without requiring a scrollbar
+ self.w_info_textview.set_size_request(484, 95)
+ self.w_info_expander.set_expanded(True)
+ self.w_info_expander.show()
+
+ details_buff = self.w_info_textview.get_buffer()
+ details_buff.set_text("")
+ itr = details_buff.get_iter_at_line(0)
+ details_buff.insert_with_tags_by_name(itr,
+ _("Latest Version: "), "bold")
+ details_buff.insert(itr, expander_text)
+
+ def __on_info_ok_button_clicked(self, widget):
+ self.w_version_info_dialog.hide()
+
+ @staticmethod
+ def __on_info_help_button_clicked(widget):
+ gui_misc.display_help("package-version")
+
+ def __on_version_info_dialog_delete_event(self, widget, event):
+ self.__on_info_ok_button_clicked(None)
+ return True
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/modules/gui/webinstall.py Mon Aug 29 14:13:13 2011 -0700
@@ -0,0 +1,493 @@
+#!/usr/bin/python
+#
+# 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 2010 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+# Location for themable icons
+ICON_LOCATION = "usr/share/package-manager/icons"
+
+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.gui.progress as progress
+import pkg.client.api_errors as api_errors
+import pkg.gui.installupdate as installupdate
+import pkg.gui.enumerations as enumerations
+import pkg.gui.repository as repository
+import pkg.fmri as fmri
+import pkg.client.publisher as publisher
+from pkg.client import global_settings
+from gettext import ngettext
+logger = global_settings.logger
+
+debug = False
+
+class Webinstall:
+ def __init__(self, image_dir):
+ global_settings.client_name = gui_misc.get_wi_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", os.path.join(
+ self.application_dir,
+ "usr/share/locale"))
+ module.textdomain("pkg")
+ gui_misc.init_for_help(self.application_dir)
+ self.pub_pkg_list = None
+ self.pr = progress.NullProgressTracker()
+ self.pub_new_tasks = []
+ self.pkg_install_tasks = []
+ self.icon_theme = gtk.icon_theme_get_default()
+ icon_location = os.path.join(self.application_dir, ICON_LOCATION)
+ self.icon_theme.append_search_path(icon_location)
+ self.param = None
+ self.disabled_pubs = {}
+ self.repo_gui = None
+ self.first_run = True
+
+ # Webinstall Dialog
+ builder = gtk.Builder()
+ self.gladefile = os.path.join(self.application_dir,
+ "usr/share/package-manager/packagemanager.ui")
+ builder.add_from_file(self.gladefile)
+ self.w_webinstall_dialog = \
+ builder.get_object("webinstalldialog")
+
+ self.w_webinstall_proceed = \
+ builder.get_object("proceed_button")
+ self.w_webinstall_cancel = \
+ builder.get_object("cancel_button")
+ self.w_webinstall_help = \
+ builder.get_object("help_button")
+ self.w_webinstall_close = \
+ builder.get_object("close_button")
+ self.w_webinstall_proceed_label = \
+ builder.get_object("proceed_new_repo_label")
+ self.w_webinstall_toplabel = \
+ builder.get_object("webinstall_toplabel")
+ self.w_webinstall_frame = \
+ builder.get_object("webinstall_frame")
+ self.w_webinstall_image = \
+ builder.get_object("pkgimage")
+ self.window_icon = gui_misc.get_icon(self.icon_theme,
+ 'packagemanager', 48)
+ self.w_webinstall_image.set_from_pixbuf(self.window_icon)
+ self.w_webinstall_info_label = \
+ builder.get_object("label19")
+
+ self.w_webinstall_textview = \
+ builder.get_object("webinstall_textview")
+ infobuffer = self.w_webinstall_textview.get_buffer()
+ infobuffer.create_tag("bold", weight=pango.WEIGHT_BOLD)
+ infobuffer.create_tag("disabled", foreground="#757575") #Close to DimGrey
+
+ self.__setup_signals()
+
+ self.w_webinstall_dialog.set_icon(self.window_icon)
+ self.api_o = gui_misc.get_api_object(self.image_dir, self.pr,
+ self.w_webinstall_dialog)
+ gui_misc.setup_logging()
+
+ def __setup_signals(self):
+ signals_table = [
+ (self.w_webinstall_dialog, "destroy_event",
+ self.__on_webinstall_dialog_close),
+ (self.w_webinstall_dialog, "close",
+ self.__on_webinstall_dialog_close),
+ (self.w_webinstall_dialog, "delete_event",
+ self.__on_webinstall_dialog_close),
+ (self.w_webinstall_cancel, "clicked",
+ self.__on_cancel_button_clicked),
+ (self.w_webinstall_close, "clicked",
+ self.__on_cancel_button_clicked),
+ (self.w_webinstall_help, "clicked",
+ self.__on_help_button_clicked),
+ (self.w_webinstall_proceed, "clicked",
+ self.__on_proceed_button_clicked),
+ ]
+ for widget, signal_name, callback in signals_table:
+ widget.connect(signal_name, callback)
+
+ def __output_new_pub_tasks(self, infobuffer, textiter, num_tasks):
+ if num_tasks == 0:
+ return
+ msg = ngettext(
+ "\n Add New Publisher\n", "\n Add New Publishers\n", num_tasks)
+ infobuffer.insert_with_tags_by_name(textiter, msg, "bold")
+ self.__output_pub_tasks(infobuffer, textiter, self.pub_new_tasks)
+
+ def __nothing_todo(self, infobuffer, textiter):
+ self.w_webinstall_proceed.hide()
+ self.w_webinstall_cancel.hide()
+ self.w_webinstall_frame.hide()
+ self.w_webinstall_toplabel.set_text(
+ _("All specified publishers are already on the system."))
+ self.w_webinstall_close.show()
+ self.w_webinstall_close.grab_focus()
+
+ def __output_pub_tasks(self, 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.repository
+ if repo != None and repo.origins != None and \
+ len(repo.origins) > 0:
+ infobuffer.insert(textiter,
+ _(" (%s)\n") % repo.origins[0].uri)
+ else:
+ infobuffer.insert(textiter,
+ _(" (No origin specified in the p5i file)\n"))
+ self.w_webinstall_proceed.hide()
+ msg = _("Publishers can <b>only</b> be added"
+ " if they have an origin specified.")
+ self.w_webinstall_proceed_label.set_markup(msg)
+
+ def __output_pkg_install_tasks(self, infobuffer, textiter, num_tasks):
+ if num_tasks == 0:
+ return
+ msg = ngettext(
+ "\n Install Package\n", "\n Install Packages\n", num_tasks)
+ infobuffer.insert_with_tags_by_name(textiter, msg, "bold")
+ for entry in self.pkg_install_tasks:
+ pub_info = entry[0]
+ packages = entry[1]
+ if len(packages) > 0:
+ if self.disabled_pubs and \
+ pub_info.prefix in self.disabled_pubs:
+ infobuffer.insert_with_tags_by_name(textiter,
+ _("\t%s (disabled)\n") % pub_info.prefix,
+ "bold", "disabled")
+ else:
+ infobuffer.insert_with_tags_by_name(textiter,
+ "\t%s\n" % pub_info.prefix, "bold")
+ for pkg in packages:
+ infobuffer.insert(textiter,
+ "\t\t%s\n" % fmri.extract_pkg_name(pkg))
+
+ def process_param(self, param=None):
+ if param == None or self.api_o == None:
+ self.w_webinstall_proceed.set_sensitive(False)
+ self.w_webinstall_cancel.grab_focus()
+ return
+ self.param = param
+ self.pub_pkg_list = self.api_parse_publisher_info()
+ 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 = 0
+ for entry in self.pkg_install_tasks:
+ packages = entry[1]
+ num_install_tasks += len(packages)
+
+ 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_dialog.present()
+ self.w_webinstall_dialog.resize(450, 100)
+ return
+ else:
+ gui_misc.change_stockbutton_label(self.w_webinstall_proceed,
+ _("_Proceed"))
+ self.w_webinstall_dialog.show_all()
+ self.w_webinstall_dialog.resize(450, 370)
+
+ 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:
+ msg = ngettext(
+ "Click Proceed <b>only</b> if you trust this new "
+ "publisher ",
+ "Click Proceed <b>only</b> if you trust these new "
+ "publishers ",
+ num_new_pub)
+ self.w_webinstall_proceed_label.set_markup(msg)
+
+ def __on_webinstall_dialog_close(self, widget, param=None):
+ self.__exit_app()
+
+ def __on_cancel_button_clicked(self, widget):
+ self.__exit_app()
+
+ @staticmethod
+ def __on_help_button_clicked(widget):
+ gui_misc.display_help("webinstall")
+
+ def __exit_app(self, be_name = None):
+ gui_misc.shutdown_logging()
+ 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:
+ continue
+
+ repo = pub_info.repository
+
+ pub_registered = self.__is_publisher_registered(pub_info.prefix)
+ if pub_registered and packages != None and len(packages) > 0 and \
+ self.__check_publisher_disabled(pub_info.prefix):
+ self.disabled_pubs[pub_info.prefix] = True
+
+ if not pub_registered:
+ if repo and repo.origins and \
+ repo.origins[0] != None and \
+ repo.origins[0].scheme in publisher.SSL_SCHEMES:
+
+ #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
+ if len(self.pub_new_tasks) > 0 or len(self.disabled_pubs) > 0 and \
+ self.repo_gui == None:
+ self.repo_gui = repository.Repository(self, self.image_dir,
+ webinstall_new=True, main_window = self.w_webinstall_dialog)
+
+ def __check_publisher_disabled(self, name):
+ try:
+ if self.api_o == None:
+ return
+ try:
+ pub = self.api_o.get_publisher(name)
+ if pub != None and pub.disabled:
+ return True
+ except api_errors.UnknownPublisher:
+ return False
+ except api_errors.PublisherError, ex:
+ gobject.idle_add(gui_misc.error_occurred,
+ self.w_webinstall_dialog,
+ str(ex),
+ _("Publisher Error"))
+ except api_errors.ApiException, ex:
+ gobject.idle_add(gui_misc.error_occurred,
+ self.w_webinstall_dialog,
+ str(ex), _("Web Installer Error"))
+ return False
+
+ def __disabled_pubs_info(self, disabled_pubs):
+ if len(disabled_pubs) == 0:
+ return
+ num = len(disabled_pubs)
+ msg = ngettext(
+ "The following publisher is disabled:\n",
+ "The following publishers are disabled:\n", num)
+
+ for pub in disabled_pubs:
+ msg += _("\t<b>%s</b>\n") % pub
+
+ msg += ngettext(
+ "\nClicking OK will enable the publisher before proceeding with "
+ "install. On completion it will be disabled again.",
+ "\nClicking OK will enable the publishers before proceeding with "
+ "install.\nOn completion they will be disabled again.",
+ num)
+
+ msgbox = gtk.MessageDialog(
+ parent = self.w_webinstall_dialog,
+ buttons = gtk.BUTTONS_OK_CANCEL,
+ flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_INFO,
+ message_format = None)
+ msgbox.set_markup(msg)
+ title = ngettext("Disabled Publisher", "Disabled Publishers",
+ len(disabled_pubs))
+ msgbox.set_title(title)
+ msgbox.set_default_response(gtk.RESPONSE_OK)
+
+ response = msgbox.run()
+ if response == gtk.RESPONSE_OK:
+ gobject.idle_add(self.__proceed)
+ msgbox.destroy()
+ return
+
+ 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(gui_misc.error_occurred,
+ self.w_webinstall_dialog,
+ str(ex), _("Publisher Error"))
+ except api_errors.ApiException, ex:
+ gobject.idle_add(gui_misc.error_occurred,
+ self.w_webinstall_dialog,
+ str(ex), _("Web Installer Error"))
+ return False
+
+ def __on_proceed_button_clicked(self, widget):
+ if not self.first_run:
+ try:
+ self.api_o.reset()
+ except api_errors.ApiException, ex:
+ gobject.idle_add(gui_misc.error_occurred,
+ self.w_webinstall_dialog,
+ str(ex), _("Web Installer Error"))
+ return
+ self.pub_pkg_list = self.api_parse_publisher_info()
+ self.__create_task_lists()
+ else:
+ self.first_run = False
+ if self.disabled_pubs and len(self.disabled_pubs) > 0:
+ self.__disabled_pubs_info(self.disabled_pubs)
+ else:
+ self.__proceed()
+
+ def __proceed(self):
+ if len(self.disabled_pubs) > 0 and self.repo_gui:
+ self.repo_gui.webinstall_enable_disable_pubs(
+ self.w_webinstall_dialog, self.disabled_pubs, True)
+ return
+ 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[0]
+ if debug:
+ print("Add New Publisher:\n\tName: %s" % pub.prefix)
+ repo = pub.repository
+ if repo != None and repo.origins != None and \
+ len(repo.origins) > 0:
+ print("\tURL: %s" % repo.origins[0].uri)
+
+ repo = pub.repository
+ if repo and len(repo.origins) > 0 and self.repo_gui:
+ self.repo_gui.webinstall_new_pub(self.w_webinstall_dialog, pub)
+ else:
+ msg = _("Failed to add %s.\n") % pub
+ msg += _("No URI specified")
+ gui_misc.error_occurred(
+ self.w_webinstall_dialog,
+ msg, _("Publisher Error"))
+
+ # Publisher Callback
+ # invoked at end of adding a publisher and enabling/disabling a set of publishers
+ def reload_packages(self, added_pub=True):
+ if len(self.pub_new_tasks) > 0:
+ if added_pub:
+ self.pub_new_tasks.pop(0)
+ if len(self.pub_new_tasks) > 0:
+ self.__add_new_pub()
+ return
+
+ if len(self.pkg_install_tasks) > 0:
+ self.api_o = gui_misc.get_api_object(self.image_dir, self.pr,
+ self.w_webinstall_dialog)
+ 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
+ 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)
+ if debug:
+ print "Install Packages: %s" % all_package_stems
+
+ installupdate.InstallUpdate(all_package_stems, self, self.image_dir,
+ action = enumerations.INSTALL_UPDATE,
+ parent_name = _("Package Manager"),
+ main_window = self.w_webinstall_dialog,
+ web_install = True)
+
+ def process_pkg_stems(self, pub_info, packages):
+ if not self.__is_publisher_registered(pub_info.prefix):
+ return []
+ pkg_stem = "pkg://" + pub_info.prefix + "/"
+ packages_with_stem = []
+ for pkg in packages:
+ if pkg.startswith(pkg_stem):
+ packages_with_stem.append(pkg)
+ else:
+ 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):
+ if update_list == None:
+ return
+ self.pkg_install_tasks = []
+ if len(self.disabled_pubs) > 0 and self.repo_gui:
+ gobject.idle_add(self.repo_gui.webinstall_enable_disable_pubs,
+ self.w_webinstall_dialog, self.disabled_pubs, False)
+ return
+ self.__exit_app()
+
+ def api_parse_publisher_info(self):
+ '''<path to mimetype file|origin_url>
+ returns list of publisher and package list tuples'''
+ try:
+ return self.api_o.parse_p5i(location=self.param)
+ except api_errors.ApiException, ex:
+ msg = str(ex)
+ print _("Web Installer Error: %s") % (msg)
+ sys.exit(1)
+ return None
--- a/src/po/Makefile Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-#
-# 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 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-MACH:sh = uname -p
-
-top_srcdir = ..
-ROOT = ../../proto/root_$(MACH)
-ROOTLOCALE = $(ROOT)/usr/share/locale
-
-POFILES:sh = echo *.po
-MOFILES = $(POFILES:%.po=%.mo)
-LINGUAS = $(POFILES:%.po=%)
-MOFILENAME = pkg.mo
-
-ROOTLOCALEDIRS = $(LINGUAS:%=$(ROOTLOCALE)/%)
-ROOTMESSAGEDIRS = $(ROOTLOCALEDIRS:%=%/LC_MESSAGES)
-
-ROOTMOFILES = $(ROOTMESSAGEDIRS:%=%/$(MOFILENAME))
-
-all: $(MOFILES)
-
-install: $(ROOTMESSAGEDIRS) $(ROOTMOFILES)
-
-%.mo: %.po
- msgfmt -o $@ $<
-
-clean:
- rm -f $(MOFILES)
-
-clobber: clean
-
-$(ROOTMESSAGEDIRS):
- mkdir -m 0755 -p $@
-
-$(ROOTLOCALE)/%/LC_MESSAGES/$(MOFILENAME): %.mo
- rm -f $@; cp $< $@; chmod 644 $@
--- a/src/setup.py Fri Sep 02 13:50:59 2011 -0700
+++ b/src/setup.py Mon Aug 29 14:13:13 2011 -0700
@@ -38,20 +38,23 @@
import hashlib
import time
-from distutils.errors import DistutilsError
+from distutils.errors import DistutilsError, DistutilsFileError
from distutils.core import setup, Extension
from distutils.cmd import Command
from distutils.command.install import install as _install
+from distutils.command.install_data import install_data as _install_data
from distutils.command.build import build as _build
from distutils.command.build_ext import build_ext as _build_ext
from distutils.command.build_py import build_py as _build_py
from distutils.command.bdist import bdist as _bdist
from distutils.command.clean import clean as _clean
from distutils.dist import Distribution
+from distutils import log
from distutils.sysconfig import get_python_inc
+import distutils.dep_util as dep_util
+import distutils.dir_util as dir_util
import distutils.file_util as file_util
-import distutils.dir_util as dir_util
import distutils.util as util
import distutils.ccompiler
from distutils.unixccompiler import UnixCCompiler
@@ -116,6 +119,16 @@
sysrepo_dir = 'etc/pkg/sysrepo'
sysrepo_logs_dir = 'var/log/pkg/sysrepo'
sysrepo_cache_dir = 'var/cache/pkg/sysrepo'
+autostart_dir = 'etc/xdg/autostart'
+desktop_dir = 'usr/share/applications'
+gconf_dir = 'etc/gconf/schemas'
+help_dir = 'usr/share/gnome/help/package-manager'
+omf_dir = 'usr/share/omf/package-manager'
+startpage_dir = 'usr/share/package-manager/data/startpagebase'
+um_lib_dir = 'usr/lib/update-manager'
+um_share_dir = 'usr/share/update-manager'
+pm_share_dir = 'usr/share/package-manager'
+locale_dir = 'usr/share/locale'
# A list of source, destination tuples of modules which should be hardlinked
@@ -145,10 +158,14 @@
['launch.py', 'pm-launch'],
['sysrepo.py', 'pkg.sysrepo'],
],
+ um_lib_dir: [
+ ['um/update-refresh.sh', 'update-refresh.sh'],
+ ],
svc_method_dir: [
['svc/svc-pkg-depot', 'svc-pkg-depot'],
['svc/svc-pkg-mdns', 'svc-pkg-mdns'],
['svc/svc-pkg-sysrepo', 'svc-pkg-sysrepo'],
+ ['um/pkg-update', 'pkg-update'],
],
}
@@ -275,6 +292,7 @@
'pkg.client.transport',
'pkg.file_layout',
'pkg.flavor',
+ 'pkg.gui',
'pkg.lint',
'pkg.portable',
'pkg.publish',
@@ -328,6 +346,64 @@
'util/misc/exec_attr.d/package:pkg:package-manager'
]
authattrd_files = ['util/misc/auth_attr.d/package:pkg']
+autostart_files = [
+ 'um/data/updatemanagernotifier.desktop',
+]
+desktop_files = [
+ 'gui/data/addmoresoftware.desktop',
+ 'gui/data/packagemanager.desktop',
+ 'um/data/updatemanager.desktop',
+]
+gconf_files = [
+ 'gui/data/packagemanager-preferences.schemas',
+ 'um/data/updatemanager-preferences.schemas',
+]
+intl_files = [
+ 'gui/data/addmoresoftware.desktop.in',
+ 'gui/data/packagemanager-info.xml.in',
+ 'gui/data/packagemanager-preferences.schemas.in',
+ 'gui/data/packagemanager.desktop.in',
+ 'um/data/updatemanager-preferences.schemas.in',
+ 'um/data/updatemanager.desktop.in',
+ 'um/data/updatemanagernotifier.desktop.in',
+]
+help_locales = \
+ 'C ar ca cs de es fr hu id it ja ko pl pt_BR ru sv zh_CN zh_HK zh_TW'.split()
+help_files = {
+ 'C': ['gui/help/C/package-manager.xml'],
+ 'C/figures': [
+ 'gui/help/C/figures/%s.png' % n
+ for n in 'pkgmgr-main startpage_new update_all_new webinstall'.split()
+ ]
+}
+help_files.update(
+ (locale, ['gui/help/%s/package-manager.xml' % locale])
+ for locale in help_locales[1:]
+)
+omf_files = [
+ 'gui/help/package-manager-%s.omf' % locale
+ for locale in help_locales
+]
+startpage_locales = \
+ 'C ar ca cs de es fr hu id it ja ko nl pt_BR ru sv zh_CN zh_HK zh_TW'.split()
+startpage_files = {
+ 'C': [
+ 'gui/data/startpagebase/C/%s.png' % n
+ for n in [
+ 'dialog-information', 'dialog-warning', 'hc_dialog-information',
+ 'hc_dialog-warning', 'hc_install', 'hc_opensolaris',
+ 'hci_dialog-information', 'hci_dialog-warning', 'hci_install',
+ 'hci_opensolaris', 'install', 'opensolaris'
+ ]
+ ] + ['gui/data/startpagebase/C/startpage.html']
+}
+startpage_files.update(
+ (locale, ['gui/data/startpagebase/%s/startpage.html' % locale])
+ for locale in startpage_locales[1:]
+)
+pkg_locales = \
+ 'ar ca cs de es fr he hu id it ja ko nl pl pt_BR ru sk sv zh_CN zh_HK zh_TW'.split()
+
syscallat_srcs = [
'modules/syscallat.c'
]
@@ -502,12 +578,9 @@
self.root_dir = root_dir
def run(self):
- """
- At the end of the install function, we need to rename some files
- because distutils provides no way to rename files as they are
- placed in their install locations.
- Also, make sure that cherrypy and other external dependencies
- are installed.
+ """At the end of the install function, we need to rename some
+ files because distutils provides no way to rename files as they
+ are placed in their install locations.
"""
_install.run(self)
@@ -532,84 +605,64 @@
dst_dir = util.change_root(self.root_dir, d)
dst_path = util.change_root(self.root_dir,
os.path.join(d, dstname))
- dir_util.mkpath(dst_dir, verbose = True)
- file_util.copy_file(srcname, dst_path, update = True)
+ dir_util.mkpath(dst_dir, verbose=True)
+ file_util.copy_file(srcname, dst_path, update=True)
# make scripts executable
os.chmod(dst_path,
os.stat(dst_path).st_mode
| stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
-def hash_sw(swname, swarc, swhash):
- if swhash == None:
- return True
+class install_data_func(_install_data):
+ """Enhance the standard install_data subcommand to take not only a list
+ of filenames, but a list of source and destination filename tuples, for
+ the cases where a filename needs to be renamed between the two
+ locations."""
- print "checksumming %s" % swname
- hash = hashlib.sha1()
- f = open(swarc, "rb")
- while True:
- data = f.read(65536)
- if data == "":
- break
- hash.update(data)
- f.close()
+ def run(self):
+ self.mkpath(self.install_dir)
+ for f in self.data_files:
+ dir, files = f
+ dir = util.convert_path(dir)
+ if not os.path.isabs(dir):
+ dir = os.path.join(self.install_dir, dir)
+ elif self.root:
+ dir = change_root(self.root, dir)
+ self.mkpath(dir)
- if hash.hexdigest() == swhash:
- return True
- else:
- print >> sys.stderr, "bad checksum! %s != %s" % \
- (swhash, hash.hexdigest())
- return False
+ if not files:
+ self.outfiles.append(dir)
+ else:
+ for file in files:
+ if isinstance(file, basestring):
+ infile = file
+ outfile = os.path.join(dir,
+ os.path.basename(file))
+ else:
+ infile, outfile = file
+ infile = util.convert_path(infile)
+ outfile = util.convert_path(outfile)
+ if os.path.sep not in outfile:
+ outfile = os.path.join(dir,
+ outfile)
+ self.copy_file(infile, outfile)
+ self.outfiles.append(outfile)
-def prep_sw(swname, swarc, swdir, swurl, swhash):
- swarc = os.path.join(extern_dir, swarc)
- swdir = os.path.join(extern_dir, swdir)
- if not os.path.exists(extern_dir):
- os.mkdir(extern_dir)
-
- if not os.path.exists(swarc):
- print "downloading %s" % swname
+ # Don't bother making this generic for the one symlink.
+ src = "HighContrastInverse"
+ dst = os.path.join(self.install_dir, pm_share_dir,
+ "icons/HighContrastLargePrintInverse")
try:
- fname, hdr = urllib.urlretrieve(swurl, swarc)
- except IOError:
- pass
- if not os.path.exists(swarc):
- print >> sys.stderr, "Unable to retrieve %s.\n" \
- "Please retrieve the file " \
- "and place it at: %s\n" % (swurl, swarc)
- # remove a partial download or error message from proxy
- remove_sw(swname)
- sys.exit(1)
- if not os.path.exists(swdir):
- if not hash_sw(swname, swarc, swhash):
- sys.exit(1)
-
- print "unpacking %s" % swname
- tar = tarfile.open(swarc)
- # extractall doesn't exist until python 2.5
- for m in tar.getmembers():
- tar.extract(m, extern_dir)
- tar.close()
+ targ = os.readlink(dst)
+ except OSError, e:
+ if e.errno in (errno.ENOENT, errno.EINVAL):
+ targ = None
+ else:
+ raise
- # If there are patches, apply them now.
- patchdir = os.path.join("patch", swname)
- already_patched = os.path.join(swdir, ".patched")
- if os.path.exists(patchdir) and not os.path.exists(already_patched):
- patches = os.listdir(patchdir)
- for p in patches:
- patchpath = os.path.join(os.path.pardir,
- os.path.pardir, patchdir, p)
- print "Applying %s to %s" % (p, swname)
- args = ["patch", "-d", swdir, "-i", patchpath, "-p0"]
- if osname == "windows":
- args.append("--binary")
- ret = subprocess.Popen(args).wait()
- if ret != 0:
- print >> sys.stderr, \
- "patch failed and returned %d." % ret
- print >> sys.stderr, \
- "Command was: %s" % " ".join(args)
- sys.exit(1)
- file(already_patched, "w").close()
+ if src != targ:
+ log.info("linking %s -> %s" % (src, dst))
+ rm_f(dst)
+ os.symlink(src, dst)
def run_cmd(args, swdir, env=None):
if env is None:
@@ -622,17 +675,101 @@
"Command was: %s" % " ".join(args)
sys.exit(1)
-def remove_sw(swname):
- print("deleting %s" % swname)
- for file in os.listdir(extern_dir):
- if fnmatch.fnmatch(file, "%s*" % swname):
- fpath = os.path.join(extern_dir, file)
- if os.path.isfile(fpath):
- os.unlink(fpath)
- else:
- shutil.rmtree(fpath, True)
+def _copy_file_contents(src, dst, buffer_size=16*1024):
+ """A clone of distutils.file_util._copy_file_contents() that strips the
+ CDDL text."""
+
+ # Match the lines between and including the CDDL header signposts, as
+ # well as empty comment lines before and after, if they exist.
+ cddl_re = re.compile("\n(#\s*\n)?^[^\n]*CDDL HEADER START.+"
+ "CDDL HEADER END[^\n]*$(\n#\s*$)?", re.MULTILINE|re.DOTALL)
+
+ with file(src, "r") as sfp:
+ try:
+ os.unlink(dst)
+ except EnvironmentError, e:
+ if e.errno != errno.ENOENT:
+ raise DistutilsFileError("could not delete "
+ "'%s': %s" % (dst, e))
+
+ with file(dst, "w") as dfp:
+ while True:
+ buf = sfp.read(buffer_size)
+ if not buf:
+ break
+ buf = cddl_re.sub("", buf)
+ dfp.write(buf)
+
+# Make file_util use our version of _copy_file_contents
+file_util._copy_file_contents = _copy_file_contents
+
+def intltool_merge(src, dst):
+ if not dep_util.newer(src, dst):
+ return
+
+ args = [
+ "/usr/bin/intltool-merge", "-d", "-u",
+ "-c", "po/.intltool-merge-cache", "po", src, dst
+ ]
+ print " ".join(args)
+ run_cmd(args, os.getcwd(), os.environ.copy().update({"LC_ALL": "C"}))
+
+def msgfmt(src, dst):
+ if not dep_util.newer(src, dst):
+ return
+
+ args = ["/usr/bin/msgfmt", "-o", dst, src]
+ print " ".join(args)
+ run_cmd(args, os.getcwd())
+
+def xml2po(src, dst, mofile):
+ msgfmt(mofile[:-3] + ".po", mofile)
+
+ monewer = dep_util.newer(mofile, dst)
+ srcnewer = dep_util.newer(src, dst)
+
+ if not srcnewer and not monewer:
+ return
+
+ args = ["/usr/bin/xml2po", "-t", mofile, "-o", dst, src]
+ print " ".join(args)
+ run_cmd(args, os.getcwd())
+
+class installfile(Command):
+ user_options = [
+ ("file=", "f", "source file to copy"),
+ ("dest=", "d", "destination directory"),
+ ("mode=", "m", "file mode"),
+ ]
+
+ description = "De-CDDLing file copy"
+
+ def initialize_options(self):
+ self.file = None
+ self.dest = None
+ self.mode = None
+
+ def finalize_options(self):
+ if self.mode is None:
+ self.mode = 0644
+ elif isinstance(self.mode, basestring):
+ try:
+ self.mode = int(self.mode, 8)
+ except ValueError:
+ self.mode = 0644
+
+ def run(self):
+ dest_file = os.path.join(self.dest, os.path.basename(self.file))
+ ret = self.copy_file(self.file, dest_file)
+
+ os.chmod(dest_file, self.mode)
+ os.utime(dest_file, None)
+
+ return ret
class build_func(_build):
+ sub_commands = _build.sub_commands + [('build_data', None)]
+
def initialize_options(self):
_build.initialize_options(self)
self.build_base = build_dir
@@ -746,7 +883,8 @@
return ret
- # override the build_module method to do VERSION substitution on pkg/__init__.py
+ # override the build_module method to do VERSION substitution on
+ # pkg/__init__.py
def build_module (self, module, module_file, package):
if module == "__init__" and package == "pkg":
@@ -802,7 +940,8 @@
if outfile.endswith("/pkg/__init__.py"):
src_mtime = self.timestamps["."]
else:
- src_mtime = self.timestamps[os.path.join("src", infile)]
+ src_mtime = self.timestamps.get(
+ os.path.join("src", infile), self.timestamps["."])
if dst_mtime != src_mtime:
f = self.force
@@ -820,11 +959,63 @@
return dst, copied
+class build_data_func(Command):
+ description = "build data files whose source isn't in deliverable form"
+ user_options = []
+
+ # As a subclass of distutils.cmd.Command, these methods are required to
+ # be implemented.
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ # Anything that gets created here should get deleted in
+ # clean_func.run() below.
+ for f in intl_files:
+ intltool_merge(f, f[:-3])
+
+ for l in help_locales:
+ path = "gui/help/%s/" % l
+ xml2po(path + "package-manager.xml.in",
+ path + "package-manager.xml",
+ path + "%s.mo" % l)
+
+ for l in pkg_locales:
+ msgfmt("po/%s.po" % l, "po/%s.mo" % l)
+
+def rm_f(filepath):
+ """Remove a file without caring whether it exists."""
+
+ try:
+ os.unlink(filepath)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+
class clean_func(_clean):
def initialize_options(self):
_clean.initialize_options(self)
self.build_base = build_dir
+ def run(self):
+ _clean.run(self)
+
+ rm_f("po/.intltool-merge-cache")
+
+ for f in intl_files:
+ rm_f(f[:-3])
+
+ for l in pkg_locales:
+ rm_f("po/%s.mo" % l)
+
+ for l in help_locales:
+ path = "gui/help/%s/" % l
+ rm_f(path + "package-manager.xml")
+ rm_f(path + "%s.mo" % l)
+
class clobber_func(Command):
user_options = []
description = "Deletes any and all files created by setup"
@@ -938,7 +1129,9 @@
data_files = web_files
cmdclasses = {
'install': install_func,
+ 'install_data': install_data_func,
'build': build_func,
+ 'build_data': build_data_func,
'build_ext': build_ext_func,
'build_py': build_py_func,
'bdist': dist_func,
@@ -949,6 +1142,7 @@
'clean': clean_func,
'clobber': clobber_func,
'test': test_func,
+ 'installfile': installfile,
}
# all builds of IPS should have manpages
@@ -976,7 +1170,70 @@
(authattrd_dir, authattrd_files),
(sysrepo_dir, sysrepo_files),
(sysrepo_logs_dir, sysrepo_log_stubs),
- (sysrepo_cache_dir, {})
+ (sysrepo_cache_dir, {}),
+ (autostart_dir, autostart_files),
+ (desktop_dir, desktop_files),
+ (gconf_dir, gconf_files),
+ (omf_dir, omf_files),
+ ('usr/share/icons/hicolor/48x48/mimetypes',
+ ['gui/data/gnome-mime-application-vnd.pkg5.info.png']),
+ ('usr/share/mime/packages', ['gui/data/packagemanager-info.xml']),
+ (pm_share_dir, ['gui/data/packagemanager.ui']),
+ ]
+ data_files += [
+ (os.path.join(startpage_dir, locale), files)
+ for locale, files in startpage_files.iteritems()
+ ]
+ data_files += [
+ (os.path.join(help_dir, locale), files)
+ for locale, files in help_files.iteritems()
+ ]
+ data_files += [
+ (os.path.join(locale_dir, locale, 'LC_MESSAGES'),
+ [('po/%s.mo' % locale, 'pkg.mo')])
+ for locale in pkg_locales
+ ]
+ for t in 'HighContrast', 'HighContrastInverse', '':
+ for px in '24', '36', '48':
+ data_files += [(
+ '%s/icons/%s/%sx%s/actions' % (um_share_dir, t or 'hicolor', px, px),
+ ['um/data/icons/%s/%sx%s/updatemanager.png' % (t, px, px)]
+ )]
+ data_files += [(
+ '%s/icons/%s/16x16/actions' % (pm_share_dir, t or 'hicolor'),
+ [
+ 'gui/data/icons/%s/16x16/%s.png' % (t, n)
+ for n in ('filter_all', 'filter_selected', 'progress_checkmark',
+ 'selection', 'status_checkmark', 'status_installed',
+ 'status_newupdate', 'status_notinstalled')
+ ]
+ )]
+ data_files += [
+ ('%s/icons/%s/%sx%s/actions' % (pm_share_dir, t or 'hicolor', px, px),
+ [
+ 'gui/data/icons/%s/%sx%s/%s.png' % (t, px, px, n)
+ for n in ('pm-install_update', 'pm-refresh',
+ 'pm-remove', 'pm-update_all')
+ ])
+ for px in (24, 48)
+ ]
+ data_files += [(
+ '%s/icons/%s/48x48/actions' % (pm_share_dir, t or 'hicolor'),
+ ['gui/data/icons/%s/48x48/packagemanager.png' % t]
+ )]
+ data_files += [
+ ('usr/share/icons/%s/48x48/apps' % (t or 'hicolor'),
+ [
+ 'um/data/icons/%s/48x48/updatemanager.png' % t,
+ 'gui/data/icons/%s/48x48/packagemanager.png' % t
+ ]),
+ ]
+ # These two icons don't fit any patterns.
+ data_files += [
+ (os.path.join(pm_share_dir, 'icons/hicolor/16x16/actions'), [
+ 'gui/data/icons/16x16/progress_blank.png']),
+ (os.path.join(pm_share_dir, 'icons/hicolor/24x24/actions'), [
+ 'gui/data/icons/24x24/pm-check.png']),
]
if osname == 'sunos' or osname == "linux":
--- a/src/um/Makefile Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,260 +0,0 @@
-#
-# 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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-MACH:sh = uname -p
-
-KSH = /usr/bin/ksh
-PYTHON = /usr/bin/python
-INSTALL = /usr/sbin/install -s
-
-ROOT = ../../proto/root_${MACH}/usr
-ROOTETC = ../../proto/root_${MACH}/etc
-ROOTLIB = ../../proto/root_${MACH}/lib
-ROOTSHARE = $(ROOT)/share/update-manager
-ROOTUSRLIB = $(ROOT)/lib
-
-ROOTAPPICONSHARE = $(ROOT)/share/icons/hicolor/48x48/apps
-ROOTAPPHIGHICONSHARE = $(ROOT)/share/icons/HighContrast/48x48/apps
-ROOTAPPHIGHINVICONSHARE = $(ROOT)/share/icons/HighContrastInverse/48x48/apps
-ROOTAUTOSTARTSHARE = $(ROOTETC)/xdg/autostart
-ROOTDESKTOPSHARE = $(ROOT)/share/applications
-ROOTGCONFSHARE = $(ROOTETC)/gconf/schemas
-ROOTHIGHICON24SHARE = $(ROOTSHARE)/icons/HighContrast/24x24/actions
-ROOTHIGHICON36SHARE = $(ROOTSHARE)/icons/HighContrast/36x36/actions
-ROOTHIGHICON48SHARE = $(ROOTSHARE)/icons/HighContrast/48x48/actions
-ROOTHIGHINVICON24SHARE = $(ROOTSHARE)/icons/HighContrastInverse/24x24/actions
-ROOTHIGHINVICON36SHARE = $(ROOTSHARE)/icons/HighContrastInverse/36x36/actions
-ROOTHIGHINVICON48SHARE = $(ROOTSHARE)/icons/HighContrastInverse/48x48/actions
-ROOTICON24SHARE = $(ROOTSHARE)/icons/hicolor/24x24/actions
-ROOTICON36SHARE = $(ROOTSHARE)/icons/hicolor/36x36/actions
-ROOTICON48SHARE = $(ROOTSHARE)/icons/hicolor/48x48/actions
-ROOTPYTHON = $(ROOTUSRLIB)/python2.6
-ROOTPYTHONVENDOR = $(ROOTPYTHON)/vendor-packages
-ROOTSCRIPTSSHARE = $(ROOT)/lib/update-manager
-ROOTSVCSHARE = $(ROOTLIB)/svc/method
-
-ROOTDIRS = \
- $(ROOTAPPICONSHARE) \
- $(ROOTAPPHIGHICONSHARE) \
- $(ROOTAUTOSTARTSHARE) \
- $(ROOTDESKTOPSHARE) \
- $(ROOTGCONFSHARE) \
- $(ROOTHIGHICON24SHARE) \
- $(ROOTHIGHICON36SHARE) \
- $(ROOTHIGHICON48SHARE) \
- $(ROOTHIGHINVICON24SHARE) \
- $(ROOTHIGHINVICON36SHARE) \
- $(ROOTHIGHINVICON48SHARE) \
- $(ROOTICON24SHARE) \
- $(ROOTICON36SHARE) \
- $(ROOTICON48SHARE) \
- $(ROOTSCRIPTSSHARE) \
- $(ROOTSHARE) \
- $(ROOTSVCSHARE)
-
-APPICONS = \
- data/icons/48x48/updatemanager.png
-
-APPHIGHICONS = \
- data/icons/HighContrast/48x48/updatemanager.png
-
-APPHIGHINVICONS = \
- data/icons/HighContrastInverse/48x48/updatemanager.png
-
-AUTOSTART = \
- data/updatemanagernotifier.desktop
-
-DESKTOP = \
- data/updatemanager.desktop
-
-GCONF = \
- data/updatemanager-preferences.schemas
-
-HIGHICONS24 = \
- data/icons/HighContrast/24x24/updatemanager.png
-
-HIGHICONS36 = \
- data/icons/HighContrast/36x36/updatemanager.png
-
-HIGHICONS48 = \
- data/icons/HighContrast/48x48/updatemanager.png
-
-HIGHINVICONS24 = \
- data/icons/HighContrastInverse/24x24/updatemanager.png
-
-HIGHINVICONS36 = \
- data/icons/HighContrastInverse/36x36/updatemanager.png
-
-HIGHINVICONS48 = \
- data/icons/HighContrastInverse/48x48/updatemanager.png
-
-ICONS24 = \
- data/icons/24x24/updatemanager.png
-
-ICONS36 = \
- data/icons/36x36/updatemanager.png
-
-ICONS48 = \
- data/icons/48x48/updatemanager.png
-
-SCRIPTS = \
- update-refresh.sh
-
-SVC = \
- pkg-update
-
-#
-# Define the paths to all of the stuff we'll install.
-#
-ROOTAPPICONS = $(APPICONS:data/icons/48x48/%=$(ROOTAPPICONSHARE)/%)
-ROOTAPPHIGHICONS = $(APPHIGHICONS:data/icons/HighContrast/48x48/%=$(ROOTAPPHIGHICONSHARE)/%)
-ROOTAPPHIGHINVICONS = $(APPHIGHINVICONS:data/icons/HighContrastInverse/48x48/%=$(ROOTAPPHIGHINVICONSHARE)/%)
-
-ROOTAUTOSTART = $(AUTOSTART:data/%=$(ROOTAUTOSTARTSHARE)/%)
-
-ROOTDESKTOP = $(DESKTOP:data/%=$(ROOTDESKTOPSHARE)/%)
-
-ROOTGCONF = $(GCONF:data/%=$(ROOTGCONFSHARE)/%)
-
-ROOTHIGHICONS24 = $(HIGHICONS24:data/icons/HighContrast/24x24/%=$(ROOTHIGHICON24SHARE)/%)
-ROOTHIGHICONS36 = $(HIGHICONS36:data/icons/HighContrast/36x36/%=$(ROOTHIGHICON36SHARE)/%)
-ROOTHIGHICONS48 = $(HIGHICONS48:data/icons/HighContrast/48x48/%=$(ROOTHIGHICON48SHARE)/%)
-
-ROOTHIGHINVICONS24 = $(HIGHINVICONS24:data/icons/HighContrastInverse/24x24/%=$(ROOTHIGHINVICON24SHARE)/%)
-ROOTHIGHINVICONS36 = $(HIGHINVICONS36:data/icons/HighContrastInverse/36x36/%=$(ROOTHIGHINVICON36SHARE)/%)
-ROOTHIGHINVICONS48 = $(HIGHINVICONS48:data/icons/HighContrastInverse/48x48/%=$(ROOTHIGHINVICON48SHARE)/%)
-
-ROOTICONS24 = $(ICONS24:data/icons/24x24/%=$(ROOTICON24SHARE)/%)
-ROOTICONS36 = $(ICONS36:data/icons/36x36/%=$(ROOTICON36SHARE)/%)
-ROOTICONS48 = $(ICONS48:data/icons/48x48/%=$(ROOTICON48SHARE)/%)
-
-ROOTSCRIPTS = $(SCRIPTS:%=$(ROOTSCRIPTSSHARE)/%)
-
-ROOTSVC = $(SVC:%=$(ROOTSVCSHARE)/%)
-
-ROOTCOMPONENTS = \
- $(ROOTAPPICONS) \
- $(ROOTAPPHIGHICONS) \
- $(ROOTAPPHIGHINVICONS) \
- $(ROOTAUTOSTART) \
- $(ROOTDESKTOP) \
- $(ROOTGCONF) \
- $(ROOTHIGHICONS24) \
- $(ROOTHIGHICONS36) \
- $(ROOTHIGHICONS48) \
- $(ROOTHIGHINVICONS24) \
- $(ROOTHIGHINVICONS36) \
- $(ROOTHIGHINVICONS48) \
- $(ROOTICONS24) \
- $(ROOTICONS36) \
- $(ROOTICONS48) \
- $(ROOTSCRIPTS) \
- $(ROOTSVC)
-
-#
-# Triggered by all:'s dependency. Drives production of e.g.
-# data/updatemanager.desktop from data/updatemanager.desktop.in
-#
-data/%: data/%.in
- LC_ALL=C intltool-merge -d -u \
- -c ../po/.intltool-merge-cache ../po [email protected] $@
-
-all: $(AUTOSTART) $(DESKTOP) $(GCONF) $(APPICONS)
-
-install: all $(ROOTCOMPONENTS) $(ROOTDIRS)
-
- # XXX out for now.
- #@cd po; pwd;\
- # mkdir -p ../$(ROOT); \
- # for PO in *.po; do \
- # LING=`basename $$PO .po`; \
- # MO=$$LING.mo; \
- # msgfmt -o $$MO $$PO; \
- # mkdir -p ../$(ROOT)/share/locale/$$LING/LC_MESSAGES; \
- # cp $$MO ../$(ROOT)/share/locale/$$LING/LC_MESSAGES/updatemanager.mo; \
- # done;
-
-clean:
- rm -f $(AUTOSTART) $(DESKTOP) $(GCONF)
-
-clobber: clean
- rm -f $(ROOTCOMPONENTS)
-
-$(ROOTDIRS):
- $(INSTALL) -d -m 0755 $@
-
-$(ROOTAPPHIGHICONSHARE)/%: $(ROOTDIRS) data/icons/HighContrast/48x48/%
- $(INSTALL) -f $(ROOTAPPHIGHICONSHARE) -m 0644 $<
-
-$(ROOTAPPHIGHINVICONSHARE)/%: $(ROOTDIRS) data/icons/HighContrastInverse/48x48/%
- $(INSTALL) -f $(ROOTAPPHIGHINVICONSHARE) -m 0644 $<
-
-$(ROOTAPPICONSHARE)/%: $(ROOTDIRS) data/icons/48x48/%
- $(INSTALL) -f $(ROOTAPPICONSHARE) -m 0644 $<
-
-$(ROOTAUTOSTARTSHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTAUTOSTARTSHARE) -m 0644 $<
-
-$(ROOTDESKTOPSHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTDESKTOPSHARE) -m 0644 $<
-
-$(ROOTGCONFSHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTGCONFSHARE) -m 0644 $<
-
-$(ROOTHIGHICON24SHARE)/%: $(ROOTDIRS) data/icons/HighContrast/24x24/%
- $(INSTALL) -f $(ROOTHIGHICON24SHARE) -m 0644 $<
-
-$(ROOTHIGHICON36SHARE)/%: $(ROOTDIRS) data/icons/HighContrast/36x36/%
- $(INSTALL) -f $(ROOTHIGHICON36SHARE) -m 0644 $<
-
-$(ROOTHIGHICON48SHARE)/%: $(ROOTDIRS) data/icons/HighContrast/48x48/%
- $(INSTALL) -f $(ROOTHIGHICON48SHARE) -m 0644 $<
-
-$(ROOTHIGHINVICON24SHARE)/%: $(ROOTDIRS) data/icons/HighContrastInverse/24x24/%
- $(INSTALL) -f $(ROOTHIGHINVICON24SHARE) -m 0644 $<
-
-$(ROOTHIGHINVICON36SHARE)/%: $(ROOTDIRS) data/icons/HighContrastInverse/36x36/%
- $(INSTALL) -f $(ROOTHIGHINVICON36SHARE) -m 0644 $<
-
-$(ROOTHIGHINVICON48SHARE)/%: $(ROOTDIRS) data/icons/HighContrastInverse/48x48/%
- $(INSTALL) -f $(ROOTHIGHINVICON48SHARE) -m 0644 $<
-
-$(ROOTICON24SHARE)/%: $(ROOTDIRS) data/icons/24x24/%
- $(INSTALL) -f $(ROOTICON24SHARE) -m 0644 $<
-
-$(ROOTICON36SHARE)/%: $(ROOTDIRS) data/icons/36x36/%
- $(INSTALL) -f $(ROOTICON36SHARE) -m 0644 $<
-
-$(ROOTICON48SHARE)/%: $(ROOTDIRS) data/icons/48x48/%
- $(INSTALL) -f $(ROOTICON48SHARE) -m 0644 $<
-
-$(ROOTSCRIPTSSHARE)/%: $(ROOTDIRS) %
- $(INSTALL) -f $(ROOTSCRIPTSSHARE) -m 0644 $<
-
-$(ROOTSHARE)/%: $(ROOTDIRS) data/%
- $(INSTALL) -f $(ROOTSHARE) -m 0644 $<
-
-$(ROOTSVCSHARE)/%: $(ROOTDIRS) %
- $(INSTALL) -f $(ROOTSVCSHARE) -m 0644 $<
--- a/src/web/Makefile Fri Sep 02 13:50:59 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#
-# 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 (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-ROOTSHARE = /usr/lib/share/pkg
-RSWEB = $(ROOTSHARE)/web
-
-all:
-
-install: all
-
-clean:
-
-clobber:
--- a/src/zoneproxy/Makefile.constants Fri Sep 02 13:50:59 2011 -0700
+++ b/src/zoneproxy/Makefile.constants Mon Aug 29 14:13:13 2011 -0700
@@ -22,11 +22,12 @@
# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
#
-INSTALL = install
+INSTALL = /usr/bin/python2.6 ../../setup.py installfile
LINT = lint
+MKDIR = mkdir -p
PROTO_AREA:sh = echo $(hg root)/proto/root_$(uname -p)
-ZONES_LIBDIR = $(PROTO_AREA)/usr/lib/zones
-ZONES_PROG = $(PROG:%=$(ZONES_LIBDIR)/%)
+ZONES_LIBDIR = $(PROTO_AREA)/usr/lib/zones
+ZONES_PROG = $(PROG:%=$(ZONES_LIBDIR)/%)
LINTFLAGS = -asxm -u -errtags=yes -s -errsecurity=core -Xc99=%none
CPPFLAGS = -D_REENTRANT -I../zoneproxyd
@@ -46,9 +47,9 @@
$(LINK.c) -o $@ $< $(LDLIBS)
$(ZONES_PROG): $(PROG)
- $(RM) -f $(ZONES_LIBDIR)/$(PROG); \
- $(INSTALL) -d -m 0755 $(ZONES_LIBDIR); \
- $(INSTALL) -s -m 0555 -f $(ZONES_LIBDIR) $(PROG)
+ $(RM) $(ZONES_LIBDIR)/$(PROG); \
+ $(MKDIR) -m 0755 $(ZONES_LIBDIR); \
+ $(INSTALL) -m 0555 -d $(ZONES_LIBDIR) -f $(PROG)
clean:
-$(RM) $(CLEANFILES)
--- a/src/zoneproxy/zoneproxyd/Makefile Fri Sep 02 13:50:59 2011 -0700
+++ b/src/zoneproxy/zoneproxyd/Makefile Mon Aug 29 14:13:13 2011 -0700
@@ -41,13 +41,14 @@
.KEEP_STATE:
-$(ROOTHDR):
- $(INSTALL) -d -m 0755 $(ROOTHDIR); \
- $(INSTALL) -s -m 0644 -f $(ROOTHDIR) $(HDR)
+$(ROOTHDR): $(ROOTHDIR) $(HDR)
+ $(INSTALL) -m 0644 -d $(ROOTHDIR) -f $(HDR)
+
+$(ROOTHDIR):
+ $(MKDIR) -m 0755 $@
all: $(PROG)
install: $(ZONES_PROG) $(ROOTHDR)
lint: lint_PROG
-