text: from __future__ import unicode_literals
  
  from django.shortcuts import get_object_or_404, redirect
  from django.contrib import messages
  from django.utils.translation import ugettext as _
  from django.utils.http import is_safe_url
  from django.views.generic import RedirectView, FormView
  from django.core.exceptions import PermissionDenied
  
  from widgy.utils import format_html
  from widgy.views.base import AuthorizedMixin
  from widgy.views.versioning import VersionTrackerMixin, CommitView, HistoryView as OldHistoryView
  
  from .forms import UndoApprovalsForm, ReviewedCommitForm
  from .models import ReviewedVersionCommit
  
  
  class ReviewedCommitView(CommitView):
      template_name = 'review_queue/commit.html'
  
      def get_form_class(self):
          if self.site.has_change_permission(self.request, ReviewedVersionCommit):
              return ReviewedCommitForm
          else:
              return super(ReviewedCommitView, self).get_form_class()
  
  
  class ApprovalChangeBaseView(AuthorizedMixin, VersionTrackerMixin, RedirectView):
      """
      Abstract class for approving or unapproving commits
      """
      http_method_names = ['post']
      permanent = False
  
      def get_redirect_url(self, pk, commit_pk):
          vt = get_object_or_404(self.get_queryset(), pk=pk)
          commit = get_object_or_404(vt.commits.select_related('root_node'),
                                     pk=commit_pk)
          commit.tracker = vt
  
          if not self.site.has_change_permission(self.request, commit.reviewedversioncommit):
              raise PermissionDenied(_("You don't have permission to approve commits."))
  
          self.action(commit)
  
          history_url = self.site.reverse(self.site.history_view, kwargs={
              'pk': vt.pk
          })
  
          messages.success(self.request, self.get_message(commit, history_url))
  
          return history_url
  
      def action(self, commit):
          raise NotImplementedError("action should be implemented in subclass")
  
      def get_message(self, commit, history_url):
          raise NotImplementedError("get_message should be implemented in subclass")
  
  
  class ApproveView(ApprovalChangeBaseView):
      def action(self, commit):
          commit.reviewedversioncommit.approve(self.request.user)
          commit.save()
  
      def get_message(self, commit, history_url):
          # XXX: Avoid circular import
          from .admin import HTML_IN_MESSAGES
  
          message = _('Commit %s has been approved') % commit
          if HTML_IN_MESSAGES:
              message = format_html('{0} {1}',
                  message,
                  UndoApprovalsForm(
                      initial={
                          'actions': [commit.pk],
                          'referer': history_url,
                      }
                  ).render(self.request, self.site)
              )
          return message
  
  
  class UnapproveView(ApprovalChangeBaseView):
      def action(self, commit):
          commit.reviewedversioncommit.unapprove(self.request.user)
          commit.save()
  
      def get_message(self, commit, history_url):
          return _('Commit %s has been unapproved.') % commit
  
  
  class UndoApprovalsView(AuthorizedMixin, FormView):
      http_method_names = ['post']
      form_class = UndoApprovalsForm
  
      def form_valid(self, form):
          approved_commits = form.cleaned_data['actions']
          if not isinstance(approved_commits, list) or \
             not all(isinstance(i, int) for i in approved_commits):
              return self.form_invalid()
  
          commits = ReviewedVersionCommit.objects.filter(pk__in=approved_commits)
  
          if not all(self.site.has_change_permission(self.request, c) for c in commits):
              raise PermissionDenied(_("You don't have permission to approve commits."))
  
          for c in commits:
              c.unapprove(self.request.user)
          url = form.cleaned_data['referer']
          if not is_safe_url(url=url, host=self.request.get_host()):
              url = '/'
          return redirect(url)
  
      def form_invalid(self, form):
          return redirect('/')
  
  
  class HistoryView(OldHistoryView):
      def get_context_data(self, **kwargs):
          kwargs = super(HistoryView, self).get_context_data(**kwargs)
          # it's not useful to approve/unapprove commits past the latest approved
          # commit
          interesting = True
          for commit in kwargs['commits']:
              commit.is_interesting_to_approve_or_unapprove = interesting
              interesting &= not self.object.commit_is_ready(commit)
          return kwargs
  