From 844b984fb17412085c306506eb977f45884a2b0f Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 27 Jan 2021 13:30:51 +0100 Subject: [PATCH] manual import rp3 working --- rowers/dataprep.py | 34 +++++++++--- rowers/rp3stuff.py | 5 ++ rowers/tasks.py | 78 +++++++++++++++++++++++++++ rowers/templates/menu_workout.html | 15 ++++++ rowers/templates/rp3_list_import.html | 2 +- rowers/uploads.py | 7 +++ rowers/urls.py | 2 +- rowers/views/importviews.py | 25 +++++++-- rowers/views/statements.py | 1 + rowers/views/workoutviews.py | 6 +++ 10 files changed, 161 insertions(+), 14 deletions(-) diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 6e3b0802..5aa8720d 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -1571,11 +1571,11 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', oarlength=2.89, inboard=0.88, forceunit='lbs', consistencychecks=False, + startdatetime='', impeller=False): message = None - powerperc = 100 * np.array([r.pw_ut2, r.pw_ut1, r.pw_at, @@ -1587,6 +1587,9 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', hrtr=r.tr, hran=r.an, ftp=r.ftp, powerperc=powerperc, powerzones=r.powerzones) row = rdata(f2, rower=rr) + if startdatetime != '': + row.rowdatetime = arrow.get(startdatetime).datetime + if title is None or title == '': title = 'Workout' @@ -1613,7 +1616,7 @@ 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) + workoutsource=workoutsource,startdatetime=startdatetime) try: checks = row.check_consistency() allchecks = 1 @@ -1700,12 +1703,20 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', summary = row.allstats() + if startdatetime != '': + workoutstartdatetime = arrow.get(startdatetime).datetime + else: + workoutstartdatetime = row.rowdatetime + timezone_str = 'UTC' try: - workoutstartdatetime = timezone.make_aware(row.rowdatetime) + workoutstartdatetime = timezone.make_aware(workoutstartdatetime) except ValueError: - workoutstartdatetime = row.rowdatetime + pass + + + try: latavg = row.df[' latitude'].mean() @@ -1840,9 +1851,11 @@ parsers = { 'eth': ETHParser, } -def parsenonpainsled(fileformat,f2,summary): +def parsenonpainsled(fileformat,f2,summary,startdatetime=''): try: row = parsers[fileformat](f2) + if startdatetime != '': + row.rowdatetime = arrow.get(startdatetime).datetime hasrecognized = True except (KeyError,IndexError,ValueError): hasrecognized = False @@ -1874,13 +1887,13 @@ def parsenonpainsled(fileformat,f2,summary): return row,hasrecognized,summary,fileformat -def handle_nonpainsled(f2, fileformat, summary=''): +def handle_nonpainsled(f2, fileformat, summary='',startdatetime=''): oarlength = 2.89 inboard = 0.88 hasrecognized = False impeller = False - row,hasrecognized,summary,fileformat = parsenonpainsled(fileformat,f2,summary) + row,hasrecognized,summary,fileformat = parsenonpainsled(fileformat,f2,summary,startdatetime=startdatetime) # Handle c2log if (fileformat == 'c2log' or fileformat == 'rowprolog'): @@ -1973,6 +1986,7 @@ def new_workout_from_file(r, f2, boattype='1x', rpe=-1, makeprivate=False, + startdatetime='', notes='', uploadoptions={'boattype':'1x','workouttype':'rower'}): message = "" @@ -2078,6 +2092,7 @@ def new_workout_from_file(r, f2, f2, summary, oarlength, inboard, fileformat, impeller = handle_nonpainsled( f2, fileformat, + startdatetime=startdatetime, summary=summary ) if not f2: @@ -2106,6 +2121,7 @@ def new_workout_from_file(r, f2, dosummary=dosummary, workoutsource=workoutsource, summary=summary, + startdatetime=startdatetime, rpe=rpe, inboard=inboard, oarlength=oarlength, title=title, @@ -2222,6 +2238,7 @@ def new_workout_from_df(r, df, boattype='1x', workouttype='rower', parent=None, + startdatetime='', setprivate=False, forceunit='lbs', dt=datetime.timedelta()): @@ -2250,7 +2267,8 @@ def new_workout_from_df(r, df, notes = '' summary = '' makeprivate = False - startdatetime = timezone.now() + if startdatetime == '': + startdatetime = timezone.now() if setprivate: makeprivate = True diff --git a/rowers/rp3stuff.py b/rowers/rp3stuff.py index 2c846ae0..3b733b88 100644 --- a/rowers/rp3stuff.py +++ b/rowers/rp3stuff.py @@ -178,6 +178,10 @@ def get_rp3_workout(user,workout_id,startdatetime=None): r = Rower.objects.get(user=user) auth_token = rp3_open(user) + if not startdatetime: + startdatetime = str(timezone.now()) + + status_code = download_rp3_file(url, auth_token, filename) if status_code != 200: @@ -192,6 +196,7 @@ def get_rp3_workout(user,workout_id,startdatetime=None): 'workouttype':'dynamic', 'boattype':'1x', 'rp3id':workout_id, + 'startdatetime':startdatetime, } session = requests.session() diff --git a/rowers/tasks.py b/rowers/tasks.py index c1ae1086..09ccae77 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -2712,6 +2712,84 @@ def handle_sendemail_invite_accept(email, name, teamname, managername, def add2(x, y,debug=False,**kwargs): return x + y +graphql_url = "https://rp3rowing-app.com/graphql" + +@app.task +def handle_rp3_async_workout(userid,rp3token,rp3id,startdatetime,debug=False,**kwargs): + headers = {'Authorization': 'Bearer ' + rp3token } + + get_download_link = """{ + download(workout_id: """ + str(rp3id) + """, type:csv){ + id + status + link + } +}""" + + have_link = False + download_url = '' + counter = 0 + max_attempts = 20 + waittime = 3 + while not have_link: + response = requests.post( + url=graphql_url, + headers=headers, + json={'query': get_download_link} + ) + + if response.status_code != 200: + have_link = True + + workout_download_details = pd.json_normalize(response.json()['data']['download']) + + if workout_download_details.iat[0,1] == 'ready': + download_url = workout_download_details.iat[0,2] + have_link = True + + counter += 1 + + if counter>max_attempts: + have_link = True + + time.sleep(waittime) + + filename = 'media/RP3Import_'+str(rp3id)+'.csv' + res = requests.get(download_url,headers=headers) + + if not startdatetime: + startdatetime = str(timezone.now()) + + if res.status_code != 200: + return 0 + + + with open(filename,'wb') as f: + f.write(res.content) + + uploadoptions = { + 'secret': UPLOAD_SERVICE_SECRET, + 'user': userid, + 'file': filename, + 'workouttype':'dynamic', + 'boattype':'1x', + 'rp3id':rp3id, + 'startdatetime':startdatetime, + } + + 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 + + workoutid = response.json()['id'] + + return workoutid + @app.task def handle_c2_async_workout(alldata,userid,c2token,c2id,debug=False,**kwargs): data = alldata[c2id] diff --git a/rowers/templates/menu_workout.html b/rowers/templates/menu_workout.html index 28f1292c..8c0d8385 100644 --- a/rowers/templates/menu_workout.html +++ b/rowers/templates/menu_workout.html @@ -241,6 +241,21 @@ {% endif %} +
  • + {% if workout.uploadedtorp3 %} + + RP3 + + {% elif user.rower.rp3token == None or user.rower.rp3token == '' %} + + Connect to RP3 + + {% else %} + + RP3 + + {% endif %} +
  • CSV diff --git a/rowers/templates/rp3_list_import.html b/rowers/templates/rp3_list_import.html index b0500f69..919e2242 100644 --- a/rowers/templates/rp3_list_import.html +++ b/rowers/templates/rp3_list_import.html @@ -21,7 +21,7 @@ {% for workout in workouts %} - Import + Import {{ workout|lookup:'starttime' }} {{ workout|lookup:'new' }} diff --git a/rowers/uploads.py b/rowers/uploads.py index 849efcd0..33edb2e9 100644 --- a/rowers/uploads.py +++ b/rowers/uploads.py @@ -560,6 +560,13 @@ def do_sync(w,options, quick=False): except KeyError: pass + try: + if options['rp3id'] != 0 and options['rp3id'] != '': + w.uploadedtorp3 = options['rp3id'] + w.save() + except KeyError: + pass + if w.duplicate: return 0 diff --git a/rowers/urls.py b/rowers/urls.py index 33253b88..b6c189e3 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -543,7 +543,7 @@ urlpatterns = [ re_path(r'^workout/stravaimport/user/(?P\d+)/$',views.workout_stravaimport_view,name='workout_stravaimport_view'), re_path(r'^workout/c2import/all/$',views.workout_getc2workout_all,name='workout_getc2workout_all'), re_path(r'^workout/c2import/all/(?P\d+)/$',views.workout_getc2workout_all,name='workout_getc2workout_all'), - re_path(r'^workout/rp3import/(?P\d+)/(?P\w+)/$',views.workout_getrp3importview, + re_path(r'^workout/rp3import/(?P\d+)/$',views.workout_getrp3importview, name='workout_getrp3importview'), re_path(r'^workout/(?P\w+.*)import/(?P\d+)/$',views.workout_getimportview,name='workout_getimportview'), re_path(r'^workout/stravaimport/all/$',views.workout_getstravaworkout_all,name='workout_getstravaworkout_all'), diff --git a/rowers/views/importviews.py b/rowers/views/importviews.py index 465ab218..4d098659 100644 --- a/rowers/views/importviews.py +++ b/rowers/views/importviews.py @@ -1023,8 +1023,8 @@ def workout_rp3import_view(request,userid=0): 'name':'Workouts' }, { - 'url':reverse('workout_stravaimport_view'), - 'name':'Strava' + 'url':reverse('workout_rp3import_view'), + 'name':'RP3' }, ] @@ -1776,8 +1776,25 @@ importsources = { } @login_required() -def workout_getrp3importview(request,externalid,startdatetime): - return 1 +def workout_getrp3importview(request,externalid): + r = getrequestrower(request) + token = rp3stuff.rp3_open(r.user) + startdatetime = request.GET.get('startdatetime') + + job = myqueue(queuehigh, + handle_rp3_async_workout, + r.user.id, + token, + externalid, + startdatetime, + ) + + #id = rp3stuff.get_rp3_workout(r.user,externalid,startdatetime=startdatetime) + + messages.info(request,'The workout will be imported in the background') + + url = reverse('workout_rp3import_view') + return HttpResponseRedirect(url) @login_required() def workout_getimportview(request,externalid,source = 'c2'): diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 342fd459..4570f56f 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -203,6 +203,7 @@ from rowers.tasks import handle_makeplot,handle_otwsetpower,handle_sendemailtcx, from rowers.tasks import ( handle_sendemail_unrecognized,handle_sendemailnewcomment, handle_sendemailsummary, + handle_rp3_async_workout, handle_send_template_email, handle_send_disqualification_email, handle_send_withdraw_email, diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index 569d4b33..867c5a20 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -4786,6 +4786,11 @@ def workout_upload_api(request): except KeyError: garminid = 0 + try: + startdatetime = post_data['startdatetime'] + except KeyError: + startdatetime = '' + r = None if form.is_valid(): t = form.cleaned_data['title'] @@ -4857,6 +4862,7 @@ def workout_upload_api(request): rpe=rpe, notes=notes, uploadoptions=post_data, + startdatetime=startdatetime, ) if id == 0: