from django.conf import settings from django.core.cache import cache from django.db import connection from django.db.utils import DatabaseError from django.utils.functional import lazy from django.utils.translation import gettext as _, pgettext as _p, get_language import hashlib from overload_translation import models NO_VALUE = "<>" def check_db_is_init(): """ Not yet initialized for first migrations """ with connection.cursor() as cursor: sql = """SELECT EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_name = 'overload_translation_translationoverload');""" cursor.execute(sql) res = cursor.fetchall() return res and res[0][0] def check_has_translations(): if not check_db_is_init(): return False try: nb = models.TranslationOverload.objects.count() except DatabaseError: return False has_translation_key = "{}-has-dynamic-translation".format( settings.PROJECT_SLUG) if not nb: cache.set(has_translation_key, False, settings.CACHE_TIMEOUT) return False cache.set(has_translation_key, True, settings.CACHE_TIMEOUT) return True 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 gettext(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 not check_has_translations(): 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 gettext_lazy = lazy(gettext, str) def pgettext(context, message): return gettext(message, context=context) pgettext_lazy = lazy(pgettext, str)