1
0
Fork 0

Fix autoupdater for forges allowing for non-domain-root install and multiple levels of projects

This commit is contained in:
Félix Piédallu 2024-02-16 19:36:52 +01:00
parent 408827f902
commit 189462259c

View file

@ -52,12 +52,19 @@ class GithubAPI:
class GitlabAPI: class GitlabAPI:
def __init__(self, upstream: str): def __init__(self, upstream: str):
split = re.search("(?P<host>https?://.+)/(?P<group>[^/]+)/(?P<project>[^/]+)/?$", upstream) # Find gitlab api root...
assert split is not None self.forge_root = self.get_forge_root(upstream)
self.forge_root = split.group("host") self.project_path = upstream.replace(self.forge_root, "").lstrip("/")
self.project_path = f"{split.group('group')}/{split.group('project')}"
self.project_id = self.find_project_id(self.project_path) self.project_id = self.find_project_id(self.project_path)
def get_forge_root(self, project_url: str) -> str:
"""A small heuristic based on the content of the html page..."""
r = requests.get(project_url)
r.raise_for_status()
match = re.search(r"const url = `(.*)/api/graphql`", r.text)
assert match is not None
return match.group(1)
def find_project_id(self, project: str) -> int: def find_project_id(self, project: str) -> int:
project = self.internal_api(f"projects/{project.replace('/', '%2F')}") project = self.internal_api(f"projects/{project.replace('/', '%2F')}")
assert isinstance(project, dict) assert isinstance(project, dict)
@ -119,10 +126,17 @@ class GitlabAPI:
class GiteaForgejoAPI: class GiteaForgejoAPI:
def __init__(self, upstream: str): def __init__(self, upstream: str):
split = re.search("(?P<host>https?://.+)/(?P<group>[^/]+)/(?P<project>[^/]+)/?$", upstream) # Find gitea/forgejo api root...
assert split is not None self.forge_root = self.get_forge_root(upstream)
self.forge_root = split.group("host") self.project_path = upstream.replace(self.forge_root, "").lstrip("/")
self.project_path = f"{split.group('group')}/{split.group('project')}"
def get_forge_root(self, project_url: str) -> str:
"""A small heuristic based on the content of the html page..."""
r = requests.get(project_url)
r.raise_for_status()
match = re.search(r"appUrl: '([^']*)',", r.text)
assert match is not None
return match.group(1).replace("\\", "")
def internal_api(self, uri: str): def internal_api(self, uri: str):
url = f"{self.forge_root}/api/v1/{uri}" url = f"{self.forge_root}/api/v1/{uri}"