Project

General

Profile

Revision 7c9baa43

ID7c9baa43d02c3b44cd7e5cdae8bd995dbfb0d2ee
Parent e71a38ac
Child 2832ea2b

Added by Francois POIROTTE almost 14 years ago

Fusion du nouveau VigiGraph basé sur mootools dans le trunk.

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

View differences:

Makefile
1 1
NAME := vigigraph
2 2
QOOXDOO_VER := 0.7.3
3 3

  
4
all: qooxdoo build
4
all: build
5 5

  
6 6
include buildenv/Makefile.common
7 7
PKGNAME := $(NAME)
......
9 9
CODEPATH := $(NAME)
10 10
EPYDOC_PARSE := vigigraph\.controllers
11 11

  
12
qooxdoo_source: javascript/qooxdoo-$(QOOXDOO_VER)-sdk/frontend/Makefile
13
javascript/qooxdoo-$(QOOXDOO_VER)-sdk.tar.gz:
14
	#wget -P javascript/ http://downloads.sourceforge.net/project/qooxdoo/qooxdoo-legacy/$(QOOXDOO_VER)/qooxdoo-$(QOOXDOO_VER)-sdk.tar.gz
15
	wget -P javascript/ http://vigilo-dev.si.c-s.fr/cache/qooxdoo-$(QOOXDOO_VER)-sdk.tar.gz
16
	touch --no-create $@
17
javascript/qooxdoo-$(QOOXDOO_VER)-sdk/frontend/Makefile: javascript/qooxdoo-$(QOOXDOO_VER)-sdk.tar.gz
18
	tar -C javascript/ -xzf javascript/qooxdoo-0.7.3-sdk.tar.gz
19
	patch -p0 < patches/001_qooxdoo_getBoxObjectFor.diff
20
	touch --no-create $@
21

  
22
qooxdoo: vigigraph/public/js/vigigraph.js
23
vigigraph/public/js/vigigraph.js: javascript/source/class/vigigraph/Application.js javascript/qooxdoo-$(QOOXDOO_VER)-sdk/frontend/Makefile
24
	make -C javascript build
25
	mkdir -p vigigraph/public/js/
26
	cp -f javascript/build/script/vigigraph.js vigigraph/public/js/vigigraph.js
27
	cp -rf javascript/build/resource vigigraph/public/
28

  
29
clean_qooxdoo:
30
	$(RM) vigigraph/public/js/vigigraph.js
31
	$(RM) -r vigigraph/public/resource
32
	$(RM) -r javascript/build/
33

  
34 12
install: vigigraph/public/js/vigigraph.js $(PYTHON)
35 13
	$(PYTHON) setup.py install --single-version-externally-managed --root=$(DESTDIR) --record=INSTALLED_FILES
36 14
	chmod a+rX -R $(DESTDIR)$(PREFIX)/lib*/python*/*
......
54 32

  
55 33
lint: lint_pylint
56 34
tests: tests_nose
57
clean: clean_python clean_qooxdoo
35
clean: clean_python
babeljs.py
1
# -*- coding: utf-8 -*-
2
"""
3
Provides a class derived from Babel's compile_catalog
4
which automatically creates JavaScript files compatible
5
with Babel's JavaScript frontend.
6

  
7
This code was taken from:
8
http://svn.python.org/projects/doctools/trunk/setup.py
9

  
10
And generates files for use with:
11
http://babel.edgewall.org/browser/trunk/contrib/babel.js
12
"""
13
try:
14
    from babel.messages.pofile import read_po
15
    from babel.messages.frontend import compile_catalog
16
    try:
17
        from simplejson import dump
18
    except ImportError:
19
        from json import dump
20
except ImportError:
21
    pass
22
else:
23
    import os
24
    from distutils import log
25

  
26
    class compile_catalog_plusjs(compile_catalog):
27
        """
28
        An extended command that writes all message strings that occur in
29
        JavaScript files to a JavaScript file along with the .mo file.
30

  
31
        Unfortunately, babel's setup command isn't built very extensible, so
32
        most of the run() code is duplicated here.
33
        """
34

  
35
        def run(self):
36
            compile_catalog.run(self)
37

  
38
            po_files = []
39
            js_files = []
40

  
41
            if not self.input_file:
42
                if self.locale:
43
                    po_files.append((self.locale,
44
                                     os.path.join(self.directory, self.locale,
45
                                                  'LC_MESSAGES',
46
                                                  self.domain + '.po')))
47
                    js_files.append(os.path.join(self.directory, self.locale,
48
                                                 'LC_MESSAGES',
49
                                                 self.domain + '.js'))
50
                else:
51
                    for locale in os.listdir(self.directory):
52
                        po_file = os.path.join(self.directory, locale,
53
                                               'LC_MESSAGES', self.domain + '.po')
54
                        if os.path.exists(po_file):
55
                            po_files.append((locale, po_file))
56
                            js_files.append(os.path.join(self.directory, locale,
57
                                                         'LC_MESSAGES',
58
                                                         self.domain + '.js'))
59
            else:
60
                po_files.append((self.locale, self.input_file))
61
                if self.output_file:
62
                    js_files.append(self.output_file)
63
                else:
64
                    js_files.append(os.path.join(self.directory, self.locale,
65
                                                 'LC_MESSAGES',
66
                                                 self.domain + '.js'))
67

  
68
            for js_file, (locale, po_file) in zip(js_files, po_files):
69
                infile = open(po_file, 'r')
70
                try:
71
                    catalog = read_po(infile, locale)
72
                finally:
73
                    infile.close()
74

  
75
                if catalog.fuzzy and not self.use_fuzzy:
76
                    continue
77

  
78
                log.info('writing JavaScript strings in catalog %r to %r',
79
                         po_file, js_file)
80

  
81
                jscatalog = {}
82
                for message in catalog:
83
                    # Si le message n'a pas encore été traduit,
84
                    # on ne l'ajoute pas. Le message d'origine
85
                    # (non traduit) sera renvoyé.
86
                    if not message.string:
87
                        continue
88

  
89
                    # On n'ajoute le message au fichier de traduction JS
90
                    # auto-généré que si le message est utilisé dans du
91
                    # code JavaScript.
92
                    if any(x[0].endswith('.js') for x in message.locations):
93
                        msgid = message.id
94
                        if isinstance(msgid, (list, tuple)):
95
                            msgid = msgid[0]
96
                        jscatalog[msgid] = message.string
97

  
98
                outfile = open(js_file, 'wb')
99
                try:
100
                    outfile.write('babel.Translations.load(');
101
                    dump(dict(
102
                        messages=jscatalog,
103
                        plural_expr=catalog.plural_expr,
104
                        locale=str(catalog.locale)
105
                        ), outfile)
106
                    outfile.write(').install();')
107
                finally:
108
                    outfile.close()
109

  
development.ini
23 23
use = egg:vigigraph
24 24

  
25 25
db_basename=vigilo_
26
password_hashing_function=md5
26
;password_hashing_function=md5
27 27
lang=fr
28 28
use_kerberos=False
29 29
help_link=http://foo.bar/help
......
33 33

  
34 34
; Emplacement des applications (vigirrd, Nagios, ...)
35 35
; sur les serveurs distants.
36
app_path.vigirrd = /vigilo/vigirrd/
36
app_path.vigirrd = /
37 37
app_path.nagios = /nagios/
38 38

  
39 39
; Schéma ("protocol") à utiliser pour se connecter
......
47 47
; Port de connexion au serveur distant hébergeant
48 48
; l'application.
49 49
; Par défaut : 80
50
app_port.vigirrd = 80
50
app_port.vigirrd = 8084
51 51
app_port.nagios = 80
52 52

  
53 53
# Délai de rafraîchissement (en secondes)
patches/001_qooxdoo_getBoxObjectFor.diff
1
--- javascript/qooxdoo-0.7.3-sdk/frontend/framework/source/class/qx/html/Location.js.old	2010-04-20 14:18:32.000000000 +0200
2
+++ javascript/qooxdoo-0.7.3-sdk/frontend/framework/source/class/qx/html/Location.js	2010-04-20 14:42:14.000000000 +0200
3
@@ -419,7 +419,7 @@
4
     getPageAreaLeft : qx.core.Variant.select("qx.client",
5
     {
6
       "gecko" : function(el) {
7
-        return el.ownerDocument.getBoxObjectFor(el).x;
8
+        return el.getBoundingClientRect().left;
9
       },
10
 
11
       "default" : function(el) {
12
@@ -439,7 +439,7 @@
13
     getPageAreaTop : qx.core.Variant.select("qx.client",
14
     {
15
       "gecko" : function(el) {
16
-        return el.ownerDocument.getBoxObjectFor(el).y;
17
+        return el.getBoundingClientRect().top;
18
       },
19
 
20
       "default" : function(el) {
pkg/vigigraph.mandriva.spec
93 93

  
94 94
%prep
95 95
%setup -q -n %{module}-%{version}
96
make qooxdoo_source
97 96

  
98 97
%build
99
make qooxdoo
100 98
make PYTHON=%{_bindir}/python SYSCONFDIR=%{_sysconfdir}
101 99

  
102 100
%install
pkg/vigigraph.redhat.spec
37 37
%setup -q -n %{module}-%{version}
38 38
# A cause des permissions sur /var/log/httpd sur Red Hat
39 39
sed -i -e '/<IfModule mod_wsgi\.c>/a WSGISocketPrefix run/wsgi' deployment/%{module}.conf
40
make qooxdoo_source
41 40

  
42 41
%build
43
make qooxdoo
44 42
make PYTHON=%{__python} SYSCONFDIR=%{_sysconfdir}
45 43

  
46 44
%install
setup.py
1 1
# -*- coding: utf-8 -*-
2 2
# vim:set expandtab tabstop=4 shiftwidth=4:
3

  
3 4
import os
5

  
4 6
try:
5 7
    from setuptools import setup, find_packages
6 8
except ImportError:
......
8 10
    use_setuptools()
9 11
    from setuptools import setup, find_packages
10 12

  
13
cmdclass = {}
14
try:
15
    from babeljs import compile_catalog_plusjs
16
except ImportError:
17
    pass
18
else:
19
    cmdclass['compile_catalog'] = compile_catalog_plusjs
20

  
11 21
sysconfdir = os.getenv("SYSCONFDIR", "/etc")
12 22

  
13 23
tests_require = [
......
38 48
    package_data={
39 49
        'vigigraph': [
40 50
            'i18n/*/LC_MESSAGES/*.mo',
51
            'i18n/*/LC_MESSAGES/*.js',
41 52
            'templates/*/*',
42 53
            'public/js/*.js',
43
#            'public/*/*',
44 54
        ],
45 55
    },
46 56
    message_extractors={
47 57
        'vigigraph': [
48 58
            ('**.py', 'python', None),
59
            ('**/public/js/*.js', 'javascript', None),
49 60
        ],
50 61
    },
51 62

  
......
61 72
        ],
62 73
    },
63 74

  
75
    cmdclass=cmdclass,
64 76
    data_files=[
65 77
        (os.path.join(sysconfdir, 'vigilo/vigigraph/'), [
66 78
            'deployment/vigigraph.conf',
vigigraph/controllers/root.py
4 4

  
5 5
import logging
6 6
from tg import expose, flash, require, request, redirect
7
from pylons.i18n import ugettext as _, lazy_ugettext as l_
7
from pylons.i18n import ugettext as _, lazy_ugettext as l_, get_lang
8 8
from repoze.what.predicates import Any, All, not_anonymous, \
9 9
                                    has_permission, in_group
10 10

  
......
45 45
        """Handle the front-page."""
46 46
        return dict(page='index')
47 47

  
48
    @expose()
49
    def i18n(self):
50
        import gettext
51
        import pylons
52
        import os.path
53

  
54
        # Repris de pylons.i18n.translation:_get_translator.
55
        conf = pylons.config.current_conf()
56
        try:
57
            rootdir = conf['pylons.paths']['root']
58
        except KeyError:
59
            rootdir = conf['pylons.paths'].get('root_path')
60
        localedir = os.path.join(rootdir, 'i18n')
61

  
62
        # Localise le fichier *.mo actuellement chargé
63
        # et génère le chemin jusqu'au *.js correspondant.
64
        filename = gettext.find(conf['pylons.package'], localedir,
65
            languages=get_lang())
66
        js = filename[:-3] + '.js'
67

  
68
        # Récupère et envoie le contenu du fichier de traduction *.js.
69
        fhandle = open(js, 'r')
70
        translations = fhandle.read()
71
        fhandle.close()
72
        return translations
73

  
48 74
    @expose('login.html')
49 75
    def login(self, came_from='/'):
50 76
        """Start the user login."""
vigigraph/controllers/rpc.py
19 19
                                    in_group, Any, All
20 20
from formencode import validators, schema
21 21
from sqlalchemy import or_
22
from sqlalchemy.sql.expression import literal_column
22 23

  
23 24
from vigilo.turbogears.controllers import BaseController
24 25
from vigilo.turbogears.helpers import get_current_user
......
35 36
from vigilo.models.tables.secondary_tables import GRAPH_PERFDATASOURCE_TABLE
36 37
from vigilo.models.functions import sql_escape_like
37 38

  
38
from vigigraph.widgets.searchhostform import SearchHostForm
39

  
40 39
LOGGER = logging.getLogger(__name__)
41 40

  
42 41
__all__ = ['RpcController']
......
78 77
            flash("'%s': %s" % (k, tmpl_context.form_errors[k]), 'error')
79 78
        redirect(request.environ.get('HTTP_REFERER', '/'))
80 79

  
81
    @expose('json')
82
    def maingroups(self, nocache=None):
83
        """
84
        Determination des groupes principaux (sans parent)
85

  
86
        @return: Dictionnaire dont la clé "items" contient une liste
87
            de tuples contenant le nom et l'ID des groupes d'éléments
88
            au sommet de la hiérarchie et auquels l'utilisateur a accès.
89
        @rtype: C{dict}
90
        @note: L'ID des groupes est converti en chaîne de caractères
91
            dans le résultat.
92
        """
93
        user = get_current_user()
94
        if user is None:
95
            return dict(items=[])
96

  
97
        groups_with_parents = DBSession.query(
98
                GroupHierarchy.idparent,
99
            ).distinct()
100

  
101
        # Les managers ont accès à tout.
102
        # Les autres ont un accès restreint.
103
        is_manager = in_group('managers').is_met(request.environ)
104
        if not is_manager:
105
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
106
            groups_with_parents = groups_with_parents.filter(
107
                GroupHierarchy.idchild.in_(supitemgroups))
108

  
109
        groups_with_parents = [g.idparent for g in groups_with_parents.all()]
110
        children = DBSession.query(
111
                SupItemGroup
112
            ).distinct(
113
            ).join(
114
                (GroupHierarchy, GroupHierarchy.idchild == SupItemGroup.idgroup)
115
            ).filter(GroupHierarchy.hops > 0)
116

  
117
        topgroups = DBSession.query(
118
                SupItemGroup,
119
            ).filter(SupItemGroup.idgroup.in_(groups_with_parents)
120
            ).except_(children).order_by(SupItemGroup.name)
121
        topgroups = [(sig.name, str(sig.idgroup)) for sig in topgroups.all()]
122
        return dict(items=topgroups)
123

  
124
    class HostgroupsSchema(schema.Schema):
125
        """Schéma de validation pour la méthode L{hostgroups}."""
126
        maingroupid = validators.Int(not_empty=True)
127
        nocache = validators.String(if_missing=None)
128

  
129
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
130
    @validate(
131
        validators = HostgroupsSchema(),
132
        error_handler = process_form_errors)
133
    @expose('json')
134
    def hostgroups(self, maingroupid, nocache):
135
        """
136
        Determination des groupes associes au groupe parent
137
        dont identificateur = argument
138

  
139
        @param maingroupid: identificateur d un groupe principal
140
        @type maingroupid: C{int}
141

  
142
        @return: Dictionnaire dont la clé "items" contient une liste
143
            de tuples avec le nom et l'ID des groupes d'éléments
144
            auxquels l'utilisateur a accès.
145
        @rtype: C{dict}
146
        @note: L'ID des groupes est converti en chaîne de caractères
147
            dans le résultat.
148
        """
149
        user = get_current_user()
150
        if user is None:
151
            return dict(items=[])
152

  
153
        hostgroups = DBSession.query(
154
                SupItemGroup.name,
155
                SupItemGroup.idgroup,
156
            ).distinct().join(
157
                (GroupHierarchy, GroupHierarchy.idchild == \
158
                    SupItemGroup.idgroup),
159
            ).filter(GroupHierarchy.idparent == maingroupid
160
            ).filter(GroupHierarchy.hops == 1
161
            ).order_by(SupItemGroup.name.asc())
162

  
163
        # Les managers ont accès à tout.
164
        # Les autres ont un accès restreint.
165
        is_manager = in_group('managers').is_met(request.environ)
166
        if not is_manager:
167
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
168
            hostgroups = hostgroups.filter(
169
                SupItemGroup.idgroup.in_(supitemgroups))
170

  
171
        hostgroups = [(hg.name, str(hg.idgroup)) for hg in hostgroups.all()]
172
        hostgroups.insert(0, (_('No subgroup'), str(maingroupid)))
173
        return dict(items=hostgroups)
174

  
175
    class HostsSchema(schema.Schema):
176
        """Schéma de validation pour la méthode L{hosts}."""
177
        othergroupid = validators.Int(not_empty=True)
178
        nocache = validators.String(if_missing=None)
179

  
180
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
181
    @validate(
182
        validators = HostsSchema(),
183
        error_handler = process_form_errors)
184
    @expose('json')
185
    def hosts(self, othergroupid, nocache):
186
        """
187
        Determination des hotes associes au groupe
188
        dont identificateur = argument
189

  
190
        @param othergroupid : identificateur d un groupe
191
        @type othergroupid : int
192

  
193
        @return: hotes
194
        @rtype: document json (sous forme de dict)
195
        """
196
        user = get_current_user()
197
        if user is None:
198
            return dict(items=[])
199

  
200
        groups_with_parents = DBSession.query(
201
                GroupHierarchy.idparent,
202
            ).distinct()
203

  
204
        # Les managers ont accès à tout.
205
        # Les autres ont un accès restreint.
206
        is_manager = in_group('managers').is_met(request.environ)
207
        if not is_manager:
208
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
209
            groups_with_parents = groups_with_parents.filter(
210
                GroupHierarchy.idchild.in_(supitemgroups))
211

  
212
        groups_with_parents = [g.idparent for g in groups_with_parents.all()]
213
        hosts = DBSession.query(
214
                Host.name,
215
                Host.idhost,
216
            ).distinct(
217
            ).join(
218
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
219
                    Host.idhost),
220
            ).filter(SUPITEM_GROUP_TABLE.c.idgroup == othergroupid
221
            ).filter(SUPITEM_GROUP_TABLE.c.idgroup.in_(groups_with_parents)
222
            ).order_by(
223
                Host.name.asc(),
224
            ).all()
225

  
226
        hosts = [(h.name, str(h.idhost)) for h in hosts]
227
        return dict(items=hosts)
228

  
229
    class GraphGroupsSchema(schema.Schema):
230
        """Schéma de validation pour la méthode L{graphgroups}."""
231
        idhost = validators.Int(not_empty=True)
232
        nocache = validators.String(if_missing=None)
233

  
234
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
235
    @validate(
236
        validators = GraphGroupsSchema(),
237
        error_handler = process_form_errors)
238
    @expose('json')
239
    def graphgroups(self, idhost, nocache):
240
        """
241
        Determination des groupes de graphes associes a l hote
242
        dont identificateur = argument
243

  
244
        @param idhost : identificateur d un hote
245
        @type idhost : int
246

  
247
        @return: groupes de service
248
        @rtype: document json (sous forme de dict)
249
        """
250
        user = get_current_user()
251
        if user is None:
252
            return dict(items=[])
253

  
254
        graphgroups = DBSession.query(
255
                GraphGroup.name,
256
                GraphGroup.idgroup,
257
            ).distinct(
258
            ).join(
259
                (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \
260
                    GraphGroup.idgroup),
261
                (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
262
                (GRAPH_PERFDATASOURCE_TABLE, \
263
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
264
                (PerfDataSource, PerfDataSource.idperfdatasource == \
265
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
266
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
267
                    PerfDataSource.idhost),
268
            ).filter(PerfDataSource.idhost == idhost
269
            ).order_by(GraphGroup.name.asc())
270

  
271
        # Les managers ont accès à tout.
272
        # Les autres ont un accès restreint.
273
        is_manager = in_group('managers').is_met(request.environ)
274
        if not is_manager:
275
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
276
            graphgroups = graphgroups.filter(
277
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
278

  
279
        graphgroups = [(gg.name, str(gg.idgroup)) for gg in graphgroups.all()]
280
        return dict(items=graphgroups)
281

  
282
    class GraphsSchema(schema.Schema):
283
        """Schéma de validation pour la méthode L{graphs}."""
284
        idgraphgroup = validators.Int(not_empty=True)
285
        idhost = validators.Int(not_empty=True)
286
        nocache = validators.String(if_missing=None)
287

  
288
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
289
    @validate(
290
        validators = GraphsSchema(),
291
        error_handler = process_form_errors)
292
    @expose('json')
293
    def graphs(self, idgraphgroup, idhost, nocache):
294
        """
295
        Determination des graphes
296
        avec un service dont identificateur = argument
297

  
298
        @param idgraph : identificateur d un service
299
        @type idgraph : int
300

  
301
        @return: graphes
302
        @rtype: document json (sous forme de dict)
303
        """
304
        user = get_current_user()
305
        if user is None:
306
            return dict(items=[])
307

  
308
        graphs = DBSession.query(
309
                Graph.name,
310
                Graph.idgraph,
311
            ).distinct().join(
312
                (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgraph == \
313
                    Graph.idgraph),
314
                (GraphGroup, GraphGroup.idgroup == \
315
                    GRAPH_GROUP_TABLE.c.idgroup),
316
                (GRAPH_PERFDATASOURCE_TABLE, \
317
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
318
                (PerfDataSource, PerfDataSource.idperfdatasource == \
319
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
320
                (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
321
                    PerfDataSource.idhost),
322
            ).filter(GraphGroup.idgroup == idgraphgroup
323
            ).filter(PerfDataSource.idhost == idhost
324
            ).order_by(Graph.name.asc())
325

  
326
        # Les managers ont accès à tout.
327
        # Les autres ont un accès restreint.
328
        is_manager = in_group('managers').is_met(request.environ)
329
        if not is_manager:
330
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
331
            graphs = graphs.filter(
332
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
333

  
334
        graphs = [(pds.name, str(pds.idgraph)) for pds in graphs.all()]
335
        return dict(items=graphs)
336

  
337 80
    class SearchHostAndGraphSchema(schema.Schema):
338 81
        """Schéma de validation pour la méthode L{searchHostAndGraph}."""
339
        host = validators.String(if_missing=None)
340
        graph = validators.String(if_missing=None)
341
        nocache = validators.String(if_missing=None)
82
        search_form_host = validators.String(if_missing=None)
83
        search_form_graph = validators.String(if_missing=None)
342 84

  
343 85
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
344 86
    @validate(
345 87
        validators = SearchHostAndGraphSchema(),
346 88
        error_handler = process_form_errors)
347 89
    @expose('json')
348
    def searchHostAndGraph(self, host, graph, nocache):
90
    def searchHostAndGraph(self, search_form_host, search_form_graph):
349 91
        """
350 92
        Determination des couples (hote-graphe) repondant aux criteres de
351 93
        recherche sur hote et/ou graphe.
......
369 111
        # On a un nom d'indicateur, mais pas de nom d'hôte,
370 112
        # on considère que l'utilisateur veut tous les indicateurs
371 113
        # correspondant au motif, quel que soit l'hôte.
372
        if graph is not None:
373
            if host is None:
374
                host = '*'
114
        if search_form_graph:
115
            if not search_form_host:
116
                search_form_host = '*'
375 117

  
376
            host = sql_escape_like(host)
377
            graph = sql_escape_like(graph)
118
            search_form_host = sql_escape_like(search_form_host)
119
            search_form_graph = sql_escape_like(search_form_graph)
378 120

  
379 121
            items = DBSession.query(
122
                    Host.idhost.label('idhost'),
380 123
                    Host.name.label('hostname'),
124
                    Graph.idgraph.label('idgraph'),
381 125
                    Graph.name.label('graphname'),
382 126
                ).distinct().join(
383 127
                    (PerfDataSource, PerfDataSource.idhost == Host.idhost),
......
388 132
                        GRAPH_PERFDATASOURCE_TABLE.c.idgraph),
389 133
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
390 134
                        Host.idhost),
391
                ).filter(Host.name.ilike(host)
392
                ).filter(Graph.name.ilike(graph)
135
                ).filter(Host.name.ilike(search_form_host)
136
                ).filter(Graph.name.ilike(search_form_graph)
393 137
                ).order_by(
394 138
                    Host.name.asc(),
395 139
                    Graph.name.asc(),
......
398 142
        # On a ni hôte, ni indicateur. On renvoie une liste vide.
399 143
        # Si l'utilisateur voulait vraiment quelque chose,
400 144
        # il n'avait qu'à le demander.
401
        elif host is None:
145
        elif not search_form_host:
402 146
            return []
403 147

  
404 148
        # Sinon, on a juste un motif pour un hôte.
405 149
        # On renvoie la liste des hôtes correspondant.
406 150
        else:
407
            host = sql_escape_like(host)
151
            search_form_host = sql_escape_like(search_form_host)
408 152
            items = DBSession.query(
153
                    Host.idhost.label('idhost'),
409 154
                    Host.name.label('hostname'),
410 155
                ).distinct().join(
411 156
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idsupitem == \
412 157
                        Host.idhost),
413
                ).filter(Host.name.ilike(host)
158
                ).filter(Host.name.ilike(search_form_host)
414 159
                ).order_by(Host.name.asc())
415 160

  
416 161
        # Les managers ont accès à tout.
......
423 168
                SUPITEM_GROUP_TABLE.c.idgroup.in_(supitemgroups))
424 169

  
425 170
        items = items.limit(100).all() # pylint: disable-msg=E1103
426
        if graph is None:
427
            items = [(item.hostname, "") for item in items]
171
        if not search_form_graph:
172
            ids = [(item.idhost, None) for item in items]
173
            labels = [(item.hostname, None) for item in items]
428 174
        else:
429
            items = [(item.hostname, item.graphname) for item in items]
430
        return dict(items=items)
431

  
432
    class SelectHostAndGraphSchema(schema.Schema):
433
        """Schéma de validation pour la méthode L{selectHostAndGraph}."""
434
        host = validators.String(if_missing=None)
435
        graph = validators.String(if_missing=None)
436
        nocache = validators.String(if_missing=None)
437

  
438
    # @TODO définir un error_handler différent pour remonter l'erreur via JS.
439
    @validate(
440
        validators = SelectHostAndGraphSchema(),
441
        error_handler = process_form_errors)
442
    @expose('json')
443
    def selectHostAndGraph(self, host, graph, nocache):
444
        """
445
        Renvoie les valeurs à sélectionner dans les comboboxes
446
        de VigiGraph pour afficher les données de l'hôte ou du
447
        couple hôte/graphe sélectionné.
448

  
449
        La clé "items" du dictionnaire renvoyé contient une liste avec
450
        2 éléments, chacun de ces éléments étant lui-même une liste.
451
        La 1ère liste contient les noms des groupes d'hôtes à sélectionner.
452
        La 2ème liste contient la liste des groupes de graphes à sélectionner.
453

  
454
        Pour le moment, la 2ème liste contiendra au plus 1 élément car
455
        les groupes de graphes ne sont pas récursifs. L'utilisation d'une
456
        liste permet d'assurer facilement une évolution vers des groupes
457
        de graphes récursifs.
458
        """
459
        user = get_current_user()
460
        if user is None:
461
            return dict(items=[[], []])
462

  
463
        # Ce cas ne devrait pas se produire, mais on tente
464
        # d'avoir un comportement gracieux malgré tout.
465
        if (not host) and (not graph):
466
            return dict(items=[[], []])
467

  
468
        if graph and not host:
469
            raise HTTPPreconditionFailed(_("No host given"))
470

  
471
        selected_hostgroups = []
472
        selected_graphgroups = []
473
        is_manager = in_group('managers').is_met(request.environ)
474

  
475
        supitemgroups = []
476
        if not is_manager:
477
            supitemgroups = [sig[0] for sig in user.supitemgroups() if sig[1]]
478

  
479
        if host:
480
            # Sélectionne l'identifiant du premier SupItemGroup auquel
481
            # l'utilisateur a accès et auquel l'hôte donné appartient.
482
            idsupitemgroup = DBSession.query(
483
                    SupItemGroup.idgroup,
484
                ).distinct().join(
485
                    (SUPITEM_GROUP_TABLE, SUPITEM_GROUP_TABLE.c.idgroup == \
486
                        SupItemGroup.idgroup),
487
                    (Host, Host.idhost == SUPITEM_GROUP_TABLE.c.idsupitem),
488
                ).filter(Host.name == host)
489

  
490
            # On prend en compte les permissions de l'utilisateur.
491
            if not is_manager:
492
                idsuitemgroup = idsupitemgroup.filter(
493
                    SupItemGroup.idgroup.in_(supitemgroups))
494

  
495
            idsupitemgroup = idsupitemgroup.scalar()
496

  
497
            # Si on a trouvé un tel groupe, on renvoie les noms des
498
            # groupes de la hiérarchie à sélectionner pour arriver
499
            # à celui-ci.
500
            if idsupitemgroup is not None:
501
                selected_hostgroups = DBSession.query(
502
                        SupItemGroup.name,
503
                    ).distinct().join(
504
                        (GroupHierarchy, GroupHierarchy.idparent == \
505
                            GraphGroup.idgroup),
506
                    ).filter(GroupHierarchy.idchild == idsupitemgroup
507
                    ).order_by(
508
                        GroupHierarchy.hops.desc()
509
                    ).all()
510

  
511
        if graph:
512
            # Le principe est le même que pour l'hôte, en considérant
513
            # cette fois les GraphGroup à la place des SupItemGroup.
514
            idgraphgroup = DBSession.query(
515
                    GraphGroup.idgroup,
516
                ).join(
517
                    (GRAPH_GROUP_TABLE, GRAPH_GROUP_TABLE.c.idgroup == \
518
                        GraphGroup.idgroup),
519
                    (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
520
                ).filter(Graph.name == graph)
521

  
522
            # On prend en compte les permissions de l'utilisateur.
523
            if not is_manager:
524
                idgraphgroup = idgraphgroup.filter(
525
                    GraphGroup.idgroup.in_(supitemgroups))
526

  
527
            idgraphgroup = idgraphgroup.scalar()
528

  
529
            # Même principe que pour l'hôte.
530
            if idgraphgroup is not None:
531
                selected_graphgroups = DBSession.query(
532
                        GraphGroup.name,
533
                    ).join(
534
                        (GroupHierarchy, GroupHierarchy.idparent == \
535
                            GraphGroup.idgroup),
536
                    ).filter(GroupHierarchy.idchild == idgraphgroup
537
                    ).order_by(
538
                        GroupHierarchy.hops.desc()
539
                    ).all()
540

  
541
        hostgroups = [hg.name for hg in selected_hostgroups]
542
        # @FIXME: Ce test est nécessaire tant que l'interface Qooxdoo
543
        # monolithique est conservée (ie: 2 niveaux de profondeur figés).
544
        if len(hostgroups) == 1:
545
            hostgroups.append(_('No subgroup'))
546
        graphgroups = [gg.name for gg in selected_graphgroups]
547
        return dict(items=[hostgroups, graphgroups])
175
            ids = [(item.idhost, item.idgraph) for item in items]
176
            labels = [(item.hostname, item.graphname) for item in items]
177
        return dict(labels=labels, ids=ids)
548 178

  
549 179
    @expose('graphslist.html')
550 180
    def graphsList(self, nocache=None, **kwargs):
......
584 214
            graphslist.append(graph)
585 215
        return dict(graphslist=graphslist)
586 216

  
587
    @expose(content_type='text/plain')
217
    @expose('json')
588 218
    def tempoDelayRefresh(self, nocache=None):
589 219
        """
590 220
        Determination valeur temporisation pour le rafraichissement automatique
......
598 228
            delay = int(config['refresh_delay'])
599 229
        except (ValueError, KeyError):
600 230
            delay = 30
601
        return str(delay)
231
        return {'delay': delay}
602 232

  
603 233
    class GetIndicatorsSchema(schema.Schema):
604 234
        """Schéma de validation pour la méthode L{getIndicators}."""
......
738 368
        return dict(host=host, graph=graph, start=start, duration=duration, \
739 369
                    presets=self.presets)
740 370

  
741
    @expose('searchhostform.html')
742
    def searchHostForm(self):
743
        """
744
        Formulaire de recherche sur les hotes
745

  
746
        @return: page avec formulaire de recherche
747
        @rtype: page html
748
        """
749
        searchhostform = SearchHostForm('search_host_form', \
750
            submit_text=None)
751

  
752
        return dict(searchhostform=searchhostform)
753

  
754 371
    @expose('searchhost.html')
755 372
    @paginate('hosts', items_per_page=10)
756 373
    def searchHost(self, *args, **kwargs):
......
806 423
        """
807 424
        return dict()
808 425

  
426
    @expose('json')
427
    def hosttree(self, parent_id=None):
428

  
429
        # Si l'identifiant du groupe parent n'est pas
430
        # spécifié, on retourne la liste des groupes racines,
431
        # fournie par la méthode get_root_hosts_groups.
432
        if parent_id is None:
433
            return self.get_root_host_groups()
434

  
435
        # TODO: Utiliser un schéma de validation
436
        parent_id = int(parent_id)
437

  
438
        # On vérifie si le groupe parent fait partie des
439
        # groupes auxquel l'utilisateur a accès, et on
440
        # retourne une liste vide dans le cas contraire
441
        is_manager = in_group('managers').is_met(request.environ)
442
        if not is_manager:
443
            direct_access = False
444
            user = get_current_user()
445
            user_groups = dict(user.supitemgroups())
446
            # On regarde d'abord si le groupe fait partie de ceux
447
            # auquels l'utilisateur a explicitement accès, ou s'il
448
            # est un parent des groupes auxquels l'utilisateur a accès
449
            if parent_id in user_groups.keys():
450
                direct_access = user_groups[parent_id]
451
            # Dans le cas contraire, on vérifie si le groupe est un
452
            # sous-groupe des groupes auxquels l'utilisateur a accès
453
            else:
454
                id_list = [ug for ug in user_groups.keys() if user_groups[ug]]
455
                child_groups = DBSession.query(SupItemGroup.idgroup
456
                    ).distinct(
457
                    ).join(
458
                        (GroupHierarchy,
459
                            GroupHierarchy.idchild == SupItemGroup.idgroup),
460
                    ).filter(GroupHierarchy.idparent.in_(id_list)
461
                    ).filter(GroupHierarchy.hops > 0
462
                    ).all()
463
                for ucg in child_groups:
464
                    if ucg.idgroup == parent_id:
465
                        direct_access = True
466
                        break
467
                # Sinon, l'utilisateur n'a pas accès à ce groupe
468
                else:
469
                    return dict(groups = [], leaves = [])
470

  
471
        # On récupère la liste des groupes dont
472
        # l'identifiant du parent est passé en paramètre
473
        db_groups = DBSession.query(
474
            SupItemGroup
475
        ).join(
476
            (GroupHierarchy, GroupHierarchy.idchild == \
477
                SupItemGroup.idgroup),
478
        ).filter(GroupHierarchy.hops == 1
479
        ).filter(GroupHierarchy.idparent == parent_id
480
        ).order_by(SupItemGroup.name.asc())
481
        if not is_manager and not direct_access:
482
            id_list = [ug for ug in user_groups.keys() if not user_groups[ug]]
483
            db_groups = db_groups.filter(
484
                SupItemGroup.idgroup.in_(id_list))
485
        groups = []
486
        for group in db_groups.all():
487
            #if group.has_children() or len(group.hosts)>0:
488
            groups.append({
489
                'id'   : group.idgroup,
490
                'name' : group.name,
491
            })
492

  
493
        # On récupère la liste des hôtes appartenant au
494
        # groupe dont l'identifiant est passé en paramètre
495
        hosts = []
496
        if is_manager or direct_access:
497
            db_hosts = DBSession.query(
498
                Host.idhost,
499
                Host.name,
500
            ).join(
501
                (SUPITEM_GROUP_TABLE,
502
                    SUPITEM_GROUP_TABLE.c.idsupitem == Host.idhost
503
                    ),
504
            ).filter(SUPITEM_GROUP_TABLE.c.idgroup == parent_id
505
            ).order_by(Host.name.asc())
506
            hosts = []
507
            for host in db_hosts.all():
508
                hosts.append({
509
                    'id'   : host.idhost,
510
                    'name' : host.name,
511
                })
512

  
513
        return dict(groups = groups, leaves = hosts)
514

  
515
    @expose('json')
516
    def graphtree(self, host_id=None, parent_id=None):
517

  
518
        # Si l'identifiant de l'hôte n'est pas spécifié, on
519
        # retourne un dictionnaire contenant deux listes vides
520
        if host_id is None:
521
            return dict(groups = [], graphs=[])
522

  
523
        # On vérifie les permissions sur l'hôte
524
        # TODO: Utiliser un schéma de validation
525
        host_id = int(host_id)
526
        host = DBSession.query(Host
527
            ).filter(Host.idhost == host_id
528
            ).first()
529
        if host is None:
530
            return dict(groups = [], graphs=[])
531
        user = get_current_user()
532
        if not host.is_allowed_for(user):
533
            return dict(groups = [], graphs=[])
534

  
535
        # On récupère la liste des groupes de graphes associé à l'hôte
536
        host_graph_groups = DBSession.query(
537
            GraphGroup
538
        ).distinct(
539
        ).join(
540
            (GRAPH_GROUP_TABLE, \
541
                GRAPH_GROUP_TABLE.c.idgroup == GraphGroup.idgroup),
542
            (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
543
            (GRAPH_PERFDATASOURCE_TABLE, \
544
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
545
            (PerfDataSource, PerfDataSource.idperfdatasource == \
546
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
547
            (SUPITEM_GROUP_TABLE, \
548
                SUPITEM_GROUP_TABLE.c.idsupitem == PerfDataSource.idhost),
549
        ).filter(PerfDataSource.idhost == host_id
550
        ).order_by(GraphGroup.name.asc())
551

  
552
        # Si l'identifiant du groupe parent n'est pas spécifié,
553
        # on récupère la liste des groupes de graphes racines.
554
        if parent_id is None:
555
            graph_groups = GraphGroup.get_top_groups()
556

  
557
        # Sinon on récupère la liste des graphes dont le
558
        # groupe passé en paramètre est le parent direct
559
        else:
560
            # TODO: Utiliser un schéma de validation
561
            parent_id = int(parent_id)
562
            graph_groups = DBSession.query(
563
                GraphGroup
564
            ).join(
565
                (GroupHierarchy, GroupHierarchy.idchild == \
566
                    GraphGroup.idgroup),
567
            ).filter(GroupHierarchy.hops == 1
568
            ).filter(GroupHierarchy.idparent == parent_id
569
            ).order_by(GraphGroup.name.asc())
570

  
571
        # On réalise l'intersection des deux listes
572
        groups = []
573
        for gg in graph_groups:
574
            if gg in host_graph_groups:
575
                groups.append({
576
                    'id'   : gg.idgroup,
577
                    'name' : gg.name,
578
                })
579

  
580
        # On récupère la liste des graphes appartenant au
581
        # groupe dont l'identifiant est passé en paramètre
582
        graphs = []
583
        if parent_id:
584
            db_graphs = DBSession.query(
585
                Graph.idgraph,
586
                Graph.name,
587
            ).join(
588
                (GRAPH_GROUP_TABLE,
589
                    GRAPH_GROUP_TABLE.c.idgraph == Graph.idgraph
590
                    ),
591
            ).filter(GRAPH_GROUP_TABLE.c.idgroup == parent_id
592
            ).order_by(Graph.name.asc())
593
            for graph in db_graphs.all():
594
                graphs.append({
595
                    'id'   : graph.idgraph,
596
                    'name' : graph.name,
597
                })
598

  
599
        return dict(groups = groups, leaves = graphs)
600

  
601
    def get_root_host_groups(self):
602
        """
603
        Retourne tous les groupes racines (c'est à dire n'ayant
604
        aucun parent) d'hôtes auquel l'utilisateur a accès.
605

  
606
        @return: Un dictionnaire contenant la liste de ces groupes.
607
        @rtype : C{dict} of C{list} of C{dict} of C{mixed}
608
        """
609

  
610
        # On récupère tous les groupes qui ont un parent.
611
        children = DBSession.query(
612
            SupItemGroup,
613
        ).distinct(
614
        ).join(
615
            (GroupHierarchy, GroupHierarchy.idchild == SupItemGroup.idgroup)
616
        ).filter(GroupHierarchy.hops > 0)
617

  
618
        # Ensuite on les exclut de la liste des groupes,
619
        # pour ne garder que ceux qui sont au sommet de
620
        # l'arbre et qui constituent nos "root groups".
621
        root_groups = DBSession.query(
622
            SupItemGroup,
623
        ).except_(children
624
        ).order_by(SupItemGroup.name)
625

  
626
        # On filtre ces groupes racines afin de ne
627
        # retourner que ceux auquels l'utilisateur a accès
628
        user = get_current_user()
629
        is_manager = in_group('managers').is_met(request.environ)
630
        if not is_manager:
631
            user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
632
            root_groups = root_groups.filter(
633
                SupItemGroup.idgroup.in_(user_groups))
634

  
635
        groups = []
636
        for group in root_groups.all():
637
            #if group.has_children() or len(group.hosts)>0:
638
            groups.append({
639
                'id'   : group.idgroup,
640
                'name' : group.name,
641
            })
642

  
643
        return dict(groups = groups, hosts=[])
644

  
645
    def get_root_graph_groups(self, host_id):
646
        """
647
        Retourne tous les groupes racines (c'est à dire n'ayant
648
        aucun parent) de graphes auquel l'utilisateur a accès et
649
        concernant l'hôte dont l'identifiant est passé en paramètre.
650

  
651
        @return: Un dictionnaire contenant la liste de ces groupes.
652
        @rtype : C{dict} of C{list} of C{dict} of C{mixed}
653
        """
654

  
655
        # On récupère tous les groupes qui ont un parent.
656
        children = DBSession.query(
657
            Graph,
658
        ).distinct(
659
        ).join(
660
            (GroupHierarchy, GroupHierarchy.idchild == SupItemGroup.idgroup)
661
        ).filter(GroupHierarchy.hops > 0)
662

  
663
        # On récupère tous les groupes racines de graphes portant sur l'hôte
664
        # souhaité, en éliminant les groupes récupérés à l'étape précédente
665
        graph_groups = DBSession.query(
666
            GraphGroup
667
        ).distinct(
668
        ).join(
669
            (GRAPH_GROUP_TABLE, \
670
                GRAPH_GROUP_TABLE.c.idgroup == GraphGroup.idgroup),
671
            (Graph, Graph.idgraph == GRAPH_GROUP_TABLE.c.idgraph),
672
            (GRAPH_PERFDATASOURCE_TABLE, \
673
                    GRAPH_PERFDATASOURCE_TABLE.c.idgraph == Graph.idgraph),
674
            (PerfDataSource, PerfDataSource.idperfdatasource == \
675
                    GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource),
676
            (SUPITEM_GROUP_TABLE, \
677
                SUPITEM_GROUP_TABLE.c.idsupitem == PerfDataSource.idhost),
678
        ).filter(PerfDataSource.idhost == host_id
679
#        ).except_(children
680
        ).order_by(GraphGroup.name.asc())
681

  
682
        # On filtre ces groupes racines afin de ne
683
        # retourner que ceux auquels l'utilisateur a accès
684
        user = get_current_user()
685
        is_manager = in_group('managers').is_met(request.environ)
686
        if not is_manager:
687
            user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]]
688
            graph_groups = graph_groups.filter(
689
                SUPITEM_GROUP_TABLE.c.idgroup.in_(user_groups))
690

  
691
        groups = []
692
        for group in graph_groups.all():
693
            #if group.has_children() or len(group.graphs)>0:
694
            groups.append({
695
                'id'   : group.idgroup,
696
                'name' : group.name,
697
            })
698

  
699
        return dict(groups = groups, graphs=[])
700

  
809 701
    def getListIndicators(self, host, graph):
810 702
        """
811 703
        Liste d indicateurs associes a un graphe
......
833 725
                ).filter(Host.name == host
834 726
                ).all()
835 727
        return indicators
728

  
vigigraph/i18n/en/LC_MESSAGES/vigigraph.po
7 7
msgstr ""
8 8
"Project-Id-Version: vigigraph 2.0.0\n"
9 9
"Report-Msgid-Bugs-To: contact@projet-vigilo.org\n"
10
"POT-Creation-Date: 2010-10-29 14:32+0200\n"
11
"PO-Revision-Date: 2010-10-29 14:32+0200\n"
10
"POT-Creation-Date: 2010-11-03 17:22+0100\n"
11
"PO-Revision-Date: 2010-11-03 17:23+0100\n"
12 12
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 13
"Language-Team: en <LL@li.org>\n"
14 14
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
......
26 26
msgid "You don't have access to VigiGraph"
27 27
msgstr "You don't have access to VigiGraph"
28 28

  
29
#: vigigraph/controllers/root.py:55
29
#: vigigraph/controllers/root.py:81
30 30
msgid "Wrong credentials"
31 31
msgstr "Wrong credentials"
32 32

  
33
#: vigigraph/controllers/root.py:70
33
#: vigigraph/controllers/root.py:96
34 34
#, python-format
35 35
msgid "\"%(username)s\" logged in (from %(IP)s)"
36 36
msgstr "\"%(username)s\" logged in (from %(IP)s)"
37 37

  
38
#: vigigraph/controllers/root.py:74
38
#: vigigraph/controllers/root.py:100
39 39
#, python-format
40 40
msgid "Welcome back, %s!"
41 41
msgstr "Welcome back, %s!"
42 42

  
43
#: vigigraph/controllers/root.py:84
43
#: vigigraph/controllers/root.py:110
44 44
#, python-format
45 45
msgid "Some user logged out (from %(IP)s)"
46 46
msgstr "Some user logged out (from %(IP)s)"
47 47

  
48
#: vigigraph/controllers/root.py:87
48
#: vigigraph/controllers/root.py:113
49 49
msgid "We hope to see you soon!"
50 50
msgstr "We hope to see you soon!"
51 51

  
......
65 65
msgid "Last %d months"
66 66
msgstr "Last %d months"
67 67

  
68
#: vigigraph/controllers/rpc.py:69
68
#: vigigraph/controllers/rpc.py:69 vigigraph/public/js/graph.js:42
69 69
msgid "Last year"
70 70
msgstr "Last year"
71 71

  
......
83 83
msgid "%a, %d %b %Y %H:%M:%S"
84 84
msgstr "%a, %d %b %Y %H:%M:%S"
85 85

  
86
#: vigigraph/widgets/host_picker.py:13
86
#: vigigraph/public/js/graph.js:12
87
msgid "Reload the graph"
88
msgstr "Reload the graph"
89

  
90
#: vigigraph/public/js/graph.js:16
91
msgid "Timeframe"
92
msgstr "Timeframe"
93

  
94
#: vigigraph/public/js/graph.js:18
95
msgid "Timeframe menu"
96
msgstr "Timeframe menu"
97

  
98
#: vigigraph/public/js/graph.js:21
99
msgid "Last 12 hours"
100
msgstr "Last 12 hours"
101

  
102
#: vigigraph/public/js/graph.js:24
103
msgid "Last 24 hours"
104
msgstr "Last 24 hours"
105

  
106
#: vigigraph/public/js/graph.js:27
107
msgid "Last 48 hours"
108
msgstr "Last 48 hours"
109

  
110
#: vigigraph/public/js/graph.js:30
111
msgid "Last 7 days"
112
msgstr "Last 7 days"
113

  
114
#: vigigraph/public/js/graph.js:33
115
msgid "Last 14 days"
116
msgstr "Last 14 days"
117

  
118
#: vigigraph/public/js/graph.js:36
119
msgid "Last 3 months"
120
msgstr "Last 3 months"
121

  
122
#: vigigraph/public/js/graph.js:39
123
msgid "Last 6 months"
124
msgstr "Last 6 months"
125

  
126
#: vigigraph/public/js/graph.js:47
127
msgid "Graph start"
128
msgstr "Graph start"
129

  
130
#: vigigraph/public/js/graph.js:54
131
msgid "Previous section"
132
msgstr "Previous section"
133

  
134
#: vigigraph/public/js/graph.js:61
135
msgid "Next section"
136
msgstr "Next section"
137

  
138
#: vigigraph/public/js/graph.js:68
139
msgid "Graph end"
140
msgstr "Graph end"
141

  
142
#: vigigraph/public/js/graph.js:75
143
msgid "Zoom in"
144
msgstr "Zoom in"
145

  
146
#: vigigraph/public/js/graph.js:82
147
msgid "Zoom out"
148
msgstr "Zoom out"
149

  
150
#: vigigraph/public/js/graph.js:88
151
msgid "Export to CSV"
152
msgstr "Export to CSV"
153

  
154
#: vigigraph/public/js/graph.js:90
155
msgid "Export the content of this graph to CSV"
156
msgstr "Export the content of this graph to CSV"
157

  
158
#: vigigraph/public/js/graph.js:106
159
msgid "All"
160
msgstr "All"
161

  
162
#: vigigraph/public/js/graph.js:111
163
msgid "Print graph"
164
msgstr "Print graph"
165

  
166
#: vigigraph/public/js/graph.js:119 vigigraph/widgets/host_picker.py:37
167
#: vigigraph/widgets/host_picker.py:76
168
msgid "Graph"
169
msgstr "Graph"
170

  
171
#: vigigraph/public/js/host_picker.js:3
172
msgid "Host Picker"
173
msgstr "Host Picker"
174

  
175
#: vigigraph/widgets/host_picker.py:13 vigigraph/widgets/host_picker.py:52
87 176
msgid "Choose"
88 177
msgstr "Choose"
89 178

  
90
#: vigigraph/widgets/host_picker.py:14
179
#: vigigraph/widgets/host_picker.py:14 vigigraph/widgets/host_picker.py:53
91 180
msgid "→"
92 181
msgstr "→"
93 182

  
94
#: vigigraph/widgets/host_picker.py:36
183
#: vigigraph/widgets/host_picker.py:36 vigigraph/widgets/host_picker.py:75
95 184
msgid "Host"
96 185
msgstr "Host"
97 186

  
98
#: vigigraph/widgets/host_picker.py:37
99
msgid "Graph"
100
msgstr "Graph"
101

  
vigigraph/i18n/fr/LC_MESSAGES/vigigraph.po
8 8
"Project-Id-Version: vigigraph 0.1\n"
9 9
"Report-Msgid-Bugs-To: contact@projet-vigilo.org\n"
10 10
"POT-Creation-Date: 2010-02-15 13:41+0100\n"
11
"PO-Revision-Date: 2010-10-29 14:32+0200\n"
11
"PO-Revision-Date: 2010-11-03 17:22+0100\n"
12 12
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 13
"Language-Team: fr_FR <LL@li.org>\n"
14 14
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
......
26 26
msgid "You don't have access to VigiGraph"
27 27
msgstr "Vous n'avez pas accès à VigiGraph"
28 28

  
29
#: vigigraph/controllers/root.py:55
29
#: vigigraph/controllers/root.py:81
30 30
msgid "Wrong credentials"
31 31
msgstr "Identifiant ou mot de passe incorrect"
32 32

  
33
#: vigigraph/controllers/root.py:70
33
#: vigigraph/controllers/root.py:96
34 34
#, python-format
35 35
msgid "\"%(username)s\" logged in (from %(IP)s)"
36 36
msgstr "\"%(username)s\" s'est connecté (depuis %(IP)s)"
37 37

  
38
#: vigigraph/controllers/root.py:74
38
#: vigigraph/controllers/root.py:100
39 39
#, python-format
40 40
msgid "Welcome back, %s!"
41 41
msgstr "Bienvenue, %s !"
42 42

  
43
#: vigigraph/controllers/root.py:84
43
#: vigigraph/controllers/root.py:110
44 44
#, python-format
45 45
msgid "Some user logged out (from %(IP)s)"
46 46
msgstr "Un utilisateur s'est déconnecté (depuis %(IP)s)"
47 47

  
48
#: vigigraph/controllers/root.py:87
48
#: vigigraph/controllers/root.py:113
49 49
msgid "We hope to see you soon!"
50 50
msgstr "Au plaisir de vous revoir !"
51 51

  
......
65 65
msgid "Last %d months"
66 66
msgstr "Les %d derniers mois"
67 67

  
68
#: vigigraph/controllers/rpc.py:69
68
#: vigigraph/controllers/rpc.py:69 vigigraph/public/js/graph.js:42
69 69
msgid "Last year"
70 70
msgstr "L'an dernier"
71 71

  
......
83 83
msgid "%a, %d %b %Y %H:%M:%S"
84 84
msgstr "%d/%m/%Y à %H:%M:%S"
85 85

  
86
#: vigigraph/widgets/host_picker.py:13
86
#: vigigraph/public/js/graph.js:12
87
msgid "Reload the graph"
88
msgstr "Recharger le graphe"
89

  
90
#: vigigraph/public/js/graph.js:16
91
msgid "Timeframe"
92
msgstr "Période"
93

  
94
#: vigigraph/public/js/graph.js:18
95
msgid "Timeframe menu"
96
msgstr "Menu de choix de la période"
97

  
98
#: vigigraph/public/js/graph.js:21
99
msgid "Last 12 hours"
100
msgstr "12 dernières heures"
101

  
102
#: vigigraph/public/js/graph.js:24
103
msgid "Last 24 hours"
104
msgstr "24 dernières heures"
105

  
106
#: vigigraph/public/js/graph.js:27
107
msgid "Last 48 hours"
108
msgstr "48 dernières heures"
109

  
110
#: vigigraph/public/js/graph.js:30
111
msgid "Last 7 days"
112
msgstr "7 derniers jours"
113

  
114
#: vigigraph/public/js/graph.js:33
115
msgid "Last 14 days"
116
msgstr "14 derniers jours"
117

  
118
#: vigigraph/public/js/graph.js:36
119
msgid "Last 3 months"
120
msgstr "3 derniers mois"
121

  
122
#: vigigraph/public/js/graph.js:39
123
msgid "Last 6 months"
124
msgstr "6 derniers mois"
125

  
126
#: vigigraph/public/js/graph.js:47
127
msgid "Graph start"
128
msgstr "Début du graphe"
129

  
130
#: vigigraph/public/js/graph.js:54
131
msgid "Previous section"
132
msgstr "Section précédente"
133

  
134
#: vigigraph/public/js/graph.js:61
135
msgid "Next section"
136
msgstr "Section suivante"
137

  
138
#: vigigraph/public/js/graph.js:68
139
msgid "Graph end"
140
msgstr "Fin du graphe"
141

  
142
#: vigigraph/public/js/graph.js:75
143
msgid "Zoom in"
144
msgstr "Zoomer"
145

  
146
#: vigigraph/public/js/graph.js:82
147
msgid "Zoom out"
148
msgstr "Dézoomer"
149

  
150
#: vigigraph/public/js/graph.js:88
151
msgid "Export to CSV"
152
msgstr "Export CSV"
153

  
154
#: vigigraph/public/js/graph.js:90
155
msgid "Export the content of this graph to CSV"
156
msgstr "Exporte le contenu du graphe au format CSV"
157

  
158
#: vigigraph/public/js/graph.js:106
159
msgid "All"
160
msgstr "Tous"
161

  
162
#: vigigraph/public/js/graph.js:111
163
msgid "Print graph"
164
msgstr "Imprimer le graphe"
165

  
166
#: vigigraph/public/js/graph.js:119 vigigraph/widgets/host_picker.py:37
167
#: vigigraph/widgets/host_picker.py:76
168
msgid "Graph"
169
msgstr "Graphe"
170

  
171
#: vigigraph/public/js/host_picker.js:3
172
msgid "Host Picker"
173
msgstr "Sélection d'un hôte"
174

  
175
#: vigigraph/widgets/host_picker.py:13 vigigraph/widgets/host_picker.py:52
87 176
msgid "Choose"
88 177
msgstr "Choisir"
89 178

  
90
#: vigigraph/widgets/host_picker.py:14
179
#: vigigraph/widgets/host_picker.py:14 vigigraph/widgets/host_picker.py:53
91 180
msgid "→"
92 181
msgstr "→"
93 182

  
94
#: vigigraph/widgets/host_picker.py:36
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff