From db4d51f5a3582a7df6f59170506e067867e5c28d Mon Sep 17 00:00:00 2001 From: Valerie Date: Sat, 24 May 2025 01:12:09 -0400 Subject: [PATCH] Add Translator Cog --- translator/__init__.py | 3 ++ translator/info.json | 21 ++++++++ translator/translator.py | 101 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 translator/__init__.py create mode 100644 translator/info.json create mode 100644 translator/translator.py diff --git a/translator/__init__.py b/translator/__init__.py new file mode 100644 index 0000000..84a3cf3 --- /dev/null +++ b/translator/__init__.py @@ -0,0 +1,3 @@ +from .translator import setup + +__red_end_user_data_statement__ = "This cog does not persistently store data about users." \ No newline at end of file diff --git a/translator/info.json b/translator/info.json new file mode 100644 index 0000000..3311190 --- /dev/null +++ b/translator/info.json @@ -0,0 +1,21 @@ +{ + "name": "Translator", + "short": "Translate messages in different languages", + "description": "A cog that allows you to translate messages by replying to them. Supports multiple languages using Google Translate.", + "end_user_data_statement": "This cog does not store any user data.", + "author": [ + "Valerie" + ], + "required_cogs": {}, + "requirements": [ + "googletrans==3.1.0a0" + ], + "tags": [ + "utility", + "translation" + ], + "min_bot_version": "3.5.0", + "hidden": false, + "disabled": false, + "type": "COG" +} \ No newline at end of file diff --git a/translator/translator.py b/translator/translator.py new file mode 100644 index 0000000..e4c15b5 --- /dev/null +++ b/translator/translator.py @@ -0,0 +1,101 @@ +from redbot.core import commands +from googletrans import Translator, LANGUAGES +import discord +import asyncio + +class TranslatorCog(commands.Cog): + """Translate messages using Google Translate""" + + def __init__(self, bot): + self.bot = bot + self.translator = Translator() + self.languages = LANGUAGES + + @commands.command(name="translate") + async def translate_text(self, ctx, *, message=None): + """Translate a message to English by replying to it + You can also specify a language code after your message to translate to that language + Example: [p]translate bonjour fr -> en + """ + if not message and not ctx.message.reference: + await ctx.send("Please either provide text to translate or reply to a message to translate it.") + return + + # If replying to a message + if ctx.message.reference: + referenced_msg = await ctx.fetch_message(ctx.message.reference.message_id) + text_to_translate = referenced_msg.content + + # Check if language was specified in the command + if message: + try: + source_lang, dest_lang = message.split("->") + source_lang = source_lang.strip() + dest_lang = dest_lang.strip() + except ValueError: + dest_lang = "en" + source_lang = "auto" + else: + dest_lang = "en" + source_lang = "auto" + else: + # Direct message translation + if "->" in message: + try: + text, langs = message.rsplit("->", 1) + text_to_translate = text.strip() + dest_lang = langs.strip() + source_lang = "auto" + except ValueError: + text_to_translate = message + dest_lang = "en" + source_lang = "auto" + else: + text_to_translate = message + dest_lang = "en" + source_lang = "auto" + + try: + # Validate destination language + if dest_lang.lower() not in self.languages and dest_lang.lower() not in {v.lower(): k for k, v in self.languages.items()}: + await ctx.send(f"Invalid destination language code. Available languages: {', '.join(self.languages.keys())}") + return + + # Convert language name to code if full name was provided + if dest_lang.lower() in {v.lower(): k for k, v in self.languages.items()}: + dest_lang = next(k for k, v in self.languages.items() if v.lower() == dest_lang.lower()) + + # Translate the text + translation = self.translator.translate(text_to_translate, dest=dest_lang, src=source_lang) + + # Create embed + embed = discord.Embed(title="Translation", color=discord.Color.blue()) + embed.add_field(name=f"Original ({translation.src}):", value=text_to_translate[:1024], inline=False) + embed.add_field(name=f"Translation ({translation.dest}):", value=translation.text[:1024], inline=False) + + await ctx.send(embed=embed) + + except Exception as e: + await ctx.send(f"An error occurred while translating: {str(e)}") + + @commands.command(name="langlist") + async def language_list(self, ctx): + """List all available language codes""" + lang_list = [] + for code, lang in self.languages.items(): + lang_list.append(f"`{code}`: {lang}") + + # Split into chunks of 20 for readability + chunks = [lang_list[i:i + 20] for i in range(0, len(lang_list), 20)] + + for i, chunk in enumerate(chunks): + if i == 0: + embed = discord.Embed(title="Available Languages", + description="Use these codes with the translate command\n\n" + "\n".join(chunk), + color=discord.Color.blue()) + else: + embed = discord.Embed(description="\n".join(chunk), color=discord.Color.blue()) + await ctx.send(embed=embed) + +async def setup(bot): + await bot.add_cog(TranslatorCog(bot)) \ No newline at end of file