def retrieve(self, request, field_id=None): """ List AFSIS for a particular field --- responseMessages: - code: 401 message: Not authenticated - code: 200 message: OK produces: - application/json """ user_data, user = verify_auth_token(request) if user_data != {} or user["paymentLevels"] != "SECOND LEVEL": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "": user["uid"] = user["memberOf"] field_afsis_obj = AFSISIndicators.objects.filter(user_id=user["uid"], field_id=field_id) serializer = GetAFSISIndicatorsSerializer(field_afsis_obj, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
def monthly_delete(request): user_data, user = verify_auth_token(request) if user_data != {} or user["memberOf"] != "" or user[ "paymentLevels"] != "SECOND LEVEL": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) old_date = datetime.now() - timedelta(days=365) old_data = WeeklyFieldIndicators.objects.filter( date_observed__lte=old_date).order_by("date_observed") if len(old_data): for data_ in old_data: data_.soft_delete() deleted_date1, deleted_date2 = old_data[0].date_observed, old_data[ len(old_data) - 1].date_observed deleted_date1, deleted_date2 = deleted_date1.strftime( "%d-%m-%Y"), deleted_date2.strftime("%d-%m-%Y") return Response( { "message": f"Weekly data has been softly deleted. Dates captured are: {deleted_date1, deleted_date2}" }, status=status.HTTP_204_NO_CONTENT) return Response({"message": "No existing data for deletion"}, status=status.HTTP_200_OK)
def retrieve(self, request, field_id=None): """ To list all the indicators for a particular field --- responseMessages: - code: 401 message: Not authenticated - code: 200 message: OK produces: - application/json """ user_data, user = verify_auth_token(request) if user_data != {}: return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "": user["uid"] = user["memberOf"] field_ndvi_obj = ArrayedFieldIndicators.objects.filter( user_id=user["uid"], field_id=field_id) serializer = GetFieldIndicatorsSerializer(field_ndvi_obj, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
def list(self, request): """ To list all the indicators for all fields --- produces: - application/json """ user_data, user = verify_auth_token(request) if user_data != {}: return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "": user["uid"] = user["memberOf"] queryset = ArrayedFieldIndicators.objects.filter(user_id=user["uid"]) page = self.paginate_queryset(queryset) if page is not None: serializer = GetFieldIndicatorsSerializer(page, many=True) return self.get_paginated_response(serializer.data) else: serializer = GetFieldIndicatorsSerializer(queryset, many=True) # import json; # with open('moringa_2019_2020.json', 'w') as fa_: # json.dump(serializer.data, fa_) return Response(serializer.data, status=status.HTTP_200_OK)
def contact_us(request): user_data, user = verify_auth_token(request) if not user_data: return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if not user_data.get('message'): return Response({"Error": "Message has been sent"}, status=status.HTTP_400_BAD_REQUEST) EmailThread(user["uid"], user_data.get('message')).start() return Response({"Messsage": "Email sent"}, status=status.HTTP_200_OK)
def create(self, request, uu_id): serializer_data, user = verify_auth_token(request) if not serializer_data: return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) serializer = self.serializer_class(data=serializer_data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED)
def create(self, request, field_id=None): serializer_data, user = verify_auth_token(request) if not serializer_data or user["memberOf"] != "": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) serializer_data['user_id'] = user["uid"] serializer = self.serializer_class(data=serializer_data) # serializer.is_valid(raise_exception=True) # serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED)
def list(self, request): user_data, user = verify_auth_token(request) if user_data != {}: return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "": user["uid"] = user["memberOf"] queryset = ForeCastIndicators.objects.filter(user_id=user["uid"]) serializer = GetForeCastIndicatorsSerializer(queryset, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
def retrieve(self, request, field_id=None): """ To list all the indicators for a particular field --- responseMessages: - code: 401 message: Not authenticated - code: 200 message: OK produces: - application/json """ user_data, user = verify_auth_token(request) if user_data != {} or user["paymentLevels"] != "SECOND LEVEL": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "" or user["paymentLevels"] != "SECOND LEVEL": user["uid"] = user["memberOf"] earliest_month = datetime.now() - timedelta(days=42) earliest_month = earliest_month.strftime("%B").lower() earliest_month = request.query_params.get("earliest_month", earliest_month) if earliest_month not in MONTHS_: return Response( {"Error": f"Month passed should be among: {MONTHS_}"}, status=status.HTTP_403_FORBIDDEN) if type(earliest_month) == str: year = datetime.now().year if MONTHS_.index( earliest_month) + 1 - datetime.now().month < 0 else ( datetime.now() - timedelta(days=366)).year earliest_month = datetime.strptime( f"{earliest_month.capitalize()}/{year}", "%B/%Y") #.strftime("%Y-%m-%d") field_ndvi_obj = WeeklyFieldIndicators.objects.filter( user_id=user["uid"], date_observed__gte=earliest_month, field_id=field_id).order_by("-date_observed") serializer = GetWeeklyFieldIndicatorsSerializer(field_ndvi_obj, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
def list(self, request): """ To list all the weekly indicators for all the fields --- produces: - application/json """ user_data, user = verify_auth_token(request) if user_data != {} or user["paymentLevels"] != "SECOND LEVEL": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "": user["uid"] = user["memberOf"] earliest_month = datetime.now() - timedelta(days=42) earliest_month = earliest_month.strftime("%B").lower() earliest_month = request.query_params.get("earliest_month", earliest_month) if earliest_month not in MONTHS_: return Response( {"Error": f"Month passed should be among: {MONTHS_}"}, status=status.HTTP_403_FORBIDDEN) if type(earliest_month) == str: # TODO: This line below is iffy. now is november...earliest is feb...calculate year = datetime.now().year if MONTHS_.index( earliest_month) + 1 - datetime.now().month < 0 else ( datetime.now() - timedelta(days=366)).year earliest_month = datetime.strptime( f"{earliest_month.capitalize()}/{year}", "%B/%Y") queryset = WeeklyFieldIndicators.objects.filter( user_id=user["uid"], date_observed__gte=earliest_month).order_by("-date_observed") page = self.paginate_queryset(queryset) if page is not None: serializer = GetWeeklyFieldIndicatorsSerializer(page, many=True) return self.get_paginated_response(serializer.data) else: serializer = GetWeeklyFieldIndicatorsSerializer(queryset, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
def put(self, request, field_id=None): serializer_data, user = verify_auth_token(request) if not serializer_data or user["memberOf"] != "": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) # check this line in the previous view serializer_data['user_id'] = user["uid"] try: forecast_obj = ForeCastIndicators.objects.get(user_id=user["uid"], field_id=field_id) serializer = self.serializer_class(forecast_obj, data=request.data) # serializer.is_valid(raise_exception=True) # serializer.save() except ForeCastIndicators.DoesNotExist: serializer_data['user_id'] = user["uid"] serializer = self.serializer_class(data=serializer_data) # serializer.is_valid(raise_exception=True) # serializer.save() return Response(serializer.data, status=status.HTTP_200_OK)
def put(self, request, uu_id): serializer_data, user = verify_auth_token(request) if not serializer_data: return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) serializer_data["properties"]['user_id'] = user["uid"] request.data["properties"]['user_id'] = user["uid"] try: user_obj = ShUserDetail.objects.get(user_id=user["uid"]) serializer = self.serializer_class(user_obj, data=request.data) serializer.is_valid(raise_exception=True) serializer.save() except ShUserDetail.DoesNotExist: serializer = self.serializer_class(data=serializer_data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_200_OK)
def get(self, request, uu_id): user_data, user = verify_auth_token(request) if user_data != {}: return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) try: user_obj = ShUserDetail.objects.get(user_id=user["uid"]) serializer = self.serializer_class(user_obj) return Response( { "current_center": serializer.data, "user_detail": user }, status=status.HTTP_200_OK) except ShUserDetail.DoesNotExist: return Response({ "current_center": None, "user_detail": user }, status=status.HTTP_200_OK)
def update(self, request, indicator=None): serializer_data, user = verify_auth_token(request) if not serializer_data or user["memberOf"] != "": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) # check this line in the previous view serializer_data['user_id'] = user["uid"] try: field_ndvi_obj = FieldIndicatorCalculations.objects.get( user_id=user["uid"], indicator=indicator, crop_type=request.data["crop_type"]) serializer = self.serializer_class(field_ndvi_obj, data=request.data) # serializer.is_valid(raise_exception=True) # serializer.save() except FieldIndicatorCalculations.DoesNotExist: serializer_data['user_id'] = user["uid"] serializer = self.serializer_class(data=serializer_data) # serializer.is_valid(raise_exception=True) # serializer.save() return Response(serializer.data, status=status.HTTP_200_OK)
def list(self, request): """ List AFSIS for fields --- produces: - application/json """ user_data, user = verify_auth_token(request) if user_data != {} or user["paymentLevels"] != "SECOND LEVEL": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "": user["uid"] = user["memberOf"] queryset = AFSISIndicators.objects.filter(user_id=user["uid"]) page = self.paginate_queryset(queryset) if page is not None: serializer = GetAFSISIndicatorsSerializer(page, many=True) return self.get_paginated_response(serializer.data) else: serializer = GetAFSISIndicatorsSerializer(queryset, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
def wider_area(request): """Get all or fitlered wider area. """ serializer_data, user = verify_auth_token(request) if not serializer_data or user["paymentLevels"] != "SECOND LEVEL" or user[ "memberOf"] != "61164207eaef91000adcfeab": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) # NOTE: To be used for storing creds, the memberOf id I mean if user["memberOf"] != "": user["uid"] = user["memberOf"] #TODO: to be generated from user_auth client_auth = (os.getenv("GEOSERVER_NAME", ""), os.getenv("GEOSERVER_PASSWORD", "")) headers = {'Content-Type': 'application/json'} #Data Link get_data_url = os.getenv( "GEOSERVER_URL", "") #nigeria_HT_grid&outputFormat=application%2Fjson' #First Generate List of AOI. #For each area/maybe when selected set the client_aoi client_aoi = 'kenya_HT_grid' client_aoi_summary = 'kenya_Grid_Summary' #The thresholds would apply when the data has been filtered on the platform and then the download button clicked. #Or if not prefiltered the default is no filter applied bu tthe user may specify which values they want to remove anyways via modal. #filterRequestCapability add '&cql_filter=slope%3E40' summary_request_url = f"{get_data_url}{client_aoi_summary}&outputFormat=application%2Fjson" summary_r = requests.get(summary_request_url, headers=headers, auth=client_auth) if summary_r.status_code == 200: summary_r = summary_r.json() summary_r = summary_r["features"][0]['properties'] else: return Response({"Error": "Issue with third-party server"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) # fcc = fertility capability classification | lc - land cover filters_ = [ 'slope', 'elevation', 'land cover', 'fertility capability classification' ] if request.data.keys(): param_filters = request.data.keys() for key_ in param_filters: if key_ not in filters_: return Response({"Error": f"Available filters are {filters_}"}, status=status.HTTP_400_BAD_REQUEST) param_values = chain.from_iterable(request.data.values()) if not all(isinstance(val_, int) for val_ in param_values): return Response( {"Error": f"Ensure values are used for all filters"}, status=status.HTTP_400_BAD_REQUEST) if not all(val_ <= 9700 or val_ > 0 for val_ in param_values): return Response( { "Error": "Maximum available value is 9700 for fertility-capability-classification. Min value is 0 for all" }, status=status.HTTP_400_BAD_REQUEST) filter_query = '&cql_filter=' for key_, val_ in request.data.items(): if key_ == "land cover" or key_ == "fertility capability classification": key_ = "".join([x[0] for x in key_.split(" ")]) query_ = f"{key_} between {val_[0]} and {val_[1]} and " filter_query += query_ # remove last " and " filter_query = filter_query[:-5] filtered_request_url = f"{get_data_url}{client_aoi}{filter_query}&outputFormat=application%2Fjson" filtered_r = requests.get(filtered_request_url, headers=headers, auth=client_auth) if filtered_r.status_code == 200: filtered_data = filtered_r.json() return Response({ "Bounds": summary_r, "Grid": filtered_data }, status=status.HTTP_200_OK) return Response({"Error": "Issue with third-party server"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) #Can be heavy result, but can load a tiff of the file, rather than the geojson, much lighter. slightly interactible. response = requests.get( f'{get_data_url}{client_aoi}&outputFormat=application%2Fjson', headers=headers, auth=client_auth) if response.status_code == 200: wider_area_data = response.json() return Response({ "Bounds": summary_r, "Grid": wider_area_data }, status=status.HTTP_200_OK) return Response({"Error": "Issue with third-party server"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def list(self, request): """ Query weekly field indicators using thresholds """ user_data, user = verify_auth_token(request) if user_data != {} or user["paymentLevels"] != "SECOND LEVEL": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "": user["uid"] = user["memberOf"] kator_thresholds = { "field_ndvi": [0.2, None], "field_precipitation": [3, None], "field_ndwi": [0, 0.3], "field_temperature": [15, 35] } indicator = request.query_params.get("indicator", "field_ndvi") below = request.query_params.get("below", kator_thresholds[indicator][0]) above = request.query_params.get("above", kator_thresholds[indicator][1]) precip_sub = deepcopy(available_indicators) precip_sub[0] = "field_precipitation" if indicator not in precip_sub: return Response( {"Error": f"Available indicators are: {precip_sub}"}, status=status.HTTP_400_BAD_REQUEST) try: if (above and float(above) > 1000) or float(below) < -1000: return Response( { "Error": f"Issue with below and above values: {below}, {above}" }, status=status.HTTP_400_BAD_REQUEST) except ValueError as e: return Response( {"Error": "Below and above values should be integers"}, status=status.HTTP_400_BAD_REQUEST) earliest_month = datetime.now() - timedelta(days=42) earliest_month = earliest_month.strftime("%B").lower() earliest_month = request.query_params.get("earliest_month", earliest_month) if earliest_month not in MONTHS_: return Response( {"Error": f"Month passed should be among: {MONTHS_}"}, status=status.HTTP_400_BAD_REQUEST) # Add +1 because datetime.now().month count is from 1 year = datetime.now().year if MONTHS_.index( earliest_month) + 1 - datetime.now().month < 0 else ( datetime.now() - timedelta(days=366)).year earliest_month = datetime.strptime( f"{earliest_month.capitalize()}/{year}", "%B/%Y") # https://stackoverflow.com/a/11442041 ** translates k:v to k=v query_dict_ = {f"{indicator}__lt": below} if above: query_dict_[f"{indicator}__gt"] = above queryset = WeeklyFieldIndicators.objects.filter( user_id=user["uid"], date_observed__gte=earliest_month, **query_dict_).order_by(f"-date_observed") page = self.paginate_queryset(queryset) if page is not None: serializer = GetWeeklyFieldIndicatorsSerializer(page, many=True) return self.get_paginated_response(serializer.data) else: serializer = GetWeeklyFieldIndicatorsSerializer(queryset, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
def list(self, request): """ Query weekly NDVI Changes """ user_data, user = verify_auth_token(request) if user_data != {} or user["paymentLevels"] != "SECOND LEVEL": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "": user["uid"] = user["memberOf"] earliest_month = datetime.now() - timedelta(days=42) earliest_month = earliest_month.strftime("%B").lower() earliest_month = request.query_params.get("earliest_month", earliest_month) if earliest_month not in MONTHS_: return Response( {"Error": f"Month passed should be among: {MONTHS_}"}, status=status.HTTP_403_FORBIDDEN) if type(earliest_month) == str: year = datetime.now().year if MONTHS_.index( earliest_month) + 1 - datetime.now().month < 0 else ( datetime.now() - timedelta(days=366)).year earliest_month = datetime.strptime( f"{earliest_month.capitalize()}/{year}", "%B/%Y") #.strftime("%Y-%m-%d") queryset = WeeklyFieldIndicators.objects.filter( user_id=user["uid"], date_observed__gte=earliest_month).order_by("-date_observed") def get_differences(results_): group_fids = [] list_results = list(results_.data) # groupby needs the sorting list_results.sort(key=lambda x: x["field_id"]) for k, g in groupby(list_results, key=lambda x: x["field_id"]): group_fids.append(list(g)) for field_data in group_fids: for i, row_ in enumerate(field_data): try: row_[ f"{row_['date_observed']} - {field_data[i+1]['date_observed']}"] = row_[ "field_ndvi"] - field_data[i + 1]["field_ndvi"] for kator in available_indicators: try: del row_[kator] except KeyError: del row_["field_precipitation"] del row_['date_observed'] except IndexError: continue # exclude last element in the group since it wasn't subtracted from anything results_ = list( chain.from_iterable([el[:len(el) - 1] for el in group_fids])) return results_ page = self.paginate_queryset(queryset) if page is not None: results_ = GetWeeklyFieldIndicatorsSerializer(page, many=True) results_ = get_differences(results_) return self.get_paginated_response(results_) else: results_ = GetWeeklyFieldIndicatorsSerializer(queryset, many=True) results_ = get_differences(results_) return Response(results_, status=status.HTTP_200_OK)
def list(self, request): """ Query Top and bottom performing fields """ user_data, user = verify_auth_token(request) if user_data != {} or user["paymentLevels"] != "SECOND LEVEL": return Response({"Error": "Unauthorized request"}, status=status.HTTP_403_FORBIDDEN) if user["memberOf"] != "": user["uid"] = user["memberOf"] previous_month = datetime.now() - timedelta(days=31) previous_month = previous_month.strftime("%B").lower() indicator = request.query_params.get("indicator", "field_rainfall") month_ = request.query_params.get("month", previous_month) try: week_ = int(request.query_params.get("week", 4)) except ValueError: return Response( {"Error": "Week value should be an integer from 1 to 4"}, status=status.HTTP_400_BAD_REQUEST) position = request.query_params.get("position", "top") percentage = request.query_params.get("percentage", 15) if not isinstance(week_, int) or week_ > 4 or week_ < 0: return Response( {"Error": "Week value should be an integer from 1 to 4"}, status=status.HTTP_400_BAD_REQUEST) if month_ not in MONTHS_: return Response( { "Error": "Month provided should be of lower case, like: january" }, status=status.HTTP_400_BAD_REQUEST) year_ = datetime.now().year if MONTHS_.index(month_)+1 - datetime.now().month < 0\ else (datetime.now() - timedelta(days=366)).year month_ = MONTHS_.index(month_) + 1 # monthrange is because some months are 30,31,28. # Also, subtracting the previous 31 days is so we can add on the weeks specified date_ = date(year_, month_, monthrange(year_, month_)[1]) - timedelta( days=31) + timedelta(weeks=week_) if position not in ["top", "bottom"]: return Response( {"Error": "Position should be either top or bottom"}, status=status.HTTP_400_BAD_REQUEST) if indicator not in available_indicators: return Response( {"Error": f"Available indicators are: {available_indicators}"}, status=status.HTTP_400_BAD_REQUEST) try: if int(percentage) < 0 or int(percentage) > 100: return Response( { "Error": "Optimal percentage range should be between 1 and 50" }, status=status.HTTP_400_BAD_REQUEST) except ValueError as e: return Response( { "Error": "Optimal percentage range should be between 1 and 50" }, status=status.HTTP_400_BAD_REQUEST) queryset = WeeklyFieldIndicators.objects.filter( user_id=user["uid"], date_observed__gte=date_).order_by("date_observed", f"-{indicator}") group_qset = [ list(v) for k, v in groupby(queryset, lambda row: row.date_observed) ] if position == "top": group_qset = [ grp[:round(len(grp) * int(percentage) / 100)] for grp in group_qset ] queryset = list(chain.from_iterable(group_qset)) elif position == "bottom": group_qset = [ grp[len(grp) - round(len(grp) * int(percentage) / 100):] for grp in group_qset ] queryset = list(chain.from_iterable(group_qset)) page = self.paginate_queryset(queryset) if page is not None: serializer = GetWeeklyFieldIndicatorsSerializer(page, many=True) return self.get_paginated_response(serializer.data) else: serializer = GetWeeklyFieldIndicatorsSerializer(queryset, many=True) return Response(serializer.data, status=status.HTTP_200_OK)