def form_valid(self, form):
        instance = form.save(self.request)
        user = None
        if self.request.user.is_authenticated():
            user = self.request.user
            LoggedAction.objects.create(
                user=user,
                action_type='record-council-result',
                ip_address=get_client_ip(self.request),
                source=form['source'].value(),
                post=form.post,
            )

        if 'report_and_confirm' in self.request.POST:
            instance.review_status = CONFIRMED_STATUS
            instance.save()
            if self.request.user.is_authenticated():
                user = self.request.user
                LoggedAction.objects.create(
                    user=user,
                    action_type='confirm-council-result',
                    ip_address=get_client_ip(self.request),
                    source="Confirmed when reporting",
                    post=form.post,
                )

        return super(PostReportVotesView, self).form_valid(form)
    def form_valid(self, form):
        instance = form.save(self.request)
        user = None
        if self.request.user.is_authenticated():
            user = self.request.user
            LoggedAction.objects.create(
                user=user,
                action_type='record-council-result',
                ip_address=get_client_ip(self.request),
                source=form['source'].value(),
                post=form.post,
            )

        if 'report_and_confirm' in self.request.POST:
            instance.review_status = CONFIRMED_STATUS
            instance.save()
            if self.request.user.is_authenticated():
                user = self.request.user
                LoggedAction.objects.create(
                    user=user,
                    action_type='confirm-council-result',
                    ip_address=get_client_ip(self.request),
                    source="Confirmed when reporting",
                    post=form.post,
                )

        return super(PostReportVotesView, self).form_valid(form)
Exemple #3
0
    def form_valid(self, form):
        with transaction.atomic():
            ballot = form.instance

            self.object = form.save()
            if hasattr(ballot, "rawpeople"):
                # Delete the raw import, as it's no longer useful
                self.object.rawpeople.delete()

            lock = self.object.candidates_locked
            post_name = ballot.post.short_label
            if lock:
                suffix = "-lock"
                pp = "Locked"
                # If we're locking this, then the suggested posts
                # can be deleted
                ballot.suggestedpostlock_set.all().delete()
            else:
                suffix = "-unlock"
                pp = "Unlocked"
            message = pp + " ballot {} ({})".format(post_name,
                                                    ballot.ballot_paper_id)

            LoggedAction.objects.create(
                user=self.request.user,
                action_type="constituency-{}".format(suffix),
                ip_address=get_client_ip(self.request),
                ballot=ballot,
                source=message,
            )
        if self.request.is_ajax():
            return JsonResponse({"locked": ballot.candidates_locked})
        else:
            return HttpResponseRedirect(ballot.get_absolute_url())
    def save(self, request):
        instance = super(ResultSetForm, self).save(commit=False)
        instance.post_result = self.post_result
        instance.user = request.user if \
            request.user.is_authenticated() else None
        instance.ip_address = get_client_ip(request)
        instance.save(request)

        winner_count = self.memberships[0][0]\
            .extra.election.postextraelection_set.filter(
                postextra=self.memberships[0][0].post.extra)[0].winner_count

        winners = dict(sorted(
            [("{}-{}".format(self[y].value(), x.person.id), x)
                for x, y in self.memberships],
            reverse=True,
            key=lambda votes: int(votes[0].split('-')[0])
        )[:winner_count])

        for membership, field_name in self.memberships:
            instance.candidate_results.create(
                membership=membership,
                is_winner=bool(membership in winners.values()),
                num_ballots_reported=self[field_name].value(),
            )

        if instance.review_status == CONFIRMED_STATUS:
            with transaction.atomic():
                self.mark_candidates_as_winner(request, instance)

        return instance
Exemple #5
0
 def form_valid(self, form):
     form.save()
     LoggedAction.objects.create(user=self.request.user,
                                 action_type='confirm-council-control',
                                 ip_address=get_client_ip(self.request),
                                 source=form['review_source'].value())
     return super(ConfirmControl, self).form_valid(form)
    def add_person(self, person_data):
        # TODO Move this out of the view layer
        person = Person.objects.create(name=person_data['name'])
        person_extra = PersonExtra.objects.create(base=person)
        check_creation_allowed(
            self.request.user, person_extra.current_candidacies
        )

        change_metadata = get_change_metadata(
            self.request, person_data['source']
        )

        person_extra.record_version(change_metadata)
        person_extra.save()

        LoggedAction.objects.create(
            user=self.request.user,
            person=person,
            action_type='person-create',
            ip_address=get_client_ip(self.request),
            popit_person_new_version=change_metadata['version_id'],
            source=change_metadata['information_source'],
        )

        # Add a message to be displayed after redirect:
        messages.add_message(
            self.request,
            messages.SUCCESS,
            get_call_to_action_flash_message(person, new_person=True),
            extra_tags='safe do-something-else'
        )
        return person_extra
def upload_photo(request, person_id):
    person = get_object_or_404(Person, id=person_id)
    if request.method == 'POST':
        form = UploadPersonPhotoForm(request.POST, request.FILES)
        if form.is_valid():
            # Make sure that we save the user that made the upload
            queued_image = form.save(commit=False)
            queued_image.user = request.user
            queued_image.save()
            # Record that action:
            LoggedAction.objects.create(
                user=request.user,
                action_type='photo-upload',
                ip_address=get_client_ip(request),
                popit_person_new_version='',
                person=person,
                source=form.cleaned_data['justification_for_use'],
            )
            return HttpResponseRedirect(
                reverse('photo-upload-success',
                        kwargs={'person_id': person.id}))
    else:
        form = UploadPersonPhotoForm(initial={'person': person})
    return render(
        request, 'moderation_queue/photo-upload-new.html', {
            'form':
            form,
            'queued_images':
            QueuedImage.objects.filter(
                person=person,
                decision='undecided',
            ).order_by('created'),
            'person':
            person
        })
Exemple #8
0
def upload_photo(request, popit_person_id):
    if request.method == 'POST':
        form = UploadPersonPhotoForm(request.POST, request.FILES)
        if form.is_valid():
            # Make sure that we save the user that made the upload
            queued_image = form.save(commit=False)
            queued_image.user = request.user
            queued_image.save()
            # Record that action:
            LoggedAction.objects.create(
                user=request.user,
                action_type='photo-upload',
                ip_address=get_client_ip(request),
                popit_person_new_version='',
                popit_person_id=popit_person_id,
                source=form.cleaned_data['justification_for_use'],
            )
            return HttpResponseRedirect(
                reverse('photo-upload-success',
                        kwargs={
                            'popit_person_id':
                            form.cleaned_data['popit_person_id']
                        }))
    else:
        form = UploadPersonPhotoForm(
            initial={'popit_person_id': popit_person_id})
    api = create_popit_api_object()
    return render(
        request, 'moderation_queue/photo-upload-new.html', {
            'form': form,
            'person': PopItPerson.create_from_popit(api, popit_person_id)
        })
Exemple #9
0
    def save(self, request):
        instance = super(ResultSetForm, self).save(commit=False)
        instance.post_result = self.post_result
        instance.user = request.user if \
            request.user.is_authenticated() else None
        instance.ip_address = get_client_ip(request)
        instance.save(request)

        winner_count = self.memberships[0][0]\
            .extra.election.postextraelection_set.filter(
                postextra=self.memberships[0][0].post.extra)[0].winner_count

        winners = dict(
            sorted(
                [("{}-{}".format(self[y].value(), x.person.id), x)
                 for x, y in self.memberships],
                reverse=True,
                key=lambda votes: int(votes[0].split('-')[0]))[:winner_count])

        for membership, field_name in self.memberships:
            instance.candidate_results.create(
                membership=membership,
                is_winner=bool(membership in winners.values()),
                num_ballots_reported=self[field_name].value(),
            )

        if instance.review_status == CONFIRMED_STATUS:
            with transaction.atomic():
                self.mark_candidates_as_winner(request, instance)

        return instance
