From e0686e8adf8d337f1ae5938b97972df2c5ebb515 Mon Sep 17 00:00:00 2001 From: Ezri Brimhall Date: Wed, 5 Feb 2025 10:23:47 -0700 Subject: [PATCH] Unifying eww configs --- .../{eww.yuck##hostname.zariman => eww.yuck} | 0 .config/eww/eww.yuck##hostname.normandy | 74 ---- .config/eww/eww.yuck##hostname.rocinante | 26 -- .config/eww/eww.yuck##hostname.tycho | 81 ---- ...work.yuck##hostname.tycho => network.yuck} | 0 .../modules/network.yuck##hostname.normandy | 194 ---------- .../modules/network.yuck##hostname.rocinante | 77 ---- .../modules/network.yuck##hostname.zariman | 347 ------------------ ...{network.py##hostname.tycho => network.py} | 0 .../eww/scripts/network.py##hostname.normandy | 64 ---- .../scripts/network.py##hostname.rocinante | 81 ---- .../eww/scripts/network.py##hostname.zariman | 306 --------------- 12 files changed, 1250 deletions(-) rename .config/eww/{eww.yuck##hostname.zariman => eww.yuck} (100%) delete mode 100644 .config/eww/eww.yuck##hostname.normandy delete mode 100644 .config/eww/eww.yuck##hostname.rocinante delete mode 100644 .config/eww/eww.yuck##hostname.tycho rename .config/eww/modules/{network.yuck##hostname.tycho => network.yuck} (100%) delete mode 100644 .config/eww/modules/network.yuck##hostname.normandy delete mode 100644 .config/eww/modules/network.yuck##hostname.rocinante delete mode 100644 .config/eww/modules/network.yuck##hostname.zariman rename .config/eww/scripts/{network.py##hostname.tycho => network.py} (100%) delete mode 100755 .config/eww/scripts/network.py##hostname.normandy delete mode 100755 .config/eww/scripts/network.py##hostname.rocinante delete mode 100755 .config/eww/scripts/network.py##hostname.zariman diff --git a/.config/eww/eww.yuck##hostname.zariman b/.config/eww/eww.yuck similarity index 100% rename from .config/eww/eww.yuck##hostname.zariman rename to .config/eww/eww.yuck diff --git a/.config/eww/eww.yuck##hostname.normandy b/.config/eww/eww.yuck##hostname.normandy deleted file mode 100644 index a1d0aa4..0000000 --- a/.config/eww/eww.yuck##hostname.normandy +++ /dev/null @@ -1,74 +0,0 @@ -;; -*-lisp-*- Include modules -(include "./modules/workspaces.yuck") -(include "./modules/clock.yuck") -(include "./modules/system.yuck") -(include "./modules/network.yuck") -(include "./modules/volume.yuck") -(include "./modules/aggietime.yuck") -(include "./modules/timer.yuck") -(include "./modules/mpris.yuck") - -(include "./windows.yuck") - -(defwindow leftbar - :monitor 2 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" - :class "bar root" - (normandy-leftbar--left) - "" ;;(normandy-leftbar--center) - (normandy-leftbar--right))) - -(defwindow rightbar - :monitor 1 - :geometry (geometry :width "100%" - :height "26px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" - :class "bar root" - (normandy-rightbar--left) - "" ;;(normandy-rightbar--center) - (normandy-rightbar--right))) - -(defwindow centerbar - :monitor 0 - :geometry (geometry :width "100%" - :height "26px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" - :class "bar root" - (normandy-centerbar--left) - (normandy-centerbar--center) - (normandy-centerbar--right))) - -(defwindow sidebar - :monitor 2 - :geometry (geometry :width "210px" - :height "1044px" - :anchor "left bottom") - :exclusive true - :focusable false - :stacking "fg" - (normandy-sidebar)) - -(defwindow sidebar2 - :monitor 1 - :geometry (geometry :width "210px" - :height "1044px" - :anchor "right bottom") - :exclusive true - :focusable false - :stacking "fg" - (normandy-sidebar)) - diff --git a/.config/eww/eww.yuck##hostname.rocinante b/.config/eww/eww.yuck##hostname.rocinante deleted file mode 100644 index 6f4e171..0000000 --- a/.config/eww/eww.yuck##hostname.rocinante +++ /dev/null @@ -1,26 +0,0 @@ -;; -*-lisp-*- Include modules -(include "./modules/workspaces.yuck") -(include "./modules/clock.yuck") -(include "./modules/system.yuck") -(include "./modules/network.yuck") -(include "./modules/volume.yuck") -(include "./modules/aggietime.yuck") -(include "./modules/timer.yuck") -(include "./modules/mpris.yuck") - -(defvar power--state "normal") - -(include "./windows.yuck") - -(defwindow builtinbar - :monitor 0 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" :class "bar root ${power--state == 'critical' ? 'reservepower' : ''}" - (rocinante-builtinbar--left) - (rocinante-builtinbar--center) - (rocinante-builtinbar--right))) diff --git a/.config/eww/eww.yuck##hostname.tycho b/.config/eww/eww.yuck##hostname.tycho deleted file mode 100644 index ede8402..0000000 --- a/.config/eww/eww.yuck##hostname.tycho +++ /dev/null @@ -1,81 +0,0 @@ -;; -*-lisp-*- Include modules -(include "./modules/workspaces.yuck") -(include "./modules/clock.yuck") -(include "./modules/system.yuck") -(include "./modules/network.yuck") -(include "./modules/volume.yuck") -(include "./modules/aggietime.yuck") -(include "./modules/timer.yuck") -(include "./modules/mpris.yuck") - -(include "./windows.yuck") - -(defwindow leftbar - :monitor 1 - :geometry (geometry :width "100%" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" - :class "bar root" - (tycho-leftbar--left) - (tycho-leftbar--center) - (tycho-leftbar--right))) - -(defwindow centerbar - :monitor 0 - :geometry (geometry :width "100%" - :height "26px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" - :class "bar root" - (tycho-centerbar--left) - (tycho-centerbar--center) - (tycho-centerbar--right))) - -(defwindow rightbar - :monitor 2 - :geometry (geometry :width "1440px" - :height "36px" - :anchor "top center") - :exclusive true - :focusable false - :stacking "fg" - (centerbox :orientation "h" - :class "bar root" - (tycho-rightbar--left) - (tycho-rightbar--center) - (tycho-rightbar--right))) - -(defwindow sidebar - :monitor 1 - :geometry (geometry :width "200px" - :height "100%" - :anchor "left center") - :exclusive true - :focusable false - :stacking "fg" - (tycho-sidebar)) - - - -(defwindow network-status - :monitor 0 - :geometry (geometry :width "200px" - :height "0px" - :x "300px" - :y "0px" - :anchor "top right") - :exclusive false - :focusable false - :stacking "overlay" - (box :orientation "v" - :class "bar root bg outline" - :visible {network--show-details} - (network-detail))) - diff --git a/.config/eww/modules/network.yuck##hostname.tycho b/.config/eww/modules/network.yuck similarity index 100% rename from .config/eww/modules/network.yuck##hostname.tycho rename to .config/eww/modules/network.yuck diff --git a/.config/eww/modules/network.yuck##hostname.normandy b/.config/eww/modules/network.yuck##hostname.normandy deleted file mode 100644 index a9d13f1..0000000 --- a/.config/eww/modules/network.yuck##hostname.normandy +++ /dev/null @@ -1,194 +0,0 @@ -(deflisten network--data - `~/.config/eww/scripts/network.py`) - -(defwidget network--wlan [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {network--data["network"][device]["offline"]} - :text "offline") - (label :visible {network--data["network"][device]["connecting"]} - :class "highlight" - :text "connecting...") - (label :visible {network--data["network"][device]["online"]} - :class "special" - :text "${network--data['wifi']['ssid']}"))) - -(defwidget network--lan [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {network--data["network"][device]["offline"]} - :text "offline") - (label :visible {network--data["network"][device]["connecting"]} - :class "highlight" - :text "connecting...") - (label :visible {network--data["network"][device]["online"] && !network--data.network[device].connecting} - :class "special" - :text "${network--data['network'][device]['ip4_addr']}/${network--data['network'][device]['ip4_prefix']}"))) - -(defwidget network--proxy-vpn [device ?required] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - :visible {network--data["network"][device]["exists"] || required} - (label :class "highlight" - :text "- insecure" - :visible {! network--data["network"][device]["exists"]}) - (label :class "green" - :text "- secured" - :visible {network--data["network"][device]["exists"]}))) - -(defwidget proxy-network [device] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "green" - :text "connected" - :visible {network--data.network[device].exists}) - (label :class "offline" - :text "offline" - :visible {!network--data.network[device].exists}) - "proxy vpn")) - -(defwidget vpn-network [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "highlight" - :text "offline" - :visible {! network--data["network"]["ezrinet"]["exists"] || ! network--data["connected"]}) - (label :class "green" - :text "connected" - :visible {network--data["network"]["ezrinet"]["exists"] && network--data["connected"]}) - "personal network")) - -(defwidget network [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 10 - (network--lan :device "insight") - (network--proxy-vpn :device "wg-mullvad" :required {!network--data.trusted})) - "communications")) - -(defwidget network-sidebar-details [] - (box :orientation "v" - :halign "start" - :class "module" - :space-evenly false - :spacing 5 - :width 200 - (box :orientation "h" - :halign "center" - :class "nebula" - :spacing 10 - :space-evenly false - (label :text "Comms" - :class "medium special")) - (centerbox :orientation "h" - :halign "start" - :class "nebula" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - "Status:") - "" - (box :halign "end" - (label :text "Online" - :class "green" - :visible {network--data.connected}) - (label :text "Offline" - :class "highlight" - :visible {!network--data.connected}))) - (centerbox :orientation "h" - :halign "start" - :class "nebula" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - "VPN:") - "" - (box :halign "end" - (label :text "Connected" - :class "green" - :visible {network--data.network.ezrinet.online && network--data.connected}) - (label :text "Offline" - :class "highlight" - :visible {!network--data.network.ezrinet.exists}))) - (centerbox :orientation "h" - :halign "start" - :class "nebula" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - "Proxy:") - "" - (box :halign "end" - (label :text "Connected" - :class "green" - :visible {network--data.network.wg-mullvad.online}) - (label :text "Offline" - :class "highlight" - :visible {!network--data.network.wg-mullvad.exists}))) - (centerbox :orientation "h" - :halign "start" - :class "nebula" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - "Wi-Fi:") - "" - (box :halign "end" - (label :text {network--data.wifi.ssid} - :limit-width 12 - :class "green" - :visible {network--data.wifi.connected}) - (label :text "Offline" - :class "offline" - :visible {!network--data.wifi.connected}))) - (centerbox :orientation "h" - :halign "start" - :spacing 10 - :width 200 - :class "nebula" - :space-evenly false - (box :valign "start" - :halign "start" - "Addrs:") - "" - (box :valign "start" - :halign "end" - :visible {network--data.connected} - :orientation "v" - (for addr in {network--data.ip4_addrs} - (box :class "special" - :halign "end" - {addr})) - (box :visible {!network--data.connected} - :class "offline" - "none"))) - ;; (box :orientation "h" - ;; :halign "start" - ;; :class "nebula" - ;; :spacing 10 - ;; :space-evenly false - ;; (label :text "Addr:") - ;; (label :text {network--data.network[device].ip4_addr} - ;; :class "medium special")))) - )) diff --git a/.config/eww/modules/network.yuck##hostname.rocinante b/.config/eww/modules/network.yuck##hostname.rocinante deleted file mode 100644 index dca9b60..0000000 --- a/.config/eww/modules/network.yuck##hostname.rocinante +++ /dev/null @@ -1,77 +0,0 @@ -;; -*-lisp-*- -(deflisten network--data - `~/.config/eww/scripts/network.py`) - -(defwidget network--wlan [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 10 - (label :class "offline" - :visible {network--data["network"][device]["offline"]} - :text "offline") - (label :visible {network--data["network"][device]["connecting"]} - :class "highlight" - :text "connecting...") - (label :visible {network--data["network"][device]["online"] && !network--data.network[device].connecting} - :class "special" - :text "${network--data['wifi']['ssid']}") - (label :visible {!network--data.connection.internet && network--data.network[device].online} - :class "highlight" - :text "- no internet" - ))) - -(defwidget network--lan [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {network--data["network"][device]["offline"]} - :text "offline") - (label :visible {network--data["network"][device]["connecting"]} - :class "highlight" - :text "connecting...") - (label :visible {network--data["network"][device]["online"] && !network--data.network[device].connecting} - :class "special" - :text "${network--data['network'][device]['ip4_addr']}/${network--data['network'][device]['ip4_prefix']}"))) - -(defwidget network--proxy-vpn [device ?required] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - :visible {network--data.connection.internet && (network--data["network"][device]["exists"] || required)} - (label :class "highlight" - :text "- insecure" - :visible {! network--data["network"][device]["exists"]}) - (label :class "green" - :text "- secured" - :visible {network--data["network"][device]["exists"]}))) - -(defwidget vpn-network [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "highlight" - :text "offline" - :visible {!network--data.connection.ezrinet}) - (label :class "green" - :text "connected" - :visible {network--data.connection.ezrinet}) - "personal network")) - -(defwidget network [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 10 - (network--wlan :device "wlan0") - (network--proxy-vpn :device "wg-mullvad" :required {!network--data.trusted})) - "communications")) - diff --git a/.config/eww/modules/network.yuck##hostname.zariman b/.config/eww/modules/network.yuck##hostname.zariman deleted file mode 100644 index a92f2cd..0000000 --- a/.config/eww/modules/network.yuck##hostname.zariman +++ /dev/null @@ -1,347 +0,0 @@ -;; -*-lisp-*- -(deflisten network--data - `~/.config/eww/scripts/network.py`) - -(defvar network--show-details false) - -(defwidget network--interface - [device] - (box :orientation "v" - :halign "center" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {!device.online} - :text "offline") - (label :visible {device.online} - :class "special" - :text "${device.addresses[0].address}/${device.addresses[0].prefixlen}"))) - -(defwidget network-big--online - [] - (box :orientation "h" - :halign "start" - :valign "center" - :space-evenly false - :spacing 10 - (label :class "medium green nebula" - :visible {network--data.online} - :text "online") - (label :class "medium offline nebula" - :visible {network--data.offline} - :text "offline") - (label :class "medium highlight nebula" - :visible {network--data.configuring} - :text "configuring"))) - -(defwidget network-big--lan - [device] - (label :visible {network--data - [device] - .online} - :class "" - :text "${network--data.interfaces[device].addresses[0].address}/${network--data.interfaces[device].addresses[0].prefixlen}")) - -(defwidget network--wlan - [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {network--data - ["network"] - [device] - ["offline"] - } - :text "offline") - (label :visible {network--data - ["network"] - [device] - ["connecting"] - } - :class "highlight" - :text "connecting...") - (label :visible {network--data - ["network"] - [device] - ["online"] - } - :class "special" - :text "${network--data['wifi']['ssid']}"))) - -(defwidget network--lan - [device] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "offline" - :visible {!device.online} - :text "offline") - (label :visible {device.online} - :class {network--data.last_update.unix < clock--data.unix - 30 ? "highlight" : "special"} - :text "${device.addresses[0].address}/${device.addresses[0].prefixlen}"))) - -(defwidget network--secure - [] - (box :orientation "h" - :halign "start" - :space-evenly false - :spacing 0 - (label :class "highlight" - :text "- insecure" - :visible {! - network--data.secure }) - (label :class "green" - :text "- secured via ${network--data.secure_msg}" - :visible {network--data.secure}))) - -(defwidget vpn-network - [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - :visible {network--data - != - ''} - (label :class "highlight" - :text "offline" - :visible {! - network--data.interfaces.ezrinet.online }) - (label :class "green" - :text "connected" - :visible {network--data.interfaces.ezrinet.online}) - "personal network")) - -(defwidget network - [] - (button :onclick "eww update network--show-details=${!network--show-details}" - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - :visible {network--data != ''} - (box :orientation "h" - :halign "center" - :space-evenly false - :spacing 10 - (network--lan :device {network--data.default_interface})) - "communications"))) - -(defwidget network--public-ip - [] - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "public ip:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class "highlight" - :text "offline" - :visible {!network--data.online}) - (label :class "highlight" - :text "no response" - :visible {network--data.online && !network--data.have_public_ip}) - (label :class "special" - :text {network--data.public_ip.ip} - :visible {network--data.online && network--data.have_public_ip})))) - -(defwidget network--default-route - [] - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "route on:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class "highlight" - :text "offline" - :visible {!network--data.online}) - (label :class "highlight" - :text "no route" - :visible {network--data.online && !network--data.have_default_route}) - (label :class "special" - :text {network--data.default_route} - :visible {network--data.online && network--data.have_default_route})))) - -(defwidget network--gateway - [] - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "gateway:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class "highlight" - :text "no response" - :visible {!network--data.have_gateway}) - (label :class "special" - :text {network--data.gateway} - :visible {network--data.have_gateway})))) - -(defwidget network--status-summary - [] - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "status:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class "highlight" - :text "offline" - :visible {!network--data.online}) - (label :class "special" - :text "online" - :visible {network--data.online && !network--data.secure}) - (label :class "green" - :text {network--data.secure_msg == "usu" ? "vpn online" : "secure"} - :visible {network--data.online && network--data.secure})))) - - -(defwidget network-detail - [] - (box :orientation "v" - :halign "start" - :space-evenly false - :spacing 0 - (network--status-summary) - (network--public-ip) - (network--default-route) - (network--gateway) - (centerbox :orientation "h" - :halign "start" - :width 200 - (box :halign "start" - "last update:") - "" - (box :halign "end" - :spacing 0 - :space-evenly false - (label :class {network--data.last_update.unix < clock--data.unix - 30 ? "highlight" : "special"} - :text "${network--data.last_update.month}-${network--data.last_update.day} ${network--data.last_update.hour}:${network--data.last_update.minute}:${network--data.last_update.second}"))) - )) - -(defwidget network-sidebar-details [] - (box :orientation "v" - :halign "start" - :class "module" - :space-evenly false - :spacing 5 - :width 200 - (box :orientation "h" - :halign "center" - :class "nebula" - :spacing 10 - :space-evenly false - (label :class "medium special" - :text "Comms")) - (box :orientation "h" - :halign "center" - :class "nebula" - :spacing 10 - :space-evenly false - (label :class "nebula green" - :text "Online" - :visible {network--data.online}) - (label :class "nebula highlight" - :text "Offline" - :visible {!network--data.online})) - (centerbox :orientation "h" - :halign "start" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - :class "nebula" - "Route On:") - "" - (box :halign "end" - (label :text "No Route" - :class "highlight" - :visible {network--data.online && !network--data.have_default_route}) - (label :text "${network--data.default_route}" - :class "special" - :visible {network--data.online && network--data.have_default_route}))) - (centerbox :orientation "h" - :halign "start" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - :valign "start" - :class "nebula" - "Address:") - "" - (box :halign "end" - :orientation "v" - (label :text "${network--data.default_interface.addresses[0].address}" - :class "special") - (label :text "/${network--data.default_interface.addresses[0].prefixlen}" - :halign "end" - :class "special"))) - (centerbox :orientation "h" - :halign "start" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - :class "nebula" - "Public IP:") - "" - (box :halign "end" - (label :text "Offline" - :class "highlight" - :visible {!network--data.have_public_ip}) - (label :text {network--data.public_ip.ip} - :class "special" - :visible {network--data.have_public_ip}))) - (centerbox :orientation "h" - :halign "start" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - :class "nebula" - "Gateway:") - "" - (box :halign "end" - (label :text "Error" - :class "highlight nebula" - :visible {!network--data.have_gateway}) - (label :text {network--data.gateway} - :class "special" - :visible {network--data.have_gateway}))) - (centerbox :orientation "h" - :halign "start" - :class "nebula" - :spacing 10 - :width 200 - :space-evenly false - (box :halign "start" - "VPN:") - "" - (box :halign "end" - (label :text "Offline" - :class "highlight" - :visible {!network--data.interfaces.ezrinet.online}) - (label :text "Online" - :class "green" - :visible {network--data.interfaces.ezrinet.online}))) - - )) - - diff --git a/.config/eww/scripts/network.py##hostname.tycho b/.config/eww/scripts/network.py similarity index 100% rename from .config/eww/scripts/network.py##hostname.tycho rename to .config/eww/scripts/network.py diff --git a/.config/eww/scripts/network.py##hostname.normandy b/.config/eww/scripts/network.py##hostname.normandy deleted file mode 100755 index 4b71007..0000000 --- a/.config/eww/scripts/network.py##hostname.normandy +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 - -import subprocess -import json -import sys -from time import sleep - -TRUSTED_NETWORKS = ['honnouji', 'honnouji_2.4'] - -def wifi(): - ssid_cmd = subprocess.run(['iwgetid', '-r'], capture_output = True) - if ssid_cmd.returncode != 0: - return {"connected": False, "ssid": None} - return {"connected": True, "ssid": ssid_cmd.stdout.decode('utf-8').strip()} - -def netdev(device: str): - ip_cmd = subprocess.run(['ip', '-j', 'addr', 'show', device], capture_output = True) - if ip_cmd.returncode != 0: - sys.stderr.write(ip_cmd.stdout.decode('utf-8')) - return {"exists": False, "online": False} - ip_data = json.loads(ip_cmd.stdout.decode('utf-8'))[0] - ip4_addr = "" - ip4_prefix_length = 24 - addr4_info = list(filter(lambda addr: addr.get("family") == "inet", ip_data["addr_info"])) - if len(addr4_info) >= 1: - ip4_addr = addr4_info[0]["local"] - ip4_prefix_length = addr4_info[0]["prefixlen"] - online = ip_data["operstate"] == "UP" or ip4_addr != "" - connecting = ip_data["operstate"] != "DOWN" and (ip4_addr == "" or not online) - return { - "exists": True, - "online": online, - "connecting": connecting, - "offline": not online and not connecting, - "ip4_addr": ip4_addr, - "ip4_prefix": ip4_prefix_length - } - -def trusted(ssid: str | None): - # Don't throw up an "INSECURE" alert when offline - if not ssid: - return True - return ssid in TRUSTED_NETWORKS - -while True: - insight = netdev('insight') - wlan0 = netdev('wlan0') - wifi_data = wifi() - connected = insight['exists'] and insight['online'] or wifi_data['connected'] - networks = { - "insight": insight, - "wlan0": netdev("wlan0"), - "ezrinet": netdev("ezrinet"), - "wg-mullvad": netdev("wg-mullvad"), - } - result = { - 'connected': connected, - "network": networks, - 'wifi': wifi_data, - "trusted": True, - "ip4_addrs": [ network.get('ip4_addr') for network in networks.values() if network.get('ip4_addr', "") != "" ] - } - print(json.dumps(result), flush=True) - sleep(1) diff --git a/.config/eww/scripts/network.py##hostname.rocinante b/.config/eww/scripts/network.py##hostname.rocinante deleted file mode 100755 index 742aa39..0000000 --- a/.config/eww/scripts/network.py##hostname.rocinante +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 - -import subprocess -import json -from time import sleep - -TRUSTED_NETWORKS = ['gayer people'] - -def wifi(): - ssid_cmd = subprocess.run(['iwgetid', '-r'], capture_output = True) - if ssid_cmd.returncode != 0: - return {"connected": False, "ssid": None} - ssid = ssid_cmd.stdout.decode('utf-8').strip() - ssid = ssid if len(ssid) <= 15 else f"{ssid[:14]}…" - return {"connected": True, "ssid": ssid} - -def netdev(device: str): - ip_cmd = subprocess.run(['ip', '-j', 'addr', 'show', device], capture_output = True) - if ip_cmd.returncode != 0: - return {"exists": False} - ip_data = json.loads(ip_cmd.stdout.decode('utf-8'))[0] - online = ip_data["operstate"] == "UP" - ip4_addr = "" - ip4_prefix_length = 24 - addr4_info = list(filter(lambda addr: addr.get("family") == "inet", ip_data["addr_info"])) - if len(addr4_info) >= 1: - ip4_addr = addr4_info[0]["local"] - ip4_prefix_length = addr4_info[0]["prefixlen"] - connecting = ip_data["operstate"] != "DOWN" and (ip4_addr == "" or not online) - return { - "exists": True, - "online": online, - "connecting": connecting, - "offline": not online and not connecting, - "ip4_addr": ip4_addr, - "ip4_prefix": ip4_prefix_length - } - -def trusted(ssid: str | None): - # Don't throw up an "INSECURE" alert when offline - if not ssid: - return True - return ssid in TRUSTED_NETWORKS - -def ping(host: str): - ping_cmd = subprocess.Popen(['/usr/bin/ping', '-c1', '-W2', host], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - return ping_cmd - -counter = 0 -ezrinet_last = False -internet_last = False -ezrinet_ping = None -internet_ping = None - -while True: - if counter == 0: - ezrinet_ping = ping('10.242.3.1') - internet_ping = ping('1.1.1.1') - if ezrinet_ping.poll() is not None: - ezrinet_last = ezrinet_ping.returncode == 0 - if internet_ping.poll() is not None: - internet_last = internet_ping.returncode == 0 - wifi_data = wifi() - result = { - "wifi": wifi_data, - "network": { - "wlan0": netdev("wlan0"), - "ezrinet": netdev("ezrinet"), - "wg-mullvad": netdev("mullvad"), - }, - "connection": { - "ezrinet": ezrinet_last, - "internet": internet_last - }, - "trusted": trusted(wifi_data.get("ssid", None)) - } - print(json.dumps(result), flush=True) - counter += 1 - # Send pings every 10 seconds - counter %= 3 - sleep(1) diff --git a/.config/eww/scripts/network.py##hostname.zariman b/.config/eww/scripts/network.py##hostname.zariman deleted file mode 100755 index 99db78e..0000000 --- a/.config/eww/scripts/network.py##hostname.zariman +++ /dev/null @@ -1,306 +0,0 @@ -#!/usr/bin/env python3 - -import trparse -from subprocess import run, PIPE, DEVNULL -import json -import sys -import os -import re -from time import sleep, time as now -from ipaddress import ( - IPv4Address as IPAddress, - IPv4Network as IPNetwork, - IPv4Interface as IPInterface, - AddressValueError, -) -from netifaces import interfaces, ifaddresses, AF_INET, AF_LINK, gateways -import dbus -from datetime import datetime - - -# These are networks that are considered secure. All traffic being routed -# through one of these networks is being encrypted and routed through an -# anonymizing service. -SECURE_FIRSTHOP_NETWORKS = { - "home": IPNetwork("10.242.0.0/16"), # Personal network - "mullvad": IPNetwork("10.64.0.1/32"), # Mullvad VPN - "usu": IPNetwork("129.123.8.126/32"), # USU VPN -} - -# Interfaces that we should check -DEFAULT_INTERFACES_TO_WATCH = ["lan", "ezrinet"] -# Interfaces that we should use when determining if we are online -DEFAULT_INTERFACES_TO_COUNT = ["lan"] -# Overrides for IP addresses to ping to determine if an interface is -# online This is useful for interfaces that don't have or report a -# gateway, but we still want to check if they're online, such as the -# ezrinet interface. -INTERFACE_PING_OVERRIDES = {"ezrinet": IPAddress("10.242.3.1")} - -INTERFACES_TO_WATCH = os.environ.get( - "NETWORK_INTERFACES_TO_WATCH", ",".join(DEFAULT_INTERFACES_TO_WATCH) -).split(",") -INTERFACES_TO_COUNT = os.environ.get( - "NETWORK_INTERFACES_TO_COUNT", ",".join(DEFAULT_INTERFACES_TO_COUNT) -).split(",") - -for key, value in os.environ.items(): - if key[: len("NETWORK_PING_OVERRIDE_")] == "NETWORK_PING_OVERRIDE_": - INTERFACE_PING_OVERRIDES[key[len("NETWORK_PING_OVERRIDE_") :]] = IPAddress( - value - ) - - -class Interface: - name: str - mac: str - addresses: list[IPInterface] - gateway: IPAddress | None - - @property - def online(self): - # If we have no addresses, we're not online - if len(self.addresses) == 0: - return False - # If we have an override, ping that - if self.name in INTERFACE_PING_OVERRIDES: - return ping(INTERFACE_PING_OVERRIDES[self.name]) - # If we have no gateway, this interface is likely not intended - # to route beyond the local network, so we'll assume it's - # online, at least for whatever it's used for. - if self.gateway is None: - return True - return ping(self.gateway) - - def asdict(self): - return { - "name": self.name, - "mac": self.mac, - "addresses": [ - { - "address": str(addr.ip), - "netmask": str(addr.netmask), - "network": str(addr.network), - "prefixlen": addr._prefixlen, - } - for addr in self.addresses - ], - "online": self.online, - } - - -def get_first_hop() -> IPAddress | None: - """Get the first network hop.""" - # Use ping to get the first hop - cmd = ["/usr/bin/ping", "-c1", "-W0.3", "-t1", "1.1.1.1"] - result = run(cmd, stdout=PIPE, stderr=PIPE) - try: - ip = IPAddress(result.stdout.decode("utf-8").split("\n")[1].split()[1]) - except (IndexError, AddressValueError): - # If we can't parse the output, return None - return None - return ip - - -def validate_first_hop_is_secure(first_hop: IPAddress): - """Check if the first hop is in a secure network.""" - for name, network in SECURE_FIRSTHOP_NETWORKS.items(): - if first_hop in network: - return name - - -def get_gateways(): - """Get gateways on each interface.""" - gw = gateways().get(AF_INET, []) - result = {} - for iface in INTERFACES_TO_WATCH: - for gateway in gw: - if gateway[1] == iface: - result[iface] = gateway[0] - - return result - - -def interface_status(interface: str, gw): - """Get the status of an interface.""" - try: - addrs = ifaddresses(interface) - except: - addrs = {} - result = Interface() - result.name = interface - result.gateway = gw.get(interface, None) - if AF_LINK in addrs: - result.mac = addrs[AF_LINK][0]["addr"] - else: - result.mac = None - if AF_INET in addrs: - result.addresses = [ - IPInterface(f'{addr["addr"]}/{addr["netmask"]}') - for addr in addrs.get(AF_INET, []) - ] - else: - result.addresses = [] - return result - - -def ping(host: IPAddress) -> bool: - cmd = ["/usr/bin/ping", "-c1", "-w1", str(host)] - result = run(cmd, stdout=DEVNULL, stderr=DEVNULL) - return result.returncode == 0 - - -def get_public_ip(): - """Get the public IP address.""" - cmd = ["/usr/bin/curl", "-s", "https://ipinfo.io"] - result = run(cmd, stdout=PIPE, stderr=PIPE) - try: - data = json.loads(result.stdout.decode("utf-8")) - except (IndexError, ValueError): - return None - try: - # If the IP address is invalid, don't return anything - IPAddress(data["ip"]) - except (AddressValueError, KeyError): - if data.get("status", None) == 429: - # We're rate limited, so return something indicating that - return {"rate_limited": True} - return None - return data - - -def get_default_route(): - """Get the default route.""" - cmd = ["/usr/bin/ip", "route", "show", "default"] - result = run(cmd, stdout=PIPE, stderr=PIPE) - try: - # Get first line (might have multiple gateway routes) - line = result.stdout.decode("utf-8").split("\n")[0] - # Get the gateway link (following "dev") - link = re.search(r"dev\s+(\S+)", line).group(1) - # We already know the gateway IP based on our firsthop check earlier, and that's more reliable since it will respect any routing rules - except (IndexError, AttributeError): - return None - return link - - -def format_time(time: datetime) -> dict[str, str | int]: - """Format a datetime object for display.""" - return { - "hour": f"{time.hour:02}", - "minute": f"{time.minute:02}", - "second": f"{time.second:02}", - "year": f"{time.year:04}", - "month": f"{time.month:02}", - "day": f"{time.day:02}", - "unix": int(time.timestamp()), - } - - -# system_bus = dbus.SystemBus() -# networkd = system_bus.get_object( -# "org.freedesktop.network1", "/org/freedesktop/network1" -# ) -# manager = dbus.Interface(networkd, "org.freedesktop.network1.Manager") - - -# def get_dbus_interfaces(): -# for iface in INTERFACES_TO_WATCH: -# dbus_object = system_bus.get_object( -# "org.freedesktop.network1", manager.GetLinkByName(iface) -# ) -# dbus_interface = dbus.Interface(dbus_object, "org.freedesktop.network1.Link") -# yield dbus_interface - -runtime_dir = os.environ.get("XDG_RUNTIME_DIR", "/tmp") - - -def load_last_data(var_name: str): - try: - if os.path.exists(f"{runtime_dir}/{var_name}.json"): - with open(f"{runtime_dir}/{var_name}.json", "r") as f: - return json.load(f), os.path.getmtime(f"{runtime_dir}/{var_name}.json") - - except: - pass - return None, None - - -def store_last_data(var_name: str, data): - with open(f"{runtime_dir}/{var_name}.json", "w") as f: - json.dump(data, f) - - -last_default_route = load_last_data("default_route")[0] -last_ip_data, last_request = load_last_data("ip_data") -try: - last_first_hop = IPAddress(load_last_data("first_hop")[0]) -except: - last_first_hop = None - -while True: - try: - online = ping("1.1.1.1") - except: - online = False - hop = get_first_hop() - gw = get_gateways() - default_route = get_default_route() - # public IP shouldn't change often, so only check every 2 hours or - # if the default route or first hop changes - if ( - default_route != last_default_route - or last_ip_data is None - or last_request is None - or now() - last_request > (2 * 60 * 60) - or (hop != last_first_hop and hop is not None) - ): - print("refreshing public IP", file=sys.stderr, flush=True) - public_ip_data = get_public_ip() - if public_ip_data is None: - print("failed to get public IP", file=sys.stderr, flush=True) - elif public_ip_data.get("rate_limited", False): - last_ip_data = public_ip_data - public_ip_data = None - else: - last_ip_data = public_ip_data - # Write the public IP data to a file - store_last_data("ip_data", public_ip_data) - last_default_route = default_route - store_last_data("default_route", default_route) - last_request = now() - last_first_hop = hop - store_last_data("first_hop", str(hop)) - else: - public_ip_data = last_ip_data - if hop is not None: - secure_msg = validate_first_hop_is_secure(hop) - secure = secure_msg is not None - else: - # If we can't reach the router, assume insecure - secure = False - iface_data = [interface_status(iface, gw) for iface in INTERFACES_TO_WATCH] - iface_dict = {iface.name: iface.asdict() for iface in iface_data} - - default_route_iface_data = interface_status(default_route, gw) - - print( - json.dumps( - { - "online": online, - "secure": secure, - "interfaces": iface_dict, - "public_ip": public_ip_data or {}, - "have_public_ip": public_ip_data is not None and "ip" in public_ip_data, - "default_route": default_route, - "default_interface": default_route_iface_data.asdict(), - "have_default_route": default_route is not None, - "gateway": str(hop), - "have_gateway": hop is not None, - "last_update": format_time(datetime.now()), - } - ), - flush=True, - ) - - sleep(5)