Compare commits

...

10 Commits

Author SHA1 Message Date
Trey t
fc29fb09f2 WIP 2023-07-28 11:14:25 -05:00
Trey t
64e04bcc78 WIP 2023-07-27 20:08:59 -05:00
Trey t
8a42c5854a WIP 2023-07-27 19:21:57 -05:00
Trey t
c08b31d07e WIP 2023-07-27 19:19:34 -05:00
Trey t
3df5ec6acc WIP 2023-07-27 19:16:44 -05:00
Trey t
67372cc8ab WIP 2023-07-27 19:07:35 -05:00
Trey t
6d68c59ac3 WIP 2023-07-26 17:21:24 -05:00
Trey t
9d9d6200dc WIP 2023-07-26 17:13:35 -05:00
Trey t
afaa8edb6e WIP 2023-07-26 13:39:39 -05:00
Trey t
6273ae9222 WIP 2023-07-26 13:11:17 -05:00
24 changed files with 53529 additions and 19 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -12,10 +12,17 @@ from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import authentication_classes
from rest_framework.decorators import permission_classes
from django.core.cache import cache
# Create your views here.
@api_view(['GET'])
def all_equipment(request):
if 'all_equipment' in cache:
data = cache.get('all_equipment')
return Response(data=data, status=status.HTTP_200_OK)
users = Equipment.objects.all()
serializer = EquipmentSerializer(users, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
data = serializer.data
cache.set('all_equipment', data, timeout=None)
return Response(data=data, status=status.HTTP_200_OK)

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-07-25 15:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('exercise', '0006_alter_exercise_name'),
]
operations = [
migrations.AddField(
model_name='exercise',
name='estimated_rep_duration',
field=models.FloatField(blank=True, max_length=255, null=True),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-07-26 22:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('exercise', '0007_exercise_estimated_rep_duration'),
]
operations = [
migrations.AddField(
model_name='exercise',
name='video_override',
field=models.CharField(blank=True, max_length=255, null=True),
),
]

View File

@@ -21,6 +21,8 @@ class Exercise(models.Model):
equipment_required = models.CharField(null=True, blank=True, max_length=255)
muscle_groups = models.CharField(null=True, blank=True, max_length=255)
synonyms = models.CharField(null=True, blank=True, max_length=255)
estimated_rep_duration = models.FloatField(null=True, blank=True, max_length=255)
video_override = models.CharField(null=True, blank=True, max_length=255)
class Meta:
ordering = ('name',)
@@ -29,7 +31,10 @@ class Exercise(models.Model):
return self.name + " --------- " + self.description
def video_url(self):
return "exercise_videos/" + self.name.replace(" ", "_") + ".mp4"
if self.video_override is not None and len(self.video_override) > 0:
return "exercise_videos/" + self.video_override
else:
return "exercise_videos/" + self.name.replace(" ", "_") + ".mp4"
def audio_url(self):
return "exercise_audio/" + self.name.replace(" ", "_") + ".m4a"

View File

@@ -12,10 +12,17 @@ from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import authentication_classes
from rest_framework.decorators import permission_classes
from django.core.cache import cache
# Create your views here.
@api_view(['GET'])
def all_exercises(request):
if 'all_exercises' in cache:
data = cache.get('all_exercises')
return Response(data=data, status=status.HTTP_200_OK)
users = Exercise.objects.all()
serializer = ExerciseSerializer(users, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
data = serializer.data
cache.set('all_exercises', data, timeout=None)
return Response(data=data, status=status.HTTP_200_OK)

View File

@@ -12,10 +12,17 @@ from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import authentication_classes
from rest_framework.decorators import permission_classes
from django.core.cache import cache
# Create your views here.
@api_view(['GET'])
def all_muscles(request):
if 'all_muscles' in cache:
data = cache.get('all_muscles')
return Response(data=data, status=status.HTTP_200_OK)
users = Muscle.objects.all()
serializer = MuscleSerializer(users, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
data = serializer.data
cache.set('all_muscles', data, timeout=None)
return Response(data=data, status=status.HTTP_200_OK)

View File

@@ -13,6 +13,7 @@ Django==4.2.2
django-debug-toolbar==4.1.0
django-import-export==3.2.0
django-push-notifications==3.0.0
django-redis==5.3.0
djangorestframework==3.14.0
et-xmlfile==1.1.0
gevent==22.10.1

View File

@@ -5,4 +5,5 @@ from . import views
urlpatterns = [
# path('sync_equipment/', views.sync_equipment, name='sync_equipment'),
# path('sync_muscle_groups/', views.sync_muscle_groups, name='sync_equipment'),
path('clear_redis/', views.clear_redis, name='clear_redis'),
]

View File

@@ -5,6 +5,7 @@ from equipment.models import Equipment, WorkoutEquipment
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from django.core.cache import cache
# Create your views here.
@api_view(['GET'])
@@ -15,7 +16,7 @@ def sync_equipment(request):
for equipment in all_equipment:
if len(equipment) > 0:
try:
equipment_obj = Equipment.objects.get(name=equipment)
equipment_obj = Equipment.objects.get(name=equipment.lower())
WorkoutEquipment.objects.create(exercise=exercise, equipment=equipment_obj).save()
except Equipment.DoesNotExist:
pass
@@ -32,11 +33,16 @@ def sync_muscle_groups(request):
if len(muscle_group) > 0:
try:
print(muscle_group)
muscle_obj = Muscle.objects.get(name=muscle_group)
muscle_obj = Muscle.objects.get(name=muscle_group.lower())
print(muscle_obj)
ExerciseMuscle.objects.create(exercise=exercise, muscle=muscle_obj).save()
except MuscleGroup.DoesNotExist:
pass
return Response(status=status.HTTP_200_OK)
@api_view(['GET'])
def clear_redis(request):
cache.clear()
return Response(status=status.HTTP_200_OK)

View File

@@ -15,7 +15,7 @@ class SupersetExerciseInline(admin.StackedInline):
@admin.register(Superset)
class SupersetAdmin(ImportExportModelAdmin):
list_display = ("name", "workout", "order", "rounds", "get_workout_id",)
list_display = ("name", "workout", "order", "rounds", "get_workout_id", "estimated_time",)
ordering = ("order",)
inlines = [
SupersetExerciseInline,

View File

@@ -0,0 +1,20 @@
# Generated by Django 4.2.2 on 2023-07-25 15:55
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('workout', '0011_alter_completedworkout_notes'),
('superset', '0005_supersetexercise_order'),
]
operations = [
migrations.AlterField(
model_name='superset',
name='workout',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='superset_workout', to='workout.workout'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-07-25 16:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('superset', '0006_alter_superset_workout'),
]
operations = [
migrations.AddField(
model_name='superset',
name='estimated_time',
field=models.FloatField(blank=True, max_length=255, null=True),
),
]

View File

@@ -10,11 +10,13 @@ class Superset(models.Model):
workout = models.ForeignKey(
Workout,
on_delete=models.CASCADE
on_delete=models.CASCADE,
related_name='superset_workout'
)
rounds = models.IntegerField(max_length=3, blank=False, null=False)
order = models.IntegerField(max_length=3, blank=False, null=False)
estimated_time = models.FloatField(max_length=255, blank=True, null=True)
def __str__(self):
return self.name #+ " : " + self.description + " | by: " + self.registered_user.nick_name

View File

@@ -58,6 +58,16 @@ MIDDLEWARE = [
ROOT_URLCONF = 'werkout_api.urls'
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://redis:6379/",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient"
},
}
}
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
@@ -159,6 +169,17 @@ if os.environ.get("DATABASE_URL"):
}
}
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": [os.environ.get('REDIS_URL', 'redis://localhost:6379')],
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient"
},
}
}
CELERY_BROKER_URL = os.environ.get("REDIS_URL", "") + "/1"
CELERY_RESULT_BACKEND = os.environ.get("REDIS_URL", "") + "/1"

