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): 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
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 })
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 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
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"], )
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)
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 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, }, )
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'], )
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 })
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
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} )
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
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'))
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'))
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'))
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
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"))