commit 7f42c04977a61e79d2ac7e2a9a2540477a822309 Author: Aaro Saila Date: Sat Jan 31 15:37:26 2026 +0200 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..631c516 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +auth +.venv* diff --git a/auth.template b/auth.template new file mode 100644 index 0000000..a761309 --- /dev/null +++ b/auth.template @@ -0,0 +1,2 @@ +EMAIL= +PASSWORD= diff --git a/dyfi.py b/dyfi.py new file mode 100644 index 0000000..b626f47 --- /dev/null +++ b/dyfi.py @@ -0,0 +1,68 @@ +import argparse +import logging +from time import sleep + +import requests as r + + +logger = logging.getLogger(__name__) + +arg_parser = argparse.ArgumentParser() +arg_parser.add_argument("-a", "--auth", default="", help="Path to auth file.") +arg_parser.add_argument("-l", "--log", default="", help="Log to file instead of stdout") +args = arg_parser.parse_args() + +MINUTE_SEC: int = 60 +HOUR_SEC: int = MINUTE_SEC * 60 +DAY_SEC: int = HOUR_SEC * 24 +SLEEP_TIME_SEC: int = DAY_SEC * 5 + HOUR_SEC * 3 + MINUTE_SEC * 14 + + +def dyfi_update(email: str, password: str, hostnames: str) -> None: + res: r.Response = r.get("https://www.dy.fi/nic/update", params={"hostname": hostnames}, auth=(email, password)) + if res.status_code != 200: + logger.error("dy.fi responded with code {res.status_code}. Response content:\n{res.text}\n") + else: + logger.info(f"dy.fi responded with 200. Response content: \n{res.text}\n") + + +def parse_auth() -> tuple[str, str, str]: + with open(args.auth, "r") as f: + lines: list[str] = f.readlines() + email_start: int = lines[0].find("EMAIL=") + if email_start == -1: + logger.error("Invalid auth file. Email not found. Must be in the format:\nEMAIL=\nPASSWORD=\nHOSTNAMES=") + + email_start += len("EMAIL=") + email = lines[0][email_start:-1] + + password_start: int = lines[1].find("PASSWORD=") + if password_start == -1: + logger.error("Invalid auth file. Password not found. Must be in the format:\nEMAIL=\nPASSWORD=\nHOSTNAMES=") + + password_start += len("PASSWORD=") + password = lines[1][password_start:-1] + + hostnames_start: int = lines[2].find("HOSTNAMES=") + if hostnames_start == -1: + logger.error("Invalid auth file. Hostnames not found. Must be in the format:\nEMAIL=\nPASSWORD=\nHOSTNAMES=") + + hostnames_start += len("HOSTNAMES=") + hostnames = lines[2][hostnames_start:-1] + + return (email, password, hostnames) + + +if __name__ == "__main__": + logging.basicConfig(filename=args.log, level=logging.INFO, format="(%(asctime)s) %(levelname)s: %(message)s") + + if args.auth == "": + logger.error("Must provide a path to an auth file.") + exit(1) + + email, password, hostnames = parse_auth() + + while True: + dyfi_update(email, password, hostnames) + logger.info(f"Sleeping for {SLEEP_TIME_SEC} seconds") + sleep(SLEEP_TIME_SEC) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..58bb7e7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +certifi==2026.1.4 +charset-normalizer==3.4.4 +idna==3.11 +requests==2.32.5 +urllib3==2.6.3