source: trunk/src/testing/ui/launcherAdmin.py @ 4

Revision 4, 12.0 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1############################################################################
2#
3# SAGE UI - A Graphical User Interface for SAGE
4# Copyright (C) 2005 Electronic Visualization Laboratory,
5# University of Illinois at Chicago
6#
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions are met:
11#
12#  * Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14#  * Redistributions in binary form must reproduce the above
15#    copyright notice, this list of conditions and the following disclaimer
16#    in the documentation and/or other materials provided with the distribution.
17#  * Neither the name of the University of Illinois at Chicago nor
18#    the names of its contributors may be used to endorse or promote
19#    products derived from this software without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32#
33# Direct questions, comments etc about SAGE UI to www.evl.uic.edu/cavern/forum
34#
35# Author: Ratko Jagodic
36#
37############################################################################
38
39
40import wx, xmlrpclib, string, socket
41import traceback as tb
42
43
44
45
46class App:
47    """ describes the app that's currently running and that has been executed by an appLauncher"""
48    def __init__(self, name, windowId, command, machine, launcher):
49        self.name = name
50        self.windowId = windowId
51        self.command = command
52        self.machine = machine
53        self.launcher = launcher  #the appLauncherId that started this app
54
55    def getName(self):
56        return self.name
57
58    def getId(self):
59        return self.windowId
60
61    def getCommand(self):
62        return self.command
63
64    def getRenderMachine(self):
65        return self.machine
66
67    def getLauncher(self):
68        return self.launcher
69
70    def getStringForm(self):
71        info = "APPLICATION NAME: " + self.name
72        info = info + "\n------------------------------------------------"
73        info = info + "\nEXECUTION COMMAND: " + str(self.command)
74        info = info + "\nRENDERING MACHINE:\t"+str(self.machine)
75        return info
76   
77
78class AppLauncher:
79
80    def __init__(self, launcherId, name, ip, port, appList):
81        self.port = port
82        self.appList = appList
83        self.ip = ip
84        self.launcherId = launcherId
85        self.name = name
86        self.connected = False
87
88
89    def connect(self):
90        if not self.connected:
91            socket.setdefaulttimeout(2)  #set the timeout to 3 seconds so that we dont wait forever
92            self.server = xmlrpclib.ServerProxy("http://" + self.ip + ":" + str(self.port))
93            try:
94                self.server.test() #just use this as a way of testing whether the server is running or not
95                self.connected = True
96            except socket.error:
97                return False
98            except:
99                tb.print_exc()
100                return False
101        return True
102
103
104    def stopApp(self, windowId):
105        try:
106            self.connect()  #connect if necessary
107            return self.server.stopApp(windowId)
108        except socket.error:
109            wx.MessageBox("No connection to the appLauncher: "+str(self.launcherId), "Failed")
110            self.connected = False
111        except:
112            wx.MessageBox("There was an error stopping application:\n\n"+
113                          str("".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))),
114                          "Failed")
115           
116    def appStatus(self):
117        try:
118            self.connect()  #connect if necessary
119            return self.server.appStatus()
120        except socket.error:
121            wx.MessageBox("No connection to the appLauncher: "+str(self.launcherId), "Failed")
122            self.connected = False
123        except:
124            wx.MessageBox("There was an error getting application list:\n\n"+
125                          str("".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))),
126                          "Failed")
127        return {}
128
129
130    def killLauncher(self):
131        try:
132            self.connect()  #connect if necessary
133            self.server.killLauncher()
134        except socket.error:
135            wx.MessageBox("No connection to the appLauncher: "+str(self.launcherId), "Failed")
136            self.connected = False
137        except:
138            wx.MessageBox("There was an error killing application launcher:\n\n"+
139                          str("".join(tb.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))),
140                          "Failed")
141
142
143
144    def getId(self):
145        return self.launcherId
146
147    def getIP(self):
148        return self.ip
149
150    def getAppList(self):
151        return self.appList
152
153    def setAppList(self, appList):
154        self.appList = appList
155
156    def getPort(self):
157        return self.port
158
159    def getName(self):
160        return self.name
161
162
163
164
165
166class MainFrame(wx.Frame):
167
168    def __init__(self, serverIP, serverPort=8009):
169        wx.Frame.__init__(self, None, -1, "AppLauncher Admin", pos = (100,100), size=(550,300))
170        self.server = xmlrpclib.ServerProxy("http://"+serverIP+":"+str(serverPort))
171        self.CreateControls()
172        self.launcherHash = {}
173        self.appHash = {}
174        self.updateLauncherList()
175        self.SetBackgroundColour(wx.Colour(51, 102, 102))
176        self.Show(True)
177
178       
179    ### connects to the sage server and retrieves the list of all app launchers running
180    def updateLauncherList(self):
181        self.launcherList.ClearAll()  #clear the ListBox
182        self.launcherHash = {}
183        try:
184            # a hash comes back (key=launcherId, value=appList - that's another hash of appNames and configs)
185            launchers = self.server.GetRegisteredLaunchers()
186        except socket.error:
187            wx.MessageBox("No connection to the sage server.", "No connection")
188        except:
189            tb.print_exc()
190        else:
191            for launcherString, appList in launchers.iteritems():
192                (name, launcherId) = launcherString.split(":",1)
193                (ip, port) = launcherId.split(":",1)
194                newId = wx.NewId()
195                item = wx.ListItem()
196                item.SetText(name)
197                item.SetData(newId)
198                self.launcherHash[newId] = AppLauncher(launcherId, name, ip, port, appList)
199                self.launcherList.InsertItem(item)
200               
201       
202    def CreateControls(self):
203        self.launcherLabel = wx.StaticText(self, -1, "Registered AppLaunchers", style=wx.ALIGN_CENTER)
204        self.appLabel = wx.StaticText(self, -1, "Apps Running On: ", style=wx.ALIGN_CENTER)
205        self.appInfoLabel = wx.StaticText(self, -1, "Details for: ", style=wx.ALIGN_CENTER)
206
207        self.launcherLabel.SetForegroundColour(wx.WHITE)
208        self.appLabel.SetForegroundColour(wx.WHITE)
209        self.appInfoLabel.SetForegroundColour(wx.WHITE)
210
211        self.launcherList = wx.ListCtrl(self, -1, style=wx.LC_LIST | wx.LC_SINGLE_SEL )
212        self.launcherList.SetMinSize((100,100))
213        self.appList = wx.ListCtrl(self, -1, style=wx.LC_LIST | wx.LC_SINGLE_SEL )
214        self.appList.SetMinSize((200,100))
215        self.appInfo = wx.TextCtrl(self, -1, "", style=wx.TE_READONLY | wx.TE_MULTILINE | wx.TE_DONTWRAP)
216        self.appInfo.SetMinSize((300,100))
217       
218        self.killAppBtn = wx.Button(self, -1, "Kill App")
219        self.killLauncherBtn = wx.Button(self, -1, "Kill Launcher")
220        self.refreshBtn = wx.Button(self, -1, "Refresh")
221
222
223        # registering event handlers
224        self.launcherList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnLauncherListSelect)
225        self.appList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnAppListSelect)
226        self.killAppBtn.Bind(wx.EVT_BUTTON, self.OnKillAppBtn)
227        self.killLauncherBtn.Bind(wx.EVT_BUTTON, self.OnKillLauncherBtn)
228        self.refreshBtn.Bind(wx.EVT_BUTTON, self.UpdateLists)
229       
230        # placement of the controls
231        gridSizer = wx.FlexGridSizer(2,3,0,20)
232        gridSizer.Add(self.launcherLabel, 0, wx.ALIGN_CENTER | wx.TOP | wx.LEFT | wx.EXPAND, border=15)
233        gridSizer.Add(self.appLabel, 0, wx.ALIGN_CENTER | wx.TOP, border=15)
234        gridSizer.Add(self.appInfoLabel, 0, wx.ALIGN_CENTER | wx.TOP, border=15)
235
236        gridSizer.Add(self.launcherList, 1, wx.EXPAND | wx.ALL, border=10)
237        gridSizer.Add(self.appList, 1, wx.EXPAND | wx.ALL, border=10)
238        gridSizer.Add(self.appInfo, 1, wx.EXPAND | wx.ALL, border=10)
239
240        gridSizer.Add(self.killLauncherBtn, 0, wx.ALIGN_CENTER | wx.BOTTOM, border=15)
241        gridSizer.Add(self.killAppBtn, 0, wx.ALIGN_CENTER | wx.BOTTOM, border=15)
242        gridSizer.Add(self.refreshBtn, 0, wx.ALIGN_RIGHT | wx.BOTTOM | wx.RIGHT, border=15)
243
244        gridSizer.AddGrowableRow(1)
245        gridSizer.AddGrowableCol(2)
246       
247        self.SetSizer(gridSizer)
248        gridSizer.Fit(self)
249
250       
251    def OnLauncherListSelect(self, event=None):
252        selection = event.GetText()
253        self.appList.ClearAll()
254        self.appLabel.SetLabel("Apps Running On: " + str(selection))
255        self.appInfo.Clear()
256        self.appInfoLabel.SetLabel("Details for: ")
257        appLauncher = self.launcherHash[event.GetData()]
258        for windowId, (appName, command, machine) in appLauncher.appStatus().iteritems():
259            newId = wx.NewId()
260            item = wx.ListItem()
261            item.SetText(appName)
262            item.SetData(newId)
263            self.appHash[newId] = App(appName, int(windowId), command, machine, appLauncher)
264            self.appList.InsertItem(item)
265        self.GetSizer().Layout()
266
267
268    def OnAppListSelect(self, event=None):
269        selection = event.GetText()
270        self.appInfo.Clear()
271        self.appInfoLabel.SetLabel("Details for: " + str(selection))
272        self.appInfo.WriteText(self.appHash[event.GetData()].getStringForm())
273        self.GetSizer().Layout()
274       
275
276    def UpdateLists(self, event=None):
277        self.updateLauncherList()
278        self.appList.ClearAll()
279        self.appLabel.SetLabel("Apps Running On: ")
280        self.appInfo.Clear()
281        self.appInfoLabel.SetLabel("Details for: ")
282        self.GetSizer().Layout()
283
284
285    def OnKillAppBtn(self, event):
286        selection = self.appList.GetFirstSelected()
287        if selection > -1:
288            app = self.appHash[self.appList.GetItemData(selection)]
289            app.getLauncher().stopApp(app.getId())
290            self.UpdateLists()
291
292
293    def OnKillLauncherBtn(self, event):
294        selection = self.launcherList.GetFirstSelected()
295        if selection > -1:
296            msg = "Really stop this application launcher? You may be interfering with someone else's work."
297            dlg = wx.MessageDialog(None, msg, "Confirm kill", style = wx.OK | wx.CANCEL)
298            if dlg.ShowModal() == wx.ID_OK:
299                appLauncher = self.launcherHash[self.launcherList.GetItemData(selection)]
300                appLauncher.killLauncher()
301                self.UpdateLists()
302
303
304
305
306class MyApp(wx.App):
307    def __init__(self):
308        wx.App.__init__(self, redirect=False)
309
310    def OnInit(self):
311        return True
312
313
314
315
316       
317
318def main(argv):
319    name, ext  = os.path.splitext(argv[1])
320
321    if len(argv) == 2:
322        serverIP = "sage.sl.startap.net"
323        serverPort = 8009
324    elif len(argv) == 3:
325        serverIP = argv[2]
326        serverPort = 8009
327    else:
328        print "Usage: python admin.py [SERVER_IP]\n"
329        sys.exit(0)
330
331    app = MyApp()
332    frame = MainFrame(serverIP, serverPort)
333    app.SetTopWindow(frame)
334    app.MainLoop()
335
336
337
338if __name__ == '__main__':
339    import sys, os
340    main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
Note: See TracBrowser for help on using the repository browser.