====== Quick project: translating text [python] ====== {{tag>dev python wordpress}} Lately, I've been considering multilanguage support on my [[https://blog.nervtech.org/|family blogging site]]. And my my my... ๐Ÿ˜ณ This is still so expensive in the end! All the extensions/plugins you can find for wordpress will request you to pay at some point to perform translations, which is fair I guess. But I don't like paying for things I can do myself. So question is, can I do that ? Translate large texts easily ? lol ๐Ÿ˜… And thus, this project at hand here: let's see if I can do that in python conviniently! I found the [[https://pypi.org/project/deep-translator|deep-translator]] package already, so let's give that a try. ====== ====== ===== The command line arguments ===== As usual let's start with the command line arguments that I could use here: * **input_text**: the input text to translate, should come as a first mandatory argument. * **source_language**: The source language of the input text, should default to **fr** * **target_language**: The target language of the translation, should default to **en** * **inverse**: should allow swapping of the source/target languages for quick reverse translations. And that should be a good start already I believe. Let's now setup the component skeleton, with a simple command ''translate'': """TextTranslator module""" import logging import sys from deep_translator import GoogleTranslator from nvp.nvp_component import NVPComponent from nvp.nvp_context import NVPContext logger = logging.getLogger(__name__) class TextTranslator(NVPComponent): """TextTranslator component class""" def __init__(self, ctx: NVPContext, proj=None): """Component constructor""" NVPComponent.__init__(self, ctx) desc = { "translate": None, } ctx.define_subparsers("main", desc) psr = ctx.get_parser('main.translate') psr.add_argument("input_text", type=str, help="Input text to translate") psr.add_argument("-s", "--src", dest="source_language", type=str, default="fr", help="Source language to use") psr.add_argument("-t", "--tgt", dest="target_language", type=str, default="en", help="Target language to use") psr.add_argument("-i", "--inverse", dest="inverse", action='store_true', help="Swap src/tgt languages") def process_command(self, cmd0): """Re-implementation of process_command""" if cmd0 == 'translate': return self.translate() return False ===== Translate method implementation ===== And here is the translate method I quickly wrote on a first pass: def translate(self): """Translate the input text here.""" text = self.get_param("input_text") # logger.info("Should translate the input text '%s' here", text) src = self.get_param("source_language") tgt = self.get_param("target_language") translator = GoogleTranslator(source=src, target=tgt) result = translator.translate(text) # logger.info("Translation to %s:\n\"%s\"", tgt, result) sys.stdout.write(f"=> {result}\n") sys.stdout.flush() return True That is working great already: kenshin@Saturn /cygdrive/d/Projects/NervHome $ nvp translate "Salut Manu. Comment รงa va?" => Hi Manu. How's it going? ===== Adding support for language swapping ===== Now adding support to swap source/target languages: def translate(self): """Translate the input text here.""" text = self.get_param("input_text") # logger.info("Should translate the input text '%s' here", text) src = self.get_param("source_language") tgt = self.get_param("target_language") swap = self.get_param("inverse") if swap: src, tgt = tgt, src translator = GoogleTranslator(source=src, target=tgt) result = translator.translate(text) # logger.info("Translation to %s:\n\"%s\"", tgt, result) sys.stdout.write(f"=> {result}\n") sys.stdout.flush() return True And the result this time is: kenshin@Saturn /cygdrive/d/Projects/NervHome $ nvp translate -i "Hi Manu. How's it going?" => Salut Manou. Comment รงa va? Nobody called me "Manou" since a loooonnng time now, but appart from that we are all good already! So that's great ๐Ÿ‘! from there I thought about using the Linguee or Pons translators for single words, but Linguee gives me an exception, and PONS give me a large chunk of mixed english/french text for a single word, so it's a mess from my perspective lol **Conclusion**: let's just stop here for this first implementation, that's good enough for me and with that I can start testing translating my blog content myself (and then I'll see if I need to extend this tool further or not ;-)