Global: Identify local routers and indicate their status

This detects local routers based on knowing their hood, but not
having the hood listed in hoodsv2 table.

This classification is performed when the routers' alfred data
is parsed. Thus, offline routers won't change.

This requires changes to the MySQL database!

Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
This commit is contained in:
Adrian Schmutzler 2018-08-27 21:36:51 +02:00
parent b38af9a74b
commit dd6d101ccd
16 changed files with 226 additions and 59 deletions

View File

@ -94,6 +94,7 @@ mysql.execute("""
`community` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`hood` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`v2` tinyint(1) NOT NULL,
`local` tinyint(1) NOT NULL,
`gateway` tinyint(1) NOT NULL,
`status_text` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`contact` varchar(200) COLLATE utf8_unicode_ci NOT NULL,

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map>
<Map background-color="transparent" srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
<Style name="routerpoint" filter-mode="first">
<Rule>
<Filter>([status] = 'online')</Filter>
<!-- For directed antenna
<PointSymbolizer file="static/img/router_direct_green.svg" allow-overlap="true" transform="rotate(45)" />
-->
<PointSymbolizer file="static/img/router_green_v2.svg" allow-overlap="true" />
</Rule>
<Rule>
<Filter>([status] = 'offline')</Filter>
<PointSymbolizer file="static/img/router_red_v2.svg" allow-overlap="true" />
</Rule>
<Rule>
<Filter>([status] = 'unknown')</Filter>
<PointSymbolizer file="static/img/router_yellow.svg" allow-overlap="true" />
</Rule>
<Rule>
<Filter>([status] = 'orphaned')</Filter>
<PointSymbolizer file="static/img/router_grey.svg" allow-overlap="true" />
</Rule>
<Rule>
<Filter>([status] = 'online_wan')</Filter>
<PointSymbolizer file="static/img/router_green_v2_white.svg" allow-overlap="true" />
</Rule>
<Rule>
<Filter>([status] = 'offline_wan')</Filter>
<PointSymbolizer file="static/img/router_red_v2_white.svg" allow-overlap="true" />
</Rule>
<Rule>
<Filter>([status] = 'unknown_wan')</Filter>
<PointSymbolizer file="static/img/router_yellow_white.svg" allow-overlap="true" />
</Rule>
<Rule>
<Filter>([status] = 'orphaned_wan')</Filter>
<PointSymbolizer file="static/img/router_grey_white.svg" allow-overlap="true" />
</Rule>
</Style>
<Style name="color" filter-mode="first">
<Rule>
<Filter>([quality] &lt; 1)</Filter>
<LineSymbolizer stroke-width="3" stroke="#008c00" stroke-linecap="butt" clip="false" />
</Rule>
<Rule>
<Filter>([quality] &lt; 105)</Filter>
<LineSymbolizer stroke-width="3" stroke="#ff1e1e" stroke-linecap="butt" clip="false" />
</Rule>
<Rule>
<Filter>([quality] &lt; 130)</Filter>
<LineSymbolizer stroke-width="3" stroke="#ff4949" stroke-linecap="butt" clip="false" />
</Rule>
<Rule>
<Filter>([quality] &lt; 155)</Filter>
<LineSymbolizer stroke-width="3" stroke="#ff6a6a" stroke-linecap="butt" clip="false" />
</Rule>
<Rule>
<Filter>([quality] &lt; 180)</Filter>
<LineSymbolizer stroke-width="3" stroke="#ffac53" stroke-linecap="butt" clip="false" />
</Rule>
<Rule>
<Filter>([quality] &lt; 205)</Filter>
<LineSymbolizer stroke-width="3" stroke="#ffeb79" stroke-linecap="butt" clip="false" />
</Rule>
<Rule>
<Filter>([quality] &lt; 230)</Filter>
<LineSymbolizer stroke-width="3" stroke="#79ff7c" stroke-linecap="butt" clip="false" />
</Rule>
<Rule>
<Filter>([quality] &lt; 300)</Filter>
<LineSymbolizer stroke-width="3" stroke="#04ff0a" stroke-linecap="butt" clip="false" />
</Rule>
</Style>
<Style name="l3_color" filter-mode="first">
<Rule>
<LineSymbolizer stroke-width="3" stroke="#0684c4" stroke-linecap="butt" clip="false" />
</Rule>
</Style>
<Style name="shadow1">
<Rule>
<LineSymbolizer stroke-width="4" stroke="#333333" stroke-linecap="round" stroke-opacity="0.5" />
</Rule>
</Style>
<Layer name="links" srs="+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>shadow1</StyleName>
<StyleName>color</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="file">csv/links_local.csv</Parameter>
</Datasource>
</Layer>
<Layer name="l3_links" srs="+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>shadow1</StyleName>
<StyleName>l3_color</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="file">csv/l3_links_local.csv</Parameter>
</Datasource>
</Layer>
<Layer name="routers" srs="+proj=latlong +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>routerpoint</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="file">csv/routers_local.csv</Parameter>
</Datasource>
</Layer>
</Map>

View File

@ -2,6 +2,7 @@
liteserv.py routers.xml --processes=5 &
liteserv.py routers_v2.xml -p 8003 --processes=5 &
liteserv.py routers_local.xml -p 8004 --processes=5 &
liteserv.py hoods.xml -p 8001 --processes=5 &
liteserv.py hoods_v2.xml -p 8002 --processes=5

View File

@ -24,6 +24,16 @@
"metatile": {"buffer": 128},
"cache lifespan": 300
},
"tiles/routers_local": {
"provider": {
"class": "dynmapnik:DynMapnik",
"kwargs": {
"mapfile": "/usr/share/ffmap/routers_local.xml"
}
},
"metatile": {"buffer": 128},
"cache lifespan": 300
},
"tiles/hoods": {
"provider": {
"class": "dynmapnik:DynMapnik",

View File

@ -11,8 +11,6 @@ import math
import numpy as np
from scipy.spatial import Voronoi
import urllib.request, json
EARTH_RADIUS = 6378137.0
def touch(fname, times=None):
@ -70,13 +68,13 @@ def draw_voronoi_lines(csv, hoods):
def update_mapnik_csv(mysql):
routers = mysql.fetchall("""
SELECT router.status, router.lat, router.lng, hoods.name AS hood, router.wan_uplink FROM router
LEFT JOIN hoods ON router.hood = hoods.name
SELECT router.status, router.lat, router.lng, router.wan_uplink, v2, local FROM router
WHERE router.lat IS NOT NULL AND router.lng IS NOT NULL
""")
rv1 = "lng,lat,status\n"
rv2 = "lng,lat,status\n"
rvlocal = "lng,lat,status\n"
for router in routers:
tmpstatus = router["status"]
@ -87,20 +85,23 @@ def update_mapnik_csv(mysql):
router["lat"],
tmpstatus
)
if router["hood"]:
rv1 += tmp
else:
if router["local"]:
rvlocal += tmp
elif router["v2"]:
rv2 += tmp
else:
rv1 += tmp
with open(os.path.join(CONFIG["csv_dir"], "routers.csv"), "w") as csv:
csv.write(rv1)
with open(os.path.join(CONFIG["csv_dir"], "routers_v2.csv"), "w") as csv:
csv.write(rv2)
with open(os.path.join(CONFIG["csv_dir"], "routers_local.csv"), "w") as csv:
csv.write(rvlocal)
dblinks = mysql.fetchall("""
SELECT r1.id AS rid, r2.id AS nid, r1.lat AS rlat, r1.lng AS rlng, r2.lat AS nlat, r2.lng AS nlng, n.netif AS netif, n.type AS type, MAX(quality) AS quality, hoods.name AS hood
SELECT r1.id AS rid, r2.id AS nid, r1.lat AS rlat, r1.lng AS rlng, r2.lat AS nlat, r2.lng AS nlng, n.netif AS netif, n.type AS type, MAX(quality) AS quality, r1.v2, r1.local
FROM router AS r1
LEFT JOIN hoods ON r1.hood = hoods.name
INNER JOIN router_neighbor AS n ON r1.id = n.router
INNER JOIN (
SELECT router, mac FROM router_netif GROUP BY mac, router
@ -108,12 +109,14 @@ def update_mapnik_csv(mysql):
INNER JOIN router AS r2 ON net.router = r2.id
WHERE r1.lat IS NOT NULL AND r1.lng IS NOT NULL AND r2.lat IS NOT NULL AND r2.lng IS NOT NULL
AND r1.status = 'online'
GROUP BY r1.id, r1.lat, r1.lng, r2.id, r2.lat, r2.lng, n.netif, n.type, hoods.name
GROUP BY r1.id, r1.lat, r1.lng, r2.id, r2.lat, r2.lng, n.netif, n.type, r1.v2, r1.local
""")
links = []
linksl3 = []
linksv2 = []
linksl3v2 = []
linkslocal = []
linksl3local = []
dictl3 = {}
dictl2 = {}
# The following code is very ugly, but works and is not too slow. Maybe make it nicer at some point ...
@ -133,10 +136,12 @@ def update_mapnik_csv(mysql):
row["nlng"],
row["nlat"],
)
if row["hood"]:
linksl3.append(tmp)
else:
if row["local"]:
linksl3local.append(tmp)
elif row["v2"]:
linksl3v2.append(tmp)
else:
linksl3.append(tmp)
else:
# Check for duplicate
if row["nid"] in dictl2.keys() and row["rid"] in dictl2[row["nid"]].keys():
@ -168,14 +173,16 @@ def update_mapnik_csv(mysql):
row["nlat"],
row["quality"],
)
dictl2[row["rid"]][row["nid"]] = {'hood':row["hood"],'data':tmp}
dictl2[row["rid"]][row["nid"]] = {'v2':row["v2"],'local':row["local"],'data':tmp}
for d1 in dictl2.values():
for d2 in d1.values():
if d2["hood"]:
links.append(d2["data"])
else:
if d2["local"]:
linkslocal.append(d2["data"])
elif d2["v2"]:
linksv2.append(d2["data"])
else:
links.append(d2["data"])
with open(os.path.join(CONFIG["csv_dir"], "links.csv"), "w") as csv:
csv.write("WKT,quality\n")
@ -187,6 +194,11 @@ def update_mapnik_csv(mysql):
for link in sorted(linksv2, key=lambda l: l[4]):
csv.write("\"LINESTRING (%f %f,%f %f)\",%i\n" % link)
with open(os.path.join(CONFIG["csv_dir"], "links_local.csv"), "w") as csv:
csv.write("WKT,quality\n")
for link in sorted(linkslocal, key=lambda l: l[4]):
csv.write("\"LINESTRING (%f %f,%f %f)\",%i\n" % link)
with open(os.path.join(CONFIG["csv_dir"], "l3_links.csv"), "w") as csv:
csv.write("WKT\n")
for link in linksl3:
@ -197,6 +209,11 @@ def update_mapnik_csv(mysql):
for link in linksl3v2:
csv.write("\"LINESTRING (%f %f,%f %f)\"\n" % link)
with open(os.path.join(CONFIG["csv_dir"], "l3_links_local.csv"), "w") as csv:
csv.write("WKT\n")
for link in linksl3local:
csv.write("\"LINESTRING (%f %f,%f %f)\"\n" % link)
dbhoods = mysql.fetchall("""
SELECT name, lat, lng FROM hoods
WHERE lat IS NOT NULL AND lng IS NOT NULL
@ -247,6 +264,7 @@ def update_mapnik_csv(mysql):
touch("/usr/share/ffmap/hoods_v2.xml")
touch("/usr/share/ffmap/routers.xml")
touch("/usr/share/ffmap/routers_v2.xml")
touch("/usr/share/ffmap/routers_local.xml")
if __name__ == '__main__':
update_mapnik_csv()

View File

@ -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, netifdict, statstime):
def import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, statstime):
#global router_rate_limit_list
#if mac in router_rate_limit_list:
@ -64,6 +64,7 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, netifdict, statstime):
try:
findrouter = mysql.findone("SELECT router FROM router_netif WHERE mac = %s LIMIT 1",(mac2int(mac),))
router_update = parse_nodewatcher_xml(xml,statstime)
router_update["local"] = bool(router_update["hood"] and not router_update["hood"] in hoodsv2)
# cancel if banned mac found
for n in router_update["netifs"]:
@ -164,7 +165,7 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, netifdict, statstime):
sys_loadavg = %s, sys_procrun = %s, sys_proctot = %s, clients = %s, clients_eth = %s, clients_w2 = %s, clients_w5 = %s,
w2_active = %s, w2_busy = %s, w5_active = %s, w5_busy = %s, w2_airtime = %s, w5_airtime = %s, wan_uplink = %s, tc_enabled = %s, tc_in = %s, tc_out = %s,
cpu = %s, chipset = %s, hardware = %s, os = %s,
batman = %s, routing_protocol = %s, kernel = %s, nodewatcher = %s, firmware = %s, firmware_rev = %s, description = %s, position_comment = %s, community = %s, hood = %s, v2 = %s, gateway = %s,
batman = %s, routing_protocol = %s, kernel = %s, nodewatcher = %s, firmware = %s, firmware_rev = %s, description = %s, position_comment = %s, community = %s, hood = %s, v2 = %s, local = %s, gateway = %s,
status_text = %s, contact = %s, lng = %s, lat = %s, neighbors = %s, reset = %s
WHERE id = %s
""",(
@ -172,7 +173,7 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, netifdict, statstime):
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["gateway"],
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["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.
@ -237,15 +238,15 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, netifdict, statstime):
sys_loadavg, sys_procrun, sys_proctot, clients, clients_eth, clients_w2, clients_w5,
w2_active, w2_busy, w5_active, w5_busy, w2_airtime, w5_airtime, wan_uplink, tc_enabled, tc_in, tc_out,
cpu, chipset, hardware, os,
batman, routing_protocol, kernel, nodewatcher, firmware, firmware_rev, description, position_comment, community, hood, v2, gateway,
batman, routing_protocol, kernel, nodewatcher, firmware, firmware_rev, description, position_comment, community, hood, v2, local, gateway,
status_text, contact, lng, lat, neighbors)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
""",(
ru["status"],ru["hostname"],created,ru["last_contact"],ru["sys_time"].strftime('%Y-%m-%d %H:%M:%S'),ru["sys_uptime"],ru["memory"]["free"],ru["memory"]["buffering"],ru["memory"]["caching"],
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["gateway"],
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["status_text"],ru["contact"],ru["lng"],ru["lat"],ru["visible_neighbours"],))
router_id = mysql.cursor().lastrowid

