--- a/src/checkforupdates.py Thu Jul 16 09:35:26 2009 -0700
+++ b/src/checkforupdates.py Thu Jul 16 18:19:39 2009 +0100
@@ -25,60 +25,149 @@
import os
import sys
-import gettext
+import time
+import getopt
import pkg.client.progress as progress
-import pkg.misc as misc
+import pkg.client.api_errors as api_errors
import pkg.gui.misc as gui_misc
+import pkg.gui.enumerations as enumerations
from pkg.client import global_settings
+from cPickle import UnpicklingError
-UPDATES_AVAILABLE = 0
-NO_UPDATES_AVAILABLE = 1
-ERROR_OCCURRED = 2
-PKG_CLIENT_NAME = "updatemanagernotifier"
-
+PKG_CLIENT_NAME = "check_for_updates"
+CACHE_VERSION = 1
+CACHE_NAME = ".last_refresh_cache"
-# Put _() in the global namespace
-import __builtin__
-__builtin__._ = gettext.gettext
-
-def check_for_updates(image_directory):
- os.nice(20)
+def __check_for_updates(image_directory, nice):
+ if nice:
+ os.nice(20)
global_settings.client_name = PKG_CLIENT_NAME
pr = progress.NullProgressTracker()
api_obj = gui_misc.get_api_object(image_directory, pr, None)
- api_obj.refresh()
+ if api_obj == None:
+ return enumerations.UPDATES_UNDETERMINED
+ ret = __check_last_refresh(api_obj)
+ if ret != enumerations.UPDATES_UNDETERMINED:
+ return ret
+ elif debug:
+ print "Updates undetermined in check_last_refresh"
- pkg_upgradeable = None
- for pkg, state in misc.get_inventory_list(api_obj.img, [],
- all_known=True, all_versions=False):
- if state["upgradable"] and state["state"] == "installed":
- pkg_upgradeable = pkg
- break
-
- if pkg_upgradeable != None:
+ try:
+ stuff_to_do, opensolaris_image, cre = \
+ api_obj.plan_update_all(sys.argv[0],
+ refresh_catalogs = True,
+ noexecute = True, force = True, verbose = False)
+ except api_errors.ApiException, e:
+ if debug:
+ print "Exception occurred: ", str(e)
+ return enumerations.UPDATES_UNDETERMINED
+ if debug:
+ print "stuff_to_do: ", stuff_to_do
+ print "opensolaris_image: ", opensolaris_image
+ print "cre: ", cre
+
+ if cre and not cre.succeeded:
+ if debug:
+ print "Error occurred in plan_update_all"
+ return enumerations.UPDATES_UNDETERMINED
+ __dump_updates_available(api_obj, stuff_to_do)
+ if stuff_to_do:
if debug:
print "Updates Available"
- sys.exit(UPDATES_AVAILABLE)
+ return enumerations.UPDATES_AVAILABLE
else:
if debug:
print "No updates Available"
- sys.exit(NO_UPDATES_AVAILABLE)
+ return enumerations.NO_UPDATES_AVAILABLE
+
+def __check_last_refresh(api_obj):
+ cache_dir = gui_misc.get_cache_dir(api_obj)
+ if not cache_dir:
+ return enumerations.UPDATES_UNDETERMINED
+ try:
+ info = gui_misc.read_cache_file(os.path.join(
+ cache_dir, CACHE_NAME + '.cpl'))
+ if info.get("version") != CACHE_VERSION:
+ return enumerations.UPDATES_UNDETERMINED
+ old_publishers = info.get("publishers")
+ count = 0
+ for p in api_obj.get_publishers():
+ if p.disabled:
+ continue
+ try:
+ if old_publishers[p.prefix] != p.last_refreshed:
+ return enumerations.UPDATES_UNDETERMINED
+ except KeyError:
+ return enumerations.UPDATES_UNDETERMINED
+ count += 1
+
+ if count != len(old_publishers):
+ return enumerations.UPDATES_UNDETERMINED
+ if info.get("updates_available"):
+ return enumerations.UPDATES_AVAILABLE
+ else:
+ return enumerations.NO_UPDATES_AVAILABLE
+
+ except (UnpicklingError, IOError):
+ return enumerations.UPDATES_UNDETERMINED
+
+def __dump_updates_available(api_obj, stuff_to_do):
+ cache_dir = gui_misc.get_cache_dir(api_obj)
+ if not cache_dir:
+ return
+ publisher_list = {}
+ for p in api_obj.get_publishers():
+ if p.disabled:
+ continue
+ publisher_list[p.prefix] = p.last_refreshed
+ if debug:
+ print "publisher_list:", publisher_list
+ dump_info = {}
+ dump_info["version"] = CACHE_VERSION
+ dump_info["updates_available"] = stuff_to_do
+ dump_info["publishers"] = publisher_list
+
+ try:
+ gui_misc.dump_cache_file(os.path.join(
+ cache_dir, CACHE_NAME + '.cpl'), dump_info)
+ except IOError, e:
+ if debug:
+ print "Failed to dump cache: %s" % str(e)
+
+ return
###############################################################################
#-----------------------------------------------------------------------------#
# Main
#-----------------------------------------------------------------------------#
-def main(image_directory):
- check_for_updates(image_directory)
- return ERROR_OCCURRED
+def main(image_directory, nice):
+ return __check_for_updates(image_directory, nice)
if __name__ == '__main__':
debug = False
- if len(sys.argv) != 2:
- print "One argument, image directory must be specified"
- sys.exit(ERROR_OCCURRED)
- image_dir = sys.argv[1]
- main(image_dir)
+ set_nice = False
+ try:
+ opts, pargs = getopt.getopt(sys.argv[1:], "n", ["nice"])
+ except getopt.GetoptError, ex:
+ print "Usage: illegal option -- %s" % ex.opt
+ sys.exit(enumerations.UPDATES_UNDETERMINED)
+ if len(pargs) != 1:
+ print "Usage: One argument, image directory must be specified"
+ sys.exit(enumerations.UPDATES_UNDETERMINED)
+ image_dir = pargs[0]
+ for opt, args in opts:
+ if debug:
+ print "opt: ", opt
+ print "args: ", args
+ if opt in ( "-n", "--nice"):
+ set_nice = True
+ if debug:
+ print "Start check_for_updates for: ", image_dir, set_nice
+ a = time.time()
+ return_value = main(image_dir, set_nice)
+ if debug:
+ print "time taken: ", time.time() - a
+ sys.exit(return_value)
--- a/src/gui/modules/cache.py Thu Jul 16 09:35:26 2009 -0700
+++ b/src/gui/modules/cache.py Thu Jul 16 18:19:39 2009 +0100
@@ -23,7 +23,6 @@
# Use is subject to license terms.
#
-import cPickle
import os
import sys
try:
@@ -51,8 +50,9 @@
self.update_available_icon = update_available_icon
self.installed_icon = installed_icon
self.not_installed_icon = not_installed_icon
- self.category_icon = gui_misc.get_pixbuf_from_path(application_dir +
- "/usr/share/package-manager/", "legend_newupdate")
+ self.category_icon = gui_misc.get_pixbuf_from_path(
+ os.path.join(application_dir,
+ "usr/share/package-manager/"), "legend_newupdate")
def check_if_cache_uptodate(self, publisher):
try:
@@ -82,22 +82,11 @@
return True
def __get_cache_dir(self):
- img = self.api_o.img
- cache_dir = os.path.join(img.imgdir, "gui_cache")
- try:
- self.__mkdir(cache_dir)
- except OSError:
- cache_dir = None
- return cache_dir
-
- @staticmethod
- def __mkdir(directory_path):
- if not os.path.isdir(directory_path):
- os.makedirs(directory_path)
+ return gui_misc.get_cache_dir(self.api_o)
def get_index_timestamp(self):
img = self.api_o.img
- index_path = "%s/state/installed" % (img.imgdir)
+ index_path = os.path.join(img.imgdir, "state/installed")
try:
return os.path.getmtime(index_path)
except (OSError, IOError):
@@ -121,7 +110,8 @@
dump_info["be_name"] = None
try:
- self.__dump_cache_file(os.path.join(cache_dir, publisher+".cpl"),
+ gui_misc.dump_cache_file(
+ os.path.join(cache_dir, publisher+".cpl"),
dump_info)
except IOError:
#Silently return, as probably user doesn't have permissions or
@@ -141,7 +131,8 @@
dump_info["be_name"] = self.__get_active_be_name()
try:
- self.__dump_cache_file(os.path.join(cache_dir, publisher+".cpl"),
+ gui_misc.dump_cache_file(
+ os.path.join(cache_dir, publisher+".cpl"),
dump_info)
self.__dump_category_list(publisher, category_list)
self.__dump_application_list(publisher, application_list)
@@ -167,7 +158,7 @@
cat["visible"] = category[enumerations.CATEGORY_VISIBLE]
cat["section_list"] = category[enumerations.SECTION_LIST_OBJECT]
categories.append(cat)
- self.__dump_cache_file(os.path.join(cache_dir,
+ gui_misc.dump_cache_file(os.path.join(cache_dir,
publisher+"_categories.cpl"), categories)
def __dump_application_list(self, publisher, application_list):
@@ -189,7 +180,7 @@
application[enumerations.CATEGORY_LIST_COLUMN]
app["pkg_authority"] = application[enumerations.AUTHORITY_COLUMN]
apps.append(app)
- self.__dump_cache_file(
+ gui_misc.dump_cache_file(
os.path.join(cache_dir, publisher+"_packages.cpl"), apps)
def __dump_section_list(self, publisher, section_list):
@@ -204,21 +195,22 @@
sec["subcategory"] = section[enumerations.SECTION_SUBCATEGORY]
sec["enabled"] = section[enumerations.SECTION_ENABLED]
sections.append(sec)
- self.__dump_cache_file(os.path.join(cache_dir, publisher+"_sections.cpl"),
+ gui_misc.dump_cache_file(
+ os.path.join(cache_dir, publisher+"_sections.cpl"),
sections)
def __load_cache_info(self, publisher):
cache_dir = self.__get_cache_dir()
if not cache_dir:
return None
- info = self.__read_cache_file(os.path.join(cache_dir, publisher+".cpl"))
+ info = gui_misc.read_cache_file(os.path.join(cache_dir, publisher+".cpl"))
return info
def load_category_list(self, publisher, category_list):
cache_dir = self.__get_cache_dir()
if not cache_dir:
return
- categories = self.__read_cache_file(
+ categories = gui_misc.read_cache_file(
os.path.join(cache_dir, publisher+"_categories.cpl"))
cat_count = 0
for cat in categories:
@@ -244,7 +236,7 @@
cache_dir = self.__get_cache_dir()
if not cache_dir:
return
- applications = self.__read_cache_file(
+ applications = gui_misc.read_cache_file(
os.path.join(cache_dir, publisher+"_packages.cpl"))
app_count = len(application_list)
if app_count > 0:
@@ -286,7 +278,7 @@
cache_dir = self.__get_cache_dir()
if not cache_dir:
return
- sections = self.__read_cache_file(
+ sections = gui_misc.read_cache_file(
os.path.join(cache_dir, publisher+"_sections.cpl"))
sec_count = 0
for sec in sections:
@@ -324,19 +316,6 @@
return name
return None
- @staticmethod
- def __read_cache_file(file_path):
- fh = open(file_path, 'r')
- data = cPickle.load(fh)
- fh.close()
- return data
-
- @staticmethod
- def __dump_cache_file(file_path, data):
- fh = open(file_path,"w")
- cPickle.dump(data, fh, True)
- fh.close()
-
def __dump_search_completion_info(self, completion_list):
cache_dir = self.__get_cache_dir()
if not cache_dir:
@@ -347,7 +326,7 @@
txt["text"] = text[0]
texts.append(txt)
try:
- self.__dump_cache_file(
+ gui_misc.dump_cache_file(
os.path.join(cache_dir, ".__search__completion.cpl"), texts)
except IOError:
return
@@ -358,7 +337,7 @@
return
texts = []
try:
- texts = self.__read_cache_file(
+ texts = gui_misc.read_cache_file(
os.path.join(cache_dir, ".__search__completion.cpl"))
except IOError:
return gtk.ListStore(str)
--- a/src/gui/modules/enumerations.py Thu Jul 16 09:35:26 2009 -0700
+++ b/src/gui/modules/enumerations.py Thu Jul 16 18:19:39 2009 +0100
@@ -115,4 +115,10 @@
PUBLISHER_ENABLED,
) = range(7)
+# Return values from /usr/lib/pm-checkforupdates
+(
+UPDATES_AVAILABLE,
+NO_UPDATES_AVAILABLE,
+UPDATES_UNDETERMINED
+) = range(3)
--- a/src/gui/modules/misc.py Thu Jul 16 09:35:26 2009 -0700
+++ b/src/gui/modules/misc.py Thu Jul 16 18:19:39 2009 +0100
@@ -28,6 +28,7 @@
# However we need to have an exception rule
# where we will cut all but three last parts.
+import cPickle
import os
import sys
try:
@@ -119,6 +120,19 @@
return pkg_name[index:].strip("/") + converted_name
return pkg_name_bk
+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, parent_dialog):
api_o = None
message = None
@@ -135,11 +149,22 @@
if parent_dialog != None:
error_occurred(parent_dialog,
message, _("API Error"))
+ sys.exit(0)
else:
print message
- sys.exit(0)
return api_o
+def read_cache_file(file_path):
+ fh = open(file_path, 'r')
+ data = cPickle.load(fh)
+ fh.close()
+ return data
+
+def dump_cache_file(file_path, data):
+ fh = open(file_path,"w")
+ cPickle.dump(data, fh, True)
+ fh.close()
+
def error_occurred(parent, error_msg, msg_title = None,
msg_type=gtk.MESSAGE_ERROR, use_markup = False):
msgbox = gtk.MessageDialog(parent =
--- a/src/packagemanager.py Thu Jul 16 09:35:26 2009 -0700
+++ b/src/packagemanager.py Thu Jul 16 18:19:39 2009 +0100
@@ -62,6 +62,7 @@
STATUS_COLUMN_INDEX = 2 # Index of Status Column in Application TreeView
PKG_CLIENT_NAME = "packagemanager"
+CHECK_FOR_UPDATES = "/usr/lib/pm-checkforupdates"
# Location for themable icons
ICON_LOCATION = "usr/share/package-manager/icons"
@@ -89,6 +90,7 @@
import getopt
import pwd
import os
+import subprocess
import sys
import time
import locale
@@ -836,15 +838,6 @@
self.api_search_error_dialog.show()
self.api_search_button.grab_focus()
- def __get_repo_publishers(self):
- repo_pub_dict = {}
- pubs = self.api_o.get_publishers()
- for pub in pubs:
- repo = pub.selected_repository
- origin = repo.origins[0]
- repo_pub_dict[origin.uri] = pub.prefix
- return repo_pub_dict
-
def __on_url(self, view, link):
# Handle mouse over events on links and reset when not on link
if link == None or link == "":
@@ -3372,7 +3365,6 @@
gobject.idle_add(self.w_updateall_menuitem.set_sensitive, False)
update_available = self.__check_if_updates_available()
gobject.idle_add(self.__g_enable_disable_update_all, update_available)
- gobject.idle_add(self.__show_info_after_catalog_load)
return False
def __show_info_after_catalog_load(self):
@@ -3385,20 +3377,22 @@
self.__show_licenses()
def __check_if_updates_available(self):
+ # First we load the catalogs so package info can work
try:
self.catalog_loaded = False
self.api_o.refresh()
self.catalog_loaded = True
- res = self.__get_inventory_list([], False, False)
- for pfmri, state in res:
- if state["upgradable"]:
- self.pylintstub = pfmri
- return True
-
except api_errors.InventoryException:
gobject.idle_add(self.__set_empty_details_panel)
return False
- return False
+ gobject.idle_add(self.__show_info_after_catalog_load)
+
+ return_code = subprocess.call([CHECK_FOR_UPDATES,
+ self.image_directory])
+ if return_code == enumerations.UPDATES_AVAILABLE:
+ return True
+ else:
+ return False
def __g_enable_disable_update_all(self, update_available):
self.w_updateall_button.set_sensitive(update_available)
--- a/src/pkgdefs/SUNWipkg-gui/prototype Thu Jul 16 09:35:26 2009 -0700
+++ b/src/pkgdefs/SUNWipkg-gui/prototype Thu Jul 16 18:19:39 2009 +0100
@@ -8,6 +8,7 @@
d none usr/bin 755 root bin
f none usr/bin/packagemanager 755 root bin
d none usr/lib 755 root bin
+f none usr/lib/pm-checkforupdates 755 root bin
f none usr/lib/pm-launch 755 root bin
d none usr/lib/python2.4 755 root bin
d none usr/lib/python2.4/vendor-packages 755 root bin
--- a/src/pkgdefs/SUNWipkg-um/prototype Thu Jul 16 09:35:26 2009 -0700
+++ b/src/pkgdefs/SUNWipkg-um/prototype Thu Jul 16 18:19:39 2009 +0100
@@ -17,7 +17,6 @@
d none usr/lib 755 root bin
d none usr/lib/update-manager 755 root bin
f none usr/lib/update-manager/update-refresh.sh 755 root bin
-f none usr/lib/um-checkforupdates 755 root bin
f none usr/lib/updatemanagernotifier 755 root bin
d none usr/share 755 root sys
d none usr/share/applications 755 root other
--- a/src/setup.py Thu Jul 16 09:35:26 2009 -0700
+++ b/src/setup.py Thu Jul 16 18:19:39 2009 +0100
@@ -163,7 +163,7 @@
lib_dir: [
['depot.py', 'pkg.depotd'],
['updatemanagernotifier.py', 'updatemanagernotifier'],
- ['checkforupdates.py', 'um-checkforupdates'],
+ ['checkforupdates.py', 'pm-checkforupdates'],
['launch.py', 'pm-launch'],
],
svc_method_dir: [
--- a/src/um/update-refresh.sh Thu Jul 16 09:35:26 2009 -0700
+++ b/src/um/update-refresh.sh Thu Jul 16 18:19:39 2009 +0100
@@ -26,7 +26,10 @@
# This script is run as part of a cron job at 0:30, 9:30, 12:30, 18:30, 21:30
# 1. Refresh the IPS catalog
#
-# 2. Fetch updates to Packagemanager's Start Page files:
+# 2. Call /usr/lib/pm-checkforupdates to check and cache whether updates
+# are available
+#
+# 3. Fetch updates to Packagemanager's Start Page files:
# startpagebase-<locale prefix>.tar.gz
#
# From the URL in the specifed Packagemanager Gconf key:
@@ -58,6 +61,9 @@
pkg refresh 2>/dev/null
+# Check and cache whether updates are available
+/usr/lib/pm-checkforupdates --nice $image_dir
+
# Fetch updates to Packagemanager's Start Page files
TAR="/usr/gnu/bin/tar"
WGET="/usr/bin/wget"
--- a/src/updatemanager.py Thu Jul 16 09:35:26 2009 -0700
+++ b/src/updatemanager.py Thu Jul 16 18:19:39 2009 +0100
@@ -26,6 +26,7 @@
import getopt
import os
+import subprocess
import sys
import time
import locale
@@ -63,6 +64,7 @@
PKG_ICON_LOCATION = "usr/share/package-manager/icons"
ICON_LOCATION = "usr/share/update-manager/icons"
+CHECK_FOR_UPDATES = "/usr/lib/pm-checkforupdates"
PKG_CLIENT_NAME = "updatemanager" # API client name
SELECTION_CHANGE_LIMIT = 0.5 # Time limit in seconds to cancel selection updates
IND_DELAY = 0.05 # Time delay for printing index progress
@@ -372,6 +374,15 @@
gobject.TYPE_STRING, # UM_STEM
)
+ # Use check_for_updates to determine whether updates
+ # are available
+ return_code = subprocess.call([CHECK_FOR_UPDATES,
+ self.__get_image_path()])
+ if return_code == enumerations.NO_UPDATES_AVAILABLE:
+ self.progress_stop_thread = True
+ gobject.idle_add(self.__display_noupdates)
+ return
+
self.api_obj = self.__get_api_obj()
image_obj = self.api_obj.img
#TODO: This part is required so misc.get_inventory_list
--- a/src/updatemanagernotifier.py Thu Jul 16 09:35:26 2009 -0700
+++ b/src/updatemanagernotifier.py Thu Jul 16 18:19:39 2009 +0100
@@ -51,6 +51,7 @@
import pkg.client.progress as progress
import pkg.misc as misc
import pkg.gui.misc as gui_misc
+import pkg.gui.enumerations as enumerations
# Put _() in the global namespace
import __builtin__
@@ -62,7 +63,7 @@
IMAGE_DIRECTORY_DEFAULT = "/"
LASTCHECK_DIR_NAME = os.path.join(os.path.expanduser("~"),'.updatemanager/notify')
IMAGE_DIR_COMMAND = "svcprop -p update/image_dir svc:/application/pkg/update"
-CHECK_FOR_UPDATES = "/usr/lib/um-checkforupdates"
+CHECK_FOR_UPDATES = "/usr/lib/pm-checkforupdates"
ICON_LOCATION = "/usr/share/update-manager/icons"
NOTIFY_ICON_NAME = "notify_update"
@@ -285,11 +286,11 @@
if len(image_directory) == 0:
image_directory = IMAGE_DIRECTORY_DEFAULT
return_code = subprocess.call([CHECK_FOR_UPDATES,
- image_directory])
+ '--nice', image_directory])
if debug:
print "return from subprocess is %d" % return_code
self.set_last_check_time()
- if return_code == 0:
+ if return_code == enumerations.UPDATES_AVAILABLE:
self.show_status_icon(True)
else:
self.show_status_icon(False)