From d86e3cd16150b5039cfc31036cac3ff2f39cdcd2 Mon Sep 17 00:00:00 2001 From: object-Object Date: Thu, 28 Nov 2024 21:36:55 -0500 Subject: [PATCH] Localize /gh --- bot/src/ghutils/cogs/app_commands/github.py | 71 +++++++++-------- bot/src/ghutils/core/translator.py | 4 +- bot/src/ghutils/resources/l10n/en-US/main.ftl | 79 +++++++++++++++++++ bot/src/ghutils/utils/l10n.py | 48 +++++++++++ 4 files changed, 166 insertions(+), 36 deletions(-) create mode 100644 bot/src/ghutils/utils/l10n.py diff --git a/bot/src/ghutils/cogs/app_commands/github.py b/bot/src/ghutils/cogs/app_commands/github.py index 03ba313..55c5d8e 100644 --- a/bot/src/ghutils/cogs/app_commands/github.py +++ b/bot/src/ghutils/cogs/app_commands/github.py @@ -26,6 +26,7 @@ UserGitHubTokens, UserLogin, ) +from ghutils.utils import l10n from ghutils.utils.discord.embeds import set_embed_author from ghutils.utils.discord.references import ( CommitReference, @@ -53,48 +54,54 @@ class GitHubCog(GHUtilsCog, GroupCog, group_name="gh"): # /gh - @app_commands.command() + @app_commands.command( + description=l10n.command_description("gh issue"), + ) @app_commands.rename(reference="issue") + @l10n.describe(gh_issue=["reference"]) + @l10n.describe_common("visibility") async def issue( self, interaction: Interaction, reference: IssueReference, visibility: MessageVisibility = "private", ): - """Get a link to a GitHub issue.""" - await respond_with_visibility( interaction, visibility, embed=_create_issue_embed(*reference), ) - @app_commands.command() + @app_commands.command( + description=l10n.command_description("gh pr"), + ) @app_commands.rename(reference="pr") + @l10n.describe(gh_pr=["reference"]) + @l10n.describe_common("visibility") async def pr( self, interaction: Interaction, reference: PRReference, visibility: MessageVisibility = "private", ): - """Get a link to a GitHub pull request.""" - await respond_with_visibility( interaction, visibility, embed=_create_issue_embed(*reference), ) - @app_commands.command() + @app_commands.command( + description=l10n.command_description("gh commit"), + ) @app_commands.rename(reference="commit") + @l10n.describe(gh_commit=["reference"]) + @l10n.describe_common("visibility") async def commit( self, interaction: Interaction, reference: CommitReference, visibility: MessageVisibility = "private", ): - """Get a link to a GitHub commit.""" - repo, commit = reference async with self.bot.github_app(interaction) as (github, _): @@ -128,15 +135,17 @@ async def commit( await respond_with_visibility(interaction, visibility, embed=embed) - @app_commands.command() + @app_commands.command( + description=l10n.command_description("gh repo"), + ) + @l10n.describe(gh_repo=["repo"]) + @l10n.describe_common("visibility") async def repo( self, interaction: Interaction, repo: FullRepositoryOption, visibility: MessageVisibility = "private", ): - """Get a link to a GitHub repository.""" - async with self.bot.github_app(interaction) as (github, _): result = await github.async_graphql( """ @@ -164,10 +173,10 @@ async def repo( await respond_with_visibility(interaction, visibility, embed=embed) - @app_commands.command() + @app_commands.command( + description=l10n.command_description("gh login"), + ) async def login(self, interaction: Interaction): - """Authorize GitHub Utils to make requests on behalf of your GitHub account.""" - user_id = interaction.user.id login_id = str(uuid.uuid4()) @@ -188,10 +197,10 @@ async def login(self, interaction: Interaction): ephemeral=True, ) - @app_commands.command() + @app_commands.command( + description=l10n.command_description("gh logout"), + ) async def logout(self, interaction: Interaction): - """Remove your GitHub account from GitHub Utils.""" - with self.bot.db_session() as session: # TODO: this should delete the authorization too, but idk how # https://docs.github.com/en/rest/apps/oauth-applications?apiVersion=2022-11-28#delete-an-app-authorization @@ -209,14 +218,15 @@ async def logout(self, interaction: Interaction): ephemeral=True, ) - @app_commands.command() + @app_commands.command( + description=l10n.command_description("gh status"), + ) + @l10n.describe_common("visibility") async def status( self, interaction: Interaction, visibility: MessageVisibility = "private", ): - """Show information about GitHub Utils.""" - if info := self.env.deployment: color = Color.green() commit_url = f"https://github.com/object-Object/discord-github-utils/commit/{info.commit_sha}" @@ -268,10 +278,12 @@ async def status( await respond_with_visibility(interaction, visibility, embed=embed) - class Search(SubGroup): - """Search for things on GitHub.""" - - @app_commands.command() + class Search(SubGroup, description=l10n.command_description("gh search")): + @app_commands.command( + description=l10n.command_description("gh search files"), + ) + @l10n.describe(gh_search_files=["repo", "query", "ref", "exact", "limit"]) + @l10n.describe_common("visibility") async def files( self, interaction: Interaction, @@ -282,15 +294,6 @@ async def files( limit: Range[int, 1, 25] = 5, visibility: MessageVisibility = "private", ): - """Search for files in a repository by name. - - Args: - ref: Branch name, tag name, or commit to search in. Defaults to the - default branch of the repo. - exact: If true, use exact search; otherwise use fuzzy search. - limit: Maximum number of results to show. - """ - async with self.bot.github_app(interaction) as (github, state): if state != LoginState.LOGGED_IN: raise NotLoggedInError() diff --git a/bot/src/ghutils/core/translator.py b/bot/src/ghutils/core/translator.py index 03e6c9d..d0bc769 100644 --- a/bot/src/ghutils/core/translator.py +++ b/bot/src/ghutils/core/translator.py @@ -32,5 +32,5 @@ async def translate( locale: Locale, context: TranslationContextTypes, ) -> str | None: - l10n = self.l10n[locale] - return l10n.format_value(string.extras["id"]) + msg_id = string.extras.get("id", string.message) + return self.l10n[locale].format_value(msg_id, string.extras) diff --git a/bot/src/ghutils/resources/l10n/en-US/main.ftl b/bot/src/ghutils/resources/l10n/en-US/main.ftl index e69de29..485a880 100644 --- a/bot/src/ghutils/resources/l10n/en-US/main.ftl +++ b/bot/src/ghutils/resources/l10n/en-US/main.ftl @@ -0,0 +1,79 @@ +# command descriptions: command-description_{command} +# |--------------------------------------------------------------------------------------------------| + +# parameter descriptions: parameter-description_{command}_{parameter} +# |--------------------------------------------------------------------------------------------------| + +# common parameters + +parameter-description_common_visibility = + Whether the message should be visible to everyone, or just you. + +# /gh issue + +command-description_gh-issue = + Get a link to a GitHub issue. + +parameter-description_gh-issue_reference = + Issue to look up (`owner/repo#123` or `#123`). Use `/gh login` to get autocomplete. + +# /gh pr + +command-description_gh-pr = + Get a link to a GitHub pull request. + +parameter-description_gh-pr_reference = + Pull request to look up (`owner/repo#123` or `#123`). Use `/gh login` to get autocomplete. + +# /gh commit + +command-description_gh-commit = + Get a link to a GitHub commit. + +parameter-description_gh-commit_reference = + Commit SHA to look up (`owner/repo@sha` or `@sha`). Use `/gh login` to get autocomplete. + +# /gh repo + +command-description_gh-repo = + Get a link to a GitHub repository. + +# /gh login + +command-description_gh-login = + Authorize GitHub Utils to make requests on behalf of your GitHub account. + +# /gh logout + +command-description_gh-logout = + Remove your GitHub account from GitHub Utils. + +# /gh status + +command-description_gh-status = + Show information about GitHub Utils. + +# /gh search + +command-description_gh-search = + Search for things on GitHub. + +# /gh search files + +command-description_gh-search-files = + Search for files in a repository by name. + +parameter-description_gh-search-files_repo = + Repository to search in (`owner/repo`). + +parameter-description_gh-search-files_query = + Filename to search for. + +parameter-description_gh-search-files_ref = + Branch name, tag name, or commit to search in. Defaults to the default branch of the repo. + +parameter-description_gh-search-files_exact = + If true, use exact search; otherwise use fuzzy search. + +parameter-description_gh-search-files_limit = + Maximum number of results to show. diff --git a/bot/src/ghutils/utils/l10n.py b/bot/src/ghutils/utils/l10n.py new file mode 100644 index 0000000..26d8dcd --- /dev/null +++ b/bot/src/ghutils/utils/l10n.py @@ -0,0 +1,48 @@ +"""Localization helpers.""" + +import re +from typing import Mapping + +from discord import app_commands +from discord.app_commands import locale_str + +type StrIterable = list[str] | tuple[str, ...] + +_SEPARATOR_PATTERN = re.compile(r"[ _-]+") + + +def command_description(command: str): + command = _format_command(command) + return locale_str(f"command-description_{command}") + + +def parameter_description(command: str | None, parameter: str): + command = _format_command(command or "common") + return locale_str(f"parameter-description_{command}_{parameter}") + + +def describe_common(*parameters: str): + return describe(common=parameters) + + +def describe( + dict_args: Mapping[str, StrIterable] | None = None, + **kwargs: StrIterable, +): + """Localize app command parameters. + + Key: command to localize parameters for. + + Value: parameter names. + """ + if dict_args: + kwargs |= dict_args + return app_commands.describe(**{ + parameter: parameter_description(command, parameter) + for command, parameters in kwargs.items() + for parameter in parameters + }) + + +def _format_command(command: str): + return _SEPARATOR_PATTERN.sub("-", command).replace("/", "")