init commit
This commit is contained in:
0
workout/__init__.py
Normal file
0
workout/__init__.py
Normal file
45
workout/admin.py
Normal file
45
workout/admin.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from django.contrib import admin
|
||||
from .models import *
|
||||
from exercise.models import Exercise
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
from superset.models import Superset
|
||||
|
||||
# Register your models here.
|
||||
class WorkoutExerciseInline(admin.StackedInline):
|
||||
model = WorkoutExercise
|
||||
ordering = ("pk",)
|
||||
extra = 0
|
||||
|
||||
class SupersetInline(admin.StackedInline):
|
||||
model = Superset
|
||||
ordering = ("pk",)
|
||||
extra = 0
|
||||
|
||||
@admin.register(Workout)
|
||||
class WorkoutAdmin(ImportExportModelAdmin):
|
||||
search_fields = ['name', 'description', ]
|
||||
list_display = ("name", "description", "estimated_time", "registered_user", "created_at", "updated_at")
|
||||
inlines = [
|
||||
SupersetInline,
|
||||
]
|
||||
|
||||
@admin.register(WorkoutExercise)
|
||||
class WorkoutExerciseAdmin(admin.ModelAdmin):
|
||||
list_display = ("workout", "exercise", "weight", "reps", "created_at", "updated_at")
|
||||
|
||||
@admin.register(CompletedWorkout)
|
||||
class CompletedWorkoutAdmin(admin.ModelAdmin):
|
||||
list_display = ("registered_user", "workout", "workout_start_time", "difficulty", "notes", "total_time", "created_at",)
|
||||
|
||||
@admin.register(PlannedWorkout)
|
||||
class PlannedWorkoutAdmin(admin.ModelAdmin):
|
||||
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
||||
formfield = super().formfield_for_foreignkey(db_field, request, **kwargs)
|
||||
if db_field.name == "workout":
|
||||
formfield.queryset = Workout.objects.all().order_by('name')
|
||||
|
||||
return formfield
|
||||
|
||||
list_display = ("registered_user", "workout", "on_date",)
|
||||
|
||||
ordering = ['-on_date']
|
||||
6
workout/apps.py
Normal file
6
workout/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class WorkoutConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'workout'
|
||||
65720
workout/cho_all_workouts.json
Normal file
65720
workout/cho_all_workouts.json
Normal file
File diff suppressed because it is too large
Load Diff
105
workout/helpers.py
Normal file
105
workout/helpers.py
Normal file
@@ -0,0 +1,105 @@
|
||||
from .models import Workout
|
||||
from superset.helpers import get_first_up_superset_exercise
|
||||
from superset.models import Superset, SupersetExercise
|
||||
from superset.serializers import SupersetExerciseSerializer
|
||||
import json
|
||||
|
||||
def create_all_exercise_list_for_workout(workout):
|
||||
all_superset_exercise = []
|
||||
|
||||
# add a beginning workout superset
|
||||
first_up_superset_exercise = get_first_up_superset_exercise(None)
|
||||
data = SupersetExerciseSerializer(first_up_superset_exercise, many=False).data
|
||||
audio_queues = default_beeps()
|
||||
superset = Superset.objects.filter(workout=workout).order_by('order').first()
|
||||
if superset is not None:
|
||||
supersetExercise = SupersetExercise.objects.filter(superset=superset).order_by('order').first()
|
||||
if supersetExercise is not None:
|
||||
next_up_data = {
|
||||
"audio_url": supersetExercise.exercise.audio_url().lower(),
|
||||
"play_at": 7
|
||||
}
|
||||
|
||||
starting_off_with = {
|
||||
"audio_url": "transitions_audio/starting_off_with.m4a",
|
||||
"play_at": 8
|
||||
}
|
||||
|
||||
audio_queues.append(next_up_data)
|
||||
audio_queues.append(starting_off_with)
|
||||
data["audio_queues"] = audio_queues
|
||||
all_superset_exercise.append(data)
|
||||
|
||||
supersets = Superset.objects.filter(workout=workout).order_by('order')
|
||||
order = 2
|
||||
for superset_count, superset in enumerate(supersets):
|
||||
supersetExercises = SupersetExercise.objects.filter(superset=superset).order_by('order')
|
||||
for x in range(superset.rounds):
|
||||
for exercise_idx, exercise in enumerate(supersetExercises):
|
||||
exercise.order = order
|
||||
ser_data = SupersetExerciseSerializer(exercise, many=False).data
|
||||
ser_data.mutable = True
|
||||
audio_queues = default_beeps()
|
||||
|
||||
if exercise.duration is not None and exercise.duration > 0 :
|
||||
coming_up_data = {
|
||||
"audio_url": "transitions_audio/coming_up.m4a",
|
||||
"play_at": 8
|
||||
}
|
||||
audio_queues.append(coming_up_data)
|
||||
|
||||
if len(supersetExercises) > exercise_idx+1:
|
||||
next_exercise = supersetExercises[exercise_idx+1]
|
||||
next_up_data = {
|
||||
"audio_url": next_exercise.exercise.audio_url().lower(),
|
||||
"play_at": 7
|
||||
}
|
||||
|
||||
audio_queues.append(next_up_data)
|
||||
|
||||
elif x < superset.rounds - 1:
|
||||
first_exercise = supersetExercises.first()
|
||||
next_up_data = {
|
||||
"audio_url": first_exercise.exercise.audio_url().lower(),
|
||||
"play_at": 7
|
||||
}
|
||||
|
||||
audio_queues.append(next_up_data)
|
||||
|
||||
elif len(supersets) > superset_count+1:
|
||||
next_superset = supersets[superset_count+1]
|
||||
next_supersetExercises = SupersetExercise.objects.filter(superset=next_superset).order_by('order').first()
|
||||
|
||||
next_up_data = {
|
||||
"audio_url": next_supersetExercises.exercise.audio_url().lower(),
|
||||
"play_at": 7
|
||||
}
|
||||
|
||||
audio_queues.append(next_up_data)
|
||||
|
||||
ser_data["audio_queues"] = audio_queues
|
||||
all_superset_exercise.append(ser_data)
|
||||
|
||||
order += 1
|
||||
|
||||
return all_superset_exercise
|
||||
|
||||
|
||||
def default_beeps():
|
||||
short_beep_start = 5
|
||||
short_beep_end = 2
|
||||
long_beep_start = 1
|
||||
|
||||
audio_queues = []
|
||||
for x in range(short_beep_end, short_beep_start):
|
||||
audio_queues.append({
|
||||
"play_at" : x,
|
||||
"audio_url": "short_beep",
|
||||
})
|
||||
|
||||
audio_queues.append({
|
||||
"play_at" : long_beep_start,
|
||||
"audio_url": "long_beep",
|
||||
})
|
||||
|
||||
return audio_queues
|
||||
51
workout/migrations/0001_initial.py
Normal file
51
workout/migrations/0001_initial.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-11 22:00
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('registered_user', '0002_remove_registereduser_phone_number'),
|
||||
('exercise', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Workout',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('name', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('description', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='registered_user.registereduser')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='WorkoutExercise',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('weight', models.IntegerField(blank=True, max_length=4, null=True)),
|
||||
('reps', models.IntegerField(blank=True, max_length=4, null=True)),
|
||||
('exercise', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workout_exercise_exercise', to='exercise.exercise')),
|
||||
('workout', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='workout_exercise_workout', to='workout.workout')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CompletedWorkout',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('difficulty', models.PositiveSmallIntegerField(choices=[(1, 'easy'), (2, 'moderate'), (3, 'average'), (4, 'hard'), (5, 'death')])),
|
||||
('registered_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='completed_workout_user', to='registered_user.registereduser')),
|
||||
('workout', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='completed_workout_workout', to='workout.workout')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-12 01:26
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='workout',
|
||||
old_name='user',
|
||||
new_name='registered_user',
|
||||
),
|
||||
]
|
||||
19
workout/migrations/0003_alter_workout_name.py
Normal file
19
workout/migrations/0003_alter_workout_name.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-12 01:49
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0002_rename_user_workout_registered_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='workout',
|
||||
name='name',
|
||||
field=models.CharField(default='q', max_length=255),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
18
workout/migrations/0004_workoutexercise_duration.py
Normal file
18
workout/migrations/0004_workoutexercise_duration.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-14 13:24
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0003_alter_workout_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='workoutexercise',
|
||||
name='duration',
|
||||
field=models.IntegerField(blank=True, max_length=4, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-22 02:08
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0004_workoutexercise_duration'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='completedworkout',
|
||||
name='total_time',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='completedworkout',
|
||||
name='workout_start_time',
|
||||
field=models.DateTimeField(default=datetime.datetime(2023, 6, 22, 2, 8, 12, 885580)),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
19
workout/migrations/0006_completedworkout_notes.py
Normal file
19
workout/migrations/0006_completedworkout_notes.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-22 03:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0005_completedworkout_total_time_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='completedworkout',
|
||||
name='notes',
|
||||
field=models.TextField(default=''),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
18
workout/migrations/0007_completedworkout_total_calories.py
Normal file
18
workout/migrations/0007_completedworkout_total_calories.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-06-24 04:23
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0006_completedworkout_notes'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='completedworkout',
|
||||
name='total_calories',
|
||||
field=models.FloatField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
26
workout/migrations/0008_plannedworkout.py
Normal file
26
workout/migrations/0008_plannedworkout.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# Generated by Django 4.2.2 on 2023-07-02 04:12
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('registered_user', '0003_registereduser_has_nsfw_toggle'),
|
||||
('workout', '0007_completedworkout_total_calories'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PlannedWorkout',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('on_date', models.DateTimeField(auto_now=True)),
|
||||
('registered_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='planned_workout_registered_user', to='registered_user.registereduser')),
|
||||
('workout', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='planned_workout_workout', to='workout.workout')),
|
||||
],
|
||||
),
|
||||
]
|
||||
18
workout/migrations/0009_alter_plannedworkout_on_date.py
Normal file
18
workout/migrations/0009_alter_plannedworkout_on_date.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-07-02 04:15
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0008_plannedworkout'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='plannedworkout',
|
||||
name='on_date',
|
||||
field=models.DateTimeField(),
|
||||
),
|
||||
]
|
||||
18
workout/migrations/0010_alter_plannedworkout_on_date.py
Normal file
18
workout/migrations/0010_alter_plannedworkout_on_date.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-07-02 04:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0009_alter_plannedworkout_on_date'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='plannedworkout',
|
||||
name='on_date',
|
||||
field=models.DateField(),
|
||||
),
|
||||
]
|
||||
18
workout/migrations/0011_alter_completedworkout_notes.py
Normal file
18
workout/migrations/0011_alter_completedworkout_notes.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-07-03 01:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0010_alter_plannedworkout_on_date'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='completedworkout',
|
||||
name='notes',
|
||||
field=models.TextField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
18
workout/migrations/0012_workout_estimated_time.py
Normal file
18
workout/migrations/0012_workout_estimated_time.py
Normal 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),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 4.2.2 on 2023-08-13 23:21
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0012_workout_estimated_time'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='completedworkout',
|
||||
name='total_calories',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='completedworkout',
|
||||
name='workout_uuid',
|
||||
field=models.CharField(blank=True, max_length=1000, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-08-13 23:35
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0013_remove_completedworkout_total_calories_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='completedworkout',
|
||||
old_name='workout_uuid',
|
||||
new_name='health_kit_workout_uuid',
|
||||
),
|
||||
]
|
||||
18
workout/migrations/0015_alter_completedworkout_difficulty.py
Normal file
18
workout/migrations/0015_alter_completedworkout_difficulty.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.2 on 2023-08-14 01:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workout', '0014_rename_workout_uuid_completedworkout_health_kit_workout_uuid'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='completedworkout',
|
||||
name='difficulty',
|
||||
field=models.PositiveSmallIntegerField(choices=[(0, 'na'), (1, 'easy'), (2, 'moderate'), (3, 'average'), (4, 'hard'), (5, 'death')]),
|
||||
),
|
||||
]
|
||||
0
workout/migrations/__init__.py
Normal file
0
workout/migrations/__init__.py
Normal file
94
workout/models.py
Normal file
94
workout/models.py
Normal file
@@ -0,0 +1,94 @@
|
||||
from django.db import models
|
||||
from exercise.models import *
|
||||
from registered_user.models import RegisteredUser
|
||||
|
||||
WORKOUT_LEVEL = (
|
||||
(0, "na"),
|
||||
(1, "easy"),
|
||||
(2, "moderate"),
|
||||
(3, "average"),
|
||||
(4, "hard"),
|
||||
(5, "death"),
|
||||
)
|
||||
|
||||
# Create your models here.
|
||||
class Workout(models.Model):
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
name = models.CharField(max_length=255)
|
||||
description = models.CharField(null=True, blank=True, max_length=255)
|
||||
registered_user = models.ForeignKey(
|
||||
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: " + str(self.registered_user.first_name) + " - on: " + str(self.created_at)
|
||||
|
||||
class WorkoutExercise(models.Model):
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
workout = models.ForeignKey(
|
||||
Workout,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='workout_exercise_workout'
|
||||
)
|
||||
exercise = models.ForeignKey(
|
||||
Exercise,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='workout_exercise_exercise'
|
||||
)
|
||||
weight = models.IntegerField(null=True, blank=True, max_length=4)
|
||||
reps = models.IntegerField(null=True, blank=True, max_length=4)
|
||||
duration = models.IntegerField(null=True, blank=True, max_length=4)
|
||||
|
||||
def __str__(self):
|
||||
return self.workout.name + " : " + self.exercise.name
|
||||
|
||||
def duration_audio(self):
|
||||
if self.duration is not None:
|
||||
return str(settings.MEDIA_URL) + "quantities_audio/" + "for_"+str(self.duration)+"_seconds.m4a"
|
||||
|
||||
def weight_audio(self):
|
||||
if self.weight is not None:
|
||||
return str(settings.MEDIA_URL) + "quantities_audio/" + "for_"+str(self.weight)+"_pounds.m4a"
|
||||
|
||||
class CompletedWorkout(models.Model):
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
registered_user = models.ForeignKey(
|
||||
RegisteredUser,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='completed_workout_user'
|
||||
)
|
||||
workout = models.ForeignKey(
|
||||
Workout,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='completed_workout_workout'
|
||||
)
|
||||
difficulty = models.PositiveSmallIntegerField(
|
||||
choices=WORKOUT_LEVEL
|
||||
)
|
||||
total_time = models.IntegerField(null=True, blank=True)
|
||||
workout_start_time = models.DateTimeField(null=False, blank=False)
|
||||
notes = models.TextField(null=True, blank=True)
|
||||
health_kit_workout_uuid = models.CharField(max_length=1000, blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.registered_user.first_name + " : " + self.registered_user.last_name + " : " + self.workout.name + " : " + str(self.difficulty)
|
||||
|
||||
class PlannedWorkout(models.Model):
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
on_date = models.DateField(auto_now=False,null=False, blank=False)
|
||||
workout = models.ForeignKey(
|
||||
Workout,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='planned_workout_workout'
|
||||
)
|
||||
registered_user = models.ForeignKey(
|
||||
RegisteredUser,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='planned_workout_registered_user'
|
||||
)
|
||||
146
workout/serializers.py
Normal file
146
workout/serializers.py
Normal file
@@ -0,0 +1,146 @@
|
||||
from rest_framework import serializers
|
||||
from .models import *
|
||||
from exercise.serializers import ExerciseSerializer
|
||||
from registered_user.serializers import GetRegisteredUserSerializer
|
||||
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, SupersetExerciseSerializer
|
||||
from superset.models import Superset, SupersetExercise
|
||||
from superset.helpers import *
|
||||
from .helpers import *
|
||||
|
||||
class WorkoutExerciseSerializer(serializers.ModelSerializer):
|
||||
exercise = ExerciseSerializer(read_only=True)
|
||||
duration_audio = serializers.ReadOnlyField()
|
||||
weight_audio = serializers.ReadOnlyField()
|
||||
|
||||
class Meta:
|
||||
model = WorkoutExercise
|
||||
fields = ('workout', 'exercise','weight','reps','duration','duration_audio','weight_audio', 'created_at',)
|
||||
|
||||
class CompleteWorkoutSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = CompletedWorkout
|
||||
exclude = ['registered_user']
|
||||
|
||||
def create(self, validated_data):
|
||||
registered_user_id = self.context.get("registered_user")
|
||||
registered_user = RegisteredUser.objects.get(id=registered_user_id)
|
||||
completed_workout = CompletedWorkout.objects.create(
|
||||
registered_user=registered_user,
|
||||
workout=validated_data['workout'],
|
||||
difficulty=validated_data['difficulty'],
|
||||
total_time=validated_data['total_time'],
|
||||
workout_start_time=validated_data['workout_start_time'],
|
||||
notes=validated_data['notes']
|
||||
)
|
||||
if "health_kit_workout_uuid" in validated_data:
|
||||
completed_workout.workout_uuid = validated_data['health_kit_workout_uuid']
|
||||
completed_workout.save()
|
||||
return completed_workout
|
||||
|
||||
class WorkoutSerializer(serializers.ModelSerializer):
|
||||
# exercise = WorkoutExerciseSerializer(source='workout_exercise_workout', many=True)
|
||||
registered_user = GetRegisteredUserSerializer(many=False, read_only=True)
|
||||
muscles = serializers.SerializerMethodField()
|
||||
equipment = serializers.SerializerMethodField()
|
||||
exercise_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Workout
|
||||
fields = '__all__'
|
||||
# depth = 1
|
||||
|
||||
def get_muscles(self, obj):
|
||||
superset_ids = Superset.objects.filter(workout=obj).values_list('id')
|
||||
exercise_ids = SupersetExercise.objects.filter(superset__id__in=superset_ids).values_list('exercise__id')
|
||||
muscles_names = ExerciseMuscle.objects.filter(exercise__id__in=exercise_ids).values_list('muscle__name', flat=True)
|
||||
return list(set(muscles_names))
|
||||
|
||||
# muscles_names = ExerciseMuscle.objects.filter(exercise__id__in=exercises).values_list('muscle__name', flat=True)
|
||||
# return list(set(muscles_names))
|
||||
|
||||
def get_equipment(self, obj):
|
||||
superset_ids = Superset.objects.filter(workout=obj).values_list('id')
|
||||
exercise_ids = SupersetExercise.objects.filter(superset__id__in=superset_ids).values_list('exercise__id')
|
||||
equipment_names = WorkoutEquipment.objects.filter(exercise__id__in=exercise_ids).values_list('equipment__name', flat=True)
|
||||
return list(set(equipment_names))
|
||||
|
||||
def get_exercise_count(self, obj):
|
||||
returnValue = 0
|
||||
supersets = Superset.objects.filter(workout=obj)
|
||||
for superset in supersets:
|
||||
exercise_count = SupersetExercise.objects.filter(superset=superset).count()
|
||||
returnValue += (superset.rounds * exercise_count)
|
||||
return returnValue
|
||||
|
||||
class WorkoutDetailSerializer(serializers.ModelSerializer):
|
||||
supersets = serializers.SerializerMethodField()
|
||||
registered_user = serializers.SerializerMethodField()
|
||||
all_superset_exercise = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Workout
|
||||
fields = ('id', 'name', 'description', 'supersets', 'registered_user', 'estimated_time', 'all_superset_exercise', )
|
||||
depth = 1
|
||||
|
||||
def get_all_superset_exercise(self, obj):
|
||||
all_exercise_data = create_all_exercise_list_for_workout(obj)
|
||||
return all_exercise_data
|
||||
|
||||
def get_supersets(self, obj):
|
||||
objs = Superset.objects.filter(workout=obj).order_by('order')
|
||||
data = SupersetSerializer(objs, many=True).data
|
||||
|
||||
# add a beginning workout superset
|
||||
first_up_superset = get_first_up_superset(obj)
|
||||
first_up_superset_exercise = get_first_up_superset_exercise(first_up_superset)
|
||||
|
||||
first_data = SupersetSerializer([first_up_superset], many=True).data
|
||||
__data = SupersetExerciseSerializer([first_up_superset_exercise], many=True).data
|
||||
first_data[0]["exercises"] = __data
|
||||
data[:0] = first_data
|
||||
|
||||
return data
|
||||
|
||||
def get_registered_user(self, obj):
|
||||
objs = RegisteredUser.objects.get(pk=obj.registered_user.pk)
|
||||
data = GetRegisteredUserSerializer(objs, many=False).data
|
||||
return data
|
||||
|
||||
class GetCompleteWorkoutSerializer(serializers.ModelSerializer):
|
||||
workout = WorkoutSerializer(many=False, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = CompletedWorkout
|
||||
exclude = ['registered_user']
|
||||
|
||||
class POSTCompleteWorkoutSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Workout
|
||||
exclude = ['registered_user']
|
||||
|
||||
class PlannedWorkoutSerializer(serializers.ModelSerializer):
|
||||
workout = POSTCompleteWorkoutSerializer(many=False, read_only=True)
|
||||
class Meta:
|
||||
model = PlannedWorkout
|
||||
exclude = ['registered_user']
|
||||
depth = 1
|
||||
|
||||
class POSTPlannedWorkoutSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = PlannedWorkout
|
||||
exclude = ['registered_user']
|
||||
|
||||
def create(self, validated_data):
|
||||
registered_user_id = self.context.get("registered_user")
|
||||
registered_user = RegisteredUser.objects.get(id=registered_user_id)
|
||||
planned_workout = PlannedWorkout.objects.create(
|
||||
registered_user=registered_user,
|
||||
workout=validated_data['workout'],
|
||||
on_date=validated_data['on_date']
|
||||
)
|
||||
planned_workout.save()
|
||||
return planned_workout
|
||||
101
workout/tasks.py
Normal file
101
workout/tasks.py
Normal file
@@ -0,0 +1,101 @@
|
||||
from celery import shared_task
|
||||
import json
|
||||
import os
|
||||
from .models import *
|
||||
from .serializers import *
|
||||
from django.core.cache import cache
|
||||
from superset.models import Superset, SupersetExercise
|
||||
from exercise.models import Exercise
|
||||
|
||||
@shared_task()
|
||||
def add_from_files_tasks():
|
||||
sample_urls = [{
|
||||
"file": os.getcwd() + "/workout/trey_all_workouts.json",
|
||||
"user_id": 2
|
||||
},{
|
||||
"file": os.getcwd() + "/workout/cho_all_workouts.json",
|
||||
"user_id": 6
|
||||
}]
|
||||
|
||||
for sample_url in sample_urls:
|
||||
with open(sample_url["file"]) 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=sample_url["user_id"]),
|
||||
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')
|
||||
3
workout/tests.py
Normal file
3
workout/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
56360
workout/trey_all_workouts.json
Normal file
56360
workout/trey_all_workouts.json
Normal file
File diff suppressed because it is too large
Load Diff
15
workout/urls.py
Normal file
15
workout/urls.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('all/', views.all_workouts, name='all workouts'),
|
||||
path('<workout_id>/details/', views.workout_details, name='single workout details'),
|
||||
path('complete/', views.complete_workout, name='user complete workout'),
|
||||
path('completed/', views.workouts_completed_by_logged_in_user, name='user completed workouts'),
|
||||
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'),
|
||||
]
|
||||
173
workout/views.py
Normal file
173
workout/views.py
Normal file
@@ -0,0 +1,173 @@
|
||||
from .models import *
|
||||
from .serializers import *
|
||||
|
||||
from django.shortcuts import render
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import authenticate
|
||||
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.shortcuts import get_object_or_404
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.core.cache import cache
|
||||
from .tasks import add_from_files_tasks
|
||||
|
||||
@api_view(['GET'])
|
||||
@authentication_classes([TokenAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
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)
|
||||
data = serializer.data
|
||||
cache.set('all_workouts', data, timeout=None)
|
||||
return Response(data=data, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@authentication_classes([TokenAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def workout_details(request, workout_id):
|
||||
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])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def complete_workout(request):
|
||||
registered_user = RegisteredUser.objects.get(user=request.user)
|
||||
serializer = CompleteWorkoutSerializer(data=request.data, context = {"registered_user":registered_user.pk})
|
||||
if serializer.is_valid():
|
||||
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'])
|
||||
@authentication_classes([TokenAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def workouts_completed_by_logged_in_user(request):
|
||||
registered_user = RegisteredUser.objects.get(user=request.user)
|
||||
workouts = CompletedWorkout.objects.filter(registered_user=registered_user)
|
||||
serializer = GetCompleteWorkoutSerializer(workouts, many=True)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
|
||||
@api_view(['POST'])
|
||||
@authentication_classes([TokenAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def add_workout(request):
|
||||
registered_user = RegisteredUser.objects.get(user=request.user)
|
||||
if registered_user is None:
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# exercise_data = dict(request.POST)["exercise_data"]
|
||||
exercise_data = request.data["supersets"]
|
||||
|
||||
if exercise_data is None:
|
||||
return Response({"supersets": [ "missing" ] }, status=status.HTTP_400_BAD_REQUEST)
|
||||
if len(exercise_data) < 1:
|
||||
return Response({"supersets": [ "empty" ] }, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
serializer = POSTCompleteWorkoutSerializer(data=request.data)
|
||||
|
||||
if serializer.is_valid():
|
||||
workout = serializer.save(registered_user=registered_user)
|
||||
workout.save()
|
||||
|
||||
workout_total_time = 0
|
||||
for superset in exercise_data:
|
||||
name = superset["name"]
|
||||
rounds = superset["rounds"]
|
||||
exercises = superset["exercises"]
|
||||
superset_order = superset["order"]
|
||||
|
||||
superset = Superset.objects.create(
|
||||
workout=workout,
|
||||
name=name,
|
||||
rounds=rounds,
|
||||
order=superset_order
|
||||
)
|
||||
superset.save()
|
||||
|
||||
superset_total_time = 0
|
||||
for exercise in exercises:
|
||||
exercise_id = exercise["id"]
|
||||
exercise_obj = Exercise.objects.get(pk=exercise_id)
|
||||
order = exercise["order"]
|
||||
|
||||
supersetExercise = SupersetExercise.objects.create(
|
||||
superset=superset,
|
||||
exercise=exercise_obj,
|
||||
order=order
|
||||
)
|
||||
|
||||
if "weight" in exercise:
|
||||
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)
|
||||
|
||||
@api_view(['GET'])
|
||||
@authentication_classes([TokenAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def workouts_planned_by_logged_in_user(request):
|
||||
registered_user = RegisteredUser.objects.get(user=request.user)
|
||||
workouts = PlannedWorkout.objects.filter(registered_user=registered_user, on_date__gte=datetime.now()- timedelta(days=1))
|
||||
serializer = PlannedWorkoutSerializer(workouts, many=True)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
@api_view(['POST'])
|
||||
@authentication_classes([TokenAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def plan_workout(request):
|
||||
registered_user = RegisteredUser.objects.get(user=request.user)
|
||||
serializer = POSTPlannedWorkoutSerializer(data=request.data,
|
||||
context = {"registered_user":registered_user.pk})
|
||||
|
||||
if serializer.is_valid():
|
||||
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'])
|
||||
@authentication_classes([TokenAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def add_from_files(request):
|
||||
add_from_files_tasks.delay()
|
||||
cache.delete('all_workouts')
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
Reference in New Issue
Block a user