Exemple #10
0
def upload_photo_image(request, person_id):
    person = get_object_or_404(Person, id=person_id)
    image_form = UploadPersonPhotoImageForm(request.POST, request.FILES)
    url_form = UploadPersonPhotoURLForm(initial={"person": person})
    if image_form.is_valid():
        # Make sure that we save the user that made the upload
        queued_image = image_form.save(commit=False)
        queued_image.user = request.user
        queued_image.save()
        # Record that action:
        LoggedAction.objects.create(
            user=request.user,
            action_type="photo-upload",
            ip_address=get_client_ip(request),
            popit_person_new_version="",
            person=person,
            source=image_form.cleaned_data["justification_for_use"],
        )
        return HttpResponseRedirect(
            reverse("photo-upload-success", kwargs={"person_id": person.id})
        )

    return render(
        request,
        "moderation_queue/photo-upload-new.html",
        {
            "image_form": image_form,
            "url_form": url_form,
            "queued_images": QueuedImage.objects.filter(
                person=person, decision="undecided"
            ).order_by("created"),
            "person": person,
        },
    )
def update_person(
    request=None, person=None, party=None, post_election=None, source=None
):
    election = post_election.election

    person.not_standing.remove(election)

    check_creation_allowed(request.user, person.current_candidacies)

    membership, _ = Membership.objects.update_or_create(
        post=post_election.post,
        person=person,
        post_election=post_election,
        defaults={
            "party": party,
            "party_list_position": None,
            "elected": None,
            "role": election.candidate_membership_role,
        },
    )

    # Now remove other memberships in this election for that
    # person, although we raise an exception if there is any
    # object that has a
    # ForeignKey to the membership, since that would result in
    # losing data.
    old_memberships = (
        Membership.objects.exclude(pk=membership.pk)
        .exclude(post_election__candidates_locked=True)
        .filter(person=person, post_election__election=post_election.election)
    )
    for old_membership in old_memberships:
        raise_if_unsafe_to_delete(old_membership)
        old_membership.delete()

    memberships_for_election = Membership.objects.filter(
        person=person, post_election__election=post_election.election
    )

    if (
        not memberships_for_election.exists()
        or memberships_for_election.count() > 1
    ):
        raise ValueError(
            "Attempt to create invalid memberships for {}".format(person)
        )

    change_metadata = get_change_metadata(request, source)

    person.record_version(change_metadata)
    person.save()

    LoggedAction.objects.create(
        user=request.user,
        person=person,
        action_type="person-update",
        ip_address=get_client_ip(request),
        popit_person_new_version=change_metadata["version_id"],
        source=change_metadata["information_source"],
    )
Exemple #12
0
    def add_person(self, person_data):
        # TODO Move this out of the view layer
        person = Person.objects.create(name=person_data['name'])
        person_extra = PersonExtra.objects.create(base=person)
        check_creation_allowed(self.request.user,
                               person_extra.current_candidacies)

        change_metadata = get_change_metadata(self.request,
                                              person_data['source'])

        person_extra.record_version(change_metadata)
        person_extra.save()

        LoggedAction.objects.create(
            user=self.request.user,
            person=person,
            action_type='person-create',
            ip_address=get_client_ip(self.request),
            popit_person_new_version=change_metadata['version_id'],
            source=change_metadata['information_source'],
        )

        # Add a message to be displayed after redirect:
        messages.add_message(self.request,
                             messages.SUCCESS,
                             get_call_to_action_flash_message(person,
                                                              new_person=True),
                             extra_tags='safe do-something-else')
        return person_extra
def update_person(request=None,
                  person_extra=None,
                  party=None,
                  post_election=None,
                  source=None):
    election = post_election.election

    person_extra.not_standing.remove(election)

    check_creation_allowed(request.user, person_extra.current_candidacies)

    membership, _ = Membership.objects.update_or_create(
        post=post_election.postextra.base,
        person=person_extra.base,
        extra__election=election,
        role=election.candidate_membership_role,
        defaults={
            'on_behalf_of': party,
        })

    MembershipExtra.objects.get_or_create(base=membership,
                                          defaults={
                                              'party_list_position': None,
                                              'election': election,
                                              'elected': None,
                                              'post_election': post_election,
                                          })

    # Now remove other memberships in this election for that
    # person, although we raise an exception if there is any
    # object (other than its MembershipExtra) that has a
    # ForeignKey to the membership, since that would result in
    # losing data.
    old_memberships = Membership.objects \
        .exclude(pk=membership.pk) \
        .filter(
            person=person_extra.base,
            extra__election=election,
            role=election.candidate_membership_role,
        )
    for old_membership in old_memberships:
        raise_if_unsafe_to_delete(old_membership)
        old_membership.delete()

    change_metadata = get_change_metadata(request, source)

    person_extra.record_version(change_metadata)
    person_extra.save()

    LoggedAction.objects.create(
        user=request.user,
        person=person_extra.base,
        action_type='person-update',
        ip_address=get_client_ip(request),
        popit_person_new_version=change_metadata['version_id'],
        source=change_metadata['information_source'],
    )
 def form_valid(self, form):
     form.save()
     LoggedAction.objects.create(
         user=self.request.user,
         action_type='confirm-council-control',
         ip_address=get_client_ip(self.request),
         source=form['review_source'].value()
     )
     return super(ConfirmControl, self).form_valid(form)
Exemple #15
0
 def form_valid(self, form):
     LoggedAction.objects.create(
         user=self.request.user,
         ballot=form.instance.ballot,
         action_type="sopn-upload",
         ip_address=get_client_ip(self.request),
         source=form.cleaned_data["source_url"],
     )
     return super().form_valid(form)
 def form_valid(self, form):
     form.save()
     if self.request.user.is_authenticated():
         user = self.request.user
         LoggedAction.objects.create(
             user=user,
             action_type='confirm-council-result',
             ip_address=get_client_ip(self.request),
             source=form['review_source'].value(),
             post=form.post,
         )
     return super(ReviewPostReportView, self).form_valid(form)
 def form_valid(self, form):
     form.save()
     if self.request.user.is_authenticated():
         user = self.request.user
         LoggedAction.objects.create(
             user=user,
             action_type='confirm-council-result',
             ip_address=get_client_ip(self.request),
             source=form['review_source'].value(),
             post=form.post,
         )
     return super(ReviewPostReportView, self).form_valid(form)