View File

@ -214,7 +214,7 @@ def hoods(mysql,selectgw=None):
def hoods_sum(mysql,selectgw=None):
data = mysql.fetchall("""
SELECT hood, COUNT(id) AS count, SUM(clients) AS clients, MAX(v2) AS v2
SELECT hood, COUNT(id) AS count, SUM(clients) AS clients, MAX(v2) AS v2, MAX(local) AS local
FROM router
GROUP BY hood
""")
@ -222,7 +222,7 @@ def hoods_sum(mysql,selectgw=None):
for rs in data:
if not rs["hood"]:
rs["hood"] = "Default"
result[rs["hood"]] = {"routers": rs["count"], "clients": rs["clients"], "v2": rs["v2"]}
result[rs["hood"]] = {"routers": rs["count"], "clients": rs["clients"], "v2": rs["v2"], "local": rs["local"]}
return result
def hoods_gws(mysql):

View File

@ -64,19 +64,22 @@ def load_neighbor_stats(dbid):
# map ajax
@api.route('/get_nearest_router')
def get_nearest_router():
if request.args.get("layer") == "none":
r = make_response(bson2json(None))
r.mimetype = 'application/json'
return r
lng = float(request.args.get("lng"))
lat = float(request.args.get("lat"))
where = ""
if request.args.get("layer") == "v1":
where = " AND h.id IS NOT NULL "
elif request.args.get("layer") == "v2":
where = " AND h.id IS NULL "
wherelist = []
if request.args.get("v1") == "on":
wherelist.append("(v2 = FALSE AND local = FALSE)")
if request.args.get("v2") == "on":
wherelist.append("(v2 = TRUE AND local = FALSE)")
if request.args.get("local") == "on":
wherelist.append("local = TRUE")
if wherelist:
where = " AND ( " + ' OR '.join(wherelist) + " ) "
else:
r = make_response(bson2json(None))
r.mimetype = 'application/json'
return r
mysql = FreifunkMySQL()
router = mysql.findone("""
@ -95,6 +98,10 @@ def get_nearest_router():
distance ASC
LIMIT 1
""",(lat,lng,lat,))
if not router:
r = make_response(bson2json(None))
r.mimetype = 'application/json'
return r
router["neighbours"] = mysql.fetchall("""
SELECT nb.mac, nb.netif, nb.quality, r.hostname, r.id
@ -143,6 +150,9 @@ def alfred():
banned = mysql.fetchall("""
SELECT mac FROM banned
""",(),"mac")
hoodsv2 = mysql.fetchall("""
SELECT name FROM hoodsv2
""",(),"name")
statstime = utcnow()
netifdict = mysql.fetchdict("SELECT id, name FROM netifs",(),"name","id")
if request.method == 'POST':
@ -157,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, netifdict, statstime)
import_nodewatcher_xml(mysql, mac, xml, banned, hoodsv2, netifdict, statstime)
if (i%500 == 0):
mysql.commit()
i += 1

View File

@ -29,6 +29,7 @@ app.register_blueprint(filters)
tileurls = {
"routers": "/tiles/routers",
"routers_v2": "/tiles/routers_v2",
"routers_local": "/tiles/routers_local",
"hoods": "/tiles/hoods",
"hoods_v2": "/tiles/hoods_v2",
}
@ -51,7 +52,7 @@ 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
SELECT router.id, hostname, status, hood, contact, nickname, hardware, router.created, sys_uptime, last_contact, clients, reset, blocked, v2, local
FROM router
LEFT JOIN users ON router.contact = users.email
LEFT JOIN (
@ -450,7 +451,7 @@ def user_info(nickname):
else:
flash("<b>You are not authorized to perform this action!</b>", "danger")
routers = mysql.fetchall("""
SELECT id, hostname, status, hood, firmware, hardware, created, sys_uptime, clients, reset, blocked, v2
SELECT id, hostname, status, hood, firmware, hardware, created, sys_uptime, clients, reset, blocked, v2, local
FROM router
LEFT JOIN (
SELECT router, blocked.mac AS blocked FROM router_netif

View File

@ -45,3 +45,18 @@ table.neighbours {
padding-left: 5px;
padding-right: 7px;
}
.hoodv2 {
color: #2db200;
}
.hoodlocal {
color: #ffbf00;
}
.hoodv2 a {
color: #2db200;
}
.hoodlocal a {
color: #ffbf00;
}

View File

@ -28,6 +28,7 @@ var overlay_config = {
var routers = new L.TileLayer(tileurls.routers + '/{z}/{x}/{y}.png', overlay_config).addTo(map);
var routers_v2 = new L.TileLayer(tileurls.routers_v2 + '/{z}/{x}/{y}.png', overlay_config).addTo(map);
var routers_local = new L.TileLayer(tileurls.routers_local + '/{z}/{x}/{y}.png', overlay_config).addTo(map);
var hoods = new L.TileLayer(tileurls.hoods + '/{z}/{x}/{y}.png', overlay_config);
var hoods_v2 = new L.TileLayer(tileurls.hoods_v2 + '/{z}/{x}/{y}.png', overlay_config);
var popuplayer = new L.TileLayer('');
@ -36,10 +37,11 @@ layersControl = new L.Control.Layers({
"openstreetmap.de": tilesosmde,
"Thunderforest Outdoors": tilestfod
}, {
"Routers": routers,
"Routers v2 und dezentral": routers_v2,
"Hoods": hoods,
"Hoods v2": hoods_v2,
"Routers V1": routers,
"Routers V2": routers_v2,
"Local Routers": routers_local,
"Hoods V1": hoods,
"Hoods V2": hoods_v2,
"Position-Popup": popuplayer
});
map.addControl(layersControl);
@ -71,15 +73,17 @@ map.on('click', function(pos) {
var size_of_world_in_px = map.options.crs.scale(map.getZoom());
layeropt = ""
if (map.hasLayer(routers) && !map.hasLayer(routers_v2)) {
if (map.hasLayer(routers)) {
console.debug("Looking for router in V1 ...");
layeropt = "&layer=v1"
} else if (!map.hasLayer(routers) && map.hasLayer(routers_v2)) {
layeropt += "&v1=on"
}
if (map.hasLayer(routers_v2)) {
console.debug("Looking for router in V2 ...");
layeropt = "&layer=v2"
} else if (!map.hasLayer(routers) && !map.hasLayer(routers_v2)) {
console.debug("No layer specified to look in.");
layeropt = "&layer=none"
layeropt += "&v2=on"
}
if (map.hasLayer(routers_local)) {
console.debug("Looking for router in local hoods ...");
layeropt += "&local=on"
}
var px_per_deg_lng = size_of_world_in_px / 360;

View File

@ -140,7 +140,7 @@
<tr><th>Position</th><td>{{ router.position_comment }}</td></tr>
{%- endif %}
{%- if router.hood %}
<tr><th>Hood</th><td><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.hood) }}">{{ router.hood }}</a>
{%- if router.community %}
({{ router.community }})
{%- endif -%}

View File

@ -47,7 +47,7 @@
{%- if router.reset %} - <span style="color:#d90000">Reset!</span>{%- endif %}{%- if router.blocked and not router.v2 %} - <span style="color:#d90000">Blocked!</span>{%- endif %}
</td>
<td class="text-center"><span class="{{ router.status|status2css }}">{{ router.status }}</span></td>
<td>{{ router.hood }}</td>
<td{%- if router.local %} class="hoodlocal"{%- elif router.v2 %} class="hoodv2"{%- endif %}>{{ router.hood }}</td>
<td>{{ router.nickname if router.nickname else "" }}</td>
<td class="text-nowrap">{{ router.hardware }}</td>
<td class="text-nowrap">{{ router.created|utc2local|format_dt_date }}</td>

View File

@ -45,9 +45,6 @@
.table-hoods .firstrow {
text-align: left;
}
.hoodv2 a {
color: #2db200;
}
</style>
{% endblock %}
@ -73,7 +70,7 @@
<tbody>
{%- for hood, value in hoods|dictsort %}
<tr>
<td class="firstrow{%- if 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[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="stats">{{ hoods_gws[hood] or "-" }}</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>

View File

@ -107,7 +107,7 @@
{%- if router.reset %} - <span style="color:#d90000">Reset!</span>{%- endif %}{%- if router.blocked and not router.v2 %} - <span style="color:#d90000">Blocked!</span>{%- endif %}
</td>
<td class="text-center"><span class="{{ router.status|status2css }}">{{ router.status }}</span></td>
<td>{{ router.hood }}</td>
<td{%- if router.local %} class="hoodlocal"{%- elif router.v2 %} class="hoodv2"{%- endif %}>{{ router.hood }}</td>
<td>{{ router.firmware }}</td>
<td class="text-nowrap">{{ router.get("hardware", "") }}</td>
<td class="text-nowrap">{{ router.created|utc2local|format_dt_date }}</td>

View File

@ -5,9 +5,9 @@ mkdir -vp /var/lib/ffmap/csv
chown -R www-data:www-data /var/lib/ffmap
mkdir -vp /usr/share/ffmap
cp -v ffmap/mapnik/{hoods,hoods_v2,routers,routers_v2}.xml /usr/share/ffmap
sed -i -e 's#>csv/#>/var/lib/ffmap/csv/#' /usr/share/ffmap/{hoods,hoods_v2,routers,routers_v2}.xml
chown www-data:www-data /usr/share/ffmap/{hoods,hoods_v2,routers,routers_v2}.xml
cp -v ffmap/mapnik/{hoods,hoods_v2,routers,routers_v2,routers_local}.xml /usr/share/ffmap
sed -i -e 's#>csv/#>/var/lib/ffmap/csv/#' /usr/share/ffmap/{hoods,hoods_v2,routers,routers_v2,routers_local}.xml
chown www-data:www-data /usr/share/ffmap/{hoods,hoods_v2,routers,routers_v2,routers_local}.xml
cp -v ffmap/mapnik/tilestache.cfg /usr/share/ffmap
cp -rv ffmap/web/static /usr/share/ffmap