Skip to content

Commit

Permalink
update fooddiary seriazilers, views, urls and fatsecret tools
Browse files Browse the repository at this point in the history
  • Loading branch information
Evgeniy-Golodnykh committed Aug 13, 2024
1 parent 4e04b92 commit 4451d87
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 69 deletions.
23 changes: 0 additions & 23 deletions blackfox/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers

from fatsecret.tools import get_fatsecret_data
from training.models import BodyStatsDiary, FoodDiary, Project
from users.serializers import CustomUserSerializer

Expand All @@ -15,7 +14,6 @@
'A diary entry for the current user and date already exists'
)
project_exists_message = 'A project with this User already exists'
project_not_exists_message = 'Please create a project with this User'
user_not_coach_message = 'A user cannot be a coach at the same time'


Expand Down Expand Up @@ -65,27 +63,6 @@ class Meta:
fields = '__all__'


class CreateUpdateFoodDiarySerializer(serializers.ModelSerializer):
"""A serializer to create/update FoodDiary instances."""

class Meta:
model = FoodDiary
exclude = ('user',)

def create(self, validated_data):
user = self.context['request'].user
if not Project.objects.filter(user=user).exists():
raise serializers.ValidationError(project_not_exists_message)
objs = get_fatsecret_data(user)
FoodDiary.objects.bulk_create(objs=objs)
return FoodDiary.objects.filter(user=user).first()

def to_representation(self, instance):
request = self.context.get('request')
context = {'request': request}
return FoodDiarySerializer(instance, context=context).data


class ProjectSerializer(serializers.ModelSerializer):
"""A serializer to read Project instances."""

Expand Down
6 changes: 5 additions & 1 deletion blackfox/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
TokenObtainPairView, TokenRefreshView,
)

from api.views import BodyStatsDiaryViewSet, FoodDiaryViewSet, ProjectViewSet
from api.views import (
BodyStatsDiaryViewSet, FoodDiaryCreateView, FoodDiaryViewSet,
ProjectViewSet,
)

router = DefaultRouter()
router.register('bodystats', BodyStatsDiaryViewSet, basename='bodystats')
Expand All @@ -19,6 +22,7 @@
path('login/', TokenObtainPairView.as_view(), name='login'),
path('login/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('fatsecret/', include('fatsecret.urls')),
path('fooddiary/', FoodDiaryCreateView.as_view(), name='create_fooddiary'),
path('', include('djoser.urls')),
path('', include(router.urls)),
]
48 changes: 39 additions & 9 deletions blackfox/api/views.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
from rest_framework import filters, viewsets
from django.contrib.auth import get_user_model
from django.shortcuts import get_object_or_404
from rest_framework import filters, status, viewsets
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from rest_framework.views import APIView

from api.permissions import IsAdmin, IsCoach
from api.serializers import (
BodyStatsDiarySerializer, CreateUpdateBodyStatsDiarySerializer,
CreateUpdateFoodDiarySerializer, CreateUpdateProjectSerializer,
FoodDiarySerializer, ProjectSerializer,
CreateUpdateProjectSerializer, FoodDiarySerializer, ProjectSerializer,
)
from fatsecret.tools import get_fooddiary_instance
from training.models import BodyStatsDiary, FoodDiary, Project

User = get_user_model()
fatsecret_account_not_exists_message = 'Please link your Fatsecret account'
project_not_exists_message = 'Please create a project for current user'


class BodyStatsDiaryViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticatedOrReadOnly]
Expand All @@ -26,22 +34,44 @@ def get_queryset(self):
return BodyStatsDiary.objects.all()


class FoodDiaryViewSet(viewsets.ModelViewSet):
class FoodDiaryViewSet(viewsets.ReadOnlyModelViewSet):
permission_classes = [IsAuthenticatedOrReadOnly]
serializer_class = FoodDiarySerializer
filter_backends = [filters.SearchFilter]
search_fields = ['user', 'date']

def get_serializer_class(self):
if self.action in ('create', 'partial_update'):
return CreateUpdateFoodDiarySerializer
return FoodDiarySerializer

def get_queryset(self):
if self.request.user.role == 'user':
return FoodDiary.objects.filter(user=self.request.user)
return FoodDiary.objects.all()


class FoodDiaryCreateView(APIView):