View File

@@ -12,8 +12,8 @@ urlpatterns = [
path('muscle/', include('muscle.urls')),
path('equipment/', include('equipment.urls')),
path('registered_user/', include('registered_user.urls')),
path('.well-known/apple-app-site-association', TemplateView.as_view(template_name='frontend/apple-app-site-association', content_type='application/json',))
# path('scripts/', include('scripts.urls')),
path('.well-known/apple-app-site-association', TemplateView.as_view(template_name='frontend/apple-app-site-association', content_type='application/json',)),
path('scripts/', include('scripts.urls')),
] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
if settings.DEBUG:

View File

@@ -17,7 +17,7 @@ class SupersetInline(admin.StackedInline):
@admin.register(Workout)
class WorkoutAdmin(ImportExportModelAdmin):
list_display = ("name", "description", "registered_user", "created_at", "updated_at")
list_display = ("name", "description", "estimated_time", "registered_user", "created_at", "updated_at")
inlines = [
SupersetInline,
]
@@ -32,4 +32,6 @@ class CompletedWorkoutAdmin(admin.ModelAdmin):
@admin.register(PlannedWorkout)
class PlannedWorkoutAdmin(admin.ModelAdmin):
list_display = ("registered_user", "workout", "on_date",)
list_display = ("registered_user", "workout", "on_date",)
ordering = ['workout__created_at']

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-07-25 16:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('workout', '0011_alter_completedworkout_notes'),
]
operations = [
migrations.AddField(
model_name='workout',
name='estimated_time',
field=models.FloatField(blank=True, max_length=255, null=True),
),
]

