From 2d77b385771481c2444bdde4a04017b6a9d65a04 Mon Sep 17 00:00:00 2001
From: Reid 'arrdem' McKenzie <me@arrdem.com>
Date: Mon, 2 Oct 2023 22:51:38 -0600
Subject: [PATCH] More tuning of the unnotifier

---
 .../src/python/ghunnotif/__main__.py          | 128 +++++++++++-------
 1 file changed, 78 insertions(+), 50 deletions(-)

diff --git a/projects/gh-unnotifier/src/python/ghunnotif/__main__.py b/projects/gh-unnotifier/src/python/ghunnotif/__main__.py
index b4624ec..4ea7a10 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):
@@ -162,70 +160,95 @@ def maintain(config_path: Path, schedule: timedelta):
     team_shitlist = config["gh-unnotifier"].get("team_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 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")
+
     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")
+
                 subject = notif["subject"]
 
-                pr = None
-                if subject["type"] == "PullRequest":
-                    if notif["reason"] == "review_requested":
-                        pr = client.get_pr(url=subject["url"])
+                match subject["type"]:
+                    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 +257,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()