395 lines
11 KiB
Python
395 lines
11 KiB
Python
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
from __future__ import unicode_literals
|
|
from __future__ import unicode_literals, absolute_import
|
|
|
|
import time
|
|
from time import strftime
|
|
|
|
import requests
|
|
|
|
#https:#oauth-stage.nkrowlink.com/oauth/authorizegrant_type=authorization_code&response_type=code&client_id=rowsandall-staging&scope=read&state=fc8fc3d8-ce0a-443e-838a-1c06fb5317c6&redirect_uri=https%3A%2F%2Fdunav.ngrok.io%2Fnk_callback%2F
|
|
#https:#oauth-stage.nkrowlink.com/oauth/authorize?grant_type=authorization_code&response_type=code&client_id=rowsandall-staging&scope=read&state=1234&redirect_uri=https%3A%2F%2Fdev.rowsandall.com%2Fnk_callback
|
|
|
|
from requests_oauthlib import OAuth2Session
|
|
|
|
import django_rq
|
|
queue = django_rq.get_queue('default')
|
|
queuelow = django_rq.get_queue('low')
|
|
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
|
|
|
|
import rowers.mytypes as mytypes
|
|
import gzip
|
|
|
|
from rowsandall_app.settings import (
|
|
NK_CLIENT_ID, NK_REDIRECT_URI, NK_CLIENT_SECRET,
|
|
SITE_URL, NK_API_LOCATION,
|
|
UPLOAD_SERVICE_URL, UPLOAD_SERVICE_SECRET,
|
|
)
|
|
|
|
from rowers.tasks import handle_nk_async_workout
|
|
|
|
|
|
try:
|
|
from json.decoder import JSONDecodeError
|
|
except ImportError:
|
|
JSONDecodeError = ValueError
|
|
|
|
from rowers.imports import *
|
|
|
|
oauth_data = {
|
|
'client_id': NK_CLIENT_ID,
|
|
'client_secret': NK_CLIENT_SECRET,
|
|
'redirect_uri': NK_REDIRECT_URI,
|
|
'autorization_uri': "https://oauth-stage.nkrowlink.com/oauth/authorize",
|
|
'content_type': 'application/json',
|
|
'tokenname': 'nktoken',
|
|
'refreshtokenname': 'nkrefreshtoken',
|
|
'expirydatename': 'nktokenexpirydate',
|
|
'bearer_auth': True,
|
|
'base_url': "https://oauth-stage.nkrowlink.com/oauth/token",
|
|
'scope':'read',
|
|
}
|
|
|
|
from requests.auth import HTTPBasicAuth
|
|
|
|
def get_token(code):
|
|
url = oauth_data['base_url']
|
|
|
|
|
|
headers = {'Accept': 'application/json',
|
|
#'Authorization': auth_header,
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
#'user-agent': 'sanderroosendaal'
|
|
}
|
|
|
|
|
|
|
|
post_data = {"client_id": oauth_data['client_id'],
|
|
"grant_type": "authorization_code",
|
|
"redirect_uri": oauth_data['redirect_uri'],
|
|
"code": code,
|
|
}
|
|
|
|
response = requests.post(url,auth=HTTPBasicAuth(oauth_data['client_id'],oauth_data['client_secret']),
|
|
data=post_data)
|
|
|
|
if response.status_code != 200:
|
|
return [0,response.text,0,0]
|
|
|
|
token_json = response.json()
|
|
|
|
access_token = token_json['access_token']
|
|
refresh_token = token_json['refresh_token']
|
|
expires_in = token_json['expires_in']
|
|
nk_owner_id = token_json['user_id']
|
|
|
|
return [access_token, expires_in, refresh_token,nk_owner_id]
|
|
|
|
|
|
def nk_open(user):
|
|
r = Rower.objects.get(user=user)
|
|
|
|
if (r.nktoken == '') or (r.nktoken is None):
|
|
s = "Token doesn't exist. Need to authorize"
|
|
raise NoTokenError("User has no token")
|
|
else:
|
|
if (timezone.now()>r.nktokenexpirydate):
|
|
|
|
thetoken = rower_nk_token_refresh(user)
|
|
if thetoken == None:
|
|
raise NoTokenError("User has no token")
|
|
return thetoken
|
|
else:
|
|
thetoken = r.nktoken
|
|
|
|
return thetoken
|
|
|
|
def get_nk_workouts(rower, do_async=True):
|
|
try:
|
|
thetoken = nk_open(rower.user)
|
|
except NoTokenError:
|
|
return 0
|
|
|
|
res = get_nk_workout_list(rower.user)
|
|
|
|
if res.status_code != 200:
|
|
return 0
|
|
|
|
nkids = [item['id'] for item in res.json()]
|
|
alldata = {}
|
|
for item in res.json():
|
|
alldata[item['id']] = item
|
|
|
|
knownnkids = [
|
|
w.uploadedtonk for w in Workout.objects.filter(user=rower)
|
|
]
|
|
|
|
tombstones = [
|
|
t.uploadedtonk for t in TombStone.objects.filter(user=rower)
|
|
]
|
|
|
|
parkedids = []
|
|
try:
|
|
with open('nkblocked.json','r') as nkblocked:
|
|
jsondata = json.load(nkblocked)
|
|
parkedids = jsondata['ids']
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
knownnkids = uniqify(knownnkids+tombstones+parkedids)
|
|
newids = [nkid for nkid in nkids if not nkid in knownnkids]
|
|
|
|
newparkedids = uniqify(newids+parkedids)
|
|
|
|
with open('nkblocked.json','wt') as nkblocked:
|
|
data = {'ids':newparkedids}
|
|
json.dump(data,nkblocked)
|
|
|
|
counter = 0
|
|
for nkid in newids:
|
|
res = myqueue(queuehigh,
|
|
handle_nk_async_workout,
|
|
alldata,
|
|
rower.user.id,
|
|
rower.nktoken,
|
|
nkid,
|
|
counter,
|
|
rower.defaulttimezone
|
|
)
|
|
counter += 1
|
|
|
|
return 1
|
|
|
|
|
|
|
|
def do_refresh_token(refreshtoken):
|
|
post_data = {"grant_type": "refresh_token",
|
|
#"client_id":NK_CLIENT_ID,
|
|
"refresh_token": refreshtoken,
|
|
}
|
|
|
|
url = oauth_data['base_url']
|
|
|
|
response = requests.post(url,data=post_data,auth=HTTPBasicAuth(oauth_data['client_id'],oauth_data['client_secret']))
|
|
|
|
if response.status_code != 200:
|
|
return [0,0,0]
|
|
|
|
token_json = response.json()
|
|
|
|
access_token = token_json['access_token']
|
|
refresh_token = token_json['refresh_token']
|
|
expires_in = token_json['expires_in']
|
|
|
|
return access_token, expires_in, refresh_token
|
|
|
|
|
|
def rower_nk_token_refresh(user):
|
|
r = Rower.objects.get(user=user)
|
|
res = do_refresh_token(r.nkrefreshtoken)
|
|
access_token = res[0]
|
|
expires_in = res[1]
|
|
refresh_token = res[2]
|
|
expirydatetime = timezone.now()+timedelta(seconds=expires_in)
|
|
|
|
r.nktoken = access_token
|
|
r.nktokenexpirydate = expirydatetime
|
|
r.nkrefreshtoken = refresh_token
|
|
r.save()
|
|
|
|
return r.nktoken
|
|
|
|
def make_authorization_url(request):
|
|
return imports_make_authorization_url(oauth_data)
|
|
|
|
def get_nk_workout_list(user,fake=False):
|
|
r = Rower.objects.get(user=user)
|
|
|
|
if (r.nktoken == '') or (r.nktoken is None):
|
|
s = "Token doesn't exist. Need to authorize"
|
|
return custom_exception_handler(401,s)
|
|
elif (r.nktokenexpirydate is None or timezone.now()+timedelta(seconds=10)>r.nktokenexpirydate):
|
|
s = "Token expired. Needs to refresh."
|
|
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()))
|
|
authorizationstring = str('Bearer ' + r.nktoken)
|
|
headers = {'Authorization': authorizationstring,
|
|
'user-agent': 'sanderroosendaal',
|
|
'Content-Type': 'application/json',
|
|
}
|
|
|
|
url = NK_API_LOCATION+"api/v1/sessions"
|
|
|
|
params = {
|
|
'startTime':startTime,
|
|
'endTime':endTime,
|
|
} # start / end time
|
|
|
|
s = requests.get(url,headers=headers,params=params)
|
|
|
|
|
|
return s
|
|
|
|
#
|
|
|
|
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):
|
|
s = "Token doesn't exist. Need to authorize"
|
|
return custom_exception_handler(401,s) ,0
|
|
elif (timezone.now()>r.nktokenexpirydate):
|
|
s = "Token expired. Needs to refresh."
|
|
return custom_exception_handler(401,s),0
|
|
|
|
params = {
|
|
'sessionIds': nkid,
|
|
}
|
|
|
|
authorizationstring = str('Bearer ' + r.nktoken)
|
|
headers = {'Authorization': authorizationstring,
|
|
'user-agent': 'sanderroosendaal',
|
|
'Content-Type': 'application/json',
|
|
}
|
|
|
|
|
|
|
|
# get strokes
|
|
url = NK_API_LOCATION+"api/v1/sessions/strokes"
|
|
response = requests.get(url,headers=headers,params=params)
|
|
|
|
|
|
if response.status_code != 200:
|
|
# error handling and logging
|
|
return {},pd.DataFrame()
|
|
|
|
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')
|
|
|
|
# get workout data
|
|
timestampbegin = df['timestamp'].min()
|
|
timestampend = df['timestamp'].max()
|
|
|
|
url = NK_API_LOCATION+"api/v1/sessions/"
|
|
params = {
|
|
'startTime':timestampbegin-1,
|
|
'endTime': timestampend+1,
|
|
}
|
|
response = requests.get(url, headers=headers,params=params)
|
|
|
|
if response.status_code != 200:
|
|
# error handling and logging
|
|
return {},df
|
|
|
|
jsondata = response.json()
|
|
workoutdata = {}
|
|
for w in jsondata:
|
|
if str(w['id']) == str(nkid):
|
|
workoutdata = w
|
|
|
|
return workoutdata, df
|