def upload_photo_url(request, person_id):
    person = get_object_or_404(Person, id=person_id)
    image_form = UploadPersonPhotoImageForm(initial={"person": person})
    url_form = UploadPersonPhotoURLForm(request.POST)

    if url_form.is_valid():
        image_url = url_form.cleaned_data["image_url"]
        try:
            img_temp_filename = download_image_from_url(image_url)
        except ImageDownloadException as ide:
            return HttpResponseBadRequest(unicode(ide).encode("utf-8"))
        try:
            queued_image = QueuedImage(
                why_allowed=url_form.cleaned_data["why_allowed_url"],
                justification_for_use=url_form.
                cleaned_data["justification_for_use_url"],
                person=person,
                user=request.user,
            )
            queued_image.save()
            with open(img_temp_filename, "rb") as f:
                queued_image.image.save(image_url, File(f))
            queued_image.save()
            LoggedAction.objects.create(
                user=request.user,
                action_type="photo-upload",
                ip_address=get_client_ip(request),
                popit_person_new_version="",
                person=person,
                source=url_form.cleaned_data["justification_for_use_url"],
            )
            return HttpResponseRedirect(
                reverse("photo-upload-success",
                        kwargs={"person_id": person.id}))
        finally:
            os.remove(img_temp_filename)
    else:
        return render(
            request,
            "moderation_queue/photo-upload-new.html",
            {
                "image_form":
                image_form,
                "url_form":
                url_form,
                "queued_images":
                QueuedImage.objects.filter(
                    person=person, decision="undecided").order_by("created"),
                "person":
                person,
            },
        )
Exemple #19
0
    def update_person(self, context, data, person_extra):
        party = Organization.objects.get(pk=data['party'].split('__')[0])
        post = context['post_extra'].base
        election = Election.objects.get(slug=context['election'])

        person_extra.not_standing.remove(election)

        membership, _ = Membership.objects.update_or_create(
            post=post,
            person=person_extra.base,
            extra__election=election,
            role=election.candidate_membership_role,
            defaults={
                'on_behalf_of': party,
            })

        MembershipExtra.objects.get_or_create(base=membership,
                                              defaults={
                                                  'party_list_position': None,
                                                  'election': election,
                                                  'elected': None,
                                              })

        # Now remove other memberships in this election for that
        # person, although we raise an exception if there is any
        # object (other than its MembershipExtra) that has a
        # ForeignKey to the membership, since that would result in
        # losing data.
        for old_membership in Membership.objects \
            .exclude(pk=membership.pk) \
            .filter(
                person=person_extra.base,
                extra__election=election,
                role=election.candidate_membership_role,
            ):
            raise_if_unsafe_to_delete(old_membership)
            old_membership.delete()

        change_metadata = get_change_metadata(self.request, data['source'])

        person_extra.record_version(change_metadata)
        person_extra.save()

        LoggedAction.objects.create(
            user=self.request.user,
            person=person_extra.base,
            action_type='person-update',
            ip_address=get_client_ip(self.request),
            popit_person_new_version=change_metadata['version_id'],
            source=change_metadata['information_source'],
        )
Exemple #20
0
def upload_photo_url(request, person_id):
    person = get_object_or_404(Person, id=person_id)
    image_form = UploadPersonPhotoImageForm(initial={'person': person})
    url_form = UploadPersonPhotoURLForm(request.POST)

    if url_form.is_valid():
        image_url = url_form.cleaned_data['image_url']
        try:
            img_temp_filename = download_image_from_url(image_url)
        except ImageDownloadException as ide:
            return HttpResponseBadRequest(unicode(ide).encode('utf-8'))
        try:
            queued_image = QueuedImage(
                why_allowed=url_form.cleaned_data['why_allowed_url'],
                justification_for_use=url_form.
                cleaned_data['justification_for_use_url'],
                person=person,
                user=request.user)
            queued_image.save()
            with open(img_temp_filename, 'rb') as f:
                queued_image.image.save(image_url, File(f))
            queued_image.save()
            LoggedAction.objects.create(
                user=request.user,
                action_type='photo-upload',
                ip_address=get_client_ip(request),
                popit_person_new_version='',
                person=person,
                source=url_form.cleaned_data['justification_for_use_url'],
            )
            return HttpResponseRedirect(
                reverse('photo-upload-success',
                        kwargs={'person_id': person.id}))
        finally:
            os.remove(img_temp_filename)
    else:
        return render(
            request, 'moderation_queue/photo-upload-new.html', {
                'image_form':
                image_form,
                'url_form':
                url_form,
                'queued_images':
                QueuedImage.objects.filter(
                    person=person,
                    decision='undecided',
                ).order_by('created'),
                'person':
                person
            })
Exemple #21
0
    def update_person(self, context, data, person_extra):
        party = Organization.objects.get(pk=data['party'])
        post = context['post_extra'].base
        election = Election.objects.get(slug=context['election'])

        previous_memberships_in_this_election = Membership.objects.filter(
            person=person_extra.base,
            extra__election=election,
            role=election.candidate_membership_role,
        )

        previous_memberships_in_this_election.delete()
        person_extra.not_standing.remove(election)

        membership, _ = Membership.objects.get_or_create(
            post=post,
            person=person_extra.base,
            extra__election=election,
            role=election.candidate_membership_role,
            defaults={
                'on_behalf_of': party,
            }
        )

        MembershipExtra.objects.get_or_create(
            base=membership,
            defaults={
                'party_list_position': None,
                'election': election,
                'elected': False,
            }
        )

        change_metadata = get_change_metadata(
            self.request, data['source']
        )

        person_extra.record_version(change_metadata)
        person_extra.save()

        LoggedAction.objects.create(
            user=self.request.user,
            person=person_extra.base,
            action_type='person-update',
            ip_address=get_client_ip(self.request),
            popit_person_new_version=change_metadata['version_id'],
            source=change_metadata['information_source'],
        )
def add_person(request, person_data):
    person = Person.objects.create(name=person_data["name"])

    change_metadata = get_change_metadata(request, person_data["source"])

    person.record_version(change_metadata, new_person=True)
    person.save()

    LoggedAction.objects.create(
        user=request.user,
        person=person,
        action_type="person-create",
        ip_address=get_client_ip(request),
        popit_person_new_version=change_metadata["version_id"],
        source=change_metadata["information_source"],
    )
    return person
    def merge(self, delete=True):
        """
        Do everything we need in order to merge two people.

        At the end of this, `self.source_person` should have no related objects
        left, and is deleted safely using `self.safe_delete`
        """
        with transaction.atomic():
            # Merge all the things
            self.merge_person_attrs()
            self.merge_versions_json()
            self.merge_person_identifiers()
            self.merge_images()
            self.merge_logged_actions()
            self.merge_memberships()
            self.merge_queued_images()
            self.merge_not_standing()
            self.merge_result_events()

            # Post merging tasks
            # Save the dest person (don't assume the methods above do this)
            change_metadata = get_change_metadata(
                self.request,
                "After merging person {}".format(self.source_person.pk),
            )

            # Log that the merge has taken place, and will be shown in
            # the recent changes, leaderboards, etc.
            if self.request:
                LoggedAction.objects.create(
                    user=self.request.user,
                    action_type="person-merge",
                    ip_address=get_client_ip(self.request),
                    popit_person_new_version=change_metadata["version_id"],
                    person=self.dest_person,
                    source=change_metadata["information_source"],
                )

            self.dest_person.record_version(change_metadata)
            self.dest_person.save()

            self.setup_redirect()

            if delete:
                # Delete the old person
                self.safe_delete(self.source_person)
