def create_terminology_project()

in pontoon/base/migrations/0005_add_terminology_project.py [0:0]


def create_terminology_project(apps, schema_editor):
    # Collect localizable term data to create entities and translations from
    Term = apps.get_model("terminology", "Term")
    TermTranslation = apps.get_model("terminology", "TermTranslation")
    terms = (
        Term.objects.filter(do_not_translate=False, forbidden=False)
        .exclude(definition="")
        .order_by("text")
    )
    term_translations = TermTranslation.objects.filter(term__in=terms)

    Locale = apps.get_model("base", "Locale")
    locales = Locale.objects.exclude(code__in=["en-US", "en"]).annotate(
        term_count=Count("terms")
    )

    # Create the "Terminology" project
    Project = apps.get_model("base", "Project")
    kwargs = {
        "slug": "terminology",
        "name": "Terminology",
        "data_source": "database",
        "can_be_requested": False,
        "sync_disabled": True,
        "visibility": "public",
        "total_strings": len(terms) * len(locales),
        "approved_strings": len(term_translations),
        "info": "A project used to localize terminology.",
        "admin_notes": "Do not remove, this is required for terminology localization.",
    }
    try:
        project = Project.objects.create(**kwargs)
    except IntegrityError:
        log.error(
            """Unable to create the Terminology project. If you already have a project with name "Terminology" or slug "terminology", please change it's name or slug."""
        )
        raise

    # Add a resource
    Resource = apps.get_model("base", "Resource")
    resource, _ = Resource.objects.get_or_create(
        path="common", project=project, total_strings=len(terms)
    )

    # Create entities from Terms
    Entity = apps.get_model("base", "Entity")
    entities = []

    for index, term in enumerate(terms):
        comment = "{}. {}.".format(
            term.part_of_speech.capitalize(),
            term.definition.capitalize().rstrip("."),
        )
        if term.usage:
            comment += " E.g. {}.".format(term.usage.capitalize().rstrip("."))

        entities.append(
            Entity(string=term.text, comment=comment, resource=resource, order=index)
        )

    created_entities = Entity.objects.bulk_create(entities)

    # Create Entity-Term OneToOne relationship
    for index, term in enumerate(terms):
        term.entity_id = created_entities[index].id
        term.save()

    # Create translations from Term Translations
    Translation = apps.get_model("base", "Translation")

    translations = [
        Translation(
            string=translation.text,
            entity=translation.term.entity,
            locale=translation.locale,
            active=True,
            approved=True,
        )
        for translation in term_translations
    ]

    Translation.objects.bulk_create(translations)

    # Enable project for all localizable locales
    ProjectLocale = apps.get_model("base", "ProjectLocale")
    TranslatedResource = apps.get_model("base", "TranslatedResource")

    counts = {}
    for locale in locales:
        counts[locale.code] = locale.term_count

    project_locales = [
        ProjectLocale(
            project=project,
            locale=locale,
            total_strings=len(terms),
            approved_strings=counts[locale.code],
        )
        for locale in locales
    ]
    translated_resources = [
        TranslatedResource(
            resource=resource,
            locale=locale,
            total_strings=len(terms),
            approved_strings=counts[locale.code],
        )
        for locale in locales
    ]

    ProjectLocale.objects.bulk_create(project_locales)
    TranslatedResource.objects.bulk_create(translated_resources)

    # Update locale stats
    for locale in locales:
        locale.total_strings += len(terms)
        locale.approved_strings += counts[locale.code]

    Locale.objects.bulk_update(
        list(locales),
        [
            "total_strings",
            "approved_strings",
        ],
    )