Files
omarchycn/shell/plugins/panels/network/Model.js
T

269 lines
7.8 KiB
JavaScript

function parseNetworkStatus(raw) {
var parts = String(raw || "disconnected\t\t\t").replace(/\r?\n+$/, "").split("\t")
return {
kind: parts[0] || "disconnected",
label: parts[1] || "",
signalStrength: parts[2] ? parseInt(parts[2], 10) : -1,
frequency: parts[3] || ""
}
}
function wifiIconFor(strength) {
var icons = ["󰤯", "󰤟", "󰤢", "󰤥", "󰤨"]
var index = Math.max(0, Math.min(4, Math.ceil(strength / 20) - 1))
return icons[index]
}
function connectionIcon(kind, signalStrength) {
if (kind === "wifi") return wifiIconFor(signalStrength)
if (kind === "ethernet") return "󰈀"
return "󰤮"
}
function formatHeaderSpeed(mbps) {
var v = parseInt(mbps, 10)
if (!v || v < 0) return ""
if (v >= 1000) return (v / 1000).toFixed(v % 1000 === 0 ? 0 : 1) + "gbit"
return v + "mbit"
}
function formatHeaderFreq(mhz) {
var v = parseFloat(mhz)
if (!v) return ""
if (v >= 2400 && v < 2500) return "2.4ghz"
if (v >= 4900 && v < 5925) return "5ghz"
if (v >= 5925 && v < 7125) return "6ghz"
if (v >= 57000 && v < 71000) return "60ghz"
var ghz = v / 1000
return ghz.toFixed(ghz % 1 === 0 ? 0 : 1) + "ghz"
}
function headerDetail(info) {
var value = info || {}
if (value.type === "ethernet") return formatHeaderSpeed(value.speed || "")
if (value.type === "wifi") return formatHeaderFreq(value.freq || "")
return ""
}
function parseKeyValue(raw) {
var next = {}
var lines = String(raw || "").split("\n")
for (var i = 0; i < lines.length; i++) {
var line = lines[i]
if (!line) continue
var idx = line.indexOf("\t")
if (idx === -1) continue
next[line.substring(0, idx)] = line.substring(idx + 1).trim()
}
return next
}
function throughputState(previous, next, now) {
var prev = previous || {}
var sample = next || {}
var iface = sample.iface || ""
var rx = parseFloat(sample.rx_bytes || "0")
var tx = parseFloat(sample.tx_bytes || "0")
var previousTime = Number(prev.prevSampleTime || 0)
if (iface !== (prev.prevIface || "") || previousTime === 0) {
return {
prevIface: iface,
prevRxBytes: rx,
prevTxBytes: tx,
prevSampleTime: now,
downloadRate: 0,
uploadRate: 0
}
}
var downloadRate = Number(prev.downloadRate || 0)
var uploadRate = Number(prev.uploadRate || 0)
var dt = now - previousTime
if (dt > 0) {
downloadRate = Math.max(0, (rx - Number(prev.prevRxBytes || 0)) / dt)
uploadRate = Math.max(0, (tx - Number(prev.prevTxBytes || 0)) / dt)
}
return {
prevIface: iface,
prevRxBytes: rx,
prevTxBytes: tx,
prevSampleTime: now,
downloadRate: downloadRate,
uploadRate: uploadRate
}
}
function pingSampleValue(raw) {
var value = parseFloat(raw)
if (!isFinite(value) || value < 0) return null
return value
}
function appendPingSample(samples, raw, limit) {
var values = Array.isArray(samples) ? samples.slice() : []
values.push(pingSampleValue(raw))
while (values.length > limit) values.shift()
return values
}
function averagePingLatency(samples, limit) {
var values = Array.isArray(samples) ? samples : []
var sampleLimit = Math.max(1, parseInt(limit, 10) || values.length || 1)
var total = 0
var count = 0
for (var i = Math.max(0, values.length - sampleLimit); i < values.length; i++) {
var value = values[i]
if (typeof value !== "number" || !isFinite(value) || value < 0) continue
total += value
count++
}
return count > 0 ? total / count : -1
}
function pingPacketLossPercent(samples) {
var values = Array.isArray(samples) ? samples : []
if (values.length === 0) return 0
var lost = 0
for (var i = 0; i < values.length; i++) {
if (values[i] === null) lost++
}
return Math.round((lost / values.length) * 100)
}
function formatPacketLoss(percent) {
var value = parseInt(percent, 10)
if (!value || value < 0) return "0%"
return value + "%"
}
function pingLatencyState(previous, next, limit, averageLimit) {
var prev = previous || {}
var sample = next || {}
var iface = sample.iface || ""
var window = Math.max(1, parseInt(limit, 10) || 5)
var averageWindow = Math.max(1, parseInt(averageLimit, 10) || window)
var reset = iface === "" || iface !== (prev.pingIface || "")
var routerSamples = reset ? [] : prev.routerPingSamples
var internetSamples = reset ? [] : prev.internetPingSamples
routerSamples = sample.router_ping_ms === undefined ? [] : appendPingSample(routerSamples, sample.router_ping_ms, window)
internetSamples = sample.internet_ping_ms === undefined ? [] : appendPingSample(internetSamples, sample.internet_ping_ms, window)
return {
pingIface: iface,
routerPingSamples: routerSamples,
internetPingSamples: internetSamples,
routerPingLatency: averagePingLatency(routerSamples, averageWindow),
internetPingLatency: averagePingLatency(internetSamples, averageWindow),
internetPingPacketLoss: pingPacketLossPercent(internetSamples)
}
}
function formatBytes(bytes) {
var n = Number(bytes)
if (!isFinite(n) || n < 0) n = 0
if (n < 1024) return Math.round(n) + " B"
if (n < 1024 * 1024) return (n / 1024).toFixed(1) + " KB"
if (n < 1024 * 1024 * 1024) return (n / (1024 * 1024)).toFixed(1) + " MB"
return (n / (1024 * 1024 * 1024)).toFixed(2) + " GB"
}
function formatRate(bytesPerSec) {
return formatBytes(bytesPerSec) + "/s"
}
function formatSpeedMbps(mbps) {
var value = parseFloat(mbps)
if (!isFinite(value) || value <= 0) return "--"
return value.toFixed(value > 0 && value < 10 ? 1 : 0) + " Mbps"
}
function formatPingLatency(ms) {
var value = parseFloat(ms)
if (!isFinite(value) || value < 0) return "Timeout"
return value.toFixed(value > 0 && value < 10 ? 1 : 0) + " ms"
}
function wifiRow(network) {
if (!network) return null
return {
network: network,
connected: !!network.connected,
known: !!network.known,
ssid: network.name || "",
signal: Math.round((network.signalStrength || 0) * 100),
security: network.security
}
}
function sortWifiRows(rows) {
var nets = Array.isArray(rows) ? rows.slice() : []
nets.sort(function(a, b) {
if (a.connected !== b.connected) return a.connected ? -1 : 1
if (a.known !== b.known) return a.known ? -1 : 1
return b.signal - a.signal
})
return nets
}
function wifiSectionTitle(wifiNetworks, index) {
var networks = Array.isArray(wifiNetworks) ? wifiNetworks : []
if (index < 0 || index >= networks.length) return ""
var net = networks[index]
if (!net) return ""
if (net.known && index === 0) return "KNOWN NETWORKS"
if (!net.known && (index === 0 || (networks[index - 1] && networks[index - 1].known))) return "OTHER NETWORKS"
return ""
}
function isProtected(security, openSecurity) {
return security !== openSecurity
}
function networkFailureReason(reason, reasons) {
var r = reasons || {}
if (reason === r.NoSecrets) return "Passphrase required"
if (reason === r.WifiAuthTimeout) return "Wrong password"
if (reason === r.WifiNetworkLost) return "Network lost"
if (reason === r.WifiClientDisconnected) return "Disconnected"
if (reason === r.WifiClientFailed) return "Connection failed"
return "Failed to connect"
}
if (typeof module !== "undefined") {
module.exports = {
parseNetworkStatus: parseNetworkStatus,
wifiIconFor: wifiIconFor,
connectionIcon: connectionIcon,
formatHeaderSpeed: formatHeaderSpeed,
formatHeaderFreq: formatHeaderFreq,
headerDetail: headerDetail,
parseKeyValue: parseKeyValue,
throughputState: throughputState,
pingLatencyState: pingLatencyState,
pingPacketLossPercent: pingPacketLossPercent,
formatPacketLoss: formatPacketLoss,
formatBytes: formatBytes,
formatRate: formatRate,
formatSpeedMbps: formatSpeedMbps,
formatPingLatency: formatPingLatency,
wifiRow: wifiRow,
sortWifiRows: sortWifiRows,
wifiSectionTitle: wifiSectionTitle,
isProtected: isProtected,
networkFailureReason: networkFailureReason
}
}