From 79166b344ce8223a628f903ff209d83c1d7b7fb7 Mon Sep 17 00:00:00 2001 From: Arindy Date: Sun, 28 Dec 2025 12:24:23 +0100 Subject: [PATCH] Add online status detection and update dependencies --- apis/networking/main.go | 23 ++++++++++++++++++----- go.mod | 6 +++++- go.sum | 7 ++++++- widgets/networkdevices.go | 14 +++++++++----- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/apis/networking/main.go b/apis/networking/main.go index c711e33..1ab6ffe 100644 --- a/apis/networking/main.go +++ b/apis/networking/main.go @@ -6,6 +6,9 @@ import ( "os" "os/exec" "strings" + "time" + + "github.com/prometheus-community/pro-bing" ) const deviceFile = "devices.json" @@ -15,6 +18,7 @@ type Device struct { IP string `json:"ip"` Interface string `json:"interface"` Icon string `json:"icon"` + Online bool `json:"online"` } func GetDevices() map[string]map[string]Device { @@ -26,6 +30,9 @@ func GetDevices() map[string]map[string]Device { if strings.HasPrefix(device.Interface, "macvlan") { continue } + if strings.HasPrefix(device.Interface, "br") { + continue + } if known, ok := knownDevices[mac]; ok { devices[mac] = Device{Name: known.Name, IP: device.IP, Interface: device.Interface, Icon: known.Icon} } else { @@ -34,22 +41,28 @@ func GetDevices() map[string]map[string]Device { } for mac, device := range knownDevices { if _, ok := devices[mac]; !ok { - devices[mac] = Device{Name: device.Name, IP: device.IP, Interface: "_offline_", Icon: device.Icon} + devices[mac] = Device{Name: device.Name, IP: device.IP, Interface: "_unknown_", Icon: device.Icon} } } writeDevices(devices) for mac, device := range devices { - if strings.HasPrefix(device.Interface, "br") { - device.Icon = "\uE7B0" - device.Interface = "bridge" - } if _, ok := result[device.Interface]; !ok { result[device.Interface] = make(map[string]Device) } if device.Icon == "" { device.Icon = "\U000F0C8A" } + pinger, err := probing.NewPinger(device.IP) + if err == nil { + pinger.Count = 1 + pinger.Timeout = 500 * time.Millisecond + if err := pinger.Run(); err == nil { + if pinger.Statistics().PacketsRecv > 0 { + device.Online = true + } + } + } result[device.Interface][mac] = device } diff --git a/go.mod b/go.mod index 8f3d189..025ebac 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/docker/docker v28.5.2+incompatible github.com/mum4k/termdash v0.20.0 github.com/pelletier/go-toml/v2 v2.2.4 + github.com/prometheus-community/pro-bing v0.7.0 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e ) @@ -25,6 +26,7 @@ require ( github.com/gdamore/tcell/v2 v2.7.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-runewidth v0.0.19 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect @@ -40,8 +42,10 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect go.opentelemetry.io/otel/metric v1.39.0 // indirect go.opentelemetry.io/otel/trace v1.39.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sync v0.18.0 // indirect golang.org/x/sys v0.39.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/term v0.37.0 // indirect golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.14.0 // indirect gotest.tools/v3 v3.5.2 // indirect diff --git a/go.sum b/go.sum index 75e65bb..3aa0729 100644 --- a/go.sum +++ b/go.sum @@ -72,6 +72,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus-community/pro-bing v0.7.0 h1:KFYFbxC2f2Fp6c+TyxbCOEarf7rbnzr9Gw8eIb0RfZA= +github.com/prometheus-community/pro-bing v0.7.0/go.mod h1:Moob9dvlY50Bfq6i88xIwfyw7xLFHH69LUgx9n5zqCE= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -114,6 +116,8 @@ golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -126,8 +130,9 @@ golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= diff --git a/widgets/networkdevices.go b/widgets/networkdevices.go index 7934330..3616ae2 100644 --- a/widgets/networkdevices.go +++ b/widgets/networkdevices.go @@ -29,20 +29,24 @@ func createNetworkDevicesList(ctx context.Context, _ terminalapi.Terminal, _ int interfaces := networking.GetDevices() list.Reset() for _, iface := range sortedInterfaces(interfaces) { - status := cell.ColorGreen - if iface == "_offline_" { - status = cell.ColorGray - } if err := list.Write(fmt.Sprintf("=== %s ===\n", iface)); err != nil { return err } for _, mac := range sortedKeys(interfaces[iface]) { + status := cell.ColorGray + if interfaces[iface][mac].Online { + status = cell.ColorGreen + } if err := list.Write(fmt.Sprintf("|%-15s|", mac), text.WriteCellOpts(cell.FgColor(cell.ColorGray))); err != nil { return err } - if err := list.Write(fmt.Sprintf("%2s ", interfaces[iface][mac].Icon), text.WriteCellOpts(cell.FgColor(status))); err != nil { + if err := list.Write(fmt.Sprintf("%2s ", interfaces[iface][mac].Icon), text.WriteCellOpts(cell.BgColor(status), cell.FgColor(cell.ColorBlack))); err != nil { return err } + if err := list.Write(fmt.Sprint("|"), text.WriteCellOpts(cell.FgColor(cell.ColorGray))); err != nil { + return err + } + if err := list.Write(fmt.Sprintf(" %s", interfaces[iface][mac].Name), text.WriteCellOpts(cell.FgColor(cell.ColorWhite))); err != nil { return err }