mirror of
https://github.com/brianshea2/meshmap.net.git
synced 2025-03-05 21:00:01 -08:00
handle special characters (e.g., newlines) in node data (#31)
This commit is contained in:
parent
92dcb58981
commit
ca2b7b3dd1
|
@ -97,7 +97,9 @@
|
|||
}
|
||||
</style>
|
||||
<div id="header">
|
||||
<div><a href="https://meshmap.net/" title="A nearly live map of Meshtastic nodes seen by the official Meshtastic MQTT server">MeshMap</a></div>
|
||||
<div>
|
||||
<a href="https://meshmap.net/" title="A nearly live map of Meshtastic nodes seen by the official Meshtastic MQTT server">MeshMap</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="#"
|
||||
|
@ -126,8 +128,10 @@
|
|||
182, 91, 46, 23, 11, 6, 3, 1,
|
||||
1, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
// encodes html reserved characters
|
||||
const html = str => str?.replace(/["&<>]/g, match => `&#${match.charCodeAt(0)};`)
|
||||
// encodes html reserved characters and ascii control characters
|
||||
const html = str => str
|
||||
?.replace(/[\x00-\x1F]/g, c => `\\x${c.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0')}`)
|
||||
.replace(/["&<>]/g, c => `&#${c.charCodeAt(0)};`)
|
||||
// makes more human-readable time duration strings
|
||||
const duration = d => {
|
||||
let s = ''
|
||||
|
@ -232,22 +236,23 @@
|
|||
<div class="title">${html(longName)} (${html(shortName)})</div>
|
||||
<div>${nodeLink(nodeNum, id)} | ${html(role)} | ${html(hwModel)}</div>
|
||||
<table><tbody>
|
||||
${fwVersion ? `<tr><th>Firmware</th><td>${html(fwVersion)}</td></tr>` : ''}
|
||||
${region ? `<tr><th>Region</th><td>${html(region)}</td></tr>` : ''}
|
||||
${modemPreset ? `<tr><th>Modem preset</th><td>${html(modemPreset)}</td></tr>` : ''}
|
||||
${hasDefaultCh ? `<tr><th>Has default channel</th><td>True</td></tr>` : ''}
|
||||
${onlineLocalNodes ? `<tr><th>Online local nodes</th><td>${onlineLocalNodes}</td></tr>` : ''}
|
||||
${batteryLevel ? `<tr><th>Power</th><td>${batteryLevel > 100 ? 'Plugged in' : `${batteryLevel}%`}${voltage ? ` (${voltage.toFixed(2)}V)` : ''}</td></tr>` : ''}
|
||||
${chUtil ? `<tr><th>ChUtil</th><td>${chUtil.toFixed(2)}%</td></tr>` : ''}
|
||||
${airUtilTx ? `<tr><th>AirUtilTX</th><td>${airUtilTx.toFixed(2)}%</td></tr>` : ''}
|
||||
${uptime ? `<tr><th>Uptime</th><td>${duration(uptime)}</td></tr>` : ''}
|
||||
${temperature ? `<tr><th>Temperature</th><td>${temperature.toFixed(1)}℃ / ${(temperature * 1.8 + 32).toFixed(1)}℉</td></tr>` : ''}
|
||||
${relativeHumidity ? `<tr><th>Relative Humidity</th><td>${Math.round(relativeHumidity)}%</td></tr>` : ''}
|
||||
${fwVersion ? `<tr><th>Firmware</th><td>${html(fwVersion)}</td></tr>` : ''}
|
||||
${region ? `<tr><th>Region</th><td>${html(region)}</td></tr>` : ''}
|
||||
${modemPreset ? `<tr><th>Modem preset</th><td>${html(modemPreset)}</td></tr>` : ''}
|
||||
${hasDefaultCh ? `<tr><th>Has default channel</th><td>True</td></tr>` : ''}
|
||||
${onlineLocalNodes ? `<tr><th>Online local nodes</th><td>${onlineLocalNodes}</td></tr>` : ''}
|
||||
${batteryLevel ? `<tr><th>Power</th><td>${batteryLevel > 100 ? 'Plugged in' : `${batteryLevel}%`}` +
|
||||
`${voltage ? ` (${voltage.toFixed(2)}V)` : ''}</td></tr>` : ''}
|
||||
${chUtil ? `<tr><th>ChUtil</th><td>${chUtil.toFixed(2)}%</td></tr>` : ''}
|
||||
${airUtilTx ? `<tr><th>AirUtilTX</th><td>${airUtilTx.toFixed(2)}%</td></tr>` : ''}
|
||||
${uptime ? `<tr><th>Uptime</th><td>${duration(uptime)}</td></tr>` : ''}
|
||||
${temperature ? `<tr><th>Temperature</th><td>${temperature.toFixed(1)}℃ / ` +
|
||||
`${(temperature * 1.8 + 32).toFixed(1)}℉</td></tr>` : ''}
|
||||
${relativeHumidity ? `<tr><th>Relative Humidity</th><td>${Math.round(relativeHumidity)}%</td></tr>` : ''}
|
||||
${barometricPressure ? `<tr><th>Barometric Pressure</th><td>${Math.round(barometricPressure)} hPa</td></tr>` : ''}
|
||||
${altitude ? `<tr><th>Altitude</th><td>${altitude.toLocaleString()} m above MSL</td></tr>` : ''}
|
||||
${precision && precisionMargins[precision-1] ?
|
||||
`<tr><th>Location precision</th><td>± ${precisionMargins[precision-1].toLocaleString()} m (orange circle)</td></tr>` : ''
|
||||
}
|
||||
${altitude ? `<tr><th>Altitude</th><td>${altitude.toLocaleString()} m above MSL</td></tr>` : ''}
|
||||
${precision && precisionMargins[precision-1] ? "<tr><th>Location precision</th><td>±" +
|
||||
`${precisionMargins[precision-1].toLocaleString()} m (orange circle)</td></tr>` : ''}
|
||||
</tbody></table>
|
||||
<table><thead>
|
||||
<tr><th>Last seen</th><th>via</th><th>root topic</th><th>channel</th></tr>
|
||||
|
@ -255,7 +260,9 @@
|
|||
${Array.from(
|
||||
new Map(
|
||||
Object.entries(seenBy)
|
||||
.map(([topic, seen]) => (m => ({seen, via: m[3] ?? id, root: m[1], chan: m[2]}))(topic.match(/^(.*)(?:\/2\/e\/(.*)\/(![0-9a-f]+)|\/2\/map\/)$/)))
|
||||
.map(([topic, seen]) => (m => ({seen, via: m[3] ?? id, root: m[1], chan: m[2]}))(
|
||||
topic.match(/^(.*)(?:\/2\/e\/(.*)\/(![0-9a-f]+)|\/2\/map\/)$/s)
|
||||
))
|
||||
.sort((a, b) => a.seen - b.seen)
|
||||
.map(v => [v.via, v])
|
||||
).values(),
|
||||
|
|
Loading…
Reference in a new issue