def add_person(request, person_data):
    person = Person.objects.create(name=person_data['name'])
    person_extra = PersonExtra.objects.create(base=person)

    change_metadata = get_change_metadata(request, person_data['source'])

    person_extra.record_version(change_metadata, new_person=True)
    person_extra.save()

    LoggedAction.objects.create(
        user=request.user,
        person=person,
        action_type='person-create',
        ip_address=get_client_ip(request),
        popit_person_new_version=change_metadata['version_id'],
        source=change_metadata['information_source'],
    )
    return person_extra
    def form_valid(self, form):
        user = self.request.user
        form.instance.user = user

        LoggedAction.objects.create(
            user=self.request.user,
            action_type="suggest-ballot-lock",
            post_election=form.cleaned_data["postextraelection"],
            ip_address=get_client_ip(self.request),
            source=form.cleaned_data["justification"],
        )

        messages.add_message(
            self.request,
            messages.SUCCESS,
            message="Thanks for suggesting we lock an area!",
        )

        return super().form_valid(form)
    def merge(self, delete=True):
        """
        Do everything we need in order to merge two people.

        At the end of this, `self.source_person` should have no related objects
        left, and is deleted safely using `self.safe_delete`
        """
        with transaction.atomic():
            # Merge all the things
            for method_name in set(self.SUPPORTED_FIELDS.values()):
                method = getattr(self, method_name)
                method()

            # Post merging tasks
            # Save the dest person (don't assume the methods above do this)
            change_metadata = get_change_metadata(
                self.request,
                "After merging person {}".format(self.source_person.pk),
            )
            # Save the dest person before creating a LoggedAction
            # See https://github.com/DemocracyClub/yournextrepresentative/issues/1037
            # for more
            self.dest_person.record_version(change_metadata)
            self.dest_person.save()

            # Log that the merge has taken place, and will be shown in
            # the recent changes, leaderboards, etc.
            if self.request:
                LoggedAction.objects.create(
                    user=self.request.user,
                    action_type="person-merge",
                    ip_address=get_client_ip(self.request),
                    popit_person_new_version=change_metadata["version_id"],
                    person=self.dest_person,
                    source=change_metadata["information_source"],
                )

            self.setup_redirect()

            if delete:
                # Delete the old person
                self.safe_delete(self.source_person)
        return self.dest_person
    def save(self, request):
        with transaction.atomic():
            instance = super().save(commit=False)
            instance.post_election = self.post_election
            instance.user = request.user if \
                request.user.is_authenticated() else None
            instance.ip_address = get_client_ip(request)
            instance.save()

            winner_count = self.post_election.winner_count
            if winner_count:
                winners = dict(sorted(
                    [("{}-{}".format(self[y].value(), x.person.id), x)
                        for x, y in self.memberships],
                    reverse=True,
                    key=lambda votes: int(votes[0].split('-')[0])
                )[:winner_count])
            else:
                winners = {}

            for membership, field_name in self.memberships:
                instance.candidate_results.update_or_create(
                    membership=membership,
                    defaults={
                        'is_winner':
                            bool(membership in winners.values()),
                        'num_ballots': self[field_name].value(),
                    }
                )

            mark_candidates_as_winner(request, instance)
            instance.record_version()

            LoggedAction.objects.create(
                user=instance.user,
                action_type='entered-results-data',
                source=instance.source,
                post_election=instance.post_election,
            )


        return instance
Exemple #28
0
    def save_model(self, request, obj, form, change):
        if form.initial["edit_limitations"] != form["edit_limitations"].value(
        ):

            try:
                limitation = EditLimitationStatuses[
                    form["edit_limitations"].value()].value
                message = "Changed edit limitations to '{}'".format(limitation)
            except KeyError:
                message = "Removed edit limitations"

            LoggedAction.objects.create(
                user=request.user,
                action_type="change-edit-limitations",
                ip_address=get_client_ip(request),
                person=obj,
                source=message,
            )

        super().save_model(request, obj, form, change)
def upload_photo(request, person_id):
    person = get_object_or_404(Person, id=person_id)
    if request.method == 'POST':
        form = UploadPersonPhotoForm(request.POST, request.FILES)
        if form.is_valid():
            # Make sure that we save the user that made the upload
            queued_image = form.save(commit=False)
            queued_image.user = request.user
            queued_image.save()
            # Record that action:
            LoggedAction.objects.create(
                user=request.user,
                action_type='photo-upload',
                ip_address=get_client_ip(request),
                popit_person_new_version='',
                person=person,
                source=form.cleaned_data['justification_for_use'],
            )
            return HttpResponseRedirect(reverse(
                'photo-upload-success',
                kwargs={
                    'person_id': person.id
                }
            ))
    else:
        form = UploadPersonPhotoForm(
            initial={
                'person': person
            }
        )
    return render(
        request,
        'moderation_queue/photo-upload-new.html',
        {'form': form,
         'queued_images': QueuedImage.objects.filter(
             person=person,
             decision='undecided',
         ).order_by('created'),
         'person': person}
    )
Exemple #30
0
    def add_person(self, person_data):
        # TODO Move this out of the view layer
        person = Person.objects.create(name=person_data['name'])
        person_extra = PersonExtra.objects.create(base=person)
        check_creation_allowed(self.request.user,
                               person_extra.current_candidacies)

        change_metadata = get_change_metadata(self.request,
                                              person_data['source'])

        person_extra.record_version(change_metadata)
        person_extra.save()

        LoggedAction.objects.create(
            user=self.request.user,
            person=person,
            action_type='person-create',
            ip_address=get_client_ip(self.request),
            popit_person_new_version=change_metadata['version_id'],
            source=change_metadata['information_source'],
        )

        return person_extra