View File

@@ -20,9 +20,10 @@ class Workout(models.Model):
RegisteredUser,
on_delete=models.CASCADE
)
estimated_time = models.FloatField(max_length=255, blank=True, null=True)
def __str__(self):
return self.name #+ " : " + self.description + " | by: " + self.registered_user.nick_name
return self.name + " : " + self.description + " | by: " + str(self.created_at)
class WorkoutExercise(models.Model):
created_at = models.DateTimeField(auto_now_add=True)

53228
workout/sample_workout.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@ from muscle.models import ExerciseMuscle
from equipment.models import WorkoutEquipment
from video.models import Video
from video.serializers import VideoSerializer
from superset.serializers import SupersetSerializer
from superset.serializers import SupersetSerializer, SupersetExerciseSerializer
from superset.models import Superset, SupersetExercise
class WorkoutExerciseSerializer(serializers.ModelSerializer):
@@ -79,12 +79,23 @@ class WorkoutDetailSerializer(serializers.ModelSerializer):
male_videos = serializers.SerializerMethodField()
female_videos = serializers.SerializerMethodField()
both_videos = serializers.SerializerMethodField()
all_superset_exercise = serializers.SerializerMethodField()
class Meta:
model = Workout
fields = ('id', 'name', 'description', 'supersets', 'registered_user', 'male_videos', 'female_videos', 'both_videos')
fields = ('id', 'name', 'description', 'supersets', 'registered_user', 'male_videos', 'female_videos', 'both_videos', 'estimated_time', 'all_superset_exercise', )
depth = 1
def get_all_superset_exercise(self, obj):
all_superset_exercise = []
supersets = Superset.objects.filter(workout=obj).order_by('order')
for superset in supersets:
supersetExercises = SupersetExercise.objects.filter(superset=superset).order_by('order')
for x in range(0, superset.rounds):
all_superset_exercise += supersetExercises
data = SupersetExerciseSerializer(all_superset_exercise, many=True).data
return data
def get_supersets(self, obj):
objs = Superset.objects.filter(workout=obj).order_by('order')
data = SupersetSerializer(objs, many=True).data

View File

@@ -10,4 +10,6 @@ urlpatterns = [
path('create/', views.add_workout, name='create new workout'),
path('planned_workouts/', views.workouts_planned_by_logged_in_user, name='planned workout for user'),
path('plan_workout/', views.plan_workout, name='plan workout'),
path('add_from_files/', views.add_from_files, name='plan workout'),
]

View File

