from django.contrib import messages from django.contrib.admin.utils import unquote from django.core.exceptions import PermissionDenied from django.db import transaction from django.http import Http404 from django.shortcuts import get_object_or_404, redirect from django.urls import reverse from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy from django.views.generic import TemplateView from django.views.generic.detail import SingleObjectMixin from wagtail.actions.copy_for_translation import CopyPageForTranslationAction from wagtail.models import DraftStateMixin, Page, TranslatableMixin from wagtail.snippets.views.snippets import get_snippet_model_from_url_params from .forms import SubmitTranslationForm class SubmitTranslationView(SingleObjectMixin, TemplateView): template_name = "simple_translation/admin/submit_translation.html" title = gettext_lazy("Translate") def get_title(self): return self.title def get_subtitle(self): return str(self.object) def get_form(self): if self.request.method == "POST": return SubmitTranslationForm(self.object, self.request.POST) return SubmitTranslationForm(self.object) def get_success_url(self, translated_object=None): raise NotImplementedError def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context.update( { "form": self.get_form(), } ) return context def post(self, request, **kwargs): # pragma: no mccabe form = self.get_form() if form.is_valid(): include_subtree = form.cleaned_data["include_subtree"] user = request.user with transaction.atomic(): for locale in form.cleaned_data["locales"]: if isinstance(self.object, Page): action = CopyPageForTranslationAction( page=self.object, locale=locale, include_subtree=include_subtree, user=user, ) action.execute(skip_permission_checks=True) else: self.object.copy_for_translation( locale ).save() # pragma: no cover single_translated_object = None if len(form.cleaned_data["locales"]) == 1: locales = form.cleaned_data["locales"][0].get_display_name() single_translated_object = self.object.get_translation( form.cleaned_data["locales"][0] ) else: # Translators: always plural locales = _("%(locales_count)s locales") % { "locales_count": len(form.cleaned_data["locales"]) } messages.success(self.request, self.get_success_message(locales)) return redirect(self.get_success_url(single_translated_object)) context = self.get_context_data(**kwargs) return self.render_to_response(context) def dispatch(self, request, *args, **kwargs): if not request.user.has_perms(["simple_translation.submit_translation"]): raise PermissionDenied self.object = self.get_object() return super().dispatch(request, *args, **kwargs) class SubmitPageTranslationView(SubmitTranslationView): title = gettext_lazy("Translate page") def get_subtitle(self): return self.object.get_admin_display_title() def get_object(self): page = get_object_or_404(Page, id=self.kwargs["page_id"]).specific # Can't translate the root page if page.is_root(): raise Http404 return page def get_success_url(self, translated_page=None): if translated_page: # If the editor chose a single locale to translate to, redirect to # the newly translated page's edit view. return reverse("wagtailadmin_pages:edit", args=[translated_page.id]) return reverse("wagtailadmin_explore", args=[self.get_object().get_parent().id]) def get_success_message(self, locales): return _( "The page '%(page_title)s' was successfully created in %(locales)s" ) % {"page_title": self.object.get_admin_display_title(), "locales": locales} class SubmitSnippetTranslationView(SubmitTranslationView): def get_title(self): return _("Translate %(model_name)s") % { "model_name": self.object._meta.verbose_name } def get_object(self): model = get_snippet_model_from_url_params( self.kwargs["app_label"], self.kwargs["model_name"] ) if not issubclass(model, TranslatableMixin): raise Http404 object = get_object_or_404(model, pk=unquote(str(self.kwargs["pk"]))) if isinstance(object, DraftStateMixin): object = object.get_latest_revision_as_object() return object def get_success_url(self, translated_snippet=None): pk = self.kwargs["pk"] if translated_snippet: # If the editor chose a single locale to translate to, redirect to # the newly translated snippet's edit view. pk = translated_snippet.pk return reverse(self.object.snippet_viewset.get_url_name("edit"), args=[pk]) def get_success_message(self, locales): return _("Successfully created %(locales)s for %(model_name)s '%(object)s'") % { "model_name": self.object._meta.verbose_name, "object": str(self.object), "locales": locales, }