source: trunk/packages/xen-3.1/xen-3.1/tools/python/logging/logging-0.4.9.2/test/logconf.py @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

  • Property svn:executable set to *
  • Property svn:mime-type set to text/script
File size: 60.9 KB
Line 
1#!/usr/bin/env python
2#
3# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
4#
5# Permission to use, copy, modify, and distribute this software and its
6# documentation for any purpose and without fee is hereby granted,
7# provided that the above copyright notice appear in all copies and that
8# both that copyright notice and this permission notice appear in
9# supporting documentation, and that the name of Vinay Sajip
10# not be used in advertising or publicity pertaining to distribution
11# of the software without specific, written prior permission.
12# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
14# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
15# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
16# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18#
19# This file is part of the Python logging distribution. See
20# http://www.red-dove.com/python_logging.html
21#
22
23"""
24A simple-minded GUI configurator for the logging module, using Tkinter.
25
26Should work under Python versions >= 1.5.2.
27
28Copyright (C) 2002 Vinay Sajip. All Rights Reserved.
29
30Configuration files are read/written using ConfigParser.
31"""
32"""
33
34(C) 2002 Vinay Sajip. All rights reserved.
35"""
36from Tkinter import *
37from tkFileDialog import *
38from tkMessageBox import *
39
40import os, sys, string, types
41import ConfigParser
42
43active = None
44
45__version__ = "0.4.1"
46
47DEFAULT_FILENAME = "logconf.ini"
48
49LOGGING_LEVELS = (
50    ("NOTSET", "NOTSET"),
51    ("DEBUG", "DEBUG"),
52    ("INFO", "INFO"),
53    ("WARNING", "WARNING"),
54    ("ERROR", "ERROR"),
55    ("CRITICAL", "CRITICAL")
56)
57
58HANDLER_TYPES = (
59    ("StreamHandlerProxy", "StreamHandler"),
60    ("FileHandlerProxy", "FileHandler"),
61    ("RotatingFileHandlerProxy", "RotatingFileHandler"),
62    ("SocketHandlerProxy", "SocketHandler"),
63    ("DatagramHandlerProxy", "DatagramHandler"),
64    ("SysLogHandlerProxy", "SysLogHandler"),
65    ("NTEventLogHandlerProxy", "NTEventLogHandler"),
66    ("SMTPHandlerProxy", "SMTPHandler"),
67    ("MemoryHandlerProxy", "MemoryHandler"),
68    ("HTTPHandlerProxy", "HTTPHandler"),
69#    ("SOAPHandlerProxy", "SOAPHandler"),
70)
71
72OUTPUT_STREAMS = (
73    ("sys.stdout", "sys.stdout"),
74    ("sys.stderr", "sys.stderr")
75)
76
77FILE_MODES = (
78    ("a", "a"),
79    ("w", "w")
80 )
81
82HTTP_METHODS = (
83    ("GET", "GET"),
84    ("POST", "POST")
85)
86
87SYSLOG_FACILITIES = (
88    ("LOG_AUTH", "auth"),
89    ("LOG_AUTHPRIV", "authpriv"),
90    ("LOG_CRON", "cron"),
91    ("LOG_DAEMON", "daemon"),
92    ("LOG_KERN", "kern"),
93    ("LOG_LPR", "lpr"),
94    ("LOG_MAIL", "mail"),
95    ("LOG_NEWS", "news"),
96    ("LOG_AUTH", "security"),
97    ("LOG_SYSLOG", "syslog"),
98    ("LOG_USER", "user"),
99    ("LOG_UUCP", "uucp"),
100    ("LOG_LOCAL0", "local0"),
101    ("LOG_LOCAL1", "local1"),
102    ("LOG_LOCAL2", "local2"),
103    ("LOG_LOCAL3", "local3"),
104    ("LOG_LOCAL4", "local4"),
105    ("LOG_LOCAL5", "local5"),
106    ("LOG_LOCAL6", "local6"),
107    ("LOG_LOCAL7", "local7"),
108)
109
110LOG_TYPES = (
111    ("Application", "Application"),
112    ("System", "System"),
113    ("Security", "Security")
114)
115
116BOOLEAN_VALUES = (
117    ("0", "False"),
118    ("1", "True")
119)
120
121class Property:
122    def __init__(self, name, caption, value=None, choices=None):
123        self.name = name
124        self.caption = caption
125        self.value = value
126        self.choices = choices
127
128    def getChoices(self):
129        return self.choices
130
131    def isvalid(self, s):
132        return 0
133
134    def getCaption(self):
135        return self.caption
136
137    def getValue(self):
138        return self.value
139
140    def getChoiceText(self, val):
141        rv = ""
142        choices = self.getChoices()
143        if choices:
144            for choice in choices:
145                if choice[0] == val:
146                    rv = choice[1]
147                    break
148        return rv
149
150    def setValue(self, val):
151        self.value = val
152
153    def getValueText(self):
154        if type(self.value) in [types.ListType, types.TupleType]:
155            v = list(self.value)
156        else:
157            v = [self.value]
158        choices = self.getChoices()
159        if choices:
160            v = map(self.getChoiceText, v)
161        return string.join(v, ',')
162
163class PropertyHolder:
164    def __init__(self, dict):
165        self.dict = dict
166        self.propnames = []
167        self.onPropListChanged = None
168
169    def getPropNames(self):
170        """
171        Return the property names in the order in which they are to
172        be listed.
173        """
174        return self.propnames
175
176    def getProp(self, name):
177        return self.dict[name]
178
179    def isReadonly(self, name):
180        return 0
181
182    #convenience methods
183    def getPropValue(self, name):
184        return self.dict[name].value
185
186    def setPropValue(self, name, value):
187        self.dict[name].setValue(value)
188
189LINE_COLOUR = '#999999'
190
191class ScrollingList(Frame):
192    def __init__(self, parent, *args, **kwargs):
193        Frame.__init__(self, parent)
194        self.parent = parent
195        self.listener = self.parent
196        self.sb = Scrollbar(self, orient=VERTICAL)
197        kwargs["yscrollcommand"] = self.sb.set
198        self.list = apply(Listbox, (self,) + args, kwargs)
199        self.sb.config(command=self.list.yview)
200        self.sb.pack(side=RIGHT, fill=Y)
201        self.list.pack(side=LEFT, fill=BOTH,expand=1)
202        self.list.bind('<ButtonRelease-1>', self.onListChange)
203        self.choices = None
204
205    def setContents(self, choices, value):
206        self.choices = choices
207        self.value = value
208        self.list.delete(0, END)
209        if type(value) == types.ListType:
210            sm = EXTENDED
211        else:
212            sm = BROWSE
213        self.list.configure(selectmode=sm)
214        i = 0
215        for choice in choices:
216            self.list.insert(END, choice[1])
217            if sm == EXTENDED:
218                if choice[0] in value:
219                    self.list.select_set(i)
220            else:
221                if choice[0] == value:
222                    self.list.select_set(i)
223            i = i + 1
224
225    def getValue(self):
226        if type(self.value) == types.ListType:
227            multi = 1
228            rv = []
229        else:
230            multi = 0
231        for i in xrange(len(self.choices)):
232            if self.list.select_includes(i):
233                if not multi:
234                    rv = self.choices[i][0]
235                    break
236                else:
237                    rv.append(self.choices[i][0])
238        return rv
239
240    def onListChange(self, event):
241        self.value = self.getValue()
242        self.listener.onListChange(self.value)
243
244class PropertyHeader(Canvas):
245    def __init__(self, parent, *args, **kwargs):
246        self.namewidth = 120
247        if kwargs.has_key("namewidth"):
248            self.namewidth = kwargs["namewidth"]
249            del kwargs["namewidth"]
250        self.rowheight = 16
251        if kwargs.has_key("rowheight"):
252            self.rowheight = kwargs["rowheight"]
253            del kwargs["rowheight"]
254        apply(Canvas.__init__, (self, parent)+args, kwargs)
255        self.bind('<Configure>', self.onConfigure)
256        x = 5
257        y = 0
258        wid = int(self.cget('width'))
259        self.create_text(x, y, text='Property', anchor='nw')
260        self.create_text(x + self.namewidth, y, text='Value', anchor='nw')
261        self.create_line(self.namewidth, 0, self.namewidth, self.rowheight, fill=LINE_COLOUR)
262        self.tline = self.create_line(0, 0, wid, 0, fill=LINE_COLOUR)
263        #self.create_line(0, 0, 0, self.rowheight, fill=LINE_COLOUR)
264        #self.create_line(wid - 1, 0, wid - 1, self.rowheight, fill=LINE_COLOUR)
265
266    def onConfigure(self, event):
267        self.delete(self.tline)
268        self.tline = self.create_line(0, 0, event.width, 0, fill=LINE_COLOUR)
269
270_popup = None
271
272class PropertyCanvas(Canvas):
273    def __init__(self, parent, *args, **kwargs):
274        self.namewidth = 120
275        if kwargs.has_key("namewidth"):
276            self.namewidth = kwargs["namewidth"]
277            del kwargs["namewidth"]
278        self.rowheight = 16
279        if kwargs.has_key("rowheight"):
280            self.rowheight = kwargs["rowheight"]
281            del kwargs["rowheight"]
282        apply(Canvas.__init__, (self, parent)+args, kwargs)
283        self.namitems = []
284        self.valitems = []
285        self.lines = []
286        self.pnames = []
287        #Event bindings...
288        self.bind('<Enter>', self.onEnter)
289        self.bind('<Button-1>', self.onClick)
290        self.bind('<Configure>', self.onConfigure)
291        self.button = Button(height=self.rowheight, width=self.rowheight, text='...', command=self.onEdit)
292        self.btnitem = None
293        self.editor = Entry()
294        self.edititem = None
295        self.popup = Toplevel()
296        self.popup.withdraw()
297        self.popup.overrideredirect(1)
298        self.list = ScrollingList(self.popup, background='white', relief=FLAT, borderwidth=0)
299        self.list.pack(fill=BOTH, expand=1)
300        self.list.listener = self
301        self.listvisible = 0
302
303    def clear(self):
304        for itm in self.namitems:
305            self.delete(itm)
306        self.namitems = []
307        for itm in self.valitems:
308            self.delete(itm)
309        self.valitems = []
310        for lin in self.lines:
311            self.delete(lin)
312        self.lines = []
313
314    def setPropertyHolder(self, ph):
315        self.ph = ph
316        self.pnames = ph.getPropNames()
317        wid = int(self.cget('width'))
318        hei = int(self.cget('height'))
319        self.clear()
320        x = 5
321        y = 0
322        i = 0
323        self.props = []
324        for n in self.pnames:
325            prop = self.ph.getProp(n)
326            self.props.append(prop)
327            tn = "n%d" % i
328            tv = "v%d" % i
329            self.namitems.append(self.create_text(x, y + 2, text=prop.getCaption(), anchor='nw', tags=tn))
330            self.valitems.append(self.create_text(x + self.namewidth, y + 2, text=prop.getValueText(), anchor='nw', tags=tv))
331            y = y + self.rowheight
332            i = i + 1
333        self.drawLines(wid, hei)
334        #self.config(height=y)
335
336    def drawLines(self, wid, hei):
337        for lin in self.lines:
338            self.delete(lin)
339        self.lines = []
340        y = 0
341        for i in xrange(len(self.pnames)):
342            self.lines.append(self.create_line(0, y, wid, y, fill=LINE_COLOUR))
343            y = y + self.rowheight
344        self.lines.append(self.create_line(0, y, wid, y, fill=LINE_COLOUR))
345        self.create_line(self.namewidth, 0, self.namewidth, hei, fill=LINE_COLOUR)
346
347    def onEnter(self, event):
348        if not self.edititem and not self.listvisible:
349            self.focus_set()
350
351    def hideControls(self):
352        if self.listvisible:
353            self.popup.withdraw()
354            global _popup
355            _popup = None
356            self.listvisible = 0
357        if self.edititem:
358            self.ph.setPropValue(self.editprop.name, self.editor.get())
359            self.itemconfig(self.valitems[self.editrow], text=self.editprop.getValueText())
360            self.delete(self.edititem)
361            self.edititem = None
362        if self.btnitem:
363            self.delete(self.btnitem)
364            self.btnitem = None
365
366    def onClick(self, event):
367        row = event.y / self.rowheight
368        self.hideControls()
369        if row < len(self.pnames):
370            wid = int(self.cget('width'))
371            hei = self.rowheight
372            prop = self.props[row]
373            if not self.ph.isReadonly(self.pnames[row]):
374                self.editrow = row
375                self.editprop = prop
376                choices = prop.getChoices()
377                if choices != None:
378                    val = prop.getValue()
379                    self.list.setContents(choices, val)
380                    self.listy = row * hei + self.rowheight
381                    self.btnitem = self.create_window(wid - hei, row * hei, width=hei, height=hei, window=self.button, anchor='nw', tags='button')
382                else:
383                    self.editor.delete(0, END)
384                    self.editor.insert(0, prop.getValueText())
385                    self.editor.select_range(0, END)
386                    self.edititem = self.create_window(self.namewidth + 1, row * hei, width=wid - self.namewidth, height = hei + 1, window=self.editor, anchor='nw', tags='editor')
387                    self.editor.focus_set()
388
389    def onConfigure(self, event):
390        self.hideControls()
391        self.drawLines(event.width, event.height)
392        self.configure(width=event.width, height=event.height)
393
394    def onEdit(self):
395        wid = int(self.cget('width'))
396        #self.listitem = self.create_window(self.namewidth + 1, self.listy, width=wid - self.namewidth - 1, height = self.rowheight * 3, window=self.list, anchor='nw', tags='list')
397        w = wid - self.namewidth - 1
398        h = self.rowheight * 5
399        x = self.winfo_rootx() + self.namewidth + 1
400        y = self.winfo_rooty() + self.listy
401        s = "%dx%d+%d+%d" % (w, h, x, y)
402        self.popup.deiconify()
403        self.popup.lift()
404        self.popup.focus_set()
405        self.listvisible = 1
406        self.list.focus_set()
407        #For some reason with 1.5.2 (Windows), making the geometry call
408        #immediately following the assignment to s doesn't work. So we
409        #do it here
410        self.popup.geometry(s)
411        global _popup
412        _popup = self.popup
413
414    def onListChange(self, val):
415        self.ph.setPropValue(self.editprop.name, val)
416        self.itemconfig(self.valitems[self.editrow], text=self.editprop.getValueText())
417        if type(val) != types.ListType:
418            self.hideControls()
419
420class PropertyEditor(Frame):
421    def __init__(self, parent, *args, **kwargs):
422        Frame.__init__(self, parent)
423        self.parent = parent
424        nw = kwargs.get("namewidth", 120)
425        rh = kwargs.get("rowheight", 16)
426        wid = kwargs.get("width", 300)
427        hei = kwargs.get("height", 60)
428        self.header = PropertyHeader(self, namewidth=nw, rowheight=rh, height=14, highlightthickness=0)
429        self.body = PropertyCanvas(self, namewidth=nw, rowheight=rh, width=wid, height=hei, background='white', highlightthickness=0)
430        self.header.pack(side=TOP, fill=X)
431        self.body.pack(side=BOTTOM, fill=BOTH, expand=1)
432
433    def setPropertyHolder(self, ph):
434        self.body.setPropertyHolder(ph)
435
436class ADUPanel(Frame):
437    def __init__(self, parent):
438        Frame.__init__(self, parent)
439        self.parent = parent
440        self.add = Button(self, text="New", command=parent.onAdd)
441        self.add.pack(side=LEFT) #, fill=X, expand=1)
442        self.rmv = Button(self, text="Delete", command=parent.onDelete)
443        self.rmv.pack(side=LEFT) #, fill=X, expand=1)
444        #self.upd = Button(self, text="Update", command=parent.onUpdate)
445        #self.upd.pack(side=RIGHT, fill=X, expand=1)
446
447class ScrollList(Frame):
448    def __init__(self, parent, *args, **kwargs):
449        Frame.__init__(self, parent)
450        self.parent = parent
451        self.sb = Scrollbar(self, orient=VERTICAL)
452        kwargs["yscrollcommand"] = self.sb.set
453        self.list = apply(Listbox, (self,) + args, kwargs)
454        self.sb.config(command=self.list.yview)
455        self.sb.pack(side=RIGHT, fill=Y)
456        self.list.pack(side=LEFT, fill=BOTH,expand=1)
457
458def sortqn(log1, log2):
459    qn1 = log1.getQualifiedName()
460    qn2 = log2.getQualifiedName()
461    if qn1 == "(root)":
462        rv = -1
463    elif qn2 == "(root)":
464        rv = 1
465    else:
466        rv = cmp(qn1, qn2)
467    return rv
468
469def sortn(obj1, obj2):
470    return cmp(obj1.getPropValue("name"), obj2.getPropValue("name"))
471
472class LoggerPanel(Frame):
473    def __init__(self, parent):
474        Frame.__init__(self, parent)
475        self.parent = parent
476        label = Label(self, text="Loggers:")
477        label.grid(row=0, column=0, sticky='w')
478        self.slist = ScrollList(self, height=15, background='white')
479        self.slist.list.bind('<ButtonRelease-1>', self.onListChange)
480        self.slist.grid(row=1, column=0, sticky="nsew")
481        self.adu = ADUPanel(self)
482        self.adu.grid(row=2, column=0, sticky="we")
483        label = Label(self, text="Properties of selected logger:")
484        label.grid(row=3, column=0, sticky='w')
485        self.pe = PropertyEditor(self, height=120, borderwidth=1)
486        self.pe.grid(row=4, column=0, sticky='nsew')
487        self.columnconfigure(0, weight=1)
488        self.rowconfigure(1, weight=3)
489        self.rowconfigure(4, weight=1)
490
491    def setConfig(self, config):
492        self.config = config
493        #populate list of loggers
494        llist = config.getLoggers()
495        llist.sort(sortqn)
496        self.slist.list.delete(0, END)
497        self.pe.body.clear()
498        self.names = []
499        for logger in llist:
500            self.names.append(logger.getPropValue("name"))
501            self.slist.list.insert(END, logger.getQualifiedName())
502
503    def onAdd(self):
504        items = self.slist.list.curselection()
505        if not len(items):
506            showerror("No Parent Selected", "You haven't selected a parent logger.")
507        else:
508            idx = int(items[0])
509            parent = self.config.getLogger(self.names[idx])
510            log = self.config.getLogger(None)
511            log.onChannelChanged = self.onChannelChanged
512            log.setPropValue("parent", parent.getPropValue("name"))
513            self.names.insert(1 + idx, log.getPropValue("name"))
514            self.slist.list.insert(1 + idx, log.getQualifiedName())
515            self.slist.list.select_clear(0, END)
516            self.slist.list.select_set(1 + idx)
517            self.pe.setPropertyHolder(log)
518
519    def onDelete(self):
520        items = self.slist.list.curselection()
521        if not len(items):
522            showerror("No Item Selected", "You haven't selected anything to delete.")
523        else:
524            idx = int(items[0])
525            name = self.slist.list.get(idx)
526            if name == "(root)":
527                showerror("Root Item Selected", "You cannot delete the root logger.")
528            else:
529                resp = askyesno("Logger Deletion", "Are you sure you want to delete logger '%s'?" % name)
530                if resp:
531                    #self.config.removeLogger(self.names[idx])
532                    log = self.config.getLogger(self.names[idx])
533                    log.deleted = 1
534                    self.slist.list.delete(idx)
535                    del self.names[idx]
536                    self.pe.body.clear()
537
538    def onChannelChanged(self, nm, chname):
539        i = self.names.index(nm)
540        sel = i
541        while i < len(self.names):
542            log = self.config.getLogger(self.names[i])
543            self.slist.list.delete(i)
544            self.slist.list.insert(i, log.getQualifiedName())
545            i = i + 1
546        self.slist.list.select_clear(0, END)
547        self.slist.list.select_set(sel)
548
549    def onListChange(self, event):
550        self.pe.body.hideControls()
551        items = self.slist.list.curselection()
552        idx = int(items[0])
553        name = self.names[idx]
554        log = self.config.getLogger(name)
555        self.pe.setPropertyHolder(log)
556
557class HandlerPanel(Frame):
558    def __init__(self, parent):
559        Frame.__init__(self, parent)
560        self.parent = parent
561        label = Label(self, text="Handlers:")
562        label.grid(row=0, column=0, sticky='w')
563        self.slist = ScrollList(self, height=6, background='white')
564        self.slist.list.bind('<ButtonRelease-1>', self.onListChange)
565        self.slist.grid(row=1, column=0, sticky="nsew")
566        self.adu = ADUPanel(self)
567        self.adu.grid(row=2, column=0, sticky="we")
568        label = Label(self, text="Properties of selected handler:")
569        label.grid(row=3, column=0, sticky='w')
570        self.pe = PropertyEditor(self, height=90, borderwidth=1)
571        self.pe.grid(row=4, column=0, sticky='nsew')
572        self.columnconfigure(0, weight=1)
573        self.rowconfigure(1, weight=1)
574        self.rowconfigure(4, weight=1)
575
576    def setConfig(self, config):
577        self.config = config
578        #populate list of handlers
579        hlist = config.getHandlers()
580        hlist.sort(sortn)
581        self.slist.list.delete(0, END)
582        self.pe.body.clear()
583        for hand in hlist:
584            hand.onPropListChanged = self.onPropListChanged
585            self.slist.list.insert(END, hand.getPropValue("name"))
586
587    def onAdd(self):
588        self.pe.body.hideControls()
589        hand = self.config.getHandler(None)
590        self.slist.list.insert(END, hand.getProp("name").getValueText())
591        self.slist.list.select_clear(0, END)
592        self.slist.list.select_set(END)
593        hand.onPropListChanged = self.onPropListChanged
594        self.pe.setPropertyHolder(hand)
595
596    def onDelete(self):
597        items = self.slist.list.curselection()
598        if not len(items):
599            showerror("No Item Selected", "You haven't selected anything to delete")
600        else:
601            name = self.slist.list.get(int(items[0]))
602            log = self.config.handlerIsUsed(name)
603            if log:
604                showerror("Handler in use",
605                          "The handler '%s' is being used by logger '%s'"\
606                          ", so it cannot be deleted." % (
607                          name, log))
608            else:
609                self.config.removeHandler(name)
610                self.slist.list.delete(items)
611                self.pe.body.clear()
612
613    def onUpdate(self):
614        print "handler update"
615
616    def onListChange(self, event):
617        self.pe.body.hideControls()
618        items = self.slist.list.curselection()
619        name = self.slist.list.get(int(items[0]))
620        hand = self.config.getHandler(name)
621        self.pe.setPropertyHolder(hand)
622
623    def onPropListChanged(self, newhand):
624        newhand.onPropListChanged = self.onPropListChanged
625        self.pe.setPropertyHolder(newhand)
626
627class FormatterPanel(Frame):
628    def __init__(self, parent):
629        Frame.__init__(self, parent)
630        self.parent = parent
631        label = Label(self, text="Formatters:")
632        label.grid(row=0, column=0, sticky='w')
633        self.slist = ScrollList(self, height=4, background='white')
634        self.slist.list.bind('<ButtonRelease-1>', self.onListChange)
635        self.slist.grid(row=1, column=0, sticky="nsew")
636        self.adu = ADUPanel(self)
637        self.adu.grid(row=2, column=0, sticky="ew")
638        label = Label(self, text="Properties of selected formatter:")
639        label.grid(row=3, column=0, sticky='w')
640        self.pe = PropertyEditor(self, height=60, borderwidth=1)
641        self.pe.grid(row=4, column=0, sticky='nsew')
642        self.columnconfigure(0, weight=1)
643        self.rowconfigure(1, weight=1)
644        self.rowconfigure(4, weight=1)
645
646    def setConfig(self, config):
647        self.config = config
648        #populate list of formatters
649        flist = config.getFormatters()
650        flist.sort(sortn)
651        self.slist.list.delete(0, END)
652        self.pe.body.clear()
653        for form in flist:
654            self.slist.list.insert(END, form.getPropValue("name"))
655
656    def onAdd(self):
657        self.pe.body.hideControls()
658        fmt = self.config.getFormatter(None)
659        self.slist.list.insert(END, fmt.getProp("name").getValueText())
660        self.slist.list.select_clear(0, END)
661        i = self.slist.list.size()
662        self.slist.list.select_set(i - 1)
663        self.pe.setPropertyHolder(fmt)
664
665    def onDelete(self):
666        self.pe.body.hideControls()
667        items = self.slist.list.curselection()
668        if not len(items):
669            showerror("No Item Selected", "You haven't selected anything to delete")
670        else:
671            name = self.slist.list.get(int(items[0]))
672            h = self.config.formatterIsUsed(name)
673            if h:
674                showerror("Formatter in use",
675                          "The formatter '%s' is being used by handler '%s'"\
676                          ", so it cannot be deleted." % (
677                          name, h))
678            else:
679                self.config.removeFormatter(name)
680                self.slist.list.delete(items)
681                self.pe.body.clear()
682
683    def onUpdate(self):
684        self.pe.body.hideControls()
685
686    def onListChange(self, event):
687        self.pe.body.hideControls()
688        items = self.slist.list.curselection()
689        name = self.slist.list.get(int(items[0]))
690        fmt = self.config.getFormatter(name)
691        self.pe.setPropertyHolder(fmt)
692
693class FilterPanel(Frame):
694    def __init__(self, parent):
695        Frame.__init__(self, parent)
696        self.parent = parent
697        label = Label(self, text="Filters:")
698        label.grid(row=0, column=0, sticky='w')
699        self.slist = ScrollList(self, height=4, background='white')
700        self.slist.list.bind('<ButtonRelease-1>', self.onListChange)
701        self.slist.grid(row=1, column=0, sticky="nsew")
702        self.adu = ADUPanel(self)
703        self.adu.grid(row=2, column=0, sticky="ew")
704        label = Label(self, text="Properties of selected filter:")
705        label.grid(row=3, column=0, sticky='w')
706        self.pe = PropertyEditor(self, height=60, borderwidth=1)
707        self.pe.grid(row=4, column=0, sticky='nsew')
708        self.columnconfigure(0, weight=1)
709        self.rowconfigure(1, weight=1)
710        self.rowconfigure(4, weight=1)
711
712    def setConfig(self, config):
713        self.config = config
714        #populate list of filters
715        flist = config.getFilters()
716        flist.sort(sortn)
717        self.slist.list.delete(0, END)
718        self.pe.body.clear()
719        for filt in flist:
720            self.slist.list.insert(END, filt.getPropValue("name"))
721
722    def onAdd(self):
723        self.pe.body.hideControls()
724        filt = self.config.getFilter(None)
725        self.slist.list.insert(END, filt.getProp("name").getValueText())
726        self.slist.list.select_clear(0, END)
727        i = self.slist.list.size()
728        self.slist.list.select_set(i - 1)
729        self.pe.setPropertyHolder(filt)
730
731    def onDelete(self):
732        self.pe.body.hideControls()
733        items = self.slist.list.curselection()
734        if not len(items):
735            showerror("No Item Selected", "You haven't selected anything to delete")
736        else:
737            name = self.slist.list.get(int(items[0]))
738            h = self.config.filterIsUsed(name)
739            if h:
740                showerror("Filter in use",
741                          "The filter '%s' is being used by '%s'"\
742                          ", so it cannot be deleted." % (
743                          name, h))
744            else:
745                self.config.removeFilter(name)
746                self.slist.list.delete(items)
747                self.pe.body.clear()
748
749    def onUpdate(self):
750        self.pe.body.hideControls()
751
752    def onListChange(self, event):
753        self.pe.body.hideControls()
754        items = self.slist.list.curselection()
755        name = self.slist.list.get(int(items[0]))
756        filt = self.config.getFilter(name)
757        self.pe.setPropertyHolder(filt)
758
759class ConfigPanel(Frame):
760    def __init__(self, parent):
761        Frame.__init__(self, parent)
762        self.parent = parent
763        self.load = Button(self, text="Load...", command=parent.onLoad)
764        self.load.pack(side=LEFT)
765        self.save = Button(self, text="Save", command=parent.onSave)
766        self.save.pack(side=LEFT)
767        self.save = Button(self, text="Save as...", command=parent.onSaveAs)
768        self.save.pack(side=LEFT)
769        self.reset = Button(self, text="Reset", command=parent.onReset)
770        self.reset.pack(side=RIGHT)
771
772class Configurator(Frame):
773    def __init__(self, parent):
774        Frame.__init__(self, parent)
775        self.parent = parent
776        self.llist = LoggerPanel(self)
777        self.llist.grid(row=0, column=0, rowspan=2, sticky='nsew')
778        spacer = Canvas(self, width=2, highlightthickness=0)
779        spacer.grid(row=0, column=1, rowspan=2, sticky='ns')
780        self.hlist = HandlerPanel(self)
781        self.hlist.grid(row=0, column=2, sticky='nsew')
782        self.flist = FormatterPanel(self)
783        self.flist.grid(row=1, column=2, sticky='nsew')
784        self.cfg = ConfigPanel(self)
785        self.cfg.grid(row=2, column=0, columnspan=2, sticky='w')
786        self.filename = None
787
788        self.rowconfigure(0, weight=1)
789        self.columnconfigure(0, weight=1)
790        self.columnconfigure(2, weight=1)
791
792        label = Label(self, text="Copyright (C) 2002 Vinay Sajip. All rights reserved.", foreground='brown')
793        label.grid(row=3, column=0, columnspan=2, sticky='w')
794
795        if len(sys.argv) > 1:
796            fn = sys.argv[1]
797            try:
798                self.loadFile(fn)
799            except Exception, e:
800                print e
801                raise
802        else:
803            self.onReset(0)
804        self.setTitle()
805        self.focus_set()
806
807    def setTitle(self):
808        if self.filename:
809            s = os.path.split(self.filename)[1]
810        else:
811            s = "untitled"
812        self.winfo_toplevel().title("%s - Python Logging Configurator V%s" % (s, __version__))
813
814    def loadFile(self, fn):
815        self.config = LoggingConfig()
816        self.config.read(fn)
817        self.filename = fn
818        self.llist.setConfig(self.config)
819        self.hlist.setConfig(self.config)
820        self.flist.setConfig(self.config)
821        self.setTitle()
822
823    def onLoad(self):
824        fn = askopenfilename(title="Choose configuration file", filetypes=[("Logging configurations", "*.ini"), ("All files", "*.*")])
825        if fn:
826            self.loadFile(fn)
827
828    def onSaveAs(self):
829        if self.filename:
830            fn = os.path.split(self.filename)[1]
831        else:
832            fn = DEFAULT_FILENAME
833        fn = asksaveasfilename(title="Save configuration as", initialfile=fn, filetypes=[("Logging configurations", "*.ini"), ("All files", "*.*")])
834        if fn:
835            self.config.save(fn)
836            self.filename = fn
837            self.setTitle()
838
839    def onSave(self):
840        if not self.filename:
841            self.onSaveAs()
842        else:
843            self.config.save(self.filename)
844
845    def onReset(self, confirm=1):
846        if not confirm:
847            doit = 1
848        else:
849            doit = askyesno("Reset", "Are you sure you want to reset?")
850        if doit:
851            self.config = LoggingConfig()
852            self.llist.setConfig(self.config)
853            self.hlist.setConfig(self.config)
854            self.flist.setConfig(self.config)
855            self.setTitle()
856
857# -- general properties
858
859class NameProperty(Property):
860    def __init__(self, value=None):
861        Property.__init__(self, "name", "Name", value)
862
863class LevelProperty(Property):
864    def __init__(self, value=None):
865        Property.__init__(self, "level", "Level", value)
866
867    def getChoices(self):
868        return LOGGING_LEVELS
869
870# -- formatter properties
871
872class FormatProperty(Property):
873    def __init__(self, value=None):
874        Property.__init__(self, "format", "Format", value)
875
876class DateFormatProperty(Property):
877    def __init__(self, value=None):
878        Property.__init__(self, "datefmt", "Date Format", value)
879
880class FormatterProxy(PropertyHolder):
881    def __init__(self, config, dict):
882        self.config = config
883        PropertyHolder.__init__(self, dict)
884        prop = NameProperty(dict.get("name", ""))
885        self.dict["name"] = prop
886        prop = FormatProperty(dict.get("format", "%(asctime)s %(levelname)s %(message)s"))
887        self.dict["format"] = prop
888        prop = DateFormatProperty(dict.get("datefmt", ""))
889        self.dict["datefmt"] = prop
890        self.propnames = ["name", "format", "datefmt"]
891
892    def isReadonly(self, name):
893        return name == "name"
894
895    def writeConfig(self, file):
896        file.write("[formatter_%s]\n" % self.getPropValue("name"))
897        file.write("format=%s\n" % self.getPropValue("format"))
898        file.write("datefmt=%s\n\n" % self.getPropValue("datefmt"))
899
900# -- filter properties
901
902class LoggerNameProperty(Property):
903    def __init__(self, value=None):
904        Property.__init__(self, "lname", "Name", value)
905
906class FilterProxy(PropertyHolder):
907    def __init__(self, config, dict):
908        self.config = config
909        PropertyHolder.__init__(self, dict)
910        prop = NameProperty(dict.get("name", ""))
911        self.dict["name"] = prop
912        prop = LoggerNameProperty(dict.get("lname", ""))
913        self.dict["lname"] = prop
914        self.propnames = ["name", "lname"]
915
916    def isReadonly(self, name):
917        return name == "name"
918
919    def writeConfig(self, file):
920        file.write("[filter_%s]\n" % self.getPropValue("name"))
921        file.write("lname=%s\n" % self.getPropValue("lname"))
922
923# -- handler properties and proxies
924
925class HandlerTypeProperty(Property):
926    def __init__(self, value=None):
927        Property.__init__(self, "class", "Type", value)
928
929    def getChoices(self):
930        return HANDLER_TYPES
931
932class FormatterProperty(Property):
933    def __init__(self, config, value=None):
934        self.config = config
935        Property.__init__(self, "formatter", "Formatter", value)
936
937    def getChoices(self):
938        return self.config.getFormatterChoice()
939
940class HandlerProxy(PropertyHolder):
941    def __init__(self, config, dict):
942        self.config = config
943        PropertyHolder.__init__(self, dict)
944        prop = NameProperty(dict.get("name", ""))
945        self.dict["name"] = prop
946        prop = HandlerTypeProperty(dict.get("class", "StreamHandlerProxy"))
947        self.dict["class"] = prop
948        prop = FormatterProperty(self.config, dict.get("formatter", ""))
949        self.dict["formatter"] = prop
950        prop = LevelProperty(dict.get("level", "NOTSET"))
951        self.dict["level"] = prop
952        self.propnames = ["name", "class", "level", "formatter"]
953
954    def isReadonly(self, name):
955        return (name == "name")
956
957    def setPropValue(self, name, value):
958        PropertyHolder.setPropValue(self, name, value)
959        if (name == "class"):   #morph type of handler
960            #print "try morph -> %s" % value
961            try:
962                klass = eval(value)
963            except Exception, e:
964                print e
965                klass = None
966            if klass:
967                n = self.getPropValue("name")
968                d = {
969                        "name": n,
970                        "class": value,
971                        "formatter": self.getPropValue("formatter"),
972                        "level": self.getPropValue("level"),
973                        }
974                newhand = klass(self.config, d)
975                self.config.handlers[n] = newhand   #FIXME encapsulation
976                if self.onPropListChanged:
977                    self.onPropListChanged(newhand)
978
979    def writeConfig(self, file):
980        file.write("[handler_%s]\n" % self.getPropValue("name"))
981        s = self.getProp("class").getValueText()
982        if not s in ["StreamHandler", "FileHandler"]:
983            s = "handlers." + s
984        file.write("class=%s\n" % s)
985        file.write("level=%s\n" % self.getPropValue("level"))
986        file.write("formatter=%s\n" % self.getPropValue("formatter"))
987
988class StreamProperty(Property):
989    def __init__(self, config, value=None):
990        self.config = config
991        Property.__init__(self, "stream", "Stream", value)
992
993    def getChoices(self):
994        return OUTPUT_STREAMS
995
996class StreamHandlerProxy(HandlerProxy):
997    def __init__(self, config, dict):
998        HandlerProxy.__init__(self, config, dict)
999        prop = StreamProperty(self.config, dict.get("stream", "sys.stderr"))
1000        self.dict["stream"] = prop
1001        self.propnames.append("stream")
1002
1003    def writeConfig(self, file):
1004        HandlerProxy.writeConfig(self, file)
1005        file.write("stream=%s\n" % self.getPropValue("stream"))
1006        file.write("args=(%s,)\n\n" % self.getPropValue("stream"))
1007
1008    def readConfig(self, sectname):
1009        prop = StreamProperty(self.config, self.config.get(sectname, "stream"))
1010        self.dict["stream"] = prop
1011        self.propnames.append("stream")
1012
1013class FilenameProperty(Property):
1014    def __init__(self, value=None):
1015        Property.__init__(self, "filename", "File name", value)
1016
1017class ModeProperty(Property):
1018    def __init__(self, value=None):
1019        Property.__init__(self, "mode", "Mode", value)
1020
1021    def getChoices(self):
1022        return FILE_MODES
1023
1024class MaxSizeProperty(Property):
1025    def __init__(self, value=None):
1026        Property.__init__(self, "maxsize", "Maximum Size (bytes)", value)
1027
1028class BackupCountProperty(Property):
1029    def __init__(self, value=None):
1030        Property.__init__(self, "backcount", "Backup Count", value)
1031
1032class FileHandlerProxy(HandlerProxy):
1033    def __init__(self, config, dict):
1034        HandlerProxy.__init__(self, config, dict)
1035        prop = FilenameProperty(dict.get("filename", "python.log"))
1036        self.dict["filename"] = prop
1037        prop = ModeProperty(dict.get("mode", "a"))
1038        self.dict["mode"] = prop
1039        self.propnames.extend(["filename", "mode"])
1040
1041    def writeConfig(self, file):
1042        HandlerProxy.writeConfig(self, file)
1043        fn = self.getPropValue("filename")
1044        file.write("filename=%s\n" % fn)
1045        mode = self.getPropValue("mode")
1046        file.write("mode=%s\n" % mode)
1047        file.write("args=('%s', '%s')\n\n" % (fn, mode))
1048
1049    def readConfig(self, sectname):
1050        prop = FilenameProperty(self.config.get(sectname, "filename"))
1051        self.dict["filename"] = prop
1052        prop = ModeProperty(self.config.get(sectname, "mode"))
1053        self.dict["mode"] = prop
1054        self.propnames.extend(["filename", "mode"])
1055
1056class RotatingFileHandlerProxy(FileHandlerProxy):
1057    def __init__(self, config, dict):
1058        FileHandlerProxy.__init__(self, config, dict)
1059        prop = MaxSizeProperty(dict.get("maxsize", "0"))
1060        self.dict["maxsize"] = prop
1061        prop = BackupCountProperty(dict.get("backcount", "1"))
1062        self.dict["backcount"] = prop
1063        self.propnames.extend(["maxsize", "backcount"])
1064
1065    def writeConfig(self, file):
1066        HandlerProxy.writeConfig(self, file)
1067        fn = self.getPropValue("filename")
1068        file.write("filename=%s\n" % fn)
1069        mode = self.getPropValue("mode")
1070        file.write("mode=%s\n" % mode)
1071        ms = self.getPropValue("maxsize")
1072        file.write("maxsize=%s\n" % ms)
1073        bc = self.getPropValue("backcount")
1074        file.write("backcount=%s\n" % bc)
1075        file.write("args=('%s', '%s', %s, %s)\n\n" % (fn, mode, ms, bc))
1076
1077    def readConfig(self, sectname):
1078        FileHandlerProxy.readConfig(self, sectname)
1079        prop = MaxSizeProperty(self.config.get(sectname, "maxsize"))
1080        self.dict["maxsize"] = prop
1081        prop = BackupCountProperty(self.config.get(sectname, "backcount"))
1082        self.dict["backcount"] = prop
1083        self.propnames.extend(["maxsize", "backcount"])
1084
1085
1086class HostProperty(Property):
1087    def __init__(self, value=None):
1088        Property.__init__(self, "host", "Host", value)
1089
1090class PortProperty(Property):
1091    def __init__(self, value=None):
1092        Property.__init__(self, "port", "Port", value)
1093
1094class SocketHandlerProxy(HandlerProxy):
1095    def __init__(self, config, dict):
1096        HandlerProxy.__init__(self, config, dict)
1097        prop = HostProperty(dict.get("host", "localhost"))
1098        self.dict["host"] = prop
1099        prop = PortProperty(dict.get("port", "handlers.DEFAULT_TCP_LOGGING_PORT"))
1100        self.dict["port"] = prop
1101        self.propnames.extend(["host", "port"])
1102
1103    def writeConfig(self, file):
1104        HandlerProxy.writeConfig(self, file)
1105        host = self.getPropValue("host")
1106        file.write("host=%s\n" % host)
1107        port = self.getPropValue("port")
1108        file.write("port=%s\n" % port)
1109        file.write("args=('%s', %s)\n\n" % (host, port))
1110
1111    def readConfig(self, sectname):
1112        prop = HostProperty(self.config.get(sectname, "host"))
1113        self.dict["host"] = prop
1114        prop = PortProperty(self.config.get(sectname, "port"))
1115        self.dict["port"] = prop
1116        self.propnames.extend(["host", "port"])
1117
1118class DatagramHandlerProxy(HandlerProxy):
1119    def __init__(self, config, dict):
1120        HandlerProxy.__init__(self, config, dict)
1121        prop = HostProperty(dict.get("host", "localhost"))
1122        self.dict["host"] = prop
1123        prop = PortProperty(dict.get("port", "handlers.DEFAULT_UDP_LOGGING_PORT"))
1124        self.dict["port"] = prop
1125        self.propnames.extend(["host", "port"])
1126
1127    def writeConfig(self, file):
1128        HandlerProxy.writeConfig(self, file)
1129        host = self.getPropValue("host")
1130        file.write("host=%s\n" % host)
1131        port = self.getPropValue("port")
1132        file.write("port=%s\n" % port)
1133        file.write("args=('%s', %s)\n\n" % (host, port))
1134
1135    def readConfig(self, sectname):
1136        prop = HostProperty(self.config.get(sectname, "host"))
1137        self.dict["host"] = prop
1138        prop = PortProperty(self.config.get(sectname, "port"))
1139        self.dict["port"] = prop
1140        self.propnames.extend(["host", "port"])
1141
1142class URLProperty(Property):
1143    def __init__(self, value=None):
1144        Property.__init__(self, "url", "URL", value)
1145
1146class MethodProperty(Property):
1147    def __init__(self, value=None):
1148        Property.__init__(self, "method", "HTTP Method", value)
1149
1150    def getChoices(self):
1151        return HTTP_METHODS
1152
1153class HTTPHandlerProxy(HandlerProxy):
1154    def __init__(self, config, dict):
1155        HandlerProxy.__init__(self, config, dict)
1156        prop = HostProperty(dict.get("host", "localhost"))
1157        self.dict["host"] = prop
1158        prop = PortProperty(dict.get("port", "80"))
1159        self.dict["port"] = prop
1160        prop = URLProperty(dict.get("url", ""))
1161        self.dict["url"] = prop
1162        prop = MethodProperty(dict.get("method", "GET"))
1163        self.dict["method"] = prop
1164        self.propnames.extend(["host", "port", "url", "method"])
1165
1166    def writeConfig(self, file):
1167        HandlerProxy.writeConfig(self, file)
1168        host = self.getPropValue("host")
1169        file.write("host=%s\n" % host)
1170        port = self.getPropValue("port")
1171        file.write("port=%s\n" % port)
1172        url = self.getPropValue("url")
1173        file.write("url=%s\n" % url)
1174        meth = self.getPropValue("method")
1175        file.write("method=%s\n" % meth)
1176        file.write("args=('%s:%s', '%s', '%s')\n\n" % (host, port, url, meth))
1177
1178    def readConfig(self, sectname):
1179        prop = HostProperty(self.config.get(sectname, "host"))
1180        self.dict["host"] = prop
1181        prop = PortProperty(self.config.get(sectname, "port"))
1182        self.dict["port"] = prop
1183        prop = URLProperty(self.config.get(sectname, "url"))
1184        self.dict["url"] = prop
1185        prop = MethodProperty(self.config.get(sectname, "method"))
1186        self.dict["method"] = prop
1187        self.propnames.extend(["host", "port", "url", "method"])
1188
1189class SOAPHandlerProxy(HandlerProxy):
1190    def __init__(self, config, dict):
1191        HandlerProxy.__init__(self, config, dict)
1192        prop = HostProperty(dict.get("host", "localhost"))
1193        self.dict["host"] = prop
1194        prop = PortProperty(dict.get("port", "80"))
1195        self.dict["port"] = prop
1196        prop = URLProperty(dict.get("url", ""))
1197        self.dict["url"] = prop
1198        self.propnames.extend(["host", "port", "url"])
1199
1200    def writeConfig(self, file):
1201        HandlerProxy.writeConfig(self, file)
1202        host = self.getPropValue("host")
1203        file.write("host=%s\n" % host)
1204        port = self.getPropValue("port")
1205        file.write("port=%s\n" % port)
1206        url = self.getPropValue("url")
1207        file.write("url=%s\n" % url)
1208        file.write("args=('%s:%s', '%s')\n\n" % (host, port, url))
1209
1210    def readConfig(self, sectname):
1211        prop = HostProperty(self.config.get(sectname, "host"))
1212        self.dict["host"] = prop
1213        prop = PortProperty(self.config.get(sectname, "port"))
1214        self.dict["port"] = prop
1215        prop = URLProperty(self.config.get(sectname, "url"))
1216        self.dict["url"] = prop
1217        self.propnames.extend(["host", "port", "url"])
1218
1219class FacilityProperty(Property):
1220    def __init__(self, value=None):
1221        Property.__init__(self, "facility", "Facility", value)
1222
1223    def getChoices(self):
1224        return SYSLOG_FACILITIES
1225
1226class SysLogHandlerProxy(HandlerProxy):
1227    def __init__(self, config, dict):
1228        HandlerProxy.__init__(self, config, dict)
1229        prop = HostProperty(dict.get("host", "localhost"))
1230        self.dict["host"] = prop
1231        prop = PortProperty(dict.get("port", "handlers.SYSLOG_UDP_PORT"))
1232        self.dict["port"] = prop
1233        prop = FacilityProperty(dict.get("facility", "handlers.SysLogHandler.LOG_USER"))
1234        self.dict["facility"] = prop
1235        self.propnames.extend(["host", "port", "facility"])
1236
1237    def writeConfig(self, file):
1238        HandlerProxy.writeConfig(self, file)
1239        host = self.getPropValue("host")
1240        file.write("host=%s\n" % host)
1241        port = self.getPropValue("port")
1242        file.write("port=%s\n" % port)
1243        fac = self.getPropValue("facility")
1244        file.write("facility=%s\n" % fac)
1245        file.write("args=(('%s', %s), handlers.SysLogHandler.%s)\n\n" % (host, port, fac))
1246
1247    def readConfig(self, sectname):
1248        prop = HostProperty(self.config.get(sectname, "host"))
1249        self.dict["host"] = prop
1250        prop = PortProperty(self.config.get(sectname, "port"))
1251        self.dict["port"] = prop
1252        prop = FacilityProperty(self.config.get(sectname, "facility"))
1253        self.dict["facility"] = prop
1254        self.propnames.extend(["host", "port", "facility"])
1255
1256class FromProperty(Property):
1257    def __init__(self, value=None):
1258        Property.__init__(self, "from", "From", value)
1259
1260class ToProperty(Property):
1261    def __init__(self, value=None):
1262        Property.__init__(self, "to", "To", value)
1263
1264class SubjectProperty(Property):
1265    def __init__(self, value=None):
1266        Property.__init__(self, "subject", "Subject", value)
1267
1268class SMTPHandlerProxy(HandlerProxy):
1269    def __init__(self, config, dict):
1270        HandlerProxy.__init__(self, config, dict)
1271        prop = HostProperty(dict.get("host", "localhost"))
1272        self.dict["host"] = prop
1273        prop = PortProperty(dict.get("port", "25"))
1274        self.dict["port"] = prop
1275        prop = FromProperty(dict.get("from", ""))
1276        self.dict["from"] = prop
1277        prop = ToProperty(dict.get("to", ""))
1278        self.dict["to"] = prop
1279        prop = SubjectProperty(dict.get("subject", ""))
1280        self.dict["subject"] = prop
1281        self.propnames.extend(["host", "port", "from", "to", "subject"])
1282
1283    def writeConfig(self, file):
1284        HandlerProxy.writeConfig(self, file)
1285        host = self.getPropValue("host")
1286        file.write("host=%s\n" % host)
1287        port = self.getPropValue("port")
1288        file.write("port=%s\n" % port)
1289        frm = self.getPropValue("from")
1290        file.write("from=%s\n" % frm)
1291        to = self.getPropValue("to")
1292        file.write("to=%s\n" % to)
1293        subj = self.getPropValue("subject")
1294        file.write("subject=%s\n" % subj)
1295        to = string.split(to, ",")
1296        file.write("args=('%s', '%s', %s, '%s')\n\n" % (host, frm, repr(to), subj))
1297
1298    def readConfig(self, sectname):
1299        prop = HostProperty(self.config.get(sectname, "host"))
1300        self.dict["host"] = prop
1301        prop = PortProperty(self.config.get(sectname, "port"))
1302        self.dict["port"] = prop
1303        prop = FromProperty(self.config.get(sectname, "from"))
1304        self.dict["from"] = prop
1305        prop = ToProperty(self.config.get(sectname, "to"))
1306        self.dict["to"] = prop
1307        prop = SubjectProperty(self.config.get(sectname, "subject"))
1308        self.dict["subject"] = prop
1309        self.propnames.extend(["host", "port", "from", "to", "subject"])
1310
1311class CapacityProperty(Property):
1312    def __init__(self, value=None):
1313        Property.__init__(self, "capacity", "Capacity", value)
1314
1315class FlushLevelProperty(LevelProperty):
1316    def __init__(self, value=None):
1317        Property.__init__(self, "flushlevel", "Flush Level", value)
1318
1319class TargetProperty(Property):
1320    def __init__(self, config, value=None):
1321        self.config = config
1322        Property.__init__(self, "target", "Target", value)
1323
1324    def getChoices(self):
1325        handlers = self.config.getHandlerChoice()
1326        nm = self.dict["name"].getValueText()
1327        #can't be own target...
1328        return filter(lambda x,nm=nm: x[0] != nm, handlers)
1329
1330class MemoryHandlerProxy(HandlerProxy):
1331    def __init__(self, config, dict):
1332        HandlerProxy.__init__(self, config, dict)
1333        prop = CapacityProperty(dict.get("capacity", "10"))
1334        self.dict["capacity"] = prop
1335        prop = FlushLevelProperty(dict.get("flushlevel", "ERROR"))
1336        self.dict["flushlevel"] = prop
1337        prop = TargetProperty(config, dict.get("target", ""))
1338        prop.dict = self.dict
1339        self.dict["target"] = prop
1340        self.propnames.extend(["capacity", "flushlevel", "target"])
1341
1342    def writeConfig(self, file):
1343        HandlerProxy.writeConfig(self, file)
1344        cap = self.getPropValue("capacity")
1345        file.write("capacity=%s\n" % cap)
1346        flvl = self.getPropValue("flushlevel")
1347        file.write("flushlevel=%s\n" % flvl)
1348        file.write("target=%s\n" % self.getPropValue("target"))
1349        file.write("args=(%s, %s)\n\n" % (cap, flvl))
1350
1351    def readConfig(self, sectname):
1352        prop = CapacityProperty(self.config.get(sectname, "capacity"))
1353        self.dict["capacity"] = prop
1354        prop = FlushLevelProperty(self.config.get(sectname, "flushlevel"))
1355        self.dict["flushlevel"] = prop
1356        prop = TargetProperty(self.config, self.config.get(sectname, "target"))
1357        prop.dict = self.dict
1358        self.dict["target"] = prop
1359        self.propnames.extend(["capacity", "flushlevel", "target"])
1360
1361class AppNameProperty(Property):
1362    def __init__(self, value=None):
1363        Property.__init__(self, "appname", "Application Name", value)
1364
1365class DLLNameProperty(Property):
1366    def __init__(self, value=None):
1367        Property.__init__(self, "dllname", "Message DLL name", value)
1368
1369class LogTypeProperty(Property):
1370    def __init__(self, value=None):
1371        Property.__init__(self, "logtype", "Log Type", value)
1372
1373    def getChoices(self):
1374        return LOG_TYPES
1375
1376class NTEventLogHandlerProxy(HandlerProxy):
1377    def __init__(self, config, dict):
1378        HandlerProxy.__init__(self, config, dict)
1379        prop = AppNameProperty(dict.get("appname", "Python Application"))
1380        self.dict["appname"] = prop
1381        prop = DLLNameProperty(dict.get("dllname", ""))
1382        self.dict["dllname"] = prop
1383        prop = LogTypeProperty(dict.get("logtype", "Application"))
1384        self.dict["logtype"] = prop
1385        self.propnames.extend(["appname", "dllname", "logtype"])
1386
1387    def writeConfig(self, file):
1388        HandlerProxy.writeConfig(self, file)
1389        app = self.getPropValue("appname")
1390        file.write("appname=%s\n" % app)
1391        dll = self.getPropValue("dllname")
1392        file.write("dllname=%s\n" % dll)
1393        ltype = self.getPropValue("logtype")
1394        file.write("logtype=%s\n" % ltype)
1395        file.write("args=('%s', '%s', '%s')\n\n" % (app, dll, ltype))
1396
1397    def readConfig(self, sectname):
1398        prop = AppNameProperty(self.config.get(sectname, "appname"))
1399        self.dict["appname"] = prop
1400        prop = DLLNameProperty(self.config.get(sectname, "dllname"))
1401        self.dict["dllname"] = prop
1402        prop = LogTypeProperty(self.config.get(sectname, "logtype"))
1403        self.dict["logtype"] = prop
1404        self.propnames.extend(["appname", "dllname", "logtype"])
1405
1406# -- logger properties and proxies
1407
1408class ChannelProperty(Property):
1409    def __init__(self, value=None):
1410        Property.__init__(self, "channel", "Name", value)
1411
1412class HandlerProperty(Property):
1413    def __init__(self, config, value=None):
1414        self.config = config
1415        Property.__init__(self, "handler", "Handlers", value)
1416
1417    def getChoices(self):
1418        return self.config.getHandlerChoice()
1419
1420class FilterProperty(Property):
1421    def __init__(self, config, value=None):
1422        self.config = config
1423        Property.__init__(self, "filter", "Filters", value)
1424
1425    def getChoices(self):
1426        return self.config.getFilterChoice()
1427
1428class ParentProperty(Property):
1429    def __init__(self, config, value=None):
1430        self.config = config
1431        Property.__init__(self, "parent", "Parent", value)
1432
1433    def getChoices(self):
1434        loggers = self.config.getLoggerChoice()
1435        nm = self.dict["name"].getValueText()
1436        #can't be own parent...
1437        return filter(lambda x,nm=nm: x[0] != nm, loggers)
1438
1439    def getValueText(self):
1440        if self.dict.has_key("root"):
1441            return ""
1442        pn = Property.getValueText(self)
1443        rv = ""
1444        while pn != "(root)":
1445            parent = self.config.getLogger(pn)
1446            rv = parent.getPropValue("channel") + "." + rv
1447            pn = parent.getProp("parent").value
1448        return rv[:-1]
1449
1450class PropagateProperty(Property):
1451    def __init__(self, config, value=None):
1452        self.config = config
1453        Property.__init__(self, "propagate", "Propagate", value)
1454
1455    def getChoices(self):
1456        return BOOLEAN_VALUES
1457
1458class LoggerProxy(PropertyHolder):
1459    def __init__(self, config, dict):
1460        self.config = config
1461        PropertyHolder.__init__(self, dict)
1462        prop = ChannelProperty(dict.get("channel", ""))
1463        self.dict["channel"] = prop
1464        prop = NameProperty(dict.get("name", ""))
1465        self.dict["name"] = prop
1466        prop = HandlerProperty(config, dict.get("handler", []))
1467        self.dict["handler"] = prop
1468        prop = LevelProperty(dict.get("level", "NOTSET"))
1469        self.dict["level"] = prop
1470        prop = PropagateProperty(self.config, dict.get("propagate", "1"))
1471        self.dict["propagate"] = prop
1472        prop = ParentProperty(config, dict.get("parent", "(root)"))
1473        prop.dict = self.dict
1474        self.dict["parent"] = prop
1475        self.propnames = ["parent", "channel", "level", "propagate", "handler"]
1476        self.onChannelChanged = None
1477        self.deleted = 0
1478
1479    def isReadonly(self, name):
1480        return (name in ["channel", "parent", "propagate"]) and self.dict.has_key("root")
1481
1482    def getQualifiedName(self):
1483        pt = self.getProp("parent").getValueText()
1484        nm = self.getPropValue("channel")
1485        if pt:
1486            pn =  pt + "." + nm
1487        else:
1488            pn = nm
1489            if pn == "":
1490                pn = "(root)"
1491        return pn
1492
1493    def setPropValue(self, name, value):
1494        PropertyHolder.setPropValue(self, name, value)
1495        if (name == "channel"):
1496            nm = self.getPropValue("name")
1497            if self.onChannelChanged:
1498                self.onChannelChanged(nm, value)
1499
1500    def writeConfig(self, file):
1501        if self.dict.has_key("root"):
1502            name = "root"
1503        else:
1504            name = self.getPropValue("name")
1505        file.write("[logger_%s]\n" % name)
1506        file.write("level=%s\n" % self.getPropValue("level"))
1507        file.write("propagate=%s\n" % self.getPropValue("propagate"))
1508        file.write("channel=%s\n" % self.getPropValue("channel"))
1509        file.write("parent=%s\n" % self.getPropValue("parent"))
1510        file.write("qualname=%s\n" % self.getQualifiedName())
1511        file.write("handlers=%s\n\n" %  string.join(self.getPropValue("handler"), ","))
1512
1513# -- logging configuration
1514
1515class LoggingConfig(ConfigParser.ConfigParser):
1516    def __init__(self, defaults=None):
1517        ConfigParser.ConfigParser.__init__(self, defaults)
1518        self.formatters = {}
1519        self.handlers = {}
1520        self.loggers = {}
1521#        self.filters = {}
1522        #create root logger
1523        d = { "name": "(root)", "root": 1, "parent": "" }
1524        self.loggers["(root)"] = LoggerProxy(self, d)
1525
1526    def read(self, fn):
1527        ConfigParser.ConfigParser.read(self, fn)
1528        llist = self.get("loggers", "keys")
1529        llist = string.split(llist, ",")
1530        llist.remove("root")
1531        sectname = "logger_root"
1532        log = self.loggers["(root)"]
1533        log.setPropValue("level", self.get(sectname, "level"))
1534        hlist = self.get(sectname, "handlers")
1535        hlist = string.split(hlist, ",")
1536        log.setPropValue("handler", hlist)
1537        for log in llist:
1538            sectname = "logger_%s" % log
1539            hlist = self.get(sectname, "handlers")
1540            hlist = string.split(hlist, ",")
1541            d = {
1542                "name"      : log,
1543                "level"     : self.get(sectname, "level"),
1544                "channel"   : self.get(sectname, "channel"),
1545                "parent"    : self.get(sectname, "parent"),
1546                "propagate" : self.get(sectname, "propagate"),
1547                "handler"   : hlist,
1548            }
1549            self.loggers[log] = LoggerProxy(self, d)
1550        hlist = self.get("handlers", "keys")
1551        if len(hlist):
1552            hlist = string.split(hlist, ",")
1553            for hand in hlist:
1554                sectname = "handler_%s" % hand
1555                klass = self.get(sectname, "class")
1556                if klass[:9] == "handlers.":
1557                    klass = klass[9:]
1558                d = {
1559                    "name"      : hand,
1560                    "class"     : "%sProxy" % klass,
1561                    "level"     : self.get(sectname, "level"),
1562                    "formatter" : self.get(sectname, "formatter"),
1563                }
1564                hobj = HandlerProxy(self, d)
1565                hobj.__class__ = eval("%sProxy" % klass)
1566                hobj.readConfig(sectname)
1567                self.handlers[hand] = hobj
1568
1569        flist = self.get("formatters", "keys")
1570        if len(flist):
1571            flist = string.split(flist, ",")
1572            for form in flist:
1573                sectname = "formatter_%s" % form
1574                d = {
1575                    "name"   : form,
1576                    "format" : self.get(sectname, "format", 1),
1577                    "datefmt" : self.get(sectname, "datefmt", 1),
1578                }
1579                self.formatters[form] = FormatterProxy(self, d)
1580
1581#        flist = self.get("filters", "keys")
1582#        if len(flist):
1583#            flist = string.split(flist, ",")
1584#            for filt in flist:
1585#                sectname = "filter_%s" % filt
1586#                d = {
1587#                    "name"   : filt,
1588#                    "lname"  : self.get(sectname, "lname", 1),
1589#                }
1590#                self.filters[filt] = FilterProxy(self, d)
1591
1592    def getFormatter(self, name):
1593        if name:
1594            fmt = self.formatters[name]
1595        else:
1596            n = len(self.formatters.keys()) + 1
1597            name = "form%02d" % n
1598            fmt = FormatterProxy(self, {"name": name})
1599            self.formatters[name] = fmt
1600        return fmt
1601
1602    def getHandler(self, name):
1603        if name:
1604            hand = self.handlers[name]
1605        else:
1606            n = len(self.handlers.keys()) + 1
1607            name = "hand%02d" % n
1608            hand = StreamHandlerProxy(self, {"name": name})
1609            self.handlers[name] = hand
1610        return hand
1611
1612    def getLogger(self, name):
1613        if name:
1614            log = self.loggers[name]
1615        else:
1616            n = len(self.loggers.keys()) + 1
1617            name = "log%02d" % n
1618            log = LoggerProxy(self, {"name": name, "channel": name})
1619            self.loggers[name] = log
1620        return log
1621
1622    def getFormatterChoice(self):
1623        values = []
1624        keys = self.formatters.keys()
1625        keys.sort()
1626        for f in keys:
1627            values.append((f, f))
1628        return tuple(values)
1629
1630    def getHandlerChoice(self):
1631        values = []
1632        keys = self.handlers.keys()
1633        keys.sort()
1634        for f in keys:
1635            values.append((f, f))
1636        return tuple(values)
1637
1638    def getFilterChoice(self):
1639        values = []
1640        keys = self.filters.keys()
1641        keys.sort()
1642        for f in keys:
1643            values.append((f, f))
1644        return tuple(values)
1645
1646    def getLoggerChoice(self):
1647        values = []
1648        keys = self.loggers.keys()
1649        keys.sort()
1650        for f in keys:
1651            values.append((f, f))
1652        return tuple(values)
1653
1654    def getLoggers(self):
1655        return self.loggers.values()
1656
1657    def getHandlers(self):
1658        return self.handlers.values()
1659
1660    def getFormatters(self):
1661        return self.formatters.values()
1662
1663    def formatterIsUsed(self, name):
1664        rv = None
1665        for h in self.handlers.keys():
1666            if self.handlers[h].getPropValue("formatter") == name:
1667                rv = h
1668                break
1669        return rv
1670
1671    def handlerIsUsed(self, name):
1672        rv = None
1673        for log in self.loggers.keys():
1674            if name in self.loggers[log].getPropValue("handler"):
1675                rv = log
1676                break
1677        return rv
1678
1679    def removeFormatter(self, name):
1680        del self.formatters[name]
1681
1682    def removeHandler(self, name):
1683        del self.handlers[name]
1684
1685    def removeLogger(self, name):
1686        del self.loggers[name]
1687
1688    def save(self, fn):
1689        #needed because 1.5.2 ConfigParser should be supported
1690        file = open(fn, "w")
1691        #Write out the keys
1692        loggers = self.loggers.keys()
1693        loggers.remove("(root)")
1694        loggers = filter(lambda x, d=self.loggers: not d[x].deleted, loggers)
1695        loggers.sort()
1696        list = ["root"]
1697        list.extend(loggers)
1698        file.write("[loggers]\nkeys=%s\n\n" % string.join(list, ","))
1699        handlers = self.handlers.keys()
1700        handlers.sort()
1701        file.write("[handlers]\nkeys=%s\n\n" % string.join(handlers, ","))
1702        formatters = self.formatters.keys()
1703        formatters.sort()
1704        file.write("[formatters]\nkeys=%s\n\n" % string.join(formatters, ","))
1705        #write out the root logger properties
1706        log = self.loggers["(root)"]
1707        log.writeConfig(file)
1708        #write out other logger properties
1709        for log in loggers:
1710            log = self.loggers[log]
1711            log.writeConfig(file)
1712        #write out handler properties
1713        for hand in handlers:
1714            hand = self.handlers[hand]
1715            hand.writeConfig(file)
1716        #write out formatter properties
1717        for form in formatters:
1718            form = self.formatters[form]
1719            form.writeConfig(file)
1720        file.close()
1721
1722root = None
1723
1724def onClose():
1725    if _popup:
1726        _popup.withdraw()
1727    root.destroy()
1728
1729def main():
1730    global root
1731    root=Tk()
1732    cfg = Configurator(root)
1733    cfg.pack(side=LEFT, fill=BOTH, expand=1)
1734    root.protocol("WM_DELETE_WINDOW", onClose)
1735    root.mainloop()
1736
1737if __name__ == "__main__":
1738    main()
Note: See TracBrowser for help on using the repository browser.