Exemple #31
0
def upload_photo(request, popit_person_id):
    if request.method == 'POST':
        form = UploadPersonPhotoForm(request.POST, request.FILES)
        if form.is_valid():
            # Make sure that we save the user that made the upload
            queued_image = form.save(commit=False)
            queued_image.user = request.user
            queued_image.save()
            # Record that action:
            LoggedAction.objects.create(
                user=request.user,
                action_type='photo-upload',
                ip_address=get_client_ip(request),
                popit_person_new_version='',
                popit_person_id=popit_person_id,
                source=form.cleaned_data['justification_for_use'],
            )
            return HttpResponseRedirect(reverse(
                'photo-upload-success',
                kwargs={
                    'popit_person_id': form.cleaned_data['popit_person_id']
                }
            ))
    else:
        form = UploadPersonPhotoForm(
            initial={
                'popit_person_id': popit_person_id
            }
        )
    api = create_popit_api_object()
    return render(
        request,
        'moderation_queue/photo-upload-new.html',
        {'form': form,
         'person': PopItPerson.create_from_popit(api, popit_person_id)}
    )
 def form_valid(self, form):
     decision = form.cleaned_data['decision']
     person = Person.objects.get(
         id=self.queued_image.person.id
     )
     person_extra = person.extra
     candidate_path = person_extra.get_absolute_url()
     candidate_name = person.name
     candidate_link = '<a href="{url}">{name}</a>'.format(
         url=candidate_path,
         name=candidate_name,
     )
     photo_review_url = self.request.build_absolute_uri(
         self.queued_image.get_absolute_url()
     )
     site_name = Site.objects.get_current().name
     def flash(level, message):
         messages.add_message(
             self.request,
             level,
             message,
             extra_tags='safe photo-review'
         )
     if decision == 'approved':
         # Crop the image...
         crop_fields = ('x_min', 'y_min', 'x_max', 'y_max')
         self.crop_and_upload_image_to_popit(
             self.queued_image.image.path,
             [form.cleaned_data[e] for e in crop_fields],
             form.cleaned_data['moderator_why_allowed'],
             form.cleaned_data['make_primary'],
         )
         self.queued_image.decision = 'approved'
         for i, field in enumerate(crop_fields):
             setattr(
                 self.queued_image,
                 'crop_' + field,
                 form.cleaned_data[field]
             )
         self.queued_image.save()
         update_message = _('Approved a photo upload from '
             '{uploading_user} who provided the message: '
             '"{message}"').format(
             uploading_user=self.queued_image.user.username,
             message=self.queued_image.justification_for_use,
         )
         change_metadata = get_change_metadata(
             self.request,
             update_message
         )
         person_extra.record_version(change_metadata)
         person_extra.save()
         person.save()
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-approve',
             ip_address=get_client_ip(self.request),
             popit_person_new_version=change_metadata['version_id'],
             person=person,
             source=update_message,
         )
         candidate_full_url = person_extra.get_absolute_url(self.request)
         self.send_mail(
             _('{site_name} image upload approved').format(
                 site_name=site_name
             ),
             render_to_string(
                 'moderation_queue/photo_approved_email.txt',
                 {
                     'site_name': site_name,
                     'candidate_page_url': candidate_full_url,
                     'intro': _(
                         "Thank-you for submitting a photo to "
                         "{site_name}; that's been uploaded now for "
                         "the candidate page here:"
                     ).format(site_name=site_name),
                     'signoff': _(
                         "Many thanks from the {site_name} volunteers"
                     ).format(site_name=site_name),
                 }
             ),
         )
         flash(
             messages.SUCCESS,
             _('You approved a photo upload for %s') % candidate_link
         )
     elif decision == 'rejected':
         self.queued_image.decision = 'rejected'
         self.queued_image.save()
         update_message = _('Rejected a photo upload from '
             '{uploading_user}').format(
             uploading_user=self.queued_image.user.username,
         )
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-reject',
             ip_address=get_client_ip(self.request),
             popit_person_new_version='',
             person=person,
             source=update_message,
         )
         retry_upload_link = self.request.build_absolute_uri(
             reverse(
                 'photo-upload',
                 kwargs={'person_id': self.queued_image.person.id}
             )
         )
         self.send_mail(
             _('{site_name} image moderation results').format(
                 site_name=Site.objects.get_current().name
             ),
             render_to_string(
                 'moderation_queue/photo_rejected_email.txt',
                 {
                     'reason': form.cleaned_data['rejection_reason'],
                     'retry_upload_link': retry_upload_link,
                     'photo_review_url': photo_review_url,
                     'intro': _(
                         "Thank-you for uploading a photo of "
                         "{candidate_name} to {site_name}, but "
                         "unfortunately we can't use that image because:"
                     ).format(
                         candidate_name=candidate_name,
                         site_name=site_name
                     ),
                     'possible_actions': _(
                         'You can just reply to this email if you want to '
                         'discuss that further, or you can try uploading a '
                         'photo with a different reason or justification '
                         'for its use using this link:'
                     ),
                     'signoff': _(
                         "Many thanks from the {site_name} volunteers"
                     ).format(site_name=site_name),
                 },
             ),
             email_support_too=True,
         )
         flash(
             messages.INFO,
             _('You rejected a photo upload for %s') % candidate_link
         )
     elif decision == 'undecided':
         # If it's left as undecided, just redirect back to the
         # photo review queue...
         flash(
             messages.INFO,
             _('You left a photo upload for {0} in the queue').format(
                 candidate_link
             )
         )
     elif decision == 'ignore':
         self.queued_image.decision = 'ignore'
         self.queued_image.save()
         update_message = _('Ignored a photo upload from '
             '{uploading_user} (This usually means it was a duplicate)').format(
             uploading_user=self.queued_image.user.username)
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-ignore',
             ip_address=get_client_ip(self.request),
             popit_person_new_version='',
             person=person,
             source=update_message,
         )
         flash(
             messages.INFO,
             _('You indicated a photo upload for {0} should be ignored').format(
                 candidate_link
             )
         )
     else:
         raise Exception("BUG: unexpected decision {0}".format(decision))
     return HttpResponseRedirect(reverse('photo-review-list'))
Exemple #33
0
 def form_valid(self, form):
     decision = form.cleaned_data['decision']
     if decision == 'approved':
         # Crop the image...
         self.crop_and_upload_image_to_popit(
             self.queued_image.image.path,
             [form.cleaned_data[e] for e in
              ('x_min', 'y_min', 'x_max', 'y_max')],
             form.cleaned_data['moderator_why_allowed']
         )
         self.queued_image.decision = 'approved'
         self.queued_image.save()
         # Now create a new version in PopIt:
         person_data, _ = self.get_person(
             self.queued_image.popit_person_id
         )
         previous_versions = person_data.pop('versions')
         update_message = (u'Approved a photo upload from ' +
             u'{uploading_user} who provided the message: ' +
             u'"{message}"').format(
             uploading_user=self.queued_image.user.username,
             message=self.queued_image.justification_for_use,
         )
         change_metadata = get_change_metadata(
             self.request,
             update_message
         )
         self.update_person(
             person_data,
             change_metadata,
             previous_versions,
         )
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-approve',
             ip_address=get_client_ip(self.request),
             popit_person_new_version=change_metadata['version_id'],
             popit_person_id=self.queued_image.popit_person_id,
             source=update_message,
         )
         candidate_path = reverse(
             'person-view',
             kwargs={'person_id': self.queued_image.popit_person_id}
         )
         self.send_mail(
             'YourNextMP image upload approved',
             render_to_string(
                 'moderation_queue/photo_approved_email.txt',
                 {'candidate_page_url':
                  self.request.build_absolute_uri(candidate_path)}
             ),
         )
     elif decision == 'rejected':
         self.queued_image.decision = 'rejected'
         self.queued_image.save()
         update_message = u'Rejected a photo upload from ' + \
             u'{uploading_user}'.format(
             uploading_user=self.queued_image.user.username,
         )
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-reject',
             ip_address=get_client_ip(self.request),
             popit_person_new_version='',
             popit_person_id=self.queued_image.popit_person_id,
             source=update_message,
         )
         self.send_mail(
             'YourNextMP image moderation results',
             render_to_string(
                 'moderation_queue/photo_rejected_email.txt',
                 {'reason': form.cleaned_data['rejection_reason']}
             ),
         )
     elif decision == 'undecided':
         # If it's left as undecided, just redirect back to the
         # photo review queue...
         pass
     else:
         raise Exception("BUG: unexpected decision {0}".format(decision))
     return HttpResponseRedirect(reverse('photo-review-list'))
