PK Y2NServerInfo.appUT qUBBUx[application] name = Venue Server Info mimetype = application/x-ag-server-info extension = agserverinfo files = ServerInfo.py [commands] Open = %(python)s ServerInfo.py -a %(appUrl)s -v %(venueUrl)s PK M2$lRlR ServerInfo.pyUT BBUximport os import sys import logging import sys import getopt import glob import pickle from string import split, join, strip from time import localtime, strftime if sys.platform=="darwin": # On osx pyGlobus/globus need to be loaded # before various modules such as socket import pyGlobus.ioc from wxPython.wx import * from AccessGrid.SharedAppClient import SharedAppClient from AccessGrid.Platform.Config import UserConfig from AccessGrid.UIUtilities import AboutDialog, MessageDialog from AccessGrid.ClientProfile import ClientProfile from AccessGrid import icons from AccessGrid.GUID import GUID from AccessGrid.Toolkit import WXGUIApplication ID_OPEN_DATA = wxNewId() ID_EXIT = wxNewId() class ErrorDialog: """ A simpler error message (no bugzilla reporting) """ def __init__(self, frame, text, text2 = "", style = wxOK|wxICON_ERROR): messageDialog = wxMessageDialog(frame, text, text2, style) messageDialog.ShowModal() messageDialog.Destroy() class ServerInfoCommon: def __init__(self, serverinfo, log, title="Server Info", size=wxSize(500, 300)): self.log = log self.serverinfo = serverinfo self.mainSizer = None self.frame = wxFrame(None, -1, title=title, size=size) self.frame.SetIcon(icons.getAGIconIcon()) self.SetTopWindow(self.frame) self.topPanel = wxPanel(self.frame, -1) menu = wxMenu() menu.Append(ID_OPEN_DATA,"&Open...","Open a data file") menu.AppendSeparator() menu.Append(ID_EXIT,"&Exit","Terminate with extreme prejudice") menubar = wxMenuBar() menubar.Append(menu,"&File") self.frame.SetMenuBar(menubar) EVT_MENU(self.frame, ID_OPEN_DATA, self.OnOpenData) EVT_MENU(self.frame, ID_EXIT, self.OnExit) # # This is the info we already have, # so is pertinent to both controller & client # self.myServerList = serverinfo.LoadMyServers() self.myServerList.sort(lambda x, y: cmp(x['metadata']['serverlabel'], y['metadata']['serverlabel'])) for server in self.myServerList: metadata = server['metadata'] serverlabel = metadata['serverlabel'] searchtime = metadata['searchtime'] print "searchtime for %s: %s" % (serverlabel, searchtime) print "======================================================" def dumbFunction(self): print "DUMB FUNCTION" def fillCurrentInfo(self): x = 0 for server in self.myServerList: rooms = server['rooms'] metadata = server['metadata'] #print "%s %s %s" % (x, metadata['serverlabel'], metadata['searchtime']) self.list.InsertStringItem(x, metadata['serverlabel']) self.list.SetStringItem(x, 1, metadata['searchtime']) self.list.SetItemData(x, x) x += 1 self.list.SetColumnWidth(0, wxLIST_AUTOSIZE) self.list.SetColumnWidth(1, 250) def OnInit(self): return 1 def OnExit(self, event=None): self.serverinfo.sharedAppClient.Shutdown() self.topPanel.Close(True) os._exit(1) def OnOpenData(self, event): print "Open data file?" class ServerInfoClientUI(wxApp, ServerInfoCommon): def __init__( self, serverinfo, log = None): wxApp.__init__(self, False) ServerInfoCommon.__init__(self, serverinfo, log, title="Server Info Client") # # This is info available from the server # self.serverInfo = [] self.loadLatestServerInfo() ilcpID = wxNewId() # # Now the list(s) # self.list = wxListCtrl(self.topPanel, wxNewId(), size = wxSize(250, 300), style=wxLC_REPORT) self.newlist = wxListCtrl(self.topPanel, wxNewId(), pos=(250, 0), size=wxSize(250, 300), style=wxLC_REPORT) self.PopulateList() EVT_RIGHT_DOWN(self.newlist, self.OnRightDown) # for wxMSW EVT_COMMAND_RIGHT_CLICK(self.newlist, ilcpID, self.OnRightClick) # for wxGTK EVT_RIGHT_UP(self.newlist, self.OnRightClick) self.frame.Show(1) # # Retrieve data from server # def loadLatestServerInfo(self): latestServerInfo = self.serverinfo.sharedAppClient.GetData("latestServerInfo") if len(latestServerInfo) <= 0: print "latestServerInfo length: ", len(latestServerInfo) return #print "Retrieved latestServerInfo: ", latestServerInfo serverInfoFile = os.path.join(self.serverinfo.userConf.GetConfigDir(), ("serverInfo_%s" % (str(GUID()) )) ) print "CLIENT pickle filename = %s" % serverInfoFile sif = open(serverInfoFile, 'w') sif.write(latestServerInfo) sif.close() sif = open(serverInfoFile, 'r') unpickler = pickle.Unpickler(sif) self.serverInfo = unpickler.load() sif.close() os.remove(serverInfoFile) self.serverInfo.sort(lambda x, y: cmp(x['metadata']['serverlabel'], y['metadata']['serverlabel'])) for server in self.serverInfo: print "%s %s" % (server['metadata']['serverlabel'], server['metadata']['searchtime']) def PopulateList(self): print "Populating the list" self.list.InsertColumn(0, "Name") self.list.InsertColumn(1, "Date") self.fillCurrentInfo() # Now the new info from server self.newlist.InsertColumn(0, "- Name") self.newlist.InsertColumn(1, "- Date") x = 0 for server in self.serverInfo: #print "%s %s" % (server['metadata']['serverlabel'], server['metadata']['searchtime']) rooms = server['rooms'] metadata = server['metadata'] #print "%s %s %s" % (x, metadata['serverlabel'], metadata['searchtime']) self.newlist.InsertStringItem(x, metadata['serverlabel']) self.newlist.SetStringItem(x, 1, metadata['searchtime']) self.newlist.SetItemData(x, x) x += 1 self.newlist.SetColumnWidth(0, wxLIST_AUTOSIZE) self.newlist.SetColumnWidth(1, 250) def OnRightDown(self, event): self.x = event.GetX() self.y = event.GetY() #item, flags = self.list.HitTest((self.x, self.y)) #if flags & wxLIST_HITTEST_ONITEM: # self.list.Select(item) event.Skip() def OnRightClick(self, event): # only do this part the first time so the events are only bound once if not hasattr(self, "popup_Install"): self.popup_Install = wxNewId() self.popup_Refresh = wxNewId() self.popup_Exit = wxNewId() EVT_MENU(self, self.popup_Install, self.OnPopup_Install) EVT_MENU(self, self.popup_Refresh, self.OnPopup_Refresh) EVT_MENU(self, self.popup_Exit, self.OnPopup_Exit) menu = wxMenu() menu.Append(self.popup_Install, "Install venue server info") menu.Append(self.popup_Refresh, "Refresh") menu.AppendSeparator() menu.Append(self.popup_Exit, "Exit ServerInfo") # Popup the menu. If an item is selected then its handler # will be called before PopupMenu returns. self.topPanel.PopupMenu(menu, wxPoint(self.x + 250, self.y)) menu.Destroy() def OnPopup_Install(self, event): print "Popup = Install" configDir = self.serverinfo.userConf.GetConfigDir() #configDir = os.path.join(self.serverinfo.userConf.GetConfigDir(), "tmp") try: for server in self.serverInfo: #print "%s %s" % (server['metadata']['serverlabel'], server['metadata']['searchtime']) rooms = server['rooms'] connections = server['connections'] metadata = server['metadata'] serverInfoFile = os.path.join(configDir, ("%s.agsvr" % metadata['serverlabel'].lower()) ) self.InfoList2agsvr(serverInfoFile, rooms, connections, metadata) except: ErrorDialog(self.topPanel, "Couldn't download server data!") MessageDialog(self.topPanel, 'downloaded data OK') self.RefreshList() def OnPopup_Exit(self, event): self.OnExit() def RefreshList(self): self.list.DeleteAllItems() self.myServerList = serverinfo.LoadMyServers() self.myServerList.sort(lambda x, y: cmp(x['metadata']['serverlabel'], y['metadata']['serverlabel'])) self.fillCurrentInfo() def OnPopup_Refresh(self, event): print "Popup = Refresh" self.RefreshList() def InfoList2agsvr(self, filename, rooms, connections, meta): serverlabel = meta['serverlabel'] searchtime = meta['searchtime'] print "Saving %s at %s as %s" % (serverlabel, searchtime, filename) f = open(filename, 'w') f.write('serverlabel=\"' + serverlabel + '\"\n') f.write('searchtime=\"' + searchtime + '\"\n') f.write('\n') for room in rooms: #print "room: ", rooms[room] f.write('\"' + room + '\" [label=\"' + rooms[room] + '\"];\n') f.write('\n') for conn in connections: #print "connection: ", conn f.write('\"' + conn[0] + '\" -- \"' + conn[1] + '\";\n') f.write('\n') f.write('\n') f.close() class ServerInfoControllerUI(wxApp, ServerInfoCommon): def __init__( self, serverinfo, log = None): wxApp.__init__(self, False) ServerInfoCommon.__init__(self, serverinfo, log, title="Server Info Controller", size=wxSize(250,300)) ilcpID = wxNewId() # # Now the list(s) # self.list = wxListCtrl(self.topPanel, wxNewId(), size = wxSize(250, 300), style=wxLC_REPORT) self.PopulateList() EVT_RIGHT_DOWN(self.list, self.OnRightDown) # for wxMSW EVT_COMMAND_RIGHT_CLICK(self.list, ilcpID, self.OnRightClick) # for wxGTK EVT_RIGHT_UP(self.list, self.OnRightClick) self.frame.Show(1) def PopulateList(self): print "Populating the list" self.list.InsertColumn(0, "Name") self.list.InsertColumn(1, "Date") self.fillCurrentInfo() def OnRightClick(self, event): # only do this part the first time so the events are only bound once if not hasattr(self, "popup_Upload"): self.popup_Upload_selected = wxNewId() self.popup_Upload_all = wxNewId() self.popup_Refresh = wxNewId() self.popup_Exit = wxNewId() EVT_MENU(self, self.popup_Upload_all, self.OnPopup_Upload_all) EVT_MENU(self, self.popup_Upload_selected, self.OnPopup_Upload_selected) EVT_MENU(self, self.popup_Refresh, self.OnPopup_Refresh) EVT_MENU(self, self.popup_Exit, self.OnPopup_Exit) print "Selected %d items" % (self.list.GetSelectedItemCount()) menu = wxMenu() menu.Append(self.popup_Upload_all, "Upload All") menu.Append(self.popup_Upload_selected, "Upload Selected") menu.Append(self.popup_Refresh, "Refresh") menu.AppendSeparator() menu.Append(self.popup_Exit, "Exit VenueInfo") # Popup the menu. If an item is selected then its handler # will be called before PopupMenu returns. self.topPanel.PopupMenu(menu, wxPoint(self.x, self.y)) menu.Destroy() def OnRightDown(self, event): print "OnRightDown, selected items:" index = self.list.GetFirstSelected() self.uploadList = [] while index != -1: #print " %s" % self.list.GetItemText(index) server = self.myServerList[index] self.uploadList.append(server) #print " %s" % server['metadata']['serverlabel'] index = self.list.GetNextSelected(index) self.x = event.GetX() self.y = event.GetY() #item, flags = self.list.HitTest((self.x, self.y)) #if flags & wxLIST_HITTEST_ONITEM: # self.list.Select(item) event.Skip() def OnPopup_Upload_selected(self, event): self.OnPopup_Upload(self.uploadList) def OnPopup_Upload_all(self, event): print "Upload ALL" self.OnPopup_Upload(self.myServerList) def OnPopup_Upload(self, sitelist): for server in sitelist: print " %s" % server['metadata']['serverlabel'] # Later, use a dialogue box to choose filename serverInfoFile = os.path.join(self.serverinfo.userConf.GetConfigDir(), ("serverInfo_%s" % (str(GUID()) )) ) sif = open(serverInfoFile, 'w') try: pickler = pickle.Pickler(sif) pickler.dump(sitelist) except: print "couldn't pickle" return sif.close() try: sif = open(serverInfoFile, 'r') astring = sif.read() sif.close() self.serverinfo.sharedAppClient.SetData("latestServerInfo", astring) self.serverinfo.sharedAppClient.SendEvent("latestServerInfo", (self.serverinfo.publicId, astring)) print "Uploaded, I think ..." except: print "Couldn't upload data" ErrorDialog(self.topPanel, "Couldn't upload the data!") os.remove(serverInfoFile) MessageDialog(self.topPanel, 'Uploaded data OK') def OnPopup_Refresh(self, event): print "Popup = Refresh" def OnPopup_Exit(self, event): self.OnExit() class ServerInfo(wxApp): def __init__( self, appUrl, name, username=None): # Create shared application client self.sharedAppClient = SharedAppClient(name) self.log = self.sharedAppClient.InitLogging() self.log.debug("ServerInfo.__init__:Started ServerInfo appUrl %s" % (appUrl)) self.username = username print "ServerInfo USERNAME: %s" % self.username # Get client profile try: self.userConf = UserConfig.instance() clientProfileFile = os.path.join(self.userConf.GetConfigDir(), "profile") clientProfile = ClientProfile(clientProfileFile) if not self.username == None: clientProfile.name = self.username print "ServerInfo PROFILE_NAME: %s" % clientProfile.name except: self.log.info("SharedAppClient.Connect: Could not load client profile, set clientProfile = None") clientProfile = None # Join the application session. self.sharedAppClient.Join(appUrl, clientProfile) self.publicId = self.sharedAppClient.GetPublicId() self.log.info("SharedAppClient.Connect: Joined session") # Am I the user who created the shared session? appState = self.sharedAppClient.GetApplicationState() self.iamowner = self.nameIsDescribedName(clientProfile.name, appState.description) # Register browse event callback self.sharedAppClient.RegisterEventCallback( "latestServerInfo", self.latestServerInfoCB) def latestServerInfoCB(self, event): (senderId, latestServerInfo) = event.data if senderId == self.sharedAppClient.GetPublicId(): self.log.debug("Ignoring new info from myself") return else: self.log.debug("Loading new info") pickledServerInfo = os.path.join(self.userConf.GetConfigDir(), ("serverInfo_%s" % (str(GUID()) )) ) print "pickle filename = %s" % pickledServerInfo psi = open(pickledServerInfo, 'r+') psi.write(latestServerInfo) unpickler = pickle.Unpickler(psi) serverInfo = unpickler.load(psi) psi.close() for server in serverInfo: print server['metadata']['serverlabel'] def nameIsDescribedName(self, name, desc): """ Determine whether name matches the name component within desc (where desc is the desciption field of a SharedApplication's State). Return True or False """ nameList = desc.split() dname = join(nameList[2:-6]) self.log.debug("name component of app description: %s", dname) return name == dname def __ParseServerFile(self, file): """ From the input file, generate a dictionary mapping URI's to room names and a list of room connection pairs rooms (as URI's). Its a bit clunky because the file format was originally designed for something else (.dot files for vizgraph tools). Maybe we should generate more appropriate data files in the first place! """ rooms = {} connections = [] metadata = {} serverlabel= 'Unnamed Server' searchtime= 'Unknown earchtime' if not os.path.exists(file): return (None, None) serverFile = open(file, 'r') for line in serverFile: if line.startswith("serverlabel="): serverlabel = line[13:-2] metadata['serverlabel'] = serverlabel continue if line.startswith("searchtime="): searchtime = line[12:-2] metadata['searchtime'] = searchtime continue l = split(line) if len(l) < 2: continue if l[1] == '--': # Need to strip quotes, also semicolon at end connections.append([strip(l[0],"\""), strip(strip(l[2],";"),"\"")]) else: # This line contains URI and room name (perhaps with spaces) roomname = join(l[1:])[8:-3] rooms[strip(l[0], "\"")] = roomname serverFile.close() return (rooms, connections, metadata) def LoadMyServers(self): serverFiles = glob.glob( os.path.join(self.userConf.GetConfigDir(), '*.agsvr')) __alist = [] for file in serverFiles: rooms, connections, metadata = self.__ParseServerFile(file) if rooms != None and connections != None: #self.myServerList.append({'rooms':rooms, 'connections':connections, 'metadata':metadata}) __alist.append({'rooms':rooms, 'connections':connections, 'metadata':metadata}) return __alist class ArgumentManager: ''' Take care of command line arguments. ''' def __init__(self): self.arguments = {} self.arguments['applicationUrl'] = None self.arguments['venueUrl'] = None self.arguments['username'] = None self.arguments['debug'] = 0 def GetArguments(self): return self.arguments def Usage(self): """ How to use the program. """ print "%s:" % sys.argv[0] print " -a|--applicationURL : " print " -v|--venueURL : " print " -u|--username : " print " -h|--help : print usage" print " -d|--debug : print debugging output" def ProcessArgs(self): """ Handle any arguments we're interested in. """ try: opts, args = getopt.getopt(sys.argv[1:], "a:l:dhv:", ["applicationURL=", "venueURL=", "username=", "debug", "help"]) except getopt.GetoptError: self.Usage() sys.exit(2) for o, a in opts: if o in ("-a", "--applicationURL"): self.arguments["applicationUrl"] = a elif o in ("-v", "--venueURL"): self.arguments["venuUrl"] = a elif o in ("-u", "--username"): self.arguments["username"] = a elif o in ("-d", "--debug"): self.arguments["debug"] = 1 elif o in ("-h", "--help"): self.Usage() sys.exit(0) if __name__ == "__main__": app = WXGUIApplication() name = "ServerInfo" # Parse command line options am = ArgumentManager() am.ProcessArgs() aDict = am.GetArguments() appUrl = aDict['applicationUrl'] venueUrl = aDict['venueUrl'] username = aDict['username'] debugMode = aDict['debug'] init_args = [] if "--debug" in sys.argv or "-d" in sys.argv: init_args.append("--debug") app.Initialize(name, args=init_args) if not appUrl: am.Usage() else: wxInitAllImageHandlers() # Create ServerInfo instance serverinfo = ServerInfo(appUrl, name, username) # Create ServerInfo's User Interface if hasattr(serverinfo, "iamowner") and serverinfo.iamowner: uiApp = ServerInfoControllerUI(serverinfo, serverinfo.log) else: uiApp = ServerInfoClientUI(serverinfo, serverinfo.log) uiApp.MainLoop() PK Y2N ServerInfo.appUTqUBUxPK M2$lRlR ServerInfo.pyUTBUxPKS