示例#1
0
    def approve_and_add(self, request, pk=None, format=None):
        stall = self.get_object()
        if stall.status != StallStatus.PENDING:
            raise BadRequest("Stall is not pending")

        if stall.election.polling_places_loaded is True:
            raise BadRequest("Election polling places already loaded")

        # Create polling place based on user-submitted location info
        pollingPlaceSerializer = PollingPlacesManagementSerializer(data={
            "geom": stall.location_info["geom"],
            "name": stall.location_info["name"],
            "address": stall.location_info["address"],
            "state": stall.location_info["state"],
            "facility_type": None,
            "election": stall.election.id,
            "status": PollingPlaceStatus.ACTIVE,
        })

        if pollingPlaceSerializer.is_valid() is True:
            pollingPlaceSerializer.save()
        else:
            raise BadRequest(pollingPlaceSerializer.errors)

        # Now that we have a polling place, add noms
        pollingPlaceWithNomsSerializer = PollingPlacesManagementSerializer(pollingPlaceSerializer.instance, data={"stall": {
            "noms": stall.noms,
            "name": stall.name,
            "description": stall.description,
            "opening_hours": stall.opening_hours,
            "website": stall.website,
        }, }, partial=True)

        if pollingPlaceWithNomsSerializer.is_valid() is True:
            pollingPlaceWithNomsSerializer.save()
        else:
            raise BadRequest(pollingPlaceWithNomsSerializer.errors)

        # Approve stall and link it to the new unofficial polling place we just added
        serializer = StallsManagementSerializer(stall, data={
            "status": StallStatus.APPROVED,
            "approved_on": datetime.now(pytz.utc),
            "polling_place": pollingPlaceSerializer.instance.id
        }, partial=True)
        if serializer.is_valid() is True:
            serializer.save()

            send_stall_approved_email(Stalls.objects.get(id=stall.id))
            return Response({})
        else:
            raise BadRequest(serializer.errors)
示例#2
0
 def without_facility_type(self, request, format=None):
     election_id = request.query_params.get("election_id", None)
     if election_id is not None:
         serializer = self.serializer_class(self.queryset.filter(election_id=election_id).filter(facility_type__isnull=True), many=True)
         return Response(serializer.data)
     else:
         raise BadRequest("No election_id provided.")
示例#3
0
    def retrieve(self, request, *args, **kwargs):
        stall = self.get_object()

        if stall.election.is_active() is False:
            raise BadRequest("The {election_name} election has already finished.".format(election_name=stall.election.name))

        return super(StallsViewSet, self).retrieve(request, *args, **kwargs)
示例#4
0
    def run(self):
        if self.can_loading_begin() is False:
            self.logger.error("Loading can't begin. There's probably pending stalls.")
        else:
            self.invoke_and_bail_if_errors("convert_to_demsausage_schema")
            self.invoke_and_bail_if_errors("check_file_validity")
            self.invoke_and_bail_if_errors("fix_polling_places")
            self.invoke_and_bail_if_errors("prepare_polling_places")
            self.invoke_and_bail_if_errors("geocode_missing_locations")
            self.invoke_and_bail_if_errors("check_polling_place_validity")
            self.invoke_and_bail_if_errors("dedupe_polling_places")

            with transaction.atomic():
                self.invoke_and_bail_if_errors("write_draft_polling_places")
                self.invoke_and_bail_if_errors("migrate_noms")
                self.invoke_and_bail_if_errors("migrate")

                if self.is_dry_run() is True:
                    # Regenerate GeoJSON because the loader does this and transactions don't help us here :)
                    regenerate_election_geojson(self.election.id)
                    raise BadRequest({"message": "Rollback", "logs": self.collects_logs()})
            
            if self.is_dry_run() is False:
                # Use a transaction to speed up all of the update calls in here
                with transaction.atomic():
                    self.invoke_and_bail_if_errors("detect_facility_type")
                    self.invoke_and_bail_if_errors("calculate_chance_of_sausage")
                    self.invoke_and_bail_if_errors("cleanup")
            
            print("All done with loading")
