Ajout d'une méthode pour supprimer les fichiers de log vides.
[minwii.git] / src / minwii / logapp.py
1 # -*- coding: utf-8 -*-
2 """
3 Interface graphique pour l'analyse des fichiers de log minwii.
4
5 $Id$
6 $URL$
7 """
8
9 from Tkinter import *
10 import tkFileDialog
11 from glob import glob
12 from os.path import join as pjoin
13 from os.path import basename
14 from os.path import getsize
15 from loganalyse import LogFileAnalyser
16 from pprint import pprint
17
18 class Application(Frame) :
19 def __init__(self, master=None) :
20 Frame.__init__(self, master)
21 self.configureStretching()
22 self.createWidgets()
23 self.logDir = ''
24 self.logFiles = []
25 self.resultsFrame = None
26
27 def configureStretching(self) :
28 top=self.winfo_toplevel()
29 top.rowconfigure(0, weight=1)
30 top.columnconfigure(0, weight=1)
31
32 self.grid(sticky=N+S+E+W, padx=10, pady=10)
33 self.rowconfigure(0, weight=1)
34 self.columnconfigure(0, weight=1)
35
36 def createWidgets(self) :
37 # zone d'affichage des données'
38 self.dataFrame = df = Frame(self)
39 #df.grid(sticky=NW)
40
41 self.identFrame = Identification(df)
42 self.identFrame.grid(sticky=NW)
43 self.nav = Navbar(df, incCallback=self.loadLogFile, decCallback=self.loadLogFile)
44 # self.nav.grid()
45
46
47 # barre de boutons
48 self.btnFrame = bf = Frame(self)
49 bf.grid(row=1, column=0, sticky=W+S+E)
50 bf.rowconfigure(0, weight=1)
51 bf.columnconfigure(0, weight=1)
52 bf.columnconfigure(1, weight=1)
53
54
55 self.chooseLogDir = Button(bf, text="Parcourir…", command=self.openFileDialog)
56 self.chooseLogDir.grid(row=0, column=0, sticky=W)
57
58 self.nav = Navbar(bf, incCallback=self.loadLogFile, decCallback=self.loadLogFile)
59 #self.nav.grid(row=0, column=1)
60
61 self.quitButton = Button(bf, text='Terminer', command=self.quit)
62 self.quitButton.grid(row=0, column=2, sticky=E)
63
64 def openFileDialog(self) :
65 self.logDir = tkFileDialog.askdirectory()
66 if self.logDir :
67 self.logFiles = glob(pjoin(self.logDir, '*.log'))
68 self._cleanupJunkFiles()
69 self.logFiles.sort()
70 self.dataFrame.grid(row=0, column=0, sticky=NW)
71 self.nav.setSize(len(self.logFiles))
72 self.nav.grid(row=0, column=1)
73 self.loadLogFile(self.nav)
74
75 def _cleanupJunkFiles(self) :
76 files = []
77 while self.logFiles :
78 f = self.logFiles.pop()
79 if not getsize(f) :
80 continue
81 # TODO : vérifier qu'il existe des événements
82 else :
83 files.append(f)
84
85 self.logFiles = files
86
87
88 def loadLogFile(self, nav) :
89 index = nav.index - 1
90 filepath = self.logFiles[index]
91 filename = basename(filepath)
92 self.identFrame.setFileName(filename)
93 if self.resultsFrame :
94 self.resultsFrame.destroy()
95 self.resultsFrame = ResultsFrame(self.dataFrame, filepath)
96 self.resultsFrame.layResults()
97 self.resultsFrame.grid()
98
99
100 class Navbar(Frame) :
101 def __init__(self, master=None, size=1, incCallback=None, decCallback=None) :
102 Frame.__init__(self, master)
103 self.caption = StringVar()
104 self.createWidgets()
105 self.setSize(size)
106 self.incCallback = incCallback if incCallback else lambda x : None
107 self.decCallback = decCallback if decCallback else lambda x : None
108 self.caption.set('%d / %d' % (self.index, self.to))
109
110 def createWidgets(self) :
111 self.backBtn = Button(self,
112 text='◀',
113 command = self.dec
114 )
115 self.backBtn.grid(row=0, column=0)
116
117 self.lbl = Label(self, textvariable=self.caption)
118 self.lbl.grid(row=0, column=1)
119
120 self.nextBtn = Button(self,
121 text='▶',
122 command = self.inc)
123 self.nextBtn.grid(row=0, column=2)
124
125 def refreshStates(self) :
126 if self.index == self.from_ :
127 self.backBtn.configure(state=DISABLED)
128 else :
129 self.backBtn.configure(state=NORMAL)
130
131 if self.index < self.to :
132 self.nextBtn.configure(state=NORMAL)
133 else :
134 self.nextBtn.configure(state=DISABLED)
135
136 self.caption.set('%d / %d' % (self.index, self.to))
137
138
139 def dec(self) :
140 self.index = self.index - 1
141 self.refreshStates()
142 self.decCallback(self)
143
144 def inc(self) :
145 self.index = self.index + 1
146 self.refreshStates()
147 self.incCallback(self)
148
149 def setSize(self, size) :
150 self.from_ = 1
151 self.to = size
152 self.index = 1
153 self.refreshStates()
154
155
156 class Identification(Frame) :
157 def __init__(self, master=None) :
158 Frame.__init__(self, master)
159 self.fileName = StringVar()
160 self.createWidgets()
161
162 def setFileName(self, name) :
163 self.fileName.set(name)
164
165 def createWidgets(self) :
166 fileLbl = Label(self, text='Fichier :')
167 fileLbl.grid(row=0, column=0, sticky=E)
168
169 fileNameLbl = Label(self, textvariable=self.fileName)
170 fileNameLbl.grid(row=0, column=1, sticky=W)
171
172 nameLbl = Label(self, text='Patient :')
173 nameLbl.grid(row=1, column=0, sticky=E)
174
175 self.nameEntry = Entry(self, width=40)
176 self.nameEntry.grid(row=1, column=1, sticky=W)
177
178 commentsLbl = Label(self, text='Commentaires :')
179 commentsLbl.grid(row=2, column=0, sticky=E)
180
181 self.commentsText = Text(self, width=40, height=4, undo=True, wrap=WORD)
182 self.commentsText.grid(row=2, column=1, sticky=W)
183
184 class ResultsFrame(Frame) :
185 def __init__(self, master, logFilePath) :
186 Frame.__init__(self, master)
187 self.logFilePath = logFilePath
188
189 def layResults(self) :
190 lfa = LogFileAnalyser(self.logFilePath)
191 results = lfa.analyse()
192 if results :
193 for i, kv in enumerate(results.items()) :
194 k, v = kv
195 kl = Label(self, text='%s :' % k)
196 kl.grid(row=i, column=0, sticky=E)
197
198 vl = Label(self, text=v)
199 vl.grid(row=i, column=1, sticky=W)
200 else :
201 msg = Label(self, text="Pas de données exploitables.")
202 msg.grid()
203
204
205
206 app = Application()
207 app.master.title("Analyseur des sessions MINWii")
208 app.mainloop()