-
Notifications
You must be signed in to change notification settings - Fork 0
/
tool.py
793 lines (674 loc) · 33 KB
/
tool.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
from GUI import Application, Window, ScrollableView, CheckBox, Frame, \
TextField, RadioButton, RadioGroup, Button, Image, Label
from myutils import querytypes, clean_list, print_and_execute, get_conn, config
from Filter import Filter, query_profile, gnuplot, SearchStringList
from MyComponents import TopqueryPanel, TopqueryLabel, GraphView, \
ResponsiveTextField
import os
import sys
from datetime import datetime
from glob import glob
DATEFORMAT = "%m/%d/%Y"
DEFAULT_BEGIN_DATE_TEXT = "Begin (mm/dd/yyyy)"
DEFAULT_END_DATE_TEXT = "End (mm/dd/yyyy)"
DEFAULT_USER_SEARCH_STRING = "User Search String"
DEFAULT_SERVER_SEARCH_STRING = "Server Search String"
top = 530 # Location of filter components
horiz_sp = 10 # Horizontal spacing of major panel elements
class Tool(Application):
def __init__(self):
Application.__init__(self, title = "Log Analysis Tool")
print >>sys.stderr, "app init'd"
self.window = Window(size = (1200, 750), title = "Log Analysis Tool")
print >>sys.stderr, "made window"
# Create db cursor
db = get_conn(dbname = 'reduced_log')
self.cur = db.cursor()
print >>sys.stderr, "made db cursor"
self.current_table_suffix = None
# Load the dummy image for now
self.image = GraphView(size = (640, 460), position = (10, 10))
self.graph_panel = Frame()
self.graph_panel.add(self.image)
print >>sys.stderr, "loaded dummy image"
# Declare other image lists
self.full_ = None
self.peruser_alltime_ = None
self.peruser_divided_total_ = None
self.peruser_divided_ = None
# Create the display selection radio
self.display_select_radiogroup = RadioGroup(action =
self.change_images)
height, startx = 495, 20
sp = 10
r1 = RadioButton("All users",
group = self.display_select_radiogroup,
value = 'all_users')
r2 = RadioButton("Per user, query type",
group = self.display_select_radiogroup,
value = 'peruser_querytype')
r3 = RadioButton("Per user, time",
group = self.display_select_radiogroup,
value = 'peruser_time')
r4 = RadioButton("Per user, query type and time",
group = self.display_select_radiogroup,
value = 'peruser_querytype_time')
self.graph_panel.place(r1, top = self.image + 10, left = sp)
self.graph_panel.place(r2, top = self.image + 10, left = r1 + sp)
self.graph_panel.place(r3, top = self.image + 10, left = r2 + sp)
self.graph_panel.place(r4, top = self.image + 10, left = r3 + sp)
self.window.place(self.graph_panel, top=0, left=0)
self.display_select_radiogroup.value = 'all_users'
# Create the top queries textbox
self.topqueries = TopqueryPanel(size = (500, 460),
extent = (500, 1000))
self.topqueries.panels = [[TopqueryLabel("This is a placeholder until you select a filter",
["This is where", "the values", "will go"])]]
self.window.place(self.topqueries, top=10, left=680)
topqueries_next_button = Button("Next", action = self.topqueries.next)
topqueries_prev_button = Button("Prev", action = self.topqueries.prev)
self.window.place(topqueries_next_button, left = 930, top = top - 50)
self.window.place(topqueries_prev_button, left = 830, top = top - 50)
print >>sys.stderr, "made top queries text box"
# Declare the filter and last updated filter pointers
self.fil = None
self.last_used_fil = None
#
# *************************
# FILTER PANEL
# *************************
#
# **CREATE DATE PANEL**
field_width = 140
self.date_panel = Frame()
self.begin_date_field = TextField(size = (field_width, 30),
position = (0, 5),
text = DEFAULT_BEGIN_DATE_TEXT)
self.end_date_field = TextField(size = (field_width, 30),
position = (0, 35),
text = DEFAULT_END_DATE_TEXT)
self.date_panel.size = (field_width, 0)
# Time division radios
self.time_division_radiogroup = RadioGroup()
left, right = 5, 70
row1, rowspace = 95, 25
group_by_label = Label("Group by:",
position = (5, 70))
hour = RadioButton("Hour",
position = (left, row1),
group = self.time_division_radiogroup,
value = 'hour')
day = RadioButton("Day",
position = (right, row1),
group = self.time_division_radiogroup,
value = 'day')
week = RadioButton('Week',
position = (left, row1 + rowspace),
group = self.time_division_radiogroup,
value = 'week',
enabled = False) #TODO: implement 'week' in the gnuplot function
month = RadioButton("Month",
position = (right, row1 + rowspace),
group = self.time_division_radiogroup,
value = 'month')
year = RadioButton("Year",
position = (left, row1 + 2*rowspace),
group = self.time_division_radiogroup,
value = 'year')
self.time_division_radiogroup.value = 'day'
self.last_grouped_by = None
# Add all to date panel
self.date_panel.add([self.begin_date_field, self.end_date_field])
self.date_panel.add([group_by_label, hour, day, week, month, year])
self.window.place(self.date_panel, top=top, left=10)
print >>sys.stderr, "made date panel"
# **CREATE QUERY TYPE FILTER CHECKBOXES**
x_pos = 0
y_pos = 0
y_spacing = 20
self.query_type_checkboxes = {}
for qtype in querytypes:
# underscores don't display properly, need an extra space after
self.query_type_checkboxes[qtype] = CheckBox(qtype.replace('_', '_ '),
position = (x_pos,
y_pos),
value = True)
y_pos += y_spacing
# Add the query type checkboxes and buttons to a Frame
self.query_type_panel = Frame()
maxw = 0
for cbox in self.query_type_checkboxes.values():
self.query_type_panel.add(cbox)
maxw = max(cbox.size[0], maxw)
self.query_type_panel.size = (maxw, 0)
# Create all/none/invert buttons for query types
buttonsize = (55, 25)
self.query_type_panel.add(Button("All",
action = (self.select_all,
'query_type'),
size = buttonsize,
position = (20, y_pos)))
y_pos += 25
self.query_type_panel.add(Button("None",
action = (self.deselect_all,
'query_type'),
size = buttonsize,
position = (20, y_pos)))
y_pos += 25
self.query_type_panel.add(Button("Invert",
action = (self.invert_all,
'query_type'),
size = buttonsize,
position = (20, y_pos)))
# Add query_type_panel to the window
self.window.place(self.query_type_panel, top = top,
left=self.date_panel + horiz_sp)
print >>sys.stderr, "made query type cboxes"
# **CREATE USER AND SERVER CHECKBOX LISTS**
self.user_panel = None
self.server_panel = None
self.create_checkbox_lists(initial=True)
self.cur.execute("SELECT user, userid FROM users")
self.userids = dict(self.cur.fetchall())
self.cur.execute("SELECT server, serverid FROM servers")
self.serverids = dict(self.cur.fetchall())
print >>sys.stderr, "made user, server cboxes"
# **CREATE QUERY SEARCH STRING PANEL**
num_search_strings = 5
spacing = 30
field_width = 250
self.search_string_panel = Frame()
self.search_string_panel.size = (field_width, 0)
self.search_string_fields = [TextField(size = (field_width, 30),
position = (0, spacing * i),
text = "Query Search String {0}".format(i + 1))
for i in range(num_search_strings)]
self.search_string_panel.add(self.search_string_fields)
self.any_all_radiogroup = RadioGroup()
any_string_radio = RadioButton("Any",
position = (40, 10 + spacing * \
num_search_strings),
group = self.any_all_radiogroup,
value = 'any')
all_strings_radio = RadioButton("All",
position = (130, 10 + spacing * \
num_search_strings),
group = self.any_all_radiogroup,
value = 'all')
no_string_radio = RadioButton("None",
position = (40, 30 + spacing * \
num_search_strings),
group = self.any_all_radiogroup,
value = 'none')
not_all_string_radio = RadioButton("Not All",
position = (130, 30 + spacing * \
num_search_strings),
group = self.any_all_radiogroup,
value = 'not all')
self.any_all_radiogroup.value = 'any'
self.search_string_panel.add(any_string_radio)
self.search_string_panel.add(all_strings_radio)
self.search_string_panel.add(no_string_radio)
self.search_string_panel.add(not_all_string_radio)
self.window.place(self.search_string_panel, top = top,
left = self.server_panel + 10)
print >>sys.stderr, "made search string panel"
# SELECT ALL/NONE, INVERT USERS
# TODO: create user, server panels? atm only the cboxes are in
# a ScrollableView
buttonsize = (55, 25)
invertbuttonsize = (60, 25)
userstart = 295
serverstart = 565
self.window.place(Button("All",
action = (self.select_all,
'user'),
size = buttonsize),
top = top + 155, left = userstart)
self.window.place(Button("None",
action = (self.deselect_all,
'user'),
size = buttonsize),
top = top + 155, left = userstart + 55 + 5)
self.window.place(Button("Invert",
action = (self.invert_all,
'user'),
size = invertbuttonsize),
top = top + 155, left = userstart + 55 + 5 + 55 + 5)
# user search string textbox
# TODO: the action is always one keystroke behind the text field.
# This is a PyGUI 'bug',but it may only happen on windows (not sure
# how the X server works).
# See http://mail.python.org/pipermail/pygui/2010-November/000102.html
self.user_search_string = ResponsiveTextField(emptyaction = None,
action = (self.select_all_matching,
'user'),
size = (180, 30),
text = DEFAULT_USER_SEARCH_STRING)
self.window.place(self.user_search_string,
top = top + 155 + 25 + 5,
left = userstart)
# SELECT ALL/NONE, INVERT SERVERS
self.window.place(Button("All",
action = (self.select_all,
'server'),
size = buttonsize),
top = top + 155, left = serverstart)
self.window.place(Button("None",
action = (self.deselect_all,
'server'),
size = buttonsize),
top = top + 155, left = serverstart + 55 + 5)
self.window.place(Button("Invert",
action = (self.invert_all,
'server'),
size = invertbuttonsize),
top = top + 155,
left = serverstart + 55 + 5 + 55 + 5)
# server search string textbox
self.server_search_string = ResponsiveTextField(emptyaction = None,
action = (self.select_all_matching,
'server'),
size = (180, 30),
text = DEFAULT_SERVER_SEARCH_STRING)
self.window.place(self.server_search_string,
top = top + 155 + 25 + 5, left=serverstart)
self.window.show()
# **CREATE BUTTONS**
self.negate = CheckBox("Negate Filter", position=(0, 0), value=False)
self.refresh_button = Button("Refresh",
position = (0, 25),
action=self.refresh)
self.update_button = Button("Update",
position = (0, 60),
action = self.update)
# Add buttons to a panel
self.button_panel = Frame()
self.button_panel.add([self.negate,
self.refresh_button,
self.update_button])
self.window.place(self.button_panel, top = top,
left=self.search_string_panel + horiz_sp)
print >>sys.stderr, "made button panel"
def create_checkbox_lists(self, initial=False):
"""
Removes the current user and server checkbox panels from the window,
if they exist (if they don't, they will be None, from __init__())
creates new ones with data from the current table, then adds them
to the window again. If @initial is True, only the last partition
(month) of the 'unified' table will be used for counts, but all
users and servers will still be shown
@initial - if this is the first time the checkbox lists are being
generated, it works a bit differently: the counts are
taken from just the last partition of the unified table
so that startup doesn't take forever. We then also need
to grab the names of other users who didn't appear in
this first partition
"""
# Remove current user and server checkbox panels from the window
if self.user_panel:
self.window.remove(self.user_panel)
if self.server_panel:
self.window.remove(self.server_panel)
# Create user filter checkboxes
if initial:
print_and_execute("""SELECT PARTITION_NAME
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_SCHEMA = 'reduced_log'
AND TABLE_NAME = 'unified'""", self.cur)
# there will be each month, then the 'other' partition, so we want to
# select from the 2nd to last partition
last_partition = [x for x, in self.cur.fetchall()][-2]
table_to_use = "unified PARTITION({0})".format(last_partition)
else:
table_to_use = self.current_table_name()
print_and_execute("""SELECT userid, user, count
FROM (SELECT userid, COUNT(*) AS count
FROM {0} GROUP BY userid
) AS sth
NATURAL JOIN users
ORDER BY count DESC
""".format(table_to_use), self.cur)
userlist = [x for x in self.cur.fetchall()]
x_pos = 0
y_pos = 0
y_spacing = 20
self.user_checkboxes = {}
size_width = 220
extent_width = size_width
for userid, user, count in userlist:
self.user_checkboxes[user] = CheckBox("{0} ({1})".format(user.replace('_', '_ '),
count),
position = (x_pos, y_pos),
value = True)
extent_width = max(self.user_checkboxes[user].size[0], extent_width)
y_pos += y_spacing
# Get users that didn't appear in the last partition, if @initial
if initial:
self.cur.execute("SELECT user, userid FROM users")
for user, userid in self.cur.fetchall():
if user in self.user_checkboxes:
continue
self.user_checkboxes[user] = CheckBox(user.replace('_', '_ ') + " (0)",
position = (x_pos, y_pos),
value = True)
extent_width = max(self.user_checkboxes[user].size[0], extent_width)
y_pos += y_spacing
# Add the user checkboxes to a ScrollableView:
self.user_panel = ScrollableView(size = (size_width, 150),
extent = (extent_width,
max(150, y_pos)),
scrolling = 'v' if extent_width <= size_width else 'hv')
for cbox in self.user_checkboxes.values():
self.user_panel.add(cbox)
# Add the panel to the window
self.window.place(self.user_panel, top = top,
left = self.query_type_panel + horiz_sp)
# Create server filter checkboxes
print_and_execute("""SELECT serverid, server, count
FROM (SELECT serverid, COUNT(*) AS count
FROM {0} GROUP BY serverid
) as sth
NATURAL JOIN servers
ORDER BY count DESC
""".format(table_to_use), self.cur)
serverlist = [x for x in self.cur.fetchall()]
x_pos = 0
y_pos = 0
y_spacing = 20
self.server_checkboxes = {}
size_width = 300
extent_width = size_width
for serverid, server, count in serverlist:
self.server_checkboxes[server] = CheckBox("{0} ({1})".format(server,
count),
position = (x_pos, y_pos),
value = True)
extent_width = max(self.server_checkboxes[server].size[0], extent_width)
y_pos += y_spacing
if initial:
self.cur.execute("SELECT server FROM servers")
for server, in self.cur.fetchall():
if server in self.server_checkboxes:
continue
self.server_checkboxes[server] = CheckBox(server.replace('_', '_ ') + " (0)",
position = (x_pos, y_pos),
value = True)
extent_width = max(self.server_checkboxes[server].size[0], extent_width)
y_pos += y_spacing
# Add the server checkboxes to a ScrollableView
self.server_panel = ScrollableView(size = (size_width, 150),
extent = (extent_width,
max(150, y_pos)),
scrolling = 'v' if extent_width <= size_width else 'hv')
for cbox in self.server_checkboxes.values():
self.server_panel.add(cbox)
# Add the server panel to the window
self.window.place(self.server_panel, top = top,
left=self.user_panel + 10)
def get_new_filter(self):
"""
Set self.fil to a new Filter reflecting the current status of the
GUI elements
"""
# Get the status of GUI elements
# TODO: support for one date field but not the other
# (should be done mostly in Filter class)
if self.begin_date_field.text \
and self.begin_date_field.text != DEFAULT_BEGIN_DATE_TEXT \
and self.end_date_field.text \
and self.end_date_field.text != DEFAULT_END_DATE_TEXT:
daterange = (datetime.strptime(self.begin_date_field.text,
DATEFORMAT),
datetime.strptime(self.end_date_field.text,
DATEFORMAT))
else:
daterange = None
# User
user = [self.userids[u] for u, cb in self.user_checkboxes.iteritems() \
if cb.value]
if len(user) == len(self.user_checkboxes): #all users selected
user = None
# Server
server = [self.serverids[s] for s, cb in self.server_checkboxes.iteritems() \
if cb.value]
if len(server) == len(self.server_checkboxes):
server = None
# Search String List
search_string = SearchStringList(self.any_all_radiogroup.value)
search_string.extend([fld.text for fld in self.search_string_fields \
if fld.text and not fld.text.startswith('Query Search String ')])
# Query types
query_type = [qtype for qtype, cb in self.query_type_checkboxes.iteritems() if cb.value]
query_type = clean_list(query_type)
if not query_type or len(query_type) == len(querytypes):
#all types selected
query_type = None
# Create the filter object
self.fil = Filter(daterange = daterange,
user = user,
server = server,
search_string = search_string,
query_type = query_type,
negate = self.negate.value)
def refresh(self):
"""
Regenerate the graphs/top query lists without changing the table that
the tool pulls from
"""
# Get the status of GUI elements
self.get_new_filter()
# Don't repeat the query if self.filter hasn't changed since the last
# update
if self.fil != self.last_used_fil:
self.create_new_temp_table()
self.create_new_graphs_and_topqueries()
elif self.last_grouped_by != self.time_division_radiogroup.value:
self.create_new_graphs_and_topqueries()
def create_new_temp_table(self):
# Create a temp table
lasttable = self.current_table_name()
nexttable = self.next_table_name()
# Create main table
self.cur.execute("DROP TABLE IF EXISTS {0}".format(nexttable))
print_and_execute("CREATE TEMPORARY TABLE {0} AS {1}".format(nexttable,
self.fil.sql(lasttable)),
self.cur)
print_and_execute("ALTER TABLE {0} ADD INDEX (userid)".format(nexttable), self.cur)
print_and_execute("ALTER TABLE {0} ADD INDEX (serverid)".format(nexttable), self.cur)
self.last_used_fil = self.fil
def create_new_graphs_and_topqueries(self):
prefix = config.get('plot_dir') or 'plots'
current_dir = os.getcwd()
# Get profiles of the created table
nexttable = self.next_table_name()
profiles = query_profile(nexttable,
config.get("numtop") or 200,
self.time_division_radiogroup.value,
self.cur)
peruser_divided, peruser_alltime, full_divided, full_alltime, full_topqueries, peruser_topqueries = profiles
# Remove previous plotted data
if os.path.exists(prefix):
os.system("rm -r {0}".format(prefix))
os.mkdir(prefix)
os.chdir(prefix)
gnuplot(profiles, time_axis_label=self.time_division_radiogroup.value)
# use a for loop so that gnuplot settings don't stick around between scripts
os.system("for x in *.gnu; do gnuplot $x; done")
# Load the new image lists
self.full_ = [Image(file=x) for x in glob('full_*.png')]
self.peruser_alltime_ = [Image(file=x) for x in \
glob('peruser_alltime_*.png')]
self.peruser_divided_ = [Image(file=x) for x in \
glob('peruser_divided_*.png') if '_total_' not in x]
self.peruser_divided_total_ = [Image(file=x) for x in \
glob('peruser_divided_total_*.png')]
os.chdir(current_dir)
# Set self.image.images = whatever's selected in the radio
# (we got new lists)
self.change_images()
# Generate the new topquery panel text
self.topqueries.new_profiles(full_topqueries, peruser_topqueries)
self.last_grouped_by = self.time_division_radiogroup.value
def update(self):
"""
Regenerate the graphs/top query lists, then change the table that the
tool pulls from to the newly generated table. Update the lists of
checkboxes.
"""
self.refresh()
if self.current_table_suffix:
self.current_table_suffix += 1
else:
self.current_table_suffix = 1
# update lists of checkboxes
self.create_checkbox_lists()
# reset status of GUI elements that weren't just recreated
# self.begin_date_field.text = DEFAULT_BEGIN_DATE_TEXT
# self.end_date_field.text = DEFAULT_END_DATE_TEXT
# for cbox in self.query_type_checkboxes.values():
# cbox.value = True
# for i, fld in enumerate(self.search_string_fields):
# fld.text = "Query Search String {0}".format(i + 1)
def change_images(self):
string = self.display_select_radiogroup.value
if string == 'all_users':
self.image.images = self.full_
elif string == 'peruser_querytype':
self.image.images = self.peruser_alltime_
elif string == 'peruser_time':
self.image.images = self.peruser_divided_total_
elif string == 'peruser_querytype_time':
self.image.images = self.peruser_divided_
else:
print >>sys.stderr, "Unrecognized display_select_radiogroup value %s" % string
if not self.image.images:
print >>sys.stderr, "image list assigned to self.image.images is None, using dummy"
self.image.images = GraphView.DUMMY_IMLIST
self.image.im_num = 0
self.image.invalidate()
def current_table_name(self):
"""
Return the name of the table we are currently pulling from
"""
if self.current_table_suffix:
return "analysis_tool_temp" + str(self.current_table_suffix)
return 'unified'
def next_table_name(self):
"""
Return the name of the table we should insert into
"""
if self.current_table_suffix:
return "analysis_tool_temp" + str(self.current_table_suffix + 1)
else:
return "analysis_tool_temp1"
def select_all(self, what):
"""
Set the value property of all checkboxes in the list to True
@what must be one of 'user' or 'server'
"""
if what == 'user':
cboxes = self.user_checkboxes.values()
elif what == 'server':
cboxes = self.server_checkboxes.values()
elif what == 'query_type':
cboxes = self.query_type_checkboxes.values()
else:
print >>sys.stderr, "unrecognized thing to select all: %s" % what
return
for cbox in cboxes:
cbox.value = True
def deselect_all(self, what):
"""
Set the value property of all checkboxes in the list to False
@what must be one of 'user' or 'server'
"""
if what == 'user':
cboxes = self.user_checkboxes.values()
elif what == 'server':
cboxes = self.server_checkboxes.values()
elif what == 'query_type':
cboxes = self.query_type_checkboxes.values()
else:
print >>sys.stderr, "unrecognized thing to deselect all: %s" % what
return
for cbox in cboxes:
cbox.value = False
def invert_all(self, what):
"""
Set the value property of all checkboxes in the list to its inverse
@what must be one of 'user' or 'server'
"""
if what == 'user':
cboxes = self.user_checkboxes.values()
elif what == 'server':
cboxes = self.server_checkboxes.values()
elif what == 'query_type':
cboxes = self.query_type_checkboxes.values()
else:
print >>sys.stderr, "unrecognized thing to select all: %s" % what
return
for cbox in cboxes:
cbox.value = not cbox.value
def enable_all(self, what):
"""
Enable all elements in the list
@what must be one of 'user' or 'server' and the relevant
checkboxes will be enabled
"""
if what == 'user':
elements = self.user_checkboxes.values()
elif what == 'server':
elements = self.server_checkboxes.values()
elif what == 'query_type':
elements = self.query_type_checkboxes.values()
else:
print >>sys.stderr, "unrecognized thing to enable all: %s" % what
return
for elem in elements:
elem.enabled = True
def disable_all(self, what):
"""
Disable all elements inthe list
@what must be one of 'user' or 'server' and the relevant
checkboxes will be disabled
"""
if what == 'user':
elements = self.user_checkboxes.values()
elif what == 'server':
elements = self.server_checkboxes.values()
elif what == 'query_type':
elements = self.query_type_checkboxes.values()
else:
print >>sys.stderr, "unrecognized thing to disable all: %s" % what
return
for elem in elements:
elem.enabled = False
def select_all_matching(self, where):
if where == 'user':
elements = self.user_checkboxes
search_string = self.user_search_string.text
elif where == 'server':
elements = self.server_checkboxes
search_string = self.server_search_string.text
else:
print >>sys.stderr, "unrecognized thing select all matching: %s" % where
return
for text, cbox in elements.iteritems():
if search_string in text:
cbox.value = True
else:
cbox.value = False
def change_topquery_ptr(self, how_much):
"""
Changes the variable indicating which topquery view is to be selected
And then updates self.topqueries.text
"""
self.topquery_ptr += how_much
self.topqueries.text = self.topquery_texts[self.topquery_ptr % len(self.topquery_texts)]
def open_app(self):
# Everything done in __init__()
pass
if __name__ == '__main__':
x = Tool() #two lines for easier debugging with "python -i tool.py"
x.run()