Skip to main content

A Pycord extension to support automatic text translations in 107 languages.

Project description

A PyCord extension for internationalization

+ Note: `Agent` class has been renamed as `AutoI18nAgent` but the old name is still supported

Key Features

  • Automatic text translations for messages, embeds etc..
  • Zero code change necessary
  • Fully customizable
  • Forward Compatible

The extension is able to automatically translate all specified objects here into any registered language depending on the preferences of the destination channel or guild. For instance, if a channel has the preference for Spanish, any messages, embeds etc.. that are being sent to the channel will be automatically translated into Spanish before it is sent.

Translations will carry over markdown!

+ I've set the language to `English` 🏴󠁧󠁢󠁥󠁮󠁧󠁿!
+ He establecido el idioma en `Spanish` 🇪🇸!
+ ငါဘာသာစကားကိုထားတယ် `မြန်မာ (ဗမာ)` 🇲🇲!

GoogleTranslated string in different languages with formatting maintained

Check out the FAQ, Examples and other feathers for more information. This extension is relatively new so please report any bugs at issues!

Fields Covered by Automatic Translation

  • Messages
  • Interaction Messages
  • Embeds
  • Buttons
  • Selects
  • Modals (beta)
  • Webhooks (beta)

Installing

This is an extension for PyCord. It is recommended that there exists an installation of py-cord>=2.0.0b5.

To install this extension, run the following command:

# Linux/macOS
python3 -m pip install -U discord-ext-i18n

# Windows
py -3 -m pip install -U discord-ext-i18n

Quick Example

Required Steps:

  • Define a language getter function decorated with the Detector.lang_getter decorator (this getter is called with an ID of guilds / channels to see if it has a language preference)
  • Instantiate a discord.ext.i18n.AutoI18nAgent class to configure and inject code
  • Create a command for users to set preferences
from typing import Optional
from discord.ext import commands
from discord import Intents
from discord.ext.i18n import AutoI18nAgent, Language, Detector

intents = Intents.default()
# not necessary for the extension, enabled for msg commands
intents.messages = True
intents.message_content = True

bot = commands.Bot(
    command_prefix="!",
    intents=intents,
)
bot.preferences = {}
bot.agent = AutoI18nAgent(translate_all=True)  # This must be instantiated at least and only once


@Detector.lang_getter
async def get_lang(id) -> Optional[Language]:
    """
    This decorated function will be called internally to get Language
    preferences.
    """
    return bot.preferences.get(id, None)


@bot.command(name="lang")
async def set_lang(ctx, lang_code):
    lang = Language.from_code(lang_code)
    if lang is None:
        return await ctx.reply("Bad language code!")
    elif lang is Language.English:
        # Bot is already in the english language so we remove their preferences
        if ctx.channel.id in bot.preferences:
            bot.preferences.pop(ctx.channel.id)
    else:
        # Set a language preference to the current channel.
        bot.preferences[ctx.channel.id] = lang

    await ctx.reply(f"I've set the language to `{lang.name.title()}` {lang.emoji}!")


@bot.command(name="hi")
async def greet(ctx):
    # This will be translated before sent if necessary
    await ctx.reply("Hey!!")


bot.run("TOKEN")

Examples

  1. Get Started - A minimal example on how to get started with the extension.
  2. Cog Example - Get started but inside a cog.
  3. Customized - An example on how to customize/make your own translator and override the default one.
  4. Settings - An example on how to enable/disable the extension from translating certain fields
  5. Optimized - An example on how to ignore translation on parts of a string that is prone to change
  6. All Objects - A summary example of every object that is affected by translation + all features discussed prior

Features Extended

Tokenization

Tokenization breaks down a string in any order or magnitude of markdown decorations to the extent accepted by discord, into separate tokens to ready for batch translation. Once translated, the new phrases are reassembeled into correct positions and thus maintaining decorative characters fairly accurately.

Constants

This library implements constants for:

  1. Language Names to Code to Emoji enum

Examples:

>>> Language.English.code
... en
>>> Language.English.emoji
... 🏴󠁧󠁢󠁥󠁮󠁧󠁿
>>> Language.name
... english

To access enum elements for a specific language through it's corresponding code or name:

>>> Language.from_code("en")
... Language.English
>>> Language.from_name("english")
... Language.English
  1. Codeblock identifiers

CODEBLOCK_LANGS is an exhaustive set of string identifiers that are considered valid code block languages in the tokenizer.

FAQ

  1. How do we tell the extension to translate x?
  2. How does the extension work?
  3. What does it use to translate the string?
  4. When are strings not translated?
  5. How do I avoid translation on specific function calls?

How do we tell the extension to translate x?

By default, the extension will translate all messages and ignore others. If you want to translate other objects such as buttons, embeds and so on, you will have to explicitly specify them as a parameter when instantiating the AutoI18nAgent class or modify the translate_x flag from the class. See detailed example here

Apart from that, you can call the usual methods like Messegable.send, ApplicationContext.respond with your texts and the translation will be handled in the backend. Absolutely no code change is necessary when calling these high-level methods.

How does the extension work?

When you call high-level methods e.g. Messegable.send the extension intercepts the text and the destination it's being sent to. It resolves whether if this text requires translation by calling the language getter with the ID of its destination. If it has one, it will append the language code into an appropriate field and this appendage is later extracted before text gets sent to the discord API where tokenization, translation, caching and other book-keeping occurs if necessary.

What does it use to translate the string?

By default, the extension translates your strings using the Google Translator library. You can override this with your own translator like in the example here.

When are strings not translated?

Strings are not translated in cases where either if the text are already detected to be in the language that it should be translated into, or the destination no preference.

How do I avoid translation on specific function calls?

You can switch the flags to process specific call translations with some code changes. One example is the command selective here.


TODO / KNOWN ISSUES

[-] Defer interaction responses only if translation doesn't exist in cache

[-] Resolve the issue with not being able to translate in time for Modals and they can't be deferred....

[-] Support translation in Webhooks

[-] More tests

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

discord-ext-i18n-0.0.8.tar.gz (24.0 kB view details)

Uploaded Source

Built Distribution

discord_ext_i18n-0.0.8-py3-none-any.whl (18.6 kB view details)

Uploaded Python 3

File details

Details for the file discord-ext-i18n-0.0.8.tar.gz.

File metadata

  • Download URL: discord-ext-i18n-0.0.8.tar.gz
  • Upload date:
  • Size: 24.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.5

File hashes

Hashes for discord-ext-i18n-0.0.8.tar.gz
Algorithm Hash digest
SHA256 cefcfb08de960c869f9d20dc96cedfdfd98bba231f8f0662ee45b018015d34ed
MD5 a829851492ea934a96d659d78d2d9785
BLAKE2b-256 14a85ec8eb0f108f3df872028de758bc4d1d2ecfa608d946773b68e9db8a4baa

See more details on using hashes here.

File details

Details for the file discord_ext_i18n-0.0.8-py3-none-any.whl.

File metadata

File hashes

Hashes for discord_ext_i18n-0.0.8-py3-none-any.whl
Algorithm Hash digest
SHA256 1093d02db54fc5cb9986148d63d94dff3590fd85307d9ff94a894e6a235da6af
MD5 2e14b63076fcb50a8f0a9a4ce239dd1a
BLAKE2b-256 dba3fb81fac76356ead2f578c0ea1de48323ad6bad04842085042a681edf6955

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page