diff --git a/setup.py b/setup.py index 531d98f..6cfce69 100644 --- a/setup.py +++ b/setup.py @@ -14,6 +14,7 @@ setup( "log = pronounomatic.plugins.log_plugin:LogPlugin", "mastodon = pronounomatic.plugins.mastodon:MastodonPlugin", "discord = pronounomatic.plugins.discord:DiscordPlugin", + "gitea = pronounomatic.plugins.gitea:GiteaPlugin", ], }, ) diff --git a/src/plugins/gitea.py b/src/plugins/gitea.py new file mode 100644 index 0000000..8d6cfe9 --- /dev/null +++ b/src/plugins/gitea.py @@ -0,0 +1,88 @@ +""" +Configuration: + Options: + host - the url of a gitea server + token - Users access token +""" + +from ..core.pronoun_update import PronounUpdate +from ..core.plugin import InvalidPluginDefinitionException, Plugin +from requests.models import Response +from typing import Any, Dict +import requests + +class GiteaApiException(Exception): + def __init__(self, error: str) -> None: + super().__init__(f"Gitea api returned an error: {error}") + + pass + + +class MastodonApiClient: + host: str + s = requests.Session() + + def __init__(self, host: str, token: str): + self.host = host + self.s.headers.update({"Authorization": f"Bearer {token}"}) + + def verify_credentials(self) -> Response: + creds = self.s.get(f"{self.host}/api/v1/user") + if not creds.ok: + error = creds.json().get("message", "the server didn't return an error") + raise GiteaApiException(error) + return creds + + def get_settings(self) -> Response: + creds = self.s.get(f"{self.host}/api/v1/user/settings") + if not creds.ok: + error = creds.json().get("message", "the server didn't return an error") + raise GiteaApiException(error) + return creds + + def update_settings(self, updated_credentials: Dict[str, Any]) -> Response: + creds = self.s.patch( + f"{self.host}/api/v1/user/settings", json=updated_credentials + ) + if not creds.ok: + error = creds.json().get("message", "the server didn't return an error") + raise GiteaApiException(error) + return creds + + +class GiteaPlugin(Plugin): + s = requests.Session() + api_client: MastodonApiClient + + @classmethod + def name(cls) -> str: + return "gitea" + + def _load_from_config(self, config: dict[str, Any]) -> None: + host = config.get("host", None) + if not isinstance(host, str): + raise InvalidPluginDefinitionException( + f"Host needs to be set to a string with the url to the mastodon compatible server, got {type(host)}" + ) + self.host = host + + access_token = config.get("token", None) + if not isinstance(access_token, str): + raise InvalidPluginDefinitionException( + f"Access token needs to be set to a string with an access token, got {type(host)}" + ) + self.access_token = access_token + + self.api_client = MastodonApiClient(host, access_token) + + # Verify the credentials + self.api_client.verify_credentials() + + def update_bio(self, update_pronouns: PronounUpdate) -> None: + credentials = self.api_client.verify_credentials().json() + new_credentials = {} + new_credentials["description"] = update_pronouns.replace_pronouns_in_bio( + credentials["description"] + ) + + self.api_client.update_settings(new_credentials)