diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 721a4aa9..0652c159 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -1047,6 +1047,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', forceunit='lbs', consistencychecks=False, startdatetime='', + workoutid='', impeller=False): message = None @@ -1089,7 +1090,8 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', return new_workout_from_df(r, newdf, title=title, boattype=boattype, workouttype=workouttype, - workoutsource=workoutsource, startdatetime=startdatetime) + workoutsource=workoutsource, startdatetime=startdatetime, + workoutid=workoutid) try: checks = row.check_consistency() allchecks = 1 @@ -1233,26 +1235,59 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', timezone_str = str(workoutstartdatetime.tzinfo) - w = Workout(user=r, name=title, date=workoutdate, - workouttype=workouttype, - boattype=boattype, - dragfactor=dragfactor, - duration=duration, distance=totaldist, - weightcategory=weightcategory, - adaptiveclass=adaptiveclass, - starttime=workoutstarttime, - duplicate=duplicate, - workoutsource=workoutsource, - rankingpiece=rankingpiece, - forceunit=forceunit, - rpe=rpe, - csvfilename=f2, notes=notes, summary=summary, - maxhr=maxhr, averagehr=averagehr, - startdatetime=workoutstartdatetime, - inboard=inboard, oarlength=oarlength, - timezone=timezone_str, - privacy=privacy, - impeller=impeller) + if workoutid: + try: + w = Workout.objects.get(id=workoutid) + w.name = title + w.date = workoutdate + w.workouttype = workouttype + w.boattype = boattype + w.dragfactor = dragfactor + w.duration = duration + w.distance = totaldist + w.weightcategory = weightcategory + w.adaptiveclass = adaptiveclass + w.starttime = workoutstarttime + w.duplicate = duplicate + w.workoutsource = workoutsource + w.rankingpiece = rankingpiece + w.forceunit = forceunit + w.rpe = rpe + w.csvfilename = f2 + w.notes = notes + w.summary = summary + w.maxhr = maxhr + w.averagehr = averagehr + w.startdatetime = workoutstartdatetime + w.inboard = inboard + w.oarlength = oarlength + w.timezone = timezone_str + w.privacy = privacy + w.impeller = impeller + except Workout.DoesNotExist: + workoutid = '' + + if not workoutid: + w = Workout(user=r, name=title, date=workoutdate, + workouttype=workouttype, + boattype=boattype, + dragfactor=dragfactor, + duration=duration, distance=totaldist, + weightcategory=weightcategory, + adaptiveclass=adaptiveclass, + starttime=workoutstarttime, + duplicate=duplicate, + workoutsource=workoutsource, + rankingpiece=rankingpiece, + forceunit=forceunit, + rpe=rpe, + csvfilename=f2, notes=notes, summary=summary, + maxhr=maxhr, averagehr=averagehr, + startdatetime=workoutstartdatetime, + inboard=inboard, oarlength=oarlength, + timezone=timezone_str, + privacy=privacy, + impeller=impeller) try: w.save() except ValidationError: # pragma: no cover @@ -1292,6 +1327,7 @@ def new_workout_from_file(r, f2, makeprivate=False, startdatetime='', notes='', + workoutid='', oarlockfirmware='', inboard=None, oarlength=None, @@ -1463,6 +1499,7 @@ def new_workout_from_file(r, f2, title=title, forceunit='N', impeller=impeller, + workoutid=workoutid, ) return (id, message, f2) @@ -1474,6 +1511,7 @@ def new_workout_from_df(r, df, boattype='1x', workouttype='rower', parent=None, + workoutid='', startdatetime='', setprivate=False, forceunit='lbs', @@ -1541,6 +1579,7 @@ def new_workout_from_df(r, df, inboard=inboard, makeprivate=makeprivate, dosmooth=False, + workoutid=workoutid, rpe=rpe, consistencychecks=False) diff --git a/rowers/models.py b/rowers/models.py index c70e9c66..c0542bf4 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -4193,6 +4193,13 @@ class WorkoutForm(ModelForm): else: del self.fields['plannedsession'] + def clean(self): + if any(self.errors): + return + cd = self.cleaned_data + if cd['duration'] is None or cd['duration'] == '': + raise forms.ValidationError('Duration cannot be empty') + # Used for the rowing physics calculations diff --git a/rowers/rp3stuff.py b/rowers/rp3stuff.py index d3e5aea2..147d851a 100644 --- a/rowers/rp3stuff.py +++ b/rowers/rp3stuff.py @@ -51,7 +51,9 @@ graphql_url = "https://rp3rowing-app.com/graphql" # Checks if user has UnderArmour token, renews them if they are expired def rp3_open(user): tokenexpirydate = user.rower.rp3tokenexpirydate - if timezone.now()-timedelta(days=120)>tokenexpirydate: + if tokenexpirydate is None: + raise NoTokenError + if tokenexpirydate is not None and timezone.now()-timedelta(days=120)>tokenexpirydate: user.rower.rp3tokenexpirydate = timezone.now()-timedelta(days=1) user.rower.save() raise NoTokenError diff --git a/rowers/tasks.py b/rowers/tasks.py index 1e4f8a0d..eaa494f0 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -315,6 +315,20 @@ def summaryfromsplitdata(splitdata, data, filename, sep='|', workouttype='rower' return sums, sa, results +@app.task +def handle_post_workout_api(uploadoptions, debug=False, **kwargs): + session = requests.session() + newHeaders = {'Content-type': 'application/json', 'Accept': 'text/plain'} + session.headers.update(newHeaders) + + response = session.post(UPLOAD_SERVICE_URL, json=uploadoptions) + + if response.status_code != 200: + return 0 + + return 1 + + @app.task def handle_remove_workouts_team(ws, t, debug=False, **kwargs): for w in ws: diff --git a/rowers/views/apiviews.py b/rowers/views/apiviews.py index 354b79d1..ebf51345 100644 --- a/rowers/views/apiviews.py +++ b/rowers/views/apiviews.py @@ -296,6 +296,10 @@ def strokedatajson_v3(request): csvfilename = 'media/{code}.csv.gz'.format(code=uuid4().hex[:16]) _ = data.to_csv(csvfilename, index_label='index', compression='gzip') + + duration = datetime.time(0,0,1) + w = Workout(user=request.user.rower,date=timezone.now().date(),duration=duration) + w.save() uploadoptions = { 'secret': UPLOAD_SERVICE_SECRET, @@ -309,20 +313,15 @@ def strokedatajson_v3(request): 'rpe': rpe, 'notes': notes, 'timezone': timeZone, + 'id': w.id, } - session = requests.session() - newHeaders = {'Content-type': 'application/json', 'Accept': 'text/plain'} - session.headers.update(newHeaders) - response = session.post(UPLOAD_SERVICE_URL, json=uploadoptions) + + _ = myqueue(queuehigh, + handle_post_workout_api, + uploadoptions) - if response.status_code != 200: - return HttpResponse(response.text, response.status_code) - - try: - workoutid = response.json()['id'] - except KeyError: - workoutid = 1 + workoutid = w.id return JsonResponse( {"workout public id": encoder.encode_hex(workoutid), diff --git a/rowers/views/statements.py b/rowers/views/statements.py index e0fdc6f1..8770ed20 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -242,6 +242,7 @@ from rowers.rows import handle_uploaded_file, handle_uploaded_image from rowers.plannedsessions import * from rowers.tasks import handle_makeplot, handle_otwsetpower, handle_sendemailtcx, handle_sendemailcsv from rowers.tasks import ( + handle_post_workout_api, handle_sendemail_newftp, instroke_static, fetch_rojabo_session, diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index 03802078..fa11f4cd 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -5210,6 +5210,7 @@ def workout_upload_api(request): # sync related IDs c2id = post_data.get('c2id', '') + workoutid = post_data.get('id','') startdatetime = post_data.get('startdatetime', '') oarlockfirmware = post_data.get('oarlockfirmware', None) @@ -5300,6 +5301,7 @@ def workout_upload_api(request): inboard=inboard, oarlength=oarlength, impeller=useImpeller, + workoutid=workoutid, ) if id == 0: # pragma: no cover