You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

533 lines
18 KiB

from django.shortcuts import render
from django.http import Http404
from decimal import Decimal
from django.db.models import F, ExpressionWrapper, FloatField, Avg, Prefetch
import datetime
from rest_framework.views import APIView
from rest_framework import viewsets
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.exceptions import PermissionDenied
from .models import (Diet, DietProhibitsIngredient, Drink, DrinkHasIngredient,
Food, FoodHasIngredient, Ingredient, Permission, Restaurant, Role,
RoleHasPermission, User, UserFollowsDiet, UserProhibitsIngredient,
UserRatesDrink, UserRatesFood, UserRatesRestaurant,
)
from .serializers import (
DietSerializer, DietProhibitsIngredientSerializer, DrinkSerializer,
DrinkHasIngredientSerializer, FoodSerializer, FoodHasIngredientSerializer,
IngredientSerializer, PermissionSerializer, RestaurantSerializer,
RoleSerializer, RoleHasPermissionSerializer, UserSerializer,
UserFollowsDietSerializer, UserProhibitsIngredientSerializer,
UserRatesDrinkSerializer, UserRatesFoodSerializer,
UserRatesRestaurantSerializer,
)
class DietViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = Diet.objects.all()
serializer_class = DietSerializer
class DietProhibitsIngredientViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = DietProhibitsIngredient.objects.all()
serializer_class = DietProhibitsIngredientSerializer
class DrinkViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = Drink.objects.all()
serializer_class = DrinkSerializer
class DrinkHasIngredientViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = DrinkHasIngredient.objects.all()
serializer_class = DrinkHasIngredientSerializer
class FoodViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = Food.objects.all()
serializer_class = FoodSerializer
class FoodHasIngredientViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = FoodHasIngredient.objects.all()
serializer_class = FoodHasIngredientSerializer
class IngredientViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = Ingredient.objects.all()
serializer_class = IngredientSerializer
class PermissionViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = Permission.objects.all()
serializer_class = PermissionSerializer
class RestaurantViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get_queryset(self):
user = self.request.user
filterType = self.request.query_params.get('filter_restaurant_type', None)
filterDistanceRadius = self.request.query_params.get('filter_restaurant_radius', None)
filterDistanceLongitude = self.request.query_params.get('filter_restaurant_longitude', None)
filterDistanceLatitude = self.request.query_params.get('filter_restaurant_latitude', None)
filterCalories = self.request.query_params.get('filter_restaurant_calories', None)
restaurants = Restaurant.objects.all()
if filterDistanceRadius is not None:
filterDistanceRadius = float(filterDistanceRadius)
filterDistanceLongitude = float(filterDistanceLongitude)
filterDistanceLatitude = float(filterDistanceLatitude)
import math
restaurants = restaurants.filter(
restaurant_latitude__range=(filterDistanceLatitude-(filterDistanceRadius/111.045),
filterDistanceLatitude+(filterDistanceRadius/111.045)))
restaurants = restaurants.filter(
restaurant_longitude__range=(filterDistanceLongitude-(filterDistanceRadius/(111.045*math.cos(math.radians(filterDistanceLatitude)))),
filterDistanceLongitude+(filterDistanceRadius/(111.045*math.cos(math.radians(filterDistanceLatitude))))))
# ======================================================================================
# WHY THE FUCK DOES BELOW CODE FAIL? :-(
# ======================================================================================
# restaurants = restaurants.annotate(distance =
# 111.045 * math.degrees(math.acos(
# math.cos(math.radians(filterDistanceLatitude))
# * math.cos(math.radians(F('restaurant_latitude')))
# * math.cos(math.radians(filterDistanceLongitude - float(F('restaurant_longitude'))))
# + math.sin(math.radians(filterDistanceLatitude))
# * math.sin(math.radians(F('restaurant_latitude')))
# )))
# restaurants = restaurants.filter(distance__lt=filterDistanceRadius)
# restaurants = restaurants.order_by('distance')
restaurants = restaurants.distinct();
if filterType is not None:
restaurants = restaurants.filter(restaurant_category=filterType)
if not user.role.role_id == 1:
restaurants = restaurants.filter(restaurant_is_approved=True)
return restaurants
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = Restaurant.objects.all()
serializer_class = RestaurantSerializer
class RoleViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = Role.objects.all()
serializer_class = RoleSerializer
class RoleHasPermissionViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = RoleHasPermission.objects.all()
serializer_class = RoleHasPermissionSerializer
class UserViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = User.objects.all()
serializer_class = UserSerializer
class UserFollowsDietViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = UserFollowsDiet.objects.all()
serializer_class = UserFollowsDietSerializer
class UserProhibitsIngredientViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = UserProhibitsIngredient.objects.all()
serializer_class = UserProhibitsIngredientSerializer
class UserRatesDrinkViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = UserRatesDrink.objects.all()
serializer_class = UserRatesDrinkSerializer
class UserRatesFoodViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = UserRatesFood.objects.all()
serializer_class = UserRatesFoodSerializer
class UserRatesRestaurantViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def perform_create(self, serializer):
user = self.request.user
try:
restaurant = Restaurant.objects.get(pk=self.request._data.get('restaurant'))
except Restaurant.DoesNotExist:
raise Http404
if restaurant.restaurant_is_approved == 0:
raise PermissionDenied({"message":"You don't have permission to access"})
serializer.save(user=user)
def get(self, request, format=None):
content = {
'user': unicode(request.user),
'auth': unicode(request.auth),
}
return Response(content)
queryset = UserRatesRestaurant.objects.all()
serializer_class = UserRatesRestaurantSerializer
class UserSetBirthDay(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def put(self, request, pk, format=None):
try:
user = User.objects.get(pk=pk)
except User.DoesNotExist:
raise Http404
if not request.user == user:
raise PermissionDenied({"message":"You don't have permission to access"})
serializer = UserSerializer(user, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class RestaurantUserView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, restaurant, format=None):
try:
restaurant = Restaurant.objects.get(restaurant_id=restaurant)
except Restaurant.DoesNotExist:
raise Http404
user = request.user
if (not user.role.role_id == 1) and (restaurant.restaurant_is_approved == 0):
raise PermissionDenied({"message":"You don't have permission to access"})
userDiets = UserFollowsDiet.objects.all().filter(user=user).only('diet')
restaurantRatings = UserRatesRestaurant.objects.filter(restaurant=restaurant) \
.prefetch_related('user')
averageRating = restaurantRatings.aggregate(Avg('rating_grade'))
ratingsPerDiet = restaurantRatings.prefetch_related('diet') \
.values('diet').filter(diet__in=[ud.diet for ud in userDiets]) \
.annotate(average_rating = Avg('rating_grade')) \
.annotate(diet_name = F('diet__diet_name'))
restaurantRatings = restaurantRatings.annotate(username = F('user__username')) \
.annotate(diet_name = F('diet__diet_name')).values()
restaurantFoods = Food.objects.all().filter(restaurant=restaurant)
restaurantDrinks = Drink.objects.all().filter(restaurant=restaurant)
foods = [FoodSerializer(food).data for food in list(restaurantFoods)]
drinks = [DrinkSerializer(drink).data for drink in list(restaurantDrinks)]
data = {'restaurantInfo': RestaurantSerializer(restaurant).data,
'averageRating': averageRating,
'avgRatingPerDiet': ratingsPerDiet,
'foods': foods,
'drinks': drinks,
'ratings': restaurantRatings}
return Response(data)
class UserDiets(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
user = request.user
userDiets = UserFollowsDiet.objects.all().filter(user=user).prefetch_related('diet')
userDiets = Diet.objects.filter(diet_id__in = userDiets.values('diet')) \
.values('diet_id', 'diet_name')
return Response(userDiets)
class FoodUserView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, food, format=None):
try:
food = Food.objects.get(food_id=food)
except Food.DoesNotExist:
raise Http404
user = request.user
if (not user.role.role_id == 1) and (food.food_is_approved == 0):
raise PermissionDenied({"message":"You don't have permission to access"})
servingRestaurant = food.restaurant.restaurant_name
foodRatings = UserRatesFood.objects.filter(food=food).prefetch_related('user')
averageRating = foodRatings.aggregate(Avg('rating_grade'))
foodRatings = foodRatings.annotate(username = F('user__username')).values()
foodIngredients = FoodHasIngredient.objects.filter(food=food).prefetch_related('ingredient_name')
foodIngredients = Ingredient.objects.filter(ingredient_name__in = foodIngredients.values('ingredient_name'))
foodIngredients = [IngredientSerializer(ingredient).data for ingredient in list(foodIngredients)]
data = {'foodInfo': FoodSerializer(food).data,
'restaurantName': servingRestaurant,
'averageRating': averageRating,
'ingredients': foodIngredients,
'ratings': foodRatings}
return Response(data)
class DrinkUserView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, drink, format=None):
try:
drink = Drink.objects.get(drink_id=drink)
except Drink.DoesNotExist:
raise Http404
user = request.user
if (not user.role.role_id == 1) and (drink.drink_is_approved == 0):
raise PermissionDenied({"message":"You don't have permission to access"})
servingRestaurant = drink.restaurant.restaurant_name
drinkRatings = UserRatesDrink.objects.filter(drink=drink).prefetch_related('user')
averageRating = drinkRatings.aggregate(Avg('rating_grade'))
drinkRatings = drinkRatings.annotate(username = F('user__username')).values()
drinkIngredients = DrinkHasIngredient.objects.filter(drink=drink).prefetch_related('ingredient_name')
drinkIngredients = Ingredient.objects.filter(ingredient_name__in = drinkIngredients.values('ingredient_name'))
drinkHasAlcohol = drinkIngredients.filter(ingredient_has_alcohol=True).count()
drinkIngredients = [IngredientSerializer(ingredient).data for ingredient in list(drinkIngredients)]
data = {'drinkInfo': DrinkSerializer(drink).data,
'restaurantName': servingRestaurant,
'averageRating': averageRating,
'drinkHasAlcohol': True if drinkHasAlcohol>0 else False,
'ingredients': drinkIngredients,
'ratings': drinkRatings}
return Response(data)
class ProfileUserView(APIView):
authentication_classes = (SessionAuthentication, BasicAuthentication)
permission_classes = (IsAuthenticated,)
def get(self, request, profile, format=None):
try:
profile = User.objects.get(pk=profile)
except Restaurant.DoesNotExist:
raise Http404
user = request.user
if profile == user or user.role.role_id == 1:
dateToday = datetime.date.today()
ageInYears = dateToday.year - profile.user_age.year
if dateToday.month < profile.user_age.month or \
(dateToday.month == profile.user_age.month and dateToday.day < profile.user_age.day):
ageInYears -= 1
profileInfo = {
'email': profile.email,
'username': profile.username,
'age': ageInYears
}
else:
profileInfo = {
'email': None,
'username': profile.username,
'age': -1
}
userDiets = UserFollowsDiet.objects.all().filter(user=profile).prefetch_related('diet')
userDiets = Diet.objects.filter(diet_id__in = userDiets.values('diet')) \
.values('diet_id', 'diet_name')
profileInfo['diets'] = userDiets
ownsRestaurants = Restaurant.objects.filter(user=profile).values('restaurant_id', 'restaurant_name')
profileInfo['owns'] = ownsRestaurants
restaurantRatings = UserRatesRestaurant.objects.filter(user=profile).prefetch_related('user') \
.prefetch_related('diet')
restaurantRatings = restaurantRatings.annotate(username = F('user__username')) \
.annotate(diet_name = F('diet__diet_name')).values()
profileInfo['reviewsNumber'] = restaurantRatings.count()
foodRatings = UserRatesFood.objects.filter(user=profile).prefetch_related('user')
foodRatings = foodRatings.annotate(username = F('user__username')).values()
drinkRatings = UserRatesDrink.objects.filter(user=profile).prefetch_related('user')
drinkRatings = drinkRatings.annotate(username = F('user__username')).values()
data = {'userInfo': profileInfo,
'foodRatings': foodRatings,
'drinkRatings': drinkRatings,
'restaurantRatings': restaurantRatings}
return Response(data)