]> git.ipfire.org Git - people/ms/westferry.git/blame - src/westferry/handlers/analytics.py
Initialize translation method in graph exporter
[people/ms/westferry.git] / src / westferry / handlers / analytics.py
CommitLineData
21a66327
MT
1#!/usr/bin/python3
2###############################################################################
3# #
4# Westferry - The IPFire web user interface #
5# Copyright (C) 2015 IPFire development team #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
22import datetime
23import collecty.client
24import mimetypes
25import tornado.web
26
27from . import base
a6144752
MT
28from .. import ui
29
3fc6d806 30from ..i18n import N_
a6144752
MT
31
32class AnalyticsBaseHandler(base.BaseHandler):
33 @property
34 def menu(self):
35 _ = self.locale.translate
36
37 m = ui.menu.Menu(self, _("Analytics"))
38
39 # Overview
40 m.add_handler(AnalyticsOverviewHandler)
41 m.add_divider()
42
30806514
MT
43 # Network
44 m.add_handler(AnalyticsNetworkOverviewHandler)
45
a6144752
MT
46 # System
47 m.add_handler(AnalyticsSystemOverviewHandler)
48
49 return m
50
03f518c7
MT
51 def render_graphs(self, graphs):
52 self.render("graphs.html", graphs=graphs)
53
a6144752
MT
54
55class AnalyticsOverviewHandler(AnalyticsBaseHandler):
56 url = r"/analytics"
57 title = N_("Overview")
58
59 def get(self):
60 self.render("base.html")
61
62
30806514
MT
63class AnalyticsNetworkBaseHandler(AnalyticsBaseHandler):
64 @property
65 def menu(self):
66 _ = self.locale.translate
67
68 m = ui.menu.Menu(self, _("Network"))
69
70 # Back...
71 m.add_handler(AnalyticsOverviewHandler, title=_("Back..."))
72 m.add_divider()
73
74 # Overview
75 m.add_handler(AnalyticsNetworkOverviewHandler, title=_("Overview"))
76 m.add_divider()
77
78 # Connections
79 m.add_handler(AnalyticsNetworkConnectionsOverviewHandler)
80
cbc61195
MT
81 # Fragmentation
82 m.add_handler(AnalyticsNetworkIPFragmentationHandler)
83
30806514
MT
84 return m
85
86
87class AnalyticsNetworkOverviewHandler(AnalyticsNetworkBaseHandler):
88 url = r"/analytics/network"
89 title = N_("Network")
90
91 def get(self):
92 self.render("base.html")
93
94
95class AnalyticsNetworkConnectionsBaseHandler(AnalyticsBaseHandler):
96 @property
97 def menu(self):
98 _ = self.locale.translate
99
100 m = ui.menu.Menu(self, _("Connections"))
101
102 # Back...
103 m.add_handler(AnalyticsNetworkOverviewHandler, title=_("Back..."))
104 m.add_divider()
105
106 # Overview
107 m.add_handler(AnalyticsNetworkConnectionsOverviewHandler, title=_("Overview"))
108 m.add_divider()
109
110 # Protocol States
111 s = m.add_submenu(_("Procotol States"))
112 s.add_handler(AnalyticsNetworkConnectionsStatesTCPHandler)
113 s.add_handler(AnalyticsNetworkConnectionsStatesSCTPHandler)
114 s.add_handler(AnalyticsNetworkConnectionsStatesDCCPHandler)
115
116 return m
117
118
119class AnalyticsNetworkConnectionsOverviewHandler(AnalyticsNetworkConnectionsBaseHandler):
120 url = r"/analytics/network/connections"
121 title = N_("Connections")
122
123 def get(self):
124 _ = self.locale.translate
125
126 graphs = [
127 ui.graphs.Graph(self, "conntrack-layer3-protocols"),
128 ui.graphs.Graph(self, "conntrack-layer4-protocols"),
129 ]
130
131 self.render_graphs(graphs)
132
133
134class AnalyticsNetworkConnectionsStatesTCPHandler(AnalyticsNetworkConnectionsBaseHandler):
135 url = r"/analytics/network/connections/states/tcp"
136 title = N_("TCP")
137
138 def get(self):
139 _ = self.locale.translate
140
141 graphs = [
142 ui.graphs.Graph(self, "conntrack-protocol-states", "tcp"),
143 ]
144
145 self.render_graphs(graphs)
146
147
148class AnalyticsNetworkConnectionsStatesSCTPHandler(AnalyticsNetworkConnectionsBaseHandler):
149 url = r"/analytics/network/connections/states/sctp"
150 title = N_("SCTP")
151
152 def get(self):
153 _ = self.locale.translate
154
155 graphs = [
156 ui.graphs.Graph(self, "conntrack-protocol-states", "sctp"),
157 ]
158
159 self.render_graphs(graphs)
160
161
162class AnalyticsNetworkConnectionsStatesDCCPHandler(AnalyticsNetworkConnectionsBaseHandler):
163 url = r"/analytics/network/connections/states/dccp"
164 title = N_("DCCP")
165
166 def get(self):
167 _ = self.locale.translate
168
169 graphs = [
170 ui.graphs.Graph(self, "conntrack-protocol-states", "dccp"),
171 ]
172
173 self.render_graphs(graphs)
174
175
cbc61195
MT
176class AnalyticsNetworkIPFragmentationHandler(AnalyticsNetworkBaseHandler):
177 url = r"/analytics/network/fragmentation"
178 title = N_("Fragmentation")
179
180 def get(self):
181 _ = self.locale.translate
182
183 graphs = [
184 ui.graphs.Graph(self, "ipv6-fragmentation"),
185 ui.graphs.Graph(self, "ipv4-fragmentation"),
186 ]
187
188 self.render_graphs(graphs)
189
190
a6144752
MT
191class AnalyticsSystemBaseHandler(AnalyticsBaseHandler):
192 @property
193 def menu(self):
194 _ = self.locale.translate
195
196 m = ui.menu.Menu(self, _("System"))
197
198 # Back...
199 m.add_handler(AnalyticsOverviewHandler, title=_("Back..."))
200 m.add_divider()
201
202 # Overview
203 m.add_handler(AnalyticsSystemOverviewHandler, title=_("Overview"))
204 m.add_divider()
205
03f518c7 206 # Most interesting items
a6144752
MT
207 m.add_handler(AnalyticsSystemProcessorsHandler)
208 m.add_handler(AnalyticsSystemMemoryHandler)
03f518c7
MT
209 m.add_handler(AnalyticsSystemTemperaturesHandler)
210
211 # Others
212 s = m.add_submenu(_("More"))
213 s.add_handler(AnalyticsSystemEntropyHandler)
0da4e21c 214 s.add_handler(AnalyticsSystemContextSwitchesHandler)
f88d0ae2 215 s.add_handler(AnalyticsSystemInterruptsHandler)
a6144752
MT
216
217 return m
218
219
220class AnalyticsSystemOverviewHandler(AnalyticsSystemBaseHandler):
221 url = r"/analytics/system"
222 title = N_("System")
223
03f518c7
MT
224 def get(self):
225 self.render("base.html")
226
a6144752
MT
227
228class AnalyticsSystemProcessorsHandler(AnalyticsSystemBaseHandler):
229 url = r"/analytics/system/processors"
230 title = N_("Processors")
231
03f518c7
MT
232 def get(self):
233 _ = self.locale.translate
234
235 graphs = [
236 ui.graphs.Graph(self, "processor"),
237 ui.graphs.Graph(self, "processor-temperature"),
238 ui.graphs.Graph(self, "cpufreq"),
239 ui.graphs.Graph(self, "loadavg"),
240 ]
241
242 self.render_graphs(graphs)
243
a6144752
MT
244
245class AnalyticsSystemMemoryHandler(AnalyticsSystemBaseHandler):
246 url = r"/analytics/system/memory"
247 title = N_("Memory")
248
03f518c7
MT
249 def get(self):
250 _ = self.locale.translate
251
252 graphs = [
253 ui.graphs.Graph(self, "memory"),
254 ]
255
256 self.render_graphs(graphs)
257
258
259class AnalyticsSystemTemperaturesHandler(AnalyticsSystemBaseHandler):
260 url = r"/analytics/system/temperatures"
261 title = N_("Temperatures")
262
263 def get(self):
264 _ = self.locale.translate
265
266 graphs = [
267 ui.graphs.Graph(self, "sensors-temperature"),
268 ui.graphs.Graph(self, "processor-temperature"),
269 ]
270
271 self.render_graphs(graphs)
272
273
274class AnalyticsSystemEntropyHandler(AnalyticsSystemBaseHandler):
275 url = r"/analytics/system/entropy"
276 title = N_("Entropy")
277
278 def get(self):
279 _ = self.locale.translate
280
281 graphs = [
282 ui.graphs.Graph(self, "entropy"),
283 ]
284
285 self.render_graphs(graphs)
286
21a66327 287
0da4e21c
MT
288class AnalyticsSystemContextSwitchesHandler(AnalyticsSystemBaseHandler):
289 url = r"/analytics/system/context-switches"
290 title = N_("Context Switches")
291
292 def get(self):
293 _ = self.locale.translate
294
295 graphs = [
296 ui.graphs.Graph(self, "context-switches"),
297 ]
298
299 self.render_graphs(graphs)
300
301
f88d0ae2
MT
302class AnalyticsSystemInterruptsHandler(AnalyticsSystemBaseHandler):
303 url = r"/analytics/system/interrupts"
304 title = N_("Interrupts")
305
306 def get(self):
307 _ = self.locale.translate
308
309 graphs = [
310 ui.graphs.Graph(self, "system-interrupts"),
311 ]
312
313 self.render_graphs(graphs)
314
315
21a66327
MT
316class GraphExportHandler(base.BaseHandler):
317 VALID_INTERVALS = ("hour", "day", "month", "week", "year")
318 DEFAULT_INTERVAL = "day"
319
320 SUPPORTED_FORMATS = ("pdf", "png", "svg")
321
0ac359f3 322 url = r"/graph(/thumbnail)?/([\w\-]+)(?:/([\w\d\.]+))?\.(%s)" % "|".join(SUPPORTED_FORMATS)
21a66327 323
0ac359f3 324 def get(self, thumbnail, template_name, object_id, format):
b7561c87
MT
325 _ = self.locale.translate
326
21a66327
MT
327 # Get the requested dimensions of the image
328 height = self.get_argument_int("height", None)
329 width = self.get_argument_int("width", None)
330
331 # Get the requested interval
332 interval = self.get_argument("interval", self.DEFAULT_INTERVAL)
333 if interval and not interval in self.VALID_INTERVALS:
334 raise tornado.web.HTTPError(400, _("Invalid interval: %s") % interval)
335
03f518c7
MT
336 # Create the graph object
337 g = ui.graphs.Graph(self, template_name, object_id=object_id)
338
21a66327 339 # Generate the graph image
cbc61195
MT
340 kwargs = {
341 "format" : format.upper(),
342 "interval" : interval,
343 "height" : height,
344 "width" : width,
0ac359f3 345 "thumbnail" : bool(thumbnail),
cbc61195
MT
346
347 # Include the title in the PDF exports
348 "with_title" : format == "pdf",
349 }
350 image = g.generate_graph(**kwargs)
21a66327
MT
351
352 # Set the HTTP headers
353 self._make_headers(format, template_name, object_id)
354
355 # Deliver the content
03f518c7 356 self.finish(image.get("image"))
21a66327
MT
357
358 def _make_headers(self, extension, template_name, object_id):
359 # Determine the mime type
360 mimetype = mimetypes.types_map.get(".%s" % extension, "application/octet-stream")
361 self.set_header("Content-Type", mimetype)
362
363 # Add the timestamp when this graph was generated
364 now = datetime.datetime.now()
365
366 # Put together the filename (for downloads)
367 filename = [self.backend.system.hostname, template_name, object_id, now.isoformat()]
368 filename = "%s.%s" % ("-".join((e for e in filename if e)), extension)
369
370 if extension == "pdf":
371 self.set_header("Content-Disposition", "attachment; filename=%s" % filename)
372 else:
373 self.set_header("Content-Disposition", "inline; filename=%s" % filename)
03f518c7
MT
374
375
376class GraphHandler(base.BaseHandler):
377 url = r"/graph/([\w\-]+)(?:/([\w\d\.]+))?"
378
379 def get(self, template, object_id):
380 graph = ui.graphs.Graph(self, template, object_id=object_id)
381
382 self.render("graph.html", graph=graph)