瀏覽代碼

gen report

Tum 2 年之前
父節點
當前提交
0a4d82614d

二進制
app/Output/excel_out_test_excel_formatter_update.xlsx


+ 56 - 0
app/backend/templates/backend/gen_report.html

@@ -0,0 +1,56 @@
1
+{% extends "base_raw.html" %}
2
+{% load backend_tags %}
3
+{% block content %}
4
+<h2>Gen Report</h2>
5
+<a href="#test_result" class='btn btn-link'>Test Result</a>
6
+<a href="#mikrotik" class='btn btn-link'>Mikrotik</a>
7
+<form class='my-2'>
8
+
9
+{% for sla in  slas %}
10
+<label class='me-3'>
11
+  <input type='checkbox' name='sla_name' value='{{ sla }}' {% if sla in request.GET.sla_name %}checked{% endif %}/>{{ sla }}
12
+</label>
13
+{% endfor %}
14
+<input type='submit' name='filter' Value='Filter' class='btn btn-primary ms-3' />
15
+<a class='btn btn-danger ms-3' href="{% url 'backend:dump_fixed_results' %}?redir={{ request.path_info }}">Dump API</a>
16
+<input type='submit' name='genReport' value='Gen Report' class='btn btn-info' />
17
+{% if report_link %}
18
+  <a href="{{ report_link }}" class='btn btn-link'>Download</a>
19
+{% endif %}
20
+</form>
21
+<h1 id='test_result'>Test Result</h1>
22
+<div class='table-responsive'>
23
+  {{ tbl|safe }} 
24
+</div>
25
+<h1 id='mikrotik'>Mikrotik</h1>
26
+<h5 class='text-primary'>IP/ROUTE</h5>
27
+{% for ip in mk_ips %}
28
+<h4>{{ ip.gateway }}</h4>
29
+  <div class='d-flex flex-row justify-content-start  flex-wrap align-content-stretch mb-5'>
30
+    {% for k,v in ip.items %}
31
+      <div class='border p-3 fw-bolder'>{{ k }}</div><div class='border p-3'>{{ v }}</div>
32
+    {% endfor %}
33
+  </div>
34
+  
35
+{% endfor %}
36
+
37
+<h5 class='text-primary'>IP/Address</h5>
38
+<!-- 
39
+<pre>
40
+{{ mk_address | pprint }}
41
+</pre> -->
42
+{% for ip in mk_address %}
43
+<h4>{{ ip.interface }}</h4>
44
+  <div class='d-flex flex-row justify-content-start  flex-wrap align-content-stretch mb-5'>
45
+    {% for k,v in ip.items %}
46
+      <div class='border p-3 fw-bolder'>{{ k }}</div><div class='border p-3'>{{ v }}</div>
47
+    {% endfor %}
48
+  </div>
49
+  
50
+{% endfor %}
51
+<style>
52
+th {
53
+  text-align:center;
54
+}
55
+</style>
56
+{% endblock %}

+ 1 - 0
app/backend/urls.py

@@ -12,4 +12,5 @@ urlpatterns = [
12 12
     path('dump_api/', views.dump_api, name='dump_api'),
13 13
     path('dump_fixed_results/', views.dump_fixed_results, name='dump_fixed_results'),
14 14
     path('print_table/', views.print_table, name='print_table'),
15
+    path('gen_report/', views.gen_report, name='gen_report'), 
15 16
 ]

+ 81 - 1
app/backend/views.py

@@ -1,4 +1,4 @@
1
-from django.shortcuts import render
1
+from django.shortcuts import render, redirect
2 2
 from backend.mongodb import db
3 3
 from exfo.lib import Exfo, Mikrotik
4 4
 from pprint import pprint
@@ -7,6 +7,7 @@ from ttp import ttp
7 7
 from django.http import JsonResponse, HttpResponse
8 8
 from datetime import datetime
9 9
 from celery import shared_task
10
+from django.contrib import messages
10 11
 
11 12
 exfo = Exfo("administrator", "exf0w0rxC@t4dm!n")
12 13
 exfo.login()
@@ -274,5 +275,84 @@ def dump_fixed_results(request):
274 275
     results = col.find({})
275 276
     data = dumps(list(results), indent=4)
276 277
     data = {'msg': 'done'}
278
+    redir = request.GET.get('redir', None)
279
+    if redir:
280
+        messages.success(request, 'Dump Fixed Results')
281
+        return redirect(redir)
277 282
     # return HttpResponse(data, content_type='application/json')
278 283
     return JsonResponse(data)
284
+
285
+import humanize
286
+
287
+def con_human(r):
288
+    try:
289
+        '''
290
+        if 'time' in r['header'].lower():
291
+            return r['results']
292
+        '''
293
+        x = r['results']
294
+        n = int(x)
295
+        if n > 1000:
296
+            return humanize.naturalsize(n,gnu=True)
297
+        else:
298
+            return n
299
+    except:
300
+        return r['results']
301
+def gen_report_notebook():
302
+    from datetime import datetime
303
+    import pandas as pd
304
+
305
+    c = db['fixed_results'].find()
306
+    data = []
307
+    for i in c:
308
+        #pprint(i['header'])
309
+        res = dict(zip(i['header'], i['results']))
310
+        d = {'header': i['header'], 'results': i['results'], 'output': res, 'params': i['parameters'], 'ts': i['ids']['time_stamp'], 
311
+             'dt': datetime.fromtimestamp(int(i['ids']['time_stamp'])/1000000000), 'test_type_name': i['ids']['fixed_results_url']}
312
+        d.update(i['names'])
313
+        #res.update(i['ids'])
314
+        #res.update(i[])
315
+        #pprint(d)
316
+        data.append(d)
317
+    df0 = pd.DataFrame(data)
318
+    df0 = df0.explode(["header", "results"])
319
+    df1 = df0[["header", "results", "dt", "sla_name", "test_display_name"]]
320
+    df1 = df1.query('sla_name == sla_name')
321
+    #pprint(df1['sla_name'].unique())
322
+    
323
+    #df1['results_text'] = df1['results'].apply(con_human)
324
+    df1['results_text'] = df1.apply(con_human, axis=1)
325
+    table = df1.pivot(index=['sla_name', 'dt'],columns=['test_display_name','header'], values='results_text').sort_values(by=['sla_name', 'dt'], ascending=[True, False])
326
+    table = table.dropna(how='all', axis=0)
327
+    return (table,df1)
328
+
329
+def gen_report(request):
330
+    pprint("report notebook ...")
331
+    table,df = gen_report_notebook()
332
+    slas = list(df['sla_name'].unique())
333
+    sla_name = request.GET.getlist('sla_name')
334
+    
335
+    pprint("--- sla_name ---")
336
+    pprint(sla_name)
337
+    if len(sla_name) > 0:
338
+        sla_filter = ", ".join(f"'{w}'" for w in sla_name)
339
+        table = table.query(f"sla_name in ({sla_filter})")
340
+    gen_report = request.GET.get('genReport', None)
341
+    
342
+    report_link = None
343
+    if gen_report:
344
+        import time
345
+        ts = int(time.time())
346
+        fn = f"report_{ts}.xlsx"
347
+        table.to_excel(f'/code/media/{fn}')
348
+        report_link = f'/media/{fn}'
349
+
350
+    try:
351
+        mk_ips = mkt.call_remote("ip/route") 
352
+        mk_address = mkt.call_remote("ip/address") 
353
+    except:
354
+        mk_ips = []
355
+        mk_address = []
356
+    return render(request, 'backend/gen_report.html', {'tbl': table.to_html(\
357
+        classes=["table", "table-striped", "table-bordered", "align-middle"],\
358
+        table_id="report_tbl"), 'slas': slas, 'report_link': report_link, 'mk_ips': mk_ips, 'mk_address': mk_address})

+ 4 - 4
app/exfo/lib.py

@@ -22,9 +22,9 @@ class Exfo:
22 22
         url = self.BASE_URL + "/Login"
23 23
         response = self.session.post(url, headers=headers, data=payload, verify=False)
24 24
        
25
-        pprint(self.session.cookies.get_dict())
26
-        pprint(response.text)
27
-        pprint(response.cookies)
25
+        # pprint(self.session.cookies.get_dict())
26
+        # pprint(response.text)
27
+        # pprint(response.cookies)
28 28
         #self.cookies = response.cookies
29 29
     def list_api(self):
30 30
         pprint("---- list_api ---")
@@ -34,7 +34,7 @@ class Exfo:
34 34
         }
35 35
         url = self.BASE_URL + "/"
36 36
         response = self.session.get(url, headers=headers, data=payload, verify=False)
37
-        pprint(response.json())
37
+        # pprint(response.json())
38 38
         return response
39 39
 
40 40
     def call_api(self, service, payload={}):

+ 6 - 0
app/templates/_messages.html

@@ -0,0 +1,6 @@
1
+{% if messages %}
2
+    {% for message in messages %}
3
+    <div{% if message.tags %} style='z-index:2000' class="alert alert-{{ message.tags }}  text-center h5 position-absolute top-50 start-50 translate-middle fs-6" {% endif %}>{{ message }}</div>
4
+    {% endfor %}
5
+{% endif %}
6
+

+ 78 - 0
app/templates/base_raw.html

@@ -0,0 +1,78 @@
1
+{% load static %}
2
+<!doctype html>
3
+<html lang="en">
4
+  <head>
5
+    <meta charset="utf-8">
6
+    <meta name="viewport" content="width=device-width, initial-scale=1">
7
+    <meta name="description" content="">
8
+    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
9
+    <meta name="generator" content="Hugo 0.84.0">
10
+    <title>Dashboard Template · Bootstrap v5.0</title>
11
+
12
+    <link rel="canonical" href="https://getbootstrap.com/docs/5.0/examples/dashboard/">
13
+
14
+    
15
+
16
+    <!-- Bootstrap core CSS -->
17
+    <link href="{% static "bootstrap/dist/css/bootstrap.css" %}" rel="stylesheet">
18
+
19
+    <!-- Favicons -->
20
+<meta name="theme-color" content="#7952b3">
21
+
22
+
23
+    <style>
24
+      .bd-placeholder-img {
25
+        font-size: 1.125rem;
26
+        text-anchor: middle;
27
+        -webkit-user-select: none;
28
+        -moz-user-select: none;
29
+        user-select: none;
30
+      }
31
+
32
+      @media (min-width: 768px) {
33
+        .bd-placeholder-img-lg {
34
+          font-size: 3.5rem;
35
+        }
36
+      }
37
+    </style>
38
+
39
+    
40
+    <!-- Custom styles for this template -->
41
+    <link href="{% static "css/dashboard.css" %}" rel="stylesheet">
42
+  </head>
43
+  <body>
44
+    
45
+<header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
46
+  <a class="navbar-brand col-md-3 col-lg-2 me-0 px-3" href="#">Company name</a>
47
+  <button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
48
+    <span class="navbar-toggler-icon"></span>
49
+  </button>
50
+  <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
51
+  <div class="navbar-nav">
52
+    <div class="nav-item text-nowrap">
53
+      <a class="nav-link px-3" href="#">Sign out</a>
54
+    </div>
55
+  </div>
56
+</header>
57
+
58
+<div class="container-fluid">
59
+  <div class="row">
60
+
61
+    <main class="col-md-12 ms-sm-auto col-lg-12 px-md-4 py-3">
62
+      {% include "_messages.html" %}
63
+      {% block content %}
64
+        <h1>Content is Here</h1>
65
+      {% endblock %}
66
+    </main>
67
+  </div>
68
+</div>
69
+
70
+
71
+    <script src="{% static "bootstrap/dist/js/bootstrap.bundle.min.js" %}"></script>
72
+
73
+      <script src="https://cdn.jsdelivr.net/npm/feather-icons@4.28.0/dist/feather.min.js" integrity="sha384-uO3SXW5IuS1ZpFPKugNNWqTZRRglnUJK6UAZ/gxOX80nxEkN9NcGZTftn6RzhGWE" crossorigin="anonymous"></script>
74
+      <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js" integrity="sha384-zNy6FEbO50N+Cg5wap8IKA4M/ZnLJgzc6w2NqACZaK0u0FXfOWRRJOnQtpZun8ha" crossorigin="anonymous"></script>
75
+      <script src="{% static "alpinejs/dist/cdn.js" %}"></script>
76
+      <script src="{% static "js/dashboard.js" %}"></script>
77
+  </body>
78
+</html>

File diff suppressed because it is too large
+ 74 - 22856
network-result.ipynb


+ 1 - 0
requirements.txt

@@ -91,3 +91,4 @@ django-autotranslate
91 91
 pymongo
92 92
 dnspython
93 93
 ttp
94
+humanize

二進制
sample_1705327996.xlsx