示例#5
0
    def approve(self, request, pk=None, format=None):
        stall = self.get_object()
        if stall.status != StallStatus.PENDING:
            raise BadRequest("Stall is not pending")

        serializer = StallsManagementSerializer(self.get_object(), data={
            "status": StallStatus.APPROVED,
            "approved_on": datetime.now(pytz.utc)
        }, partial=True)
        if serializer.is_valid() is True:
            serializer.save()

            send_stall_approved_email(Stalls.objects.get(id=stall.id))
            return Response({})
        else:
            raise BadRequest(serializer.errors)
示例#6
0
 def favourited(self, request, format=None):
     election_id = request.query_params.get("election_id", None)
     if election_id is not None:
         serializer = self.serializer_class(self.queryset.filter(election_id=election_id).filter(noms__isnull=False, noms__favourited=True).order_by("-noms__id"), many=True)
         return Response(serializer.data)
     else:
         raise BadRequest("No election_id provided.")
示例#7
0
    def set_primary(self, request, pk=None, format=None):
        self.get_queryset().filter(is_primary=True).update(is_primary=False)

        serializer = ElectionsSerializer(self.get_object(), data={"is_primary": True}, partial=True)
        if serializer.is_valid() is True:
            serializer.save()
            return Response({})
        else:
            raise BadRequest(serializer.errors)
示例#8
0
    def is_valid(self):
        searchParams = list(self.get_fields().keys())
        queryParams = list(self.request.query_params.keys())

        if is_one_of_these_things_in_this_other_thing(searchParams,
                                                      queryParams) is False:
            raise BadRequest("Please supply a filter criteria: {}".format(
                ", ".join(searchParams)))
        return super(PollingPlacesSearchFilter, self).is_valid()
示例#9
0
    def create(self, request, format=None):
        serializer = StallsManagementSerializer(data=request.data)
        if serializer.is_valid() is True:
            serializer.save()

            send_stall_submitted_email(Stalls.objects.get(id=serializer.instance.id))
            return Response({}, status=status.HTTP_201_CREATED)
        else:
            raise BadRequest(serializer.errors)
示例#10
0
 def filter(self, qs, value):
     if value == []:
         raise BadRequest("Please supply at least one value to filter by")
     elif value is not None:
         for search_term in value:
             qs = qs.filter(
                 Q(name__icontains=search_term)
                 | Q(premises__icontains=search_term)
                 | Q(address__icontains=search_term))
     return qs
示例#11
0
    def nearby_bbox(self, request, format=None):
        """
        Retrieve the bounding box of the 15 polling places closest to a given latitude, longitude.

        Uses the same parameters as /polling_places/nearby/
        """
        election_id = request.query_params.get("election_id", None)
        lonlat = request.query_params.get("lonlat", None)

        if election_id is None or election_id == "":
            raise BadRequest("No election_id provided.")

        if lonlat is None or lonlat == "":
            raise BadRequest("No lonlat provided.")

        polling_places_filter = LonLatFilter().filter(PollingPlaces.objects.filter(election_id=election_id).filter(status=PollingPlaceStatus.ACTIVE), lonlat)
        extent = polling_places_filter.annotate(geom_as_geometry=Func("geom", template="geom::geometry")).aggregate(Extent("geom_as_geometry"))

        return Response({"extent_wgs84": extent["geom_as_geometry__extent"]})
示例#12
0
    def update_and_resubmit(self, request, pk=None, format=None):
        stall = self.get_object()

        if stall.election.is_active() is False:
            raise BadRequest("The {election_name} election has already finished.".format(election_name=stall.election.name))

        data = deepcopy(request.data)
        del data["token"]
        del data["signature"]
        if stall.status == StallStatus.APPROVED or stall.status == StallStatus.DECLINED:
            data["status"] = StallStatus.PENDING

        serializer = StallsUserEditSerializer(stall, data, partial=True)
        if serializer.is_valid() is True:
            serializer.save()

            send_stall_edited_email(Stalls.objects.get(id=stall.id))
            return Response({})
        else:
            raise BadRequest(serializer.errors)
