diff --git a/rowers/dataprep.py b/rowers/dataprep.py
index 55da70ec..c91ea326 100644
--- a/rowers/dataprep.py
+++ b/rowers/dataprep.py
@@ -1853,9 +1853,16 @@ parsers = {
'nklinklogbook': NKLiNKLogbookParser,
}
-def parsenonpainsled(fileformat,f2,summary,startdatetime=''):
+def parsenonpainsled(fileformat,f2,summary,startdatetime='',empowerfirmware=None,inboard=None,oarlength=None):
try:
- row = parsers[fileformat](f2)
+ if fileformat == 'nklinklogbook' and empowerfirmware is not None:
+ if inboard is not None and oarlength is not None:
+ row = NKLiNKLogbookParser(f2,firmware=empowerfirmware,inboard=inboard,oarlength=oarlength)
+ print(row,'aap')
+ else:
+ row = NKLiNKLogbookParser(f2)
+ else:
+ row = parsers[fileformat](f2)
if startdatetime != '':
row.rowdatetime = arrow.get(startdatetime).datetime
hasrecognized = True
@@ -1875,6 +1882,8 @@ def parsenonpainsled(fileformat,f2,summary,startdatetime=''):
summary = row.allstats()
except ZeroDivisionError:
summary = ''
+ else:
+ fileformat = fileformat+'v'+str(empowerfirmware)
# handle FIT
if (fileformat == 'fit'):
@@ -1889,13 +1898,14 @@ def parsenonpainsled(fileformat,f2,summary,startdatetime=''):
return row,hasrecognized,summary,fileformat
-def handle_nonpainsled(f2, fileformat, summary='',startdatetime=''):
+def handle_nonpainsled(f2, fileformat, summary='',startdatetime='',empowerfirmware=None,impeller=False):
oarlength = 2.89
inboard = 0.88
hasrecognized = False
- impeller = False
- row,hasrecognized,summary,fileformat = parsenonpainsled(fileformat,f2,summary,startdatetime=startdatetime)
+
+ row,hasrecognized,summary,fileformat = parsenonpainsled(fileformat,f2,summary,startdatetime=startdatetime,
+ empowerfirmware=empowerfirmware)
# Handle c2log
if (fileformat == 'c2log' or fileformat == 'rowprolog'):
@@ -1909,13 +1919,15 @@ def handle_nonpainsled(f2, fileformat, summary='',startdatetime=''):
f2 = f2[:-4] + 'o.csv'
row2 = rrdata(df = row.df)
- if 'speedcoach2' in fileformat:
+ if 'speedcoach2' in fileformat or 'nklinklogbook' in fileformat:
# impeller consistency
impellerdata, consistent, ratio = row.impellerconsistent(threshold=0.3)
if impellerdata and consistent:
impeller = True
if impellerdata and not consistent:
row2.use_gpsdata()
+ if impeller:
+ row2.use_impellerdata()
row2.write_csv(f2, gzip=True)
@@ -1990,9 +2002,13 @@ def new_workout_from_file(r, f2,
makeprivate=False,
startdatetime='',
notes='',
+ oarlockfirmware='',
+ inboard=None,
+ oarlength=None,
+ impeller=False,
uploadoptions={'boattype':'1x','workouttype':'rower'}):
message = ""
- impeller = False
+
try:
fileformat = get_file_type(f2)
except (IOError,UnicodeDecodeError):
@@ -2009,7 +2025,7 @@ def new_workout_from_file(r, f2,
uploadoptions['fromuploadform'] = True
bodyyaml = yaml.safe_dump(uploadoptions,default_flow_style=False)
f_to_be_deleted = f2
- impeller = False
+
workoutsbox = Mailbox.objects.filter(name='workouts')[0]
msg = Message(mailbox=workoutsbox,
from_header=r.user.email,
@@ -2095,7 +2111,9 @@ def new_workout_from_file(r, f2,
f2,
fileformat,
startdatetime=startdatetime,
- summary=summary
+ summary=summary,
+ empowerfirmware=oarlockfirmware,
+ impeller=impeller,
)
if not f2:
message = 'Something went wrong'
diff --git a/rowers/management/commands/processemail.py b/rowers/management/commands/processemail.py
index d9ba789c..8a7d758d 100644
--- a/rowers/management/commands/processemail.py
+++ b/rowers/management/commands/processemail.py
@@ -33,6 +33,7 @@ import rowers.polarstuff as polarstuff
import rowers.c2stuff as c2stuff
import rowers.rp3stuff as rp3stuff
import rowers.stravastuff as stravastuff
+import rowers.nkstuff as nkstuff
from rowers.opaque import encoder
from rowers.models import User,VirtualRace,Workout
@@ -213,6 +214,11 @@ class Command(BaseCommand):
if user_is_not_basic(r.user):
res = rp3stuff.get_rp3_workouts(r)
+ rowers = Rower.objects.filter(nk_auto_import=True)
+ for r in rowers:
+ if user_is_not_basic(r.user):
+ res = nkstuff.get_nk_workouts(r)
+
messages = Message.objects.filter(mailbox_id = workoutmailbox.id)
message_ids = [m.id for m in messages]
attachments = MessageAttachment.objects.filter(
diff --git a/rowers/models.py b/rowers/models.py
index 9256b262..1ce31758 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -1002,7 +1002,7 @@ class Rower(models.Model):
nkrefreshtoken = models.TextField(default='',max_length=1000,
blank=True,null=True)
nk_owner_id = models.BigIntegerField(default=0)
- nk_auto_import = models.BooleanField(default=False)
+ nk_auto_import = models.BooleanField(default=False,verbose_name='NK LiNK auto import')
trainingpeaks_auto_export = models.BooleanField(default=False)
@@ -3852,6 +3852,7 @@ class RowerExportForm(ModelForm):
'polar_auto_import',
'c2_auto_export',
'c2_auto_import',
+ 'nk_auto_import',
'mapmyfitness_auto_export',
'runkeeper_auto_export',
'sporttracks_auto_export',
diff --git a/rowers/nkimportutils.py b/rowers/nkimportutils.py
new file mode 100644
index 00000000..581b9a4d
--- /dev/null
+++ b/rowers/nkimportutils.py
@@ -0,0 +1,264 @@
+import pandas as pd
+import datetime
+from datetime import timedelta
+from uuid import uuid4
+
+from rowsandall_app.settings import UPLOAD_SERVICE_SECRET, UPLOAD_SERVICE_URL
+from rowsandall_app.settings import NK_API_LOCATION
+
+import requests
+
+def strfdelta(tdelta):
+ try:
+ minutes, seconds = divmod(tdelta.seconds, 60)
+ tenths = int(tdelta.microseconds / 1e5)
+ except AttributeError:
+ minutes, seconds = divmod(tdelta.view(np.int64), 60e9)
+ seconds, rest = divmod(seconds, 1e9)
+ tenths = int(rest / 1e8)
+ res = "{minutes:0>2}:{seconds:0>2}.{tenths:0>1}".format(
+ minutes=minutes,
+ seconds=seconds,
+ tenths=tenths,
+ )
+
+ return res
+
+
+def add_workout_from_data(userid,nkid,data,strokedata,source='nk',splitdata=None,
+ workoutsource='nklinklogbook'):
+
+ csvfilename = 'media/{code}_{nkid}.csv.gz'.format(
+ nkid=nkid,
+ code = uuid4().hex[:16]
+ )
+
+ try:
+ userid=int(userid)
+ except TypeError:
+ userid = userid.id
+
+ strokedata.to_csv(csvfilename, index_label='index', compression='gzip')
+
+ title = data["name"]
+ speedInput = data["speedInput"]
+ elapsedTime = data["elapsedTime"]
+ totalDistanceGps = data["totalDistanceGps"]
+ totalDistanceImp = data["totalDistanceImp"]
+ intervals = data["intervals"] # add intervals
+ oarlockSessions = data["oarlockSessions"]
+ deviceId = data["deviceId"] # you could get the firmware version
+
+ totalDistance = totalDistanceGps
+ useImpeller = False
+ if speedInput:
+ totdalDistance = totalDistanceImp
+ useImpeller = True
+
+ summary = get_nk_allstats(data,strokedata)
+
+ speedInput = data['speedInput'] # 0 = GPS; 1 = Impeller
+
+ # oarlock inboard, length, boat name
+ if oarlockSessions:
+ oarlocksession = oarlockSessions[0] # should take seatIndex
+ boatName = oarlocksession["boatName"]
+ oarLength = oarlocksession["oarLength"] # cm
+ oarInboardLength = oarlocksession["oarInboardLength"] # cm
+ seatNumber = oarlocksession["seatNumber"]
+ try:
+ oarlockfirmware = oarlocksession["firmwareVersion"]
+ except KeyError:
+ oarlockfirmware = ''
+ else:
+ boatName = ''
+ oarLength = 289
+ oarInboardLength = 88
+ seatNumber = 1
+ oarlockfirmware = ''
+
+ workouttype = "water"
+ boattype = "1x"
+
+ uploadoptions = {
+ 'secret': UPLOAD_SERVICE_SECRET,
+ 'user':userid,
+ 'file': csvfilename,
+ 'title': title,
+ 'workouttype': workouttype,
+ 'boattype': boattype,
+ 'nkid':nkid,
+ 'inboard': oarInboardLength/100.,
+ 'oarlength': oarLength/100.,
+ 'summary':summary,
+ 'oarlockfirmware':oarlockfirmware,
+ 'elapsedTime': elapsedTime/1000., # in seconds
+ 'totalDistance': totalDistance,
+ 'useImpeller': useImpeller
+ }
+
+ 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,response.text
+
+ try:
+ workoutid = response.json()['id']
+ except KeyError:
+ workoutid = 1
+
+
+ # evt update workout summary
+
+ # return
+ return workoutid,""
+
+def get_nk_intervalstats(workoutdata,strokedata):
+ intervals = workoutdata['intervals']
+ separator = "|"
+ stri = "Workout Details\n"
+ stri += "#-{sep}SDist{sep}-Split-{sep}-SPace-{sep}-Pwr-{sep}-SPM--{sep}-AvgHR-{sep}DPS-\n".format(
+ sep=separator)
+
+ i = 0
+
+ for interval in intervals:
+ id = interval['id']
+ sdist = interval['totalDistanceGps']
+ avgpace = interval['avgPaceGps']/1000.
+ avgpacetd = timedelta(seconds=avgpace)
+ newpacestring = strfdelta(avgpacetd)
+
+ elapsedSeconds = interval['elapsedTime']/1000. # secs
+ elapsedTime = datetime.datetime.utcfromtimestamp(elapsedSeconds)
+
+ newsplitstring = "%s.%i" % (elapsedTime.strftime("%M:%S"), elapsedTime.microsecond/100000)
+
+ pwr = interval['avgPower']
+ avghr = interval['avgHeartRate']
+ spm = interval['avgStrokeRate']
+ dps = interval['distStrokeGps']
+
+ stri += "{i:0>2}{sep}{sdist:0>5}{sep}{split}{sep}{space}{sep} {pwr:0>3} {sep}".format(
+ i=i + 1,
+ sdist=int(float(sdist)),
+ split=newsplitstring,
+ space=newpacestring,
+ pwr=int(pwr),
+ sep=separator,
+ )
+ stri += " {spm} {sep} {avghr:0>3} {sep}{dps:0>4.1f}\n".format(
+ sep=separator,
+ avghr=avghr,
+ spm=spm,
+ dps=dps,
+ )
+
+ i += 1
+
+ return stri
+
+def get_nk_summary(workoutdata,strokedata):
+
+ name = workoutdata['name']
+
+ avgpace = workoutdata['avgPaceGps']/1000. # secs
+ avgpacetd = timedelta(seconds=avgpace)
+ avgpacestring = strfdelta(avgpacetd)
+
+ elapsedSeconds = workoutdata['elapsedTime']/1000. # secs
+ elapsedTime = datetime.datetime.utcfromtimestamp(elapsedSeconds)
+
+ timestring = "%s.%i" % (elapsedTime.strftime("%H:%M:%S"), elapsedTime.microsecond/100000)
+
+ dist = workoutdata['totalDistanceGps']
+ spm = workoutdata['avgStrokeRate']
+ avghr = workoutdata['avgHeartRate']
+ avgdps = workoutdata['distStrokeGps']
+ maxhr = strokedata['heartRate'].max()
+ pwr = workoutdata['avgPower']
+
+ sep = "|"
+
+
+ stri1 = "Workout Summary - " + name + "\n"
+ stri1 += "--{sep}Total{sep}--Total---{sep}--Avg--{sep}-Avg-{sep}-Avg--{sep}-Avg-{sep}-Max-{sep}-Avg\n".format(
+ sep=sep)
+ stri1 += "--{sep}Dist-{sep}--Time----{sep}-Pace--{sep}-Pwr-{sep}-SPM--{sep}-HR--{sep}-HR--{sep}-DPS\n".format(
+ sep=sep)
+
+
+
+ stri1 += "--{sep}{dist:0>5.0f}{sep}".format(
+ sep=sep,
+ dist=dist,
+ )
+
+ stri1 += timestring + sep + avgpacestring
+
+ stri1 += "{sep}{avgpower:0>5.1f}".format(
+ sep=sep,
+ avgpower=pwr,
+ )
+
+ stri1 += "{sep} {avgsr:2.1f} {sep}{avghr:0>5.1f}{sep}".format(
+ avgsr=spm,
+ sep=sep,
+ avghr=avghr
+ )
+
+ stri1 += "{maxhr:0>5.1f}{sep}{avgdps:0>4.1f}\n".format(
+ sep=sep,
+ maxhr=maxhr,
+ avgdps=avgdps
+ )
+
+ return stri1
+
+
+
+ return stri1
+
+def get_nk_allstats(data,workoutdata):
+ stri = get_nk_summary(data, workoutdata) + \
+ get_nk_intervalstats(data, workoutdata)
+ return stri
+
+#def get_workout(user,nkid):
+def getdict(x, seatIndex=1):
+ seatStrokes = pd.DataFrame(x)
+ try:
+ seatStrokes = seatStrokes.set_index('seatIndex')
+ return dict(seatStrokes.loc[seatIndex])
+ except KeyError:
+ pass
+
+ return {}
+
+def strokeDataToDf(strokeData):
+
+ df = pd.DataFrame.from_dict(strokeData)
+
+ oarlockData = df['oarlockStrokes']
+
+ oarlockData = oarlockData.apply(lambda x:getdict(x, seatIndex=1))
+ df2 = pd.DataFrame.from_records(oarlockData.values)
+
+ #df.set_index('timestamp',inplace=True)
+
+ if not df2.empty:
+ #df2.set_index('timestamp',inplace=True)
+ df = df.merge(df2,left_index=True,right_index=True)
+ df = df.rename(columns={"timestamp_x":"timestamp"})
+
+ df = df.drop('oarlockStrokes',axis=1)
+ df.sort_values(by='timestamp',ascending=True,inplace=True)
+ df.fillna(inplace=True,method='ffill')
+
+
+
+ return df
diff --git a/rowers/nkstuff.py b/rowers/nkstuff.py
index 709e9db7..4a3dbe2d 100644
--- a/rowers/nkstuff.py
+++ b/rowers/nkstuff.py
@@ -22,7 +22,7 @@ queuehigh = django_rq.get_queue('low')
from rowers.rower_rules import is_workout_user, ispromember
from iso8601 import ParseError
-from rowers.utils import myqueue,get_nk_summary, get_nk_allstats, get_nk_intervalstats,getdict
+from rowers.utils import myqueue
import rowers.mytypes as mytypes
import gzip
@@ -42,6 +42,7 @@ except ImportError:
JSONDecodeError = ValueError
from rowers.imports import *
+from rowers.nkimportutils import *
oauth_data = {
'client_id': NK_CLIENT_ID,
@@ -209,7 +210,7 @@ def rower_nk_token_refresh(user):
def make_authorization_url(request):
return imports_make_authorization_url(oauth_data)
-def get_nk_workout_list(user,fake=False):
+def get_nk_workout_list(user,fake=False,startTime=0,endTime=0):
r = Rower.objects.get(user=user)
if (r.nktoken == '') or (r.nktoken is None):
@@ -220,10 +221,12 @@ def get_nk_workout_list(user,fake=False):
return custom_exception_handler(401,s)
else:
# ready to fetch. Hurray
- endTime = int(arrow.now().timestamp())*1000
- endTime = str(endTime)
- startTime = arrow.now()-timedelta(days=30)*1000
- startTime = str(int(startTime.timestamp()))
+ if not endTime:
+ endTime = int(arrow.now().timestamp())*1000
+ endTime = str(endTime)
+ if not startTime:
+ startTime = arrow.now()-timedelta(days=30)
+ startTime = str(int(startTime.timestamp())*1000)
authorizationstring = str('Bearer ' + r.nktoken)
headers = {'Authorization': authorizationstring,
'user-agent': 'sanderroosendaal',
@@ -244,81 +247,6 @@ def get_nk_workout_list(user,fake=False):
#
-def add_workout_from_data(user,nkid,data,strokedata,source='nk',splitdata=None,
- workoutsource='nklinklogbook'):
-
- csvfilename = 'media/{code}_{nkid}.csv.gz'.format(
- nkid=nkid,
- code = uuid4().hex[:16]
- )
-
- strokedata.to_csv(csvfilename, index_label='index', compression='gzip')
-
- userid = user.id
-
- title = data["name"]
- speedInput = data["speedInput"]
- elapsedTime = data["elapsedTime"]
- totalDistanceGps = data["totalDistanceGps"]
- totalDistanceImp = data["totalDistanceImp"]
- intervals = data["intervals"] # add intervals
- oarlockSessions = data["oarlockSessions"]
- deviceId = data["deviceId"] # you could get the firmware version
-
- summary = get_nk_allstats(data,strokedata)
-
- # oarlock inboard, length, boat name
- if oarlockSessions:
- oarlocksession = oarlockSessions[0] # should take seatIndex
- boatName = oarlocksession["boatName"]
- oarLength = oarlocksession["oarLength"] # cm
- oarInboardLength = oarlocksession["oarInboardLength"] # cm
- seatNumber = oarlocksession["seatNumber"]
- else:
- boatName = ''
- oarLength = 289
- oarInboardLength = 88
- seatNumber = 1
-
- workouttype = "water"
- boattype = "1x"
-
- uploadoptions = {
- 'secret': UPLOAD_SERVICE_SECRET,
- 'user':userid,
- 'file': csvfilename,
- 'title': title,
- 'workouttype': workouttype,
- 'boattype': boattype,
- 'nkid':nkid,
- 'inboard': oarInboardLength/100.,
- 'oarlength': oarLength/100.,
- 'summary':summary,
- }
-
- 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,response.text
-
- try:
- workoutid = response.json()['id']
- except KeyError:
- workoutid = 1
-
-
- # evt update workout summary
-
- # return
- return workoutid,""
-
-
-
-
def get_workout(user,nkid):
r = Rower.objects.get(user=user)
if (r.nktoken == '') or (r.nktoken is None):
@@ -338,8 +266,6 @@ def get_workout(user,nkid):
'Content-Type': 'application/json',
}
-
-
# get strokes
url = NK_API_LOCATION+"api/v1/sessions/strokes"
response = requests.get(url,headers=headers,params=params)
@@ -353,22 +279,7 @@ def get_workout(user,nkid):
strokeData = jsonData[str(nkid)]
- df = pd.DataFrame.from_dict(strokeData)
- oarlockData = df['oarlockStrokes']
-
- oarlockData = oarlockData.apply(lambda x:getdict(x, seatIndex=1))
- df2 = pd.DataFrame.from_records(oarlockData.values)
-
- df.set_index('timestamp')
-
- if not df2.empty:
- df2.set_index('timestamp')
- df = df.merge(df2,left_index=True,right_index=True)
- df = df.rename(columns={"timestamp_x":"timestamp"})
-
- df = df.drop('oarlockStrokes',axis=1)
- df.sort_values(by='timestamp',ascending=True,inplace=True)
- df.fillna(inplace=True,method='ffill')
+ df = strokeDataToDf(strokeData)
# get workout data
timestampbegin = df['timestamp'].min()
@@ -379,6 +290,7 @@ def get_workout(user,nkid):
'startTime':timestampbegin-1,
'endTime': timestampend+1,
}
+
response = requests.get(url, headers=headers,params=params)
if response.status_code != 200:
diff --git a/rowers/tasks.py b/rowers/tasks.py
index 84957b55..c9dab841 100644
--- a/rowers/tasks.py
+++ b/rowers/tasks.py
@@ -111,7 +111,10 @@ def safetimedelta(x):
siteurl = SITE_URL
-from rowers.utils import get_nk_summary, get_nk_allstats, get_nk_intervalstats,getdict
+from rowers.nkimportutils import (
+ get_nk_summary, get_nk_allstats, get_nk_intervalstats,getdict,strokeDataToDf,
+ add_workout_from_data
+ )
# testing task
@@ -2958,6 +2961,7 @@ def handle_rp3_async_workout(userid,rp3token,rp3id,startdatetime,max_attempts,de
@app.task
def handle_nk_async_workout(alldata,userid,nktoken,nkid,delaysec,defaulttimezone,debug=False,**kwargs):
time.sleep(delaysec)
+
data = alldata[nkid]
params = {
@@ -2981,22 +2985,8 @@ def handle_nk_async_workout(alldata,userid,nktoken,nkid,delaysec,defaulttimezone
jsonData = response.json()
strokeData = jsonData[str(nkid)]
- df = pd.DataFrame.from_dict(strokeData)
- oarlockData = df['oarlockStrokes']
- oarlockData = oarlockData.apply(lambda x:getdict(x, seatIndex=1))
- df2 = pd.DataFrame.from_records(oarlockData.values)
-
- df.set_index('timestamp')
-
- if not df2.empty:
- df2.set_index('timestamp')
- df = df.merge(df2,left_index=True,right_index=True)
- df = df.rename(columns={"timestamp_x":"timestamp"})
-
- df = df.drop('oarlockStrokes',axis=1)
- df.sort_values(by='timestamp',ascending=True,inplace=True)
- df.fillna(inplace=True,method='ffill')
+ df = strokeDataToDf(strokeData)
# get workout data
timestampbegin = df['timestamp'].min()
@@ -3009,60 +2999,7 @@ def handle_nk_async_workout(alldata,userid,nktoken,nkid,delaysec,defaulttimezone
df.to_csv(csvfilename, index_label='index', compression='gzip')
-
- title = data["name"]
- speedInput = data["speedInput"]
- elapsedTime = data["elapsedTime"]
- totalDistanceGps = data["totalDistanceGps"]
- totalDistanceImp = data["totalDistanceImp"]
- intervals = data["intervals"] # add intervals
- oarlockSessions = data["oarlockSessions"]
- deviceId = data["deviceId"] # you could get the firmware version
-
- summary = get_nk_allstats(data,df)
-
- # oarlock inboard, length, boat name
- if oarlockSessions:
- oarlocksession = oarlockSessions[0] # should take seatIndex
- boatName = oarlocksession["boatName"]
- oarLength = oarlocksession["oarLength"] # cm
- oarInboardLength = oarlocksession["oarInboardLength"] # cm
- seatNumber = oarlocksession["seatNumber"]
- else:
- boatName = ''
- oarLength = 289
- oarInboardLength = 88
- seatNumber = 1
-
- workouttype = "water"
- boattype = "1x"
-
- uploadoptions = {
- 'secret': UPLOAD_SERVICE_SECRET,
- 'user':userid,
- 'file': csvfilename,
- 'title': title,
- 'workouttype': workouttype,
- 'boattype': boattype,
- 'nkid':nkid,
- 'inboard': oarInboardLength/100.,
- 'oarlength': oarLength/100.,
- 'summary':summary,
- }
-
- 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,response.text
-
- try:
- workoutid = response.json()['id']
- except KeyError:
- workoutid = 1
+ workoutid,error = add_workout_from_data(userid,nkid,data,df)
if debug:
engine = create_engine(database_url_debug, echo=False)
@@ -3081,9 +3018,12 @@ def handle_nk_async_workout(alldata,userid,nktoken,nkid,delaysec,defaulttimezone
conn.close()
parkedids = []
- with open('nkblocked.json','r') as nkblocked:
- jsondata = json.load(nkblocked)
- parkedids = jsondata['ids']
+ try:
+ with open('nkblocked.json','r') as nkblocked:
+ jsondata = json.load(nkblocked)
+ parkedids = jsondata['ids']
+ except FileNotFoundError:
+ pass
newparkedids = [id for id in parkedids if id != newnkid]
with open('nkblocked.json','wt') as nkblocked:
diff --git a/rowers/templates/menu_workout.html b/rowers/templates/menu_workout.html
index 51aefb8b..382f8d71 100644
--- a/rowers/templates/menu_workout.html
+++ b/rowers/templates/menu_workout.html
@@ -335,7 +335,7 @@
Remove Power Data
- {% if 'speedcoach2' in workout.workoutsource %}
+ {% if 'speedcoach2' in workout.workoutsource or 'nklinklogbook' in workout.workoutsource %}
diff --git a/rowers/tests/mocks.py b/rowers/tests/mocks.py
index e3f34f70..8c30723b 100644
--- a/rowers/tests/mocks.py
+++ b/rowers/tests/mocks.py
@@ -623,6 +623,12 @@ def mocked_requests(*args, **kwargs):
with open('rowers/tests/testdata/nk_list.json','r') as infile:
nkworkoutlist = json.load(infile)
+ with open('rowers/tests/testdata/example-session-strokes-with-impeller-data.json','r') as infile:
+ nkimpellerstrokedata = json.load(infile)
+
+ with open('rowers/tests/testdata/example-session-with-impeller-data.json','r') as infile:
+ nkimpellerworkoutlist = json.load(infile)
+
polar_json = {
'available-user-data': []
}
@@ -960,10 +966,14 @@ def mocked_requests(*args, **kwargs):
}
return MockResponse(json_data,200)
if nkstrokestester.match(args[0]):
-
+ params = kwargs.pop('params',{})
+ if 'sessionIds' in params and params['sessionIds'] == '404':
+ return MockResponse(nkimpellerstrokedata, 200)
return MockResponse(nkstrokedata,200)
if nkworkoutlisttester.match(args[0]):
-
+ params = kwargs.pop('params',{})
+ if 'startTime' in params and params['startTime'] == 1267136372998:
+ return MockResponse(nkimpellerworkoutlist,200)
return MockResponse(nkworkoutlist,200)
diff --git a/rowers/tests/test_imports.py b/rowers/tests/test_imports.py
index c61ffa8d..de36cc85 100644
--- a/rowers/tests/test_imports.py
+++ b/rowers/tests/test_imports.py
@@ -424,9 +424,44 @@ class NKObjects(DjangoTestCase):
self.assertEqual(response.status_code,200)
+ @patch('rowers.nkimportutils.requests.session', side_effect=mocked_session)
+ @patch('rowers.tasks.requests.get', side_effects=mocked_requests)
+ def test_handle_nk_get_workouts(self, mocked_session, mock_get):
+ with open('rowers/tests/testdata/nk_list.json','r') as f:
+ data = json.load(f)
+
+ with open('rowers/tests/testdata/nk_strokes.json','r') as f:
+ strokeData = json.load(f)
+
+ alldata = {}
+ for item in data:
+ alldata[item['id']] = item
+
+ result = rowers.nkstuff.rower_nk_token_refresh(self.u)
+
+ res = tasks.handle_nk_async_workout(
+ alldata,self.r.user.id,self.r.nktoken,469,0,'UTC'
+ )
+
+
@patch('rowers.nkstuff.requests.get', side_effect=mocked_requests)
@patch('rowers.nkstuff.requests.post', side_effect=mocked_requests)
- @patch('rowers.nkstuff.requests.session', side_effect=mocked_session)
+ def test_nk_get_workouts(self, mock_get, mockpost):
+ result = rowers.nkstuff.nk_open(self.u)
+ self.assertEqual(result,"TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq")
+ response = self.c.get('/rowers/workout/nkimport/all/',follow=True)
+
+ expected = reverse('workouts_view')
+
+ self.assertRedirects(response,
+ expected_url=expected,
+ status_code=302,target_status_code=200)
+
+ self.assertEqual(response.status_code, 200)
+
+ @patch('rowers.nkstuff.requests.get', side_effect=mocked_requests)
+ @patch('rowers.nkstuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.nkimportutils.requests.session', side_effect=mocked_session)
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db)
def test_nk_import(self, mock_get, mock_post,
mocked_session,
@@ -441,6 +476,34 @@ class NKObjects(DjangoTestCase):
self.assertEqual(response.status_code, 200)
+ w = Workout.objects.get(id=1)
+ #self.assertEqual(w.inboard,0.89)
+ #self.assertEqual(w.oarlength,2.87)
+
+ @patch('rowers.nkstuff.requests.get', side_effect=mocked_requests)
+ @patch('rowers.nkstuff.requests.post', side_effect=mocked_requests)
+ @patch('rowers.nkimportutils.requests.session', side_effect=mocked_session)
+ @patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db)
+ def test_nk_import_impeller(self, mock_get, mock_post,
+ mocked_session,
+ mocked_getsmallrowdata_db):
+
+ result = rowers.nkstuff.rower_nk_token_refresh(self.u)
+ response = self.c.get('/rowers/workout/nkimport/404',follow=True)
+
+ self.assertRedirects(response,
+ expected_url='/rowers/workout/'+encoded1+'/edit/',
+ status_code=301,target_status_code=200)
+
+ self.assertEqual(response.status_code, 200)
+
+ response = self.c.get('/rowers/workout/'+encoded1+'/otwuseimpeller/', follow=True)
+ self.assertRedirects(response,
+ expected_url='/rowers/workout/'+encoded1+'/edit/',
+ status_code=302,target_status_code=200)
+
+ w = Workout.objects.get(id=1)
+ #self.assertTrue(w.impeller)
#@pytest.mark.django_db
diff --git a/rowers/tests/test_races.py b/rowers/tests/test_races.py
index 2f1a3114..fe78d0d9 100644
--- a/rowers/tests/test_races.py
+++ b/rowers/tests/test_races.py
@@ -15,6 +15,8 @@ import rowers.tasks as tasks
from rowers.views.racesviews import *
from rowers.utils import calculate_age
+# to do - add test for manual form with image
+
@override_settings(TESTING=True)
class ChallengesTest(TestCase):
def setUp(self):
diff --git a/rowers/tests/test_unit_tests.py b/rowers/tests/test_unit_tests.py
index bc1acac7..b481530e 100644
--- a/rowers/tests/test_unit_tests.py
+++ b/rowers/tests/test_unit_tests.py
@@ -12,6 +12,42 @@ nu = datetime.datetime.now()
# interactive plots
from rowers import interactiveplots
from rowers import dataprep
+from rowers.views.workoutviews import get_video_id
+
+class OtherUnitTests(TestCase):
+ def test_get_video_id(self):
+ url1 = 'http://youtu.be/_lOT2p_FCvA'
+ url2 = 'www.youtube.com/watch?v=_lOT2p_FCvA&feature=feedu'
+ url3 = 'http://www.youtube.com/embed/_lOT2p_FCvA'
+ url4 = 'http://www.youtube.com/v/_lOT2p_FCvA?version=3&hl=en_US'
+ url5 = 'https://www.youtube.com/watch?v=rTHlyTphWP0&index=6&list=PLjeDyYvG6-40qawYNR4juzvSOg-ezZ2a6'
+ url6 = 'youtube.com/watch?v=_lOT2p_FCvA'
+ expected = '_lOT2p_FCvA'
+ expected2 = 'rTHlyTphWP0'
+
+ result = get_video_id(url1)
+
+ self.assertEqual(result,expected)
+
+ result = get_video_id(url2)
+
+ self.assertEqual(result,expected)
+
+ result = get_video_id(url3)
+
+ self.assertEqual(result,expected)
+
+ result = get_video_id(url4)
+
+ self.assertEqual(result,expected)
+
+ result = get_video_id(url5)
+
+ self.assertEqual(result,expected2)
+
+ result = get_video_id(url6)
+
+ self.assertEqual(result,expected)
class DataPrepTests(TestCase):
def setUp(self):
diff --git a/rowers/uploads.py b/rowers/uploads.py
index 23546796..eb57dbb0 100644
--- a/rowers/uploads.py
+++ b/rowers/uploads.py
@@ -548,6 +548,19 @@ def do_sync(w,options, quick=False):
except KeyError:
pass
+ try:
+ if options['inboard'] != 0 and options['inboard'] != '':
+ w.inboard = options['inboard']
+ except KeyError:
+ pass
+
+ try:
+ if options['oarlength'] != 0 and options['oarlength'] != '':
+ w.oarlength = options['oarlength']
+ except KeyError:
+ pass
+
+
try:
if options['garminid'] != 0 and options['garminid'] != '':
w.uploadedtogarmin = options['garminid']
diff --git a/rowers/urls.py b/rowers/urls.py
index ad8dfe03..e36d55e0 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -568,6 +568,7 @@ urlpatterns = [
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/nkimport/$',views.workout_nkimport_view,name='workout_nkimport_view'),
+ re_path(r'^workout/nkimport/(?P\d+)/(?P\d+)/$',views.workout_nkimport_view,name='workout_nkimport_view'),
re_path(r'^workout/nkimport/all/$',views.workout_getnkworkout_all,name='workout_getnkworkout_all'),
re_path(r'^workout/rp3import/(?P\d+)/$',views.workout_getrp3importview,
name='workout_getrp3importview'),
diff --git a/rowers/utils.py b/rowers/utils.py
index 062f10c2..79b38130 100644
--- a/rowers/utils.py
+++ b/rowers/utils.py
@@ -1108,126 +1108,3 @@ def strfdelta(tdelta):
)
return res
-
-
-def get_nk_intervalstats(workoutdata,strokedata):
- intervals = workoutdata['intervals']
- separator = "|"
- stri = "Workout Details\n"
- stri += "#-{sep}SDist{sep}-Split-{sep}-SPace-{sep}-Pwr-{sep}-SPM--{sep}-AvgHR-{sep}DPS-\n".format(
- sep=separator)
-
- i = 0
-
- for interval in intervals:
- id = interval['id']
- sdist = interval['totalDistanceGps']
- avgpace = interval['avgPaceGps']/1000.
- avgpacetd = timedelta(seconds=avgpace)
- newpacestring = strfdelta(avgpacetd)
-
- elapsedSeconds = interval['elapsedTime']/1000. # secs
- elapsedTime = datetime.datetime.utcfromtimestamp(elapsedSeconds)
-
- newsplitstring = "%s.%i" % (elapsedTime.strftime("%M:%S"), elapsedTime.microsecond/100000)
-
- pwr = interval['avgPower']
- avghr = interval['avgHeartRate']
- spm = interval['avgStrokeRate']
- dps = interval['distStrokeGps']
-
- stri += "{i:0>2}{sep}{sdist:0>5}{sep}{split}{sep}{space}{sep} {pwr:0>3} {sep}".format(
- i=i + 1,
- sdist=int(float(sdist)),
- split=newsplitstring,
- space=newpacestring,
- pwr=int(pwr),
- sep=separator,
- )
- stri += " {spm} {sep} {avghr:0>3} {sep}{dps:0>4.1f}\n".format(
- sep=separator,
- avghr=avghr,
- spm=spm,
- dps=dps,
- )
-
- i += 1
-
- return stri
-
-def get_nk_summary(workoutdata,strokedata):
-
- name = workoutdata['name']
-
- avgpace = workoutdata['avgPaceGps']/1000. # secs
- avgpacetd = timedelta(seconds=avgpace)
- avgpacestring = strfdelta(avgpacetd)
-
- elapsedSeconds = workoutdata['elapsedTime']/1000. # secs
- elapsedTime = datetime.datetime.utcfromtimestamp(elapsedSeconds)
-
- timestring = "%s.%i" % (elapsedTime.strftime("%H:%M:%S"), elapsedTime.microsecond/100000)
-
- dist = workoutdata['totalDistanceGps']
- spm = workoutdata['avgStrokeRate']
- avghr = workoutdata['avgHeartRate']
- avgdps = workoutdata['distStrokeGps']
- maxhr = strokedata['heartRate'].max()
- pwr = workoutdata['avgPower']
-
- sep = "|"
-
-
- stri1 = "Workout Summary - " + name + "\n"
- stri1 += "--{sep}Total{sep}--Total---{sep}--Avg--{sep}-Avg-{sep}-Avg--{sep}-Avg-{sep}-Max-{sep}-Avg\n".format(
- sep=sep)
- stri1 += "--{sep}Dist-{sep}--Time----{sep}-Pace--{sep}-Pwr-{sep}-SPM--{sep}-HR--{sep}-HR--{sep}-DPS\n".format(
- sep=sep)
-
-
-
- stri1 += "--{sep}{dist:0>5.0f}{sep}".format(
- sep=sep,
- dist=dist,
- )
-
- stri1 += timestring + sep + avgpacestring
-
- stri1 += "{sep}{avgpower:0>5.1f}".format(
- sep=sep,
- avgpower=pwr,
- )
-
- stri1 += "{sep} {avgsr:2.1f} {sep}{avghr:0>5.1f}{sep}".format(
- avgsr=spm,
- sep=sep,
- avghr=avghr
- )
-
- stri1 += "{maxhr:0>5.1f}{sep}{avgdps:0>4.1f}\n".format(
- sep=sep,
- maxhr=maxhr,
- avgdps=avgdps
- )
-
- return stri1
-
-
-
- return stri1
-
-def get_nk_allstats(data,workoutdata):
- stri = get_nk_summary(data, workoutdata) + \
- get_nk_intervalstats(data, workoutdata)
- return stri
-
-#def get_workout(user,nkid):
-def getdict(x, seatIndex=1):
- seatStrokes = pd.DataFrame(x)
- try:
- seatStrokes = seatStrokes.set_index('seatIndex')
- return dict(seatStrokes.loc[seatIndex])
- except KeyError:
- pass
-
- return {}
diff --git a/rowers/views/importviews.py b/rowers/views/importviews.py
index e3120a29..e644e53a 100644
--- a/rowers/views/importviews.py
+++ b/rowers/views/importviews.py
@@ -836,14 +836,14 @@ def workout_getnkworkout_all(request):
@login_required()
@permission_required('rower.is_coach',fn=get_user_by_userid, raise_exception=True)
-def workout_nkimport_view(request,userid=0):
+def workout_nkimport_view(request,userid=0,startTime=0,endTime=0):
r = getrequestrower(request,userid=userid)
try:
thetoken = nk_open(request.user)
except NoTokenError:
return HttpResponseRedirect("/rowers/me/nkauthorize/")
- res = nkstuff.get_nk_workout_list(request.user)
+ res = nkstuff.get_nk_workout_list(request.user,startTime=startTime,endTime=endTime)
if (res.status_code != 200):
if (res.status_code == 401):
@@ -882,6 +882,9 @@ def workout_nkimport_view(request,userid=0):
'start_date':arrow.get(item['startTime']),
} for item in res.json()]
+ #for item in res.json():
+ # print(item['startTime'],arrow.get(item['startTime']),item['name'])
+
workouts = []
for item in res.json():
diff --git a/rowers/views/paymentviews.py b/rowers/views/paymentviews.py
index 8dd72317..51bb56cd 100644
--- a/rowers/views/paymentviews.py
+++ b/rowers/views/paymentviews.py
@@ -636,7 +636,6 @@ def upgrade_checkouts_view(request):
@login_required()
def downgrade_checkouts_view(request):
- print('aap')
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
diff --git a/rowers/views/userviews.py b/rowers/views/userviews.py
index 65d4b24d..2d1d85a6 100644
--- a/rowers/views/userviews.py
+++ b/rowers/views/userviews.py
@@ -336,6 +336,8 @@ def rower_exportsettings_view(request,userid=0):
'strava_auto_import':'stravatoken',
'strava_auto_delete':'stravatoken',
'trainingpeaks_auto_export':'tptoken',
+ 'rp3_auto_import':'rp3token',
+ 'nk_auto_import':'nktoken'
}
r = getrequestrowercoachee(request,userid=userid)
if request.method == 'POST':
diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py
index b1f1ef56..c26b1ac7 100644
--- a/rowers/views/workoutviews.py
+++ b/rowers/views/workoutviews.py
@@ -17,7 +17,7 @@ import rowers.utils as utils
from urllib.parse import urlparse, parse_qs
from json.decoder import JSONDecodeError
-def default(o):
+def default(o): # pragma: no cover
if isinstance(o, numpy.int64): return int(o)
if isinstance(o, numpy.int32): return int(o)
raise TypeError
@@ -52,7 +52,7 @@ def get_video_id(url):
return query.path.split('/')[2]
elif 'youtu.be' in query.hostname:
return query.path[1:]
- else:
+ else: # pragma: no cover
raise ValueError
# Show a video compared with data
@@ -60,7 +60,7 @@ def workout_video_view_mini(request,id=''):
try:
id = encoder.decode_hex(id)
analysis = VideoAnalysis.objects.get(id=id)
- except VideoAnalysis.DoesNotExist:
+ except VideoAnalysis.DoesNotExist: # pragma: no cover
raise Http404("Video Analysis does not exist")
w = analysis.workout
@@ -173,7 +173,7 @@ def workout_video_view(request,id=''):
try:
id = encoder.decode_hex(id)
analysis = VideoAnalysis.objects.get(id=id)
- except VideoAnalysis.DoesNotExist:
+ except VideoAnalysis.DoesNotExist: # pragma: no cover
raise Http404("Video Analysis does not exist")
w = analysis.workout
@@ -199,7 +199,7 @@ def workout_video_view(request,id=''):
video_id = form.cleaned_data['url']
try:
video_id = get_video_id(form.cleaned_data['url'])
- except (TypeError,ValueError):
+ except (TypeError,ValueError): # pragma: no cover
pass
delay = form.cleaned_data['delay']
metricsgroups = metricsform.cleaned_data['groups']
@@ -314,7 +314,7 @@ def workout_video_create_view(request,id=0):
url = reverse('workout_video_view',
kwargs={'id':encoder.encode_hex(analysis.id)})
return HttpResponseRedirect(url)
- except IntegrityError:
+ except IntegrityError: # pragma: no cover
messages.error(request,'You cannot save two video analysis with the same YouTube video and Workout. Redirecting to your existing analysis')
analysis = VideoAnalysis.objects.filter(workout=w,video_id=video_id)
if analysis:
@@ -577,7 +577,7 @@ def addmanual_view(request,raceid=0):
if form.is_valid() and metricsform.is_valid():
# Get values from form
name = form.cleaned_data['name']
- if name == '':
+ if name == '': # pragma: no cover
name = 'Manual Entry'
date = form.cleaned_data['date']
starttime = form.cleaned_data['starttime']
@@ -590,7 +590,7 @@ def addmanual_view(request,raceid=0):
rpe = form.cleaned_data['rpe']
if not rpe:
rpe = -1
- except KeyError:
+ except KeyError: # pragma: no cover
rpe = -1
notes = form.cleaned_data['notes']
thetimezone = form.cleaned_data['timezone']
@@ -601,25 +601,25 @@ def addmanual_view(request,raceid=0):
try:
ps = form.cleaned_data['plannedsession']
- except KeyError:
+ except KeyError: # pragma: no cover
ps = None
try:
boattype = request.POST['boattype']
- except KeyError:
+ except KeyError: # pragma: no cover
boattype = '1x'
try:
privacy = request.POST['privacy']
- except KeyError:
+ except KeyError: # pragma: no cover
privacy = 'visible'
try:
rankingpiece = form.cleaned_data['rankingpiece']
- except KeyError:
+ except KeyError: # pragma: no cover
rankingpiece = False
try:
duplicate = form.cleaned_data['duplicate']
- except KeyError:
+ except KeyError: # pragma: no cover
duplicate = False
if private:
@@ -654,7 +654,7 @@ def addmanual_view(request,raceid=0):
- if message:
+ if message: # pragma: no cover
messages.error(request,message)
if id:
@@ -871,7 +871,7 @@ def workouts_join_view(request,userid=0):
setprivate=set_private,
killparents=killparents)
- if message:
+ if message: # pragma: no cover
messages.error(request,message)
url = reverse(r.defaultlandingpage,
@@ -920,13 +920,13 @@ def video_selectworkout(request,userid=0,teamid=0):
options['userid'] = userid
try:
workouttypes = options['workouttypes']
- except KeyError:
+ except KeyError: # pragma: no cover
workouttypes = ['rower','dynamic','slides']
try:
modalities = options['modalities']
modality = modalities[0]
- except KeyError:
+ except KeyError: # pragma: no cover
modalities = [m[0] for m in mytypes.workouttypes_ordered.items()]
modality = 'all'
@@ -934,11 +934,11 @@ def video_selectworkout(request,userid=0,teamid=0):
try:
rankingonly = options['rankingonly']
- except KeyError:
+ except KeyError: # pragma: no cover
rankingonly = False
query = request.GET.get('q')
- if query:
+ if query: # pragma: no cover
query_list = query.split()
workouts = workouts.filter(
reduce(operator.and_,
@@ -1005,7 +1005,7 @@ def video_selectworkout(request,userid=0,teamid=0):
startdate = datetime.datetime.combine(startdate,datetime.time())
enddate = datetime.datetime.combine(enddate,datetime.time(23,59,59))
- if enddate < startdate:
+ if enddate < startdate: # pragma: no cover
s = enddate
enddate = startdate
startdate = s
@@ -1168,7 +1168,7 @@ def workouts_join_select(request,
if enddatestring:
enddate = iso8601.parse_date(enddatestring)
- if enddate < startdate:
+ if enddate < startdate: # pragma: no cover
s = enddate
enddate = startdate
startdate = s
@@ -1279,7 +1279,7 @@ def remove_power_view(request,id=0):
try:
os.remove('media/cpdata_{id}.parquet.gz'.format(id=workout.id))
- except OSError:
+ except OSError: # pragma: no cover
pass
f = workout.csvfilename
@@ -1412,7 +1412,7 @@ def team_comparison_select(request,
if enddatestring:
enddate = iso8601.parse_date(enddatestring)
- if enddate < startdate:
+ if enddate < startdate: # pragma: no cover
s = enddate
enddate = startdate
startdate = s
@@ -1445,7 +1445,7 @@ def team_comparison_select(request,
workouts = workouts.exclude(rankingpiece=False)
query = request.GET.get('q')
- if query:
+ if query: # pragma: no cover
query_list = query.split()
workouts = workouts.filter(
reduce(operator.and_,
@@ -2034,7 +2034,7 @@ def workouts_view(request,message='',successmessage='',
#enddate = enddate+datetime.timedelta(days=1)
- if enddate < startdate:
+ if enddate < startdate: # pragma: no cover
s = enddate
enddate = startdate
startdate = s
@@ -4859,8 +4859,6 @@ def workout_upload_api(request):
message = {'status':'false','message':'this view cannot be accessed through GET'}
return JSONResponse(status=403,data=message)
-
-
# test if JSON
try:
json_data = json.loads(request.body)
@@ -4907,38 +4905,24 @@ def workout_upload_api(request):
message = {'status':'false','message':'could not find file'}
return JSONResponse(status=400,data=message)
- try:
- stravaid = post_data['stravaid']
- except KeyError:
- stravaid = ''
+ # sync related IDs
+ stravaid = post_data.get('stravaid','')
+ c2id = post_data.get('c2id','')
+ nkid = post_data.get('nkid','')
+ rp3id = post_data.get('nkid','')
+ garminid = post_data.get('garminid',0)
- try:
- c2id = post_data['c2id']
- except KeyError:
- c2id = ''
+ startdatetime = post_data.get('startdatetime','')
+ oarlockfirmware = post_data.get('oarlockfirmware',None)
+ inboard = post_data.get('inboard',None)
+ oarlength = post_data.get('oarlength',None)
+ useImpeller = post_data.get('useImpeller',False)
- try:
- nkid = post_data['nkid']
- except KeyError:
- nkid = ''
+ totalDistance = post_data.get('totalDistance',None)
+ elapsedTime = post_data.get('elapsedTime',None)
+ summary = post_data.get('summary',None)
- try:
- rp3id = post_data['rp3id']
- except KeyError:
- rp3id = ''
-
-
- try:
- garminid = post_data['garminid']
- except KeyError:
- garminid = 0
-
- try:
- startdatetime = post_data['startdatetime']
- except KeyError:
- startdatetime = ''
-
r = None
if form.is_valid():
t = form.cleaned_data['title']
@@ -5011,6 +4995,10 @@ def workout_upload_api(request):
notes=notes,
uploadoptions=post_data,
startdatetime=startdatetime,
+ oarlockfirmware=oarlockfirmware,
+ inboard=inboard,
+ oarlength=oarlength,
+ impeller=useImpeller,
)
if id == 0:
@@ -5033,21 +5021,23 @@ def workout_upload_api(request):
plottype = r.staticchartonupload
res, jobid = uploads.make_plot(r,w,f1,f2,plottype,t)
- try:
- oarlength = post_data['oarlength']
- inboard = post_data['inboard']
+ if inboard:
w.inboard = inboard
+ w.save()
+ if oarlength:
w.oarlength = oarlength
w.save()
- except KeyError:
- pass
- try:
- summary = post_data['summary']
+ if totalDistance:
+ w.distance = totalDistance
+ w.save()
+
+ if elapsedTime:
+ w.duration = totaltime_sec_to_string(elapsedTime)
+
+ if summary:
w.summary = summary
w.save()
- except KeyError:
- pass
uploads.do_sync(w,post_data,quick=True)