Skip to content

Commit

Permalink
edited models and url
Browse files Browse the repository at this point in the history
  • Loading branch information
emoltz committed Jun 15, 2024
1 parent 757504b commit 032207d
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 43 deletions.
22 changes: 22 additions & 0 deletions api/migrations/0013_food_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.0.3 on 2024-06-15 21:57

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0012_food_archived_food_image_url'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.AddField(
model_name='food',
name='user',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
]
23 changes: 23 additions & 0 deletions api/migrations/0014_food_follow_up_food_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 5.0.3 on 2024-06-15 22:20

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0013_food_user'),
]

operations = [
migrations.AddField(
model_name='food',
name='follow_up',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='food',
name='response',
field=models.TextField(blank=True, null=True),
),
]
3 changes: 3 additions & 0 deletions api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ class Food(models.Model):
"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255, default="")
user = models.ForeignKey(User, on_delete=models.CASCADE, null=False, blank=False)
initial_description = models.TextField(blank=True, null=True)
response = models.TextField(blank=True, null=True)
follow_up = models.TextField(blank=True, null=True)
archived = models.BooleanField(default=False)
image_url = models.URLField(blank=True, null=True)
# the system with nutritional info is on a *range* of values, so we need to store the min and max values
Expand Down
3 changes: 2 additions & 1 deletion api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from rest_framework.authtoken.views import obtain_auth_token

from api.views import LogFood, GetMealsAndDetails, GetFoodDetails, Apple_CreateAccount, UserExists, \
Apple_GetUserToken, SaveFood
Apple_GetUserToken, SaveFood, GetFoods

urlpatterns = [
path('get-reg-user-token/', obtain_auth_token, name="api_token_auth"),
Expand All @@ -13,4 +13,5 @@
path('save-food/<str:id>', SaveFood.as_view(), name='save_food'),
path('meals/', GetMealsAndDetails.as_view(), name='get_meal_info'),
path('food/<str:id>/', GetFoodDetails.as_view(), name='get_food_details'),
path('get-foods/', GetFoods.as_view(), name='get_foods_from_ids')
]
119 changes: 77 additions & 42 deletions api/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Optional

import requests
from django.contrib.auth.models import User
from rest_framework import status
from rest_framework.authtoken.models import Token
Expand Down Expand Up @@ -33,12 +34,13 @@ class ErrorMessage(APIException):

class UserExists(APIView):
def get(self, request, *args, **kwargs):
print("Checking if user exists...")
user_id: str = self.kwargs.get('user_id')
if not user_id:
return Response({'message': 'Please provide a user_id'}, status=status.HTTP_400_BAD_REQUEST)
if User.objects.filter(username=user_id).exists():
return Response({'exists': True}, status=status.HTTP_200_OK)
return Response({'exists': False}, status=status.HTTP_404_NOT_FOUND)
return Response({'exists': False}, status=status.HTTP_200_OK)

class SaveFood(APIView):
permission_classes = [IsAuthenticated]
Expand All @@ -59,54 +61,22 @@ def get(self, request, *args, **kwargs):
class LogFood(APIView):
permission_classes = [IsAuthenticated]

@dataclass
class RequestType:
"""
For reference only. Not used in the code.
"""
description: str
meal_type: str
date: str # YYYY-MM-DD "2024-05-12"
name: Optional[str]
image: Optional[any]

@dataclass
class ResponseType:
"""
For reference only. Not used in the code.
"""
response: str
follow_up: str
meal_name: str
calories_min: float
calories_max: float
protein_min: float
protein_max: float
total_fat_min: float
total_fat_max: float
saturated_fat_min: float
saturated_fat_max: float
carbohydrates_min: float
carbohydrates_max: float
sugar_min: float
sugar_max: float
fiber_min: float
fiber_max: float
cholesterol_min: float
cholesterol_max: float
sodium_grams_min: float
sodium_grams_max: float

@staticmethod
def add_food_to_meal(user, food: Food, meal_type: str, date: str, meal_name=None) -> Meal:
meal, created = Meal.objects.get_or_create(meal_type=meal_type, date=date, user=user)
meal.meal_items.add(food)
if meal_name:
meal.name = meal_name

if not meal.description:
meal.description = food.initial_description
else:
meal.description += " " + food.initial_description
meal.save()
return meal

def post(self, request):
print("getting response from OpenAI...")
user = request.user
description = request.data.get("description")
meal_type = request.data.get("meal_type")
Expand Down Expand Up @@ -162,21 +132,23 @@ def post(self, request):

response = json.loads(response)



# serialize into database
# add extra properties
if image_url:
response["image_url"] = image_url

response["name"] = name if name else response["name"]

# serialize into database
response["archived"] = True
response["user"] = user.id

food_serializer = FoodSerializer(data=response)
if food_serializer.is_valid():
food = food_serializer.save()
food.initial_description = description
food.save()
else:
print(food_serializer.errors)
raise ErrorMessage("Error saving food data to database")

self.add_food_to_meal(user, food, meal_type, date_str, name)
Expand All @@ -187,6 +159,28 @@ def post(self, request):
return Response(response)


class GetFoods(APIView):
permission_classes = [IsAuthenticated]

@staticmethod
def get(request):
user = request.user
all_foods = Food.objects.filter(user=user)
food_serializer = FoodSerializer(all_foods, many=True)
return Response(food_serializer.data)


@staticmethod
def post(request):
user = request.user
ids_arr: list[str] = request.data.get("ids")
if not ids_arr:
raise ErrorMessage("Please provide an array of ids")
foods = Food.objects.filter(id__in=ids_arr)
food_serializer = FoodSerializer(foods, many=True)
return Response(food_serializer.data)


class GetFoodDetails(APIView):
permission_classes = [IsAuthenticated]

Expand Down Expand Up @@ -313,6 +307,7 @@ def get(self, request, *args, **kwargs):
class Apple_CreateAccount(APIView):
@staticmethod
def post(request):
print("Creating Apple User...")
serializer = CreateUserSerializer(data=request.data)
if serializer.is_valid():
username = serializer.validated_data['user_id']
Expand Down Expand Up @@ -341,3 +336,43 @@ def post(request):
else:
return Response({'error': 'Apple User already exists.'}, status=status.HTTP_400_BAD_REQUEST)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class VerifyAppleToken(APIView):
def post(self, request, *args, **kwargs):
user_id = request.data.get('user_id')
identity_token = request.data.get('identity_token')

if not user_id or not identity_token:
return Response({'message': 'Missing user_id or identity_token'}, status=status.HTTP_400_BAD_REQUEST)

# Validate the token with Apple
client_id = "YOUR_CLIENT_ID"
client_secret = "YOUR_CLIENT_SECRET"

response = requests.post(
'https://appleid.apple.com/auth/token',
data={
'client_id': client_id,
'client_secret': client_secret,
'code': identity_token,
'grant_type': 'authorization_code',
}
)

if response.status_code != 200:
return Response({'message': 'Invalid token'}, status=response.status_code)

response_data = response.json()
# TODO: finish this

# Check if the user exists in the database
try:
user = User.objects.get(username=user_id)
except User.DoesNotExist:
return Response({'message': 'User not found'}, status=status.HTTP_404_NOT_FOUND)

# Ensure the user has a token
if not hasattr(user, 'auth_token'):
Token.objects.create(user=user)

return Response({'token': user.auth_token.key}, status=status.HTTP_200_OK)

0 comments on commit 032207d

Please sign in to comment.