diff --git a/rowers/forms.py b/rowers/forms.py index 0ce79b0c..f5716641 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -37,6 +37,19 @@ formaxlabels = axlabels.copy() formaxlabels.pop('None') parchoices = list(sorted(formaxlabels.items(), key=lambda x: x[1])) +class DeepWaterLoginForm(forms.Form): + username = forms.CharField( + max_length=150, label='Username', + widget=forms.TextInput(attrs={'placeholder': 'Username'})) + password = forms.CharField( + max_length=128, label='Password', + widget=forms.PasswordInput(attrs={'placeholder': 'Password'})) + + def clean(self): + cleaned_data = super(DeepWaterLoginForm, self).clean() + if not cleaned_data.get('username') or not cleaned_data.get('password'): + raise forms.ValidationError("Please enter both username and password.") + return cleaned_data class SurveyForm(forms.Form): surveydone = forms.ChoiceField( diff --git a/rowers/management/commands/loadnextweeksessions.py b/rowers/management/commands/loadnextweeksessions.py new file mode 100644 index 00000000..09440387 --- /dev/null +++ b/rowers/management/commands/loadnextweeksessions.py @@ -0,0 +1,44 @@ +#!/srv/venv/bin/python + +import sys +import os + +from django.core.management.base import BaseCommand +from rowers.models import Rower +from rowers.tasks import handle_loadnextweek +from rowers.utils import myqueue, dologging + +import django_rq + +PY3K = sys.version_info >= (3, 0) + +queue = django_rq.get_queue('default') +queuelow = django_rq.get_queue('low') +queuehigh = django_rq.get_queue('low') + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument( + '--testing', + action='store_true', + dest='testing', + default=False, + help="Run in testing mode, don't send emails", ) + + def handle(self, *args, **options): + if 'testing' in options: + testing = options['testing'] + else: + testing = False + + rowers = Rower.objects.filter(training_plan_code__isnull=False).exclude(training_plan_code__exact='') + rowers = rowers.filter(training_plan_secret__isnull=False).exclude(training_plan_secret__exact='') + + for rower in rowers: + _ = myqueue(queue, handle_loadnextweek, + rower) + + self.stdout.write(self.style.SUCCESS( + 'Successfully loaded next week plans' + )) diff --git a/rowers/tasks.py b/rowers/tasks.py index 7c222634..325d7210 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -18,6 +18,7 @@ from rowers.models import ( GraphImage, Team, PlannedSession ) from rowers.session_utils import is_session_complete + import math from rowers.courseutils import ( coursetime_paths, coursetime_first, time_in_path, @@ -333,6 +334,106 @@ def summaryfromsplitdata(splitdata, data, filename, sep='|', workouttype='rower' return sums, sa, results +from rowers.utils import intensitymap + +def strcapitalize(s): + if s is None: + return None + if isinstance(s, str): + return s[0].upper() + s[1:] + + return s + +def correct_intensity(workout): + # reads the steps and if the intensity is an integer, converts it to a string + steps = workout['steps'] + for step in steps: + if 'intensity' in step: + if isinstance(step['intensity'], int): + step['intensity'] = intensitymap[step['intensity']] + step['durationType'] = strcapitalize(step['durationType']) + step['targetType'] = strcapitalize(step['targetType']) + step['intensity'] = strcapitalize(step['intensity']) + + return workout + + +@app.task +def handle_loadnextweek(rower, debug=False, **kwargs): + + plan = rower.training_plan_code + secret = rower.training_plan_secret + post_data = { + 'fitness': rower.actualfit, + 'fatigue': rower.actualfatigue, + 'plan': plan, + 'secret': secret, + } + + url = "http://localhost:8898/next-week-plan/" + response = requests.post(url, data=post_data) + + if response.status_code in [200, 201]: + data = response.json() + + today = timezone.now() + startdate = today - timedelta(days=today.weekday())+timezone.timedelta(days=7) + enddate = startdate + timedelta(days=6) + + sps = PlannedSession.objects.filter( + rower__in=[rower], + startdate__gte=startdate, + enddate__lte=enddate, + is_template=False, + ) + + for ps in sps: + ps.delete() + + trainingdays = data['cycles'] + # start date is the first day of the following week + + ndays = 0 + for day in trainingdays: + try: + workouts = day[0][1:] + except IndexError: + workouts =[] + for workout in workouts: + sessionsport = 'water' + try: + sessionsport = mytypes.fitmappinginv[workout['sport'].lower()] + except KeyError: + pass + + preferreddate = startdate+timedelta(days=ndays) + sessionmode = 'time' + + ps = PlannedSession( + startdate=preferreddate - timedelta(days=preferreddate.weekday()), + enddate=preferreddate + timedelta(days=-preferreddate.weekday()-1, weeks=1), + preferreddate=preferreddate, + sessionsport=sessionsport, # change this + name=workout['workoutName'], + steps=correct_intensity(workout), + manager=rower.user, + sessionmode=sessionmode, + comment=workout['description'], + from_plan=None, + ) + ps.save() + ps.rower.add(rower) + ps.save() + if ps.fitfile: + ps.steps = {} + ps.save() + ndays += 1 + + + return 1 + + return 0 + @app.task def handle_assignworkouts(workouts, rowers, remove_workout, debug=False, **kwargs): for workout in workouts: diff --git a/rowers/templates/deepwaterlogin.html b/rowers/templates/deepwaterlogin.html new file mode 100644 index 00000000..5372e753 --- /dev/null +++ b/rowers/templates/deepwaterlogin.html @@ -0,0 +1,32 @@ +{% extends "newbase.html" %} +{% load static %} +{% load rowerfilters %} + +{% block title %}Login to Deep Water{% endblock %} + +{% block main %} + +