diff options
| -rw-r--r-- | archaeological_operations/migrations/0071_auto_20191115_1650.py | 20 | ||||
| -rw-r--r-- | example_project/local_settings.py.sample | 3 | ||||
| -rw-r--r-- | example_project/settings.py | 6 | ||||
| -rw-r--r-- | ishtar_common/apps.py | 5 | ||||
| -rw-r--r-- | ishtar_common/models.py | 5 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 11 | ||||
| -rw-r--r-- | overload_translation/__init__.py | 1 | ||||
| -rw-r--r-- | overload_translation/admin.py | 13 | ||||
| -rw-r--r-- | overload_translation/migrations/0001_initial.py | 34 | ||||
| -rw-r--r-- | overload_translation/migrations/__init__.py | 0 | ||||
| -rw-r--r-- | overload_translation/models.py | 17 | ||||
| -rw-r--r-- | overload_translation/utils.py | 80 | 
12 files changed, 192 insertions, 3 deletions
| diff --git a/archaeological_operations/migrations/0071_auto_20191115_1650.py b/archaeological_operations/migrations/0071_auto_20191115_1650.py new file mode 100644 index 000000000..992142752 --- /dev/null +++ b/archaeological_operations/migrations/0071_auto_20191115_1650.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.18 on 2019-11-15 16:50 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_operations', '0070_auto_20190923_1408'), +    ] + +    operations = [ +        migrations.AlterField( +            model_name='culturalattributiontype', +            name='order', +            field=models.IntegerField(default=10, verbose_name='Order'), +        ), +    ] diff --git a/example_project/local_settings.py.sample b/example_project/local_settings.py.sample index f49963c84..555adb711 100644 --- a/example_project/local_settings.py.sample +++ b/example_project/local_settings.py.sample @@ -51,3 +51,6 @@ SRID = 27572  ENCODING = ''  # specific encoding for CSV export - default to utf-8  SURFACE_UNIT = 'square-metre'  SURFACE_UNIT_LABEL = u'm²' + +# translation overload can consume resources for a low profile machine +# USE_TRANSLATION_OVERLOAD = True diff --git a/example_project/settings.py b/example_project/settings.py index 65ca93395..b858c5907 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -170,6 +170,9 @@ INSTALLED_APPS = [      # 'debug_toolbar',  ] +USE_TRANSLATION_OVERLOAD = True +TRANSLATION_OVERLOAD_DEBUG = False +  MAIN_APP = ""  LOGFILE = '' @@ -294,6 +297,9 @@ except ImportError as e:      except ImportError as e:          print('Unable to load local_settings.py:', e) +if USE_TRANSLATION_OVERLOAD: +    INSTALLED_APPS.insert(0, 'overload_translation') +  if "SECRET_KEY" not in globals():  # explicit import from the root for celery      current_path = os.path.abspath(__file__)      current_dir_path = os.path.dirname(current_path).split(os.sep)[-1] diff --git a/ishtar_common/apps.py b/ishtar_common/apps.py index 56768bc51..41dce9300 100644 --- a/ishtar_common/apps.py +++ b/ishtar_common/apps.py @@ -15,6 +15,11 @@ class IshtarAdminSite(AdminSite):  admin_site = IshtarAdminSite(name='ishtaradmin') +class TranslationOverloadConfig(AppConfig): +    name = "overload_translation" +    verbose_name = _("Translation - Overload") + +  class ArchaeologicalContextRecordConfig(AppConfig):      name = 'archaeological_context_records'      verbose_name = _("Ishtar - Context record") diff --git a/ishtar_common/models.py b/ishtar_common/models.py index f6ed81f9c..e7f0e9262 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -68,8 +68,9 @@ from django.db.utils import DatabaseError  from django.template.defaultfilters import slugify  from django.utils.functional import lazy  from django.utils.safestring import SafeText, mark_safe -from django.utils.translation import ugettext_lazy as _, ugettext, \ -    pgettext_lazy, activate, deactivate +from django.utils.translation import activate, deactivate +from ishtar_common.utils import ugettext_lazy as _, ugettext, \ +    pgettext_lazy  from ishtar_common.utils_secretary import IshtarSecretaryRenderer  from simple_history.models import HistoricalRecords as BaseHistoricalRecords  from unidecode import unidecode diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index d446a381a..d828e79cd 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -55,10 +55,19 @@ from django.db import models  from django.http import HttpResponseRedirect  from django.utils.datastructures import MultiValueDict as BaseMultiValueDict  from django.utils.safestring import mark_safe -from django.utils.translation import ugettext_lazy as _, ugettext  from django.template.defaultfilters import slugify +if settings.USE_TRANSLATION_OVERLOAD: +    from overload_translation.utils import ugettext_lazy, ugettext, \ +        pgettext_lazy, pgettext +else: +    from django.utils.translation import ugettext_lazy, ugettext, \ +        pgettext_lazy, pgettext + +_ = ugettext_lazy + +  def dict_to_tuple(dct):      values = []      for k, v in dct.items(): diff --git a/overload_translation/__init__.py b/overload_translation/__init__.py new file mode 100644 index 000000000..e9e41546e --- /dev/null +++ b/overload_translation/__init__.py @@ -0,0 +1 @@ +default_app_config = 'ishtar_common.apps.TranslationOverloadConfig' diff --git a/overload_translation/admin.py b/overload_translation/admin.py new file mode 100644 index 000000000..85f7543cd --- /dev/null +++ b/overload_translation/admin.py @@ -0,0 +1,13 @@ +from django.contrib import admin + +from overload_translation import models +from ishtar_common.apps import admin_site + + +class TranslationOverloadAdmin(admin.ModelAdmin): +    list_display = ("message", "context", "lang", "translation") +    list_filter = ("lang",) +    search_fields = ("message", "context") + + +admin_site.register(models.TranslationOverload, TranslationOverloadAdmin) diff --git a/overload_translation/migrations/0001_initial.py b/overload_translation/migrations/0001_initial.py new file mode 100644 index 000000000..33e2732ad --- /dev/null +++ b/overload_translation/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.18 on 2019-11-15 17:48 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    initial = True + +    dependencies = [ +    ] + +    operations = [ +        migrations.CreateModel( +            name='TranslationOverload', +            fields=[ +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), +                ('message', models.TextField(verbose_name='String')), +                ('context', models.CharField(blank=True, default='', max_length=256, verbose_name='Translation context')), +                ('translation', models.TextField(verbose_name='Translation')), +                ('lang', models.CharField(choices=[('fr', 'Français'), ('en', 'English')], max_length=4, verbose_name='Language')), +            ], +            options={ +                'verbose_name_plural': 'Translations overload', +                'verbose_name': 'Translation overload', +            }, +        ), +        migrations.AlterUniqueTogether( +            name='translationoverload', +            unique_together=set([('message', 'lang', 'context')]), +        ), +    ] diff --git a/overload_translation/migrations/__init__.py b/overload_translation/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/overload_translation/migrations/__init__.py diff --git a/overload_translation/models.py b/overload_translation/models.py new file mode 100644 index 000000000..723c22836 --- /dev/null +++ b/overload_translation/models.py @@ -0,0 +1,17 @@ +from django.conf import settings +from django.db import models +from django.utils.translation import ugettext_lazy as _ + + +class TranslationOverload(models.Model): +    message = models.TextField(_("String")) +    context = models.CharField(_("Translation context"), max_length=256, +                               default="", blank=True) +    translation = models.TextField(_("Translation")) +    lang = models.CharField(_("Language"), choices=settings.LANGUAGES, +                            max_length=4) + +    class Meta: +        verbose_name = _("Translation overload") +        verbose_name_plural = _("Translations overload") +        unique_together = ("message", "lang", "context") diff --git a/overload_translation/utils.py b/overload_translation/utils.py new file mode 100644 index 000000000..1b7c04cdd --- /dev/null +++ b/overload_translation/utils.py @@ -0,0 +1,80 @@ +from django.conf import settings +from django.core.cache import cache +from django.db.utils import DatabaseError +from django.utils.functional import lazy +from django.utils.translation import ugettext as _, pgettext as _p, get_language + +import hashlib + +from overload_translation import models + + +NO_VALUE = "<<no-value>>" + + +def simple_trans(message, context): +    if context: +        s = _p(context, message) +    else: +        s = _(message) +    if not settings.TRANSLATION_OVERLOAD_DEBUG: +        return s +    s += " - message:\"{}\"".format( +        message.replace("{", "OPEN-BRACES").replace("}", "CLOSE-BRACES")) +    if context: +        s += " - context:\"{}\"".format(context) +    return s + + +def ugettext(message, context=""): +    has_translation_key = "{}-has-dynamic-translation".format( +        settings.PROJECT_SLUG) +    has_translations = cache.get(has_translation_key) +    if has_translations is False: +        return simple_trans(message, context) +    elif has_translations is None: +        if models.TranslationOverload.objects.count(): +            cache.set(has_translation_key, True, settings.CACHE_TIMEOUT) +        else: +            cache.set(has_translation_key, False, settings.CACHE_TIMEOUT) +            return simple_trans(message, context) +    current_language = get_language() +    if not current_language: +        return simple_trans(message, context) +    current_context = current_language +    if context: +        current_context += "-" + context +    key = "{}-translation-{}-{}".format(settings.PROJECT_SLUG, +                                        current_context, message) + +    m = hashlib.md5() +    m.update(key.encode('utf-8')) +    key = m.hexdigest() +    value = cache.get(key) +    if value == NO_VALUE: +        return simple_trans(message, context) +    elif value: +        return value +    try: +        q = models.TranslationOverload.objects.filter( +            lang=current_language, message=message, context=context) +        nb = q.count() +    except DatabaseError: +        cache.set(key, NO_VALUE, settings.CACHE_TIMEOUT) +        return simple_trans(message, context) +    if not nb: +        cache.set(key, NO_VALUE, settings.CACHE_TIMEOUT) +        return simple_trans(message, context) +    value = q.values_list("translation", flat=True).all()[0] +    cache.set(key, value, settings.CACHE_TIMEOUT) +    return value + + +ugettext_lazy = lazy(ugettext, str) + + +def pgettext(context, message): +    return ugettext(message, context=context) + + +pgettext_lazy = lazy(pgettext, str)
\ No newline at end of file | 
