2024-02-07 14:49:55 +01:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
2024-01-23 23:37:24 +01:00
|
|
|
import re
|
2024-02-07 14:49:55 +01:00
|
|
|
from enum import Enum
|
2024-02-12 16:59:54 +01:00
|
|
|
from typing import Any
|
2024-01-23 22:32:31 +01:00
|
|
|
|
2024-02-07 14:49:55 +01:00
|
|
|
import requests
|
|
|
|
|
2024-01-23 22:32:31 +01:00
|
|
|
|
|
|
|
class RefType(Enum):
|
|
|
|
tags = 1
|
|
|
|
commits = 2
|
|
|
|
|
|
|
|
|
|
|
|
class GithubAPI:
|
2024-02-12 16:59:54 +01:00
|
|
|
def __init__(self, upstream: str, auth: tuple[str, str] | None = None):
|
2024-01-23 22:32:31 +01:00
|
|
|
self.upstream = upstream
|
|
|
|
self.upstream_repo = upstream.replace("https://github.com/", "")\
|
|
|
|
.strip("/")
|
|
|
|
assert (
|
|
|
|
len(self.upstream_repo.split("/")) == 2
|
|
|
|
), f"'{upstream}' doesn't seem to be a github repository ?"
|
|
|
|
self.auth = auth
|
|
|
|
|
2024-02-12 16:59:54 +01:00
|
|
|
def internal_api(self, uri: str) -> Any:
|
2024-01-23 22:32:31 +01:00
|
|
|
url = f"https://api.github.com/{uri}"
|
|
|
|
r = requests.get(url, auth=self.auth)
|
|
|
|
assert r.status_code == 200, r
|
|
|
|
return r.json()
|
|
|
|
|
2024-02-12 16:59:54 +01:00
|
|
|
def tags(self) -> list[dict[str, str]]:
|
2024-01-23 22:32:31 +01:00
|
|
|
"""Get a list of tags for project."""
|
|
|
|
return self.internal_api(f"repos/{self.upstream_repo}/tags")
|
|
|
|
|
2024-02-12 16:59:54 +01:00
|
|
|
def commits(self) -> list[dict[str, ]]:
|
2024-01-23 22:32:31 +01:00
|
|
|
"""Get a list of commits for project."""
|
|
|
|
return self.internal_api(f"repos/{self.upstream_repo}/commits")
|
|
|
|
|
2024-02-12 16:59:54 +01:00
|
|
|
def releases(self) -> list[dict[str]]:
|
2024-01-23 22:32:31 +01:00
|
|
|
"""Get a list of releases for project."""
|
|
|
|
return self.internal_api(f"repos/{self.upstream_repo}/releases")
|
|
|
|
|
|
|
|
def url_for_ref(self, ref: str, ref_type: RefType) -> str:
|
|
|
|
"""Get a URL for a ref."""
|
|
|
|
if ref_type == RefType.tags:
|
|
|
|
return f"{self.upstream}/archive/refs/tags/{ref}.tar.gz"
|
|
|
|
elif ref_type == RefType.commits:
|
|
|
|
return f"{self.upstream}/archive/{ref}.tar.gz"
|
|
|
|
else:
|
|
|
|
raise NotImplementedError
|
2024-01-23 23:37:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
class GitlabAPI:
|
|
|
|
def __init__(self, upstream: str):
|
|
|
|
split = re.search("(?P<host>https?://.+)/(?P<group>[^/]+)/(?P<project>[^/]+)/?$", upstream)
|
2024-02-12 16:59:54 +01:00
|
|
|
assert split is not None
|
2024-01-23 23:37:24 +01:00
|
|
|
self.upstream = split.group("host")
|
|
|
|
self.upstream_repo = f"{split.group('group')}/{split.group('project')}"
|
2024-01-26 22:52:33 +01:00
|
|
|
self.project_id = self.find_project_id(self.upstream_repo)
|
2024-01-23 23:37:24 +01:00
|
|
|
|
|
|
|
def find_project_id(self, project: str) -> int:
|
2024-01-26 22:52:33 +01:00
|
|
|
project = self.internal_api(f"projects/{project.replace('/', '%2F')}")
|
2024-02-12 16:59:54 +01:00
|
|
|
assert isinstance(project, dict)
|
|
|
|
project_id = project.get("id", None)
|
|
|
|
return project_id
|
2024-01-23 23:37:24 +01:00
|
|
|
|
2024-02-12 16:59:54 +01:00
|
|
|
def internal_api(self, uri: str) -> Any:
|
2024-01-23 23:37:24 +01:00
|
|
|
url = f"{self.upstream}/api/v4/{uri}"
|
|
|
|
r = requests.get(url)
|
|
|
|
assert r.status_code == 200, r
|
|
|
|
return r.json()
|
|
|
|
|
2024-02-12 16:59:54 +01:00
|
|
|
def tags(self) -> list[dict[str, str]]:
|
2024-01-23 23:37:24 +01:00
|
|
|
"""Get a list of tags for project."""
|
|
|
|
return self.internal_api(f"projects/{self.project_id}/repository/tags")
|
|
|
|
|
2024-02-12 16:59:54 +01:00
|
|
|
def commits(self) -> list[dict[str, Any]]:
|
2024-01-23 23:37:24 +01:00
|
|
|
"""Get a list of commits for project."""
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
"sha": commit["id"],
|
|
|
|
"commit": {
|
2024-01-26 22:52:33 +01:00
|
|
|
"author": {
|
2024-01-23 23:37:24 +01:00
|
|
|
"date": commit["committed_date"]
|
|
|
|
}
|
2024-02-12 16:59:54 +01:00
|
|
|
}
|
2024-01-23 23:37:24 +01:00
|
|
|
}
|
|
|
|
for commit in self.internal_api(f"projects/{self.project_id}/repository/commits")
|
2024-02-12 16:59:54 +01:00
|
|
|
]
|
2024-01-23 23:37:24 +01:00
|
|
|
|
2024-02-12 16:59:54 +01:00
|
|
|
def releases(self) -> list[dict[str, Any]]:
|
2024-01-23 23:37:24 +01:00
|
|
|
"""Get a list of releases for project."""
|
|
|
|
releases = self.internal_api(f"projects/{self.project_id}/releases")
|
2024-01-24 19:32:24 +01:00
|
|
|
retval = []
|
|
|
|
for release in releases:
|
|
|
|
r = {
|
2024-01-23 23:37:24 +01:00
|
|
|
"tag_name": release["tag_name"],
|
|
|
|
"prerelease": False,
|
|
|
|
"draft": False,
|
|
|
|
"html_url": release["_links"]["self"],
|
|
|
|
"assets": [{
|
|
|
|
"name": asset["name"],
|
|
|
|
"browser_download_url": asset["direct_asset_url"]
|
|
|
|
} for asset in release["assets"]["links"]],
|
2024-01-24 19:32:24 +01:00
|
|
|
}
|
|
|
|
for source in release["assets"]["sources"]:
|
|
|
|
r["assets"].append({
|
|
|
|
"name": f"source.{source['format']}",
|
|
|
|
"browser_download_url": source['url']
|
|
|
|
})
|
|
|
|
retval.append(r)
|
|
|
|
|
|
|
|
return retval
|
2024-01-23 23:37:24 +01:00
|
|
|
|
|
|
|
def url_for_ref(self, ref: str, ref_type: RefType) -> str:
|
|
|
|
return f"{self.upstream}/api/v4/projects/{self.project_id}/repository/archive.tar.gz/?sha={ref}"
|
2024-02-14 03:40:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
class GiteaForgejoAPI:
|
|
|
|
def __init__(self, upstream: str):
|
|
|
|
split = re.search("(?P<host>https?://.+)/(?P<group>[^/]+)/(?P<project>[^/]+)/?$", upstream)
|
|
|
|
self.upstream = split.group("host")
|
|
|
|
self.upstream_repo = f"{split.group('group')}/{split.group('project')}"
|
|
|
|
|
|
|
|
def internal_api(self, uri: str):
|
|
|
|
url = f"{self.upstream}/api/v1/{uri}"
|
|
|
|
r = requests.get(url)
|
|
|
|
assert r.status_code == 200, r
|
|
|
|
return r.json()
|
|
|
|
|
|
|
|
def tags(self) -> List[str]:
|
|
|
|
"""Get a list of tags for project."""
|
|
|
|
return self.internal_api(f"repos/{self.upstream_repo}/tags")
|
|
|
|
|
|
|
|
def commits(self) -> List[str]:
|
|
|
|
"""Get a list of commits for project."""
|
|
|
|
return self.internal_api(f"repos/{self.upstream_repo}/commits")
|
|
|
|
|
|
|
|
def releases(self) -> List[str]:
|
|
|
|
"""Get a list of releases for project."""
|
|
|
|
return self.internal_api(f"repos/{self.upstream_repo}/releases")
|
|
|
|
|
|
|
|
def url_for_ref(self, ref: str, ref_type: RefType) -> str:
|
|
|
|
"""Get a URL for a ref."""
|
|
|
|
return f"{self.upstream}/{self.upstream_repo}/archive/{ref}.tar.gz"
|