Merge branch 'release/v18.2.7'
This commit is contained in:
@@ -93,6 +93,10 @@ def get_token(code):
|
||||
data=post_data,
|
||||
headers=headers)
|
||||
|
||||
if response.status_code != 200: # pragma: no cover
|
||||
dologging('polar.log','Getting token, got:')
|
||||
dologging('polar.log',response.status_code)
|
||||
dologging('polar.log',response.text)
|
||||
|
||||
try:
|
||||
token_json = response.json()
|
||||
@@ -100,11 +104,17 @@ def get_token(code):
|
||||
expires_in = token_json['expires_in']
|
||||
user_id = token_json['x_user_id']
|
||||
dologging('polar.log',response.status_code)
|
||||
dologging('polar.log',response.text)
|
||||
try:
|
||||
dologging('polar.log',response.text)
|
||||
except AttributeError:
|
||||
pass
|
||||
dologging('polar.log',token_json)
|
||||
except (KeyError,JSONDecodeError) as e:
|
||||
except (KeyError,JSONDecodeError) as e: # pragma: no cover
|
||||
dologging('polar.log',e)
|
||||
dologging('polar.log',response.text)
|
||||
try:
|
||||
dologging('polar.log',response.text)
|
||||
except AttributeError:
|
||||
pass
|
||||
thetoken = 0
|
||||
expires_in = 0
|
||||
user_id = 0
|
||||
@@ -112,7 +122,7 @@ def get_token(code):
|
||||
return [thetoken,expires_in,user_id]
|
||||
|
||||
# Make authorization URL including random string
|
||||
def make_authorization_url():
|
||||
def make_authorization_url(): # pragma: no cover
|
||||
# Generate a random string for the state parameter
|
||||
# Save it for use later to prevent xsrf attacks
|
||||
state = str(uuid4())
|
||||
@@ -127,16 +137,17 @@ def make_authorization_url():
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
def revoke_access(user):
|
||||
def revoke_access(user): # pragma: no cover
|
||||
headers = {
|
||||
'Authorization': 'Bearer {token}'.format(token=user.rower.polartoken)
|
||||
}
|
||||
|
||||
response = requests.delete('https://www.polaraccesslink.com/v3/users/{user-id}', params={
|
||||
'user-id':user.rower.polaruserid,
|
||||
}, headers = headers)
|
||||
response = requests.delete('https://www.polaraccesslink.com/v3/users/{userid}'.format(
|
||||
userid = user.rower.polaruserid
|
||||
), headers = headers)
|
||||
|
||||
dologging('polar.log',response.text)
|
||||
dologging('polar.log',response.reason)
|
||||
|
||||
return 1
|
||||
|
||||
@@ -156,7 +167,7 @@ def get_polar_notifications():
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=headers)
|
||||
except ConnectionError:
|
||||
except ConnectionError: # pragma: no cover
|
||||
response = {
|
||||
'status_code':400,
|
||||
}
|
||||
@@ -167,11 +178,14 @@ def get_polar_notifications():
|
||||
if response.status_code == 200:
|
||||
available_data = response.json()['available-user-data']
|
||||
dologging('polar.log',available_data)
|
||||
else:
|
||||
else: # pragma: no cover
|
||||
dologging('polar.log',response.status_code)
|
||||
dologging('polar.log',reponse.text)
|
||||
except AttributeError:
|
||||
dologging('polar.log',response.text)
|
||||
dologging('polar.log',response.text)
|
||||
except AttributeError: # pragma: no cover
|
||||
try:
|
||||
dologging('polar.log',response.text)
|
||||
except AttributeError:
|
||||
pass
|
||||
pass
|
||||
|
||||
return available_data
|
||||
@@ -181,7 +195,7 @@ from rowers.rower_rules import ispromember
|
||||
def get_all_new_workouts(available_data,testing=False):
|
||||
for record in available_data:
|
||||
dologging('polar.log',str(record))
|
||||
if testing:
|
||||
if testing: # pragma: no cover
|
||||
print(record)
|
||||
if record['data-type'] == 'EXERCISE':
|
||||
try:
|
||||
@@ -190,9 +204,9 @@ def get_all_new_workouts(available_data,testing=False):
|
||||
if r.polar_auto_import and ispromember(u):
|
||||
exercise_list = get_polar_workouts(u)
|
||||
dologging('polar.log',exercise_list)
|
||||
if testing:
|
||||
if testing: # pragma: no cover
|
||||
print(exercise_list)
|
||||
except Rower.DoesNotExist:
|
||||
except Rower.DoesNotExist: # pragma: no cover
|
||||
pass
|
||||
|
||||
return 1
|
||||
@@ -206,7 +220,7 @@ def get_polar_workouts(user):
|
||||
if (r.polartoken == '') or (r.polartoken is None):
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
return custom_exception_handler(401,s)
|
||||
elif (timezone.now()>r.polartokenexpirydate):
|
||||
elif (timezone.now()>r.polartokenexpirydate): # pragma: no cover
|
||||
s = "Token expired. Needs to refresh"
|
||||
dologging('polar.log',s)
|
||||
return custom_exception_handler(401,s)
|
||||
@@ -264,7 +278,7 @@ def get_polar_workouts(user):
|
||||
workouttype = 'other'
|
||||
try:
|
||||
workouttype = mytypes.polaraccesslink_sports[exercise_dict['detailed-sport-info']]
|
||||
except KeyError:
|
||||
except KeyError: # pragma: no cover
|
||||
dologging('polar.log',exercise_dict['detailed-sport-info'])
|
||||
dologging('polar.log',workouttype)
|
||||
try:
|
||||
@@ -305,7 +319,7 @@ def get_polar_workouts(user):
|
||||
)
|
||||
|
||||
dologging('polar.log',response.status_code)
|
||||
if response.status_code != 200:
|
||||
if response.status_code != 200: # pragma: no cover
|
||||
try:
|
||||
dologging('polar.log',response.text)
|
||||
except:
|
||||
@@ -316,7 +330,7 @@ def get_polar_workouts(user):
|
||||
pass
|
||||
|
||||
exercise_dict['filename'] = filename
|
||||
else:
|
||||
else: # pragma: no cover
|
||||
exercise_dict['filename'] = ''
|
||||
|
||||
exercise_list.append(exercise_dict)
|
||||
@@ -332,6 +346,39 @@ def get_polar_workouts(user):
|
||||
|
||||
return exercise_list
|
||||
|
||||
def register_user(user):
|
||||
r = Rower.objects.get(user=user)
|
||||
if (r.polartoken == '') or (r.polartoken is None):
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
return custom_exception_handler(401,s)
|
||||
elif (timezone.now()>r.polartokenexpirydate):
|
||||
s = "Token expired. Needs to refresh"
|
||||
return custom_exception_handler(401,s)
|
||||
|
||||
authorizationstring = str('Bearer ' + r.polartoken)
|
||||
headers = {
|
||||
'Content-Type': 'application/xml',
|
||||
'Authorization':authorizationstring,
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
params = {
|
||||
'member-id': str(user.id)
|
||||
}
|
||||
|
||||
url = baseurl+'/users'
|
||||
|
||||
dologging('polar.log','Registering user')
|
||||
response = requests.post(url,params=params,headers=headers)
|
||||
|
||||
if response.status_code != 200:
|
||||
dologging('polar.log',response.status_code)
|
||||
return {}
|
||||
|
||||
polar_user_data = response.json()
|
||||
|
||||
return polar_user_data
|
||||
|
||||
def get_polar_user_info(user,physical=False):
|
||||
r = Rower.objects.get(user=user)
|
||||
if (r.polartoken == '') or (r.polartoken is None):
|
||||
@@ -340,34 +387,34 @@ def get_polar_user_info(user,physical=False):
|
||||
elif (timezone.now()>r.polartokenexpirydate):
|
||||
s = "Token expired. Needs to refresh"
|
||||
return custom_exception_handler(401,s)
|
||||
else:
|
||||
authorizationstring = str('Bearer ' + r.polartoken)
|
||||
headers = {
|
||||
'Authorization':authorizationstring,
|
||||
'Accept': 'application/json'
|
||||
|
||||
authorizationstring = str('Bearer ' + r.polartoken)
|
||||
headers = {
|
||||
'Authorization':authorizationstring,
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
|
||||
params = {
|
||||
'user-id': r.polaruserid
|
||||
}
|
||||
|
||||
|
||||
params = {
|
||||
'user-id': r.polaruserid
|
||||
}
|
||||
|
||||
if not physical:
|
||||
url = baseurl+'/users/{userid}'.format(
|
||||
userid = r.polaruserid
|
||||
if not physical:
|
||||
url = baseurl+'/users/{userid}'.format(
|
||||
userid = r.polaruserid
|
||||
)
|
||||
else:
|
||||
url = 'https://www.polaraccesslink.com/v3/users/{userid}/physical-information-transactions/'.format(
|
||||
userid = r.polaruserid
|
||||
)
|
||||
else:
|
||||
url = 'https://www.polaraccesslink.com/v3/users/{userid}/physical-information-transactions/'.format(
|
||||
userid = r.polaruserid
|
||||
)
|
||||
|
||||
|
||||
if physical:
|
||||
response = requests.post(url, headers=headers)
|
||||
else:
|
||||
response = requests.get(url, headers=headers)
|
||||
if physical:
|
||||
response = requests.post(url, headers=headers)
|
||||
else:
|
||||
response = requests.get(url, headers=headers)
|
||||
|
||||
return response
|
||||
return response
|
||||
|
||||
|
||||
def get_polar_workout(user,id,transactionid):
|
||||
@@ -415,11 +462,15 @@ def get_polar_workout(user,id,transactionid):
|
||||
transactionid = transactionid,
|
||||
exerciseid = id
|
||||
)
|
||||
authorizationstring = str('Bearer ' + r.polartoken)
|
||||
headers2 = {
|
||||
'Authorization':authorizationstring,
|
||||
}
|
||||
|
||||
response = requests.get(url,headers = headers2)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.text
|
||||
result = response.content
|
||||
# commit transaction
|
||||
url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}'.format(
|
||||
transactionid = transactionid,
|
||||
@@ -427,9 +478,9 @@ def get_polar_workout(user,id,transactionid):
|
||||
)
|
||||
response = requests.put(url,headers=headers)
|
||||
dologging('polar.log','Committing transaction on {url}'.format(url=url))
|
||||
else:
|
||||
else: # pragma: no cover
|
||||
result = None
|
||||
|
||||
return result
|
||||
|
||||
return None
|
||||
return None # pragma: no cover
|
||||
|
||||
@@ -768,6 +768,25 @@ def mocked_requests(*args, **kwargs):
|
||||
]
|
||||
}
|
||||
|
||||
polar_user_data = {
|
||||
"polar-user-id": 475,
|
||||
"member-id": "i09u9ujj",
|
||||
"registration-date": "2011-10-14T12:50:37.000Z",
|
||||
"first-name": "Eka",
|
||||
"last-name": "Toka",
|
||||
"birthdate": "1985-09-06",
|
||||
"gender": "MALE",
|
||||
"weight": 66,
|
||||
"height": 170,
|
||||
"field": [
|
||||
{
|
||||
"value": "2",
|
||||
"index": 0,
|
||||
"name": "number-of-children"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
polar_exercise_dict = {
|
||||
"id": 1937529874,
|
||||
"upload-time": "2008-10-13T10:40:02Z",
|
||||
@@ -1021,6 +1040,7 @@ def mocked_requests(*args, **kwargs):
|
||||
|
||||
|
||||
polartester = re.compile(r'.*?polaraccesslink\.com')
|
||||
polarremotetester = re.compile(r'.*?polarremote\.com')
|
||||
c2tester = re.compile(r'.*?log\.concept2\.com')
|
||||
stravatester = re.compile(r'.*?strava\.com')
|
||||
sttester = re.compile(r'.*?sporttracks\.mobi')
|
||||
@@ -1041,6 +1061,12 @@ def mocked_requests(*args, **kwargs):
|
||||
polartcxregex = r'.*?polaraccesslink\.com\/.*\/(\d+)\/tcx'
|
||||
polartcxtester = re.compile(polartcxregex)
|
||||
|
||||
polaruserregex = r'.*?polaraccesslink\.com\/.*\/users$'
|
||||
polarusertester = re.compile(polaruserregex)
|
||||
|
||||
polarnotificationregex = r'.*polaraccesslink\.com\/.*\/notifications'
|
||||
polarnotificationtester = re.compile(polarnotificationregex)
|
||||
|
||||
c2importregex = r'.*?concept2.com\/api\/users\/me\/results\/\d+'
|
||||
c2importtester = re.compile(c2importregex)
|
||||
|
||||
@@ -1134,8 +1160,35 @@ def mocked_requests(*args, **kwargs):
|
||||
json_data = stravaathletejson
|
||||
return MockResponse(json_data,200)
|
||||
|
||||
if polarremotetester.match(args[0]):
|
||||
json_data = {
|
||||
'access_token':'aap',
|
||||
'expires_in':31535999,
|
||||
'x_user_id':475,
|
||||
}
|
||||
return MockResponse(json_data,200)
|
||||
|
||||
if polartester.match(args[0]):
|
||||
if polartcxtester.match(args[0]):
|
||||
if polarnotificationtester.match(args[0]):
|
||||
json_data = {
|
||||
"available-user-data": [
|
||||
{
|
||||
"user-id": 475,
|
||||
"data-type": "ACTIVITY_SUMMARY",
|
||||
"url": "https://www.polaraccesslink.com/v3/users/475/activity-transactions"
|
||||
},
|
||||
{
|
||||
'user-id': 475,
|
||||
'data-type': 'EXERCISE',
|
||||
'url': 'https://polaraccesslink.com/v3/users/40273947/exercise-transactions'
|
||||
}
|
||||
]
|
||||
}
|
||||
return MockResponse(json_data,200)
|
||||
elif polarusertester.match(args[0]):
|
||||
json_data = polar_user_data
|
||||
return MockResponse(json_data,200)
|
||||
elif polartcxtester.match(args[0]):
|
||||
filename = 'rowers/tests/testdata/polar_response.tcx'
|
||||
return MockContentResponse(filename,200)
|
||||
elif polarexercisetester.match(args[0]):
|
||||
|
||||
@@ -774,6 +774,9 @@ class PolarObjects(DjangoTestCase):
|
||||
|
||||
self.r.polartoken = '12'
|
||||
self.r.polarrefreshtoken = '123'
|
||||
self.r.polaruserid = 475
|
||||
self.r.rowerplan = 'pro'
|
||||
self.r.polar_auto_import = True
|
||||
self.r.polartokenexpirydate = arrow.get(datetime.datetime.now()+datetime.timedelta(days=100)).datetime
|
||||
|
||||
|
||||
@@ -821,6 +824,34 @@ class PolarObjects(DjangoTestCase):
|
||||
res = polarstuff.get_polar_workouts(self.r.user)
|
||||
self.assertEqual(len(res),2)
|
||||
|
||||
@patch('rowers.polarstuff.requests.post', side_effect=mocked_requests)
|
||||
@patch('rowers.polarstuff.requests.get', side_effect=mocked_requests)
|
||||
def test_polar_callback(self, mock_get, mock_post):
|
||||
response = self.c.get('/polarflowcallback?code=abcdef&state=12sdss',follow=True)
|
||||
|
||||
self.assertEqual(response.status_code,200)
|
||||
|
||||
@patch('rowers.polarstuff.requests.post', side_effect=mocked_requests)
|
||||
@patch('rowers.polarstuff.requests.get', side_effect=mocked_requests)
|
||||
def test_polar_notifications(self, mock_get, mock_post):
|
||||
data = polarstuff.get_polar_notifications()
|
||||
|
||||
self.assertEqual(data[0]['user-id'],475)
|
||||
|
||||
response = polarstuff.get_all_new_workouts(data)
|
||||
self.assertEqual(response,1)
|
||||
|
||||
@patch('rowers.polarstuff.requests.post', side_effect=mocked_requests)
|
||||
@patch('rowers.polarstuff.requests.get', side_effect=mocked_requests)
|
||||
def test_polar_get_workout(self, mock_get, mock_post):
|
||||
transaction_id = 240522162
|
||||
id = 1937529874
|
||||
|
||||
response = polarstuff.get_polar_workout(self.u, id, transaction_id)
|
||||
self.assertEqual(len(response),14836)
|
||||
|
||||
|
||||
|
||||
#@pytest.mark.django_db
|
||||
@override_settings(TESTING=True)
|
||||
class RP3Objects(DjangoTestCase):
|
||||
|
||||
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
Binary file not shown.
@@ -200,7 +200,7 @@ def rower_strava_authorize(request): # pragma: no cover
|
||||
|
||||
# Polar Authorization
|
||||
@login_required()
|
||||
def rower_polar_authorize(request):
|
||||
def rower_polar_authorize(request): # pragma: no cover
|
||||
|
||||
state = str(uuid4())
|
||||
|
||||
@@ -413,14 +413,14 @@ def rower_process_polarcallback(request):
|
||||
|
||||
error = request.GET.get('error','no error')
|
||||
dologging('polar.log','Callback: {error}'.format(error=error))
|
||||
if error != 'no error':
|
||||
if error != 'no error': # pragma: no cover
|
||||
messages.error(request,error)
|
||||
url = reverse('rower_exportsettings_view')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
try:
|
||||
code = request.GET['code']
|
||||
except MultiValueDictKeyError:
|
||||
except MultiValueDictKeyError: # pragma: no cover
|
||||
try:
|
||||
message = request.GET['error']
|
||||
except MultiValueDictKeyError:
|
||||
@@ -432,6 +432,15 @@ def rower_process_polarcallback(request):
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
access_token, expires_in, user_id = polarstuff.get_token(code)
|
||||
polar_user_data = polarstuff.register_user(request.user)
|
||||
|
||||
try:
|
||||
user_id2 = polar_user_data['polar-user-id']
|
||||
except KeyError:
|
||||
user_id2 = 0
|
||||
|
||||
if user_id2 != user_id:
|
||||
messages.error(request,'Polar User ID error')
|
||||
|
||||
expirydatetime = timezone.now()+datetime.timedelta(seconds=expires_in)
|
||||
|
||||
@@ -442,8 +451,11 @@ def rower_process_polarcallback(request):
|
||||
|
||||
r.save()
|
||||
|
||||
successmessage = "Tokens stored. Good to go. Please check your import/export settings"
|
||||
messages.info(request,successmessage)
|
||||
if user_id2 == user_id:
|
||||
successmessage = "Tokens stored. Good to go. Please check your import/export settings"
|
||||
messages.info(request,successmessage)
|
||||
else:
|
||||
messages.error(request,"Please contact support@rowsandall.com for help.")
|
||||
url = reverse('rower_exportsettings_view')
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user