vigiboard / vigiboard / controllers / vigiboardrequest.py @ d5a41c9b
History | View | Annotate | Download (16.3 KB)
1 | 19e88cb8 | Thomas ANDREJAK | # -*- coding: utf-8 -*-
|
---|---|---|---|
2 | 65383903 | Francois POIROTTE | # vim:set expandtab tabstop=4 shiftwidth=4:
|
3 | a77de887 | Francois POIROTTE | ################################################################################
|
4 | #
|
||
5 | 25892058 | Francois POIROTTE | # Copyright (C) 2007-2013 CS-SI
|
6 | a77de887 | Francois POIROTTE | #
|
7 | # This program is free software; you can redistribute it and/or modify
|
||
8 | # it under the terms of the GNU General Public License version 2 as
|
||
9 | # published by the Free Software Foundation.
|
||
10 | #
|
||
11 | # This program is distributed in the hope that it will be useful,
|
||
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
14 | # GNU General Public License for more details.
|
||
15 | #
|
||
16 | # You should have received a copy of the GNU General Public License
|
||
17 | # along with this program; if not, write to the Free Software
|
||
18 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
19 | ################################################################################
|
||
20 | |||
21 | 19e88cb8 | Thomas ANDREJAK | """Gestion de la requête, des plugins et de l'affichage du Vigiboard"""
|
22 | |||
23 | 7365fb51 | Francois POIROTTE | from time import mktime |
24 | |||
25 | e181e86c | Francois POIROTTE | from tg import config, tmpl_context, request, url |
26 | 7365fb51 | Francois POIROTTE | from pylons.i18n import ugettext as _ |
27 | b2346a00 | Francois POIROTTE | from paste.deploy.converters import asbool |
28 | |||
29 | 6ab72614 | Vincent QUEMENER | from sqlalchemy import not_, and_, asc, desc |
30 | 8b2edebe | Aurelien BOMPARD | from sqlalchemy.sql.expression import null as expr_null, union_all |
31 | cf3c2494 | Vincent QUEMENER | from sqlalchemy.orm import contains_eager |
32 | 7365fb51 | Francois POIROTTE | |
33 | e7e3d45e | Francois POIROTTE | from vigilo.models.session import DBSession |
34 | from vigilo.models.tables import Event, CorrEvent, EventHistory, \ |
||
35 | 916e4b79 | Francois POIROTTE | Host, LowLevelService, StateName, UserSupItem |
36 | e181e86c | Francois POIROTTE | from vigiboard.widgets.edit_event import EditEventForm |
37 | 86662bc9 | Francois POIROTTE | from vigiboard.controllers.plugins import VigiboardRequestPlugin, INNER, ITEMS |
38 | 7365fb51 | Francois POIROTTE | |
39 | 19e88cb8 | Thomas ANDREJAK | class VigiboardRequest(): |
40 | 86c3ae23 | Francois POIROTTE | """
|
41 | Classe gérant la génération de la requête finale,
|
||
42 | le préformatage des événements et celui des historiques
|
||
43 | """
|
||
44 | |||
45 | 5a845c93 | Vincent QUEMENER | def __init__(self, user, mask_closed_events=True, search=None, sort=None, order=None): |
46 | 19e88cb8 | Thomas ANDREJAK | """
|
47 | 54644278 | Francois POIROTTE | Initialisation de l'objet qui effectue les requêtes de VigiBoard
|
48 | sur la base de données.
|
||
49 | Cet objet est responsable de la vérification des droits de
|
||
50 | l'utilisateur sur les données manipulées.
|
||
51 | 5a845c93 | Vincent QUEMENER |
|
52 | @param user: Nom de l'utilisateur cherchant à afficher les événements.
|
||
53 | @type user: C{str}
|
||
54 | @param mask_closed_events: Booléen indiquant si l'on souhaite masquer les
|
||
55 | événements fermés ou non.
|
||
56 | @type mask_closed_events: C{boolean}
|
||
57 | @param search: Dictionnaire contenant les critères de recherche.
|
||
58 | @type search: C{dict}
|
||
59 | @param sort: Colonne de tri; vide en l'absence de tri.
|
||
60 | @type sort: C{unicode}
|
||
61 | @param order: Ordre du tri ("asc" ou "desc"); vide en l'absence de tri.
|
||
62 | @type order: C{unicode}
|
||
63 |
|
||
64 | 19e88cb8 | Thomas ANDREJAK | """
|
65 | |||
66 | 0f0e32ed | Francois POIROTTE | # Permet s'appliquer des filtres de recherche aux sous-requêtes.
|
67 | self.subqueries = []
|
||
68 | 19e88cb8 | Thomas ANDREJAK | self.generaterq = False |
69 | 24d74687 | Francois POIROTTE | |
70 | 86662bc9 | Francois POIROTTE | # Éléments à retourner (SELECT ...)
|
71 | self.table = []
|
||
72 | |||
73 | # Tables sur lesquelles porte la récupération (JOIN)
|
||
74 | self.join = []
|
||
75 | |||
76 | # Options à ajouter la requête
|
||
77 | self.option = []
|
||
78 | |||
79 | # Tables sur lesquelles porte la récupération (OUTER JOIN)
|
||
80 | self.outerjoin = []
|
||
81 | |||
82 | # Critères de filtrage (WHERE)
|
||
83 | self.filter = []
|
||
84 | |||
85 | # Regroupements (GROUP BY)
|
||
86 | # PostgreSQL est pointilleux sur les colonnes qui apparaissent
|
||
87 | # dans la clause GROUP BY. Si une colonne apparaît dans ORDER BY,
|
||
88 | # elle doit systématiquement apparaître AUSSI dans GROUP BY.
|
||
89 | self.groupby = [
|
||
90 | StateName.order, |
||
91 | Event.timestamp, |
||
92 | 8ba2de75 | Francois POIROTTE | CorrEvent.ack, |
93 | 86662bc9 | Francois POIROTTE | CorrEvent.priority, |
94 | StateName.statename, |
||
95 | ] |
||
96 | |||
97 | self.req = DBSession
|
||
98 | self.plugin = []
|
||
99 | self.events = []
|
||
100 | |||
101 | 73119f8a | Francois POIROTTE | # Si l'utilisateur est privilégié, il a accès
|
102 | # à tous les hôtes/services sans restriction.
|
||
103 | if config.is_manager.is_met(request.environ):
|
||
104 | 180b869a | Vincent QUEMENER | # Sélection de tous les services de la BDD.
|
105 | 0f0e32ed | Francois POIROTTE | lls_query = DBSession.query( |
106 | 180b869a | Vincent QUEMENER | LowLevelService.idservice.label("idsupitem"),
|
107 | LowLevelService.servicename.label("servicename"),
|
||
108 | Host.name.label("hostname"),
|
||
109 | ).join( |
||
110 | (Host, Host.idhost == LowLevelService.idhost), |
||
111 | 0f0e32ed | Francois POIROTTE | ).distinct() |
112 | 180b869a | Vincent QUEMENER | |
113 | # Sélection de tous les hôtes de la BDD.
|
||
114 | 0f0e32ed | Francois POIROTTE | host_query = DBSession.query( |
115 | 180b869a | Vincent QUEMENER | Host.idhost.label("idsupitem"),
|
116 | expr_null().label("servicename"),
|
||
117 | Host.name.label("hostname"),
|
||
118 | 032d0f30 | Vincent QUEMENER | ).distinct() |
119 | 0f0e32ed | Francois POIROTTE | |
120 | # Application des filtres des plugins si nécessaire.
|
||
121 | if search is not None: |
||
122 | # On tire ici partie du fait que les listes sont passées
|
||
123 | # par référence dans les fonctions.
|
||
124 | subqueries = [lls_query, host_query] |
||
125 | 8b2edebe | Aurelien BOMPARD | for _plugin, instance in config.get('columns_plugins', []): |
126 | 86662bc9 | Francois POIROTTE | instance.handle_search_fields( |
127 | self, search, INNER, subqueries)
|
||
128 | 0f0e32ed | Francois POIROTTE | lls_query = subqueries[0]
|
129 | host_query = subqueries[1]
|
||
130 | 180b869a | Vincent QUEMENER | |
131 | # Union des deux sélections précédentes
|
||
132 | self.items = union_all(
|
||
133 | 0f0e32ed | Francois POIROTTE | lls_query, |
134 | host_query, |
||
135 | 180b869a | Vincent QUEMENER | correlate=False
|
136 | ).alias() |
||
137 | |||
138 | # Sinon, on ne récupère que les hôtes/services auquel il a accès.
|
||
139 | else:
|
||
140 | 916e4b79 | Francois POIROTTE | items = DBSession.query( |
141 | 180b869a | Vincent QUEMENER | UserSupItem.idsupitem, |
142 | UserSupItem.servicename, |
||
143 | UserSupItem.hostname, |
||
144 | ).filter( |
||
145 | UserSupItem.username == user.user_name |
||
146 | 0f0e32ed | Francois POIROTTE | ).distinct() |
147 | 180b869a | Vincent QUEMENER | |
148 | 0f0e32ed | Francois POIROTTE | # Application des filtres des plugins si nécessaire.
|
149 | if search is not None: |
||
150 | # On tire ici partie du fait que les listes sont passées
|
||
151 | # par référence dans les fonctions.
|
||
152 | subqueries = [items] |
||
153 | 8b2edebe | Aurelien BOMPARD | for _plugin, instance in config.get('columns_plugins', []): |
154 | 86662bc9 | Francois POIROTTE | instance.handle_search_fields( |
155 | self, search, INNER, subqueries)
|
||
156 | 0f0e32ed | Francois POIROTTE | items = subqueries[0]
|
157 | 916e4b79 | Francois POIROTTE | |
158 | 86662bc9 | Francois POIROTTE | # Permet d'avoir le même format que pour l'autre requête.
|
159 | 0f0e32ed | Francois POIROTTE | self.items = items.subquery()
|
160 | 8484b8bd | Francois POIROTTE | |
161 | 5a845c93 | Vincent QUEMENER | # Tris (ORDER BY)
|
162 | # Permet de répondre aux exigences suivantes :
|
||
163 | # - VIGILO_EXIG_VIGILO_BAC_0050
|
||
164 | # - VIGILO_EXIG_VIGILO_BAC_0060
|
||
165 | self.orderby = []
|
||
166 | if sort:
|
||
167 | for _plugin, instance in config.get('columns_plugins', []): |
||
168 | criterion = instance.get_sort_criterion(self, sort)
|
||
169 | if criterion is not None: |
||
170 | if order == 'asc': |
||
171 | self.orderby.append(asc(criterion))
|
||
172 | else:
|
||
173 | self.orderby.append(desc(criterion))
|
||
174 | |||
175 | # Permet de définir le sens de tri pour la priorité.
|
||
176 | if config['vigiboard_priority_order'] == 'asc': |
||
177 | priority_order = asc(CorrEvent.priority) |
||
178 | else:
|
||
179 | priority_order = desc(CorrEvent.priority) |
||
180 | |||
181 | self.orderby.extend([
|
||
182 | asc(CorrEvent.ack), # État acquittement
|
||
183 | asc(StateName.statename.in_([u'OK', u'UP'])), # Vert / Pas vert |
||
184 | priority_order, # Priorité ITIL
|
||
185 | ]) |
||
186 | |||
187 | if asbool(config.get('state_first', True)): |
||
188 | self.orderby.extend([
|
||
189 | desc(StateName.order), # Etat courant
|
||
190 | desc(Event.timestamp), # Timestamp
|
||
191 | ]) |
||
192 | else:
|
||
193 | self.orderby.extend([
|
||
194 | desc(Event.timestamp), # Timestamp
|
||
195 | desc(StateName.order), # Etat courant
|
||
196 | ]) |
||
197 | |||
198 | 86662bc9 | Francois POIROTTE | if search is not None: |
199 | # 2nde passe pour les filtres : self.items est désormais défini.
|
||
200 | 8b2edebe | Aurelien BOMPARD | for _plugin, instance in config.get('columns_plugins', []): |
201 | 86662bc9 | Francois POIROTTE | instance.handle_search_fields(self, search, ITEMS, subqueries)
|
202 | 911069bc | Francois POIROTTE | |
203 | 54644278 | Francois POIROTTE | if mask_closed_events:
|
204 | self.filter.append(
|
||
205 | # On masque les événements avec l'état OK
|
||
206 | 8ba2de75 | Francois POIROTTE | # et traités (ack == CorrEvent.ACK_CLOSED).
|
207 | 54644278 | Francois POIROTTE | not_(and_( |
208 | StateName.statename.in_([u'OK', u'UP']), |
||
209 | 8ba2de75 | Francois POIROTTE | CorrEvent.ack == CorrEvent.ACK_CLOSED |
210 | 54644278 | Francois POIROTTE | )) |
211 | ) |
||
212 | 8484b8bd | Francois POIROTTE | |
213 | 19e88cb8 | Thomas ANDREJAK | |
214 | def add_plugin(self, *argv): |
||
215 | """
|
||
216 | Ajout d'un plugin, on lui prélève ses ajouts dans la requête
|
||
217 | """
|
||
218 | df66bc2c | Francois POIROTTE | for i in argv: |
219 | 19e88cb8 | Thomas ANDREJAK | if isinstance(i, VigiboardRequestPlugin): |
220 | df66bc2c | Francois POIROTTE | if i.table:
|
221 | 19e88cb8 | Thomas ANDREJAK | self.add_table(*i.table)
|
222 | df66bc2c | Francois POIROTTE | if i.join:
|
223 | 19e88cb8 | Thomas ANDREJAK | self.add_join(*i.join)
|
224 | df66bc2c | Francois POIROTTE | if i.outerjoin:
|
225 | 19e88cb8 | Thomas ANDREJAK | self.add_outer_join(*i.outerjoin)
|
226 | df66bc2c | Francois POIROTTE | if i.filter:
|
227 | 19e88cb8 | Thomas ANDREJAK | self.add_filter(*i.filter)
|
228 | 65383903 | Francois POIROTTE | if i.groupby:
|
229 | 19e88cb8 | Thomas ANDREJAK | self.add_group_by(*i.groupby)
|
230 | df66bc2c | Francois POIROTTE | if i.orderby:
|
231 | 19e88cb8 | Thomas ANDREJAK | self.add_order_by(*i.orderby)
|
232 | self.plugin.append(i)
|
||
233 | |||
234 | def generate_request(self): |
||
235 | """
|
||
236 | Génération de la requête avec l'ensemble des données stockées
|
||
237 | et la place dans la variable rq de la classe
|
||
238 | """
|
||
239 | 911069bc | Francois POIROTTE | if self.generaterq: |
240 | return
|
||
241 | |||
242 | 65383903 | Francois POIROTTE | for plugin in config['columns_plugins']: |
243 | self.add_plugin(plugin)
|
||
244 | bc94248f | Francois POIROTTE | |
245 | b00c0ea7 | Francois POIROTTE | # Toutes les requêtes ont besoin de récupérer l'état courant
|
246 | # de l'événement.
|
||
247 | 5d20c2c5 | Francois POIROTTE | self.join.append((StateName, StateName.idstatename == \
|
248 | Event.current_state)) |
||
249 | b00c0ea7 | Francois POIROTTE | |
250 | # PostgreSQL est pointilleux sur les colonnes qui apparaissent
|
||
251 | # dans la clause GROUP BY. Si une colonne apparaît dans SELECT,
|
||
252 | # elle doit systématiquement apparaître AUSSI dans GROUP BY.
|
||
253 | # Ici, on ajoute automatiquement les colonnes du SELECT au GROUP BY.
|
||
254 | 911069bc | Francois POIROTTE | self.add_group_by(*self.table) |
255 | |||
256 | 19e88cb8 | Thomas ANDREJAK | # query et join ont besoin de referrence
|
257 | self.req = self.req.query(*self.table) |
||
258 | self.req = self.req.join(*self.join) |
||
259 | cf3c2494 | Vincent QUEMENER | self.req = self.req.options(*self.option) |
260 | 19e88cb8 | Thomas ANDREJAK | |
261 | # le reste, non
|
||
262 | for i in self.outerjoin: |
||
263 | self.req = self.req.outerjoin(i) |
||
264 | for i in self.filter: |
||
265 | self.req = self.req.filter(i) |
||
266 | for i in self.groupby: |
||
267 | self.req = self.req.group_by(i) |
||
268 | for i in self.orderby: |
||
269 | self.req = self.req.order_by(i) |
||
270 | 911069bc | Francois POIROTTE | self.generaterq = True |
271 | |||
272 | 19e88cb8 | Thomas ANDREJAK | def num_rows(self): |
273 | """
|
||
274 | Retourne le nombre de lignes de la requête.
|
||
275 | Si celle-ci n'est pas encore générée, on le fait.
|
||
276 |
|
||
277 | 0bd9c069 | Francois POIROTTE | @return: Nombre de ligne
|
278 | 19e88cb8 | Thomas ANDREJAK | """
|
279 | |||
280 | 911069bc | Francois POIROTTE | self.generate_request()
|
281 | 19e88cb8 | Thomas ANDREJAK | return self.req.count() |
282 | |||
283 | def add_table(self, *argv): |
||
284 | """
|
||
285 | Ajoute une ou plusieurs tables/élément d'une table à
|
||
286 | la requête.
|
||
287 |
|
||
288 | @param argv: Liste des tables à ajouter
|
||
289 | """
|
||
290 | 65383903 | Francois POIROTTE | |
291 | 8484b8bd | Francois POIROTTE | # On vérifie qu'il n'y a pas de doublons dans la liste finale
|
292 | # des tables.
|
||
293 | 65383903 | Francois POIROTTE | |
294 | 19e88cb8 | Thomas ANDREJAK | for i in argv : |
295 | for j in self.table: |
||
296 | if str(i) == str(j): |
||
297 | break
|
||
298 | self.table.append(i)
|
||
299 | |||
300 | def add_join(self, *argv): |
||
301 | """
|
||
302 | Ajoute une ou plusieurs jointures à
|
||
303 | la requête.
|
||
304 |
|
||
305 | @param argv: Liste des jointures à ajouter
|
||
306 | """
|
||
307 | 65383903 | Francois POIROTTE | |
308 | 8484b8bd | Francois POIROTTE | # On vérifie qu'il n'y a pas de doublons dans la liste finale
|
309 | # des jointures.
|
||
310 | 65383903 | Francois POIROTTE | |
311 | 19e88cb8 | Thomas ANDREJAK | for i in argv: |
312 | for j in self.join: |
||
313 | if str(i) == str(j): |
||
314 | break
|
||
315 | self.join.append(i)
|
||
316 | |||
317 | cf3c2494 | Vincent QUEMENER | def add_option(self, *argv): |
318 | """
|
||
319 | Ajoute une ou plusieurs options à la requête.
|
||
320 |
|
||
321 | @param argv: Liste des options à ajouter
|
||
322 | """
|
||
323 | |||
324 | # On vérifie qu'il n'y a pas de doublons
|
||
325 | # dans la liste finale des options.
|
||
326 | |||
327 | for i in argv: |
||
328 | for j in self.option: |
||
329 | if str(i) == str(j): |
||
330 | break
|
||
331 | self.option.append(i)
|
||
332 | |||
333 | def add_contains_eager(self, relation): |
||
334 | """
|
||
335 | Ajoute une option de type contains_eager à la
|
||
336 | requête pour la relation passée en paramètre.
|
||
337 | """
|
||
338 | self.add_option(contains_eager(relation))
|
||
339 | |||
340 | 19e88cb8 | Thomas ANDREJAK | def add_outer_join(self, *argv): |
341 | """
|
||
342 | Ajoute une ou plusieurs jointures externes à
|
||
343 | la requête.
|
||
344 |
|
||
345 | @param argv: Liste des jointures externes à ajouter
|
||
346 | """
|
||
347 | 65383903 | Francois POIROTTE | |
348 | 8484b8bd | Francois POIROTTE | # On vérifie qu'il n'y a pas de doublons dans la liste finale
|
349 | # des jointures externes.
|
||
350 | 65383903 | Francois POIROTTE | |
351 | 19e88cb8 | Thomas ANDREJAK | for i in argv: |
352 | for j in self.outerjoin: |
||
353 | if str(i) == str(j): |
||
354 | break
|
||
355 | 65383903 | Francois POIROTTE | self.outerjoin.append(i)
|
356 | 19e88cb8 | Thomas ANDREJAK | |
357 | def add_filter(self, *argv): |
||
358 | """
|
||
359 | Ajoute un ou plusieurs filtres à la requête.
|
||
360 |
|
||
361 | @param argv: Liste des filtres à ajouter
|
||
362 | """
|
||
363 | 65383903 | Francois POIROTTE | |
364 | 8484b8bd | Francois POIROTTE | # On vérifie qu'il n'y a pas de doublons dans la liste finale
|
365 | # des filtres.
|
||
366 | 65383903 | Francois POIROTTE | |
367 | 19e88cb8 | Thomas ANDREJAK | for i in argv: |
368 | for j in self.filter: |
||
369 | if str(i) == str(j): |
||
370 | break
|
||
371 | self.filter.append(i)
|
||
372 | |||
373 | def add_group_by(self, *argv): |
||
374 | """
|
||
375 | Ajoute un ou plusieurs groupements à la requête.
|
||
376 |
|
||
377 | @param argv: Liste des groupements à ajouter
|
||
378 | """
|
||
379 | 65383903 | Francois POIROTTE | |
380 | 8484b8bd | Francois POIROTTE | # On vérifie qu'il n'y a pas de doublons dans la liste finale
|
381 | # des groupements.
|
||
382 | 65383903 | Francois POIROTTE | |
383 | 19e88cb8 | Thomas ANDREJAK | for i in argv: |
384 | for j in self.groupby: |
||
385 | df66bc2c | Francois POIROTTE | try:
|
386 | if str(i) == str(j): |
||
387 | break
|
||
388 | # SQLAlchemy lève cette exception pour certains attributes,
|
||
389 | # par exemple les attributs définis avec synonym().
|
||
390 | except AttributeError: |
||
391 | pass
|
||
392 | 19e88cb8 | Thomas ANDREJAK | self.groupby.append(i)
|
393 | |||
394 | def add_order_by(self, *argv): |
||
395 | """
|
||
396 | Ajoute un ou plusieurs orders à la requête.
|
||
397 |
|
||
398 | @param argv: Liste des ordres à ajouter
|
||
399 | """
|
||
400 | 65383903 | Francois POIROTTE | |
401 | 8484b8bd | Francois POIROTTE | # On vérifie qu'il n'y a pas de doublons dans la liste finale
|
402 | # des ordres.
|
||
403 | 65383903 | Francois POIROTTE | |
404 | 19e88cb8 | Thomas ANDREJAK | for i in argv: |
405 | for j in self.orderby: |
||
406 | if str(i) == str(j): |
||
407 | break
|
||
408 | self.orderby.append(i)
|
||
409 | |||
410 | def format_events(self, first_row, last_row): |
||
411 | """
|
||
412 | Formate la réponse de la requête et y applique les plugins
|
||
413 | pour un affichage simple du résultat par Genshi.
|
||
414 | On génère une liste de liste, chaqu'une étant la description de
|
||
415 | a2a22ade | Francois POIROTTE | l'affichage pour un événement donné.
|
416 | 19e88cb8 | Thomas ANDREJAK |
|
417 | a2a22ade | Francois POIROTTE | @param first_row: Indice de début de la liste des événements
|
418 | @param last_row: Indice de fin de la liste des événements
|
||
419 | 19e88cb8 | Thomas ANDREJAK | """
|
420 | 65383903 | Francois POIROTTE | |
421 | 19e88cb8 | Thomas ANDREJAK | # Si la requête n'est pas générée, on le fait
|
422 | 911069bc | Francois POIROTTE | self.generate_request()
|
423 | 19e88cb8 | Thomas ANDREJAK | |
424 | # Liste des éléments pour la tête du tableau
|
||
425 | 15b98053 | Francois POIROTTE | self.events = []
|
426 | 19e88cb8 | Thomas ANDREJAK | |
427 | 15b98053 | Francois POIROTTE | for data in self.req[first_row : last_row]: |
428 | 94f31908 | Francois POIROTTE | self.events.append(data)
|
429 | 19e88cb8 | Thomas ANDREJAK | |
430 | 8484b8bd | Francois POIROTTE | def format_history(self): |
431 | 19e88cb8 | Thomas ANDREJAK | """
|
432 | a2a22ade | Francois POIROTTE | Formate les historiques correspondant aux événements sélectionnés
|
433 | 19e88cb8 | Thomas ANDREJAK | pour un affichage simple du résultat par Genshi.
|
434 | 8484b8bd | Francois POIROTTE | On génère une liste de liste, chaqu'une étant la description
|
435 | de l'affichage pour un historique donné.
|
||
436 | 19e88cb8 | Thomas ANDREJAK | """
|
437 | |||
438 | 539f69fc | Francois POIROTTE | ids = [data[0].idevent for data in self.events] |
439 | ee3ae8c8 | Francois POIROTTE | history = DBSession.query( |
440 | EventHistory, |
||
441 | 15b98053 | Francois POIROTTE | ).filter(EventHistory.idevent.in_(ids) |
442 | 19e88cb8 | Thomas ANDREJAK | ).order_by(desc(EventHistory.timestamp) |
443 | ).order_by(desc(EventHistory.idhistory)) |
||
444 | 539f69fc | Francois POIROTTE | return history
|
445 | 19e88cb8 | Thomas ANDREJAK | |
446 | 24d4f8b0 | Vincent QUEMENER | def generate_tmpl_context(self): |
447 | 19e88cb8 | Thomas ANDREJAK | """
|
448 | Génère et peuple la variable tmpl_context avec les Dialogs et
|
||
449 | formulaires nécessaire au fonctionnement de Vigiboard
|
||
450 | """
|
||
451 | |||
452 | 97f6d842 | Vincent QUEMENER | from vigiboard.controllers.root import get_last_modification_timestamp |
453 | bcf87133 | Francois POIROTTE | |
454 | # Si les objets manipulés sont des Event, on a facilement les idevent.
|
||
455 | 94f31908 | Francois POIROTTE | if not len(self.events): |
456 | ids = [] |
||
457 | elif isinstance(self.events[0][0], Event): |
||
458 | bcf87133 | Francois POIROTTE | ids = [data[0].idevent for data in self.events] |
459 | # Sinon, il s'agit de CorrEvent(s) dont on récupère l'idcause.
|
||
460 | else:
|
||
461 | ids = [data[0].idcause for data in self.events] |
||
462 | e9ccb711 | Francois POIROTTE | |
463 | 57387640 | Francois POIROTTE | # Ajout des formulaires et préparation
|
464 | # des données pour ces formulaires.
|
||
465 | tmpl_context.last_modification = \ |
||
466 | mktime(get_last_modification_timestamp(ids).timetuple()) |
||
467 | |||
468 | e181e86c | Francois POIROTTE | tmpl_context.edit_event_form = EditEventForm("edit_event_form",
|
469 | a5f99051 | Francois POIROTTE | submit_text=_('Apply'), action=url('/update')) |