@@ -15,20 +15,35 @@ from rest_framework.decorators import permission_classes
from django.shortcuts import get_object_or_404
from datetime import datetime
import json
import os
from django.core.cache import cache
@api_view(['GET'])
def all_workouts(request):
if 'all_workouts' in cache:
data = cache.get('all_workouts')
return Response(data=data, status=status.HTTP_200_OK)
users = Workout.objects.all()
serializer = WorkoutSerializer(users, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
data = serializer.data
cache.set('all_workouts', data, timeout=None)
return Response(data=data, status=status.HTTP_200_OK)
@api_view(['GET'])
def workout_details(request, workout_id):
users = Workout.objects.get(pk=workout_id)
serializer = WorkoutDetailSerializer(users, many=False)
return Response(data=serializer.data, status=status.HTTP_200_OK)
cache_name = "wk"+str(workout_id)
if cache_name in cache:
data = cache.get(cache_name)
return Response(data=data, status=status.HTTP_200_OK)
workout = Workout.objects.get(pk=workout_id)
serializer = WorkoutDetailSerializer(workout, many=False)
data = serializer.data
cache.set(cache_name, data, timeout=300)
return Response(data = data, status=status.HTTP_200_OK)
@api_view(['POST'])
@authentication_classes([TokenAuthentication])
@@ -73,6 +88,7 @@ def add_workout(request):
workout = serializer.save(registered_user=registered_user)
workout.save()
workout_total_time = 0
for superset in exercise_data:
name = superset["name"]
rounds = superset["rounds"]
@@ -87,6 +103,7 @@ def add_workout(request):
)
superset.save()
superset_total_time = 0
for exercise in exercises:
exercise_id = exercise["id"]
exercise_obj = Exercise.objects.get(pk=exercise_id)
@@ -102,11 +119,23 @@ def add_workout(request):
supersetExercise.weight = exercise["weight"]
if "reps" in exercise:
supersetExercise.reps = exercise["reps"]
superset_total_time += exercise["reps"] * exercise_obj.estimated_rep_duration
if "duration" in exercise:
supersetExercise.duration = exercise["duration"]
superset_total_time += exercise["duration"]
supersetExercise.save()
superset.estimated_time = superset_total_time
superset.save()
workout_total_time += (superset_total_time * rounds)
superset_order += 1
workout.estimated_time = workout_total_time
workout.save()
cache.delete('all_workouts')
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@@ -132,3 +161,91 @@ def plan_workout(request):
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@api_view(['GET'])
def add_from_files(request):
sample_url = os.getcwd() + "/workout/sample_workout.json"
print(sample_url)
with open(sample_url) as user_file:
file_contents = user_file.read()
parsed_json = json.loads(file_contents)
for item in parsed_json:
workout_name = item["name"]
workout_description = item["description"]
workout_created = item["created"]
workout_obj = Workout.objects.create(
registered_user = RegisteredUser.objects.get(pk=2),
description = workout_description,
name = workout_name,
created_at = workout_created
)
workout_obj.save()
workout_obj.created_at = workout_created
workout_obj.save(update_fields=['created_at'])
workout_total_time = 0
supersets = item["supersets"]
superset_order = 1
for superset in supersets:
superset_name = superset["name"]
superset_rounds = superset["rounds"]
superset_obj = Superset.objects.create(
workout=workout_obj,
name=superset_name,
rounds=superset_rounds,
order=superset_order
)
superset_obj.save()
superset_order += 1
exercises = superset["exercises"]
exercise_order = 1
superset_total_time = 0
for exercise in exercises:
side = exercise["side"]
name = exercise["name"]
duration = exercise["duration"]
reps = exercise["reps"]
side = exercise["side"]
exercise_obj = None
if len(side) > 0:
exercise_obj = Exercise.objects.get(name=name, side=side)
else:
exercise_obj = Exercise.objects.get(name=name, side="")
supersetExercise = SupersetExercise.objects.create(
superset=superset_obj,
exercise=exercise_obj,
order=exercise_order
)
if reps != 0:
supersetExercise.reps = reps
superset_total_time += reps * exercise_obj.estimated_rep_duration
if reps == 0 and duration != 0:
supersetExercise.duration = duration
superset_total_time += exercise["duration"]
supersetExercise.save()
exercise_order += 1
superset_obj.estimated_time = superset_total_time
superset_obj.save()
workout_total_time += (superset_total_time * superset_rounds)
workout_obj.estimated_time = workout_total_time
workout_obj.save()
cache.delete('all_workouts')
return Response(status=status.HTTP_200_OK)