def manage_project()

in pontoon/administration/views.py [0:0]


def manage_project(request, slug=None, template="admin_project.html"):
    """Admin project."""
    log.debug("Admin project.")

    if not request.user.has_perm("base.can_manage_project"):
        raise PermissionDenied

    form = ProjectForm()
    repo_formset = RepositoryInlineFormSet()
    external_resource_formset = ExternalResourceInlineFormSet()
    tag_formset = TagInlineFormSet()
    locales_readonly = Locale.objects.none()
    locales_selected = Locale.objects.none()
    locales_pretranslate = Locale.objects.none()
    subtitle = "Add project"
    pk = None
    project = None

    # Save project
    if request.method == "POST":
        locales_readonly = Locale.objects.filter(
            pk__in=request.POST.getlist("locales_readonly")
        )
        locales_selected = Locale.objects.filter(
            pk__in=request.POST.getlist("locales")
        ).exclude(pk__in=locales_readonly)
        locales_pretranslate = Locale.objects.filter(
            pk__in=request.POST.getlist("locales_pretranslate")
        )

        # Update existing project
        try:
            pk = request.POST["pk"]
            project = Project.objects.visible_for(request.user).get(pk=pk)
            form = ProjectForm(request.POST, instance=project)
            # Needed if form invalid
            repo_formset = RepositoryInlineFormSet(request.POST, instance=project)
            tag_formset = (
                TagInlineFormSet(request.POST, instance=project)
                if project.tags_enabled
                else None
            )
            external_resource_formset = ExternalResourceInlineFormSet(
                request.POST, instance=project
            )
            subtitle = "Edit project"

        # Add a new project
        except MultiValueDictKeyError:
            form = ProjectForm(request.POST)
            # Needed if form invalid
            repo_formset = RepositoryInlineFormSet(request.POST)
            external_resource_formset = ExternalResourceInlineFormSet(request.POST)
            tag_formset = None

        if form.is_valid():
            project = form.save(commit=False)
            repo_formset = RepositoryInlineFormSet(request.POST, instance=project)
            external_resource_formset = ExternalResourceInlineFormSet(
                request.POST, instance=project
            )
            if tag_formset:
                tag_formset = TagInlineFormSet(request.POST, instance=project)
            formsets_valid = (
                repo_formset.is_valid()
                and external_resource_formset.is_valid()
                and (tag_formset.is_valid() if tag_formset else True)
            )
            if formsets_valid:
                project.save()

                # Manually save ProjectLocales due to intermediary model
                locales_form = form.cleaned_data.get("locales", [])
                locales_readonly_form = form.cleaned_data.get("locales_readonly", [])
                locales = locales_form | locales_readonly_form

                (
                    ProjectLocale.objects.filter(project=project)
                    .exclude(locale__pk__in=[loc.pk for loc in locales])
                    .delete()
                )

                for locale in locales:
                    # The implicit pre_save and post_save signals sent here are required
                    # to maintain django-guardian permissions.
                    ProjectLocale.objects.get_or_create(project=project, locale=locale)

                project_locales = ProjectLocale.objects.filter(project=project)

                # Update readonly flags
                locales_readonly_pks = [loc.pk for loc in locales_readonly_form]
                project_locales.exclude(locale__pk__in=locales_readonly_pks).update(
                    readonly=False
                )
                project_locales.filter(locale__pk__in=locales_readonly_pks).update(
                    readonly=True
                )

                # Update pretranslate flags
                locales_pretranslate_form = form.cleaned_data.get(
                    "locales_pretranslate", []
                )
                locales_pretranslate_pks = [loc.pk for loc in locales_pretranslate_form]
                project_locales.exclude(locale__pk__in=locales_pretranslate_pks).update(
                    pretranslation_enabled=False
                )
                project_locales.filter(locale__pk__in=locales_pretranslate_pks).update(
                    pretranslation_enabled=True
                )

                repo_formset.save()
                external_resource_formset.save()
                if tag_formset:
                    tag_formset.save()

                # If the data source is database and there are new strings, save them.
                if project.data_source == Project.DataSource.DATABASE:
                    _save_new_strings(project, request.POST.get("new_strings", ""))
                    _create_or_update_translated_resources(project, locales)

                # Properly displays formsets, but removes errors (if valid only)
                repo_formset = RepositoryInlineFormSet(instance=project)
                external_resource_formset = ExternalResourceInlineFormSet(
                    instance=project
                )
                if project.tags_enabled:
                    tag_formset = TagInlineFormSet(instance=project)
                subtitle += ". Saved."
                pk = project.pk
            else:
                subtitle += ". Error."
        else:
            subtitle += ". Error."

    # If URL specified and found, show edit, otherwise show add form
    elif slug is not None:
        try:
            project = Project.objects.get(slug=slug)
            pk = project.pk
            form = ProjectForm(instance=project)
            repo_formset = RepositoryInlineFormSet(instance=project)
            tag_formset = (
                TagInlineFormSet(instance=project) if project.tags_enabled else None
            )
            external_resource_formset = ExternalResourceInlineFormSet(instance=project)
            locales_readonly = Locale.objects.filter(
                project_locale__readonly=True,
                project_locale__project=project,
            )
            locales_selected = project.locales.exclude(pk__in=locales_readonly)
            locales_pretranslate = Locale.objects.filter(
                project_locale__pretranslation_enabled=True,
                project_locale__project=project,
            )
            subtitle = "Edit project"
        except Project.DoesNotExist:
            form = ProjectForm(initial={"slug": slug})

    # Override default label suffix
    form.label_suffix = ""

    projects = sorted([p.name for p in Project.objects.all()])

    locales_available = Locale.objects.exclude(pk__in=locales_readonly).exclude(
        pk__in=locales_selected
    )

    locales_pretranslate_available = locales_selected.exclude(
        pk__in=locales_pretranslate
    )

    # Admins reason in terms of locale codes (see bug 1394194)
    locales_readonly = locales_readonly.order_by("code")
    locales_selected = locales_selected.order_by("code")
    locales_available = locales_available.order_by("code")
    locales_pretranslate = locales_pretranslate.order_by("code")
    locales_pretranslate_available = locales_pretranslate_available.order_by("code")

    data = {
        "slug": slug,
        "form": form,
        "repo_formset": repo_formset,
        "tag_formset": tag_formset,
        "external_resource_formset": external_resource_formset,
        "locales_readonly": locales_readonly,
        "locales_selected": locales_selected,
        "locales_available": locales_available,
        "locales_pretranslate": locales_pretranslate,
        "locales_pretranslate_available": locales_pretranslate_available,
        "subtitle": subtitle,
        "pk": pk,
        "project": project,
        "projects": projects,
    }

    # Set locale in Translate link
    if Resource.objects.filter(project=project).exists() and locales_selected:
        locale = (
            utils.get_project_locale_from_request(request, project.locales)
            or locales_selected[0].code
        )
        if locale:
            data["translate_locale"] = locale

    return render(request, template, data)