Merge branch 'release/v18.6.2'
This commit is contained in:
@@ -90,6 +90,8 @@ SETTINGS_NAME = settings.SETTINGS_NAME
|
|||||||
UPLOAD_SERVICE_URL = settings.UPLOAD_SERVICE_URL
|
UPLOAD_SERVICE_URL = settings.UPLOAD_SERVICE_URL
|
||||||
UPLOAD_SERVICE_SECRET = settings.UPLOAD_SERVICE_SECRET
|
UPLOAD_SERVICE_SECRET = settings.UPLOAD_SERVICE_SECRET
|
||||||
NK_API_LOCATION = settings.NK_API_LOCATION
|
NK_API_LOCATION = settings.NK_API_LOCATION
|
||||||
|
TP_CLIENT_ID = settings.TP_CLIENT_ID
|
||||||
|
TP_CLIENT_SECRET = settings.TP_CLIENT_SECRET
|
||||||
|
|
||||||
from requests_oauthlib import OAuth1, OAuth1Session
|
from requests_oauthlib import OAuth1, OAuth1Session
|
||||||
|
|
||||||
@@ -299,6 +301,23 @@ def summaryfromsplitdata(splitdata, data, filename, sep='|', workouttype='rower'
|
|||||||
|
|
||||||
return sums, sa, results
|
return sums, sa, results
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def check_tp_workout_id(workout, location, attempts=5, debug=False, **kwargs):
|
||||||
|
authorizationstring = str('Bearer ' + workout.user.tptoken)
|
||||||
|
headers = {'Authorization': authorizationstring,
|
||||||
|
'user-agent': 'sanderroosendaal',
|
||||||
|
'Content-Type': 'application/json'}
|
||||||
|
response = requests.get(location, headers=headers, params={})
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
status = response.json()['Status']
|
||||||
|
if status == 'Success':
|
||||||
|
tpid = response.json()['WorkoutIds'][0]
|
||||||
|
workout.uploadedtotp = tpid
|
||||||
|
workout.save()
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def instroke_static(w, metric, debug=False, **kwargs):
|
def instroke_static(w, metric, debug=False, **kwargs):
|
||||||
f1 = w.csvfilename[6:-4]
|
f1 = w.csvfilename[6:-4]
|
||||||
|
|||||||
@@ -116,6 +116,10 @@ def mocked_session(*args, **kwargs):
|
|||||||
def __init__(self, json_data, status_code):
|
def __init__(self, json_data, status_code):
|
||||||
self.json_data = json_data
|
self.json_data = json_data
|
||||||
self.status_code = status_code
|
self.status_code = status_code
|
||||||
|
self.reason = 'mock reason'
|
||||||
|
self.headers = {
|
||||||
|
'Location':'MockLocation',
|
||||||
|
}
|
||||||
self.ok = True
|
self.ok = True
|
||||||
|
|
||||||
def json(self):
|
def json(self):
|
||||||
@@ -916,6 +920,9 @@ def mocked_requests(*args, **kwargs):
|
|||||||
self.json_data = json_data
|
self.json_data = json_data
|
||||||
self.status_code = status_code
|
self.status_code = status_code
|
||||||
self.ok = True
|
self.ok = True
|
||||||
|
self.headers = {
|
||||||
|
'Location':'MockLocation',
|
||||||
|
}
|
||||||
|
|
||||||
def json(self):
|
def json(self):
|
||||||
return self.json_data
|
return self.json_data
|
||||||
@@ -1132,7 +1139,7 @@ def mocked_requests(*args, **kwargs):
|
|||||||
uauserregex = r'.*?api\.ua\.com\/v7.1\/user\/self\/'
|
uauserregex = r'.*?api\.ua\.com\/v7.1\/user\/self\/'
|
||||||
uausertester = re.compile(uauserregex)
|
uausertester = re.compile(uauserregex)
|
||||||
|
|
||||||
tpuploadregex = r'.*?trainingpeaks\.com\/v1\/file'
|
tpuploadregex = r'.*?trainingpeaks\.com\/v3\/file'
|
||||||
tpuploadtester = re.compile(tpuploadregex)
|
tpuploadtester = re.compile(tpuploadregex)
|
||||||
|
|
||||||
garmindownloadregex = r'.*?garmin\.com\/mockfile?id=1'
|
garmindownloadregex = r'.*?garmin\.com\/mockfile?id=1'
|
||||||
@@ -1445,6 +1452,9 @@ class MockResponse:
|
|||||||
self.json_data = json_data
|
self.json_data = json_data
|
||||||
self.status_code = status_code
|
self.status_code = status_code
|
||||||
self.ok = True
|
self.ok = True
|
||||||
|
self.headers = {
|
||||||
|
'Location':'MockLocation',
|
||||||
|
}
|
||||||
|
|
||||||
def json(self):
|
def json(self):
|
||||||
return self.json_data
|
return self.json_data
|
||||||
|
|||||||
@@ -5,6 +5,14 @@ from django_rq import job
|
|||||||
# All the functionality needed to connect to Runkeeper
|
# All the functionality needed to connect to Runkeeper
|
||||||
from rowers.imports import *
|
from rowers.imports import *
|
||||||
from rowers.utils import dologging
|
from rowers.utils import dologging
|
||||||
|
from rowers.tasks import check_tp_workout_id
|
||||||
|
|
||||||
|
import django_rq
|
||||||
|
queue = django_rq.get_queue('default')
|
||||||
|
queuelow = django_rq.get_queue('low')
|
||||||
|
queuehigh = django_rq.get_queue('low')
|
||||||
|
|
||||||
|
from rowers.utils import myqueue
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
import gzip
|
import gzip
|
||||||
@@ -17,7 +25,8 @@ from rowsandall_app.settings import (
|
|||||||
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
|
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
|
||||||
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
|
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
|
||||||
TP_CLIENT_ID, TP_CLIENT_SECRET,
|
TP_CLIENT_ID, TP_CLIENT_SECRET,
|
||||||
TP_REDIRECT_URI, TP_CLIENT_KEY,TP_API_LOCATION
|
TP_REDIRECT_URI, TP_CLIENT_KEY,TP_API_LOCATION,
|
||||||
|
TP_OAUTH_LOCATION,
|
||||||
)
|
)
|
||||||
|
|
||||||
tpapilocation = TP_API_LOCATION
|
tpapilocation = TP_API_LOCATION
|
||||||
@@ -50,7 +59,6 @@ def do_refresh_token(refreshtoken):
|
|||||||
|
|
||||||
# Exchange access code for long-lived access token
|
# Exchange access code for long-lived access token
|
||||||
|
|
||||||
|
|
||||||
def get_token(code):
|
def get_token(code):
|
||||||
# client_auth = requests.auth.HTTPBasicAuth(TP_CLIENT_KEY, TP_CLIENT_SECRET)
|
# client_auth = requests.auth.HTTPBasicAuth(TP_CLIENT_KEY, TP_CLIENT_SECRET)
|
||||||
post_data = {
|
post_data = {
|
||||||
@@ -62,10 +70,13 @@ def get_token(code):
|
|||||||
}
|
}
|
||||||
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
"https://oauth.trainingpeaks.com/oauth/token",
|
TP_OAUTH_LOCATION+"/oauth/token/",
|
||||||
data=post_data, verify=False,
|
data=post_data, verify=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
return 0,0,0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
token_json = response.json()
|
token_json = response.json()
|
||||||
thetoken = token_json['access_token']
|
thetoken = token_json['access_token']
|
||||||
@@ -116,7 +127,7 @@ def tp_check(access_token): # pragma: no cover
|
|||||||
'authorization': 'Bearer %s' % access_token
|
'authorization': 'Bearer %s' % access_token
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = requests.post(tpapilocation+"/v1/info/version",
|
resp = requests.post(tpapilocation+"/v2/info/version",
|
||||||
headers=headers, verify=False)
|
headers=headers, verify=False)
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
@@ -147,17 +158,21 @@ def uploadactivity(access_token, filename, description='',
|
|||||||
"Data": base64.b64encode(data_gz.getvalue()).decode("ascii")
|
"Data": base64.b64encode(data_gz.getvalue()).decode("ascii")
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = requests.post(tpapilocation+"/v1/file",
|
#resp = requests.post(tpapilocation+"/v2/file/synchronous",
|
||||||
|
# data=json.dumps(data),
|
||||||
|
# headers=headers, verify=False)
|
||||||
|
|
||||||
|
resp = requests.post(tpapilocation+"/v3/file",
|
||||||
data=json.dumps(data),
|
data=json.dumps(data),
|
||||||
headers=headers, verify=False)
|
headers=headers, verify=False)
|
||||||
|
|
||||||
if resp.status_code != 200: # pragma: no cover
|
if resp.status_code not in (200, 202): # pragma: no cover
|
||||||
dologging('tp_export.log',resp.status_code)
|
dologging('tp_export.log',resp.status_code)
|
||||||
dologging('tp_export.log',resp.reason)
|
dologging('tp_export.log',resp.reason)
|
||||||
dologging('tp_export.log',json.dumps(data))
|
dologging('tp_export.log',json.dumps(data))
|
||||||
return 0, resp.reason, resp.status_code, headers
|
return 0, resp.reason, resp.status_code, headers
|
||||||
else:
|
else:
|
||||||
return resp.json()[0]["Id"], "ok", 200, ""
|
return 1, "ok", 200, resp.headers
|
||||||
|
|
||||||
return 0, 0, 0, 0 # pragma: no cover
|
return 0, 0, 0, 0 # pragma: no cover
|
||||||
|
|
||||||
@@ -194,6 +209,12 @@ def workout_tp_upload(user, w): # pragma: no cover
|
|||||||
tpid = res
|
tpid = res
|
||||||
w.save()
|
w.save()
|
||||||
os.remove(tcxfile)
|
os.remove(tcxfile)
|
||||||
|
|
||||||
|
job = myqueue(queuelow,
|
||||||
|
check_tp_workout_id,
|
||||||
|
w,
|
||||||
|
headers['Location'])
|
||||||
|
|
||||||
return 'Successfully synchronized to TrainingPeaks', tpid
|
return 'Successfully synchronized to TrainingPeaks', tpid
|
||||||
|
|
||||||
else: # no tcxfile
|
else: # no tcxfile
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
from rowsandall_app.settings import NK_OAUTH_LOCATION, ROJABO_OAUTH_LOCATION
|
from rowsandall_app.settings import (
|
||||||
|
NK_OAUTH_LOCATION, ROJABO_OAUTH_LOCATION,
|
||||||
|
TP_OAUTH_LOCATION,
|
||||||
|
)
|
||||||
|
|
||||||
from rowers.views.statements import *
|
from rowers.views.statements import *
|
||||||
from rowers.plannedsessions import get_dates_timeperiod
|
from rowers.plannedsessions import get_dates_timeperiod
|
||||||
@@ -49,6 +52,11 @@ def workout_tp_upload_view(request, id=0):
|
|||||||
w.uploadedtotp = res
|
w.uploadedtotp = res
|
||||||
w.save()
|
w.save()
|
||||||
os.remove(tcxfile)
|
os.remove(tcxfile)
|
||||||
|
job = myqueue(queuelow,
|
||||||
|
check_tp_workout_id,
|
||||||
|
w,
|
||||||
|
headers['Location'])
|
||||||
|
|
||||||
messages.info(request, 'Uploaded to TrainingPeaks')
|
messages.info(request, 'Uploaded to TrainingPeaks')
|
||||||
|
|
||||||
else: # pragma: no cover # no tcxfile
|
else: # pragma: no cover # no tcxfile
|
||||||
@@ -295,7 +303,7 @@ def rower_tp_authorize(request): # pragma: no cover
|
|||||||
"redirect_uri": TP_REDIRECT_URI,
|
"redirect_uri": TP_REDIRECT_URI,
|
||||||
"scope": "file:write",
|
"scope": "file:write",
|
||||||
}
|
}
|
||||||
url = "https://oauth.trainingpeaks.com/oauth/authorize/?" + \
|
url = TP_OAUTH_LOCATION+"oauth/authorize/?" + \
|
||||||
urllib.parse.urlencode(params)
|
urllib.parse.urlencode(params)
|
||||||
|
|
||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ from rowers.tasks import (
|
|||||||
handle_c2_async_workout,
|
handle_c2_async_workout,
|
||||||
handle_send_email_instantplan_notification,
|
handle_send_email_instantplan_notification,
|
||||||
handle_nk_async_workout,
|
handle_nk_async_workout,
|
||||||
|
check_tp_workout_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
from scipy.signal import savgol_filter
|
from scipy.signal import savgol_filter
|
||||||
|
|||||||
@@ -328,6 +328,11 @@ try:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
TP_API_LOCATION = "https://api.trainingpeaks.com"
|
TP_API_LOCATION = "https://api.trainingpeaks.com"
|
||||||
|
|
||||||
|
try:
|
||||||
|
TP_OAUTH_LOCATION = CFG['tp_oauth_location']
|
||||||
|
except KeyError:
|
||||||
|
TP_OAUTH_LOCATION = "https://oauth.trainingpeaks.com/oauth/token"
|
||||||
|
|
||||||
# RP3
|
# RP3
|
||||||
RP3_CLIENT_ID = CFG["rp3_client_id"]
|
RP3_CLIENT_ID = CFG["rp3_client_id"]
|
||||||
RP3_CLIENT_SECRET = CFG["rp3_client_secret"]
|
RP3_CLIENT_SECRET = CFG["rp3_client_secret"]
|
||||||
|
|||||||
Reference in New Issue
Block a user