Exemple #34
0
    def form_valid(self, form):
        decision = form.cleaned_data['decision']
        person = Person.objects.get(
            id=self.queued_image.person.id
        )
        person_extra = person.extra
        candidate_path = person_extra.get_absolute_url()
        candidate_name = person.name
        candidate_link = '<a href="{url}">{name}</a>'.format(
            url=candidate_path,
            name=candidate_name,
        )
        photo_review_url = self.request.build_absolute_uri(
            self.queued_image.get_absolute_url()
        )
        site_name = Site.objects.get_current().name
        def flash(level, message):
            messages.add_message(
                self.request,
                level,
                message,
                extra_tags='safe photo-review'
            )
        if self.queued_image.user:
            uploaded_by = self.queued_image.user.username
        else:
            uploaded_by = _("a script")

        if decision == 'approved':
            # Crop the image...
            crop_fields = ('x_min', 'y_min', 'x_max', 'y_max')
            self.crop_and_upload_image_to_popit(
                self.queued_image.image.path,
                [form.cleaned_data[e] for e in crop_fields],
                form.cleaned_data['moderator_why_allowed'],
                form.cleaned_data['make_primary'],
            )
            self.queued_image.decision = 'approved'
            for i, field in enumerate(crop_fields):
                setattr(
                    self.queued_image,
                    'crop_' + field,
                    form.cleaned_data[field]
                )
            self.queued_image.save()

            update_message = _('Approved a photo upload from '
                '{uploading_user} who provided the message: '
                '"{message}"').format(
                uploading_user=uploaded_by,
                message=self.queued_image.justification_for_use,
            )
            change_metadata = get_change_metadata(
                self.request,
                update_message
            )
            person_extra.record_version(change_metadata)
            person_extra.save()
            person.save()
            LoggedAction.objects.create(
                user=self.request.user,
                action_type='photo-approve',
                ip_address=get_client_ip(self.request),
                popit_person_new_version=change_metadata['version_id'],
                person=person,
                source=update_message,
            )
            candidate_full_url = person_extra.get_absolute_url(self.request)
            self.send_mail(
                _('{site_name} image upload approved').format(
                    site_name=site_name
                ),
                render_to_string(
                    'moderation_queue/photo_approved_email.txt',
                    {
                        'site_name': site_name,
                        'candidate_page_url': candidate_full_url,
                        'intro': _(
                            "Thank-you for submitting a photo to "
                            "{site_name}; that's been uploaded now for "
                            "the candidate page here:"
                        ).format(site_name=site_name),
                        'signoff': _(
                            "Many thanks from the {site_name} volunteers"
                        ).format(site_name=site_name),
                    }
                ),
            )
            flash(
                messages.SUCCESS,
                _('You approved a photo upload for %s') % candidate_link
            )
        elif decision == 'rejected':
            self.queued_image.decision = 'rejected'
            self.queued_image.save()
            update_message = _('Rejected a photo upload from '
                '{uploading_user}').format(
                uploading_user=uploaded_by,
            )
            LoggedAction.objects.create(
                user=self.request.user,
                action_type='photo-reject',
                ip_address=get_client_ip(self.request),
                popit_person_new_version='',
                person=person,
                source=update_message,
            )
            retry_upload_link = self.request.build_absolute_uri(
                reverse(
                    'photo-upload',
                    kwargs={'person_id': self.queued_image.person.id}
                )
            )
            self.send_mail(
                _('{site_name} image moderation results').format(
                    site_name=Site.objects.get_current().name
                ),
                render_to_string(
                    'moderation_queue/photo_rejected_email.txt',
                    {
                        'reason': form.cleaned_data['rejection_reason'],
                        'retry_upload_link': retry_upload_link,
                        'photo_review_url': photo_review_url,
                        'intro': _(
                            "Thank-you for uploading a photo of "
                            "{candidate_name} to {site_name}, but "
                            "unfortunately we can't use that image because:"
                        ).format(
                            candidate_name=candidate_name,
                            site_name=site_name
                        ),
                        'possible_actions': _(
                            'You can just reply to this email if you want to '
                            'discuss that further, or you can try uploading a '
                            'photo with a different reason or justification '
                            'for its use using this link:'
                        ),
                        'signoff': _(
                            "Many thanks from the {site_name} volunteers"
                        ).format(site_name=site_name),
                    },
                ),
                email_support_too=True,
            )
            flash(
                messages.INFO,
                _('You rejected a photo upload for %s') % candidate_link
            )
        elif decision == 'undecided':
            # If it's left as undecided, just redirect back to the
            # photo review queue...
            flash(
                messages.INFO,
                _('You left a photo upload for {0} in the queue').format(
                    candidate_link
                )
            )
        elif decision == 'ignore':
            self.queued_image.decision = 'ignore'
            self.queued_image.save()
            update_message = _('Ignored a photo upload from '
                '{uploading_user} (This usually means it was a duplicate)').format(
                uploading_user=uploaded_by)
            LoggedAction.objects.create(
                user=self.request.user,
                action_type='photo-ignore',
                ip_address=get_client_ip(self.request),
                popit_person_new_version='',
                person=person,
                source=update_message,
            )
            flash(
                messages.INFO,
                _('You indicated a photo upload for {0} should be ignored').format(
                    candidate_link
                )
            )
        else:
            raise Exception("BUG: unexpected decision {0}".format(decision))
        return HttpResponseRedirect(reverse('photo-review-list'))
    def form_valid(self, form):
        decision = form.cleaned_data['decision']
        person = PopItPerson.create_from_popit(
            self.api, self.queued_image.popit_person_id)
        candidate_path = person.get_absolute_url()
        candidate_name = person.name
        candidate_link = u'<a href="{url}">{name}</a>'.format(
            url=candidate_path,
            name=candidate_name,
        )
        photo_review_url = self.request.build_absolute_uri(
            self.queued_image.get_absolute_url())

        def flash(level, message):
            messages.add_message(self.request,
                                 level,
                                 message,
                                 extra_tags='safe photo-review')

        if decision == 'approved':
            # Crop the image...
            crop_fields = ('x_min', 'y_min', 'x_max', 'y_max')
            self.crop_and_upload_image_to_popit(
                self.queued_image.image.path,
                [form.cleaned_data[e] for e in crop_fields],
                form.cleaned_data['moderator_why_allowed'],
                form.cleaned_data['make_primary'],
            )
            self.queued_image.decision = 'approved'
            for i, field in enumerate(crop_fields):
                setattr(self.queued_image, 'crop_' + field,
                        form.cleaned_data[field])
            self.queued_image.save()
            update_message = _(
                u'Approved a photo upload from '
                u'{uploading_user} who provided the message: '
                u'"{message}"').format(
                    uploading_user=self.queued_image.user.username,
                    message=self.queued_image.justification_for_use,
                )
            change_metadata = get_change_metadata(self.request, update_message)
            # We have to refetch the person from PopIt, otherwise
            # saving the new version will write back the images array
            # from before we uploaded the image:
            person = PopItPerson.create_from_popit(self.api, person.id)
            person.record_version(change_metadata)
            person.save_to_popit(self.api, self.request.user)
            LoggedAction.objects.create(
                user=self.request.user,
                action_type='photo-approve',
                ip_address=get_client_ip(self.request),
                popit_person_new_version=change_metadata['version_id'],
                popit_person_id=self.queued_image.popit_person_id,
                source=update_message,
            )
            self.send_mail(
                _('YourNextMP image upload approved'),
                render_to_string('moderation_queue/photo_approved_email.txt', {
                    'candidate_page_url':
                    person.get_absolute_url(self.request)
                }),
            )
            flash(messages.SUCCESS,
                  _(u'You approved a photo upload for %s') % candidate_link)
        elif decision == 'rejected':
            self.queued_image.decision = 'rejected'
            self.queued_image.save()
            update_message = _(
                u'Rejected a photo upload from '
                u'{uploading_user}').format(
                    uploading_user=self.queued_image.user.username, )
            LoggedAction.objects.create(
                user=self.request.user,
                action_type='photo-reject',
                ip_address=get_client_ip(self.request),
                popit_person_new_version='',
                popit_person_id=self.queued_image.popit_person_id,
                source=update_message,
            )
            retry_upload_link = self.request.build_absolute_uri(
                reverse('photo-upload',
                        kwargs={
                            'popit_person_id':
                            self.queued_image.popit_person_id
                        }))
            self.send_mail(
                _('YourNextMP image moderation results'),
                render_to_string(
                    'moderation_queue/photo_rejected_email.txt',
                    {
                        'reason': form.cleaned_data['rejection_reason'],
                        'candidate_name': candidate_name,
                        'retry_upload_link': retry_upload_link,
                        'photo_review_url': photo_review_url
                    },
                ),
                email_support_too=True,
            )
            flash(messages.INFO,
                  _(u'You rejected a photo upload for %s') % candidate_link)
        elif decision == 'undecided':
            # If it's left as undecided, just redirect back to the
            # photo review queue...
            flash(
                messages.INFO,
                _(u'You left a photo upload for {0} in the queue').format(
                    candidate_link))
        elif decision == 'ignore':
            self.queued_image.decision = 'ignore'
            self.queued_image.save()
            update_message = _(
                u'Ignored a photo upload from '
                u'{uploading_user} (This usually means it was a duplicate)'
            ).format(uploading_user=self.queued_image.user.username)
            LoggedAction.objects.create(
                user=self.request.user,
                action_type='photo-ignore',
                ip_address=get_client_ip(self.request),
                popit_person_new_version='',
                popit_person_id=self.queued_image.popit_person_id,
                source=update_message,
            )
            flash(
                messages.INFO,
                _(u'You indicated a photo upload for {0} should be ignored').
                format(candidate_link))
        else:
            raise Exception("BUG: unexpected decision {0}".format(decision))
        return HttpResponseRedirect(reverse('photo-review-list'))
 def form_valid(self, form):
     decision = form.cleaned_data['decision']
     person = PopItPerson.create_from_popit(
         self.api,
         self.queued_image.popit_person_id
     )
     candidate_path = person.get_absolute_url()
     candidate_name = person.name
     candidate_link = u'<a href="{url}">{name}</a>'.format(
         url=candidate_path,
         name=candidate_name,
     )
     photo_review_url = self.request.build_absolute_uri(
         self.queued_image.get_absolute_url()
     )
     def flash(level, message):
         messages.add_message(
             self.request,
             level,
             message,
             extra_tags='safe photo-review'
         )
     if decision == 'approved':
         # Crop the image...
         crop_fields = ('x_min', 'y_min', 'x_max', 'y_max')
         self.crop_and_upload_image_to_popit(
             self.queued_image.image.path,
             [form.cleaned_data[e] for e in crop_fields],
             form.cleaned_data['moderator_why_allowed'],
             form.cleaned_data['make_primary'],
         )
         self.queued_image.decision = 'approved'
         for i, field in enumerate(crop_fields):
             setattr(
                 self.queued_image,
                 'crop_' + field,
                 form.cleaned_data[field]
             )
         self.queued_image.save()
         update_message = _(u'Approved a photo upload from '
             u'{uploading_user} who provided the message: '
             u'"{message}"').format(
             uploading_user=self.queued_image.user.username,
             message=self.queued_image.justification_for_use,
         )
         change_metadata = get_change_metadata(
             self.request,
             update_message
         )
         # We have to refetch the person from PopIt, otherwise
         # saving the new version will write back the images array
         # from before we uploaded the image:
         person = PopItPerson.create_from_popit(self.api, person.id)
         person.record_version(change_metadata)
         person.save_to_popit(self.api, self.request.user)
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-approve',
             ip_address=get_client_ip(self.request),
             popit_person_new_version=change_metadata['version_id'],
             popit_person_id=self.queued_image.popit_person_id,
             source=update_message,
         )
         self.send_mail(
             _('YourNextMP image upload approved'),
             render_to_string(
                 'moderation_queue/photo_approved_email.txt',
                 {'candidate_page_url':
                  person.get_absolute_url(self.request)}
             ),
         )
         flash(
             messages.SUCCESS,
             _(u'You approved a photo upload for %s') % candidate_link
         )
     elif decision == 'rejected':
         self.queued_image.decision = 'rejected'
         self.queued_image.save()
         update_message = _(u'Rejected a photo upload from '
             u'{uploading_user}').format(
             uploading_user=self.queued_image.user.username,
         )
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-reject',
             ip_address=get_client_ip(self.request),
             popit_person_new_version='',
             popit_person_id=self.queued_image.popit_person_id,
             source=update_message,
         )
         retry_upload_link = self.request.build_absolute_uri(
             reverse(
                 'photo-upload',
                 kwargs={'popit_person_id': self.queued_image.popit_person_id}
             )
         )
         self.send_mail(
             _('YourNextMP image moderation results'),
             render_to_string(
                 'moderation_queue/photo_rejected_email.txt',
                 {'reason': form.cleaned_data['rejection_reason'],
                  'candidate_name': candidate_name,
                  'retry_upload_link': retry_upload_link,
                  'photo_review_url': photo_review_url},
             ),
             email_support_too=True,
         )
         flash(
             messages.INFO,
             _(u'You rejected a photo upload for %s') % candidate_link
         )
     elif decision == 'undecided':
         # If it's left as undecided, just redirect back to the
         # photo review queue...
         flash(
             messages.INFO,
             _(u'You left a photo upload for {0} in the queue').format(
                 candidate_link
             )
         )
     elif decision == 'ignore':
         self.queued_image.decision = 'ignore'
         self.queued_image.save()
         update_message = _(u'Ignored a photo upload from '
             u'{uploading_user} (This usually means it was a duplicate)').format(
             uploading_user=self.queued_image.user.username)
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-ignore',
             ip_address=get_client_ip(self.request),
             popit_person_new_version='',
             popit_person_id=self.queued_image.popit_person_id,
             source=update_message,
         )
         flash(
             messages.INFO,
             _(u'You indicated a photo upload for {0} should be ignored').format(
                 candidate_link
             )
         )
     else:
         raise Exception("BUG: unexpected decision {0}".format(decision))
     return HttpResponseRedirect(reverse('photo-review-list'))
