Advertisement
Guest User

Untitled

a guest
Jun 20th, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.88 KB | None | 0 0
  1. import os
  2. import logging
  3. import json
  4. from datetime import datetime
  5. from geopy.geocoders import Nominatim
  6. from geopy.distance import geodesic
  7.  
  8. from django.db import models
  9. from rest_framework import generics
  10. from django.shortcuts import get_object_or_404
  11. from gamma.models import Volunteer, Opportunity, Skill, Charity, Signup
  12. from gamma.serializers import VolunteerSerializer, OpportunitySerializer, SkillSerializer, CharitySerializer, SignupSerializer
  13. from django.views.generic import View
  14. from django.http import HttpResponse
  15. from django.http import JsonResponse
  16. from django.conf import settings
  17. from django.core import serializers
  18. from scipy.stats import norm
  19. from django.forms.models import model_to_dict
  20.  
  21. from django.http import HttpResponseRedirect
  22. from django.contrib.auth.models import User
  23. from rest_framework import permissions, status
  24. from rest_framework.decorators import api_view
  25. from rest_framework.response import Response
  26. from rest_framework.views import APIView
  27. from .serializers import UserSerializer, UserSerializerWithToken
  28.  
  29.  
  30. @api_view(['GET'])
  31. def current_user(request):
  32.     """
  33.    Determine the current user by their token, and return their data
  34.    """
  35.  
  36.     serializer = UserSerializer(request.user)
  37.     return Response(serializer.data)
  38.  
  39.  
  40. class UserList(APIView):
  41.     """
  42.    Create a new user. It's called 'UserList' because normally we'd have a get
  43.    method here too, for retrieving a list of all User objects.
  44.    """
  45.  
  46.     permission_classes = (permissions.AllowAny,)
  47.  
  48.     def post(self, request, format=None):
  49.         serializer = UserSerializerWithToken(data=request.data)
  50.         if serializer.is_valid():
  51.             serializer.save()
  52.             return Response(serializer.data, status=status.HTTP_201_CREATED)
  53.         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  54.  
  55. def serialize(obj):
  56.     data = serializers.serialize('json', [ obj, ])
  57.     struct = json.loads(data)
  58.     return json.dumps(struct[0])
  59.  
  60. def volunteer_signups(request):
  61.     params = json.loads(request.body)
  62.     id = params.get('id')
  63.     signups = Signup.objects.filter(volunteer=id)
  64.     res = []
  65.     for signup in signups:
  66.         if (signup.opportunity is None):
  67.             continue
  68.         res.append({"opp" : serialize(signup.opportunity), "accepted" : signup.accepted})
  69.     return JsonResponse(res, safe=False)
  70.  
  71. def charity_signups(request):
  72.     params = json.loads(request.body)
  73.     charity_id = params.get('id')
  74.     signups = Signup.objects.filter(opportunity__charity__id=charity_id)
  75.     data = {}
  76.     for signup in signups:
  77.         if (signup.opportunity.pk not in data):
  78.             data[signup.opportunity.pk] = []
  79.         data[signup.opportunity.pk].append({"vol" : signup.volunteer, "accepted" : signup.accepted, "id" : signup.id })
  80.  
  81.     opportunities = Opportunity.objects.filter(charity=charity_id)
  82.     for opportunity in opportunities:
  83.         if (not opportunity.pk in data):
  84.             data[opportunity.pk] = []
  85.  
  86.     response = []
  87.     for opportunity_id, volunteers in data.items():
  88.         opportunity = Opportunity.objects.get(pk=opportunity_id)
  89.         opportunity_ser = serialize(opportunity)
  90.         volunteers_ser = [{"volunteer" : serialize(volunteer["vol"]),
  91.                            "score" : calculate_score(volunteer["vol"], opportunity),
  92.                            "accepted" : volunteer["accepted"],
  93.                            "signup_id" : volunteer["id"]} for volunteer in volunteers]
  94.         volunteers_ser.sort(key=sortScore, reverse=True)
  95.  
  96.         response.append({"opportunity" : opportunity_ser, "volunteers" : list(map(lambda elem : json.dumps(elem), volunteers_ser))})
  97.  
  98.     return JsonResponse(response, safe=False)
  99.  
  100. def filter_skillbox(opps, skills):
  101.     filter = [skill for skill, bool in skills.items() if bool]
  102.     res = []
  103.     for opp in opps:
  104.         opp_skill = opp.skills
  105.         for skill, value in model_to_dict(opp_skill).items():
  106.             if (value > 0 and skill in filter):
  107.                 res.append(opp)
  108.                 break
  109.     return res
  110.  
  111. def get_skill_incremenet(base, skill, total):
  112.     return base * (skill/total)
  113.  
  114. def verify(request):
  115.     params = json.loads(request.body)
  116.     volunteer = Volunteer.objects.get(id=params['volunteer'])
  117.     opportunity = Opportunity.objects.get(id=params['opportunity'])
  118.     duration = opportunity.duration
  119.     base = 100
  120.     total = 20
  121.  
  122.     volunteer.experiences.communication += duration * get_skill_incremenet(base, opportunity.skills.communication, total)
  123.     volunteer.experiences.technical += duration * get_skill_incremenet(base, opportunity.skills.technical, total)
  124.     volunteer.experiences.finance += duration * get_skill_incremenet(base, opportunity.skills.finance, total)
  125.     volunteer.experiences.marketing += duration * get_skill_incremenet(base, opportunity.skills.marketing, total)
  126.     volunteer.experiences.medical += duration * get_skill_incremenet(base, opportunity.skills.medical, total)
  127.     volunteer.experiences.teamwork += duration * get_skill_incremenet(base, opportunity.skills.teamwork, total)
  128.     volunteer.experiences.problem_solving += duration * get_skill_incremenet(base, opportunity.skills.problem_solving, total)
  129.     volunteer.experiences.creativity += duration * get_skill_incremenet(base, opportunity.skills.creativity, total)
  130.     volunteer.experiences.craftmanship += duration * get_skill_incremenet(base, opportunity.skills.craftmanship, total)
  131.  
  132.     volunteer.experiences.save()
  133.     return HttpResponse('', status=200)
  134.  
  135. def filter_keywords(opps, word):
  136.     word = word.lower()
  137.     return list(filter(lambda opp: word in opp.title.lower() or word in opp.description.lower(), opps))
  138.  
  139. def filter_date(opp_date, start, end):
  140.     format = '%Y-%m-%d'
  141.  
  142.     if (not opp_date):
  143.         return False
  144.  
  145.     try:
  146.         opportunity_date = datetime.strptime(opp_date, format)
  147.     except:
  148.         return False
  149.  
  150.     start_date = datetime.strptime(start, format)
  151.     end_date = datetime.strptime(end, format)
  152.     return start_date <= opportunity_date  and opportunity_date <= end_date
  153.  
  154. def filter_location(opps, location, distance):
  155.     res = []
  156.     geolocator = Nominatim(user_agent="Evolvunteer")
  157.     geo_loc = geolocator.geocode(location)
  158.  
  159.     if(geo_loc is None):
  160.         return res
  161.  
  162.     location_geodesic = (geo_loc.latitude, geo_loc.longitude)
  163.     for opp in opps:
  164.         if (not opp.address):
  165.             continue
  166.         opp_location = geolocator.geocode(opp.address)
  167.  
  168.         if (opp_location is None):
  169.             continue
  170.  
  171.         opp_geodesic = (opp_location.latitude, opp_location.longitude)
  172.  
  173.         if (geodesic(location_geodesic, opp_geodesic).miles <= distance):
  174.             res.append(opp)
  175.     return res
  176.  
  177. def get_search_results(request):
  178.     opps = Opportunity.objects.all()
  179.     params = json.loads(request.body)
  180.  
  181.     if (params['keyword']):
  182.         opps = filter_keywords(opps, params["keyword"])
  183.  
  184.     if (params['skills']):
  185.         opps = filter_skillbox(opps, params['skills'])
  186.  
  187.     if (params['start_date']):
  188.         start = params["start_date"]
  189.         end = params["end_date"]
  190.         opps = list(filter(lambda opp : filter_date(opp.date, start, end), opps))
  191.  
  192.     if (params['location']):
  193.         opps = filter_location(opps, params["location"], 100)
  194.  
  195.     volunteer = Volunteer.objects.get(id=params["id"])
  196.     res = [{"opportunity" : serialize(obj), "score" : calculate_score(volunteer, obj)} for obj in opps]
  197.     res.sort(key=sortScore, reverse=True)
  198.     return JsonResponse(list(map(lambda elem: json.dumps(elem), res)), safe=False)
  199.  
  200. def sortScore(opp):
  201.     return opp["score"]
  202.  
  203. def calculate_score(volunteer, opportunity):
  204.     sum = 0
  205.     res = 0
  206.     base = 20
  207.     vol_skills = model_to_dict(volunteer.skills)
  208.     vol_learnings = model_to_dict(volunteer.learnings)
  209.     op_skills = model_to_dict(opportunity.skills)
  210.     for k, v in vol_skills.items():
  211.         sum += get_skill_score(v, op_skills[k], 2)
  212.         res += (vol_learnings[k] / base) * (op_skills[k] / base)
  213.  
  214.     average_optimality_score = sum / len(vol_skills)
  215.  
  216.     return average_optimality_score
  217.  
  218. def get_skill_score(actual, expected, delta):
  219.     maximum = expected-delta if expected-delta > 0 else 0
  220.     return norm.pdf(actual, maximum, 4)/norm.pdf(maximum, maximum, 4)
  221.  
  222. class ListVolunteers(generics.ListCreateAPIView):
  223.     permission_classes = (permissions.AllowAny,)
  224.  
  225.     queryset = Volunteer.objects.all()
  226.     serializer_class = VolunteerSerializer
  227.  
  228. class CharityList(generics.ListCreateAPIView):
  229.     permission_classes = (permissions.AllowAny,)
  230.  
  231.     queryset = Charity.objects.all()
  232.     serializer_class = CharitySerializer
  233.  
  234. class SignupList(generics.ListCreateAPIView):
  235.     queryset = Signup.objects.all()
  236.     serializer_class = SignupSerializer
  237.  
  238. class DetailSignup(generics.RetrieveUpdateDestroyAPIView):
  239.     queryset = Signup.objects.all()
  240.     serializer_class = SignupSerializer
  241.  
  242. class DetailCharity(generics.RetrieveUpdateDestroyAPIView):
  243.     queryset = Charity.objects.all()
  244.     serializer_class = CharitySerializer
  245.  
  246. class ListOpportunities(generics.ListCreateAPIView):
  247.     queryset = Opportunity.objects.all()
  248.     serializer_class = OpportunitySerializer
  249.  
  250.  
  251. class SearchOpportunities(generics.ListCreateAPIView):
  252.     serializer_class = OpportunitySerializer
  253.  
  254.     @property
  255.     def get_queryset(self):
  256.         return Opportunity.objects.filter(title__regex=r"([a-zA-z ])*%s([a-zA-z ])*" % self.kwargs['title'])
  257.  
  258.  
  259. class DetailVolunteer(generics.RetrieveUpdateDestroyAPIView):
  260.     queryset = Volunteer.objects.all()
  261.     serializer_class = VolunteerSerializer
  262.  
  263. class ListSkill(generics.ListCreateAPIView):
  264.     permission_classes = (permissions.AllowAny,)
  265.  
  266.     queryset = Skill.objects.all()
  267.     serializer_class = SkillSerializer
  268.  
  269. class DetailSkill(generics.RetrieveUpdateDestroyAPIView):
  270.     permission_classes = (permissions.AllowAny,)
  271.  
  272.     queryset = Skill.objects.all()
  273.     serializer_class = SkillSerializer
  274.  
  275. class DetailOpportunities(generics.RetrieveUpdateDestroyAPIView):
  276.     queryset = Opportunity.objects.all()
  277.     serializer_class = OpportunitySerializer
  278.  
  279.  
  280. class FrontendAppView(View):
  281.  
  282.     permission_classes = (permissions.AllowAny,)
  283.  
  284.     def get(self, request):
  285.         try:
  286.  
  287.             with open(os.path.join(settings.REACT_APP_DIR, 'build', 'index.html')) as f:
  288.                 return HttpResponse(f.read())
  289.         except FileNotFoundError:
  290.             logging.exception('Production build of app not found')
  291.             path = os.path.join(settings.REACT_APP_DIR, 'build', 'index.html')
  292.             return HttpResponse(
  293.                 """
  294.                This URL is only used when you have built the production
  295.                version of the app. Visit http://localhost:3000/ instead, or
  296.                run `yarn run build` to test the production version.
  297.  
  298.                Possibly the path %s is incorrect.
  299.                """ % path,
  300.                 status=501,
  301.             )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement