import asyncio import os import traceback import aiohttp import discord # We don't use the converser cog here because we want to be able to redo for the last images and text prompts at the same time from sqlitedict import SqliteDict from models.deepl_model import TranslationModel from services.environment_service import EnvService from services.image_service import ImageService from services.text_service import TextService ALLOWED_GUILDS = EnvService.get_allowed_guilds() def build_translation_embed(text, translated_text, translated_language): """Build an embed for the translation""" embed = discord.Embed( title=f"Translation to " + translated_language, color=0x311432, ) embed.add_field(name="Original text", value=text, inline=False) embed.add_field(name="Translated Text", value=translated_text, inline=False) return embed class TranslationService(discord.Cog, name="TranslationService"): """Cog containing a draw commands and file management for saved images""" def __init__( self, bot, translation_model, ): super().__init__() self.bot = bot self.translation_model = translation_model # Make a mapping of all the country codes and their full country names: def build_supported_language_embed(self): """Build an embed for the translation""" embed = discord.Embed( title=f"Translator supported languages", color=0x311432, ) # Add the list of supported languages in a nice format embed.add_field( name="Languages", value=", ".join( [f"{name}" for name in TranslationModel.get_all_country_names()] ), inline=False, ) return embed async def translate_command(self, ctx, text, target_language): """Delete all local images""" await ctx.defer() # TODO Add pagination! if ( target_language.lower().strip() not in TranslationModel.get_all_country_names(lower=True) ): await ctx.respond( f"The language {target_language} is not recognized or supported. Please use `/languages` to see the list of supported languages." ) return try: response = await self.translation_model.send_translate_request( text, TranslationModel.get_country_code_from_name(target_language) ) except aiohttp.ClientResponseError as e: await ctx.respond(f"There was an error with the DeepL API: {e.message}") return await ctx.respond( embed=build_translation_embed(text, response, target_language) ) async def translate_action(self, ctx, message): await ctx.defer(ephemeral=True) selection_message = await ctx.respond( "Select language", ephemeral=True, delete_after=60 ) await selection_message.edit( view=TranslateView(self.translation_model, message, selection_message) ) async def languages_command(self, ctx): """Show all languages supported for translation""" await ctx.defer() await ctx.respond(embed=self.build_supported_language_embed()) class TranslateView(discord.ui.View): def __init__(self, translation_model, message, selection_message): super().__init__() self.translation_model = translation_model self.message = message self.selection_message = selection_message @discord.ui.select( # the decorator that lets you specify the properties of the select menu placeholder="Language", # the placeholder text that will be displayed if nothing is selected min_values=1, # the minimum number of values that must be selected by the users max_values=1, # the maximum number of values that can be selected by the users options=[ # the list of options from which users can choose, a required field discord.SelectOption( label=name, ) for name in TranslationModel.get_all_country_names() ], ) async def select_callback( self, select, interaction ): # the function called when the user is done selecting options try: response = await self.translation_model.send_translate_request( self.message.content, TranslationModel.get_country_code_from_name(select.values[0]), ) await self.message.reply( mention_author=False, embed=build_translation_embed( self.message.content, response, select.values[0] ), ) await self.selection_message.delete() except aiohttp.ClientResponseError as e: await interaction.response.send_message( f"There was an error with the DeepL API: {e.message}", ephemeral=True, delete_after=15, ) return except Exception as e: await interaction.response.send_message( f"There was an error: {e}", ephemeral=True, delete_after=15 ) return