diff --git a/profiles/migrations/__init__.py b/fitnotes/__init__.py similarity index 100% rename from profiles/migrations/__init__.py rename to fitnotes/__init__.py diff --git a/fitnotes/admin.py b/fitnotes/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/fitnotes/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/fitnotes/importer.py b/fitnotes/importer.py new file mode 100644 index 0000000..70d92c9 --- /dev/null +++ b/fitnotes/importer.py @@ -0,0 +1,40 @@ +import sqlite3 +from django.db import transaction +from lifting.models import Lift, Set + + +def _clean_name(name): + return name.lower() + + +def import_fitnotes_db(filename, user, fitnotes_to_lift): + # lift name => id + lift_ids = {_clean_name(l.name): l.id for l in Lift.objects.all()} + + # build mapping FitNotes exercise id => our lift id + lift_id_mapping = {} + + conn = sqlite3.connect(filename) + cur = conn.cursor() + for fnid, ename in cur.execute('SELECT _id, name FROM exercise WHERE exercise_type_id=0'): + cleaned = _clean_name(ename) + + if cleaned not in fitnotes_to_lift: + lift_id_mapping[fnid] = cleaned + else: + lift_id_mapping[fnid] = lift_ids[fitnotes_to_lift[cleaned]] + + with transaction.atomic(): + Set.objects.filter(source='fitnotes').delete() + for fnid, date, weight_kg, reps in cur.execute( + 'SELECT exercise_id, date, metric_weight, reps FROM training_log'): + + # error if mapping wasn't found and there's a workout using it + if isinstance(lift_id_mapping[fnid], str): + raise ValueError('no known conversion for fitnotes exercise "{}"'.format( + lift_id_mapping[fnid])) + + lift_id = lift_id_mapping[fnid] + + Set.objects.create(lift_id=lift_id, date=date, weight_kg=weight_kg, reps=reps, + source='fitnotes', user=user) diff --git a/fitnotes/migrations/__init__.py b/fitnotes/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fitnotes/models.py b/fitnotes/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/fitnotes/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/lifting/testdata/baddata.fitnotes b/fitnotes/testdata/baddata.fitnotes similarity index 100% rename from lifting/testdata/baddata.fitnotes rename to fitnotes/testdata/baddata.fitnotes diff --git a/lifting/testdata/example.fitnotes b/fitnotes/testdata/example.fitnotes similarity index 100% rename from lifting/testdata/example.fitnotes rename to fitnotes/testdata/example.fitnotes diff --git a/fitnotes/tests.py b/fitnotes/tests.py new file mode 100644 index 0000000..0a38095 --- /dev/null +++ b/fitnotes/tests.py @@ -0,0 +1,62 @@ +from django.test import TestCase +from django.contrib.auth.models import User +from inventory.models import Lift +from lifting.models import Set +from .importer import import_fitnotes_db + + +class TestFitnotesImport(TestCase): + # fitnotes.db has: + # April 1 + # bench press 10 @ 45 + # bench press 5 @ 95 + # bench press 3 @ 135 + # bench press 5 @ 155 + # April 3 + # squat 10 @ 45 + # squat 5 @ 95 + # squat 3 @ 135 + # squat 2 @ 185 + # squat 5 @ 225 + + def setUp(self): + self.user = User.objects.create_user('default', 'default@example.com', 'default') + self.bench = Lift.objects.create(name='bench press') + self.squat = Lift.objects.create(name='squat') + + self.good_mapping = {'flat barbell bench press': 'bench press', + 'barbell squat': 'squat' + } + self.bad_mapping = {'flat barbell bench press': 'bench press' } + + def test_basic_import(self): + # ensure that the data comes in + import_fitnotes_db('fitnotes/testdata/example.fitnotes', self.user, self.good_mapping) + assert Set.objects.filter(lift=self.bench).count() == 4 + assert Set.objects.filter(lift=self.squat).count() == 5 + + def test_double_import(self): + # two identical dbs, should be idempotent + import_fitnotes_db('fitnotes/testdata/example.fitnotes', self.user, self.good_mapping) + import_fitnotes_db('fitnotes/testdata/example.fitnotes', self.user, self.good_mapping) + assert Set.objects.filter(lift=self.bench).count() == 4 + assert Set.objects.filter(lift=self.squat).count() == 5 + + def test_import_with_other_data(self): + Set.objects.create(lift=self.bench, weight_kg=100, reps=10, date='2014-01-01', + user=self.user) + import_fitnotes_db('fitnotes/testdata/example.fitnotes', self.user, self.good_mapping) + assert Set.objects.filter(lift=self.bench).count() == 5 + + def test_import_with_bad_mapping(self): + with self.assertRaises(ValueError): + import_fitnotes_db('fitnotes/testdata/example.fitnotes', self.user, self.bad_mapping) + assert Set.objects.filter(lift=self.bench).count() == 0 + + def test_bad_data_import(self): + # good db then bad db, should fail without screwing up existing data + import_fitnotes_db('fitnotes/testdata/example.fitnotes', self.user, self.good_mapping) + with self.assertRaises(Exception): + # baddata.fitnotes has all lift ids set to 9999 + import_fitnotes_db('fitnotes/testdata/baddata.fitnotes', self.user, self.good_mapping) + assert Set.objects.count() == 9 diff --git a/profiles/urls.py b/fitnotes/urls.py similarity index 54% rename from profiles/urls.py rename to fitnotes/urls.py index a8d7128..26cb2e9 100644 --- a/profiles/urls.py +++ b/fitnotes/urls.py @@ -3,5 +3,5 @@ from django.conf.urls import url from . import views urlpatterns = [ - url(r'^edit/$', views.edit_profile, name='edit-profile'), + url(r'^fitnotes/$', views.fitnotes_upload), ] diff --git a/fitnotes/views.py b/fitnotes/views.py new file mode 100644 index 0000000..8abb44b --- /dev/null +++ b/fitnotes/views.py @@ -0,0 +1,18 @@ +from django.shortcuts import render + +@login_required +def fitnotes_upload(request): + if request.method == 'POST': + form = FitnotesUploadForm(request.POST, request.FILES) + if form.is_valid(): + _, fname = tempfile.mkstemp() + with open(fname, 'wb') as tmp: + for chunk in request.FILES['file'].chunks(): + tmp.write(chunk) + try: + importers.import_fitnotes_db(fname, request.user) + finally: + os.remove(fname) + else: + form = FitnotesUploadForm() + return render(request, 'lifting/fitnotes.html', {'form': form}) diff --git a/inventory/__init__.py b/inventory/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/inventory/admin.py b/inventory/admin.py new file mode 100644 index 0000000..74c6522 --- /dev/null +++ b/inventory/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin +from .models import Lift + +@admin.register(Lift) +class LiftAdmin(admin.ModelAdmin): + pass diff --git a/inventory/migrations/0001_initial.py b/inventory/migrations/0001_initial.py new file mode 100644 index 0000000..c061669 --- /dev/null +++ b/inventory/migrations/0001_initial.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Bar', + fields=[ + ('id', models.AutoField(verbose_name='ID', auto_created=True, serialize=False, primary_key=True)), + ('name', models.CharField(max_length=100)), + ('weight_kg', models.DecimalField(max_digits=7, decimal_places=3)), + ], + ), + migrations.CreateModel( + name='Lift', + fields=[ + ('id', models.AutoField(verbose_name='ID', auto_created=True, serialize=False, primary_key=True)), + ('name', models.CharField(max_length=200)), + ], + ), + ] diff --git a/inventory/migrations/__init__.py b/inventory/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/inventory/models.py b/inventory/models.py new file mode 100644 index 0000000..6ad588c --- /dev/null +++ b/inventory/models.py @@ -0,0 +1,22 @@ +from django.db import models +from common import to_lb + + +class Bar(models.Model): + name = models.CharField(max_length=100) + weight_kg = models.DecimalField(max_digits=7, decimal_places=3) + + def __str__(self): + return '{} ({}lb / {}kg)'.format(self.name, self.weight_kg, self.weight_lb) + + @property + def weight_lb(self): + return to_lb(self.weight_kg) + + +class Lift(models.Model): + name = models.CharField(max_length=200) + + def __str__(self): + return self.name + diff --git a/inventory/tests.py b/inventory/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/inventory/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/lifting/__init__.py b/lifting/__init__.py index e69de29..4726558 100644 --- a/lifting/__init__.py +++ b/lifting/__init__.py @@ -0,0 +1 @@ +default_app_config = 'lifting.apps.LiftingConfig' diff --git a/lifting/admin.py b/lifting/admin.py index a8dfee1..d7702fc 100644 --- a/lifting/admin.py +++ b/lifting/admin.py @@ -1,15 +1,10 @@ from django.contrib import admin -from .models import Exercise, Set - -@admin.register(Exercise) -class ExerciseAdmin(admin.ModelAdmin): - pass +from .models import Set @admin.register(Set) class SetAdmin(admin.ModelAdmin): date_hierarchy = 'date' - readonly_fields = ('user', 'exercise', 'date') - list_filter = ('user__username', 'exercise') - fields = ('user', 'exercise', 'date', 'weight_kg', 'reps', 'source') - + readonly_fields = ('user', 'lift', 'date') + list_filter = ('user__username', 'lift') + fields = ('user', 'lift', 'date', 'weight_kg', 'reps', 'source') diff --git a/profiles/apps.py b/lifting/apps.py similarity index 64% rename from profiles/apps.py rename to lifting/apps.py index 6ed3e1f..af5d6c3 100644 --- a/profiles/apps.py +++ b/lifting/apps.py @@ -5,14 +5,14 @@ from django.contrib.auth.models import User def create_profile(sender, created, instance, **kwargs): - from .models import Profile + from .models import LiftingOptions if created: - Profile.objects.create(user=instance) + LiftingOptions.objects.create(user=instance) -class ProfileConfig(AppConfig): - name = 'profiles' - app_label = 'profiles' +class LiftingConfig(AppConfig): + name = 'lifting' + app_label = 'lifting' def ready(self): post_save.connect(create_profile, sender=User) diff --git a/lifting/importers.py b/lifting/importers.py deleted file mode 100644 index 0bd66b3..0000000 --- a/lifting/importers.py +++ /dev/null @@ -1,40 +0,0 @@ -import sqlite3 -from django.db import transaction -from lifting.models import Exercise, Set - - -def _clean_name(name): - return name.lower() - - -def import_fitnotes_db(filename, user): - # exercise names to db ids - exercises = {} - for e in Exercise.objects.all(): - for n in e.names: - exercises[_clean_name(n)] = e.id - - # build mapping FitNotes exercise id => our exercise id - exercise_id_mapping = {} - - conn = sqlite3.connect(filename) - cur = conn.cursor() - for fnid, ename in cur.execute('SELECT _id, name FROM exercise WHERE exercise_type_id=0'): - cleaned = _clean_name(ename) - # map to an Exercise id or str - exercise_id_mapping[fnid] = exercises[cleaned] if cleaned in exercises else cleaned - - with transaction.atomic(): - Set.objects.filter(source='fitnotes').delete() - for fnid, date, weight_kg, reps in cur.execute( - 'SELECT exercise_id, date, metric_weight, reps FROM training_log'): - - # create Exercise if it wasn't found and there's a workout using it - if isinstance(exercise_id_mapping[fnid], str): - exercise_id_mapping[fnid] = Exercise.objects.create( - names=[exercise_id_mapping[fnid]]).id - - exercise_id = exercise_id_mapping[fnid] - - Set.objects.create(exercise_id=exercise_id, date=date, weight_kg=weight_kg, reps=reps, - source='fitnotes', user=user) diff --git a/lifting/migrations/0001_initial.py b/lifting/migrations/0001_initial.py index f7611cf..5a5ee98 100644 --- a/lifting/migrations/0001_initial.py +++ b/lifting/migrations/0001_initial.py @@ -3,30 +3,36 @@ from __future__ import unicode_literals from django.db import models, migrations import django.contrib.postgres.fields +from django.conf import settings class Migration(migrations.Migration): dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('inventory', '0001_initial'), ] operations = [ migrations.CreateModel( - name='Exercise', + name='LiftingOptions', fields=[ - ('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)), - ('names', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=200), size=None)), + ('id', models.AutoField(verbose_name='ID', auto_created=True, serialize=False, primary_key=True)), + ('lifting_units', models.CharField(default='i', choices=[('m', 'Metric (kg)'), ('i', 'Imperial (lb)')], max_length=1)), + ('plate_pairs', django.contrib.postgres.fields.ArrayField(base_field=models.DecimalField(max_digits=7, decimal_places=3), default=['45', '45', '25', '10', '5', '5', '2.5', '1.25'], size=None)), + ('user', models.OneToOneField(related_name='lifting_options', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='Set', fields=[ - ('id', models.AutoField(verbose_name='ID', auto_created=True, primary_key=True, serialize=False)), + ('id', models.AutoField(verbose_name='ID', auto_created=True, serialize=False, primary_key=True)), ('date', models.DateField()), - ('weight_kg', models.DecimalField(decimal_places=3, max_digits=7)), + ('weight_kg', models.DecimalField(max_digits=7, decimal_places=3)), ('reps', models.PositiveIntegerField()), ('source', models.CharField(max_length=100)), - ('exercise', models.ForeignKey(to='lifting.Exercise', related_name='sets')), + ('lift', models.ForeignKey(related_name='sets', to='inventory.Lift')), + ('user', models.ForeignKey(related_name='sets', to=settings.AUTH_USER_MODEL)), ], ), ] diff --git a/lifting/migrations/0002_set_user.py b/lifting/migrations/0002_set_user.py deleted file mode 100644 index d9ca992..0000000 --- a/lifting/migrations/0002_set_user.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('lifting', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='set', - name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='sets', default=None), - preserve_default=False, - ), - ] diff --git a/lifting/models.py b/lifting/models.py index ee33358..4cef423 100644 --- a/lifting/models.py +++ b/lifting/models.py @@ -1,30 +1,34 @@ from django.db import models from django.contrib.auth.models import User from django.contrib.postgres.fields import ArrayField +from inventory.models import Lift SET_TYPES = ( ('warmup', 'Warmup'), ('planned', 'Planned'), ) +UNITS = ( + ('m', 'Metric (kg)'), + ('i', 'Imperial (lb)'), +) -class Exercise(models.Model): - names = ArrayField(models.CharField(max_length=200)) - def display_name(self): - return self.names[0].title() +class LiftingOptions(models.Model): + user = models.OneToOneField(User, related_name='lifting_options') - def __str__(self): - return ', '.join(self.names) + lifting_units = models.CharField(max_length=1, choices=UNITS, default='i') + plate_pairs = ArrayField(models.DecimalField(max_digits=7, decimal_places=3), + default=['45','45','25','10','5','5','2.5','1.25']) class Set(models.Model): user = models.ForeignKey(User, related_name='sets') date = models.DateField() - exercise = models.ForeignKey(Exercise, related_name='sets') + lift = models.ForeignKey(Lift, related_name='sets') weight_kg = models.DecimalField(max_digits=7, decimal_places=3) reps = models.PositiveIntegerField() source = models.CharField(max_length=100) def __str__(self): - return '{} - {} @ {}kg - {}'.format(self.exercise, self.reps, self.weight_kg, self.date) + return '{} - {} @ {}kg - {}'.format(self.lift, self.reps, self.weight_kg, self.date) diff --git a/lifting/tests.py b/lifting/tests.py index 3f45138..e6101e7 100644 --- a/lifting/tests.py +++ b/lifting/tests.py @@ -1,55 +1,10 @@ from django.test import TestCase from django.contrib.auth.models import User -from lifting.models import Exercise, Set -from lifting.importers import import_fitnotes_db +from lifting.models import LiftingOptions -class TestFitnotesImport(TestCase): - # fitnotes.db has: - # April 1 - # bench press 10 @ 45 - # bench press 5 @ 95 - # bench press 3 @ 135 - # bench press 5 @ 155 - # April 3 - # squat 10 @ 45 - # squat 5 @ 95 - # squat 3 @ 135 - # squat 2 @ 185 - # squat 5 @ 225 +class TestLiftingOptions(TestCase): - def setUp(self): - self.user = User.objects.create_user('default', 'default@example.com', 'default') - - def test_basic_import(self): - # ensure that the data comes in - import_fitnotes_db('lifting/testdata/example.fitnotes', self.user) - - assert Exercise.objects.count() == 2 - bp = Exercise.objects.get(names__contains=["flat barbell bench press"]) - squat = Exercise.objects.get(names__contains=["barbell squat"]) - assert Set.objects.count() == 9 - - def test_double_import(self): - # two identical dbs, should be idempotent - import_fitnotes_db('lifting/testdata/example.fitnotes', self.user) - import_fitnotes_db('lifting/testdata/example.fitnotes', self.user) - assert Exercise.objects.count() == 2 - assert Set.objects.count() == 9 - - def test_import_with_other_data(self): - Exercise.objects.create(names=['incline bench press']) - e = Exercise.objects.create(names=['flat barbell bench press']) - Set.objects.create(exercise=e, weight_kg=100, reps=10, date='2014-01-01', user=self.user) - import_fitnotes_db('lifting/testdata/example.fitnotes', self.user) - assert Exercise.objects.count() == 3 - assert Set.objects.count() == 10 - - def test_bad_import(self): - # good db then bad db, should fail without screwing up existing data - import_fitnotes_db('lifting/testdata/example.fitnotes', self.user) - with self.assertRaises(Exception): - # baddata.fitnotes has all exercise ids set to 9999 - import_fitnotes_db('lifting/testdata/baddata.fitnotes', self.user) - assert Exercise.objects.count() == 2 - assert Set.objects.count() == 9 + def test_signal(self): + u = User.objects.create_user(username='test', email='test@example.com', password='test') + assert LiftingOptions.objects.filter(user=u).count() == 1 diff --git a/lifting/urls.py b/lifting/urls.py index a4d48fe..691968e 100644 --- a/lifting/urls.py +++ b/lifting/urls.py @@ -10,5 +10,5 @@ urlpatterns = [ url(r'^lifts/$', views.lift_list, name='lift-list'), url(r'^lifts/(?P\d+)/$', views.by_lift, name='lift-detail'), - url(r'^fitnotes/$', views.fitnotes_upload), + url(r'^edit/$', views.edit_profile, name='edit-profile'), ] diff --git a/lifting/views.py b/lifting/views.py index d2cfe2e..c872fb3 100644 --- a/lifting/views.py +++ b/lifting/views.py @@ -11,7 +11,8 @@ from django.views.generic import dates from django.db.models import Count, Max from . import importers -from .models import Set, Exercise +from .models import Set +from inventory.models import Lift @login_required @@ -20,7 +21,7 @@ def month_lifts(request, year, month): sets_by_day = defaultdict(set) for workset in Set.objects.filter(user=request.user, date__year=year, date__month=month): - sets_by_day[workset.date.day].add(workset.exercise) + sets_by_day[workset.date.day].add(workset.lift) date = datetime.date(year, month, 1) # build calendar @@ -68,7 +69,7 @@ def day_lifts(request, year, month, day): @login_required def lift_list(request): - lifts = Exercise.objects.filter(sets__user=request.user).annotate( + lifts = Lift.objects.filter(sets__user=request.user).annotate( total=Count('sets'), max_kg=Max('sets__weight_kg'), last_date=Max('sets__date'), ).order_by('-last_date') @@ -77,8 +78,8 @@ def lift_list(request): @login_required def by_lift(request, lift_id): - lift = Exercise.objects.get(pk=lift_id) - sets = Set.objects.filter(user=request.user, exercise=lift).order_by('-date') + lift = Lift.objects.get(pk=lift_id) + sets = Set.objects.filter(user=request.user, lift=lift).order_by('-date') return render(request, 'lifting/by_lift.html', {'lift': lift, 'sets': sets}) @@ -87,18 +88,7 @@ class FitnotesUploadForm(forms.Form): @login_required -def fitnotes_upload(request): - if request.method == 'POST': - form = FitnotesUploadForm(request.POST, request.FILES) - if form.is_valid(): - _, fname = tempfile.mkstemp() - with open(fname, 'wb') as tmp: - for chunk in request.FILES['file'].chunks(): - tmp.write(chunk) - try: - importers.import_fitnotes_db(fname, request.user) - finally: - os.remove(fname) - else: - form = FitnotesUploadForm() - return render(request, 'lifting/fitnotes.html', {'form': form}) +def edit_profile(request): + form = request.user.profile + + return render(request, 'profiles/edit.html', {'form': form}) diff --git a/profiles/__init__.py b/profiles/__init__.py deleted file mode 100644 index 7e21d18..0000000 --- a/profiles/__init__.py +++ /dev/null @@ -1 +0,0 @@ -default_app_config = 'profiles.apps.ProfileConfig' diff --git a/profiles/migrations/0001_initial.py b/profiles/migrations/0001_initial.py deleted file mode 100644 index 92d412d..0000000 --- a/profiles/migrations/0001_initial.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Profile', - fields=[ - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True, serialize=False)), - ('lifting_units', models.CharField(max_length=1, choices=[('m', 'Metric (kg)'), ('i', 'Imperial (lbs)')])), - ('user', models.OneToOneField(related_name='config', to=settings.AUTH_USER_MODEL)), - ], - ), - ] diff --git a/profiles/migrations/0002_auto_20150410_1627.py b/profiles/migrations/0002_auto_20150410_1627.py deleted file mode 100644 index 6be8450..0000000 --- a/profiles/migrations/0002_auto_20150410_1627.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -from django.conf import settings -import django.contrib.postgres.fields - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('profiles', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='Bar', - fields=[ - ('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID', primary_key=True)), - ('name', models.CharField(max_length=100)), - ('weight_kg', models.DecimalField(max_digits=7, decimal_places=3)), - ('user', models.OneToOneField(related_name='bar', to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.AddField( - model_name='profile', - name='plate_pairs', - field=django.contrib.postgres.fields.ArrayField(default=['45', '45', '25', '10', '5', '5', '2.5', '1.25'], base_field=models.DecimalField(max_digits=7, decimal_places=3), size=None), - ), - migrations.AlterField( - model_name='profile', - name='lifting_units', - field=models.CharField(default='i', choices=[('m', 'Metric (kg)'), ('i', 'Imperial (lb)')], max_length=1), - ), - migrations.AlterField( - model_name='profile', - name='user', - field=models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/profiles/models.py b/profiles/models.py deleted file mode 100644 index f3f0284..0000000 --- a/profiles/models.py +++ /dev/null @@ -1,31 +0,0 @@ -from django.db import models -from django.contrib.auth.models import User -from django.contrib.postgres.fields import ArrayField -from common import to_lb - -UNITS = ( - ('m', 'Metric (kg)'), - ('i', 'Imperial (lb)'), -) - - -class Profile(models.Model): - user = models.OneToOneField(User, related_name='profile') - - lifting_units = models.CharField(max_length=1, choices=UNITS, default='i') - plate_pairs = ArrayField(models.DecimalField(max_digits=7, decimal_places=3), - default=['45','45','25','10','5','5','2.5','1.25']) - - -class Bar(models.Model): - user = models.OneToOneField(User, related_name='bar') - - name = models.CharField(max_length=100) - weight_kg = models.DecimalField(max_digits=7, decimal_places=3) - - def __str__(self): - return '{} ({}lb / {}kg)'.format(self.name, self.weight_kg, self.weight_lb) - - @property - def weight_lb(self): - return to_lb(self.weight_kg) diff --git a/profiles/tests.py b/profiles/tests.py deleted file mode 100644 index aaa1f54..0000000 --- a/profiles/tests.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.test import TestCase -from django.contrib.auth.models import User -from .models import Profile - - -class TestProfile(TestCase): - - def test_signal(self): - - u = User.objects.create_user(username='test', email='test@example.com', password='test') - - assert Profile.objects.filter(user=u).count() == 1 diff --git a/profiles/views.py b/profiles/views.py deleted file mode 100644 index 840b1ff..0000000 --- a/profiles/views.py +++ /dev/null @@ -1,10 +0,0 @@ -from django.shortcuts import render -from django import forms -from django.contrib.auth.decorators import login_required - - -@login_required -def edit_profile(request): - form = request.user.profile - - return render(request, 'profiles/edit.html', {'form': form}) diff --git a/templates/lifting/day.html b/templates/lifting/day.html index 49b5937..2eb26ef 100644 --- a/templates/lifting/day.html +++ b/templates/lifting/day.html @@ -16,7 +16,7 @@ - + @@ -24,7 +24,7 @@ {% for set in sets %} - + diff --git a/templates/lifting/lift_list.html b/templates/lifting/lift_list.html index 12eef25..760b921 100644 --- a/templates/lifting/lift_list.html +++ b/templates/lifting/lift_list.html @@ -14,7 +14,7 @@
ExerciseLift Weight Reps
{{set.exercise}}{{set.lift}} {% mass_unit set.weight_kg %} {{set.reps}}
- + diff --git a/web/settings.py b/web/settings.py index 76dd16e..d559542 100644 --- a/web/settings.py +++ b/web/settings.py @@ -21,8 +21,9 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'django_gravatar', - 'profiles', + 'inventory', 'lifting', + 'fitnotes', ) MIDDLEWARE_CLASSES = (
ExerciseLift Total Sets Last Set Max Weight