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 <freifunk@adrianschmutzler.de>
This commit is contained in:
Adrian Schmutzler 2018-08-28 15:28:25 +02:00
parent dd6d101ccd
commit 0bf2312fe4
13 changed files with 124 additions and 60 deletions

View File

@ -10,6 +10,33 @@ mysql = FreifunkMySQL()
mysql.execute(""" mysql.execute("""
CREATE TABLE hoods ( 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, `id` int(11) NOT NULL,
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`net` varchar(30) COLLATE utf8_unicode_ci NOT NULL, `net` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
@ -21,7 +48,7 @@ mysql.execute("""
""") """)
mysql.execute(""" mysql.execute("""
ALTER TABLE hoods ALTER TABLE hoodsv1
ADD PRIMARY KEY (`id`), ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `name` (`name`), ADD UNIQUE KEY `name` (`name`),
ADD KEY `lat` (`lat`), ADD KEY `lat` (`lat`),
@ -30,11 +57,6 @@ mysql.execute("""
ADD KEY `sin_lat` (`sin_lat`) 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(""" mysql.execute("""
CREATE TABLE hoodsv2 ( CREATE TABLE hoodsv2 (
`id` int(11) NOT NULL, `id` int(11) NOT NULL,

View File

@ -92,7 +92,7 @@ mysql.execute("""
`description` varchar(200) COLLATE utf8_unicode_ci NOT NULL, `description` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`position_comment` 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, `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, `v2` tinyint(1) NOT NULL,
`local` tinyint(1) NOT NULL, `local` tinyint(1) NOT NULL,
`gateway` tinyint(1) NOT NULL, `gateway` tinyint(1) NOT NULL,

View File

@ -47,7 +47,7 @@ mysql.execute("""
mysql.execute(""" mysql.execute("""
CREATE TABLE stats_hood ( CREATE TABLE stats_hood (
`time` int(11) NOT NULL, `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, `clients` mediumint(9) NOT NULL,
`online` smallint(6) NOT NULL, `online` smallint(6) NOT NULL,
`offline` smallint(6) NOT NULL, `offline` smallint(6) NOT NULL,

View File

@ -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,)) 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 # 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: for n in db_keys:
if n in kx_keys or n==0: if n in kx_keys or n==0:
continue 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 # Create/update entries from KeyXchange to DB
mysql.executemany(""" 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) VALUES (%s, %s, %s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE ON DUPLICATE KEY UPDATE
name=VALUES(name), name=VALUES(name),

View File

@ -215,7 +215,7 @@ def update_mapnik_csv(mysql):
csv.write("\"LINESTRING (%f %f,%f %f)\"\n" % link) csv.write("\"LINESTRING (%f %f,%f %f)\"\n" % link)
dbhoods = mysql.fetchall(""" 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 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: with open(os.path.join(CONFIG["csv_dir"], "hood-points.csv"), "w", encoding="UTF-8") as csv:

View File

@ -136,7 +136,7 @@ def defrag_table(mysql,table,sleep):
print("--- Defragmented table %s: %.3f seconds ---" % (table,end_time - start_time)) print("--- Defragmented table %s: %.3f seconds ---" % (table,end_time - start_time))
def defrag_all(mysql,doall=False): 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') stattables = ('router_stats','router_stats_gw','router_stats_neighbor','router_stats_netif','stats_global','stats_gw','stats_hood')
for t in alltables: for t in alltables:

View File

@ -43,7 +43,7 @@ def ban_router(mysql,dbid):
mysql.execute("INSERT INTO banned (mac, added) VALUES (%s, %s)",(mac,added,)) mysql.execute("INSERT INTO banned (mac, added) VALUES (%s, %s)",(mac,added,))
mysql.commit() 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 #global router_rate_limit_list
#if mac in 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: if findrouter:
router_id = findrouter["router"] 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: if olddata:
uptime = olddata["sys_uptime"] uptime = olddata["sys_uptime"]
@ -110,20 +116,32 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, statstim
) )
) AS distance ) AS distance
FROM FROM
hoods hoodsv1
WHERE lat IS NOT NULL AND lng IS NOT NULL WHERE lat IS NOT NULL AND lng IS NOT NULL
ORDER BY ORDER BY
distance ASC distance ASC
LIMIT 1 LIMIT 1
""",(lat,lng,lat,),"name") """,(lat,lng,lat,),"name")
if not router_update["hood"]: if not router_update["hood"]:
router_update["hood"] = "Default" router_update["hood"] = "DefaultV1"
if router_update["neighbours"] and not router_update["has_wan_uplink"]: if router_update["neighbours"] and not router_update["has_wan_uplink"]:
router_update["hood"] = "NoCoordinates" router_update["hood"] = "NoCoordinates"
if not router_update['lat'] and not router_update['lng'] and olddata and olddata['lat'] and olddata['lng']: 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 # Enable reset state; do before variable fallback
reset = True 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']: if not router_update['hostname']:
router_update['hostname'] = 'Give Me A Name' 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["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["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["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,)) 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. # 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"], 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"], 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["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"],)) ru["status_text"],ru["contact"],ru["lng"],ru["lat"],ru["visible_neighbours"],))
router_id = mysql.cursor().lastrowid router_id = mysql.cursor().lastrowid

View File

@ -199,17 +199,19 @@ def router_firmwares(mysql,selecthood=None,selectgw=None):
def hoods(mysql,selectgw=None): def hoods(mysql,selectgw=None):
data = mysql.fetchall(""" 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 FROM router
GROUP BY hood, status LEFT JOIN hoods ON router.hood = hoods.id
GROUP BY hoods.id, hoods.name, status
""") """)
result = {} result = {}
for rs in data: for rs in data:
if not rs["hood"]: if not rs["hood"]:
rs["hood"] = "Default" rs["hoodid"] = "1"
if not rs["hood"] in result: rs["hood"] = "NoHood"
result[rs["hood"]] = {} if not rs["hoodid"] in result:
result[rs["hood"]][rs["status"]] = rs["count"] result[rs["hoodid"]] = {'name':rs["hood"]}
result[rs["hoodid"]][rs["status"]] = rs["count"]
return result return result
def hoods_sum(mysql,selectgw=None): def hoods_sum(mysql,selectgw=None):

View File

@ -92,7 +92,6 @@ def get_nearest_router():
) AS distance ) AS distance
FROM FROM
router AS r 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 + """ WHERE r.lat IS NOT NULL AND r.lng IS NOT NULL """ + where + """
ORDER BY ORDER BY
distance ASC distance ASC
@ -155,6 +154,7 @@ def alfred():
""",(),"name") """,(),"name")
statstime = utcnow() statstime = utcnow()
netifdict = mysql.fetchdict("SELECT id, name FROM netifs",(),"name","id") netifdict = mysql.fetchdict("SELECT id, name FROM netifs",(),"name","id")
hoodsdict = mysql.fetchdict("SELECT id, name FROM hoods",(),"name","id")
if request.method == 'POST': if request.method == 'POST':
try: try:
alfred_data = request.get_json() alfred_data = request.get_json()
@ -167,7 +167,7 @@ def alfred():
# load router status xml data # load router status xml data
i = 1 i = 1
for mac, xml in alfred_data.get("64", {}).items(): 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): if (i%500 == 0):
mysql.commit() mysql.commit()
i += 1 i += 1
@ -260,8 +260,9 @@ def wifianal(selecthood):
SELECT hostname, mac, netif SELECT hostname, mac, netif
FROM router FROM router
INNER JOIN router_netif ON router.id = router_netif.router INNER JOIN router_netif ON router.id = router_netif.router
WHERE hood = %s INNER JOIN hoods ON router.hood = hoods.id
GROUP BY id, netif WHERE hoods.name = %s
GROUP BY router.id, netif
""",(selecthood,)) """,(selecthood,))
mysql.close() mysql.close()
@ -351,8 +352,9 @@ def routers():
# Suppresses routers without br-mesh # Suppresses routers without br-mesh
mysql = FreifunkMySQL() mysql = FreifunkMySQL()
router_data = mysql.fetchall(""" 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 FROM router
INNER JOIN hoods ON router.hood = hoods.id
INNER JOIN router_netif ON router.id = router_netif.router INNER JOIN router_netif ON router.id = router_netif.router
LEFT JOIN users ON router.contact = users.email LEFT JOIN users ON router.contact = users.email
WHERE netif = 'br-mesh' WHERE netif = 'br-mesh'
@ -394,6 +396,7 @@ def routers():
'id': str(router['id']), 'id': str(router['id']),
'name': router['hostname'], 'name': router['hostname'],
'mac': int2mac(router['mac']), 'mac': int2mac(router['mac']),
'hoodid': router['hoodid'],
'hood': router['hood'], 'hood': router['hood'],
'status': router['status'], 'status': router['status'],
'user': router['nickname'], 'user': router['nickname'],
@ -487,7 +490,7 @@ def get_routers_by_keyxchange_id(keyxchange_id):
mysql = FreifunkMySQL() mysql = FreifunkMySQL()
hood = mysql.findone(""" hood = mysql.findone("""
SELECT name SELECT name
FROM hoods FROM hoodsv1
WHERE id = %s WHERE id = %s
LIMIT 1 LIMIT 1
""",(int(keyxchange_id),)) """,(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 SELECT router.id, hostname, hardware, mac, fe80_addr, firmware, lat, lng, contact, position_comment, description
FROM router FROM router
INNER JOIN router_netif ON router.id = router_netif.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 ORDER BY hostname ASC
""",(hood["name"],)) """,(hood["name"],))
mysql.close() mysql.close()

View File

@ -52,8 +52,9 @@ def router_list():
mysql = FreifunkMySQL() mysql = FreifunkMySQL()
routers = mysql.fetchall(""" 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 FROM router
INNER JOIN hoods ON router.hood = hoods.id
LEFT JOIN users ON router.contact = users.email LEFT JOIN users ON router.contact = users.email
LEFT JOIN ( LEFT JOIN (
SELECT router, blocked.mac AS blocked FROM router_netif SELECT router, blocked.mac AS blocked FROM router_netif
@ -95,7 +96,11 @@ def router_mac(mac):
def router_info(dbid): def router_info(dbid):
try: try:
mysql = FreifunkMySQL() 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 mac = None
if router: if router:
@ -451,8 +456,9 @@ def user_info(nickname):
else: else:
flash("<b>You are not authorized to perform this action!</b>", "danger") flash("<b>You are not authorized to perform this action!</b>", "danger")
routers = mysql.fetchall(""" 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 FROM router
INNER JOIN hoods ON router.hood = hoods.id
LEFT JOIN ( LEFT JOIN (
SELECT router, blocked.mac AS blocked FROM router_netif SELECT router, blocked.mac AS blocked FROM router_netif
INNER JOIN blocked ON router_netif.mac = blocked.mac INNER JOIN blocked ON router_netif.mac = blocked.mac
@ -480,6 +486,7 @@ def global_statistics():
@app.route('/hoodstatistics/<selecthood>') @app.route('/hoodstatistics/<selecthood>')
def global_hoodstatistics(selecthood): def global_hoodstatistics(selecthood):
selecthood = int(selecthood)
mysql = FreifunkMySQL() mysql = FreifunkMySQL()
stats = mysql.fetchall("SELECT * FROM stats_hood WHERE hood = %s",(selecthood,)) stats = mysql.fetchall("SELECT * FROM stats_hood WHERE hood = %s",(selecthood,))
return helper_statistics(mysql,stats,selecthood,None) return helper_statistics(mysql,stats,selecthood,None)
@ -496,12 +503,17 @@ def helper_statistics(mysql,stats,selecthood,selectgw):
hoods = stattools.hoods(mysql,selectgw) hoods = stattools.hoods(mysql,selectgw)
gws = stattools.gws(mysql,selecthood) gws = stattools.gws(mysql,selecthood)
if selecthood:
selecthoodname = mysql.findone("SELECT name FROM hoods WHERE id = %s",(selecthood,),'name')
else:
selecthoodname = None
if selectgw: if selectgw:
selectgwint = mac2int(selectgw) selectgwint = mac2int(selectgw)
else: else:
selectgwint = None selectgwint = None
if selecthood and not selecthood in hoods: if selecthood and not selecthood in hoods.keys():
mysql.close() mysql.close()
return "Hood not found" return "Hood not found"
if selectgw and not selectgwint in gws: if selectgw and not selectgwint in gws:
@ -516,8 +528,9 @@ def helper_statistics(mysql,stats,selecthood,selectgw):
if selectgw: if selectgw:
newest_routers = mysql.fetchall(""" newest_routers = mysql.fetchall("""
SELECT id, hostname, hood, created SELECT router.id, hostname, hoods.id AS hoodid, hoods.name AS hood, created
FROM router FROM router
INNER JOIN hoods ON router.hood = hoods.id
INNER JOIN router_gw ON router.id = router_gw.router INNER JOIN router_gw ON router.id = router_gw.router
WHERE hardware <> 'Legacy' AND mac = %s WHERE hardware <> 'Legacy' AND mac = %s
ORDER BY created DESC ORDER BY created DESC
@ -525,14 +538,15 @@ def helper_statistics(mysql,stats,selecthood,selectgw):
""",(mac2int(selectgw),numnew,)) """,(mac2int(selectgw),numnew,))
else: else:
if selecthood: if selecthood:
where = " AND hood = %s" where = " AND hoods.id = %s"
tup = (selecthood,numnew,) tup = (selecthood,numnew,)
else: else:
where = "" where = ""
tup = (numnew,) tup = (numnew,)
newest_routers = mysql.fetchall(""" newest_routers = mysql.fetchall("""
SELECT id, hostname, hood, created SELECT router.id, hostname, hoods.id AS hoodid, hoods.name AS hood, created
FROM router FROM router
INNER JOIN hoods ON router.hood = hoods.id
WHERE hardware <> 'Legacy' {} WHERE hardware <> 'Legacy' {}
ORDER BY created DESC ORDER BY created DESC
LIMIT %s LIMIT %s
@ -552,6 +566,7 @@ def helper_statistics(mysql,stats,selecthood,selectgw):
return render_template("statistics.html", return render_template("statistics.html",
selecthood = selecthood, selecthood = selecthood,
selecthoodname = selecthoodname,
selectgw = selectgw, selectgw = selectgw,
selectgwint = selectgwint, selectgwint = selectgwint,
stats = stats, stats = stats,

View File

@ -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 " 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) k = "HEX(mac) {} REGEXP %s".format(no)
t.append(value.replace(':','')) 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) k = key + " {} REGEXP %s".format(no)
t.append(value.replace("_",".")) t.append(value.replace("_","."))
elif (key == 'hostname') or (key == 'firmware'): elif (key == 'hostname') or (key == 'firmware'):

View File

@ -139,8 +139,8 @@
{%- if router.position_comment %} {%- if router.position_comment %}
<tr><th>Position</th><td>{{ router.position_comment }}</td></tr> <tr><th>Position</th><td>{{ router.position_comment }}</td></tr>
{%- endif %} {%- endif %}
{%- if router.hood %} {%- if router.hoodname %}
<tr><th>Hood</th><td{%- if router.local %} class="hoodlocal"{%- elif router.v2 %} class="hoodv2"{%- endif %}><a href="{{ url_for('router_list', q='hood:^%s$' % router.hood) }}">{{ router.hood }}</a> <tr><th>Hood</th><td{%- if router.local %} class="hoodlocal"{%- elif router.v2 %} class="hoodv2"{%- endif %}><a href="{{ url_for('router_list', q='hood:^%s$' % router.hoodname) }}">{{ router.hoodname }}</a>
{%- if router.community %} {%- if router.community %}
({{ router.community }}) ({{ router.community }})
{%- endif -%} {%- endif -%}

View File

@ -1,5 +1,5 @@
{% extends "bootstrap.html" %} {% 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()}} {% block head %}{{super()}}
<script src="{{ url_for('static', filename='js/graph/date.js') }}"></script> <script src="{{ url_for('static', filename='js/graph/date.js') }}"></script>
<script src="{{ url_for('static', filename='js/graph/jquery.flot.js') }}"></script> <script src="{{ url_for('static', filename='js/graph/jquery.flot.js') }}"></script>
@ -68,16 +68,16 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{%- for hood, value in hoods|dictsort %} {%- for hoodid, value in hoods|dictsort %}
<tr> <tr>
<td class="firstrow{%- if hoods_sum[hood]["local"] %} hoodlocal{%- elif hoods_sum[hood]["v2"] %} hoodv2{%- endif %}"><a href="{{ url_for('router_list', q='hood:^%s$' % hood.replace(' ','_')) }}">{{ hood }}</a></td> <td class="firstrow{%- if hoods_sum[hoodid]["local"] %} hoodlocal{%- elif hoods_sum[hoodid]["v2"] %} hoodv2{%- endif %}"><a href="{{ url_for('router_list', q='hood:^%s$' % value['name'].replace(' ','_')) }}">{{ value['name'] }}</a></td>
<td class="stats">{{ hoods_gws[hood] or "-" }}</td> <td class="stats">{{ hoods_gws[hoodid] or "-" }}</td>
<td class="success">{{ value["online"] or 0 }}</td> <td class="success">{{ value["online"] or 0 }}</td>
<td class="danger" data-order="{{ value["offline"] or 0 }}">{{ value["offline"] or 0 }}{%- if value["orphaned"] %} ({{ value["orphaned"] or 0 }}){%- endif %}</td> <td class="danger" data-order="{{ value["offline"] or 0 }}">{{ value["offline"] or 0 }}{%- if value["orphaned"] %} ({{ value["orphaned"] or 0 }}){%- endif %}</td>
<td class="warning">{{ value["unknown"] or 0 }}</td> <td class="warning">{{ value["unknown"] or 0 }}</td>
<td class="active">{{ hoods_sum[hood]["routers"] }}</td> <td class="active">{{ hoods_sum[hoodid]["routers"] }}</td>
<td class="info">{{ hoods_sum[hood]["clients"] }}</td> <td class="info">{{ hoods_sum[hoodid]["clients"] }}</td>
<td class="stats"><a href="{{ url_for('global_hoodstatistics', selecthood='%s' % hood) }}">Stats</a></td> <td class="stats"><a href="{{ url_for('global_hoodstatistics', selecthood='%s' % hoodid) }}">Stats</a></td>
</tr> </tr>
{%- endfor %} {%- endfor %}
</tbody> </tbody>
@ -90,7 +90,7 @@
<td class="warning">{{ router_status.unknown or 0 }}</td> <td class="warning">{{ router_status.unknown or 0 }}</td>
<td class="active">{{ router_status.sum or 0 }}</td> <td class="active">{{ router_status.sum or 0 }}</td>
<td class="info">{{ clients }}</td> <td class="info">{{ clients }}</td>
<td class="stats"><a href="{{ url_for('global_statistics') }}">Global</a></td> <td class="stats"><a href="{{ url_for('global_statistics') }}">Global</a></td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
@ -99,27 +99,27 @@
</div> </div>
<div class="col-xs-12 col-md-6"> <div class="col-xs-12 col-md-6">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Routers{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }} (selected only){%- endif -%}</div> <div class="panel-heading">Routers{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }} (selected only){%- endif -%}</div>
<div class="panel-body"> <div class="panel-body">
<div id="globrouterstat" class="graph"></div> <div id="globrouterstat" class="graph"></div>
</div> </div>
</div> </div>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Clients{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }} (selected only){%- endif -%}</div> <div class="panel-heading">Clients{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }} (selected only){%- endif -%}</div>
<div class="panel-body"> <div class="panel-body">
<div id="globclientstat" class="graph"></div> <div id="globclientstat" class="graph"></div>
</div> </div>
</div> </div>
{%- if not selectgw %} {%- if not selectgw %}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Traffic{%- if selecthood %} @ {{ selecthood }}{%- endif -%}</div> <div class="panel-heading">Traffic{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}</div>
<div class="panel-body"> <div class="panel-body">
<div id="netstat" class="graph"></div> <div id="netstat" class="graph"></div>
</div> </div>
</div> </div>
{%- endif -%} {%- endif -%}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Newest Routers{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}</div> <div class="panel-heading">Newest Routers{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}</div>
<div class="panel-body" style="padding-bottom:34px"> <div class="panel-body" style="padding-bottom:34px">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-condensed"> <table class="table table-condensed">
@ -144,7 +144,7 @@
<div class="row"> <div class="row">
<div class="col-xs-12 col-md-6"> <div class="col-xs-12 col-md-6">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Gateways (selected / others){%- if selecthood %} @ {{ selecthood }}{%- endif -%}</div> <div class="panel-heading">Gateways (selected / others){%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}</div>
<div class="panel-body"> <div class="panel-body">
<table id="gwlist" class="table table-condensed table-hoods"> <table id="gwlist" class="table table-condensed table-hoods">
<thead> <thead>
@ -211,19 +211,19 @@
</div> </div>
{%- endif %} {%- endif %}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Router Firmwares{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}</div> <div class="panel-heading">Router Firmwares{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}</div>
<div class="panel-body"> <div class="panel-body">
<div id="globrouterfwstat" class="graph-pie"></div> <div id="globrouterfwstat" class="graph-pie"></div>
</div> </div>
</div> </div>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Router Models{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}</div> <div class="panel-heading">Router Models{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}</div>
<div class="panel-body"> <div class="panel-body">
<div id="globroutermodelsstat" class="graph-pie"></div> <div id="globroutermodelsstat" class="graph-pie"></div>
</div> </div>
</div> </div>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Router Models per Client{%- if selecthood %} @ {{ selecthood }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}</div> <div class="panel-heading">Router Models per Client{%- if selecthood %} @ {{ selecthoodname }}{%- endif -%}{%- if selectgw %} @ {{ selectgw }}{%- endif -%}</div>
<div class="panel-body"> <div class="panel-body">
<div id="globroutermodelsperclient" class="graph-pie"></div> <div id="globroutermodelsperclient" class="graph-pie"></div>
</div> </div>
@ -236,7 +236,7 @@
var router_models = {{ router_models|tojson }}; var router_models = {{ router_models|tojson }};
var routers_page_url = "{{ url_for('router_list') }}"; var routers_page_url = "{{ url_for('router_list') }}";
{%- if selecthood %} {%- if selecthood %}
var hood = "{{selecthood}}"; var hood = "{{selecthoodname}}";
var hoodstr = "hood:^" + hood.replace(/ /g, '_') + "$"; var hoodstr = "hood:^" + hood.replace(/ /g, '_') + "$";
{%- else %} {%- else %}
var hoodstr = ""; var hoodstr = "";