diff --git a/setup.py b/setup.py index 6cfce69..6556a16 100644 --- a/setup.py +++ b/setup.py @@ -15,6 +15,7 @@ setup( "mastodon = pronounomatic.plugins.mastodon:MastodonPlugin", "discord = pronounomatic.plugins.discord:DiscordPlugin", "gitea = pronounomatic.plugins.gitea:GiteaPlugin", + "github = pronounomatic.plugins.github:GithubPlugin", ], }, ) diff --git a/src/plugins/gitea.py b/src/plugins/gitea.py index 8d6cfe9..9269b07 100644 --- a/src/plugins/gitea.py +++ b/src/plugins/gitea.py @@ -18,7 +18,7 @@ class GiteaApiException(Exception): pass -class MastodonApiClient: +class GiteaApiClient: host: str s = requests.Session() @@ -52,7 +52,7 @@ class MastodonApiClient: class GiteaPlugin(Plugin): s = requests.Session() - api_client: MastodonApiClient + api_client: GiteaApiClient @classmethod def name(cls) -> str: @@ -73,7 +73,7 @@ class GiteaPlugin(Plugin): ) self.access_token = access_token - self.api_client = MastodonApiClient(host, access_token) + self.api_client = GiteaApiClient(host, access_token) # Verify the credentials self.api_client.verify_credentials() diff --git a/src/plugins/github.py b/src/plugins/github.py new file mode 100644 index 0000000..0b3e7cd --- /dev/null +++ b/src/plugins/github.py @@ -0,0 +1,70 @@ +""" +Configuration: + Options: + 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 GithubApiException(Exception): + def __init__(self, error: str) -> None: + super().__init__(f"Gitea api returned an error: {error}") + + pass + + +class GithubApiClient: + s = requests.Session() + + def __init__(self, token: str): + self.s.headers.update({"Authorization": f"token {token}"}) + + def verify_credentials(self) -> Response: + creds = self.s.get(f"https://api.github.com/user") + if not creds.ok: + error = creds.json().get("message", "the server didn't return an error") + raise GithubApiException(error) + return creds + + def update_account(self, updated_credentials: Dict[str, Any]) -> Response: + creds = self.s.patch( + f"https://api.github.com/user", json=updated_credentials + ) + if not creds.ok: + error = creds.json().get("message", "the server didn't return an error") + raise GithubApiException(error) + return creds + + +class GithubPlugin(Plugin): + s = requests.Session() + api_client: GithubApiClient + + @classmethod + def name(cls) -> str: + return "github" + + def _load_from_config(self, config: dict[str, Any]) -> None: + 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(access_token)}" + ) + self.access_token = access_token + + self.api_client = GithubApiClient(access_token) + + # Verify the credentials + self.api_client.verify_credentials() + + def update_bio(self, update_pronouns: PronounUpdate) -> None: + cur_bio = self.api_client.verify_credentials().json()["bio"] + new_bio = update_pronouns.replace_pronouns_in_bio( + cur_bio + ) + + self.api_client.update_account({"bio": new_bio})