From 0bf2312fe45291d6ce8ed3f0ac5c09b97e375b8c Mon Sep 17 00:00:00 2001 From: Adrian Schmutzler Date: Tue, 28 Aug 2018 15:28:25 +0200 Subject: [PATCH] Global: Put hoods into table and use smallint for reference This will reduce size of stats_hood and, more importantly, make hood assignment independent of hood name changes: Previouly: Name change = changing string in every place Now: Name change = change of one table entry This requires changes to the MySQL database! Signed-off-by: Adrian Schmutzler --- ffmap/db/hoods.py | 34 ++++++++++++++++++++++++----- ffmap/db/routers.py | 2 +- ffmap/db/stats.py | 2 +- ffmap/hoodtools.py | 6 ++--- ffmap/maptools.py | 2 +- ffmap/misc.py | 2 +- ffmap/routertools.py | 32 +++++++++++++++++++++------ ffmap/stattools.py | 14 +++++++----- ffmap/web/api.py | 18 +++++++++------ ffmap/web/application.py | 29 ++++++++++++++++++------ ffmap/web/helpers.py | 5 ++++- ffmap/web/templates/router.html | 4 ++-- ffmap/web/templates/statistics.html | 34 ++++++++++++++--------------- 13 files changed, 124 insertions(+), 60 deletions(-) diff --git a/ffmap/db/hoods.py b/ffmap/db/hoods.py index ae82922..f48e1f9 100755 --- a/ffmap/db/hoods.py +++ b/ffmap/db/hoods.py @@ -10,6 +10,33 @@ mysql = FreifunkMySQL() mysql.execute(""" CREATE TABLE hoods ( + id smallint(6) UNSIGNED NOT NULL, + name varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci +""") + +mysql.execute(""" + ALTER TABLE hoods + ADD PRIMARY KEY (id), + ADD UNIQUE KEY name (name) +""") + +mysql.execute(""" + ALTER TABLE hoods + MODIFY id smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT +""") + +mysql.execute(""" + ALTER TABLE hoods AUTO_INCREMENT = 30001 +""") + +mysql.execute(""" + INSERT INTO hoods (id, name) + VALUES (%s, %s) +""",(10000,NoCoordinates,)) + +mysql.execute(""" + CREATE TABLE hoodsv1 ( `id` int(11) NOT NULL, `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `net` varchar(30) COLLATE utf8_unicode_ci NOT NULL, @@ -21,7 +48,7 @@ mysql.execute(""" """) mysql.execute(""" - ALTER TABLE hoods + ALTER TABLE hoodsv1 ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `name` (`name`), ADD KEY `lat` (`lat`), @@ -30,11 +57,6 @@ mysql.execute(""" ADD KEY `sin_lat` (`sin_lat`) """) -mysql.execute(""" - INSERT INTO hoods (id, name, net, lat, lng, cos_lat, sin_lat) - VALUES (%s, %s, %s, %s, %s, %s, %s) -""",(0,NoCoordinates,"",None,None,None,None,)) - mysql.execute(""" CREATE TABLE hoodsv2 ( `id` int(11) NOT NULL, diff --git a/ffmap/db/routers.py b/ffmap/db/routers.py index a578dbb..e764311 100755 --- a/ffmap/db/routers.py +++ b/ffmap/db/routers.py @@ -92,7 +92,7 @@ mysql.execute(""" `description` varchar(200) COLLATE utf8_unicode_ci NOT NULL, `position_comment` varchar(200) COLLATE utf8_unicode_ci NOT NULL, `community` varchar(200) COLLATE utf8_unicode_ci NOT NULL, - `hood` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, + `hood` smallint(5) UNSIGNED DEFAULT NULL, `v2` tinyint(1) NOT NULL, `local` tinyint(1) NOT NULL, `gateway` tinyint(1) NOT NULL, diff --git a/ffmap/db/stats.py b/ffmap/db/stats.py index 5debc23..807077d 100755 --- a/ffmap/db/stats.py +++ b/ffmap/db/stats.py @@ -47,7 +47,7 @@ mysql.execute(""" mysql.execute(""" CREATE TABLE stats_hood ( `time` int(11) NOT NULL, - `hood` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + `hood` smallint(5) UNSIGNED NOT NULL, `clients` mediumint(9) NOT NULL, `online` smallint(6) NOT NULL, `offline` smallint(6) NOT NULL, diff --git a/ffmap/hoodtools.py b/ffmap/hoodtools.py index 936e492..39ec91c 100644 --- a/ffmap/hoodtools.py +++ b/ffmap/hoodtools.py @@ -62,15 +62,15 @@ def update_hoods_v1(mysql): kx_data.append((kx["id"],kx["name"],kx["net"],kx.get("lat",None),kx.get("lon",None),cos_lat,sin_lat,)) # Delete entries in DB where hood is missing in KeyXchange - db_keys = mysql.fetchall("SELECT id FROM hoods",(),"id") + db_keys = mysql.fetchall("SELECT id FROM hoodsv1",(),"id") for n in db_keys: if n in kx_keys or n==0: continue - mysql.execute("DELETE FROM hoods WHERE id = %s",(n,)) + mysql.execute("DELETE FROM hoodsv1 WHERE id = %s",(n,)) # Create/update entries from KeyXchange to DB mysql.executemany(""" - INSERT INTO hoods (id, name, net, lat, lng, cos_lat, sin_lat) + INSERT INTO hoodsv1 (id, name, net, lat, lng, cos_lat, sin_lat) VALUES (%s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE name=VALUES(name), diff --git a/ffmap/maptools.py b/ffmap/maptools.py index 2df00fd..15453b1 100644 --- a/ffmap/maptools.py +++ b/ffmap/maptools.py @@ -215,7 +215,7 @@ def update_mapnik_csv(mysql): csv.write("\"LINESTRING (%f %f,%f %f)\"\n" % link) dbhoods = mysql.fetchall(""" - SELECT name, lat, lng FROM hoods + SELECT name, lat, lng FROM hoodsv1 WHERE lat IS NOT NULL AND lng IS NOT NULL """) with open(os.path.join(CONFIG["csv_dir"], "hood-points.csv"), "w", encoding="UTF-8") as csv: diff --git a/ffmap/misc.py b/ffmap/misc.py index 944a2e6..c227f60 100644 --- a/ffmap/misc.py +++ b/ffmap/misc.py @@ -136,7 +136,7 @@ def defrag_table(mysql,table,sleep): print("--- Defragmented table %s: %.3f seconds ---" % (table,end_time - start_time)) def defrag_all(mysql,doall=False): - alltables = ('gw','gw_admin','gw_netif','hoods','hoodsv2','netifs','router','router_events','router_gw','router_ipv6','router_neighbor','router_netif','users') + alltables = ('gw','gw_admin','gw_netif','hoods','hoodsv1','hoodsv2','netifs','router','router_events','router_gw','router_ipv6','router_neighbor','router_netif','users') stattables = ('router_stats','router_stats_gw','router_stats_neighbor','router_stats_netif','stats_global','stats_gw','stats_hood') for t in alltables: diff --git a/ffmap/routertools.py b/ffmap/routertools.py index 3e3c983..0155c76 100644 --- a/ffmap/routertools.py +++ b/ffmap/routertools.py @@ -43,7 +43,7 @@ def ban_router(mysql,dbid): mysql.execute("INSERT INTO banned (mac, added) VALUES (%s, %s)",(mac,added,)) mysql.commit() -def import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, statstime): +def import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, hoodsdict, statstime): #global router_rate_limit_list #if mac in router_rate_limit_list: @@ -78,7 +78,13 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, statstim if findrouter: router_id = findrouter["router"] - olddata = mysql.findone("SELECT sys_uptime, sys_time, firmware, hostname, hood, status, lat, lng, contact, description, position_comment, w2_active, w2_busy, w5_active, w5_busy FROM router WHERE id = %s LIMIT 1",(router_id,)) + olddata = mysql.findone(""" + SELECT sys_uptime, sys_time, firmware, hostname, hoods.id AS hoodid, hoods.name AS hood, status, lat, lng, contact, description, position_comment, w2_active, w2_busy, w5_active, w5_busy + FROM router + LEFT JOIN hoods ON router.hood = hoods.id + WHERE router.id = %s + LIMIT 1 + """,(router_id,)) if olddata: uptime = olddata["sys_uptime"] @@ -110,20 +116,32 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, statstim ) ) AS distance FROM - hoods + hoodsv1 WHERE lat IS NOT NULL AND lng IS NOT NULL ORDER BY distance ASC LIMIT 1 """,(lat,lng,lat,),"name") if not router_update["hood"]: - router_update["hood"] = "Default" + router_update["hood"] = "DefaultV1" if router_update["neighbours"] and not router_update["has_wan_uplink"]: router_update["hood"] = "NoCoordinates" if not router_update['lat'] and not router_update['lng'] and olddata and olddata['lat'] and olddata['lng']: # Enable reset state; do before variable fallback reset = True - + + if not router_update["hood"] in hoodsdict.keys(): + checkagain = mysql.findone("SELECT id FROM hoods WHERE name = %s",(router_update["hood"],),"id") + # Prevent adding the same hood for all routers (won't break, but each will raise the AUTO_INCREMENT) + if not checkagain: + mysql.execute(""" + INSERT INTO hoods (name) + VALUES (%s) + ON DUPLICATE KEY UPDATE name=name + """,(router_update["hood"],)) + hoodsdict = mysql.fetchdict("SELECT id, name FROM hoods",(),"name","id") + router_update["hoodid"] = hoodsdict[router_update["hood"]] + if not router_update['hostname']: router_update['hostname'] = 'Give Me A Name' @@ -173,7 +191,7 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, statstim ru["sys_loadavg"],ru["processes"]["runnable"],ru["processes"]["total"],ru["clients"],ru["clients_eth"],ru["clients_w2"],ru["clients_w5"], ru["w2_active"],ru["w2_busy"],ru["w5_active"],ru["w5_busy"],ru["w2_airtime"],ru["w5_airtime"],ru["has_wan_uplink"],ru["tc_enabled"],ru["tc_in"],ru["tc_out"], ru["cpu"],ru["chipset"],ru["hardware"],ru["os"], - ru["batman_adv"],ru["rt_protocol"],ru["kernel"],ru["nodewatcher"],ru["firmware"],ru["firmware_rev"],ru["description"],ru["position_comment"],ru["community"],ru["hood"],ru["v2"],ru["local"],ru["gateway"], + ru["batman_adv"],ru["rt_protocol"],ru["kernel"],ru["nodewatcher"],ru["firmware"],ru["firmware_rev"],ru["description"],ru["position_comment"],ru["community"],ru["hoodid"],ru["v2"],ru["local"],ru["gateway"], ru["status_text"],ru["contact"],ru["lng"],ru["lat"],ru["visible_neighbours"],reset,router_id,)) # Previously, I just deleted all entries and recreated them again with INSERT. @@ -246,7 +264,7 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, statstim ru["sys_loadavg"],ru["processes"]["runnable"],ru["processes"]["total"],ru["clients"],ru["clients_eth"],ru["clients_w2"],ru["clients_w5"], None,None,None,None,None,None,ru["has_wan_uplink"],ru["tc_enabled"],ru["tc_in"],ru["tc_out"], ru["cpu"],ru["chipset"],ru["hardware"],ru["os"], - ru["batman_adv"],ru["rt_protocol"],ru["kernel"],ru["nodewatcher"],ru["firmware"],ru["firmware_rev"],ru["description"],ru["position_comment"],ru["community"],ru["hood"],ru["v2"],ru["local"],ru["gateway"], + ru["batman_adv"],ru["rt_protocol"],ru["kernel"],ru["nodewatcher"],ru["firmware"],ru["firmware_rev"],ru["description"],ru["position_comment"],ru["community"],ru["hoodid"],ru["v2"],ru["local"],ru["gateway"], ru["status_text"],ru["contact"],ru["lng"],ru["lat"],ru["visible_neighbours"],)) router_id = mysql.cursor().lastrowid diff --git a/ffmap/stattools.py b/ffmap/stattools.py index 9cabc94..770bc64 100644 --- a/ffmap/stattools.py +++ b/ffmap/stattools.py @@ -199,17 +199,19 @@ def router_firmwares(mysql,selecthood=None,selectgw=None): def hoods(mysql,selectgw=None): data = mysql.fetchall(""" - SELECT hood, status, COUNT(id) AS count + SELECT hoods.id AS hoodid, hoods.name AS hood, status, COUNT(router.id) AS count FROM router - GROUP BY hood, status + LEFT JOIN hoods ON router.hood = hoods.id + GROUP BY hoods.id, hoods.name, status """) result = {} for rs in data: if not rs["hood"]: - rs["hood"] = "Default" - if not rs["hood"] in result: - result[rs["hood"]] = {} - result[rs["hood"]][rs["status"]] = rs["count"] + rs["hoodid"] = "1" + rs["hood"] = "NoHood" + if not rs["hoodid"] in result: + result[rs["hoodid"]] = {'name':rs["hood"]} + result[rs["hoodid"]][rs["status"]] = rs["count"] return result def hoods_sum(mysql,selectgw=None): diff --git a/ffmap/web/api.py b/ffmap/web/api.py index a9d8d36..4b29e69 100755 --- a/ffmap/web/api.py +++ b/ffmap/web/api.py @@ -92,7 +92,6 @@ def get_nearest_router(): ) AS distance FROM router AS r - LEFT JOIN hoods AS h ON r.hood = h.name WHERE r.lat IS NOT NULL AND r.lng IS NOT NULL """ + where + """ ORDER BY distance ASC @@ -155,6 +154,7 @@ def alfred(): """,(),"name") statstime = utcnow() netifdict = mysql.fetchdict("SELECT id, name FROM netifs",(),"name","id") + hoodsdict = mysql.fetchdict("SELECT id, name FROM hoods",(),"name","id") if request.method == 'POST': try: alfred_data = request.get_json() @@ -167,7 +167,7 @@ def alfred(): # load router status xml data i = 1 for mac, xml in alfred_data.get("64", {}).items(): - import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, statstime) + import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, hoodsdict, statstime) if (i%500 == 0): mysql.commit() i += 1 @@ -260,8 +260,9 @@ def wifianal(selecthood): SELECT hostname, mac, netif FROM router INNER JOIN router_netif ON router.id = router_netif.router - WHERE hood = %s - GROUP BY id, netif + INNER JOIN hoods ON router.hood = hoods.id + WHERE hoods.name = %s + GROUP BY router.id, netif """,(selecthood,)) mysql.close() @@ -351,8 +352,9 @@ def routers(): # Suppresses routers without br-mesh mysql = FreifunkMySQL() router_data = mysql.fetchall(""" - SELECT router.id, hostname, status, hood, contact, nickname, hardware, firmware, clients, lat, lng, last_contact, mac, sys_loadavg + SELECT router.id, hostname, status, hoods.id AS hoodid, hoods.name AS hood, contact, nickname, hardware, firmware, clients, lat, lng, last_contact, mac, sys_loadavg FROM router + INNER JOIN hoods ON router.hood = hoods.id INNER JOIN router_netif ON router.id = router_netif.router LEFT JOIN users ON router.contact = users.email WHERE netif = 'br-mesh' @@ -394,6 +396,7 @@ def routers(): 'id': str(router['id']), 'name': router['hostname'], 'mac': int2mac(router['mac']), + 'hoodid': router['hoodid'], 'hood': router['hood'], 'status': router['status'], 'user': router['nickname'], @@ -487,7 +490,7 @@ def get_routers_by_keyxchange_id(keyxchange_id): mysql = FreifunkMySQL() hood = mysql.findone(""" SELECT name - FROM hoods + FROM hoodsv1 WHERE id = %s LIMIT 1 """,(int(keyxchange_id),)) @@ -501,7 +504,8 @@ def get_routers_by_keyxchange_id(keyxchange_id): SELECT router.id, hostname, hardware, mac, fe80_addr, firmware, lat, lng, contact, position_comment, description FROM router INNER JOIN router_netif ON router.id = router_netif.router - WHERE hood = %s AND netif = 'br-mesh' + INNER JOIN hoods ON router.hood = hoods.id + WHERE hoods.name = %s AND netif = 'br-mesh' ORDER BY hostname ASC """,(hood["name"],)) mysql.close() diff --git a/ffmap/web/application.py b/ffmap/web/application.py index b1dbcfb..1316370 100755 --- a/ffmap/web/application.py +++ b/ffmap/web/application.py @@ -52,8 +52,9 @@ def router_list(): mysql = FreifunkMySQL() routers = mysql.fetchall(""" - SELECT router.id, hostname, status, hood, contact, nickname, hardware, router.created, sys_uptime, last_contact, clients, reset, blocked, v2, local + SELECT router.id, hostname, status, hoods.id AS hoodid, hoods.name AS hood, contact, nickname, hardware, router.created, sys_uptime, last_contact, clients, reset, blocked, v2, local FROM router + INNER JOIN hoods ON router.hood = hoods.id LEFT JOIN users ON router.contact = users.email LEFT JOIN ( SELECT router, blocked.mac AS blocked FROM router_netif @@ -95,7 +96,11 @@ def router_mac(mac): def router_info(dbid): try: mysql = FreifunkMySQL() - router = mysql.findone("""SELECT * FROM router WHERE id = %s LIMIT 1""",(dbid,)) + router = mysql.findone(""" + SELECT router.*, hoods.id AS hoodid, hoods.name AS hoodname FROM router + INNER JOIN hoods ON router.hood = hoods.id + WHERE router.id = %s LIMIT 1 + """,(dbid,)) mac = None if router: @@ -451,8 +456,9 @@ def user_info(nickname): else: flash("You are not authorized to perform this action!", "danger") routers = mysql.fetchall(""" - SELECT id, hostname, status, hood, firmware, hardware, created, sys_uptime, clients, reset, blocked, v2, local + SELECT router.id, hostname, status, hoods.id AS hoodid, hoods.name AS hood, firmware, hardware, created, sys_uptime, clients, reset, blocked, v2, local FROM router + INNER JOIN hoods ON router.hood = hoods.id LEFT JOIN ( SELECT router, blocked.mac AS blocked FROM router_netif INNER JOIN blocked ON router_netif.mac = blocked.mac @@ -480,6 +486,7 @@ def global_statistics(): @app.route('/hoodstatistics/') def global_hoodstatistics(selecthood): + selecthood = int(selecthood) mysql = FreifunkMySQL() stats = mysql.fetchall("SELECT * FROM stats_hood WHERE hood = %s",(selecthood,)) return helper_statistics(mysql,stats,selecthood,None) @@ -496,12 +503,17 @@ def helper_statistics(mysql,stats,selecthood,selectgw): hoods = stattools.hoods(mysql,selectgw) gws = stattools.gws(mysql,selecthood) + if selecthood: + selecthoodname = mysql.findone("SELECT name FROM hoods WHERE id = %s",(selecthood,),'name') + else: + selecthoodname = None + if selectgw: selectgwint = mac2int(selectgw) else: selectgwint = None - if selecthood and not selecthood in hoods: + if selecthood and not selecthood in hoods.keys(): mysql.close() return "Hood not found" if selectgw and not selectgwint in gws: @@ -516,8 +528,9 @@ def helper_statistics(mysql,stats,selecthood,selectgw): if selectgw: newest_routers = mysql.fetchall(""" - SELECT id, hostname, hood, created + SELECT router.id, hostname, hoods.id AS hoodid, hoods.name AS hood, created FROM router + INNER JOIN hoods ON router.hood = hoods.id INNER JOIN router_gw ON router.id = router_gw.router WHERE hardware <> 'Legacy' AND mac = %s ORDER BY created DESC @@ -525,14 +538,15 @@ def helper_statistics(mysql,stats,selecthood,selectgw): """,(mac2int(selectgw),numnew,)) else: if selecthood: - where = " AND hood = %s" + where = " AND hoods.id = %s" tup = (selecthood,numnew,) else: where = "" tup = (numnew,) newest_routers = mysql.fetchall(""" - SELECT id, hostname, hood, created + SELECT router.id, hostname, hoods.id AS hoodid, hoods.name AS hood, created FROM router + INNER JOIN hoods ON router.hood = hoods.id WHERE hardware <> 'Legacy' {} ORDER BY created DESC LIMIT %s @@ -552,6 +566,7 @@ def helper_statistics(mysql,stats,selecthood,selectgw): return render_template("statistics.html", selecthood = selecthood, + selecthoodname = selecthoodname, selectgw = selectgw, selectgwint = selectgwint, stats = stats, diff --git a/ffmap/web/helpers.py b/ffmap/web/helpers.py index f3dec5b..67e1d64 100644 --- a/ffmap/web/helpers.py +++ b/ffmap/web/helpers.py @@ -100,7 +100,10 @@ def parse_router_list_search_query(args): j += " INNER JOIN ( SELECT router, mac FROM router_neighbor GROUP BY router, mac) AS j ON router.id = j.router " k = "HEX(mac) {} REGEXP %s".format(no) t.append(value.replace(':','')) - elif (key == 'hardware') or (key == 'hood') or (key == 'nickname'): + elif (key == 'hood'): + k = "hoods.name {} REGEXP %s".format(no) + t.append(value.replace("_",".")) + elif (key == 'hardware') or (key == 'nickname'): k = key + " {} REGEXP %s".format(no) t.append(value.replace("_",".")) elif (key == 'hostname') or (key == 'firmware'): diff --git a/ffmap/web/templates/router.html b/ffmap/web/templates/router.html index db64506..96a9c28 100644 --- a/ffmap/web/templates/router.html +++ b/ffmap/web/templates/router.html @@ -139,8 +139,8 @@ {%- if router.position_comment %} Position{{ router.position_comment }} {%- endif %} - {%- if router.hood %} - Hood{{ router.hood }} + {%- if router.hoodname %} + Hood{{ router.hoodname }} {%- if router.community %} ({{ router.community }}) {%- endif -%} diff --git a/ffmap/web/templates/statistics.html b/ffmap/web/templates/statistics.html index ffb2c47..d799fad 100644 --- a/ffmap/web/templates/statistics.html +++ b/ffmap/web/templates/statistics.html @@ -1,5 +1,5 @@ {% extends "bootstrap.html" %} -{% block title %}{{super()}} :: Statistics{%- if selecthood %} for {{ selecthood }}{%- endif -%}{%- if selectgw %} for GW {{ selectgw }}{%- endif -%}{% endblock %} +{% block title %}{{super()}} :: Statistics{%- if selecthood %} for {{ selecthoodname }}{%- endif -%}{%- if selectgw %} for GW {{ selectgw }}{%- endif -%}{% endblock %} {% block head %}{{super()}} @@ -68,16 +68,16 @@ - {%- for hood, value in hoods|dictsort %} + {%- for hoodid, value in hoods|dictsort %} - {{ hood }} - {{ hoods_gws[hood] or "-" }} + {{ value['name'] }} + {{ hoods_gws[hoodid] or "-" }} {{ value["online"] or 0 }} {{ value["offline"] or 0 }}{%- if value["orphaned"] %} ({{ value["orphaned"] or 0 }}){%- endif %} {{ value["unknown"] or 0 }} - {{ hoods_sum[hood]["routers"] }} - {{ hoods_sum[hood]["clients"] }} - Stats + {{ hoods_sum[hoodid]["routers"] }} + {{ hoods_sum[hoodid]["clients"] }} + Stats {%- endfor %} @@ -90,7 +90,7 @@ {{ router_status.unknown or 0 }} {{ router_status.sum or 0 }} {{ clients }} - Global + Global @@ -99,27 +99,27 @@
-
Routers{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }} (selected only){%- endif -%}
+
Routers{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }} (selected only){%- endif -%}
-
Clients{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }} (selected only){%- endif -%}
+
Clients{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }} (selected only){%- endif -%}
{%- if not selectgw %}
-
Traffic{%- if selecthood %} @ {{ selecthood }}{%- endif -%}
+
Traffic{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}
{%- endif -%}
-
Newest Routers{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}
+
Newest Routers{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}
@@ -144,7 +144,7 @@
-
Gateways (selected / others){%- if selecthood %} @ {{ selecthood }}{%- endif -%}
+
Gateways (selected / others){%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}
@@ -211,19 +211,19 @@ {%- endif %}
-
Router Firmwares{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}
+
Router Firmwares{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}
-
Router Models{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}
+
Router Models{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}
-
Router Models per Client{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}
+
Router Models per Client{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}
@@ -236,7 +236,7 @@ var router_models = {{ router_models|tojson }}; var routers_page_url = "{{ url_for('router_list') }}"; {%- if selecthood %} - var hood = "{{selecthood}}"; + var hood = "{{selecthoodname}}"; var hoodstr = "hood:^" + hood.replace(/ /g, '_') + "$"; {%- else %} var hoodstr = "";