mirror of
https://github.com/revanced/revanced-static-api.git
synced 2025-05-02 15:44:26 +02:00
refactor: black formatting
This commit is contained in:
parent
07dc65e1ee
commit
1beb377b4b
165
src/app/api.py
165
src/app/api.py
@ -2,96 +2,113 @@ from abc import abstractmethod
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
class Api():
|
|
||||||
_api_key: str
|
|
||||||
|
|
||||||
@abstractmethod
|
class Api:
|
||||||
def __init__(self, api_key: str = None) -> None:
|
_api_key: str
|
||||||
self._api_key: str = api_key
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_release(self, repository: str, all: bool = False, prerelease: bool = False) -> dict | list:
|
def __init__(self, api_key: str = None) -> None:
|
||||||
'''Gets the release(s) for a repository.
|
self._api_key: str = api_key
|
||||||
|
|
||||||
Args:
|
@abstractmethod
|
||||||
repository (str): The repository to get releases for.
|
def get_release(
|
||||||
all (bool, optional): Whether to get all releases or not. Defaults to False.
|
self, repository: str, all: bool = False, prerelease: bool = False
|
||||||
prerelease (bool, optional): Whether to get prereleases or not. Defaults to False.
|
) -> dict | list:
|
||||||
Returns:
|
"""Gets the release(s) for a repository.
|
||||||
dict | list: The release(s) for the repository.
|
|
||||||
'''
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
@abstractmethod
|
Args:
|
||||||
def get_contributor(self, repository):
|
repository (str): The repository to get releases for.
|
||||||
'''Gets the contributors for a repository.
|
all (bool, optional): Whether to get all releases or not. Defaults to False.
|
||||||
|
prerelease (bool, optional): Whether to get prereleases or not. Defaults to False.
|
||||||
|
Returns:
|
||||||
|
dict | list: The release(s) for the repository.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_contributor(self, repository):
|
||||||
|
"""Gets the contributors for a repository.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
repository (str): The repository to get contributors for.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
Args:
|
|
||||||
repository (str): The repository to get contributors for.
|
|
||||||
'''
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
class GitHubApi(Api):
|
class GitHubApi(Api):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_contributor(self, repository):
|
def get_contributor(self, repository):
|
||||||
def transform_contributor(contributor: dict) -> dict:
|
def transform_contributor(contributor: dict) -> dict:
|
||||||
'''Transforms a contributor into a dict.
|
"""Transforms a contributor into a dict.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
contributor (dict): The contributor to transform.
|
contributor (dict): The contributor to transform.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: The transformed contributor.
|
dict: The transformed contributor.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'username': contributor['login'],
|
"username": contributor["login"],
|
||||||
'avatar': contributor['avatar_url'], # TODO: Proxy via a CDN.
|
"avatar": contributor["avatar_url"], # TODO: Proxy via a CDN.
|
||||||
'link': contributor['html_url'],
|
"link": contributor["html_url"],
|
||||||
'contributions': contributor['contributions']
|
"contributions": contributor["contributions"],
|
||||||
}
|
}
|
||||||
|
|
||||||
def sort_and_delete_key(contributor: dict) -> int:
|
def sort_and_delete_key(contributor: dict) -> int:
|
||||||
contributions = contributor['contributions']
|
contributions = contributor["contributions"]
|
||||||
del contributor['contributions']
|
del contributor["contributions"]
|
||||||
return contributions
|
return contributions
|
||||||
|
|
||||||
contributors = requests.get(f'https://api.github.com/repos/{repository}/contributors').json()
|
contributors = requests.get(
|
||||||
contributors = list(map(transform_contributor, contributors)) # List might not be needed.
|
f"https://api.github.com/repos/{repository}/contributors"
|
||||||
contributors.sort(key=sort_and_delete_key, reverse=True)
|
).json()
|
||||||
|
contributors = list(
|
||||||
|
map(transform_contributor, contributors)
|
||||||
|
) # List might not be needed.
|
||||||
|
contributors.sort(key=sort_and_delete_key, reverse=True)
|
||||||
|
|
||||||
return contributors
|
return contributors
|
||||||
|
|
||||||
def get_release(self, repository: str, all: bool = False, prerelease: bool = False) -> dict | list:
|
def get_release(
|
||||||
def transform_release(release: dict) -> dict:
|
self, repository: str, all: bool = False, prerelease: bool = False
|
||||||
'''Transforms a release dict into a dict.
|
) -> dict | list:
|
||||||
|
def transform_release(release: dict) -> dict:
|
||||||
|
"""Transforms a release dict into a dict.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
release (dict): The release dict to transform.
|
release (dict): The release dict to transform.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: The transformed release dict.
|
dict: The transformed release dict.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
return {
|
return {
|
||||||
# TODO: Check if theres any need for this: 'id': release['id'].
|
# TODO: Check if theres any need for this: 'id': release['id'].
|
||||||
'tag': release['tag_name'],
|
"tag": release["tag_name"],
|
||||||
'prerelease': release['prerelease'],
|
"prerelease": release["prerelease"],
|
||||||
'published_at': release['published_at'],
|
"published_at": release["published_at"],
|
||||||
'assets': [
|
"assets": [
|
||||||
{
|
{
|
||||||
'name': asset['name'],
|
"name": asset["name"],
|
||||||
'download_url': asset['browser_download_url'] # TODO: Proxy via a CDN.
|
"download_url": asset[
|
||||||
} for asset in release['assets']
|
"browser_download_url"
|
||||||
]
|
], # TODO: Proxy via a CDN.
|
||||||
}
|
}
|
||||||
|
for asset in release["assets"]
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
# A little bit of code duplication but more readable than a ternary operation.
|
# A little bit of code duplication but more readable than a ternary operation.
|
||||||
if all:
|
if all:
|
||||||
releases: list = requests.get(f'https://api.github.com/repos/{repository}/releases').json()
|
releases: list = requests.get(
|
||||||
return list(map(transform_release, releases)) # List might not be needed.
|
f"https://api.github.com/repos/{repository}/releases"
|
||||||
else:
|
).json()
|
||||||
latest_release: object = requests.get(f'https://api.github.com/repos/{repository}/releases/latest?prerelease={prerelease}').json()
|
return list(map(transform_release, releases)) # List might not be needed.
|
||||||
return transform_release(latest_release)
|
else:
|
||||||
|
latest_release: object = requests.get(
|
||||||
|
f"https://api.github.com/repos/{repository}/releases/latest?prerelease={prerelease}"
|
||||||
|
).json()
|
||||||
|
return transform_release(latest_release)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
def load_config() -> dict:
|
def load_config() -> dict:
|
||||||
with open('config.json', 'r') as config_file:
|
with open("config.json", "r") as config_file:
|
||||||
return json.load(config_file)
|
return json.load(config_file)
|
||||||
|
@ -4,107 +4,113 @@ from app import api
|
|||||||
from app.utils import get_repository_name, write_json, read_json, create_if_not_exists
|
from app.utils import get_repository_name, write_json, read_json, create_if_not_exists
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
|
||||||
class Api():
|
|
||||||
_api: api.Api
|
|
||||||
|
|
||||||
def __init__(self, name: str, api: api.Api = api.GitHubApi()) -> None:
|
class Api:
|
||||||
self.name = name
|
_api: api.Api
|
||||||
self._api = api
|
|
||||||
|
|
||||||
@abstractmethod
|
def __init__(self, name: str, api: api.Api = api.GitHubApi()) -> None:
|
||||||
def generate(self, config, path):
|
self.name = name
|
||||||
'''
|
self._api = api
|
||||||
Generates the api based on the config to the path.
|
|
||||||
|
@abstractmethod
|
||||||
|
def generate(self, config, path):
|
||||||
|
"""
|
||||||
|
Generates the api based on the config to the path.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config (dict): The config for the api
|
||||||
|
path (str): The path where the api should be generated
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
Args:
|
|
||||||
config (dict): The config for the api
|
|
||||||
path (str): The path where the api should be generated
|
|
||||||
'''
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
class ReleaseApi(Api):
|
class ReleaseApi(Api):
|
||||||
def __init__(self, api) -> None:
|
def __init__(self, api) -> None:
|
||||||
super().__init__("release", api)
|
super().__init__("release", api)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def generate(self, config, path):
|
def generate(self, config, path):
|
||||||
path = join(path, 'release')
|
path = join(path, "release")
|
||||||
|
|
||||||
repositories = config["repositories"]
|
repositories = config["repositories"]
|
||||||
|
|
||||||
for repository in repositories:
|
for repository in repositories:
|
||||||
release = self._api.get_release(repository)
|
release = self._api.get_release(repository)
|
||||||
repository_name = get_repository_name(repository)
|
repository_name = get_repository_name(repository)
|
||||||
|
|
||||||
tag = release['tag']
|
tag = release["tag"]
|
||||||
|
|
||||||
release_path = join(path, repository_name)
|
release_path = join(path, repository_name)
|
||||||
release_json = json.dumps(release)
|
release_json = json.dumps(release)
|
||||||
|
|
||||||
create_if_not_exists(release_path)
|
create_if_not_exists(release_path)
|
||||||
|
|
||||||
write_json(release_json, join(release_path, f'{tag}.json'), overwrite=False)
|
write_json(release_json, join(release_path, f"{tag}.json"), overwrite=False)
|
||||||
write_json(release_json, join(release_path, 'latest.json')) # Overwrite the latest release
|
write_json(
|
||||||
|
release_json, join(release_path, "latest.json")
|
||||||
|
) # Overwrite the latest release
|
||||||
|
|
||||||
# At last join the current tag to an index file
|
# At last join the current tag to an index file
|
||||||
index_path = join(path, f'{repository_name}.json')
|
index_path = join(path, f"{repository_name}.json")
|
||||||
|
|
||||||
index = read_json(index_path, [])
|
index = read_json(index_path, [])
|
||||||
if tag not in index: # TODO: Check if there a better way to do this
|
if tag not in index: # TODO: Check if there a better way to do this
|
||||||
index.append(tag) # Add the current tag to the index
|
index.append(tag) # Add the current tag to the index
|
||||||
|
|
||||||
|
write_json(index, index_path)
|
||||||
|
|
||||||
write_json(index, index_path)
|
|
||||||
|
|
||||||
class ContributorApi(Api):
|
class ContributorApi(Api):
|
||||||
def __init__(self, api) -> None:
|
def __init__(self, api) -> None:
|
||||||
super().__init__("contributor", api)
|
super().__init__("contributor", api)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def generate(self, config, path):
|
def generate(self, config, path):
|
||||||
path = join(path, 'contributor')
|
path = join(path, "contributor")
|
||||||
|
|
||||||
create_if_not_exists(path)
|
create_if_not_exists(path)
|
||||||
repositories = config["repositories"]
|
repositories = config["repositories"]
|
||||||
|
|
||||||
for repository in repositories:
|
for repository in repositories:
|
||||||
repository_name = get_repository_name(repository)
|
repository_name = get_repository_name(repository)
|
||||||
|
|
||||||
contributors = self._api.get_contributor(repository)
|
contributors = self._api.get_contributor(repository)
|
||||||
contributors_path = join(path, f'{repository_name}.json')
|
contributors_path = join(path, f"{repository_name}.json")
|
||||||
|
|
||||||
|
write_json(contributors, contributors_path)
|
||||||
|
|
||||||
write_json(contributors, contributors_path)
|
|
||||||
|
|
||||||
class SocialApi(Api):
|
class SocialApi(Api):
|
||||||
def __init__(self, api) -> None:
|
def __init__(self, api) -> None:
|
||||||
super().__init__("social", api)
|
super().__init__("social", api)
|
||||||
|
|
||||||
def generate(self, config, path):
|
def generate(self, config, path):
|
||||||
new_social = config
|
new_social = config
|
||||||
|
|
||||||
social_path = join(path, f"social.json")
|
social_path = join(path, f"social.json")
|
||||||
social = read_json(social_path, new_social)
|
social = read_json(social_path, new_social)
|
||||||
|
|
||||||
write_json(social, social_path)
|
write_json(social, social_path)
|
||||||
|
|
||||||
class ApiProvider():
|
|
||||||
_apis: list[Api]
|
|
||||||
|
|
||||||
def __init__(self, apis: list[Api]) -> None:
|
class ApiProvider:
|
||||||
self._apis = apis
|
_apis: list[Api]
|
||||||
|
|
||||||
def get(self, name: str) -> Api:
|
def __init__(self, apis: list[Api]) -> None:
|
||||||
for api in self._apis:
|
self._apis = apis
|
||||||
if api.name == name:
|
|
||||||
return api
|
def get(self, name: str) -> Api:
|
||||||
|
for api in self._apis:
|
||||||
|
if api.name == name:
|
||||||
|
return api
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
class DefaultApiProvider(ApiProvider):
|
class DefaultApiProvider(ApiProvider):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._api = api.GitHubApi() # Use GitHub as default api
|
self._api = api.GitHubApi() # Use GitHub as default api
|
||||||
|
|
||||||
super().__init__([
|
super().__init__(
|
||||||
ReleaseApi(self._api),
|
[ReleaseApi(self._api), ContributorApi(self._api), SocialApi(self._api)]
|
||||||
ContributorApi(self._api),
|
)
|
||||||
SocialApi(self._api)]
|
|
||||||
)
|
|
||||||
|
@ -1,21 +1,25 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def write_json(text: str | dict | list, to, overwrite=True):
|
def write_json(text: str | dict | list, to, overwrite=True):
|
||||||
if not os.path.exists(to) or overwrite:
|
if not os.path.exists(to) or overwrite:
|
||||||
with open(to, 'w') as f:
|
with open(to, "w") as f:
|
||||||
if not isinstance(text, str):
|
if not isinstance(text, str):
|
||||||
text = json.dumps(text)
|
text = json.dumps(text)
|
||||||
f.write(text)
|
f.write(text)
|
||||||
|
|
||||||
|
|
||||||
def read_json(path, default):
|
def read_json(path, default):
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
with open(path, 'r') as f:
|
with open(path, "r") as f:
|
||||||
return json.load(f)
|
return json.load(f)
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
def create_if_not_exists(path):
|
def create_if_not_exists(path):
|
||||||
os.makedirs(path, exist_ok=True)
|
os.makedirs(path, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
def get_repository_name(repository: str):
|
def get_repository_name(repository: str):
|
||||||
return repository.split('/')[-1]
|
return repository.split("/")[-1]
|
||||||
|
17
src/main.py
17
src/main.py
@ -3,15 +3,16 @@ from app.generator import DefaultApiProvider
|
|||||||
|
|
||||||
config = load_config()
|
config = load_config()
|
||||||
|
|
||||||
output = config['output']
|
output = config["output"]
|
||||||
apis = config['api']
|
apis = config["api"]
|
||||||
|
|
||||||
api_provider = DefaultApiProvider()
|
api_provider = DefaultApiProvider()
|
||||||
|
|
||||||
for api in apis:
|
for api in apis:
|
||||||
types = api['type'].split('+')
|
types = api["type"].split("+")
|
||||||
del api['type'] # Don't need the type for the api anymore below
|
del api["type"] # Don't need the type for the api anymore below
|
||||||
for type in types:
|
for type in types:
|
||||||
api_type = api_provider.get(type)
|
api_type = api_provider.get(type)
|
||||||
if api_type is None: continue
|
if api_type is None:
|
||||||
api_type.generate(api, output)
|
continue
|
||||||
|
api_type.generate(api, output)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user