diff --git a/docs/changes.rst b/docs/changes.rst index d99ae92e6640..7b3576fd3b73 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -9,6 +9,8 @@ Not yet released. **Bug fixes** +* Update outdated plural definitions during the database migration. + **Compatibility** **Upgrading** diff --git a/pyproject.toml b/pyproject.toml index 43e90eac38be..9a7bd7fa4746 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,7 +84,7 @@ dependencies = [ "translate-toolkit>=3.14.1,<3.15", "translation-finder>=2.16,<3.0", "user-agents>=2.0,<2.3", - "weblate-language-data>=2024.6", + "weblate-language-data>=2024.9", "weblate-schemas==2024.1" ] description = "A web-based continuous localization system with tight version control integration" diff --git a/weblate/lang/models.py b/weblate/lang/models.py index 3ff5eb5fb93a..4d57f5400db6 100644 --- a/weblate/lang/models.py +++ b/weblate/lang/models.py @@ -30,6 +30,7 @@ from weblate.checks.format import BaseFormatCheck from weblate.checks.models import CHECKS from weblate.lang import data +from weblate.lang.data import FORMULA_WITH_ZERO from weblate.logger import LOGGER from weblate.trans.defines import LANGUAGE_CODE_LENGTH, LANGUAGE_NAME_LENGTH from weblate.trans.mixins import CacheKeyMixin @@ -460,7 +461,7 @@ def default_language(self): """Return English language object.""" return self.get(code=settings.DEFAULT_LANGUAGE, skip_cache=True) - def setup(self, update, logger=lambda x: x) -> None: + def setup(self, update, logger=lambda x: x) -> None: # noqa: C901 """ Create basic set of languages. @@ -472,7 +473,7 @@ def setup(self, update, logger=lambda x: x) -> None: # Invalidate cache, we might change languages self.flush_object_cache() languages = {language.code: language for language in self.prefetch()} - plurals: dict[str, dict[int, list[str]]] = {} + plurals: dict[str, dict[int, list[Plural]]] = {} # Create Weblate languages for code, name, nplurals, plural_formula in LANGUAGES: population = POPULATION[code] @@ -555,8 +556,35 @@ def setup(self, update, logger=lambda x: x) -> None: formula=plural_formula, type=get_plural_type(lang.base_code, plural_formula), ) + plurals[code][source].append(plural) logger(f"Created plural {plural_formula} for language {code}") + # CLDR and QT plurals should have just a single of them + if source != Plural.SOURCE_GETTEXT and len(plurals[code][source]) > 1: + logger( + f"Removing extra {source} plurals for language {code} ({len(plurals[code][source])})!" + ) + for extra_plural in plurals[code][source]: + if extra_plural != plural: + extra_plural.translation_set.update(plural=plural) + extra_plural.delete() + plurals[code][source] = [plural] + + # Sync FORMULA_WITH_ZERO + for code, language_plurals in plurals.items(): + if Plural.SOURCE_CLDR_ZERO in language_plurals: + if Plural.SOURCE_CLDR not in language_plurals: + logger(f"Missing CLDR plural for {code}!") + continue + zero_plural = language_plurals[Plural.SOURCE_CLDR_ZERO][0] + cldr_plural = language_plurals[Plural.SOURCE_CLDR][0] + current_formula = FORMULA_WITH_ZERO[cldr_plural.formula] + if zero_plural.formula != current_formula: + logger(f"Updating CLDR plural with zero for {code}") + zero_plural.formula = current_formula + zero_plural.number = cldr_plural.number + 1 + zero_plural.save(update_fields=["formula", "number"]) + self._fixup_plural_types(logger) def _fixup_plural_types(self, logger) -> None: