class SageData: #### constructor initializes member values def __init__(self, sageGate, autosave, displayName): self.noOfApps = 0 self.hashCallback = {} # functions to call in sageui.py for updating the UI self.hashApps = {} # all the apps available for running?? self.hashAppStatusInfo = {} # apps currently running self.hashAppPerfInfo = {} self.hashFileInfo = {} self.displayInfo = SageDisplayInfo() self.sageGate = sageGate self.autosave = autosave self.timeStarted = time.strftime("%Y%m%d-%H%M%S", time.localtime()) self.displayName = displayName.strip() self.__firstAutosave = True self._sageColor = (0,0,0) self.__bPerformanceLogging = True # (AKS 2005-02-15) The hash below is used for determining when to # calculate the total values for all active applications. This # hash originally belonged in GraphManager of Graph.py. However, # the implementation was not clean and lent itself to infinite # recursion. So, having the total calculation at the source of # where the data is kept seemed to make the most sense. #self.__hashAppGraphUpdateFlag = {} # Constants used for keys in __hashAppPerfTotals (public scope) self.I_RENDER_TOTAL_BANDWIDTH = 10 self.I_RENDER_AVG_FRAME_RATE = 20 self.I_RENDER_TOTAL_NODES = 30 self.I_DISPLAY_TOTAL_BANDWIDTH = 40 self.I_DISPLAY_AVG_FRAME_RATE = 50 self.I_DISPLAY_TOTAL_NODES = 60 self.__hashAppPerfTotals = {} self.__hashAppPerfTotals[ self.I_RENDER_TOTAL_BANDWIDTH ] = 0.0 self.__hashAppPerfTotals[ self.I_RENDER_AVG_FRAME_RATE ] = 0.0 self.__hashAppPerfTotals[ self.I_RENDER_TOTAL_NODES ] = 0 self.__hashAppPerfTotals[ self.I_DISPLAY_TOTAL_BANDWIDTH ] = 0.0 self.__hashAppPerfTotals[ self.I_DISPLAY_AVG_FRAME_RATE ] = 0.0 self.__hashAppPerfTotals[ self.I_DISPLAY_TOTAL_NODES ] = 0 # for knowing when to zero out the totals since # sage doesnt send perf data when it's 0 self.__lastTotalsUpdate = time.time() # (AKS 2005-05-07) Create two PerformanceGraphs (one for total render bandwidth # and one for total display bandwidth). This is a hack...2 is specified in # the GraphManager class not for updating purposes but so that the x-axis values # are computed correctly. The created numarray object takes the place of what # sageAppPerfInfo does (well, it's adjusted manually later) self.__iMaxArraySize = 30 self.__iUpdateInterval = 2 self.__pgTotalRenderBandwidth = Graph.PerformanceGraph( "Totals", "Render Bandwidth (Mbps)", self.__iMaxArraySize, self.__iUpdateInterval ) self.__pgTotalDisplayBandwidth = Graph.PerformanceGraph( "Totals", "Display Bandwidth (Mbps)", self.__iMaxArraySize, self.__iUpdateInterval ) self.__sapiPerfTotals = sageAppPerfInfo() #### Set the sage status def setSageStatus(self, appHash) : self.noOfApps = len(appHash) #for line in listTokens: for appName, configs in appHash.iteritems(): hashSingleAppInfo = {} self.hashApps[appName] = SageAppInitial(appName, configs) # when done processing the incoming data, call a function in the UI to update the screen if ( 40000 in self.hashCallback ): self.hashCallback[ 40000 ]() #---------------------------------------------------------------------- ### Set the possible execution configurations for each app def setSageAppExecConfig(self, data): tokens = string.split( data, '\n', 1 ) appName = tokens[0] data = tokens[1] #the rest configList = string.split( data, "config ") del configList[0] #remove the first item in the list for config in configList: if appName in self.hashApps.keys(): (name, stringConfig) = string.split(config, ":", 1) self.hashApps[appName].AddConfig(name, stringConfig) if ( 40006 in self.hashCallback ): self.hashCallback[ 40006 ](self.hashApps[appName]) #---------------------------------------------------------------------- #### Set the SAGE display information #### def setDisplayInfo(self, data): listTokens = string.split(data, '\n') for i in range(0, len(listTokens), 3): tileNumTokens = string.split(listTokens[i], ' ') desktopTokens = string.split(listTokens[i+1], ' ') tileConfTokens = string.split(listTokens[i+2], ' ') # so that we can support the old sage as well displayId = 0 if len(tileConfTokens) > 2: displayId = int(tileConfTokens[2]) self.displayInfo.addDisplay(int(tileNumTokens[0]), int(tileNumTokens[1]), int(tileNumTokens[2]), int(desktopTokens[0]), int(desktopTokens[1]), int(tileConfTokens[0]), int(tileConfTokens[1]), displayId) # (AKS 2004-10-23) Provide the app-id to the callback if ( 40004 in self.hashCallback ): self.hashCallback[ 40004 ]() #---------------------------------------------------------------------- # returns the SageDisplayInfo object def getDisplayInfo(self, displayId=0): return self.displayInfo #---------------------------------------------------------------------- def setDisplayConnections(self, data): for connection in data.split('\n'): tokens = connection.split() displayId = int(tokens[2]) self.displayInfo.getDisplay(displayId).placement = int(tokens[1]) if ( 40007 in self.hashCallback ): self.hashCallback[ 40007 ]() #---------------------------------------------------------------------- #### Get the new list of z values from SAGE #### and update local hashes, then call the function to update the UI visually def setSageZValue(self, message): tokens = string.split(message) numZChanges = int(tokens[0]) #the first item that comes in is the number of z changes # loop through all the tokens and update the z values of the apps for i in range(numZChanges): self.setZvalue( int(tokens[i*2+1]), int(tokens[i*2+2]) ) # now call the appropriate function to update the UI visually if ( 40005 in self.hashCallback ): self.hashCallback[ 40005 ]( ) #---------------------------------------------------------------------- #### Set the SAGE app status #### prints Invalid app ID if does not exists def setSageAppInfo(self, data): listTokens = string.split(data) listApps = self.hashApps.keys() # to support old sage as well displayId = 0 orientation = 0 appId = 0 launcherId = "none" if len(listTokens) > 8: orientation = int(listTokens[8]) displayId = int(listTokens[9]) if len(listTokens) > 11: appId = int(listTokens[10]) launcherId = listTokens[11] # now update the app properties... or create a new one windowId = int( listTokens[ 1 ] ) if windowId in self.hashAppStatusInfo: # app exists self.hashAppStatusInfo[ windowId ].setAll( listTokens[0], int(listTokens[1]), int(listTokens[2]), int(listTokens[3]), int(listTokens[4]), int(listTokens[5]), int(listTokens[6]), int(listTokens[7]), orientation, displayId, appId, launcherId) else: # when new app is started it is assigned a z=0 but since previous app on top had z=0, # we set this one even higher temporarily (z=-1) so that it gets drawn on top # the new z order message comes right after the app is started so this -1 is temporary zValue = int(listTokens[7]) for app in self.hashAppStatusInfo.itervalues(): if app.getZvalue() == zValue: zValue = -1 self.hashAppStatusInfo[ windowId ] = SageApp( listTokens[0], int(listTokens[1]), int(listTokens[2]), int(listTokens[3]), int(listTokens[4]), int(listTokens[5]), int(listTokens[6]), zValue, orientation, displayId, appId, launcherId) # (AKS 2004-10-23) Provide the app-id to the callback if ( 40001 in self.hashCallback ): self.hashCallback[ 40001 ]( self.hashAppStatusInfo[windowId] ) if self.autosave: if self.__firstAutosave: self.__deleteOldAutosaves() self.__firstAutosave = False self.saveState("_autosave_LATEST", "") return #---------------------------------------------------------------------- ##### ShutDown the sage application ##### prints invalid app ID if doesn't exist def sageAppShutDown(self, data): listTokens = string.split(data) windowId = int(listTokens[0]) listApps = self.hashApps.keys() # do this first and then remove the app from the hash!! if ( 40003 in self.hashCallback ): self.hashCallback[ 40003 ]( self.hashAppStatusInfo[windowId] ) if windowId in self.hashAppStatusInfo : del self.hashAppStatusInfo[windowId] if windowId in self.hashAppPerfInfo : del self.hashAppPerfInfo[windowId] if windowId in self.hashFileInfo : fileObject = self.hashFileInfo.get(windowId) fileObject.close() del self.hashFileInfo[windowId] #---------------------------------------------------------------------- def getLogFileHash(self): return self.hashFileInfo #---------------------------------------------------------------------- #### Set the SAGE app performance status #### prints Invalid app ID if does not exists def setSagePerfInfo(self, data): #print ">>> SET SAGE PERF INFO <<<" listTokens = string.split(data, '\n', 1) windowId = int(listTokens[0]) data = listTokens[1] if not windowId in self.hashAppPerfInfo: self.hashAppPerfInfo[windowId] = sageAppPerfInfo() appPerfInfo = self.hashAppPerfInfo.get(windowId) if (appPerfInfo): lineTokens = string.split(data, '\n') displayItemTokens = string.split(lineTokens[0]) appPerfInfo.setDisplayPerfInfo(float(displayItemTokens[1]), float(displayItemTokens[2]),\ float(displayItemTokens[3]), int(displayItemTokens[4])) renderItemTokens = string.split(lineTokens[1]) # FIX: this is just a hack for now.. there actually is no data coming in for the last # two entries in the array but we fill it with 0s so that we dont have to change everything # (it might be used later as well) # in Graph.py we jsut decide not to print the last two values #renderItemTokens.append(0.0) #print "renderItemTokens = ", renderItemTokens renderItemTokens.append(0) appPerfInfo.setRenderPerfInfo(float(renderItemTokens[1]), float(renderItemTokens[2]),\ float(renderItemTokens[3]), int(renderItemTokens[4])) # Now open a file and log the data on it try: #in case the file and directory permissions are not right if not windowId in self.hashFileInfo: sageApp = self.hashAppStatusInfo[ windowId ] stAppName = sageApp.getName() stDateTime = time.strftime("%Y%m%d-%H%M%S", time.localtime()) stFilename = stAppName + '-' + str(windowId) + '-' + stDateTime stPath = opj(DATA_DIR, stFilename + ".txt") stFilename = os.path.normpath( stPath ) fileObject = open(stFilename, "w") fileObject.write( stAppName + ":" + str(windowId) + " >> " + time.asctime() + "\n" ) fileObject.write( '-' * 120 + "\n\n" ) tempString = (' Disp BW Disp FR Packet Loss Num Receivers Rend BW Rend FR Packet Loss Num Receivers\n') fileObject.write(tempString) fileObject.write( '-' * len(tempString) + "\n" ) self.hashFileInfo[windowId] = fileObject fileObject.flush() # end of initialization if ( self.__bPerformanceLogging == True ): fileObject = self.hashFileInfo.get(windowId) tempString = "%8.3f %7.3f %3.2f %8d " % (float(displayItemTokens[1]), float(displayItemTokens[2]), float(displayItemTokens[3]), int(displayItemTokens[4])) fileObject.write(tempString) tempString = "%8.3f %7.3f %3.2f %8d\n" % (float(renderItemTokens[1]), float(renderItemTokens[2]), float(renderItemTokens[3]), int(renderItemTokens[4])) fileObject.write(tempString) fileObject.flush() # >>> end file writing...else, nothing except: pass #do nothing if something fails (such as permissions) # calculate totals self.__hashAppPerfTotals[ self.I_RENDER_TOTAL_BANDWIDTH ] = 0.0 self.__hashAppPerfTotals[ self.I_RENDER_AVG_FRAME_RATE ] = 0.0 self.__hashAppPerfTotals[ self.I_RENDER_TOTAL_NODES ] = 0 self.__hashAppPerfTotals[ self.I_DISPLAY_TOTAL_BANDWIDTH ] = 0.0 self.__hashAppPerfTotals[ self.I_DISPLAY_AVG_FRAME_RATE ] = 0.0 self.__hashAppPerfTotals[ self.I_DISPLAY_TOTAL_NODES ] = 0 fSumRenderFrameRate = 0.0 fSumDisplayFrameRate = 0.0 #print "zeroing..." # (AKS 2005-04-05) This comment is de # For each application, I am taking each of its metrics and adding them to the # totals which are stored in the hash. The hash is just a dictionary of totals # for metrics for *ALL* application instances. for iKey in self.hashAppPerfInfo: #print "hash perf: ", self.hashAppPerfInfo sapiAppStats = self.hashAppPerfInfo[ iKey ] self.__hashAppPerfTotals[ self.I_RENDER_TOTAL_BANDWIDTH ] = self.__hashAppPerfTotals[ self.I_RENDER_TOTAL_BANDWIDTH ] + sapiAppStats.getRenderInformation( 'bandWidth', 1 )[0] fSumRenderFrameRate = fSumRenderFrameRate + sapiAppStats.getRenderInformation( 'frameRate', 1 )[0] self.__hashAppPerfTotals[ self.I_RENDER_TOTAL_NODES ] = self.__hashAppPerfTotals[ self.I_RENDER_TOTAL_NODES ] + sapiAppStats.getRenderInformation( 'nodes', 1 )[0] self.__hashAppPerfTotals[ self.I_DISPLAY_TOTAL_BANDWIDTH ] = self.__hashAppPerfTotals[ self.I_DISPLAY_TOTAL_BANDWIDTH ] + sapiAppStats.getDisplayInformation( 'bandWidth', 1 )[0] fSumDisplayFrameRate = fSumRenderFrameRate + sapiAppStats.getDisplayInformation( 'frameRate', 1 )[0] self.__hashAppPerfTotals[ self.I_DISPLAY_TOTAL_NODES ] = self.__hashAppPerfTotals[ self.I_DISPLAY_TOTAL_NODES ] + sapiAppStats.getDisplayInformation( 'nodes', 1 )[0] # Make sure to clear update flag since data has been processed #self.__hashAppGraphUpdateFlag[ iKey ] = False # end of loop iAppCount = len( self.hashAppStatusInfo ) # Calculate averages for frame rates if ( iAppCount == 0 ): self.__hashAppPerfTotals[ self.I_RENDER_AVG_FRAME_RATE ] = 0.0 self.__hashAppPerfTotals[ self.I_DISPLAY_AVG_FRAME_RATE ] = 0.0 else: self.__hashAppPerfTotals[ self.I_DISPLAY_AVG_FRAME_RATE ] = fSumDisplayFrameRate / iAppCount self.__hashAppPerfTotals[ self.I_RENDER_AVG_FRAME_RATE ] = fSumRenderFrameRate / iAppCount # (AKS 2005-01-24) Performance data information is not posted at this time #tempString = "%8.3f \t %4d \t %7.3f \n" % (float(dataItemTokens[1]), int(dataItemTokens[2]), float(dataItemTokens[3])) #fileObject.write(tempString) # (AKS 2005-05-07) Now that the total bandwidth metrics have been calculated, # update their respective PerformanceGraphs self.__sapiPerfTotals.setDisplayPerfInfo( float( self.__hashAppPerfTotals[ self.I_DISPLAY_TOTAL_BANDWIDTH ] ), 0.0, 0.0, 0 ) self.__sapiPerfTotals.setRenderPerfInfo( float( self.__hashAppPerfTotals[ self.I_RENDER_TOTAL_BANDWIDTH ] ), 0.0, 0.0, 0 ) self.__pgTotalRenderBandwidth.update( self.__sapiPerfTotals.getRenderInformation( 'bandWidth', 30 ) ) self.__pgTotalDisplayBandwidth.update( self.__sapiPerfTotals.getDisplayInformation( 'bandWidth', 30 ) ) self.__lastTotalsUpdate = time.time() # (AKS 2004-10-23): Changed to send ID back if ( 40002 in self.hashCallback ): self.hashCallback[ 40002 ]( windowId ) #---------------------------------------------------------------------- # saves the performance data totals into a file from this SAGE site only def saveSiteTotals(self, siteName): totalsID = -10 # save the totals as appId = -10 try: if not totalsID in self.hashFileInfo and self.__bPerformanceLogging: stDateTime = time.strftime("%Y%m%d-%H%M%S", time.localtime()) stFilename = "SITE_TOTAL-" + siteName + '-' + stDateTime #stPath = "./data/" + stFilename + ".txt" stPath = opj(DATA_DIR, stFilename + ".txt") stFilename = os.path.normpath( stPath ) fileObject = open(stFilename, "w") fileObject.write( siteName + "\n" + time.asctime() + "\n" ) fileObject.write( '-' * 65 + "\n" ) tempString = (' Timestamp(s) Disp BW(Gbps) Rend BW(Gbps)\n') fileObject.write(tempString) fileObject.write( '-' * len(tempString) + "\n" ) self.hashFileInfo[totalsID] = fileObject fileObject.flush() # end of initialization if ( self.__bPerformanceLogging ): fileObject = self.hashFileInfo[totalsID] tempString = "%12d %12.4f %12.4f\n" % (getTimeStamp(), self.getDisplayBWTotal(), self.getRenderBWTotal()) fileObject.write(tempString) fileObject.flush() except: print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) #---------------------------------------------------------------------- def getRenderBWTotal(self): # zero out the totals if it hasn't been update in a while if time.time() - self.__lastTotalsUpdate > 2.0: self.__hashAppPerfTotals[self.I_RENDER_TOTAL_BANDWIDTH] = 0.0 return float(self.__hashAppPerfTotals[self.I_RENDER_TOTAL_BANDWIDTH])/1000.0 def getDisplayBWTotal(self): # zero out the totals if it hasn't been update in a while if time.time() - self.__lastTotalsUpdate > 2.0: self.__hashAppPerfTotals[self.I_DISPLAY_TOTAL_BANDWIDTH] = 0.0 return float(self.__hashAppPerfTotals[self.I_DISPLAY_TOTAL_BANDWIDTH])/1000.0 #---------------------------------------------------------------------- # Get the z value of the app # @arg windowId App instance ID of the app # @return Returns Z value if windowId exists else returns -1 def getZvalue(self, windowId): if windowId in self.hashAppStatusInfo: return self.hashAppStatusInfo[windowId].getZvalue() else: print("getZvalue: Invalid app instance ID") return #---------------------------------------------------------------------- # Set the Z value of the app # @arg windowId App instance ID of the app # @arg value New Z value to be set def setZvalue(self, windowId, value): if (windowId in self.hashAppStatusInfo): self.hashAppStatusInfo[windowId].setZvalue(value) else: print ('setZvalue: Invalid app instance ID: %d'% (windowId)) return #---------------------------------------------------------------------- ### Get the sage app Info ### @arg windowId Instance id of the application ### @returns A list of format [<left>, <right>, <top>, <bottom>] def getAppInfo(self, windowId): if windowId in self.hashAppStatusInfo: return self.hashAppStatusInfo[windowId].getBounds() else: print("getAppInfo: Invalid app instance ID") return [] #---------------------------------------------------------------------- # returns the SageApp associated with the given windowId def getApp(self, windowId): return self.hashAppStatusInfo[windowId] #---------------------------------------------------------------------- ### Get the sage app display information ### @arg windowId Instance id of the application ### @arg interval Total no of values required (max = 30) ### @returns A array def getDisplayItem(self, stItemName, windowId, interval): if windowId in self.hashAppPerfInfo: appInfo = self.hashAppPerfInfo.get(windowId) return appInfo.getDisplayInformation( stItemName, interval ) else: print("getDisplayItem: Invalid app instance ID") ### Get the sage app render information ### @arg windowId Instance id of the application ### @arg interval Total no of values required (max = 30) ### @returns A array def getRenderItem(self, stItemName, windowId, interval): if windowId in self.hashAppPerfInfo: appInfo = self.hashAppPerfInfo.get(windowId) return appInfo.getRenderInformation( stItemName, interval ) else: print("Invalid app instance ID") #---------------------------------------------------------------------- ### Get the sage app data service bandwidth ### @arg windowId Instance id of the application ### @arg interval Total no of values required (max = 30) ### @returns A array def getDataBandWidth(self, windowId, interval): if windowId in self.hashAppPerfInfo: appInfo = self.hashAppPerfInfo.get(windowId) return appInfo.getDataBandWidth(interval) else: print("Invalid app instance ID") #---------------------------------------------------------------------- ### So that SageData knows what to call when a message arrives def registerCallbackFunction( self, iSageID, function ): self.hashCallback[ iSageID ] = function #---------------------------------------------------------------------- ### (RJ 2005-01-15) ### Returns a list of all the available apps def getAvailableApps( self ): return self.hashApps #---------------------------------------------------------------------- ### sage background color def setSAGEColor(self, (r,g,b)): self._sageColor = (r,g,b)
class SageData: #### constructor initializes member values def __init__(self): self.hashApps = {} # all the apps available for running?? self.hashAppStatusInfo = {} # apps currently running self.displayInfo = SageDisplayInfo() self.sageGate = getSageGate() self.sageGate.registerCallbackFunction(40000, self.setSageStatus) self.sageGate.registerCallbackFunction(40001, self.setSageAppInfo) # self.sageGate.registerCallbackFunction(40002, self.setSagePerfInfo) self.sageGate.registerCallbackFunction(40003, self.sageAppShutDown) self.sageGate.registerCallbackFunction(40004, self.setDisplayInfo) self.sageGate.registerCallbackFunction(40005, self.setSageZValue) self.sageGate.registerCallbackFunction(40006, self.setSageAppExecConfig) self.sageGate.registerCallbackFunction(40007, self.setDisplayConnections) self.sageGate.registerCallbackFunction(40018, self.setSageObjectInfo) ### clears the current state (to be done when reconnecting) def clear(self): self.hashApps = {} # all the apps available for running?? self.hashAppStatusInfo = {} #### Set the sage status def setSageStatus(self, appHash): for appName, configs in appHash.iteritems(): self.hashApps[appName] = SageAppInitial(appName, configs) # ---------------------------------------------------------------------- ### Set the possible execution configurations for each app def setSageAppExecConfig(self, data): tokens = string.split(data, "\n", 1) appName = tokens[0] data = tokens[1] # the rest configList = string.split(data, "config ") del configList[0] # remove the first item in the list for config in configList: if appName in self.hashApps.keys(): (name, stringConfig) = string.split(config, ":", 1) self.hashApps[appName].AddConfig(name, stringConfig) # ---------------------------------------------------------------------- #### Set the SAGE display information #### def setDisplayInfo(self, data): listTokens = string.split(data, "\n") for i in range(0, len(listTokens), 3): tileNumTokens = string.split(listTokens[i], " ") desktopTokens = string.split(listTokens[i + 1], " ") tileConfTokens = string.split(listTokens[i + 2], " ") # so that we can support the old sage as well displayId = 0 if len(tileConfTokens) > 2: displayId = int(tileConfTokens[2]) self.displayInfo.addDisplay( int(tileNumTokens[0]), int(tileNumTokens[1]), int(tileNumTokens[2]), int(desktopTokens[0]), int(desktopTokens[1]), int(tileConfTokens[0]), int(tileConfTokens[1]), displayId, ) # for one display and old SAGE there are no connection messages so just # pretend that one came in for drawing everything correctly if self.displayInfo.getNumDisplays() == 1: self.setDisplayConnections("") # ---------------------------------------------------------------------- # returns the SageDisplayInfo object def getDisplayInfo(self, displayId=0): return self.displayInfo.getDisplay(displayId) # ---------------------------------------------------------------------- def setDisplayConnections(self, data): if data: for connection in data.split("\n"): tokens = connection.split() displayId = int(tokens[2]) self.displayInfo.getDisplay(displayId).placement = int(tokens[1]) evt = events.DisplayInfoEvent(self.displayInfo) getEvtMgr().postEvent(evt) # ---------------------------------------------------------------------- #### Get the new list of z values from SAGE #### and update local hashes, then call the function to update the UI visually def setSageZValue(self, message): tokens = string.split(message) numZChanges = int(tokens[0]) # the first item that comes in is the number of z changes zHash = {} # key=appId, value=new z value # loop through all the tokens and update the z values of the apps for i in range(numZChanges): self.setZvalue(int(tokens[i * 2 + 1]), int(tokens[i * 2 + 2])) zHash[int(tokens[i * 2 + 1])] = int(tokens[i * 2 + 2]) evt = events.ZChangeEvent(zHash) getEvtMgr().postEvent(evt) # ---------------------------------------------------------------------- #### Set the SAGE app status #### prints Invalid app ID if does not exists def setSageAppInfo(self, data): listTokens = string.split(data) # to support old sage as well displayId = 0 orientation = 0 if len(listTokens) > 8: orientation = int(listTokens[8]) displayId = int(listTokens[9]) appId = int(listTokens[1]) if appId in self.hashAppStatusInfo: # update the app in the hash self.hashAppStatusInfo[appId].setAll( listTokens[0], int(listTokens[1]), int(listTokens[2]), int(listTokens[3]), int(listTokens[4]), int(listTokens[5]), int(listTokens[6]), int(listTokens[7]), orientation, displayId, ) # make the event evt = events.AppInfoEvent(self.hashAppStatusInfo[appId]) else: # when new app is started it is assigned a z=0 but since previous app on top had z=0, # we set this one even higher temporarily (z=-1) so that it gets drawn on top # the new z order message comes right after the app is started so this -1 is temporary zValue = int(listTokens[7]) for app in self.hashAppStatusInfo.itervalues(): if app.getZvalue() == zValue: zValue = -1 self.hashAppStatusInfo[appId] = SageApp( listTokens[0], int(listTokens[1]), int(listTokens[2]), int(listTokens[3]), int(listTokens[4]), int(listTokens[5]), int(listTokens[6]), zValue, orientation, displayId, ) # make the event evt = events.NewAppEvent(self.hashAppStatusInfo[appId]) # post the event about the state change getEvtMgr().postEvent(evt) # ---------------------------------------------------------------------- ##### ShutDown the sage application ##### prints invalid app ID if doesn't exist def sageAppShutDown(self, data): listTokens = string.split(data) appId = int(listTokens[0]) if appId in self.hashAppStatusInfo: # do this first and then remove the app from the hash!! # make and post the event evt = events.AppKilledEvent(self.hashAppStatusInfo[appId]) getEvtMgr().postEvent(evt) # delete the app del self.hashAppStatusInfo[appId] # ---------------------------------------------------------------------- def setSageObjectInfo(self, data): evt = events.ObjectInfoEvent(data) getEvtMgr().postEvent(evt) # ---------------------------------------------------------------------- # Get the z value of the app # @arg appInstID App instance ID of the app # @return Returns Z value if appID exists else returns -1 def getZvalue(self, appId): if appId in self.hashAppStatusInfo: return self.hashAppStatusInfo[appId].getZvalue() else: print("getZvalue: Invalid app instance ID") return # ---------------------------------------------------------------------- # Set the Z value of the app # @arg appInstId App instance ID of the app # @arg value New Z value to be set def setZvalue(self, appId, value): if appId in self.hashAppStatusInfo: self.hashAppStatusInfo[appId].setZvalue(value) else: print("setZvalue: Invalid app instance ID") return # ---------------------------------------------------------------------- # returns the SageApp associated with the given appInstId def getApp(self, appInstId): return self.hashAppStatusInfo[appInstId] # ---------------------------------------------------------------------- ### (RJ 2005-01-15) ### Returns a list of all the available apps def getAvailableApps(self): return self.hashApps ### (AKS 2004-10-23) ### Get all app IDs ### currently running on sage ### @return list of app ids def getAllAppIDs(self): return self.hashAppStatusInfo.keys() # ---------------------------------------------------------------------- ### Returns a hash of all running apps def getRunningApps(self): return self.hashAppStatusInfo # ---------------------------------------------------------------------- # checks all the apps and reports whether any one of them was # hit with a click and which region was hit (corners or shape in general) # if more than one shape was hit it returns the one on the top def checkHits(self, x, y): zHash = {} # key=z value, value=SageApp try: for appId, sageApp in self.hashAppStatusInfo.items(): zHash[sageApp.getZvalue()] = sageApp zKeys = zHash.keys() zKeys.sort() for z in zKeys: hitResult = zHash[z].hitTest(x, y) if hitResult >= 0: return (zHash[z], hitResult) except: pass return (None, -1) # ---------------------------------------------------------------------- # returns (appId, zValue) or (-1,sys.maxint) if no apps def getTopApp(self): minZ = (-1, sys.maxint) try: for appId, app in self.hashAppStatusInfo.items(): if app.getZvalue() < minZ[1]: minZ = (appId, app.getZvalue()) except: pass return minZ
class SageData2: #### constructor initializes member values def __init__(self, sg) : self.hashApps = {} # all the apps available for running self.hashAppStatusInfo = {} # apps currently running self.displayInfo = SageDisplayInfo() # minimize bounds... loaded from a state and to be applied to the sageApp when created # key = appName+str(pos+size), value = minimizeBounds self.__minBoundsByApp = {} self.sageGate = sg self.sageGate.registerCallbackFunction(40000, self.setSageStatus) self.sageGate.registerCallbackFunction(40001, self.setSageAppInfo) self.sageGate.registerCallbackFunction(40003, self.sageAppShutDown) self.sageGate.registerCallbackFunction(40004, self.setDisplayInfo) self.sageGate.registerCallbackFunction(40005, self.setSageZValue) self.sageGate.registerCallbackFunction(40006, self.setSageAppExecConfig) self.sageGate.registerCallbackFunction(40007, self.setDisplayConnections) ### clears the current state (to be done when reconnecting) def clear(self): self.hashApps = {} # all the apps available for running?? self.hashAppStatusInfo = {} #### Set the sage status def setSageStatus(self, appHash) : print("SageData2> setSageStatus") for appName, configs in appHash.iteritems(): self.hashApps[appName] = SageAppInitial(appName, configs) #---------------------------------------------------------------------- ### Set the possible execution configurations for each app def setSageAppExecConfig(self, data): tokens = string.split( data, '\n', 1 ) appName = tokens[0] data = tokens[1] #the rest configList = string.split( data, "config ") del configList[0] #remove the first item in the list for config in configList: if appName in self.hashApps.keys(): (name, stringConfig) = string.split(config, ":", 1) self.hashApps[appName].AddConfig(name, stringConfig) #---------------------------------------------------------------------- #### Set the SAGE display information #### def setDisplayInfo(self, data): print("SageData2> setDisplayInfo", data) listTokens = string.split(data, '\n') for i in range(0, len(listTokens), 3): tileNumTokens = string.split(listTokens[i], ' ') desktopTokens = string.split(listTokens[i+1], ' ') tileConfTokens = string.split(listTokens[i+2], ' ') # so that we can support the old sage as well displayId = 0 if len(tileConfTokens) > 2: displayId = int(tileConfTokens[2]) self.displayInfo.addDisplay(int(tileNumTokens[0]), int(tileNumTokens[1]), int(tileNumTokens[2]), int(desktopTokens[0]), int(desktopTokens[1]), int(tileConfTokens[0]), int(tileConfTokens[1]), displayId) # for one display and old SAGE there are no connection messages so just # pretend that one came in for drawing everything correctly if self.displayInfo.getNumDisplays() == 1: self.setDisplayConnections("") #---------------------------------------------------------------------- # returns the SageDisplayInfo object def getDisplayInfo(self, displayId=0): return self.displayInfo.getDisplay(displayId) #---------------------------------------------------------------------- def setDisplayConnections(self, data): print("SageData2> setDisplayConnections") if data: for connection in data.split('\n'): tokens = connection.split() displayId = int(tokens[2]) self.displayInfo.getDisplay(displayId).placement = int(tokens[1]) # evt = events.DisplayInfoEvent(self.displayInfo) # getEvtMgr().postEvent(evt) #---------------------------------------------------------------------- #### Get the new list of z values from SAGE #### and update local hashes, then call the function to update the UI visually def setSageZValue(self, message): print("SageData2> setSageZValue") writeLog(LOG_WINDOW_Z_CHANGE, message) tokens = string.split(message) numZChanges = int(tokens[0]) #the first item that comes in is the number of z changes zHash = {} # key=windowId, value=new z value # loop through all the tokens and update the z values of the apps for i in range(numZChanges): self.setZvalue( int(tokens[i*2+1]), int(tokens[i*2+2]) ) zHash[int(tokens[i*2+1])] = int(tokens[i*2+2]) # evt = events.ZChangeEvent(zHash) # getEvtMgr().postEvent(evt) #---------------------------------------------------------------------- #### Set the SAGE app status #### prints Invalid app ID if does not exists def setSageAppInfo(self, data): print("SageData2> setSageAppInfo") listTokens = string.split(data) # to support old sage as well displayId = 0 orientation = 0 appId = 0 launcherId = "none" resX = -1 resY = -1 myMsg = False appName = listTokens[0] windowId = int( listTokens[ 1 ] ) left = int( listTokens[ 2 ] ) right = int( listTokens[ 3 ] ) bottom = int( listTokens[ 4 ] ) top = int( listTokens[ 5 ] ) sailId = int( listTokens[ 6 ] ) zValue = int( listTokens[ 7 ] ) if len(listTokens) > 8: orientation = int(listTokens[8]) displayId = int(listTokens[9]) if len(listTokens) > 11: appId = int(listTokens[10]) launcherId = listTokens[11] if len(listTokens) > 13: resX = int(listTokens[12]) resY = int(listTokens[13]) if len(listTokens) > 14: myMsg = bool(int(listTokens[14])) newApp = None # ------ EXISTING APP --------# if windowId in self.hashAppStatusInfo: writeLog(LOG_WINDOW_CHANGE, data) # update the app in the hash self.hashAppStatusInfo[ windowId ].setAll( appName, windowId, left, right, bottom, top, sailId, zValue, orientation, displayId, appId, launcherId) # make the event evt = events.AppInfoEvent(self.hashAppStatusInfo[windowId], myMsg) # ------ NEW APP -------# else: extra = "" if appName.lower().startswith("vnc"): if launcherId != "none": appLauncher = xmlrpclib.ServerProxy("http://" + launcherId) try: res = appLauncher.getAppConfigInfo( appId ) if res != -1: extra = "ARGS "+res[1] except: extra = "" writeLog(LOG_WINDOW_NEW, data, extra) # when new app is started it is assigned a z=0 but since previous app on top had z=0, # we set this one even higher temporarily (z=-1) so that it gets drawn on top # the new z order message comes right after the app is started so this -1 is temporary for app in self.hashAppStatusInfo.itervalues(): if app.getZvalue() == zValue: zValue = -1 newApp = SageApp( appName, windowId, left, right, bottom, top, sailId, zValue, orientation, displayId, appId, launcherId, resX, resY) self.hashAppStatusInfo[ windowId ] = newApp # make the event evt = events.NewRemoteAppEvent(newApp) # post the event about the state change #getEvtMgr().postEvent(evt) if newApp: # set its minimized bounds... if available and applicable... p = newApp.getPos() s = newApp.getSize() appname = newApp.getName() minBoundsKey = appName+str(p+s) if minBoundsKey in self.__minBoundsByApp: newApp._setMinimizedBounds(self.__minBoundsByApp[minBoundsKey]) del self.__minBoundsByApp[minBoundsKey] print("SageData2> New remote app") #---------------------------------------------------------------------- ##### ShutDown the sage application ##### prints invalid app ID if doesn't exist def sageAppShutDown(self, data): print("SageData2> sageAppShutDown") writeLog(LOG_WINDOW_REMOVE, data) listTokens = string.split(data) windowId = int(listTokens[0]) if windowId in self.hashAppStatusInfo : # do this first and then remove the app from the hash!! # make and post the event evt = events.AppKilledEvent(self.hashAppStatusInfo[windowId]) #getEvtMgr().postEvent(evt) # delete the app del self.hashAppStatusInfo[windowId] #---------------------------------------------------------------------- # Get the z value of the app # @arg appInstID App instance ID of the app # @return Returns Z value if appID exists else returns -1 def getZvalue(self, windowId): print("SageData2> getZvalue") if windowId in self.hashAppStatusInfo: return self.hashAppStatusInfo[windowId].getZvalue() else: print("getZvalue: Invalid app instance ID") return #---------------------------------------------------------------------- # Set the Z value of the app # @arg appInstId App instance ID of the app # @arg value New Z value to be set def setZvalue(self, windowId, value): print("SageData2> setZvalue") if (windowId in self.hashAppStatusInfo): self.hashAppStatusInfo[windowId].setZvalue(value) else: print ('setZvalue: Invalid app instance ID') return #---------------------------------------------------------------------- # returns the SageApp associated with the given appInstId def getApp(self, appInstId): print("SageData2> getApp") if appInstId in self.hashAppStatusInfo: return self.hashAppStatusInfo[appInstId] else: return None #---------------------------------------------------------------------- ### (RJ 2005-01-15) ### Returns a list of all the available apps def getAvailableApps( self ): print("SageData2> getAvailableApps") return self.hashApps ### (AKS 2004-10-23) ### Get all app IDs ### currently running on sage ### @return list of app ids def getAllAppIDs(self) : print("SageData2> getAllAppIDs") return self.hashAppStatusInfo.keys() #---------------------------------------------------------------------- ### Returns a hash of all running apps def getRunningApps( self ): print("SageData2> getRunningApps") return self.hashAppStatusInfo #---------------------------------------------------------------------- # checks all the apps and reports whether any one of them was # hit with a click and which region was hit (corners or shape in general) # if more than one shape was hit it returns the one on the top def checkHits(self, x, y): zHash = {} #key=z value, value=SageApp try: for windowId, sageApp in self.hashAppStatusInfo.items(): zHash[sageApp.getZvalue()] = sageApp zKeys = zHash.keys() zKeys.sort() for z in zKeys: hitResult = zHash[z].hitTest(x,y) if hitResult >= 0: return (zHash[z], hitResult) except: pass return (None, -1) #---------------------------------------------------------------------- # returns (windowId, zValue) or (-1,sys.maxint) if no apps def getTopApp(self): minZ = (-1, sys.maxint) try: for windowId, app in self.hashAppStatusInfo.items(): if app.getZvalue() < minZ[1]: minZ = (windowId, app.getZvalue()) except: pass return minZ
class SageData: #### constructor initializes member values def __init__(self, autosave, sg) : self.hashApps = {} # all the apps available for running self.hashAppStatusInfo = {} # apps currently running self.displayInfo = SageDisplayInfo() # minimize bounds... loaded from a state and to be applied to the sageApp when created # key = appName+str(pos+size), value = minimizeBounds self.__minBoundsByApp = {} self.__firstAutosave = True self.autosave = autosave self.sageGate = sg self.sageGate.registerCallbackFunction(40000, self.setSageStatus) self.sageGate.registerCallbackFunction(40001, self.setSageAppInfo) #self.sageGate.registerCallbackFunction(40002, self.setSagePerfInfo) self.sageGate.registerCallbackFunction(40003, self.sageAppShutDown) self.sageGate.registerCallbackFunction(40004, self.setDisplayInfo) self.sageGate.registerCallbackFunction(40005, self.setSageZValue) self.sageGate.registerCallbackFunction(40006, self.setSageAppExecConfig) self.sageGate.registerCallbackFunction(40007, self.setDisplayConnections) self.sageGate.registerCallbackFunction(40018, self.addOverlay) self.sageGate.registerCallbackFunction(40019, self.removeOverlay) self.sageGate.registerCallbackFunction(40020, self.onChangedOverlay) ### clears the current state (to be done when reconnecting) def clear(self): self.hashApps = {} # all the apps available for running?? self.hashAppStatusInfo = {} #### Set the sage status def setSageStatus(self, appHash) : for appName, configs in appHash.iteritems(): self.hashApps[appName] = SageAppInitial(appName, configs) #---------------------------------------------------------------------- ### Set the possible execution configurations for each app def setSageAppExecConfig(self, data): tokens = string.split( data, '\n', 1 ) appName = tokens[0] data = tokens[1] #the rest configList = string.split( data, "config ") del configList[0] #remove the first item in the list for config in configList: if appName in self.hashApps.keys(): (name, stringConfig) = string.split(config, ":", 1) self.hashApps[appName].AddConfig(name, stringConfig) #---------------------------------------------------------------------- #### Set the SAGE display information #### def setDisplayInfo(self, data): listTokens = string.split(data, '\n') for i in range(0, len(listTokens), 3): tileNumTokens = string.split(listTokens[i], ' ') desktopTokens = string.split(listTokens[i+1], ' ') tileConfTokens = string.split(listTokens[i+2], ' ') # so that we can support the old sage as well displayId = 0 if len(tileConfTokens) > 2: displayId = int(tileConfTokens[2]) self.displayInfo.addDisplay(int(tileNumTokens[0]), int(tileNumTokens[1]), int(tileNumTokens[2]), int(desktopTokens[0]), int(desktopTokens[1]), int(tileConfTokens[0]), int(tileConfTokens[1]), displayId) # for one display and old SAGE there are no connection messages so just # pretend that one came in for drawing everything correctly if self.displayInfo.getNumDisplays() == 1: self.setDisplayConnections("") #---------------------------------------------------------------------- # returns the SageDisplayInfo object def getDisplayInfo(self, displayId=0): return self.displayInfo.getDisplay(displayId) #---------------------------------------------------------------------- def setDisplayConnections(self, data): if data: for connection in data.split('\n'): tokens = connection.split() displayId = int(tokens[2]) self.displayInfo.getDisplay(displayId).placement = int(tokens[1]) evt = events.DisplayInfoEvent(self.displayInfo) getEvtMgr().postEvent(evt) #---------------------------------------------------------------------- #### Get the new list of z values from SAGE #### and update local hashes, then call the function to update the UI visually def setSageZValue(self, message): writeLog(LOG_WINDOW_Z_CHANGE, message) tokens = string.split(message) numZChanges = int(tokens[0]) #the first item that comes in is the number of z changes zHash = {} # key=windowId, value=new z value # loop through all the tokens and update the z values of the apps for i in range(numZChanges): self.setZvalue( int(tokens[i*2+1]), int(tokens[i*2+2]) ) zHash[int(tokens[i*2+1])] = int(tokens[i*2+2]) evt = events.ZChangeEvent(zHash) getEvtMgr().postEvent(evt) #---------------------------------------------------------------------- #### Set the SAGE app status #### prints Invalid app ID if does not exists def setSageAppInfo(self, data): listTokens = string.split(data) # to support old sage as well displayId = 0 orientation = 0 appId = 0 launcherId = "none" resX = -1 resY = -1 myMsg = False appName = listTokens[0] windowId = int( listTokens[ 1 ] ) left = int( listTokens[ 2 ] ) right = int( listTokens[ 3 ] ) bottom = int( listTokens[ 4 ] ) top = int( listTokens[ 5 ] ) sailId = int( listTokens[ 6 ] ) zValue = int( listTokens[ 7 ] ) if len(listTokens) > 8: orientation = int(listTokens[8]) displayId = int(listTokens[9]) if len(listTokens) > 11: appId = int(listTokens[10]) launcherId = listTokens[11] if len(listTokens) > 13: resX = int(listTokens[12]) resY = int(listTokens[13]) if len(listTokens) > 14: myMsg = bool(int(listTokens[14])) newApp = None # ------ EXISTING APP --------# if windowId in self.hashAppStatusInfo: writeLog(LOG_WINDOW_CHANGE, data) # update the app in the hash self.hashAppStatusInfo[ windowId ].setAll( appName, windowId, left, right, bottom, top, sailId, zValue, orientation, displayId, appId, launcherId) # make the event evt = events.AppInfoEvent(self.hashAppStatusInfo[windowId], myMsg) # ------ NEW APP -------# else: extra = "" if appName.lower().startswith("vnc"): if launcherId != "none": appLauncher = xmlrpclib.ServerProxy("http://" + launcherId) try: res = appLauncher.getAppConfigInfo( appId ) if res != -1: extra = "ARGS "+res[1] except: extra = "" writeLog(LOG_WINDOW_NEW, data, extra) # when new app is started it is assigned a z=0 but since previous app on top had z=0, # we set this one even higher temporarily (z=-1) so that it gets drawn on top # the new z order message comes right after the app is started so this -1 is temporary for app in self.hashAppStatusInfo.itervalues(): if app.getZvalue() == zValue: zValue = -1 newApp = SageApp( appName, windowId, left, right, bottom, top, sailId, zValue, orientation, displayId, appId, launcherId, resX, resY) self.hashAppStatusInfo[ windowId ] = newApp # make the event evt = events.NewAppEvent(newApp) # post the event about the state change getEvtMgr().postEvent(evt) if newApp: # set its minimized bounds... if available and applicable... p = newApp.getPos() s = newApp.getSize() appname = newApp.getName() minBoundsKey = appName+str(p+s) if minBoundsKey in self.__minBoundsByApp: newApp._setMinimizedBounds(self.__minBoundsByApp[minBoundsKey]) del self.__minBoundsByApp[minBoundsKey] if self.autosave: if self.__firstAutosave: self.__deleteOldAutosaves() self.__firstAutosave = False self.saveState("_autosave_LATEST", "") #---------------------------------------------------------------------- ##### ShutDown the sage application ##### prints invalid app ID if doesn't exist def sageAppShutDown(self, data): writeLog(LOG_WINDOW_REMOVE, data) listTokens = string.split(data) windowId = int(listTokens[0]) if windowId in self.hashAppStatusInfo : # do this first and then remove the app from the hash!! # make and post the event evt = events.AppKilledEvent(self.hashAppStatusInfo[windowId]) getEvtMgr().postEvent(evt) # delete the app del self.hashAppStatusInfo[windowId] if self.autosave: if self.__firstAutosave: self.__deleteOldAutosaves() self.__firstAutosave = False self.saveState("_autosave_LATEST", "") #---------------------------------------------------------------------- def addOverlay(self, data): evt = events.ObjectInfoEvent(data) getEvtMgr().postEvent(evt) #---------------------------------------------------------------------- def removeOverlay(self, data): evt = events.ObjectRemovedEvent(data) getEvtMgr().postEvent(evt) #---------------------------------------------------------------------- def onChangedOverlay(self, data): evt = events.ObjectChangedEvent(data) getEvtMgr().postEvent(evt) #---------------------------------------------------------------------- # Get the z value of the app # @arg appInstID App instance ID of the app # @return Returns Z value if appID exists else returns -1 def getZvalue(self, windowId): if windowId in self.hashAppStatusInfo: return self.hashAppStatusInfo[windowId].getZvalue() else: print("getZvalue: Invalid app instance ID") return #---------------------------------------------------------------------- # Set the Z value of the app # @arg appInstId App instance ID of the app # @arg value New Z value to be set def setZvalue(self, windowId, value): if (windowId in self.hashAppStatusInfo): self.hashAppStatusInfo[windowId].setZvalue(value) else: print ('setZvalue: Invalid app instance ID') return #---------------------------------------------------------------------- # returns the SageApp associated with the given appInstId def getApp(self, appInstId): if appInstId in self.hashAppStatusInfo: return self.hashAppStatusInfo[appInstId] else: return None #---------------------------------------------------------------------- ### (RJ 2005-01-15) ### Returns a list of all the available apps def getAvailableApps( self ): return self.hashApps ### (AKS 2004-10-23) ### Get all app IDs ### currently running on sage ### @return list of app ids def getAllAppIDs(self) : return self.hashAppStatusInfo.keys() #---------------------------------------------------------------------- ### Returns a hash of all running apps def getRunningApps( self ): return self.hashAppStatusInfo #---------------------------------------------------------------------- # checks all the apps and reports whether any one of them was # hit with a click and which region was hit (corners or shape in general) # if more than one shape was hit it returns the one on the top def checkHits(self, x, y): zHash = {} #key=z value, value=SageApp try: for windowId, sageApp in self.hashAppStatusInfo.items(): zHash[sageApp.getZvalue()] = sageApp zKeys = zHash.keys() zKeys.sort() for z in zKeys: hitResult = zHash[z].hitTest(x,y) if hitResult >= 0: return (zHash[z], hitResult) except: pass return (None, -1) #---------------------------------------------------------------------- # returns (windowId, zValue) or (-1,sys.maxint) if no apps def getTopApp(self): minZ = (-1, sys.maxint) try: for windowId, app in self.hashAppStatusInfo.items(): if app.getZvalue() < minZ[1]: minZ = (windowId, app.getZvalue()) except: pass return minZ #---------------------------------------------------------------------- def saveState(self, stateName, description=""): #appLaunchers = self.sageGate.getLaunchers() appList = [] # sort the apps by z first... appsByZ = {} # key=z, value=SageApp obj for app in self.hashAppStatusInfo.values(): appsByZ[app.getZvalue()] = app keys = appsByZ.keys() keys.sort(reverse=True) # gather all the data that needs to be saved for each app for zValue in keys: app = appsByZ[zValue] # get the config info from the right appLauncher if app.getLauncherId() != "none": appLauncher = xmlrpclib.ServerProxy("http://" + app.getLauncherId()) try: res = appLauncher.getAppConfigInfo( app.getAppId() ) except: print "\nUnable to connect to appLauncher on", app.getLauncherId(), \ "so not saving this app: ", app.getName() continue if res == -1: print " failed to save", app.getLauncherId() continue # skip this app... something went wrong configName, optionalArgs = res # get the other app parameters from sageApp object pos = app.getPos() size = app.getSize() minBounds = app._getMinimizedBounds() # append the tuple of app's data to the list that will be saved appList.append( (app.getLauncherId(), app.getName(), configName, pos, size, optionalArgs, minBounds) ) # now save the sections too sectionState = getLayoutSections().getState() # open the file and write to it try: #in case the file and directory permissions are not right f = open(opj(SAVED_STATES_DIR, stateName+".state"), "w") pickle.Pickler(f, 0).dump( (description, appList, sectionState) ) f.close() except IOError: print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) return False return True def __deleteOldAutosaves(self): # remove old autosave files... try: saves = os.listdir(SAVED_STATES_DIR) if "_autosave_PREV.state" in saves: os.remove(opj(SAVED_STATES_DIR, "_autosave_PREV.state")) if "_autosave_LATEST.state" in saves: shutil.move(opj(SAVED_STATES_DIR, "_autosave_LATEST.state"), opj(SAVED_STATES_DIR, "_autosave_PREV.state")) except: print "ERROR while deleting old states:" print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) def loadState(self, stateName): """ tries to reload the apps from the saved state """ writeLog(LOG_STATE_LOAD) self.sageGate.updateLauncherList() appList = [] description = "" # load the state from a file try: f = open(opj(SAVED_STATES_DIR, stateName+".state"), "r") savedStuff = pickle.Unpickler(f).load() if len(savedStuff) == 2: (description, appList) = savedStuff sectionState = None else: (description, appList, sectionState) = savedStuff print "Loading state: description ", description print "Loading state: appList ", appList print "Loading state: sectionState ", sectionState f.close() except: print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) print "\nUnable to read saved state file: "+stateName+".state" return False # first, load all the sections getLayoutSections().loadState(sectionState) # try re-running all the apps count = 0 for appInfo in appList: if len(appInfo) == 6: launcherId, appName, configName, pos, size, optionalArgs = appInfo elif len(appInfo) == 7: launcherId, appName, configName, pos, size, optionalArgs, minBounds = appInfo self.__minBoundsByApp[appName+str(pos+size)] = minBounds # a hack to save the mininmize bounds and apply them to the appInfo when it comes back from sage self.sageGate.executeRemoteApp(launcherId, appName, configName, pos, size, optionalArgs) time.sleep(2) count+=1 return True def deleteState(self, stateName): """ tries to delete an existing state """ try: filePath = opj(SAVED_STATES_DIR, stateName+".state") os.remove(filePath) except: print "".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])) print "\nUnable to delete the saved state: ", filePath return False return True def getStateList(self): """ returns a hash of key=stateName, value=description """ stateHash = {} appList = [] description = "" # load all the states and read descriptions from them for fileName in os.listdir(SAVED_STATES_DIR): filePath = opj(SAVED_STATES_DIR, fileName) if os.path.isfile(filePath) and os.path.splitext(filePath)[1] == ".state": try: stateName = os.path.splitext( os.path.split(filePath)[1] )[0] f = open(filePath, "rb") # allow loading of older style files that didn't have sections savedStuff = pickle.Unpickler(f).load() if len(savedStuff) == 2: (description, appList) = savedStuff sectionState = None else: (description, appList, sectionState) = savedStuff f.close() stateHash[stateName] = description except: print "\nUnable to read saved state file: "+filePath continue return stateHash