示例#13
0
    def save_logs(self, logs):
        with open("/app/logs/pollingplaceloader-{}.json".format(datetime.now().strftime("%Y-%m-%dT%H:%M:%S")), "w") as f:
            json.dump(logs, f)

        serializer = PollingPlaceLoaderEventsSerializer(data={
            "timestamp": datetime.now().strftime("%Y-%m-%dT%H:%M:%S"),
            "payload": logs
        })

        if serializer.is_valid() is True:
            serializer.save()
        else:
            raise BadRequest("Error saving logs :(")
示例#14
0
    def stall_lookup(self, request, format=None):
        """
        Lookup the details for an individual polling place by the id of the stall attached to it.
        """
        stall_id = request.query_params.get("stall_id", None)

        if stall_id is not None:
            pollingPlace = find_by_stall(stall_id, self.queryset)
            if pollingPlace is not None:
                return Response(self.serializer_class(pollingPlace).data)
            return HttpResponseNotFound()
        else:
            raise BadRequest("No stall_id provided.")
示例#15
0
    def polling_places_rollback(self, request, pk=None, format=None):
        election = self.get_object()
        dry_run = True if request.data.get("dry_run", None) == "1" else False

        rollback = RollbackPollingPlaces(election, dry_run)
        rollback.run()

        if rollback.is_dry_run() is True:
            # Regenerate GeoJSON because the loader does this and transactions don't help us here :)
            regenerate_election_geojson(election.id)
            raise BadRequest({"message": "Rollback", "logs": rollback.collects_logs()})
        rollback.collects_logs()
        return Response({})
示例#16
0
    def polling_places(self, request, pk=None, format=None):
        election = self.get_object()
        dry_run = True if str(request.data.get("dry_run", 0)) == "1" else False
        config = request.data.get("config", None)
        try:
            if config is not None and len(config) > 0:
                config = json.loads(config)
        except ValueError as e:
            raise BadRequest("Could not parse config: {}".format(e))

        loader = LoadPollingPlaces(election, request.data["file"], dry_run, config)
        loader.run()

        return Response({"message": "Done", "logs": loader.collects_logs()})
示例#17
0
    def lookup(self, request, format=None):
        """
        Lookup the details for an individual polling place by its name + premises + state or its ec_id field.
        """
        election_id = request.query_params.get("election_id", None)
        lookup_terms = {
            "ec_id": request.query_params.get("ec_id", None),
            "name": request.query_params.get("name", None),
            "premises": request.query_params.get("premises", None),
            "state": request.query_params.get("state", None),
        }

        if election_id is not None:
            pollingPlace = find_by_lookup_terms(election_id, lookup_terms, self.queryset)
            if pollingPlace is not None:
                return Response(self.serializer_class(pollingPlace).data)
            return HttpResponseNotFound()
        else:
            raise BadRequest("No election_id provided.")
示例#18
0
    def filter(self, qs, value):
        if value not in (None, ""):
            from django.contrib.gis.geos import Point
            from demsausage.app.sausage.polling_places import find_by_distance

            try:
                lon, lat = [float(v) for v in value[0:1000].split(",")]
                search_point = Point(float(lon), float(lat), srid=4326)
            except Exception as e:
                raise BadRequest(e)

            polling_places_filter = find_by_distance(search_point,
                                                     distance_threshold_km=50,
                                                     limit=15,
                                                     qs=qs)
            if polling_places_filter.count() == 0:
                polling_places_filter = find_by_distance(
                    search_point, distance_threshold_km=1000, limit=15, qs=qs)
            return polling_places_filter
        return qs
示例#19
0
 def raise_exception_if_errors(self):
     if self.has_errors_messages() is True:
         print("Bailing with errors")
         raise BadRequest({"message": "Oh dear, looks like we hit a snag (get it - snag?!)", "logs": self.collects_logs()})
示例#20
0
 def filter(self, qs, value):
     if value == []:
         raise BadRequest("Please supply at least one value to filter by")
     else:
         return super(ValueInFilter, self).filter(qs, value)