From d3b2090f2c48b2acb376612b42effcda374edab6 Mon Sep 17 00:00:00 2001
From: trinity-1686a <trinity@deuxfleurs.fr>
Date: Sun, 18 Feb 2024 17:37:59 +0100
Subject: [PATCH] add suppport for listing preferred and default projects

---
 config/main.yaml                 |  4 ++++
 src/torbot/core/configuration.py | 14 ++++++++++++++
 src/torbot/gitlab/__init__.py    | 27 +++++++++++++++++++--------
 3 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/config/main.yaml b/config/main.yaml
index cdf7f74..b73dfc8 100644
--- a/config/main.yaml
+++ b/config/main.yaml
@@ -16,6 +16,10 @@ irc:
     tls_auth_key: ~/bot/tls-auth.key
   channels:
     - channel: "#tor-dev"
+      default_project: "tpo/core/team"
+      preferred_projects:
+        - "tpo/core/tor"
+        - "tpo/anti-censorship/pluggable-transports/snowflake"
     - channel: "#tor-project"
     - channel: "#tor-bot-test"
 
diff --git a/src/torbot/core/configuration.py b/src/torbot/core/configuration.py
index b2373c1..17cbb22 100644
--- a/src/torbot/core/configuration.py
+++ b/src/torbot/core/configuration.py
@@ -93,6 +93,20 @@ class Configuration:
         data = self.gitlab_access_token_file()
         return data.get("access_token", "")
 
+    def preferred_projects(self, target: str):
+        for channel in self.irc_channels():
+            if channel["channel"] != target:
+                continue
+            return channel.get("preferred_projects") or []
+        return []
+
+    def default_project(self):
+        for channel in self.irc_channels():
+            if channel["channel"] != target:
+                continue
+            return channel.get("default_project")
+        return None
+
     def get(self, key: str):
         tokens = key.split(".")
         config = self._config
diff --git a/src/torbot/gitlab/__init__.py b/src/torbot/gitlab/__init__.py
index 823f381..9036a1b 100644
--- a/src/torbot/gitlab/__init__.py
+++ b/src/torbot/gitlab/__init__.py
@@ -10,7 +10,7 @@ import irc3.rfc
 import re
 import sys
 
-from typing import List, Optional, Set
+from typing import List, Optional
 
 
 class GitlabScanner:
@@ -21,7 +21,7 @@ class GitlabScanner:
             assert chararacter not in self._types
             self._types[chararacter] = re.compile(r"([\w/-]+)?" + chararacter + r"([0-9]+)")
 
-    def match(self, input_string: str) -> Set[str]:
+    def match(self, input_string: str) -> List[str]:
         result = []
 
         for type_name, regex in self._types.items():
@@ -38,8 +38,10 @@ class GitlabScanner:
         return result
 
 class FuzzyProjectFinder:
-    def __init__(self, projects: List[str]) -> None:
+    # preference is a list of projects to prefer in case of tie
+    def __init__(self, projects: List[str], preferences: List[str]) -> None:
         self._projects = {}
+        self._preferences = preferences
 
         projects.sort()
 
@@ -50,10 +52,10 @@ class FuzzyProjectFinder:
             assert project not in self._projects
             self._projects[project] = tokens
 
-    def match(self, input_project: str, default_project: str) -> Set[str]:
+    def match(self, input_project: str, default_project: str) -> List[str]:
         if input_project is None:
             if default_project is None:
-                return set()
+                return []
 
             input_project = default_project
 
@@ -62,6 +64,7 @@ class FuzzyProjectFinder:
         input_tokens_len = len(input_tokens)
 
         result = []
+        preferred_result = []
 
         for project_name, project_tokens in self._projects.items():
             project_tokens = project_tokens.copy()
@@ -69,11 +72,16 @@ class FuzzyProjectFinder:
             while project_tokens:
                 if input_tokens == project_tokens[0:input_tokens_len]:
                     result.append(project_name)
+                    if project_name in self._preferences:
+                        preferred_result.append(project_name)
                     break
 
                 project_tokens.pop()
 
-        return result
+        if len(preferred_result) == 1:
+            return preferred_result
+        else:
+            return result
 
 @irc3.plugin
 class Gitlab:
@@ -107,10 +115,13 @@ class Gitlab:
         if event == 'NOTICE' or data.startswith('\x01VERSION') or not target.is_channel:
             return
 
-        finder = FuzzyProjectFinder(list(self.projects.keys()))
+        finder = FuzzyProjectFinder(
+                list(self.projects.keys()),
+                self.bot._config.preferred_projects(target)
+                )
 
         for match in self.scanner.match(data):
-            matches = finder.match(match["project"], None)
+            matches = finder.match(match["project"], self.bot._config.default_project(target))
 
             if len(matches) == 0:
                 # self.bot.privmsg(target, "Unknown project: {}".format(match["project"]))
-- 
GitLab