41 from Tkconstants
import *
42 from tkFileDialog
import *
46 sys.path.insert(0,
"/usr/local/lib/python2.7/site-packages")
47 sys.path.insert(0,
"/prj/lib/python2.7/site-packages")
56 "/prj/share/Laelaps/images",
57 "/prj/share/Laelaps/images/icons",
58 "/prj/share/appkit/images",
59 "/prj/share/appkit/images/icons",
60 "/usr/local/share/Laelaps/images",
61 "/usr/local/share/Laelaps/images/icons" 62 "/usr/local/share/appkit/images",
63 "/usr/local/share/appkit/images/icons" 77 'unknown': fgColors[
'normal'],
78 'running': fgColors[
'ok'],
79 'stopped': fgColors[
'error']
83 reDone = re.compile(
r"done", re.IGNORECASE)
84 reFail = re.compile(
r"fail", re.IGNORECASE)
85 reDoneDone = re.compile(
r"done.*done", re.DOTALL | re.IGNORECASE)
86 reFailDone = re.compile(
r"fail.*done", re.DOTALL | re.IGNORECASE)
87 reRunning = re.compile(
r"\s*is\s*running", re.IGNORECASE)
88 reNotRunning = re.compile(
r"\s*is\s*not\s*running", re.IGNORECASE)
111 image_paths=imagePath)
113 Frame.__init__(self, master=master, cnf=cnf, **kw)
114 self.master.title(
"Laelaps Init.d Console")
117 self.m_imageLoader.loadImage(
"icons/LaelapsInitIcon.png")
118 if self.
m_icons[
'app_icon']
is not None:
119 self.master.tk.call(
'wm',
'iconphoto', self.master._w,
125 self.grid(row=0, column=0, padx=5, pady=5)
144 'laelaps_bsproxy',
'laelaps_roscore',
'laelaps_control',
145 'laelaps_xbox',
'laelaps_teleop']
147 'laelaps_bsproxy':
'BotSense Proxy Server',
148 'laelaps_roscore':
'ROS Master, Parameter Server, rosout logging node',
149 'laelaps_control':
'Laelaps Control ROS node',
150 'laelaps_xbox':
'HID Xbox360 daemon / ROS node',
151 'laelaps_teleop':
'Laelaps Teleoperation ROS node'}
152 self.
m_lock = threading.Lock()
154 if kw.has_key(
'debug'):
172 self.update_idletasks()
181 self.
m_icons[
'rn_logo'] = self.m_imageLoader.loadImage(
"RNLogo48.png");
183 w[
'image'] = self.
m_icons[
'rn_logo']
188 w.grid(row=0, column=0, sticky=W)
192 w[
'font'] = (
'Helvetica', 16)
193 w[
'text'] =
'Laelaps Init.d Console' 195 w.grid(row=0, column=1, sticky=E+W)
199 self.
m_icons[
'laelaps_logo'] = \
200 self.m_imageLoader.loadImage(
"icon_laelaps_logo.png");
201 if self.
m_icons[
'laelaps_logo']:
202 w[
'image'] = self.
m_icons[
'laelaps_logo']
205 w[
'text'] =
'laelaps' 208 w.grid(row=0, column=2, sticky=E)
215 wframe[
'borderwidth'] = 2
216 wframe[
'relief'] =
'ridge' 217 wframe.grid(row=1, column=0, padx=1, pady=3, sticky=N+W+E)
224 w[
'state'] =
'disabled' 225 w.grid(row=row, column=0, sticky=N+E+W)
232 w[
'state'] =
'disabled' 233 w.grid(row=row, column=0, sticky=N+E+W)
238 w = self.
createButton(wframe,
"Restart",
"icon_resume.png",
240 w[
'state'] =
'disabled' 241 w.grid(row=row, column=0, sticky=N+E+W)
250 wframe[
'borderwidth'] = 2
251 wframe[
'relief'] =
'ridge' 252 wframe.grid(row=1, column=1, padx=1, pady=3, sticky=N+W+E)
257 for text
in [
'Sel',
'Status',
'Service',
'Description']:
259 w = Label(wframe, text=text, foreground=fgColors[
'focus'])
260 w[
'font'] = (
'Helvetica', 10,
"bold")
261 w.grid(row=row, column=col, padx=3, pady=3, stick=W)
277 service[
'sel'] = IntVar(0)
279 w = Checkbutton(wframe, bg=bg, variable=service[
'sel'],
281 w.grid(row=row, column=col, padx=1, pady=3, sticky=W)
285 service[
'status'] = StringVar()
286 service[
'status'].set(
"unknown")
288 w = Label(wframe, bg=bg, textvariable=service[
'status'])
289 w[
'fg'] = statusText[service[
'status'].get()]
291 w.grid(row=row, column=col, padx=1, pady=3, stick=W)
292 service[
'wstatus'] = w
296 w = Label(wframe, bg=bg, anchor=W, justify=LEFT, text=key)
297 w.grid(row=row, column=col, padx=1, pady=3, stick=W+E)
301 w = Label(wframe, bg=bg, anchor=W, justify=LEFT, text=self.
m_svcDesc[key])
302 w.grid(row=row, column=col, padx=1, pady=3, stick=W+E)
320 wframe[
'borderwidth'] = 2
321 wframe[
'relief'] =
'ridge' 322 wframe.grid(row=1, column=2, padx=1, pady=3, sticky=N+W+E)
327 w = self.
createButton(wframe,
"Refresh",
"icon_refresh.png",
329 w.grid(row=row, column=0, sticky=N+E+W)
333 w = self.
createButton(wframe,
"Save",
"icon_floppy.png",
335 w[
'state'] =
'disabled' 336 w.grid(row=row, column=0, sticky=N+E+W)
343 w.grid(row=row, column=0, sticky=N+E+W)
350 wframe[
'borderwidth'] = 2
351 wframe[
'relief'] =
'ridge' 352 wframe.grid(row=2, column=0, columnspan=3, padx=1, pady=3, sticky=N+E+W+S)
354 w = Scrollbar(wframe)
355 w.grid(row=0, column=1, sticky=N+S)
365 self.m_wStatusBar.grid(row=0, column=0, padx=3, pady=3, sticky=N+E+W+S)
368 self.
m_wStatusBar[
'yscrollcommand'] = self.m_wScrollBar.set
383 key = str.lower(text.replace(
"\n",
"_"))
384 self.
m_icons[key] = self.m_imageLoader.loadImage(imagefile)
398 w[
'command'] = command
414 bttns = [
'start',
'stop',
'restart']
424 self.
m_wBttn[key][
'state'] = state
430 self.
showSbInfo(
"Starting selected services...\n")
433 text =
" Starting {0} service".format(key)
435 self.update_idletasks()
445 self.
showSbInfo(
"Stopping selected services...\n")
448 text =
" Stopping {0} service".format(key)
450 self.update_idletasks()
460 self.
showSbInfo(
"Restarting selected services...\n")
463 text =
" Restarting {0} service".format(key)
465 self.update_idletasks()
475 self.
showSbInfo(
"Refreshing status of all services...\n")
477 text =
" Checking {0} status".format(key)
479 self.update_idletasks()
503 idx0 = self.m_wStatusBar.index(INSERT)
504 self.m_wStatusBar.insert(END, text)
505 idx1 = self.m_wStatusBar.index(INSERT)
506 self.m_wStatusBar.tag_add(
"norm", idx0, idx1)
507 self.m_wStatusBar.tag_config(
"norm", foreground=fgColors[
'normal'])
508 self.m_wStatusBar.see(END)
518 idx0 = self.m_wStatusBar.index(INSERT)
519 self.m_wStatusBar.insert(END, text)
520 idx1 = self.m_wStatusBar.index(INSERT)
521 self.m_wStatusBar.tag_add(
"err", idx0, idx1)
522 self.m_wStatusBar.tag_config(
"err", foreground=fgColors[
'error'])
523 self.m_wStatusBar.see(END)
533 idx0 = self.m_wStatusBar.index(INSERT)
534 self.m_wStatusBar.insert(END, text)
535 idx1 = self.m_wStatusBar.index(INSERT)
536 self.m_wStatusBar.tag_add(
"ok", idx0, idx1)
537 self.m_wStatusBar.tag_config(
"ok", foreground=fgColors[
'ok'])
538 self.m_wStatusBar.see(END)
564 if status ==
'running':
567 elif status ==
'stopped':
581 self.
m_service[service][
'status'].set(status)
582 self.
m_service[service][
'wstatus'][
'fg'] = statusText[status]
584 def autoRefresh(self):
605 hasLock = self.m_lock.acquire()
607 s = subprocess.check_output([
"service", service,
"start"],
608 stderr=subprocess.STDOUT)
609 except subprocess.CalledProcessError, inst:
610 self.m_lock.release()
612 self.m_lock.release()
627 hasLock = self.m_lock.acquire()
629 s = subprocess.check_output([
"service", service,
"stop"],
630 stderr=subprocess.STDOUT)
631 except subprocess.CalledProcessError, inst:
632 self.m_lock.release()
634 self.m_lock.release()
649 hasLock = self.m_lock.acquire()
651 s = subprocess.check_output([
"service", service,
"restart"],
652 stderr=subprocess.STDOUT)
653 except subprocess.CalledProcessError, inst:
654 self.m_lock.release()
656 self.m_lock.release()
657 if reDoneDone.search(s):
659 elif reFailDone.search(s):
673 hasLock = self.m_lock.acquire()
675 s = subprocess.check_output([
"service", service,
"status"],
676 stderr=subprocess.STDOUT)
677 except subprocess.CalledProcessError, inst:
679 self.m_lock.release()
680 if reRunning.search(s):
681 return (
'running', s)
682 elif reNotRunning.search(s):
683 return (
'stopped', s)
685 return (
'unknown', s)
732 print "%s: %s" % (self.
_Argv0, emsg)
734 print "%s: error" % (self.
_Argv0)
735 print "Try '%s --help' for more information." % (self.
_Argv0)
744 Options and arguments: 746 -h, --help : Display this help and exit. 762 self.
_Argv0 = kwargs.get(
'argv0', __file__)
765 kwargs[
'debug'] =
False 769 opts, args = getopt.getopt(argv[1:],
"?h",
771 except getopt.error, msg:
773 for opt, optarg
in opts:
774 if opt
in (
'-h',
'--help',
'-?'):
794 def run(self, argv=None, **kwargs):
809 root.protocol(
'WM_DELETE_WINDOW', root.destroy)
812 self.m_win.mainloop()
820 if __name__ ==
'__main__':
822 sys.exit( app.run() );
def __init__(self, msg)
Constructor.
def printUsageErr(self, emsg)
Print usage error.
def cbSelect(self)
Checkbox change state callback.
def getOptions(self, argv=None, kwargs)
Get command-line options.
def createHeading(self)
Create top gui heading.
def cbRestartServices(self)
Restart selected services callback.
def showSbOk(self, text)
Show ok text on status bar.
def __init__(self)
Constructor.
def refresh(self)
Refresh status of all services.
def clearSelect(self)
Clear all select checkboxes.
def cbStopServices(self)
Stop selected services callback.
def printUsage(self)
Print Command-Line Usage Message.
def createWidgets(self)
Create gui widgets with supporting data and show.
def cbSave(self)
Save new settings callback.
def __init__(self, master=None, cnf={}, kw)
Constructor.
def execRestart(self, service)
Execute 'service <service> restart' subprocess.
def cbRefreshStatus(self)
Refresh services status callback.
def createStatusBar(self)
Create gui multi-line status bar at bottom of gui window.
def destroy(self)
Destroy window callback.
Window class supporting application.
def showSbInfo(self, text)
Show information text on status bar.
def setStatus(self, service, status)
Set service status field.
def showSbResult(self, text, success)
Show operation result on status bar.
def showSbStatus(self, text, status)
Show service status result on status bar.
def showSbError(self, text)
Show error text on status bar.
def createCenterPanel(self)
Create gui center panel.
def createButton(self, parent, text, imagefile, command, fg='black')
Create button.
def cbStartServices(self)
Start selected services callback.
def execStop(self, service)
Execute 'service <service> stop' subprocess.
def createRightButtons(self)
Create gui right hand side buttons.
def execStart(self, service)
Execute 'service <service> start' subprocess.
def initData(self, kw)
Initialize class state data.
def execStatus(self, service)
Execute 'service <service> status' subprocess.
Unit test command-line exception class.
def createLeftButtons(self)
Create gui left hand side buttons.
def run(self, argv=None, kwargs)
Run application.
msg
error message attribute