Private
Public Access
1
0

done runkeeper

This commit is contained in:
Sander Roosendaal
2018-07-03 22:01:53 +02:00
parent ce53c29fee
commit 8da86e610d
7 changed files with 164 additions and 5 deletions
+5 -2
View File
@@ -1,5 +1,6 @@
# All the functionality needed to connect to Runkeeper # All the functionality needed to connect to Runkeeper
from rowers.imports import * from rowers.imports import *
import re
from rowsandall_app.settings import ( from rowsandall_app.settings import (
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
@@ -225,8 +226,10 @@ def createrunkeeperworkoutdata(w):
# upload # upload
def getidfromresponse(response): def getidfromresponse(response):
uri = response.headers["Location"] uri = response.headers["Location"]
id = uri[len(uri)-9:]
tester = re.compile('^\/fitnessActivities\/(\d+)$')
id = int(tester.match(uri).group(1))
return int(id) return int(id)
def geturifromid(access_token,id): def geturifromid(access_token,id):
+2 -2
View File
@@ -169,11 +169,11 @@ def get_workout(user,sporttracksid):
s = requests.get(url,headers=headers) s = requests.get(url,headers=headers)
data = s.json() data = s.json()
strokedata = pd.DataFrame.from_dict({ strokedata = pd.DataFrame.from_dict({
key: pd.Series(value) for key, value in data.items() key: pd.Series(value) for key, value in data.items()
}) })
return data,strokedata return data,strokedata
# Create Workout Data for upload to SportTracks # Create Workout Data for upload to SportTracks
+1 -1
View File
@@ -111,7 +111,7 @@
{% endif %} {% endif %}
{% else %} {% else %}
<div class="grid_1 alpha"> <div class="grid_1 alpha">
<a href="https://runkeeper.com/activity/{{ workout.uploadedtorunkeeper }}"> <a href="https://runkeeper.com/user/{{ rkuserid }}/activity/{{ workout.uploadedtorunkeeper }}">
<img src="/static/img/rkchecked.png" alt="Runkeeper icon" width="60" height="60"></a> <img src="/static/img/rkchecked.png" alt="Runkeeper icon" width="60" height="60"></a>
</div> </div>
{% endif %} {% endif %}
+1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+153
View File
@@ -82,6 +82,9 @@ def mocked_requests(*args, **kwargs):
stravaworkoutlist = json.load(open('rowers/testdata/stravaworkoutlist.txt')) stravaworkoutlist = json.load(open('rowers/testdata/stravaworkoutlist.txt'))
sporttracksworkoutlist = json.load(open('rowers/testdata/sporttracksworkouts.txt')) sporttracksworkoutlist = json.load(open('rowers/testdata/sporttracksworkouts.txt'))
rkworkoutlistjson = json.load(open('rowers/testdata/rkworkoutslist.txt','r'))
stravasummaryjson = json.load(open('rowers/testdata/stravaworkoutsummary.txt','r')) stravasummaryjson = json.load(open('rowers/testdata/stravaworkoutsummary.txt','r'))
stravatimejson = json.load(open('rowers/testdata/stravatimetestdata.txt','r')) stravatimejson = json.load(open('rowers/testdata/stravatimetestdata.txt','r'))
@@ -100,6 +103,10 @@ def mocked_requests(*args, **kwargs):
'cadence':stravaspmjson, 'cadence':stravaspmjson,
} }
ststrokesjson = json.load(open('rowers/testdata/sporttracksstrokedata.txt','r'))
rkstrokesjson = json.load(open('rowers/testdata/rkstrokes.txt','r'))
class MockResponse: class MockResponse:
def __init__(self, json_data, status_code): def __init__(self, json_data, status_code):
self.json_data = json_data self.json_data = json_data
@@ -108,6 +115,12 @@ def mocked_requests(*args, **kwargs):
def json(self): def json(self):
return self.json_data return self.json_data
class MockHeaderResponse:
def __init__(self, header_data, status_code):
self.headers = header_data
self.status_code = status_code
class MockSession: class MockSession:
def send(self,prepped): def send(self,prepped):
# prepped.url # prepped.url
@@ -129,6 +142,7 @@ def mocked_requests(*args, **kwargs):
c2tester = re.compile('.*?log\.concept2\.com') c2tester = re.compile('.*?log\.concept2\.com')
stravatester = re.compile('.*?strava\.com') stravatester = re.compile('.*?strava\.com')
sttester = re.compile('.*?sporttracks\.mobi') sttester = re.compile('.*?sporttracks\.mobi')
rktester = re.compile('.*?runkeeper\.com')
c2importregex = '.*?concept2.com\/api\/users\/me\/results\/\d+' c2importregex = '.*?concept2.com\/api\/users\/me\/results\/\d+'
c2importtester = re.compile(c2importregex) c2importtester = re.compile(c2importregex)
@@ -156,6 +170,54 @@ def mocked_requests(*args, **kwargs):
stworkoutlistregex = '.*?sporttracks\.mobi\/api\/v2\/fitnessActivities$' stworkoutlistregex = '.*?sporttracks\.mobi\/api\/v2\/fitnessActivities$'
stworkoutlisttester = re.compile(stworkoutlistregex) stworkoutlisttester = re.compile(stworkoutlistregex)
ststrokesregex = '.*?sporttracks\.mobi\/api\/v2\/fitnessActivities/\d+$'
ststrokestester = re.compile(ststrokesregex)
rkuploadregex = '.*?api\.runkeeper\.com\/fitnessActivities$'
rkuploadtester = re.compile(rkuploadregex)
rkuserregex = '.*?api\.runkeeper\.com\/user$'
rkusertester = re.compile(rkuserregex)
rkstrokesregex = '.*?api\.runkeeper\.com\/fitnessActivities/\d+$'
rkstrokestester = re.compile(rkstrokesregex)
if rktester.match(args[0]):
if 'token' in args[0]:
json_data = {
'access_token': 'TA3n1vrNjuQJWw0TdCDHnjSmrjIPULhTlejMIWqq',
'expires_in': 604800,
'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
}
return MockResponse(json_data,200)
if rkuploadtester.match(args[0]):
if 'data' in kwargs:
# post
header_data = {
'Location': '/fitnessActivities/12'
}
return MockHeaderResponse(header_data,200)
else:
json_data = rkworkoutlistjson
return MockResponse(json_data,200)
if rkusertester.match(args[0]):
json_data = {
"userID": 1234567890,
"profile": "/profile",
"settings": "/settings",
"fitness_activities": "/fitnessActivities",
"strength_training_activities": "/strengthTrainingActivities",
"background_activities": "/backgroundActivities",
"sleep": "/sleep",
"nutrition": "/nutrition",
"weight": "/weight",
"general_measurements": "/generalMeasurements",
"diabetes": "/diabetes",
"records": "/records",
"team": "/team"
}
return MockResponse(json_data, 200)
if rkstrokestester.match(args[0]):
return MockResponse(rkstrokesjson,200)
if sttester.match(args[0]): if sttester.match(args[0]):
if 'oauth2/token' in args[0]: if 'oauth2/token' in args[0]:
@@ -165,6 +227,8 @@ def mocked_requests(*args, **kwargs):
'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR' 'refresh_token': 'jHJhFzCfOOKB8oyiayubhLAlxaMkG3ruC1E8YxaR'
} }
return MockResponse(json_data,200) return MockResponse(json_data,200)
if ststrokestester.match(args[0]):
return MockResponse(ststrokesjson,200)
if stuploadtester.match(args[0]): if stuploadtester.match(args[0]):
json_data = { json_data = {
"uris": [ "uris": [
@@ -508,6 +572,95 @@ class STObjects(DjangoTestCase):
res = add_workout_from_data(self.u,1,data,data) res = add_workout_from_data(self.u,1,data,data)
class RunKeeperObjects(DjangoTestCase):
def setUp(self):
self.c = Client()
self.u = User.objects.create_user('john',
'sander@ds.ds',
'koeinsloot')
self.u.first_name = 'John'
self.u.last_name = 'Sander'
self.u.save()
self.r = Rower.objects.create(user=self.u,gdproptin=True,
gdproptindate=timezone.now()
)
self.r.runkeepertoken = '12'
self.r.save()
self.c.login(username='john',password='koeinsloot')
self.nu = datetime.datetime.now()
filename = 'rowers/testdata/testdata.csv'
rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2,
hrut1=self.r.ut1,hrat=self.r.at,
hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp)
row = rdata(filename,rower=rr)
totaldist = row.df['cum_dist'].max()
totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min()
totaltime = totaltime+row.df.ix[0,' ElapsedTime (sec)']
hours = int(totaltime/3600.)
minutes = int((totaltime - 3600.*hours)/60.)
seconds = int(totaltime - 3600.*hours - 60.*minutes)
tenths = int(10*(totaltime - 3600.*hours - 60.*minutes - seconds))
duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths)
workoutdate = row.rowdatetime.strftime('%Y-%m-%d')
workoutstarttime = row.rowdatetime.strftime('%H:%M:%S')
self.w = Workout.objects.create(
name='testworkout',workouttype='On-water',
user=self.r,date=self.nu.strftime('%Y-%m-%d'),
starttime=workoutstarttime,
startdatetime=row.rowdatetime,
duration=duration,distance=totaldist,
csvfilename=filename
)
@patch('rowers.runkeeperstuff.requests.post', side_effect=mocked_requests)
def test_runkeeper_callback(self, mock_post):
response = self.c.get('/runkeeper_callback?code=dsdoij232s',follow=True)
self.assertEqual(response.status_code, 200)
@patch('rowers.runkeeperstuff.requests.post', side_effect=mocked_requests)
@patch('rowers.runkeeperstuff.requests.get', side_effect=mocked_requests)
def test_runkeeper_upload(self, mock_get, mock_post):
response = self.c.get('/rowers/workout/1/runkeeperuploadw/')
self.assertRedirects(response,
expected_url = '/rowers/workout/1/export',
status_code=302,target_status_code=200)
self.assertEqual(response.url, '/rowers/workout/1/export')
self.assertEqual(response.status_code, 302)
@patch('rowers.runkeeperstuff.requests.get', side_effect=mocked_requests)
def test_runkeeper_list(self, mock_get):
response = self.c.get('/rowers/workout/runkeeperimport',follow=True)
self.assertEqual(response.status_code,200)
@patch('rowers.imports.requests.get', side_effect=mocked_requests)
def test_runkeeper_import(self, mock_get):
response = self.c.get('/rowers/workout/runkeeperimport/12/',follow=True)
self.assertRedirects(response,
expected_url='/rowers/workout/2/edit',
status_code=302,target_status_code=200)
self.assertEqual(response.status_code, 200)
class TestErrorPages(TestCase): class TestErrorPages(TestCase):
def test_error_handlers(self): def test_error_handlers(self):