depot/ops/nixos/swann/ee-scrape-data.py

97 lines
2.6 KiB
Python

import re
import sys
import textwrap
import bs4
import requests
BYTE_SUFFIXES = {
"": 1,
"B": 1,
"kB": 1024,
"MB": 1024 * 1024,
"GB": 1024 * 1024 * 1024,
"TB": 1024 * 1024 * 1024 * 1024,
}
TIME_SUFFIXES = {
"Days": 60 * 60 * 24,
"Day": 60 * 60 * 24,
"Hrs": 60 * 60,
"Hr": 60 * 60,
"Mins": 60,
"Min": 60,
}
def uniec(n):
m = re.match(r"^([0-9]+(?:[.][0-9]+)?)([a-zA-Z]*)$", n)
if not m:
raise ValueError(f"invalid suffixed-bytes {n}")
val, suffix = m.groups()
val = float(val)
if suffix not in BYTE_SUFFIXES:
raise ValueError(f"unknown suffix {suffix} from {n}")
return val * BYTE_SUFFIXES[suffix]
def untime(n):
remaining = n
x = 0
while remaining and (m := re.match(r"^([0-9]+) ([a-zA-Z]+)(?: (.*)|$)", remaining)):
val, suffix, remaining = m.groups()
val = float(val)
if suffix not in TIME_SUFFIXES:
raise ValueError(f"unknown suffix {suffix} from {n}")
x += val * TIME_SUFFIXES[suffix]
return x
def scrape_data():
resp = requests.get("http://10.42.0.1/mbbstatus")
resp.raise_for_status()
soup = bs4.BeautifulSoup(resp.text, "html5lib")
data = {}
account_number_el = soup.select("p.account__details > span")[1]
data["account_number"] = account_number_el.get_text().strip().replace(" ", "")
allowance_left_el = soup.select("span.allowance__left")[0]
allowance_left_str, allowance_total_str = list(allowance_left_el.stripped_strings)
data["allowance_left"] = uniec(allowance_left_str)
if allowance_total_str.startswith("left of "):
allowance_total_str = allowance_total_str[len("left of ") :]
data["allowance_total"] = uniec(allowance_total_str)
timespan_str = " ".join(soup.select(".allowance__timespan")[0].stripped_strings)
if timespan_str.startswith("Lasts for "):
timespan_str = timespan_str[len("Lasts for ") :]
data["time_remaining"] = untime(timespan_str)
return textwrap.dedent(
f"""
ee_allowance_left{{account_number="{data['account_number']}"}} {data['allowance_left']}
ee_allowance_total{{account_number="{data['account_number']}"}} {data['allowance_total']}
ee_time_remaining{{account_number="{data['account_number']}"}} {data['time_remaining']}
"""
).strip()
def main(args):
if len(args) > 2:
print(f"{args[0]} (output path)", file=sys.stderr)
sys.exit(1)
data = scrape_data()
if len(args) == 1:
print(data)
else:
with open(args[1], "w") as f:
print(data, file=f)
if __name__ == "__main__":
main(sys.argv)