Project

General

Profile

Revision 27140946

ID27140946a1ee5a4006fe10e7765e92b81451b59a
Parent 03059edd
Child 558ccefb

Added by Francois POIROTTE over 13 years ago

Grosse simplification de la gestion des plugins

Ces modifications permettent d'isoler un peu plus les plugins
du code principal de VigiBoard (de sorte qu'il serait possible
de fournir les plugins dans des paquets RPM séparés).

Ajout d'un validateur type !FormEncode pour la conversion d'une date
selon un format (obtenu dans les traductions).

Ajout d'un mécanisme permettant aux plugins d'ajouter dynamiquement
des lignes dans le formulaire de recherche.

Ajout de nouveaux plugins pour coller au mécanisme décrit ci-dessus.

Transformation des plugins existants pour profiter de ce modèle
dynamique pour la recherche. En conséquence, le code nécessaire
pour gérer la recherche dans le contrôleur Root a été grandement
simplifié.

Ajout de la possibilité de filtrer en fonction de la priorité des
événements affichés (cf. #572).

Légère correction dans les tests (pour ne pas dépendre de l'i18n).

git-svn-id: https://vigilo-dev.si.c-s.fr/svn@6559 b22e2e97-25c9-44ff-b637-2e5ceca36478

View differences:

vigiboard/controllers/root.py
22 22

  
23 23
from datetime import datetime
24 24
from time import mktime
25
import math
26 25

  
27
from tg.exceptions import HTTPNotFound, HTTPInternalServerError
26
from tg.exceptions import HTTPNotFound
28 27
from tg import expose, validate, require, flash, url, \
29 28
    tmpl_context, request, config, session, redirect
30 29
from webhelpers import paginate
......
33 32
from sqlalchemy import asc
34 33
from sqlalchemy.sql import func
35 34
from sqlalchemy.orm import aliased
36
from sqlalchemy.orm import contains_eager
37 35
from sqlalchemy.sql.expression import or_
38 36
from repoze.what.predicates import Any, All, in_group, \
39 37
                                    has_permission, not_anonymous, \
40 38
                                    NotAuthorizedError
41 39
from formencode import schema
42
from pkg_resources import working_set
43 40

  
44 41
from vigilo.models.session import DBSession
45 42
from vigilo.models.tables import Event, EventHistory, CorrEvent, Host, \
46 43
                                    SupItem, SupItemGroup, LowLevelService, \
47 44
                                    StateName, State, DataPermission
48 45
from vigilo.models.tables.grouphierarchy import GroupHierarchy
49
from vigilo.models.functions import sql_escape_like
50 46
from vigilo.models.tables.secondary_tables import EVENTSAGGREGATE_TABLE, \
51 47
        USER_GROUP_TABLE, SUPITEM_GROUP_TABLE
52 48

  
......
60 56

  
61 57
from vigiboard.widgets.edit_event import edit_event_status_options, \
62 58
                                            EditEventForm
63
from vigiboard.widgets.search_form import create_search_form, get_calendar_lang
59
from vigiboard.widgets.search_form import create_search_form
64 60

  
65 61
__all__ = ('RootController', 'get_last_modification_timestamp',
66 62
           'date_to_timestamp')
......
88 84

  
89 85
    def process_form_errors(self, *argv, **kwargv):
90 86
        """
91
        Gestion des erreurs de validation : On affiche les erreurs
87
        Gestion des erreurs de validation : on affiche les erreurs
92 88
        puis on redirige vers la dernière page accédée.
93 89
        """
94 90
        for k in tmpl_context.form_errors:
......
103 99
    class DefaultSchema(schema.Schema):
104 100
        """Schéma de validation de la méthode default."""
105 101
        page = validators.Int(min=1, if_missing=1, if_invalid=1)
106
        supitemgroup = validators.Int(if_missing=None, if_invalid=None)
107
        host = validators.String(if_missing=None)
108
        service = validators.String(if_missing=None)
109
        output = validators.String(if_missing=None)
110
        trouble_ticket = validators.String(if_missing=None)
111
        from_date = validators.String(if_missing=None)
112
        to_date = validators.String(if_missing=None)
102

  
103
        # Nécessaire pour que les critères de recherche soient conservés.
104
        allow_extra_fields = True
105

  
106
        # 2ème validation, cette fois avec les champs
107
        # du formulaire de recherche.
108
        chained_validators = [create_search_form.validator]
113 109

  
114 110
    @validate(
115 111
        validators=DefaultSchema(),
116 112
        error_handler = process_form_errors)
117 113
    @expose('events_table.html')
118 114
    @require(access_restriction)
119
    def default(self, page, supitemgroup, host, service,
120
                output, trouble_ticket, from_date, to_date):
115
    def default(self, page, **search):
121 116
        """
122 117
        Page d'accueil de Vigiboard. Elle affiche, suivant la page demandée
123 118
        (page 1 par defaut), la liste des événements, rangés par ordre de prise
......
125 120
        Pour accéder à cette page, l'utilisateur doit être authentifié.
126 121

  
127 122
        @param page: Numéro de la page souhaitée, commence à 1
128
        @param host: Si l'utilisateur souhaite sélectionner seulement certains
129
                     événements suivant leur hôte, il peut placer une expression
130
                     ici en suivant la structure du LIKE en SQL
131
        @param service: Idem que host mais sur les services
132
        @param output: Idem que host mais sur le text explicatif
133
        @param trouble_ticket: Idem que host mais sur les tickets attribués
123
        @type page: C{int}
124
        @param search: Dictionnaire contenant les critères de recherche.
125
        @type search: C{dict}
134 126

  
135 127
        Cette méthode permet de satisfaire les exigences suivantes :
136 128
            - VIGILO_EXIG_VIGILO_BAC_0040,
......
152 144
            Event.idsupitem == aggregates.items.c.idsupitem))
153 145
        aggregates.add_order_by(asc(aggregates.items.c.hostname))
154 146

  
155
        search = {}
156

  
157
        # Application des filtres si nécessaire
158
        if supitemgroup:
159
            search['supitemgroup'] = supitemgroup
160
            aggregates.add_join((GroupHierarchy, GroupHierarchy.idchild ==
161
                aggregates.items.c.idsupitemgroup))
162
            aggregates.add_filter(GroupHierarchy.idparent == supitemgroup)
163

  
164
        if host:
165
            search['host_'] = host
166
            host = sql_escape_like(host)
167
            aggregates.add_filter(aggregates.items.c.hostname.ilike(
168
                '%s' % host))
169

  
170
        if service:
171
            search['service'] = service
172
            service = sql_escape_like(service)
173
            aggregates.add_filter(aggregates.items.c.servicename.ilike(
174
                '%s' % service))
175

  
176
        if output:
177
            search['output'] = output
178
            output = sql_escape_like(output)
179
            aggregates.add_filter(Event.message.ilike('%s' % output))
180

  
181
        if trouble_ticket:
182
            search['tt'] = trouble_ticket
183
            trouble_ticket = sql_escape_like(trouble_ticket)
184
            aggregates.add_filter(CorrEvent.trouble_ticket.ilike(
185
                '%s' % trouble_ticket))
186

  
187
        if from_date:
188
            search['from_date'] = from_date.lower()
189
            try:
190
                # TRANSLATORS: Format de date et heure Python/JavaScript.
191
                # TRANSLATORS: http://www.dynarch.com/static/jscalendar-1.0/doc/html/reference.html#node_sec_5.3.5
192
                # TRANSLATORS: http://docs.python.org/release/2.5/lib/module-time.html
193
                from_date = datetime.strptime(
194
                    from_date.encode('utf8'),
195
                    _('%Y-%m-%d %I:%M:%S %p').encode('utf8'))
196
            except ValueError:
197
                # On ignore silencieusement la date invalide reçue.
198
                pass
199
            else:
200
                aggregates.add_filter(CorrEvent.timestamp_active >= from_date)
201

  
202
        if to_date:
203
            search['to_date'] = to_date.lower()
204
            try:
205
                # TRANSLATORS: Format de date et heure Python/JavaScript.
206
                # TRANSLATORS: http://www.dynarch.com/static/jscalendar-1.0/doc/html/reference.html#node_sec_5.3.5
207
                # TRANSLATORS: http://docs.python.org/release/2.5/lib/module-time.html
208
                to_date = datetime.strptime(
209
                    to_date.encode('utf8'),
210
                    _('%Y-%m-%d %I:%M:%S %p').encode('utf8'))
211
            except ValueError:
212
                # On ignore silencieusement la date invalide reçue.
213
                pass
214
            else:
215
                aggregates.add_filter(CorrEvent.timestamp_active <= to_date)
147
        # Application des filtres des plugins si nécessaire.
148
        for plugin, instance in config.get('columns_plugins', []):
149
            instance.handle_search_fields(aggregates, search)
150

  
151
        # Certains arguments sont réservés dans url_for().
152
        # On effectue les substitutions adéquates.
153
        # Par exemple: "host" devient "host_".
154
        reserved = ('host', )
155
        copy = search.copy()
156
        for column in copy:
157
            if column in reserved:
158
                search[column + '_'] = search[column]
159
                del search[column]
216 160

  
217 161
        # Pagination des résultats
218 162
        aggregates.generate_request()
219 163
        items_per_page = int(config['vigiboard_items_per_page'])
220
        page = paginate.Page(aggregates.req, page=page, items_per_page=items_per_page)
164
        page = paginate.Page(aggregates.req, page=page,
165
            items_per_page=items_per_page)
221 166

  
222 167
        # Récupération des données des plugins
223 168
        plugins_data = {}
......
246 191
            event_edit_status_options = edit_event_status_options,
247 192
            search_form = create_search_form,
248 193
            search = search,
249
            get_calendar_lang = get_calendar_lang,
250 194
        )
251 195

  
252 196

  
......
310 254
        # Pagination des résultats
311 255
        events.generate_request()
312 256
        items_per_page = int(config['vigiboard_items_per_page'])
313
        page = paginate.Page(events.req, page=page, items_per_page=items_per_page)
257
        page = paginate.Page(events.req, page=page,
258
            items_per_page=items_per_page)
314 259

  
315 260
        # Vérification que l'événement existe
316 261
        if not page.item_count:
......
325 270
            page = page,
326 271
            search_form = create_search_form,
327 272
            search = {},
328
            get_calendar_lang = get_calendar_lang,
329 273
        )
330 274

  
331 275

  
......
388 332
            page = page,
389 333
            search_form = create_search_form,
390 334
            search = {},
391
            get_calendar_lang = get_calendar_lang,
392 335
        )
393 336

  
394 337

  
......
436 379
        # Pagination des résultats
437 380
        aggregates.generate_request()
438 381
        items_per_page = int(config['vigiboard_items_per_page'])
439
        page = paginate.Page(aggregates.req, page=page, items_per_page=items_per_page)
382
        page = paginate.Page(aggregates.req, page=page,
383
            items_per_page=items_per_page)
440 384

  
441 385
        # Vérification qu'il y a au moins 1 événement qui correspond
442 386
        if not page.item_count:
......
460 404
            event_edit_status_options = edit_event_status_options,
461 405
            search_form = create_search_form,
462 406
            search = {},
463
            get_calendar_lang = get_calendar_lang,
464 407
        )
465 408

  
466 409

  
......
554 497
        for event in events.req:
555 498
            if trouble_ticket and trouble_ticket != event.trouble_ticket:
556 499
                history = EventHistory(
557
                        type_action="Ticket change",
500
                        type_action=u"Ticket change",
558 501
                        idevent=event.idcause,
559 502
                        value=unicode(trouble_ticket),
560 503
                        text="Changed trouble ticket from '%(from)s' "

Also available in: Unified diff