From 718453de9622a0dea433f3d3c2ee097e2e9cf4c4 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 10 Mar 2020 15:53:18 +0100 Subject: [PATCH] async strava sync --- rowers/stravastuff.py | 88 +++++++++++++++++++++--------------- rowers/tasks.py | 22 +++++++++ rowers/uploads.py | 2 +- rowers/utils.py | 1 - rowers/views/workoutviews.py | 4 +- 5 files changed, 76 insertions(+), 41 deletions(-) diff --git a/rowers/stravastuff.py b/rowers/stravastuff.py index 228281db..d10baf85 100644 --- a/rowers/stravastuff.py +++ b/rowers/stravastuff.py @@ -29,6 +29,8 @@ from rowers.utils import myqueue import rowers.mytypes as mytypes import gzip +from rowers.tasks import handle_strava_sync + from rowsandall_app.settings import ( C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET @@ -442,7 +444,7 @@ def createstravaworkoutdata(w,dozip=True): # Upload the TCX file to Strava and set the workout activity type # to rowing on Strava def handle_stravaexport(f2,workoutname,stravatoken,description='', - activity_type='Rowing',quick=False): + activity_type='Rowing',quick=False,asynchron=False): # w = Workout.objects.get(id=workoutid) client = stravalib.Client(access_token=stravatoken) @@ -628,7 +630,7 @@ def add_workout_from_data(user,importid,data,strokedata, return id,message -def workout_strava_upload(user,w, quick=False): +def workout_strava_upload(user,w, quick=False,asynchron=True): try: thetoken = strava_open(user) except NoTokenError: @@ -641,55 +643,67 @@ def workout_strava_upload(user,w, quick=False): if (r.stravatoken == '') or (r.stravatoken is None): s = "Token doesn't exist. Need to authorize" raise NoTokenError("Your hovercraft is full of eels") - else: - if (is_workout_user(user,w)): - try: - tcxfile,tcxmesg = createstravaworkoutdata(w) - if tcxfile: - with open(tcxfile,'rb') as f: - res,mes = handle_stravaexport( - f,w.name, - r.stravatoken, - description=w.notes+'\n from '+w.workoutsource+' via rowsandall.com', - activity_type=r.stravaexportas,quick=quick) - if res==0: - message = mes - w.uploadedtostrava = -1 - stravaid = -1 - w.save() - try: - os.remove(tcxfile) - except WindowsError: - pass - return message,stravaid - w.uploadedtostrava = res + if (is_workout_user(user,w)): + if asynchron: + tcxfile, tcxmesg = createstravaworkoutdata(w) + if not tcxfile: + return "Failed to create workout data",0 + job = myqueue(queue, + handle_strava_sync, + r.stravatoken, + w.id, + tcxfile,w.name,r.stravaexportas, + w.notes + ) + return "Asynchronous sync",-1 + try: + tcxfile,tcxmesg = createstravaworkoutdata(w) + if tcxfile: + with open(tcxfile,'rb') as f: + res,mes = handle_stravaexport( + f,w.name, + r.stravatoken, + description=w.notes+'\n from '+w.workoutsource+' via rowsandall.com', + activity_type=r.stravaexportas,quick=quick,asynchron=asynchron) + if res==0: + message = mes + w.uploadedtostrava = -1 + stravaid = -1 w.save() try: os.remove(tcxfile) except WindowsError: pass - message = mes - stravaid = res return message,stravaid - else: - message = "Strava TCX data error "+tcxmesg - w.uploadedtostrava = -1 - stravaid = -1 - w.save() - return message, stravaid - except ActivityUploadFailed as e: - message = "Strava Upload error: %s" % e + w.uploadedtostrava = res + w.save() + try: + os.remove(tcxfile) + except WindowsError: + pass + message = mes + stravaid = res + return message,stravaid + else: + message = "Strava TCX data error "+tcxmesg w.uploadedtostrava = -1 stravaid = -1 w.save() - os.remove(tcxfile) - return message,stravaid - return message,stravaid + return message, stravaid + + except ActivityUploadFailed as e: + message = "Strava Upload error: %s" % e + w.uploadedtostrava = -1 + stravaid = -1 + w.save() + os.remove(tcxfile) + return message,stravaid return message,stravaid + def handle_strava_import_stroke_data(title, useremail, stravatoken, diff --git a/rowers/tasks.py b/rowers/tasks.py index a9348b65..4eac9536 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -101,6 +101,7 @@ import rowers.utils as utils import requests import rowers.longtask as longtask import arrow +import stravalib from rowers.utils import get_strava_stream @@ -135,6 +136,27 @@ def handle_c2_sync(workoutid,url,headers,data,debug=False,**kwargs): return res +@app.task +def handle_strava_sync(stravatoken,workoutid,filename,name,activity_type,description,debug=False,**kwargs): + client = stravalib.Client(access_token=stravatoken) + with open(filename,'rb') as f: + act = client.upload_activity(f,'tcx.gz',name=name) + res = act.wait(poll_interval=5.0, timeout=60) + try: + act = client.update_activity(res.id,activity_type=activity_type, + description=description,device_name='Rowsandall.com') + except TypeError: + act = client.update_activity(res.id,activity_type=activity_type, + description=description) + + result = update_workout_field_sql(workoutid,'uploadedtostrava',res.id,debug=debug) + try: + os.remove(filename) + except WindowsError: + pass + + return 1 + @app.task def handle_c2_import_stroke_data(c2token, c2id,workoutid, diff --git a/rowers/uploads.py b/rowers/uploads.py index ef2f5a4e..4d435e6a 100644 --- a/rowers/uploads.py +++ b/rowers/uploads.py @@ -535,7 +535,7 @@ def do_sync(w,options, quick=False): if ('upload_to_Strava' in options and upload_to_strava) or (w.user.strava_auto_export and ispromember(w.user.user)): try: message,id = stravastuff.workout_strava_upload( - w.user.user,w,quick=quick + w.user.user,w,quick=quick,asynchron=True, ) except NoTokenError: id = 0 diff --git a/rowers/utils.py b/rowers/utils.py index a1258b1c..5d34a9a0 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -305,7 +305,6 @@ def myqueue(queue,function,*args,**kwargs): return MockJob() elif settings.CELERY: kwargs['debug'] = True - job = function.delay(*args,**kwargs) else: if settings.DEBUG: diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index d08c8a89..7da74585 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -4810,7 +4810,7 @@ def workout_upload_view(request, # upload to C2 if (upload_to_c2): try: - message,id = c2stuff.workout_c2_upload(request.user,w,asynchron=True) + message,id = c2stuff.workout_c2_upload(request.user,w) except NoTokenError: id = 0 message = "Something went wrong with the Concept2 sync" @@ -4822,7 +4822,7 @@ def workout_upload_view(request, if (upload_to_strava): try: message,id = stravastuff.workout_strava_upload( - request.user,w + request.user,w,asynchron=True, ) except NoTokenError: id = 0