--- a/src/updatemanagernotifier.py Fri Sep 27 11:21:00 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,491 +0,0 @@
-#!/usr/bin/python2.6
-#
-# 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, 2012, Oracle and/or its affiliates. All rights reserved.
-#
-
-import os
-import subprocess
-import errno
-import sys
-import time
-import socket
-import locale
-import gettext
-import getopt
-import random
-try:
- import gobject
- gobject.threads_init()
- import gconf
- import gtk
- import pygtk
- pygtk.require("2.0")
-except ImportError:
- sys.exit(1)
-import pkg.client.progress as progress
-import pkg.misc as misc
-import pkg.gui.misc as gui_misc
-import pkg.gui.enumerations as enumerations
-from gettext import ngettext
-try:
- import pynotify
-except ImportError:
- print "%s package must be installed" % (
- gui_misc.package_name["SUNWpython26-notify"])
- sys.exit(1)
-
-# Put _() in the global namespace
-import __builtin__
-__builtin__._ = gettext.gettext
-
-START_DELAY_DEFAULT = 120
-REFRESH_PERIOD_DEFAULT = "Never"
-SHOW_NOTIFY_ICON_DEFAULT = True
-IMAGE_DIRECTORY_DEFAULT = "/"
-LASTCHECK_DIR_NAME = os.path.join(os.path.expanduser("~"),'.updatemanager/notify')
-CHECKFOR_UPDATES = "/usr/lib/pm-checkforupdates"
-UPDATEMANAGER = "pm-updatemanager"
-
-ICON_LOCATION = "/usr/share/update-manager/icons"
-NOTIFY_ICON_NAME = "updatemanager"
-GKSU_PATH = "/usr/bin/gksu"
-
-UPDATEMANAGER_PREFERENCES = "/apps/updatemanager/preferences"
-START_DELAY_PREFERENCES = "/apps/updatemanager/preferences/start_delay"
-REFRESH_PERIOD_PREFERENCES = "/apps/updatemanager/preferences/refresh_period"
-SHOW_NOTIFY_MESSAGE_PREFERENCES = "/apps/updatemanager/preferences/show_notify_message"
-SHOW_ICON_ON_STARTUP_PREFERENCES = "/apps/updatemanager/preferences/show_icon_on_startup"
-TERMINATE_AFTER_ICON_ACTIVATE_PREFERENCES = \
- "/apps/updatemanager/preferences/terminate_after_icon_activate"
-
-DAILY = "Daily"
-WEEKLY = "Weekly"
-MONTHLY = "Monthly"
-NEVER = "Never"
-
-DAILY_SECS = 24*60*60
-WEEKLY_SECS = 7*24*60*60
-# We asssume that a month has 30 days
-MONTHLY_SECS = 30*24*60*60
-NEVER_SECS = 365*24*60*60
-
-class UpdateManagerNotifier:
- def __init__(self):
- os.nice(20)
- try:
- self.application_dir = os.environ["UPDATE_MANAGER_NOTIFIER_ROOT"]
- except KeyError:
- self.application_dir = "/"
- misc.setlocale(locale.LC_ALL, "")
- gettext.bindtextdomain("pkg", os.path.join(
- self.application_dir,
- "usr/share/locale"))
- gettext.textdomain("pkg")
- self.pr = None
- self.last_check_filename = None
- self.time_until_next_check = 0
- self.status_icon = None
- self.n_updates = 0
- self.n_installs = 0
- self.n_removes = 0
- self.notify = None
- self.host = None
- self.last_check_time = 0
- self.refresh_period = 0
- self.timeout_id = 0
- self.terminate_after_activate = False
-
- self.client = gconf.client_get_default()
- self.start_delay = self.get_start_delay()
- # Allow gtk.main loop to start as quickly as possible
- gobject.timeout_add(self.start_delay * 1000, self.check_and_start)
-
- def check_and_start(self):
- self.check_already_running()
- self.client.add_dir(UPDATEMANAGER_PREFERENCES,
- gconf.CLIENT_PRELOAD_NONE)
- self.client.notify_add(REFRESH_PERIOD_PREFERENCES,
- self.refresh_period_changed)
- self.client.notify_add(SHOW_ICON_ON_STARTUP_PREFERENCES,
- self.show_icon_changed)
- self.refresh_period = self.get_refresh_period()
- self.host = socket.gethostname()
-
- self.last_check_time = self.get_last_check_time()
- self.pr = progress.NullProgressTracker()
- if self.get_show_icon_on_startup():
- self.client.set_bool(SHOW_ICON_ON_STARTUP_PREFERENCES, False)
- self.schedule_check_for_updates()
- else:
- gobject.idle_add(self.do_next_check)
- return False
-
- def refresh_period_changed(self, client, connection_id, entry, arguments):
- old_delta = self.get_delta_for_refresh_period()
- if entry.get_value().type == gconf.VALUE_STRING:
- self.refresh_period = entry.get_value().get_string()
- new_delta = self.get_delta_for_refresh_period()
- if debug == True:
- print "old_delta %d" % old_delta
- print "new_delta %d" % new_delta
- if old_delta > new_delta:
- if self.timeout_id > 0:
- gobject.source_remove(self.timeout_id)
- self.timeout_id = 0
- self.do_next_check()
-
- def show_icon_changed(self, client, connection_id, entry, arguments):
- if entry.get_value().type == gconf.VALUE_BOOL:
- show_icon = entry.get_value().get_bool()
- if self.status_icon != None:
- self.status_icon.set_visible(show_icon)
-
- def get_start_delay(self):
- start_delay = self.client.get_int(START_DELAY_PREFERENCES)
- if start_delay == 0:
- start_delay = START_DELAY_DEFAULT
- if debug == True:
- start_delay = 1
- print "start_delay: %d" % start_delay
- return start_delay
-
- def get_refresh_period(self):
- refresh_period = self.client.get_string(REFRESH_PERIOD_PREFERENCES)
- if refresh_period == None:
- refresh_period = REFRESH_PERIOD_DEFAULT
- if debug == True:
- print "refresh_period: %s" % refresh_period
- return refresh_period
-
- def get_show_notify_message(self):
- show_notify_message = \
- self.client.get_bool(SHOW_NOTIFY_MESSAGE_PREFERENCES)
- if debug == True:
- print "show_notify_message: %d" % show_notify_message
- return show_notify_message
-
- def get_show_icon_on_startup(self):
- show_icon_on_startup = \
- self.client.get_bool(SHOW_ICON_ON_STARTUP_PREFERENCES)
- if debug == True:
- print "show_icon_on_startup: %d" % show_icon_on_startup
- return show_icon_on_startup
-
- def get_terminate_after_activate(self):
- terminate_after_activate = \
- self.client.get_bool(TERMINATE_AFTER_ICON_ACTIVATE_PREFERENCES)
- if debug == True:
- print "terminate_after_activate: %d" % terminate_after_activate
- return terminate_after_activate
-
- def get_last_check_time(self):
- if (self.last_check_filename == None):
- self.last_check_filename = \
- os.path.join(LASTCHECK_DIR_NAME,
- self.host + '-lastcheck')
- try:
- f = open(self.last_check_filename, "r")
-
- try:
- return float(f.read(64))
- finally:
- f.close()
-
- except IOError, strerror:
- if debug == True:
- print "Unable to get last check time error %s" % strerror
-
- return 0
-
- def set_last_check_time(self):
- try:
- os.makedirs(LASTCHECK_DIR_NAME)
- except os.error, eargs:
- if eargs[0] != errno.EEXIST: # File exists
- raise os.error, args
-
- try:
- f = open(self.last_check_filename, "w")
-
- try:
- f.write(str(self.last_check_time))
- finally:
- f.close()
-
- except IOError, strerror:
- print "I/O error: %s opening %s" \
- % (strerror, self.last_check_filename)
-
- def get_delta_for_refresh_period(self):
- if self.refresh_period == DAILY:
- delta = DAILY_SECS
- elif self.refresh_period == WEEKLY:
- delta = WEEKLY_SECS
- elif self.refresh_period == MONTHLY:
- delta = MONTHLY_SECS
- else:
- delta = NEVER_SECS
- return delta
-
- def is_check_required(self):
- delta = self.get_delta_for_refresh_period()
- if delta == NEVER_SECS:
- self.time_until_next_check = NEVER_SECS
- return False
- if self.last_check_time == 0:
- return True
- current_time = time.time()
- if debug == True:
- print "current time %f " % current_time
- print "last check time %f " % self.last_check_time
- self.time_until_next_check = self.last_check_time + delta - current_time
- if debug == True:
- print "time until next check %f " % self.time_until_next_check
- if self.time_until_next_check <= 0:
- return True
- else:
- return False
-
- def show_status_icon(self, value):
- if self.status_icon == None:
- self.status_icon = self.create_status_icon()
- self.client.set_bool(SHOW_ICON_ON_STARTUP_PREFERENCES, value)
- self.status_icon.set_visible(value)
- if not value:
- return
-
- toolfmt = _("<b>Updates are available: </b>\n"
- "%(updates)s %(installs)s %(removes)s")
- tooltip = self.__set_updates_str(toolfmt)
- self.status_icon.set_tooltip_markup(tooltip)
-
- def __set_updates_str(self, str_fmt):
- if self.n_updates == 0:
- updates_str = ""
- else:
- updates_fmt = ngettext("%d Update,", "%d Updates,",
- self.n_updates)
- updates_str = updates_fmt % self.n_updates
- if self.n_installs == 0:
- installs_str = ""
- else:
- installs_fmt = ngettext("%d Install,", "%d Installs,",
- self.n_installs)
- installs_str = installs_fmt % self.n_installs
- if self.n_removes == 0:
- removes_str = ""
- else:
- removes_fmt = ngettext("%d Remove", "%d Removes",
- self.n_removes)
- removes_str = removes_fmt % self.n_removes
- updates_str = str_fmt % \
- {"updates": updates_str,
- "installs": installs_str,
- "removes": removes_str}
- updates_str = updates_str.rstrip(', ')
- return updates_str
-
- def schedule_check_for_updates(self):
- self.last_check_time = time.time()
- # Add random delay so that servers will not be hit
- # all at once
- if debug:
- random_delay = 0
- else:
- random_delay = random.randint(0, 1800)
- gobject.timeout_add(random_delay * 1000, self.check_for_updates)
-
- def check_for_updates(self):
- proc = subprocess.Popen([CHECKFOR_UPDATES,
- '--nice', '--checkupdates-cache',
- '--image-dir', IMAGE_DIRECTORY_DEFAULT],
- stdout=subprocess.PIPE)
-
- output = proc.communicate()[0].strip()
- lines = output.splitlines()
- n_updates = 0
- n_installs = 0
- n_removes = 0
- for line in lines:
- if line.startswith("n_updates"):
- updates = line.split(":", 1)
- n_updates = int(updates[1])
- if line.startswith("n_installs"):
- installs = line.split(":", 1)
- n_installs = int(installs[1])
- if line.startswith("n_removes"):
- removes = line.split(":", 1)
- n_removes = int(removes[1])
- return_code = proc.wait()
- if debug:
- print "return from subprocess is %d" % return_code
- self.set_last_check_time()
- if return_code == enumerations.UPDATES_AVAILABLE:
- self.n_updates = n_updates
- self.n_installs = n_installs
- self.n_removes = n_removes
- self.show_status_icon(True)
- else:
- self.show_status_icon(False)
- self.schedule_next_check_for_checks()
- return False
-
- def create_status_icon(self):
- icon_theme = gtk.IconTheme()
- icon_theme.append_search_path(ICON_LOCATION)
- icon = gui_misc.get_icon(icon_theme, NOTIFY_ICON_NAME, 24)
- status_icon = gtk.status_icon_new_from_pixbuf(icon)
- status_icon.set_visible(False)
- status_icon.connect('activate', self.activate_status_icon)
- status_icon.connect('notify', self.notify_status_icon)
- return status_icon
-
- def notify_status_icon(self, status_icon, paramspec):
- if paramspec.name == "embedded" and self.status_icon.is_embedded():
- if self.get_show_notify_message():
- gobject.idle_add(self.show_notify_message)
-
- def activate_status_icon(self, status_icon):
- self.show_status_icon(False)
- gobject.spawn_async([GKSU_PATH, UPDATEMANAGER])
- if self.get_terminate_after_activate():
- gtk.main_quit()
- sys.exit(0)
- else:
- self.schedule_next_check_for_checks()
-
- def show_notify_message(self):
- if self.notify == None:
- if pynotify.init("UpdateManager"):
- notify_fmt = _("Updates available\n"
- "%(updates)s %(installs)s %(removes)s")
- notify_str = self.__set_updates_str(notify_fmt)
- notify_str += _("\nPlease click on icon to update.")
- self.notify = pynotify.Notification(\
- _("Update Manager"), notify_str)
-
- if self.notify != None:
- self.set_notify_position()
- self.notify.show()
-
- def set_notify_position(self):
- geometry = self.status_icon.get_geometry()
- rectangle = geometry[1]
- orientation = geometry[2]
- x = rectangle.x
- y = rectangle.y
-
- if orientation == gtk.ORIENTATION_HORIZONTAL and y > 200:
- x += 10
- y += 5
- elif orientation == gtk.ORIENTATION_HORIZONTAL and y <=200:
- x += 10
- y += 25
- elif orientation == gtk.ORIENTATION_VERTICAL and x >200:
- x -= 5
- y += 10
- else:
- x += 25
- y += 10
- self.notify.set_hint_int32("x", x)
- self.notify.set_hint_int32("y", y)
-
- def schedule_next_check_for_checks(self):
- """This schedules the next time to wake up to check if it's
- necessary to check for updates yet."""
- if self.time_until_next_check <= 0:
- next_check_time = self.get_delta_for_refresh_period()
- else:
- next_check_time = self.time_until_next_check
- if debug == True:
- print "scheduling next check: %s" % next_check_time
- self.timeout_id = gobject.timeout_add(int(next_check_time * 1000),
- self.do_next_check)
-
- def do_next_check(self):
- self.timeout_id = 0
- if debug == True:
- print "Called do_next_check"
- print "time for check: %f - %f \n" % (time.time(), \
- self.last_check_time)
- if self.is_check_required():
- self.schedule_check_for_updates()
- else:
- self.schedule_next_check_for_checks()
- return False
-
- @staticmethod
- def check_already_running():
- atom = gtk.gdk.atom_intern("UPDATEMANAGERNOTIFIER",
- only_if_exists = False)
- pid = os.getpid()
- atom_args = [pid, ]
- fail = True
-
- is_running = gtk.gdk.get_default_root_window().property_get(atom)
- if is_running != None:
- old_pid = is_running[2][0]
- try:
- os.kill(old_pid, 0)
- except os.error, eargs:
- if eargs[0] != errno.ESRCH: # No such process
- raise os.error, args
- # Old process no longer exists
- fail = False
- else:
- # Atom does not exist
- fail = False
-
- if fail == True:
- print _("Another instance of UpdateManagerNotify is running")
- sys.exit(1)
-
- gtk.gdk.get_default_root_window().property_change(atom,
- "INTEGER", 16, gtk.gdk.PROP_MODE_REPLACE, atom_args)
-
-###############################################################################
-#-----------------------------------------------------------------------------#
-# Main
-#-----------------------------------------------------------------------------#
-
-def main():
- gtk.main()
- return 0
-
-if __name__ == '__main__':
- debug = False
- try:
- opts, args = getopt.getopt(sys.argv[1:], "hd", ["help", "debug"])
- except getopt.error, msg:
- print "%s, for help use --help" % msg
- sys.exit(2)
-
- for option, argument in opts:
- if option in ("-h", "--help"):
- print "Use -d (--debug) to run in debug mode."
- sys.exit(0)
- if option in ("-d", "--debug"):
- debug = True
-
- updatemanager_notifier = UpdateManagerNotifier()
-
- main()