Exemple #37
0
    def save(self, request):
        with transaction.atomic():
            instance = super().save(commit=False)
            instance.ballot = self.ballot
            instance.user = (
                request.user if request.user.is_authenticated else None
            )
            instance.ip_address = get_client_ip(request)
            instance.save()

            fields_with_values = [
                x.value() for x in self.membership_fields() if x.value()
            ]
            winners = {}
            if len(fields_with_values) == len(self.membership_fields()):
                winner_count = self.ballot.winner_count
                if winner_count:
                    winners = dict(
                        sorted(
                            [
                                (
                                    "{}-{}".format(
                                        self[y].value(), x.person.id
                                    ),
                                    x,
                                )
                                for x, y in self.memberships
                            ],
                            reverse=True,
                            key=lambda votes: int(votes[0].split("-")[0]),
                        )[:winner_count]
                    )
                else:
                    winners = {}

            if winners:
                self.ballot.membership_set.update(elected=None)
            recorder = RecordBallotResultsHelper(self.ballot, instance.user)
            for membership, field_name in self.memberships:
                if not self[field_name].value():
                    continue
                winner = bool(membership in winners.values())
                instance.candidate_results.update_or_create(
                    membership=membership,
                    defaults={
                        "is_winner": winner,
                        "num_ballots": self[field_name].value(),
                    },
                )
                if winner:
                    recorder.mark_person_as_elected(
                        membership.person, source=instance.source
                    )

            instance.record_version()

            LoggedAction.objects.create(
                user=instance.user,
                action_type="entered-results-data",
                source=instance.source,
                ballot=instance.ballot,
            )

        return instance
