dotfiles/os/wireless/apply.py

59 lines
1.7 KiB
Python

"""
Add the networks saved in wireless_networks to wpa_supplicant,
without restarting it or touching its config file.
"""
import json
import os
import re
import subprocess
NETWORKS_FILE = "/etc/keys/wireless_networks.json"
def wpa_cli(command: list[str]) -> list[bytes]:
command.insert(0, "wpa_cli")
process = subprocess.run(command, stdout=subprocess.PIPE)
process.check_returncode()
lines = process.stdout.splitlines()
while lines[0].startswith(b"Selected interface"):
lines.pop(0)
return lines
network_numbers: dict[str, int] = dict()
networks_tsv = wpa_cli(["list_networks"])
networks_tsv.pop(0)
for network_line in networks_tsv:
split = network_line.split(b"\t")
number = int(split[0])
ssid_bytes = split[1]
ssid = re.sub(
rb"\\x([0-9a-f]{2})",
lambda d: int(d[1], base=16).to_bytes(),
ssid_bytes,
).decode()
network_numbers[ssid] = number
if os.path.isfile(NETWORKS_FILE):
with open(NETWORKS_FILE) as fd:
networks = json.load(fd)
for network in networks:
ssid = network["ssid"]
if ssid in network_numbers:
number = network_numbers[ssid]
else:
number = int(wpa_cli(["add_network"])[0])
number_str = str(number)
for key, value in network.items():
if isinstance(value, str):
value_str = f'"{value}"'
elif isinstance(value, list):
value_str = " ".join(value)
else:
value_str = str(value)
ret = wpa_cli(["set_network", number_str, key, value_str])
if ret[0] != b"OK":
raise RuntimeError(f"Couldn't set {key} for {ssid}, got {ret}")