Guido van Rossum | 4450bab | 1994-10-11 14:57:03 +0000 | [diff] [blame] | 1 | #! /usr/local/bin/python |
| 2 | |
Guido van Rossum | 502d960 | 1995-09-07 19:59:22 +0000 | [diff] [blame] | 3 | # Tkinter interface to SYSV `ps' and `kill' commands. |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 4 | |
| 5 | from Tkinter import * |
Guido van Rossum | 502d960 | 1995-09-07 19:59:22 +0000 | [diff] [blame] | 6 | |
| 7 | if TkVersion < 4.0: |
| 8 | raise ImportError, "This version of svkill requires Tk 4.0 or later" |
| 9 | |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 10 | from string import splitfields |
| 11 | from string import split |
| 12 | import commands |
| 13 | import os |
| 14 | |
| 15 | user = os.environ['LOGNAME'] |
| 16 | |
| 17 | class BarButton(Menubutton): |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 18 | def __init__(self, master=None, cnf={}): |
Guido van Rossum | 502d960 | 1995-09-07 19:59:22 +0000 | [diff] [blame] | 19 | Menubutton.__init__(self, master, cnf) |
| 20 | self.pack(side='left') |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 21 | self.menu = Menu(self, {'name': 'menu'}) |
| 22 | self['menu'] = self.menu |
| 23 | |
| 24 | class Kill(Frame): |
| 25 | # List of (name, option, pid_column) |
| 26 | view_list = [ |
| 27 | ('Default', ''), |
| 28 | ('Every (-e)', '-e'), |
| 29 | ('Non process group leaders (-d)', '-d'), |
| 30 | ('Non leaders with tty (-a)', '-a'), |
| 31 | ('For this user (-u %s)' % user, '-u %s' % user), |
| 32 | ] |
| 33 | format_list = [ |
| 34 | ('Default', '', 0), |
| 35 | ('Long (-l)', '-l', 3), |
| 36 | ('Full (-f)', '-f', 1), |
| 37 | ('Full Long (-f -l)', '-l -f', 3), |
| 38 | ('Session and group ID (-j)', '-j', 0), |
| 39 | ('Scheduler properties (-c)', '-c', 0), |
| 40 | ] |
| 41 | def kill(self, selected): |
| 42 | c = self.format_list[self.format.get()][2] |
| 43 | pid = split(selected)[c] |
| 44 | os.system('kill' + ' -9 ' + pid) |
| 45 | self.do_update() |
| 46 | def do_update(self): |
| 47 | format = self.format_list[self.format.get()][1] |
| 48 | view = self.view_list[self.view.get()][1] |
| 49 | s = commands.getoutput('ps %s %s' % (view, format)) |
| 50 | list = splitfields(s, '\n') |
| 51 | self.header.set(list[0] + ' ') |
| 52 | del list[0] |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 53 | self.frame.list.delete(0, AtEnd()) |
| 54 | for line in list: |
| 55 | self.frame.list.insert(0, line) |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 56 | def do_motion(self, e): |
Guido van Rossum | 502d960 | 1995-09-07 19:59:22 +0000 | [diff] [blame] | 57 | e.widget.select_clear('0', 'end') |
| 58 | e.widget.select_set(e.widget.nearest(e.y)) |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 59 | def do_leave(self, e): |
Guido van Rossum | 502d960 | 1995-09-07 19:59:22 +0000 | [diff] [blame] | 60 | e.widget.select_clear('0', 'end') |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 61 | def do_1(self, e): |
| 62 | self.kill(e.widget.get(e.widget.nearest(e.y))) |
| 63 | def __init__(self, master=None, cnf={}): |
| 64 | Frame.__init__(self, master, cnf) |
| 65 | self.pack({'expand': 'yes', 'fill': 'both'}) |
| 66 | self.bar = Frame( |
| 67 | self, |
| 68 | {'name': 'bar', |
| 69 | 'relief': 'raised', |
| 70 | 'bd': 2, |
| 71 | Pack: {'side': 'top', |
| 72 | 'fill': 'x'}}) |
| 73 | self.bar.file = BarButton(self.bar, {'text': 'File'}) |
| 74 | self.bar.file.menu.add_command( |
| 75 | {'label': 'Quit', 'command': self.quit}) |
| 76 | self.bar.view = BarButton(self.bar, {'text': 'View'}) |
| 77 | self.bar.format = BarButton(self.bar, {'text': 'Format'}) |
| 78 | self.view = IntVar(self) |
| 79 | self.view.set(0) |
| 80 | self.format = IntVar(self) |
| 81 | self.format.set(0) |
| 82 | for num in range(len(self.view_list)): |
| 83 | label, option = self.view_list[num] |
| 84 | self.bar.view.menu.add_radiobutton( |
| 85 | {'label': label, |
| 86 | 'command': self.do_update, |
| 87 | 'variable': self.view, |
| 88 | 'value': num}) |
| 89 | for num in range(len(self.format_list)): |
| 90 | label, option, col = self.format_list[num] |
| 91 | self.bar.format.menu.add_radiobutton( |
| 92 | {'label': label, |
| 93 | 'command': self.do_update, |
| 94 | 'variable': self.format, |
| 95 | 'value': num}) |
| 96 | self.bar.tk_menuBar(self.bar.file, |
| 97 | self.bar.view, |
| 98 | self.bar.format) |
| 99 | self.frame = Frame( |
| 100 | self, |
| 101 | {'relief': 'raised', 'bd': 2, |
| 102 | Pack: {'side': 'top', |
| 103 | 'expand': 'yes', |
| 104 | 'fill': 'both'}}) |
| 105 | self.header = StringVar(self) |
| 106 | self.frame.label = Label( |
| 107 | self.frame, |
| 108 | {'relief': 'flat', |
| 109 | 'anchor': 'nw', |
| 110 | 'borderwidth': 0, |
| 111 | 'font': '*-Courier-Bold-R-Normal-*-120-*', |
| 112 | 'textvariable': self.header, |
| 113 | Pack: {'side': 'top', |
| 114 | 'fill': 'y', |
| 115 | 'anchor': 'w'}}) |
| 116 | self.frame.vscroll = Scrollbar( |
| 117 | self.frame, |
| 118 | {'orient': 'vertical'}) |
| 119 | self.frame.list = Listbox( |
| 120 | self.frame, |
| 121 | {'relief': 'sunken', |
| 122 | 'font': '*-Courier-Medium-R-Normal-*-120-*', |
Guido van Rossum | 502d960 | 1995-09-07 19:59:22 +0000 | [diff] [blame] | 123 | 'width': 40, 'height': 10, |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 124 | 'selectbackground': '#eed5b7', |
| 125 | 'selectborderwidth': 0, |
Guido van Rossum | 502d960 | 1995-09-07 19:59:22 +0000 | [diff] [blame] | 126 | 'selectmode': 'browse', |
Guido van Rossum | 18886ab | 1994-07-08 15:08:55 +0000 | [diff] [blame] | 127 | 'yscroll': self.frame.vscroll.set}) |
| 128 | self.frame.vscroll['command'] = self.frame.list.yview |
| 129 | self.frame.vscroll.pack({'side': 'right', 'fill': 'y'}) |
| 130 | self.frame.list.pack( |
| 131 | {'side': 'top', |
| 132 | 'expand': 'yes', |
| 133 | 'fill': 'both'}) |
| 134 | self.update = Button( |
| 135 | self, |
| 136 | {'text': 'Update', |
| 137 | 'command': self.do_update, |
| 138 | Pack: {'expand': 'no', |
| 139 | 'fill': 'x'}}) |
| 140 | self.frame.list.bind('<Motion>', self.do_motion) |
| 141 | self.frame.list.bind('<Leave>', self.do_leave) |
| 142 | self.frame.list.bind('<1>', self.do_1) |
| 143 | self.do_update() |
| 144 | |
| 145 | if __name__ == '__main__': |
| 146 | kill = Kill(None, {'bd': 5}) |
| 147 | kill.winfo_toplevel().title('Tkinter Process Killer (SYSV)') |
| 148 | kill.winfo_toplevel().minsize(1, 1) |
| 149 | kill.mainloop() |