From 98efddb8d7be50b893f6173417337a6191e15b86 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 28 May 2020 06:16:59 +0200 Subject: [PATCH] standards can be downloaded and deactivated --- rowers/migrations/0001_initial.py | 40 ++++++++------ rowers/models.py | 10 +++- rowers/scoring.py | 86 +++++++++++++++++++++-------- rowers/templates/standard_form.html | 13 ++++- rowers/templates/standard_view.html | 6 +- rowers/urls.py | 4 ++ rowers/views/racesviews.py | 50 ++++++++++++++++- 7 files changed, 163 insertions(+), 46 deletions(-) diff --git a/rowers/migrations/0001_initial.py b/rowers/migrations/0001_initial.py index 95afc7b0..5f0cdb04 100644 --- a/rowers/migrations/0001_initial.py +++ b/rowers/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.7 on 2020-05-26 18:20 +# Generated by Django 2.1.7 on 2020-05-28 03:31 import datetime from django.conf import settings @@ -45,7 +45,7 @@ class Migration(migrations.Migration): name='C2WorldClassAgePerformance', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('weightcategory', models.CharField(choices=[('hwt', 'heavy-weight'), ('lwt', 'light-weight')], default='hwt', max_length=30)), + ('weightcategory', models.CharField(choices=[('hwt', 'open-weight'), ('lwt', 'light-weight')], default='hwt', max_length=30)), ('sex', models.CharField(choices=[('male', 'male'), ('female', 'female')], default='female', max_length=30)), ('age', models.IntegerField(default=19, verbose_name='Age')), ('distance', models.IntegerField(default=2000)), @@ -59,8 +59,8 @@ class Migration(migrations.Migration): name='CalcAgePerformance', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('weightcategory', models.CharField(choices=[('hwt', 'heavy-weight'), ('lwt', 'light-weight')], default='hwt', max_length=30)), - ('sex', models.CharField(choices=[('male', 'male'), ('female', 'female')], default='female', max_length=30)), + ('weightcategory', models.CharField(choices=[('hwt', 'open-weight'), ('lwt', 'light-weight')], default='hwt', max_length=30)), + ('sex', models.CharField(choices=[('male', 'Open'), ('female', 'Female')], default='female', max_length=30)), ('age', models.IntegerField(default=19, verbose_name='Age')), ('duration', models.FloatField(blank=True, default=1)), ('power', models.IntegerField(default=200)), @@ -109,14 +109,14 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=150)), ('coursedistance', models.IntegerField()), ('coursetime', models.CharField(default='', max_length=100)), - ('coursestandard', models.FloatField()), + ('referencespeed', models.FloatField()), ('agemin', models.IntegerField(default=0)), ('agemax', models.IntegerField(default=120)), ('boatclass', models.CharField(max_length=150)), ('boattype', models.CharField(choices=[('1x', '1x (single)'), ('2x', '2x (double)'), ('2x+', '2x+ (coxed double)'), ('2-', '2- (pair)'), ('2+', '2+ (coxed pair)'), ('3x+', '3x+ (coxed triple)'), ('3x-', '3x- (triple)'), ('4x', '4x (quad)'), ('4x+', '4x+ (coxed quad)'), ('4-', '4- (four)'), ('4+', '4+ (coxed four)'), ('8+', '8+ (eight)'), ('8x+', '8x+ (octuple scull)')], default='1x', max_length=50)), ('sex', models.CharField(max_length=150)), ('weightclass', models.CharField(max_length=150)), - ('adaptiveclass', models.CharField(choices=[('None', 'None'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50)), + ('adaptiveclass', models.CharField(choices=[('None', 'Open'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50)), ('skillclass', models.CharField(max_length=150)), ], ), @@ -227,15 +227,19 @@ class Migration(migrations.Migration): ('teamname', models.CharField(blank=True, max_length=80, null=True, verbose_name='Team Name')), ('username', models.CharField(max_length=150)), ('workoutid', models.IntegerField(null=True)), - ('weightcategory', models.CharField(choices=[('hwt', 'heavy-weight'), ('lwt', 'light-weight')], default='hwt', max_length=10, verbose_name='Weight Category')), - ('adaptiveclass', models.CharField(choices=[('None', 'None'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50, verbose_name='Adaptive Class')), + ('weightcategory', models.CharField(choices=[('hwt', 'open-weight'), ('lwt', 'light-weight')], default='hwt', max_length=10, verbose_name='Weight Category')), + ('adaptiveclass', models.CharField(choices=[('None', 'Open'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50, verbose_name='Adaptive Class')), + ('skillclass', models.CharField(default='Open', max_length=50, verbose_name='Skill Class')), ('duration', models.TimeField(default=datetime.time(1, 0))), ('distance', models.IntegerField(default=0)), + ('referencespeed', models.FloatField(default=5.0)), + ('points', models.IntegerField(default=0)), ('boatclass', models.CharField(choices=[('rower', 'Indoor Rower'), ('dynamic', 'Dynamic Indoor Rower'), ('slides', 'Indoor Rower on Slides')], default='rower', max_length=40, verbose_name='Ergometer Class')), ('coursecompleted', models.BooleanField(default=False)), ('sex', models.CharField(choices=[('male', 'male'), ('female', 'female'), ('not specified', 'not specified')], default='not specified', max_length=30, verbose_name='Gender')), ('age', models.IntegerField(null=True)), ('emailnotifications', models.BooleanField(default=True, verbose_name='Receive challenge notifications by email')), + ('entrycategory', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='rowers.CourseStandard', verbose_name='Group')), ], ), migrations.CreateModel( @@ -340,9 +344,9 @@ class Migration(migrations.Migration): ('tr', models.IntegerField(default=167, verbose_name='TR band lower HR')), ('an', models.IntegerField(default=180, verbose_name='AN band lower HR')), ('hrftp', models.IntegerField(default=0, verbose_name='FTP heart rate')), - ('weightcategory', models.CharField(choices=[('hwt', 'heavy-weight'), ('lwt', 'light-weight')], default='hwt', max_length=30)), + ('weightcategory', models.CharField(choices=[('hwt', 'open-weight'), ('lwt', 'light-weight')], default='hwt', max_length=30)), ('sex', models.CharField(choices=[('male', 'male'), ('female', 'female'), ('not specified', 'not specified')], default='not specified', max_length=30)), - ('adaptiveclass', models.CharField(choices=[('None', 'None'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50, verbose_name='Adaptive Classification')), + ('adaptiveclass', models.CharField(choices=[('None', 'Open'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50, verbose_name='Adaptive Classification')), ('birthdate', models.DateField(blank=True, null=True)), ('ftp', models.IntegerField(default=226, verbose_name='Functional Threshold Power')), ('p0', models.FloatField(default=1.0, verbose_name='CP p1')), @@ -588,10 +592,12 @@ class Migration(migrations.Migration): ('teamname', models.CharField(blank=True, max_length=80, null=True, verbose_name='Team Name')), ('username', models.CharField(max_length=150)), ('workoutid', models.IntegerField(null=True)), - ('weightcategory', models.CharField(choices=[('hwt', 'heavy-weight'), ('lwt', 'light-weight')], default='hwt', max_length=10, verbose_name='Weight Category')), - ('adaptiveclass', models.CharField(choices=[('None', 'None'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50, verbose_name='Adaptive Class')), + ('weightcategory', models.CharField(choices=[('hwt', 'open-weight'), ('lwt', 'light-weight')], default='hwt', max_length=10, verbose_name='Weight Category')), + ('adaptiveclass', models.CharField(choices=[('None', 'Open'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50, verbose_name='Adaptive Class')), + ('skillclass', models.CharField(default='Open', max_length=50, verbose_name='Skill Class')), ('duration', models.TimeField(default=datetime.time(1, 0))), ('distance', models.IntegerField(default=0)), + ('points', models.IntegerField(default=0)), ('boatclass', models.CharField(choices=[('water', 'Standard Racing Shell'), ('coastal', 'Coastal'), ('c-boat', 'Dutch C boat'), ('churchboat', 'Finnish Church boat')], default='water', max_length=40, verbose_name='Boat Class')), ('boattype', models.CharField(choices=[('1x', '1x (single)'), ('2x', '2x (double)'), ('2x+', '2x+ (coxed double)'), ('2-', '2- (pair)'), ('2+', '2+ (coxed pair)'), ('3x+', '3x+ (coxed triple)'), ('3x-', '3x- (triple)'), ('4x', '4x (quad)'), ('4x+', '4x+ (coxed quad)'), ('4-', '4- (four)'), ('4+', '4+ (coxed four)'), ('8+', '8+ (eight)'), ('8x+', '8x+ (octuple scull)')], default='1x', max_length=40, verbose_name='Boat Type')), ('coursecompleted', models.BooleanField(default=False)), @@ -600,6 +606,8 @@ class Migration(migrations.Migration): ('emailnotifications', models.BooleanField(default=True, verbose_name='Receive challenge notifications by email')), ('startsecond', models.FloatField(default=0)), ('endsecond', models.FloatField(default=0)), + ('referencespeed', models.FloatField(default=5.0)), + ('entrycategory', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='rowers.CourseStandard', verbose_name='Group')), ], ), migrations.CreateModel( @@ -611,7 +619,7 @@ class Migration(migrations.Migration): ('workouttype', models.CharField(choices=[('water', 'Standard Racing Shell'), ('rower', 'Indoor Rower'), ('skierg', 'Ski Erg'), ('bikeerg', 'Bike Erg'), ('dynamic', 'Dynamic Indoor Rower'), ('slides', 'Indoor Rower on Slides'), ('paddle', 'Paddle Adapter'), ('snow', 'On-snow'), ('coastal', 'Coastal'), ('c-boat', 'Dutch C boat'), ('churchboat', 'Finnish Church boat'), ('Ride', 'Ride'), ('Bike', 'Bike'), ('Run', 'Run'), ('NordicSki', 'NordicSki'), ('Swim', 'Swim'), ('Hike', 'Hike'), ('Walk', 'Walk'), ('Canoeing', 'Canoeing'), ('Crossfit', 'Crossfit'), ('StandUpPaddling', 'StandUpPaddling'), ('IceSkate', 'IceSkate'), ('WeightTraining', 'WeightTraining'), ('InlineSkate', 'InlineSkate'), ('Kayaking', 'Kayaking'), ('Workout', 'Workout'), ('Yoga', 'Yoga'), ('other', 'Other')], max_length=50, verbose_name='Exercise/Boat Class')), ('workoutsource', models.CharField(default='unknown', max_length=100)), ('boattype', models.CharField(choices=[('1x', '1x (single)'), ('2x', '2x (double)'), ('2x+', '2x+ (coxed double)'), ('2-', '2- (pair)'), ('2+', '2+ (coxed pair)'), ('3x+', '3x+ (coxed triple)'), ('3x-', '3x- (triple)'), ('4x', '4x (quad)'), ('4x+', '4x+ (coxed quad)'), ('4-', '4- (four)'), ('4+', '4+ (coxed four)'), ('8+', '8+ (eight)'), ('8x+', '8x+ (octuple scull)')], default='1x', max_length=50, verbose_name='Boat Type')), - ('adaptiveclass', models.CharField(choices=[('None', 'None'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50, verbose_name='Adaptive Classification')), + ('adaptiveclass', models.CharField(choices=[('None', 'Open'), ('PR1', 'PR1 (Arms and Shoulders)'), ('PR2', 'PR2 (Trunk and Arms)'), ('PR3', 'PR3 (Leg Trunk and Arms)'), ('FES', 'FES (Functional Electrical Stimulation)')], default='None', max_length=50, verbose_name='Adaptive Classification')), ('starttime', models.TimeField(default=datetime.time(12, 0))), ('startdatetime', models.DateTimeField(blank=True, null=True)), ('timezone', models.CharField(default='UTC', max_length=100)), @@ -624,7 +632,7 @@ class Migration(migrations.Migration): ('normp', models.IntegerField(blank=True, default=-1)), ('normv', models.FloatField(blank=True, default=-1)), ('normw', models.FloatField(blank=True, default=-1)), - ('weightcategory', models.CharField(choices=[('hwt', 'heavy-weight'), ('lwt', 'light-weight')], default='hwt', max_length=10, verbose_name='Weight Category')), + ('weightcategory', models.CharField(choices=[('hwt', 'open-weight'), ('lwt', 'light-weight')], default='hwt', max_length=10, verbose_name='Weight Category')), ('weightvalue', models.FloatField(blank=True, default=80.0, verbose_name='Average Crew Weight (kg)')), ('csvfilename', models.CharField(blank=True, max_length=150)), ('uploadedtoc2', models.IntegerField(default=0)), @@ -671,7 +679,7 @@ class Migration(migrations.Migration): ('timezone', models.CharField(choices=[('Africa/Abidjan', 'Africa/Abidjan'), ('Africa/Accra', 'Africa/Accra'), ('Africa/Addis_Ababa', 'Africa/Addis_Ababa'), ('Africa/Algiers', 'Africa/Algiers'), ('Africa/Asmara', 'Africa/Asmara'), ('Africa/Bamako', 'Africa/Bamako'), ('Africa/Bangui', 'Africa/Bangui'), ('Africa/Banjul', 'Africa/Banjul'), ('Africa/Bissau', 'Africa/Bissau'), ('Africa/Blantyre', 'Africa/Blantyre'), ('Africa/Brazzaville', 'Africa/Brazzaville'), ('Africa/Bujumbura', 'Africa/Bujumbura'), ('Africa/Cairo', 'Africa/Cairo'), ('Africa/Casablanca', 'Africa/Casablanca'), ('Africa/Ceuta', 'Africa/Ceuta'), ('Africa/Conakry', 'Africa/Conakry'), ('Africa/Dakar', 'Africa/Dakar'), ('Africa/Dar_es_Salaam', 'Africa/Dar_es_Salaam'), ('Africa/Djibouti', 'Africa/Djibouti'), ('Africa/Douala', 'Africa/Douala'), ('Africa/El_Aaiun', 'Africa/El_Aaiun'), ('Africa/Freetown', 'Africa/Freetown'), ('Africa/Gaborone', 'Africa/Gaborone'), ('Africa/Harare', 'Africa/Harare'), ('Africa/Johannesburg', 'Africa/Johannesburg'), ('Africa/Juba', 'Africa/Juba'), ('Africa/Kampala', 'Africa/Kampala'), ('Africa/Khartoum', 'Africa/Khartoum'), ('Africa/Kigali', 'Africa/Kigali'), ('Africa/Kinshasa', 'Africa/Kinshasa'), ('Africa/Lagos', 'Africa/Lagos'), ('Africa/Libreville', 'Africa/Libreville'), ('Africa/Lome', 'Africa/Lome'), ('Africa/Luanda', 'Africa/Luanda'), ('Africa/Lubumbashi', 'Africa/Lubumbashi'), ('Africa/Lusaka', 'Africa/Lusaka'), ('Africa/Malabo', 'Africa/Malabo'), ('Africa/Maputo', 'Africa/Maputo'), ('Africa/Maseru', 'Africa/Maseru'), ('Africa/Mbabane', 'Africa/Mbabane'), ('Africa/Mogadishu', 'Africa/Mogadishu'), ('Africa/Monrovia', 'Africa/Monrovia'), ('Africa/Nairobi', 'Africa/Nairobi'), ('Africa/Ndjamena', 'Africa/Ndjamena'), ('Africa/Niamey', 'Africa/Niamey'), ('Africa/Nouakchott', 'Africa/Nouakchott'), ('Africa/Ouagadougou', 'Africa/Ouagadougou'), ('Africa/Porto-Novo', 'Africa/Porto-Novo'), ('Africa/Sao_Tome', 'Africa/Sao_Tome'), ('Africa/Tripoli', 'Africa/Tripoli'), ('Africa/Tunis', 'Africa/Tunis'), ('Africa/Windhoek', 'Africa/Windhoek'), ('America/Adak', 'America/Adak'), ('America/Anchorage', 'America/Anchorage'), ('America/Anguilla', 'America/Anguilla'), ('America/Antigua', 'America/Antigua'), ('America/Araguaina', 'America/Araguaina'), ('America/Argentina/Buenos_Aires', 'America/Argentina/Buenos_Aires'), ('America/Argentina/Catamarca', 'America/Argentina/Catamarca'), ('America/Argentina/Cordoba', 'America/Argentina/Cordoba'), ('America/Argentina/Jujuy', 'America/Argentina/Jujuy'), ('America/Argentina/La_Rioja', 'America/Argentina/La_Rioja'), ('America/Argentina/Mendoza', 'America/Argentina/Mendoza'), ('America/Argentina/Rio_Gallegos', 'America/Argentina/Rio_Gallegos'), ('America/Argentina/Salta', 'America/Argentina/Salta'), ('America/Argentina/San_Juan', 'America/Argentina/San_Juan'), ('America/Argentina/San_Luis', 'America/Argentina/San_Luis'), ('America/Argentina/Tucuman', 'America/Argentina/Tucuman'), ('America/Argentina/Ushuaia', 'America/Argentina/Ushuaia'), ('America/Aruba', 'America/Aruba'), ('America/Asuncion', 'America/Asuncion'), ('America/Atikokan', 'America/Atikokan'), ('America/Bahia', 'America/Bahia'), ('America/Bahia_Banderas', 'America/Bahia_Banderas'), ('America/Barbados', 'America/Barbados'), ('America/Belem', 'America/Belem'), ('America/Belize', 'America/Belize'), ('America/Blanc-Sablon', 'America/Blanc-Sablon'), ('America/Boa_Vista', 'America/Boa_Vista'), ('America/Bogota', 'America/Bogota'), ('America/Boise', 'America/Boise'), ('America/Cambridge_Bay', 'America/Cambridge_Bay'), ('America/Campo_Grande', 'America/Campo_Grande'), ('America/Cancun', 'America/Cancun'), ('America/Caracas', 'America/Caracas'), ('America/Cayenne', 'America/Cayenne'), ('America/Cayman', 'America/Cayman'), ('America/Chicago', 'America/Chicago'), ('America/Chihuahua', 'America/Chihuahua'), ('America/Costa_Rica', 'America/Costa_Rica'), ('America/Creston', 'America/Creston'), ('America/Cuiaba', 'America/Cuiaba'), ('America/Curacao', 'America/Curacao'), ('America/Danmarkshavn', 'America/Danmarkshavn'), ('America/Dawson', 'America/Dawson'), ('America/Dawson_Creek', 'America/Dawson_Creek'), ('America/Denver', 'America/Denver'), ('America/Detroit', 'America/Detroit'), ('America/Dominica', 'America/Dominica'), ('America/Edmonton', 'America/Edmonton'), ('America/Eirunepe', 'America/Eirunepe'), ('America/El_Salvador', 'America/El_Salvador'), ('America/Fort_Nelson', 'America/Fort_Nelson'), ('America/Fortaleza', 'America/Fortaleza'), ('America/Glace_Bay', 'America/Glace_Bay'), ('America/Goose_Bay', 'America/Goose_Bay'), ('America/Grand_Turk', 'America/Grand_Turk'), ('America/Grenada', 'America/Grenada'), ('America/Guadeloupe', 'America/Guadeloupe'), ('America/Guatemala', 'America/Guatemala'), ('America/Guayaquil', 'America/Guayaquil'), ('America/Guyana', 'America/Guyana'), ('America/Halifax', 'America/Halifax'), ('America/Havana', 'America/Havana'), ('America/Hermosillo', 'America/Hermosillo'), ('America/Indiana/Indianapolis', 'America/Indiana/Indianapolis'), ('America/Indiana/Knox', 'America/Indiana/Knox'), ('America/Indiana/Marengo', 'America/Indiana/Marengo'), ('America/Indiana/Petersburg', 'America/Indiana/Petersburg'), ('America/Indiana/Tell_City', 'America/Indiana/Tell_City'), ('America/Indiana/Vevay', 'America/Indiana/Vevay'), ('America/Indiana/Vincennes', 'America/Indiana/Vincennes'), ('America/Indiana/Winamac', 'America/Indiana/Winamac'), ('America/Inuvik', 'America/Inuvik'), ('America/Iqaluit', 'America/Iqaluit'), ('America/Jamaica', 'America/Jamaica'), ('America/Juneau', 'America/Juneau'), ('America/Kentucky/Louisville', 'America/Kentucky/Louisville'), ('America/Kentucky/Monticello', 'America/Kentucky/Monticello'), ('America/Kralendijk', 'America/Kralendijk'), ('America/La_Paz', 'America/La_Paz'), ('America/Lima', 'America/Lima'), ('America/Los_Angeles', 'America/Los_Angeles'), ('America/Lower_Princes', 'America/Lower_Princes'), ('America/Maceio', 'America/Maceio'), ('America/Managua', 'America/Managua'), ('America/Manaus', 'America/Manaus'), ('America/Marigot', 'America/Marigot'), ('America/Martinique', 'America/Martinique'), ('America/Matamoros', 'America/Matamoros'), ('America/Mazatlan', 'America/Mazatlan'), ('America/Menominee', 'America/Menominee'), ('America/Merida', 'America/Merida'), ('America/Metlakatla', 'America/Metlakatla'), ('America/Mexico_City', 'America/Mexico_City'), ('America/Miquelon', 'America/Miquelon'), ('America/Moncton', 'America/Moncton'), ('America/Monterrey', 'America/Monterrey'), ('America/Montevideo', 'America/Montevideo'), ('America/Montserrat', 'America/Montserrat'), ('America/Nassau', 'America/Nassau'), ('America/New_York', 'America/New_York'), ('America/Nipigon', 'America/Nipigon'), ('America/Nome', 'America/Nome'), ('America/Noronha', 'America/Noronha'), ('America/North_Dakota/Beulah', 'America/North_Dakota/Beulah'), ('America/North_Dakota/Center', 'America/North_Dakota/Center'), ('America/North_Dakota/New_Salem', 'America/North_Dakota/New_Salem'), ('America/Nuuk', 'America/Nuuk'), ('America/Ojinaga', 'America/Ojinaga'), ('America/Panama', 'America/Panama'), ('America/Pangnirtung', 'America/Pangnirtung'), ('America/Paramaribo', 'America/Paramaribo'), ('America/Phoenix', 'America/Phoenix'), ('America/Port-au-Prince', 'America/Port-au-Prince'), ('America/Port_of_Spain', 'America/Port_of_Spain'), ('America/Porto_Velho', 'America/Porto_Velho'), ('America/Puerto_Rico', 'America/Puerto_Rico'), ('America/Punta_Arenas', 'America/Punta_Arenas'), ('America/Rainy_River', 'America/Rainy_River'), ('America/Rankin_Inlet', 'America/Rankin_Inlet'), ('America/Recife', 'America/Recife'), ('America/Regina', 'America/Regina'), ('America/Resolute', 'America/Resolute'), ('America/Rio_Branco', 'America/Rio_Branco'), ('America/Santarem', 'America/Santarem'), ('America/Santiago', 'America/Santiago'), ('America/Santo_Domingo', 'America/Santo_Domingo'), ('America/Sao_Paulo', 'America/Sao_Paulo'), ('America/Scoresbysund', 'America/Scoresbysund'), ('America/Sitka', 'America/Sitka'), ('America/St_Barthelemy', 'America/St_Barthelemy'), ('America/St_Johns', 'America/St_Johns'), ('America/St_Kitts', 'America/St_Kitts'), ('America/St_Lucia', 'America/St_Lucia'), ('America/St_Thomas', 'America/St_Thomas'), ('America/St_Vincent', 'America/St_Vincent'), ('America/Swift_Current', 'America/Swift_Current'), ('America/Tegucigalpa', 'America/Tegucigalpa'), ('America/Thule', 'America/Thule'), ('America/Thunder_Bay', 'America/Thunder_Bay'), ('America/Tijuana', 'America/Tijuana'), ('America/Toronto', 'America/Toronto'), ('America/Tortola', 'America/Tortola'), ('America/Vancouver', 'America/Vancouver'), ('America/Whitehorse', 'America/Whitehorse'), ('America/Winnipeg', 'America/Winnipeg'), ('America/Yakutat', 'America/Yakutat'), ('America/Yellowknife', 'America/Yellowknife'), ('Antarctica/Casey', 'Antarctica/Casey'), ('Antarctica/Davis', 'Antarctica/Davis'), ('Antarctica/DumontDUrville', 'Antarctica/DumontDUrville'), ('Antarctica/Macquarie', 'Antarctica/Macquarie'), ('Antarctica/Mawson', 'Antarctica/Mawson'), ('Antarctica/McMurdo', 'Antarctica/McMurdo'), ('Antarctica/Palmer', 'Antarctica/Palmer'), ('Antarctica/Rothera', 'Antarctica/Rothera'), ('Antarctica/Syowa', 'Antarctica/Syowa'), ('Antarctica/Troll', 'Antarctica/Troll'), ('Antarctica/Vostok', 'Antarctica/Vostok'), ('Arctic/Longyearbyen', 'Arctic/Longyearbyen'), ('Asia/Aden', 'Asia/Aden'), ('Asia/Almaty', 'Asia/Almaty'), ('Asia/Amman', 'Asia/Amman'), ('Asia/Anadyr', 'Asia/Anadyr'), ('Asia/Aqtau', 'Asia/Aqtau'), ('Asia/Aqtobe', 'Asia/Aqtobe'), ('Asia/Ashgabat', 'Asia/Ashgabat'), ('Asia/Atyrau', 'Asia/Atyrau'), ('Asia/Baghdad', 'Asia/Baghdad'), ('Asia/Bahrain', 'Asia/Bahrain'), ('Asia/Baku', 'Asia/Baku'), ('Asia/Bangkok', 'Asia/Bangkok'), ('Asia/Barnaul', 'Asia/Barnaul'), ('Asia/Beirut', 'Asia/Beirut'), ('Asia/Bishkek', 'Asia/Bishkek'), ('Asia/Brunei', 'Asia/Brunei'), ('Asia/Chita', 'Asia/Chita'), ('Asia/Choibalsan', 'Asia/Choibalsan'), ('Asia/Colombo', 'Asia/Colombo'), ('Asia/Damascus', 'Asia/Damascus'), ('Asia/Dhaka', 'Asia/Dhaka'), ('Asia/Dili', 'Asia/Dili'), ('Asia/Dubai', 'Asia/Dubai'), ('Asia/Dushanbe', 'Asia/Dushanbe'), ('Asia/Famagusta', 'Asia/Famagusta'), ('Asia/Gaza', 'Asia/Gaza'), ('Asia/Hebron', 'Asia/Hebron'), ('Asia/Ho_Chi_Minh', 'Asia/Ho_Chi_Minh'), ('Asia/Hong_Kong', 'Asia/Hong_Kong'), ('Asia/Hovd', 'Asia/Hovd'), ('Asia/Irkutsk', 'Asia/Irkutsk'), ('Asia/Jakarta', 'Asia/Jakarta'), ('Asia/Jayapura', 'Asia/Jayapura'), ('Asia/Jerusalem', 'Asia/Jerusalem'), ('Asia/Kabul', 'Asia/Kabul'), ('Asia/Kamchatka', 'Asia/Kamchatka'), ('Asia/Karachi', 'Asia/Karachi'), ('Asia/Kathmandu', 'Asia/Kathmandu'), ('Asia/Khandyga', 'Asia/Khandyga'), ('Asia/Kolkata', 'Asia/Kolkata'), ('Asia/Krasnoyarsk', 'Asia/Krasnoyarsk'), ('Asia/Kuala_Lumpur', 'Asia/Kuala_Lumpur'), ('Asia/Kuching', 'Asia/Kuching'), ('Asia/Kuwait', 'Asia/Kuwait'), ('Asia/Macau', 'Asia/Macau'), ('Asia/Magadan', 'Asia/Magadan'), ('Asia/Makassar', 'Asia/Makassar'), ('Asia/Manila', 'Asia/Manila'), ('Asia/Muscat', 'Asia/Muscat'), ('Asia/Nicosia', 'Asia/Nicosia'), ('Asia/Novokuznetsk', 'Asia/Novokuznetsk'), ('Asia/Novosibirsk', 'Asia/Novosibirsk'), ('Asia/Omsk', 'Asia/Omsk'), ('Asia/Oral', 'Asia/Oral'), ('Asia/Phnom_Penh', 'Asia/Phnom_Penh'), ('Asia/Pontianak', 'Asia/Pontianak'), ('Asia/Pyongyang', 'Asia/Pyongyang'), ('Asia/Qatar', 'Asia/Qatar'), ('Asia/Qostanay', 'Asia/Qostanay'), ('Asia/Qyzylorda', 'Asia/Qyzylorda'), ('Asia/Riyadh', 'Asia/Riyadh'), ('Asia/Sakhalin', 'Asia/Sakhalin'), ('Asia/Samarkand', 'Asia/Samarkand'), ('Asia/Seoul', 'Asia/Seoul'), ('Asia/Shanghai', 'Asia/Shanghai'), ('Asia/Singapore', 'Asia/Singapore'), ('Asia/Srednekolymsk', 'Asia/Srednekolymsk'), ('Asia/Taipei', 'Asia/Taipei'), ('Asia/Tashkent', 'Asia/Tashkent'), ('Asia/Tbilisi', 'Asia/Tbilisi'), ('Asia/Tehran', 'Asia/Tehran'), ('Asia/Thimphu', 'Asia/Thimphu'), ('Asia/Tokyo', 'Asia/Tokyo'), ('Asia/Tomsk', 'Asia/Tomsk'), ('Asia/Ulaanbaatar', 'Asia/Ulaanbaatar'), ('Asia/Urumqi', 'Asia/Urumqi'), ('Asia/Ust-Nera', 'Asia/Ust-Nera'), ('Asia/Vientiane', 'Asia/Vientiane'), ('Asia/Vladivostok', 'Asia/Vladivostok'), ('Asia/Yakutsk', 'Asia/Yakutsk'), ('Asia/Yangon', 'Asia/Yangon'), ('Asia/Yekaterinburg', 'Asia/Yekaterinburg'), ('Asia/Yerevan', 'Asia/Yerevan'), ('Atlantic/Azores', 'Atlantic/Azores'), ('Atlantic/Bermuda', 'Atlantic/Bermuda'), ('Atlantic/Canary', 'Atlantic/Canary'), ('Atlantic/Cape_Verde', 'Atlantic/Cape_Verde'), ('Atlantic/Faroe', 'Atlantic/Faroe'), ('Atlantic/Madeira', 'Atlantic/Madeira'), ('Atlantic/Reykjavik', 'Atlantic/Reykjavik'), ('Atlantic/South_Georgia', 'Atlantic/South_Georgia'), ('Atlantic/St_Helena', 'Atlantic/St_Helena'), ('Atlantic/Stanley', 'Atlantic/Stanley'), ('Australia/Adelaide', 'Australia/Adelaide'), ('Australia/Brisbane', 'Australia/Brisbane'), ('Australia/Broken_Hill', 'Australia/Broken_Hill'), ('Australia/Currie', 'Australia/Currie'), ('Australia/Darwin', 'Australia/Darwin'), ('Australia/Eucla', 'Australia/Eucla'), ('Australia/Hobart', 'Australia/Hobart'), ('Australia/Lindeman', 'Australia/Lindeman'), ('Australia/Lord_Howe', 'Australia/Lord_Howe'), ('Australia/Melbourne', 'Australia/Melbourne'), ('Australia/Perth', 'Australia/Perth'), ('Australia/Sydney', 'Australia/Sydney'), ('Canada/Atlantic', 'Canada/Atlantic'), ('Canada/Central', 'Canada/Central'), ('Canada/Eastern', 'Canada/Eastern'), ('Canada/Mountain', 'Canada/Mountain'), ('Canada/Newfoundland', 'Canada/Newfoundland'), ('Canada/Pacific', 'Canada/Pacific'), ('Europe/Amsterdam', 'Europe/Amsterdam'), ('Europe/Andorra', 'Europe/Andorra'), ('Europe/Astrakhan', 'Europe/Astrakhan'), ('Europe/Athens', 'Europe/Athens'), ('Europe/Belgrade', 'Europe/Belgrade'), ('Europe/Berlin', 'Europe/Berlin'), ('Europe/Bratislava', 'Europe/Bratislava'), ('Europe/Brussels', 'Europe/Brussels'), ('Europe/Bucharest', 'Europe/Bucharest'), ('Europe/Budapest', 'Europe/Budapest'), ('Europe/Busingen', 'Europe/Busingen'), ('Europe/Chisinau', 'Europe/Chisinau'), ('Europe/Copenhagen', 'Europe/Copenhagen'), ('Europe/Dublin', 'Europe/Dublin'), ('Europe/Gibraltar', 'Europe/Gibraltar'), ('Europe/Guernsey', 'Europe/Guernsey'), ('Europe/Helsinki', 'Europe/Helsinki'), ('Europe/Isle_of_Man', 'Europe/Isle_of_Man'), ('Europe/Istanbul', 'Europe/Istanbul'), ('Europe/Jersey', 'Europe/Jersey'), ('Europe/Kaliningrad', 'Europe/Kaliningrad'), ('Europe/Kiev', 'Europe/Kiev'), ('Europe/Kirov', 'Europe/Kirov'), ('Europe/Lisbon', 'Europe/Lisbon'), ('Europe/Ljubljana', 'Europe/Ljubljana'), ('Europe/London', 'Europe/London'), ('Europe/Luxembourg', 'Europe/Luxembourg'), ('Europe/Madrid', 'Europe/Madrid'), ('Europe/Malta', 'Europe/Malta'), ('Europe/Mariehamn', 'Europe/Mariehamn'), ('Europe/Minsk', 'Europe/Minsk'), ('Europe/Monaco', 'Europe/Monaco'), ('Europe/Moscow', 'Europe/Moscow'), ('Europe/Oslo', 'Europe/Oslo'), ('Europe/Paris', 'Europe/Paris'), ('Europe/Podgorica', 'Europe/Podgorica'), ('Europe/Prague', 'Europe/Prague'), ('Europe/Riga', 'Europe/Riga'), ('Europe/Rome', 'Europe/Rome'), ('Europe/Samara', 'Europe/Samara'), ('Europe/San_Marino', 'Europe/San_Marino'), ('Europe/Sarajevo', 'Europe/Sarajevo'), ('Europe/Saratov', 'Europe/Saratov'), ('Europe/Simferopol', 'Europe/Simferopol'), ('Europe/Skopje', 'Europe/Skopje'), ('Europe/Sofia', 'Europe/Sofia'), ('Europe/Stockholm', 'Europe/Stockholm'), ('Europe/Tallinn', 'Europe/Tallinn'), ('Europe/Tirane', 'Europe/Tirane'), ('Europe/Ulyanovsk', 'Europe/Ulyanovsk'), ('Europe/Uzhgorod', 'Europe/Uzhgorod'), ('Europe/Vaduz', 'Europe/Vaduz'), ('Europe/Vatican', 'Europe/Vatican'), ('Europe/Vienna', 'Europe/Vienna'), ('Europe/Vilnius', 'Europe/Vilnius'), ('Europe/Volgograd', 'Europe/Volgograd'), ('Europe/Warsaw', 'Europe/Warsaw'), ('Europe/Zagreb', 'Europe/Zagreb'), ('Europe/Zaporozhye', 'Europe/Zaporozhye'), ('Europe/Zurich', 'Europe/Zurich'), ('GMT', 'GMT'), ('Indian/Antananarivo', 'Indian/Antananarivo'), ('Indian/Chagos', 'Indian/Chagos'), ('Indian/Christmas', 'Indian/Christmas'), ('Indian/Cocos', 'Indian/Cocos'), ('Indian/Comoro', 'Indian/Comoro'), ('Indian/Kerguelen', 'Indian/Kerguelen'), ('Indian/Mahe', 'Indian/Mahe'), ('Indian/Maldives', 'Indian/Maldives'), ('Indian/Mauritius', 'Indian/Mauritius'), ('Indian/Mayotte', 'Indian/Mayotte'), ('Indian/Reunion', 'Indian/Reunion'), ('Pacific/Apia', 'Pacific/Apia'), ('Pacific/Auckland', 'Pacific/Auckland'), ('Pacific/Bougainville', 'Pacific/Bougainville'), ('Pacific/Chatham', 'Pacific/Chatham'), ('Pacific/Chuuk', 'Pacific/Chuuk'), ('Pacific/Easter', 'Pacific/Easter'), ('Pacific/Efate', 'Pacific/Efate'), ('Pacific/Enderbury', 'Pacific/Enderbury'), ('Pacific/Fakaofo', 'Pacific/Fakaofo'), ('Pacific/Fiji', 'Pacific/Fiji'), ('Pacific/Funafuti', 'Pacific/Funafuti'), ('Pacific/Galapagos', 'Pacific/Galapagos'), ('Pacific/Gambier', 'Pacific/Gambier'), ('Pacific/Guadalcanal', 'Pacific/Guadalcanal'), ('Pacific/Guam', 'Pacific/Guam'), ('Pacific/Honolulu', 'Pacific/Honolulu'), ('Pacific/Kiritimati', 'Pacific/Kiritimati'), ('Pacific/Kosrae', 'Pacific/Kosrae'), ('Pacific/Kwajalein', 'Pacific/Kwajalein'), ('Pacific/Majuro', 'Pacific/Majuro'), ('Pacific/Marquesas', 'Pacific/Marquesas'), ('Pacific/Midway', 'Pacific/Midway'), ('Pacific/Nauru', 'Pacific/Nauru'), ('Pacific/Niue', 'Pacific/Niue'), ('Pacific/Norfolk', 'Pacific/Norfolk'), ('Pacific/Noumea', 'Pacific/Noumea'), ('Pacific/Pago_Pago', 'Pacific/Pago_Pago'), ('Pacific/Palau', 'Pacific/Palau'), ('Pacific/Pitcairn', 'Pacific/Pitcairn'), ('Pacific/Pohnpei', 'Pacific/Pohnpei'), ('Pacific/Port_Moresby', 'Pacific/Port_Moresby'), ('Pacific/Rarotonga', 'Pacific/Rarotonga'), ('Pacific/Saipan', 'Pacific/Saipan'), ('Pacific/Tahiti', 'Pacific/Tahiti'), ('Pacific/Tarawa', 'Pacific/Tarawa'), ('Pacific/Tongatapu', 'Pacific/Tongatapu'), ('Pacific/Wake', 'Pacific/Wake'), ('Pacific/Wallis', 'Pacific/Wallis'), ('US/Alaska', 'US/Alaska'), ('US/Arizona', 'US/Arizona'), ('US/Central', 'US/Central'), ('US/Eastern', 'US/Eastern'), ('US/Hawaii', 'US/Hawaii'), ('US/Mountain', 'US/Mountain'), ('US/Pacific', 'US/Pacific'), ('UTC', 'UTC')], default='UTC', max_length=100)), ('contact_phone', models.CharField(blank=True, max_length=17, validators=[django.core.validators.RegexValidator(message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.", regex='^\\+?1?\\d{9,15}$')])), ('contact_email', models.EmailField(blank=True, max_length=254, validators=[django.core.validators.EmailValidator()])), - ('coursestandards', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='rowers.StandardCollection')), + ('coursestandards', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='rowers.StandardCollection', verbose_name='Standard Times')), ], bases=('rowers.plannedsession',), ), @@ -852,6 +860,6 @@ class Migration(migrations.Migration): ), migrations.AlterUniqueTogether( name='coursestandard', - unique_together={('name', 'sex', 'agemin', 'agemax', 'boatclass', 'boattype', 'weightclass', 'adaptiveclass', 'skillclass', 'standardcollection')}, + unique_together={('name', 'standardcollection')}, ), ] diff --git a/rowers/models.py b/rowers/models.py index a0a74a42..715e37c3 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -2187,6 +2187,7 @@ class StandardCollection(models.Model): name = models.CharField(max_length=150) manager = models.ForeignKey(User, null=True,on_delete=models.CASCADE) notes = models.CharField(blank=True,null=True,max_length=1000) + active = models.BooleanField(default=True) def __str__(self): return self.name @@ -2207,9 +2208,10 @@ class CourseStandard(models.Model): standardcollection = models.ForeignKey(StandardCollection,on_delete=models.CASCADE) class Meta: - unique_together = ('name','sex','agemin', - 'agemax','boatclass','boattype','weightclass','adaptiveclass', - 'skillclass','standardcollection') + unique_together = ( + ('name','standardcollection') + ) + def __str__(self): return self.name @@ -2456,6 +2458,7 @@ class IndoorVirtualRaceForm(ModelForm): self.fields['sessionunit'].initial = 'm' if timezone: self.fields['timezone'].initial = timezone + self.fields['coursestandards'].queryset = StandardCollection.objects.filter(active=True) def clean(self): cd = self.cleaned_data @@ -2583,6 +2586,7 @@ class VirtualRaceForm(ModelForm): def __init__(self,*args,**kwargs): super(VirtualRaceForm, self).__init__(*args, **kwargs) self.fields['course'].queryset = GeoCourse.objects.all().order_by("country","name") + self.fields['coursestandards'].queryset = StandardCollection.objects.filter(active=True) def clean(self): diff --git a/rowers/scoring.py b/rowers/scoring.py index 38cba81a..8e24257b 100644 --- a/rowers/scoring.py +++ b/rowers/scoring.py @@ -1,4 +1,4 @@ -from rowers.models import StandardCollection,CourseStandard +from rowers.models import StandardCollection,CourseStandard, VirtualRaceResult,IndoorVirtualRaceResult import pandas as pd import arrow @@ -10,7 +10,8 @@ def save_scoring(name,user,filename,id=0,notes=""): collection.save() standards = CourseStandard.objects.filter(standardcollection=collection) for standard in standards: - standard.delete() + standards.delete() + else: try: collection = StandardCollection.objects.get(id=id) @@ -19,8 +20,11 @@ def save_scoring(name,user,filename,id=0,notes=""): collection.save() standards = CourseStandard.objects.filter(standardcollection=collection) for standard in standards: - print(standard,collection) - standard.delete() + records1 = VirtualRaceResult.objects.filter(entrycategory=standard) + records2 = IndoorVirtualRaceResult.objects.filter(entrycategory=standard) + if records1.count()+records2.count() == 0: + standard.delete() + except StandardCollection.DoesNotExist: return 0 @@ -30,6 +34,22 @@ def save_scoring(name,user,filename,id=0,notes=""): except: return 0 + df.rename( + columns={ + 'name':'Name', + 'agemax':'MaxAge', + 'agemin':'MinAge', + 'adaptiveclass':'AdaptiveClass', + 'coursedistance':'CourseDistance', + 'coursetime':'CourseStandard', + 'boatclass':'BoatClass', + 'boattype':'BoatType', + 'sex':'Gender', + 'weightclass':'WeightClass', + 'skillclass':'SkillClass', + }, + inplace=True) + df = df.drop_duplicates(['Name']) for index, row in df.iterrows(): @@ -60,9 +80,9 @@ def save_scoring(name,user,filename,id=0,notes=""): try: boatclass = row['BoatClass'] - if boatclass.lower() in ['standard','olympic','normal']: + if boatclass.lower() in ['standard','olympic','normal','water']: boatclass = 'water' - elif boatclass.lower() in ['erg','c2','concept','static']: + elif boatclass.lower() in ['erg','c2','concept','static','rower']: boatclass = 'rower' elif boatclass.lower() in ['dynamic']: boatclass = 'dynamic' @@ -115,23 +135,43 @@ def save_scoring(name,user,filename,id=0,notes=""): except KeyError: skillclass = 'Open' - # some testing - standard = CourseStandard( - name=name, - coursedistance=coursedistance, - referencespeed=referencespeed, - coursetime=coursetime, - agemin=agemin, - agemax=agemax, - boatclass=boatclass, - boattype=boattype, - sex=sex, - weightclass=weightclass, - adaptiveclass=adaptiveclass, - skillclass=skillclass, - standardcollection = collection, - ) + # finding existing standard + existingstandards = CourseStandard.objects.filter(name=name,standardcollection=collection) + #print(existingstandards,collection) + if existingstandards: + existingstandards.update( + name=name, + coursedistance=coursedistance, + referencespeed=referencespeed, + coursetime=coursetime, + agemin=agemin, + agemax=agemax, + boatclass=boatclass, + boattype=boattype, + sex=sex, + weightclass=weightclass, + adaptiveclass=adaptiveclass, + skillclass=skillclass, + standardcollection = collection, + ) + else: + #print('not') + standard = CourseStandard( + name=name, + coursedistance=coursedistance, + referencespeed=referencespeed, + coursetime=coursetime, + agemin=agemin, + agemax=agemax, + boatclass=boatclass, + boattype=boattype, + sex=sex, + weightclass=weightclass, + adaptiveclass=adaptiveclass, + skillclass=skillclass, + standardcollection = collection, + ) - standard.save() + standard.save() return collection.id diff --git a/rowers/templates/standard_form.html b/rowers/templates/standard_form.html index 2e8c2314..282ba443 100644 --- a/rowers/templates/standard_form.html +++ b/rowers/templates/standard_form.html @@ -21,7 +21,18 @@
  • -

    Drag and drop files here

    +

    Drag and drop files here. +

    +

    + If you're updating an existing set of standard times, + existing groups with challenge entries will be updated. New + groups will be created. All groups with challenge entries will + remain, even if you delete them from the CSV file. So, it + is not possible to remove groups if there have been starts in this group.

    +

    + If you want to still remove those groups, it is better to set the + existing set of standard times to inactive and upload a new one. +

    diff --git a/rowers/templates/standard_view.html b/rowers/templates/standard_view.html index c76f0f49..8a92f859 100644 --- a/rowers/templates/standard_view.html +++ b/rowers/templates/standard_view.html @@ -33,7 +33,11 @@
  • -

    Update these Standard Times + {% if request.user == collection.manager %} +

    Update these Standard Times

    +

    Deactivate this standard

    + {% endif %} +

    Download as CSV file

  • Standard Times

    diff --git a/rowers/urls.py b/rowers/urls.py index 4f387b5f..3549c4a5 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -756,6 +756,10 @@ urlpatterns = [ name='course_replace_view'), re_path(r'^courses/(?P\d+)/$',views.course_view,name='course_view'), re_path(r'^standards/(?P\d+)/$',views.standard_view,name='standard_view'), + re_path(r'^standards/(?P\d+)/download/$',views.standards_download_view, + name='standards_download_view'), + re_path(r'^standards/(?P\d+)/deactivate/$',views.standard_deactivate_view, + name='standard_decativate_view'), re_path(r'^courses/(?P\d+)/map/$',views.course_map_view,name='course_map_view'), # URLS to be created re_path(r'^help/$',TemplateView.as_view(template_name='help.html'), name='help'), diff --git a/rowers/views/racesviews.py b/rowers/views/racesviews.py index 9bd0693a..2c0ac70c 100644 --- a/rowers/views/racesviews.py +++ b/rowers/views/racesviews.py @@ -40,7 +40,7 @@ def courses_view(request): def standards_view(request): r = getrower(request.user) - standards = StandardCollection.objects.all().order_by("name") + standards = StandardCollection.objects.filter(active=True).order_by("name") # add search processing query = request.GET.get('q') @@ -521,11 +521,57 @@ def course_upload_view(request): else: return {'result':0} +# Standards deactivate +@login_required() +def standard_deactivate_view(request,id=0): + is_ajax = False + if request.is_ajax(): + is_ajax = True + + r = getrower(request.user) + + try: + collection = StandardCollection.objects.get(id=id) + except StandardCollection.DoesNotExist: + raise Http404("Does not exist") + + if request.user != collection.manager: + raise PermissionDenied("You cannot change this set of time standards") + + collection.active = False + collection.save() + + url = reverse(standards_view) + + return HttpResponseRedirect(url) + +def standards_download_view(request,id=0): + try: + collection = StandardCollection.objects.get(id=id) + except StandardCollection.DoesNotExist: + raise Http404("Does not exist") + + filename = 'Standard Times {name} {id} {date}.csv'.format( + id=id, + name=collection.name, + date=timezone.now().strftime("%Y-%m-%d %H:%M:%S %Z") + ) + + standards = CourseStandard.objects.filter(standardcollection=collection) + df = pd.DataFrame.from_records(standards.values()) + + response = HttpResponse(df.to_csv()) + + response['Content-Disposition'] = 'attachment; filename="%s"' % filename + response['Content-Type'] = 'application/octet-stream' + + return response + + # Standards upload @login_required() def standards_upload_view(request,id=0): is_ajax = False - print(id,'aap') if request.is_ajax(): is_ajax = True r = getrower(request.user)