Source code for django_amazon_translate.translator

import re

import boto3
from django.db import models
from modeltranslation.settings import AVAILABLE_LANGUAGES, DEFAULT_LANGUAGE
from modeltranslation.translator import translator
from modeltranslation.utils import build_localized_fieldname


class _amazonTranslate(object):
    def __init__(self, client=None):
        self.translate = client or boto3.client('translate')

    def translate_text(self, text, source_language, dest_language):
        return self.translate.translate_text(
                            Text=text,
                            SourceLanguageCode=source_language,
                            TargetLanguageCode=dest_language
        )


[docs]def get_translate_client(): """ Return an Amazon Translate object for doing translation. We wrap this because then we can mock it during tests. """ return _amazonTranslate()
[docs]def translate_po_file(po, language): """ Update a given .po file with translated strings from Amazon Translate. """ # Get a client for translations translate = get_translate_client() for s in po.untranslated_entries(): # We replace the formatting specifiers with something # that Amazon Translate will just assume is a title and # not translate. subbed_message = re.sub( r"%\((\w+)\)s", r"FORMAT_\1_END", s.msgid ) # Translate the text itself response = translate.translate_text( subbed_message, "en", language, ) # Put back the correct gettext formatting s.msgstr = re.sub( r"FORMAT_(\w+)_END", r"%(\1)s", response['TranslatedText'] ) return po
[docs]class TranslationTracker(object): """ Django Model addition/plugin to provide automated translations in conjunction with modeltranslation and Amazon Translate Add to a model doing something like:: class MyModel(models.Model): tt = TranslationTracker() """
[docs] def contribute_to_class(self, cls, name): self.name = name models.signals.class_prepared.connect(self.finalize_class, sender=cls)
[docs] def finalize_class(self, sender, **kwargs): self.model_class = sender setattr(sender, self.name, self) self.patch_save(sender)
[docs] @staticmethod def patch_save(model): original_save = model.save def save(instance, *args, **kwargs): translate = get_translate_client() cls = instance.__class__ old = cls.objects.filter(pk=instance.pk).first() new = instance opts = translator.get_options_for_model(cls) # Loop through the fields and work out what actually changed changed_fields = [] if old: for field in cls._meta.get_fields(): field_name = field.name if getattr(old, field_name) != getattr(new, field_name): changed_fields.append(field_name) # Go through each translatable field for field_name in opts.fields.keys(): def_lang_fieldname = build_localized_fieldname( field_name, DEFAULT_LANGUAGE ) for lang in AVAILABLE_LANGUAGES: if lang == DEFAULT_LANGUAGE: continue lang_fieldname = build_localized_fieldname( field_name, lang ) # If they updated the translation as well as # the source. if lang_fieldname in changed_fields: continue if ( def_lang_fieldname in changed_fields or not getattr(new, def_lang_fieldname) or not old ): r = translate.translate_text( getattr(new, def_lang_fieldname), DEFAULT_LANGUAGE, lang ) setattr(new, lang_fieldname, r['TranslatedText']) return original_save(instance, *args, **kwargs) model.save = save