diff --git a/projects/gh-unnotifier/src/python/ghunnotif/__main__.py b/projects/gh-unnotifier/src/python/ghunnotif/__main__.py index b4624ec..2cc1e2a 100644 --- a/projects/gh-unnotifier/src/python/ghunnotif/__main__.py +++ b/projects/gh-unnotifier/src/python/ghunnotif/__main__.py @@ -6,7 +6,7 @@ import tomllib from typing import Optional from datetime import datetime, timedelta, timezone from time import sleep -from pprint import pformat +from pprint import pprint import click import requests @@ -149,8 +149,6 @@ def parse_seconds(text: str) -> timedelta: "--config", "config_path", type=Path, - default=lambda: Path(os.getenv("BUILD_WORKSPACE_DIRECTORY", "")) - / "projects/gh-unnotifier/config.toml", ) @click.option("--schedule", "schedule", default="30 seconds", type=parse_seconds) def maintain(config_path: Path, schedule: timedelta): @@ -160,72 +158,107 @@ def maintain(config_path: Path, schedule: timedelta): client = Client(config["gh-unnotifier"]["api_key"]) org_shitlist = config["gh-unnotifier"].get("org_shitlist", []) team_shitlist = config["gh-unnotifier"].get("team_shitlist", []) + author_shitlist = config["gh-unnotifier"].get("author_shitlist", []) user = client.get_user() user_teams = {it["slug"] for it in client.get_user_teams()} - mark = None + mark = savepoint = prev = None def _resolve(notif, reason): client.read(notif) client.unsubscribe(notif) click.echo(f"Resolved {notif['id']} {reason} ({notif['subject']})") + def _pr(subject, notif): + pr = client.get_pr(url=subject["url"]) + + if pr.get("merged", False): + _resolve(notif, "Merged") + return + + if pr.get("state") == "closed": + _resolve(notif, "Closed") + return + + if pr["user"]["login"] in author_shitlist: + _resolve(notif, "Ignoring PR by author") + return + + if notif["reason"] == "review_requested": + reviewers = client.get_pr_reviewers(pr) + if ( + any(org in subject["url"] for org in org_shitlist) + and not any( + it["login"] == user["login"] + for it in reviewers.get("users", []) + ) + and not any( + it["slug"] in user_teams + and it["slug"] not in team_shitlist + for it in reviewers.get("teams", []) + ) + ): + _resolve(notif, "Reviewed") + return + + print("Oustanding PR notification") + pprint({"subject": subject, "notif": notif, "pr": pr}) + + def _mention(subject, notif): + pr = client.get_pr(url=subject["url"]) + + reviewers = client.get_pr_reviewers(pr) + if ( + any(org in subject["url"] for org in org_shitlist) + and not any( + it["login"] == user["login"] + for it in reviewers.get("users", []) + ) + and not any( + it["slug"] in user_teams + and it["slug"] not in team_shitlist + for it in reviewers.get("teams", []) + ) + ): + _resolve(notif, "Ignoring team mention") + return + + def _issue(subject, notif): + issue = client.get_issue(url=subject["url"]) + + if issue["state"] == "closed": + comments = client.get_comments(url=issue["comments_url"]) + if not any( + it["user"]["login"] == user["login"] for it in comments + ): + _resolve(notif, "Unengaged issue closed") + + if issue["user"]["login"] in author_shitlist: + _resolve(notif, "Ignoring issue by author") + while True: try: + savepoint = prev prev = mark mark = datetime.now(timezone.utc) tick = mark + schedule assert tick - schedule == mark for notif in client.get_all_notifications(since=prev): + notif_timestamp = datetime.fromisoformat(notif["updated_at"]) + if (mark - notif_timestamp).days > 3: + _resolve(notif, "More than 3 days old") + continue + subject = notif["subject"] - pr = None - if subject["type"] == "PullRequest": - if notif["reason"] == "review_requested": - pr = client.get_pr(url=subject["url"]) + match subject["type"].lower(): + case "pullrequest": + _pr(subject, notif) - reviewers = client.get_pr_reviewers(pr) - if ( - any(org in subject["url"] for org in org_shitlist) - and not any( - it["login"] == user["login"] - for it in reviewers.get("users", []) - ) - and not any( - it["slug"] in user_teams - and it["slug"] not in team_shitlist - for it in reviewers.get("teams", []) - ) - ): - _resolve(notif, "Reviewed") - continue + case "mention": + _mention(subject, notif) - elif notif["reason"] == "team_mention": - pr = client.get_pr(url=subject["url"]) - - reviewers = client.get_pr_reviewers(pr) - if ( - any(org in subject["url"] for org in org_shitlist) - and not any( - it["login"] == user["login"] - for it in reviewers.get("users", []) - ) - and not any( - it["slug"] in user_teams - and it["slug"] not in team_shitlist - for it in reviewers.get("teams", []) - ) - ): - _resolve(notif, "Ignoring team mention") - continue - - elif subject["type"] == "Issue": - issue = client.get_issue(url=subject["url"]) - if issue["state"] == "closed": - comments = client.get_comments(url=issue["comments_url"]) - if not any( - it["user"]["login"] == user["login"] for it in comments - ): - _resolve(notif, "Unengaged issue closed") + case "issue": + _issue(subject, notif) duration = (tick - datetime.now(timezone.utc)).total_seconds() if duration > 0: @@ -234,6 +267,11 @@ def maintain(config_path: Path, schedule: timedelta): except KeyboardInterrupt: break + except requests.exceptions.HTTPError as e: + print("Encoutered exception", e, "backing off") + prev = savepoint + sleep(schedule.total_seconds()) + if __name__ == "__main__": cli() diff --git a/projects/tentacles/src/python/tentacles/workers.py b/projects/tentacles/src/python/tentacles/workers.py index e3f500c..a1cb34d 100644 --- a/projects/tentacles/src/python/tentacles/workers.py +++ b/projects/tentacles/src/python/tentacles/workers.py @@ -70,7 +70,7 @@ def poll_printers(app: App, db: Db) -> None: def _set_status(status: str): if printer.status != status: log.info(f"Printer {printer.id} {printer.status} -> {status}") - db.update_printer_status(pid=printer.id, status=status) + db.update_printer_status(pid=printer.id, status=status) def _bed_clear(): if not ( @@ -117,7 +117,7 @@ def poll_printers(app: App, db: Db) -> None: if mapped_job: db.start_job(jid=mapped_job.id) - elif printer_job.get("state").lower() == "connecting": + elif printer_job.get("state", "").lower() == "connecting": _set_status("connecting") elif printer_state.get("ready"): @@ -171,8 +171,8 @@ def assign_jobs(app: App, db: Db) -> None: db.assign_job(jid=job.id, pid=printer.id) log.info(f"Mapped job {job.id} to printer {printer.id}") break - else: - print("Could not map\n", job, "\n", printer) + else: + log.info(f"Could not map job {job!r}") def push_jobs(app: App, db: Db) -> None: @@ -307,7 +307,8 @@ def analyze_files(app: App, db: Db): for file in db.list_unanalyzed_files(): p = Path(file.path) if not p.is_file(): - log.error(f"Invalid file {file.id}!") + log.error(f"Deleting missing file {file.id}!") + db.delete_file(uid=file.user_id, fid=file.id) continue record = analyze_gcode_file(p) diff --git a/tools/python/requirements.in b/tools/python/requirements.in index 7546ca0..c88d77b 100644 --- a/tools/python/requirements.in +++ b/tools/python/requirements.in @@ -54,3 +54,4 @@ unify yamllint yaspin pytimeparse +git+https://github.com/arrdem/jaraco.text.git@0dd8d0b25a93c3fad896f3a92d11caff61ff273d#egg=jaraco.text diff --git a/tools/python/requirements_lock.txt b/tools/python/requirements_lock.txt index e2c15b9..912d645 100644 --- a/tools/python/requirements_lock.txt +++ b/tools/python/requirements_lock.txt @@ -42,7 +42,7 @@ itsdangerous==2.1.2 jaraco.collections==4.3.0 jaraco.context==4.3.0 jaraco.functools==3.8.0 -jaraco.text==3.11.1 +jaraco.text @ git+https://github.com/arrdem/jaraco.text.git@0dd8d0b25a93c3fad896f3a92d11caff61ff273d jedi==0.18.2 Jinja2==3.1.2 jsonschema==4.18.4