1 #!/usr/bin/env python 2 3 CDDL = ''' 4 CDDL HEADER START 5 6 The contents of this file are subject to the terms of the 7 Common Development and Distribution License (the "License"). 8 You may not use this file except in compliance with the License. 9 10 You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 or http://www.opensolaris.org/os/licensing. 12 See the License for the specific language governing permissions 13 and limitations under the License. 14 15 When distributing Covered Code, include this CDDL HEADER in each 16 file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 If applicable, add the following below this CDDL HEADER, with the 18 fields enclosed by brackets "[]" replaced with your own identifying 19 information: Portions Copyright [yyyy] [name of copyright owner] 20 21 CDDL HEADER END 22 ''' 23 24 # 25 # Copyright 2008 Sun Microsystems, Inc. All rights reserved. 26 # Use is subject to license terms. 27 # 28 # ident "%Z%%M% %I% %E% SMI" 29 # 30 31 # -*- coding: utf-8 -*- 32 33 import sys 34 import ipsgui 35 import os 36 from signal import * 37 import getopt 38 from threading import Thread 39 from threading import Condition 40 import time 41 42 try: 43 import pygtk 44 pygtk.require("2.0") 45 except: 46 pass 47 try: 48 import gtk 49 import gtk.glade 50 import gobject 51 except: 52 sys.exit(1) 53 54 class IpsService: 55 def __init__(self, flags): 56 57 self.ipsGuiInstance = ipsgui.IpsGui(self) 58 signal(15, self.signal_handler) 59 signal(2, self.signal_handler) 60 signal(1, self.signal_handler) 61 62 self.atom = gtk.gdk.atom_intern("UpdateServiceIpsGui",\ 63 only_if_exists=False) 64 atom_args = ['HaveInstance',] 65 isRunning = gtk.gdk.get_default_root_window().property_get(self.atom) 66 if force == False and isRunning != None: 67 print "Another instance of updateservice is already running" 68 sys.exit(1) 69 else: 70 gtk.gdk.get_default_root_window().property_change(self.atom,\ 71 "ATOM", 32, gtk.gdk.PROP_MODE_REPLACE,atom_args) 72 try: 73 pid = os.fork() 74 if pid > 0: os._exit(0) 75 self.create_status_icon() 76 except OSError, error: 77 raise error 78 os._exit(1) 79 80 self.condition = Condition() 81 self.stop = 0 82 Thread(target=self.main_service_loop, args=()).start() 83 84 def main_service_loop(self): 85 while 1: 86 self.condition.acquire() 87 if not self.stop: 88 # Working loop 89 self.condition.wait(60) 90 self.condition.release() 91 else: 92 # Stopping the thread 93 self.condition.release() 94 break 95 96 def signal_handler(self,sig, frame): 97 #print "Exitinig update service daemon" 98 self.condition.acquire() 99 self.stop = 1 100 self.condition.notifyAll() 101 self.condition.release() 102 gtk.gdk.get_default_root_window().property_delete(self.atom) 103 gtk.main_quit() 104 return True 105 106 def create_status_icon(self,parent=None): 107 #shoud hide and show if there is no update 108 icon = self.ipsGuiInstance.get_icon_pixbuf('installed') 109 status_icon = gtk.status_icon_new_from_pixbuf(icon) 110 status_icon.set_blinking(False) 111 status_icon.connect('activate', self.on_mouse_right_click) 112 status_icon.set_visible(False) 113 import time 114 time.sleep(1) 115 self.updates = 0 116 status_icon.set_visible(True) 117 gdk_screen, gdk_rectangle, gtk_orientation = status_icon.get_geometry() 118 if gdk_rectangle.x == 0 or gdk_rectangle.y== 0: 119 # icon not up yet to get geometry 120 time.sleep(0.5) 121 gdk_screen, gdk_rectangle, gtk_orientation = status_icon.get_geometry() 122 self.show_notification_message(gdk_rectangle.x, gdk_rectangle.y,\ 123 gtk_orientation.value_nick) 124 def on_mouse_right_click(self, status_icon): 125 self.run_ips_gui() 126 127 def show_notification_message(self,x,y,orientation): 128 x_x = x 129 y_y = y 130 if orientation == "horizontal" and y > 200: 131 x_x = x - 10 132 y_y = y + 5 133 elif orientation == "horizontal" and y <= 200: 134 x_x = x - 10 135 y_y = y + 25 136 elif orientation == "vertical" and x > 200: 137 x_x = x - 5 138 y_y = y - 10 139 else: 140 x_x = x + 25 141 y_y = y - 10 142 143 # CAUTION DONT CHANGE UNLESS ABSOLUTE NEED HARD TO ADJUST 144 os.popen("notify-send --hint=int:x:%d --hint=int:y:%d -i gtk-dialog-info\ 145 'Updates Available!\n' 'A Total of %d updates are available.\nPlease \ 146 click on icon to update.'" %(x_x, y_y, self.updates)) 147 148 def run_ips_gui(self): 149 self.ipsGuiInstance.run_gui(False) 150 151 152 ############################################################################### 153 #-----------------------------------------------------------------------------# 154 # Main 155 #-----------------------------------------------------------------------------# 156 157 def main(): 158 gtk.main() 159 return 0 160 161 if __name__ == '__main__': 162 force = False 163 try: 164 opts, args = getopt.getopt(sys.argv[1:], "hf", ["help", "force"]) 165 except getopt.error, msg: 166 print "%s, for help use --help" % msg 167 sys.exit(2) 168 for option, arguments in opts: 169 if option in ("-h", "--help"): 170 print "Use -f (--force) if you are unable to start server." 171 sys.exit(0) 172 if option in ("-f", "--force"): 173 force = True 174 175 ipsservice = IpsService(force) 176 main() 177