Exemple #38
0
 def form_valid(self, form):
     decision = form.cleaned_data['decision']
     if decision == 'approved':
         # Crop the image...
         self.crop_and_upload_image_to_popit(
             self.queued_image.image.path, [
                 form.cleaned_data[e]
                 for e in ('x_min', 'y_min', 'x_max', 'y_max')
             ], form.cleaned_data['moderator_why_allowed'])
         self.queued_image.decision = 'approved'
         self.queued_image.save()
         # Now create a new version in PopIt:
         person_data, _ = self.get_person(self.queued_image.popit_person_id)
         previous_versions = person_data.pop('versions')
         update_message = (
             u'Approved a photo upload from ' +
             u'{uploading_user} who provided the message: ' +
             u'"{message}"').format(
                 uploading_user=self.queued_image.user.username,
                 message=self.queued_image.justification_for_use,
             )
         change_metadata = get_change_metadata(self.request, update_message)
         self.update_person(
             person_data,
             change_metadata,
             previous_versions,
         )
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-approve',
             ip_address=get_client_ip(self.request),
             popit_person_new_version=change_metadata['version_id'],
             popit_person_id=self.queued_image.popit_person_id,
             source=update_message,
         )
         candidate_path = reverse(
             'person-view',
             kwargs={'person_id': self.queued_image.popit_person_id})
         self.send_mail(
             'YourNextMP image upload approved',
             render_to_string(
                 'moderation_queue/photo_approved_email.txt', {
                     'candidate_page_url':
                     self.request.build_absolute_uri(candidate_path)
                 }),
         )
     elif decision == 'rejected':
         self.queued_image.decision = 'rejected'
         self.queued_image.save()
         update_message = u'Rejected a photo upload from ' + \
             u'{uploading_user}'.format(
             uploading_user=self.queued_image.user.username,
         )
         LoggedAction.objects.create(
             user=self.request.user,
             action_type='photo-reject',
             ip_address=get_client_ip(self.request),
             popit_person_new_version='',
             popit_person_id=self.queued_image.popit_person_id,
             source=update_message,
         )
         self.send_mail(
             'YourNextMP image moderation results',
             render_to_string(
                 'moderation_queue/photo_rejected_email.txt',
                 {'reason': form.cleaned_data['rejection_reason']}),
         )
     elif decision == 'undecided':
         # If it's left as undecided, just redirect back to the
         # photo review queue...
         pass
     elif decision == 'ignore':
         self.queued_image.decision = 'ignore'
         self.queued_image.save()
     else:
         raise Exception("BUG: unexpected decision {0}".format(decision))
     return HttpResponseRedirect(reverse('photo-review-list'))
    def form_valid(self, form):
        decision = form.cleaned_data["decision"]
        person = Person.objects.get(id=self.queued_image.person.id)

        candidate_path = person.get_absolute_url()
        candidate_name = person.name
        candidate_link = '<a href="{url}">{name}</a>'.format(
            url=candidate_path, name=candidate_name)
        photo_review_url = self.request.build_absolute_uri(
            self.queued_image.get_absolute_url())
        site_name = Site.objects.get_current().name

        def flash(level, message):
            messages.add_message(self.request,
                                 level,
                                 message,
                                 extra_tags="safe photo-review")

        if self.queued_image.user:
            uploaded_by = self.queued_image.user.username
        else:
            uploaded_by = _("a script")

        if decision == "approved":
            # Crop the image...
            crop_fields = ("x_min", "y_min", "x_max", "y_max")
            self.crop_and_upload_image_to_popit(
                self.queued_image.image.file,
                [form.cleaned_data[e] for e in crop_fields],
                form.cleaned_data["moderator_why_allowed"],
                form.cleaned_data["make_primary"],
            )
            self.queued_image.decision = "approved"
            for i, field in enumerate(crop_fields):
                setattr(self.queued_image, "crop_" + field,
                        form.cleaned_data[field])
            self.queued_image.save()

            sentence = "Approved a photo upload from {uploading_user}"
            ' who provided the message: "{message}"'

            update_message = _(sentence).format(
                uploading_user=uploaded_by,
                message=self.queued_image.justification_for_use,
            )
            change_metadata = get_change_metadata(self.request, update_message)
            person.record_version(change_metadata)
            person.save()
            person.save()
            LoggedAction.objects.create(
                user=self.request.user,
                action_type="photo-approve",
                ip_address=get_client_ip(self.request),
                popit_person_new_version=change_metadata["version_id"],
                person=person,
                source=update_message,
            )
            candidate_full_url = self.request.build_absolute_uri(
                person.get_absolute_url(self.request))

            self.send_mail(
                _("{site_name} image upload approved").format(
                    site_name=site_name),
                render_to_string(
                    "moderation_queue/photo_approved_email.txt",
                    {
                        "site_name":
                        site_name,
                        "candidate_page_url":
                        candidate_full_url,
                        "intro":
                        _("Thank you for submitting a photo to "
                          "{site_name}. It has been uploaded to "
                          "the candidate page here:").format(
                              site_name=site_name),
                        "signoff":
                        _("Many thanks from the {site_name} volunteers").
                        format(site_name=site_name),
                    },
                ),
            )
            flash(
                messages.SUCCESS,
                _("You approved a photo upload for %s") % candidate_link,
            )
        elif decision == "rejected":
            self.queued_image.decision = "rejected"
            self.queued_image.save()

            sentence = "Rejected a photo upload from {uploading_user}"

            update_message = _(sentence).format(uploading_user=uploaded_by)
            LoggedAction.objects.create(
                user=self.request.user,
                action_type="photo-reject",
                ip_address=get_client_ip(self.request),
                popit_person_new_version="",
                person=person,
                source=update_message,
            )
            retry_upload_link = self.request.build_absolute_uri(
                reverse(
                    "photo-upload",
                    kwargs={"person_id": self.queued_image.person.id},
                ))
            self.send_mail(
                _("{site_name} image moderation results").format(
                    site_name=Site.objects.get_current().name),
                render_to_string(
                    "moderation_queue/photo_rejected_email.txt",
                    {
                        "reason":
                        form.cleaned_data["rejection_reason"],
                        "retry_upload_link":
                        retry_upload_link,
                        "photo_review_url":
                        photo_review_url,
                        "intro":
                        _("Thank-you for uploading a photo of "
                          "{candidate_name} to {site_name}, "
                          "but unfortunately we can't use that image because:"
                          ).format(candidate_name=candidate_name,
                                   site_name=site_name),
                        "possible_actions":
                        _("You can just reply to this email if you want to "
                          "discuss that further, or you can try uploading a "
                          "photo with a different reason or justification "
                          "for its use using this link:"),
                        "signoff":
                        _("Many thanks from the {site_name} volunteers").
                        format(site_name=site_name),
                    },
                ),
                email_support_too=True,
            )
            flash(
                messages.INFO,
                _("You rejected a photo upload for %s") % candidate_link,
            )
        elif decision == "undecided":
            # If it's left as undecided, just redirect back to the
            # photo review queue...
            flash(
                messages.INFO,
                _("You left a photo upload for {0} in the queue").format(
                    candidate_link),
            )
        elif decision == "ignore":
            self.queued_image.decision = "ignore"
            self.queued_image.save()

            sentence = "Ignored a photo upload from {uploading_user}"
            " (This usually means it was a duplicate)"

            update_message = _(sentence).format(uploading_user=uploaded_by)
            LoggedAction.objects.create(
                user=self.request.user,
                action_type="photo-ignore",
                ip_address=get_client_ip(self.request),
                popit_person_new_version="",
                person=person,
                source=update_message,
            )
            flash(
                messages.INFO,
                _("You indicated a photo upload for {0} should be ignored").
                format(candidate_link),
            )
        else:
            raise Exception("BUG: unexpected decision {}".format(decision))
        return HttpResponseRedirect(reverse("photo-review-list"))