def post(self, request):
username = request.query_params.get('user')
if username:
user = get_object_or_404(User, username=username)
else:
user = request.user
if not user.fatsecret_token or not user.fatsecret_secret:
return Response(
{'message': fatsecret_account_not_exists_message},
status=status.HTTP_400_BAD_REQUEST
)
if not Project.objects.filter(user=user).exists():
return Response(
{'message': project_not_exists_message},
status=status.HTTP_400_BAD_REQUEST
)
FoodDiary.objects.bulk_create(
objs=get_fooddiary_instance(user)
)
queryset = FoodDiary.objects.filter(user=user)
serializer = FoodDiarySerializer(queryset, many=True)
return Response(serializer.data)


class ProjectViewSet(viewsets.ModelViewSet):
permission_classes = [IsAdmin | IsCoach]
queryset = Project.objects.all()
Expand Down
Binary file modified blackfox/db.sqlite3
Binary file not shown.
77 changes: 41 additions & 36 deletions blackfox/fatsecret/tools.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import datetime as dt
import os

from django.shortcuts import redirect
from rauth import OAuth1Service

from training.models import FoodDiary, Project
Expand All @@ -26,36 +25,56 @@

def unix_date_converter(date):
epoch = dt.date.fromtimestamp(0)
if type(date) is int:
return epoch + dt.timedelta(date)
if type(date) is str:
return (dt.date.fromisoformat(date) - epoch).days
return (date - epoch).days


def food_caclulator(foods, instance):
def food_caclulator(foods, project, date):
instance = {
'user': project.user,
'date': date,
'calories_target': project.target_calories,
'carbohydrate_target': project.target_carbohydrate,
'fat_target': project.target_fat,
'fiber_target': project.target_fiber,
'protein_target': project.target_protein,
'sugar_target': project.target_sugar,
}
for food in foods:
instance['calories_actual'] = (
instance.get('calories_actual', 0) + int(food.get('calories', 0))
instance.get('calories_actual', 0)
+ int(food.get('calories', 0))
)
instance['carbohydrate_actual'] = (
instance.get('carbohydrate_actual', 0)
+ float(food.get('carbohydrate', 0))
instance['carbohydrate_actual'] = round(
(instance.get('carbohydrate_actual', 0)
+ float(food.get('carbohydrate', 0))),
2
)
instance['fat_actual'] = (
instance.get('fat_actual', 0) + float(food.get('fat', 0))
instance['fat_actual'] = round(
(instance.get('fat_actual', 0)
+ float(food.get('fat', 0))),
2
)
instance['fiber_actual'] = (
instance.get('fiber_actual', 0) + float(food.get('fiber', 0))
instance['fiber_actual'] = round(
(instance.get('fiber_actual', 0)
+ float(food.get('fiber', 0))),
2
)
instance['protein_actual'] = (
instance.get('protein_actual', 0) + float(food.get('protein', 0))
instance['protein_actual'] = round(
(instance.get('protein_actual', 0)
+ float(food.get('protein', 0))),
2
)
instance['sugar_actual'] = (
instance.get('sugar_actual', 0) + float(food.get('sugar', 0))
instance['sugar_actual'] = round(
(instance.get('sugar_actual', 0)
+ float(food.get('sugar', 0))),
2
)
return instance


def get_fatsecret_data(user):
def get_fooddiary_instance(user):
fooddiary = FoodDiary.objects.filter(user=user).first()
project = Project.objects.filter(user=user).first()
if fooddiary:
Expand All @@ -65,37 +84,23 @@ def get_fatsecret_data(user):
last_date = project.start_date
current_date = dt.date.today()

instance = {
'user': user,
'calories_target': project.target_calories,
'carbohydrate_target': project.target_carbohydrate,
'fat_target': project.target_fat,
'fiber_target': project.target_fiber,
'protein_target': project.target_protein,
'sugar_target': project.target_sugar,
}

access_token = user.fatsecret_token
access_token_secret = user.fatsecret_secret
if not access_token or not access_token_secret:
return redirect('get_request_token') # зарайзить ValidationError
session = fatsecret.get_session(
token=(access_token, access_token_secret)
token=(user.fatsecret_token, user.fatsecret_secret)
)

params = {'method': 'food_entries.get.v2', 'format': 'json'}

objects = []
while last_date <= current_date:
params['date'] = (last_date - dt.date.fromtimestamp(0)).days
params['date'] = unix_date_converter(last_date)
fatsecret_data = session.get(BASE_URL, params=params).json()
food_entries = fatsecret_data.get('food_entries')
if food_entries:
instance['date'] = last_date
objects.append(
FoodDiary(**food_caclulator(
food_entries.get('food_entry'), instance
food_entries.get('food_entry'), project, last_date
))
)
last_date += dt.timedelta(1)
session.close()

return objects

0 comments on commit 4451d87

Please sign in to comment.