Private
Public Access
1
0

Finishing light comments and cleanup

This commit is contained in:
Sander Roosendaal
2017-01-16 17:35:39 +01:00
parent 5f551528da
commit ef7cd92415
4 changed files with 71 additions and 88 deletions

View File

@@ -1,3 +1,5 @@
# All the functionality to connect to SportTracks
# Python # Python
import oauth2 as oauth import oauth2 as oauth
import cgi import cgi
@@ -31,6 +33,8 @@ from rowers.models import Rower,Workout
from rowsandall_app.settings import C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET, SPORTTRACKS_CLIENT_SECRET, SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI from rowsandall_app.settings import C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET, SPORTTRACKS_CLIENT_SECRET, SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI
# Custom exception handler, returns a 401 HTTP message
# with exception details in the json data
def custom_exception_handler(exc,message): def custom_exception_handler(exc,message):
response = { response = {
@@ -48,6 +52,7 @@ def custom_exception_handler(exc,message):
return res return res
# Refresh ST token using refresh token
def do_refresh_token(refreshtoken): def do_refresh_token(refreshtoken):
client_auth = requests.auth.HTTPBasicAuth(SPORTTRACKS_CLIENT_ID, SPORTTRACKS_CLIENT_SECRET) client_auth = requests.auth.HTTPBasicAuth(SPORTTRACKS_CLIENT_ID, SPORTTRACKS_CLIENT_SECRET)
post_data = {"grant_type": "refresh_token", post_data = {"grant_type": "refresh_token",
@@ -75,7 +80,7 @@ def do_refresh_token(refreshtoken):
return [thetoken,expires_in,refresh_token] return [thetoken,expires_in,refresh_token]
# Exchange ST access code for long-lived ST access token
def get_token(code): def get_token(code):
client_auth = requests.auth.HTTPBasicAuth(SPORTTRACKS_CLIENT_ID, SPORTTRACKS_CLIENT_SECRET) client_auth = requests.auth.HTTPBasicAuth(SPORTTRACKS_CLIENT_ID, SPORTTRACKS_CLIENT_SECRET)
post_data = {"grant_type": "authorization_code", post_data = {"grant_type": "authorization_code",
@@ -100,6 +105,7 @@ def get_token(code):
return [thetoken,expires_in,refresh_token] return [thetoken,expires_in,refresh_token]
# Make authorization URL including random string
def make_authorization_url(request): def make_authorization_url(request):
# Generate a random string for the state parameter # Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks # Save it for use later to prevent xsrf attacks
@@ -118,7 +124,7 @@ def make_authorization_url(request):
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
# This is token refresh. Looks for tokens in our database, then refreshes
def rower_sporttracks_token_refresh(user): def rower_sporttracks_token_refresh(user):
r = Rower.objects.get(user=user) r = Rower.objects.get(user=user)
res = do_refresh_token(r.sporttracksrefreshtoken) res = do_refresh_token(r.sporttracksrefreshtoken)
@@ -135,6 +141,7 @@ def rower_sporttracks_token_refresh(user):
r.save() r.save()
return r.sporttrackstoken return r.sporttrackstoken
# Get list of workouts available on SportTracks
def get_sporttracks_workout_list(user): def get_sporttracks_workout_list(user):
r = Rower.objects.get(user=user) r = Rower.objects.get(user=user)
if (r.sporttrackstoken == '') or (r.sporttrackstoken is None): if (r.sporttrackstoken == '') or (r.sporttrackstoken is None):
@@ -154,7 +161,7 @@ def get_sporttracks_workout_list(user):
return s return s
# Get workout summary data by SportTracks ID
def get_sporttracks_workout(user,sporttracksid): def get_sporttracks_workout(user,sporttracksid):
r = Rower.objects.get(user=user) r = Rower.objects.get(user=user)
if (r.sporttrackstoken == '') or (r.sporttrackstoken is None): if (r.sporttrackstoken == '') or (r.sporttrackstoken is None):
@@ -174,6 +181,7 @@ def get_sporttracks_workout(user,sporttracksid):
return s return s
# Create Workout Data for upload to SportTracks
def createsporttracksworkoutdata(w): def createsporttracksworkoutdata(w):
filename = w.csvfilename filename = w.csvfilename
try: try:
@@ -272,6 +280,8 @@ def createsporttracksworkoutdata(w):
return data return data
# Obtain SportTracks Workout ID from the response returned on successful
# upload
def getidfromresponse(response): def getidfromresponse(response):
t = json.loads(response.text) t = json.loads(response.text)
uri = t['uris'][0] uri = t['uris'][0]

View File

@@ -1,3 +1,5 @@
# All the functionality needed to connect to Strava
# Python # Python
import oauth2 as oauth import oauth2 as oauth
import cgi import cgi
@@ -30,6 +32,9 @@ import stravalib
from rowsandall_app.settings import C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET from rowsandall_app.settings import C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET
# Exponentially weighted moving average
# Used for data smoothing of the jagged data obtained by Strava
# See bitbucket issue 72
def ewmovingaverage(interval,window_size): def ewmovingaverage(interval,window_size):
# Experimental code using Exponential Weighted moving average # Experimental code using Exponential Weighted moving average
@@ -45,45 +50,11 @@ def ewmovingaverage(interval,window_size):
return interval2 return interval2
def geo_distance(lat1,lon1,lat2,lon2): from utils import geo_distance
""" Approximate distance and bearing between two points
defined by lat1,lon1 and lat2,lon2
This is a slight underestimate but is close enough for our purposes,
We're never moving more than 10 meters between trackpoints
Bearing calculation fails if one of the points is a pole.
"""
# radius of earth in km
R = 6373.0
# pi
pi = math.pi
lat1 = math.radians(lat1)
lat2 = math.radians(lat2)
lon1 = math.radians(lon1)
lon2 = math.radians(lon2)
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = R * c
tc1 = atan2(sin(lon2-lon1)*cos(lat2),
cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1))
tc1 = tc1 % (2*pi)
bearing = math.degrees(tc1)
return [distance,bearing]
# Custom exception handler, returns a 401 HTTP message
# with exception details in the json data
def custom_exception_handler(exc,message): def custom_exception_handler(exc,message):
response = { response = {
@@ -101,6 +72,7 @@ def custom_exception_handler(exc,message):
return res return res
# Exchange access code for long-lived access token
def get_token(code): def get_token(code):
client_auth = requests.auth.HTTPBasicAuth(STRAVA_CLIENT_ID, STRAVA_CLIENT_SECRET) client_auth = requests.auth.HTTPBasicAuth(STRAVA_CLIENT_ID, STRAVA_CLIENT_SECRET)
post_data = {"grant_type": "authorization_code", post_data = {"grant_type": "authorization_code",
@@ -118,7 +90,7 @@ def get_token(code):
return [thetoken] return [thetoken]
# Make authorization URL including random string
def make_authorization_url(request): def make_authorization_url(request):
# Generate a random string for the state parameter # Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks # Save it for use later to prevent xsrf attacks
@@ -134,6 +106,7 @@ def make_authorization_url(request):
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
# Get list of workouts available on Strava
def get_strava_workout_list(user): def get_strava_workout_list(user):
r = Rower.objects.get(user=user) r = Rower.objects.get(user=user)
if (r.stravatoken == '') or (r.stravatoken is None): if (r.stravatoken == '') or (r.stravatoken is None):
@@ -150,6 +123,7 @@ def get_strava_workout_list(user):
return s return s
# Get a Strava workout summary data and stroke data by ID
def get_strava_workout(user,stravaid): def get_strava_workout(user,stravaid):
r = Rower.objects.get(user=user) r = Rower.objects.get(user=user)
if (r.stravatoken == '') or (r.stravatoken is None): if (r.stravatoken == '') or (r.stravatoken is None):
@@ -236,6 +210,7 @@ def get_strava_workout(user,stravaid):
return [workoutsummary,df] return [workoutsummary,df]
# Generate Workout data for Strava (a TCX file)
def createstravaworkoutdata(w): def createstravaworkoutdata(w):
filename = w.csvfilename filename = w.csvfilename
try: try:
@@ -247,6 +222,8 @@ def createstravaworkoutdata(w):
return tcxfilename return tcxfilename
# Upload the TCX file to Strava and set the workout activity type
# to rowing on Strava
def handle_stravaexport(file,workoutname,stravatoken,description=''): def handle_stravaexport(file,workoutname,stravatoken,description=''):
# w = Workout.objects.get(id=workoutid) # w = Workout.objects.get(id=workoutid)
client = stravalib.Client(access_token=stravatoken) client = stravalib.Client(access_token=stravatoken)
@@ -264,12 +241,6 @@ def handle_stravaexport(file,workoutname,stravatoken,description=''):
errorlog.write(timestr+errorstring+"\r\n") errorlog.write(timestr+errorstring+"\r\n")
errorlog.write("stravastuff.py line 262\r\n") errorlog.write("stravastuff.py line 262\r\n")
# w.uploadedtostrava = res.id
# w.save()
# file.close()
return res.id return res.id

42
rowers/utils.py Normal file
View File

@@ -0,0 +1,42 @@
import math
def geo_distance(lat1,lon1,lat2,lon2):
""" Approximate distance and bearing between two points
defined by lat1,lon1 and lat2,lon2
This is a slight underestimate but is close enough for our purposes,
We're never moving more than 10 meters between trackpoints
Bearing calculation fails if one of the points is a pole.
(Hey, from the North pole you can walk South, East, North and end up
on the same spot!)
"""
# radius of our earth in km --> should be moved to settings if
# rowing takes off on other planets
R = 6373.0
# pi
pi = math.pi
lat1 = math.radians(lat1)
lat2 = math.radians(lat2)
lon1 = math.radians(lon1)
lon2 = math.radians(lon2)
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = R * c
tc1 = atan2(sin(lon2-lon1)*cos(lat2),
cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1))
tc1 = tc1 % (2*pi)
bearing = math.degrees(tc1)
return [distance,bearing]

View File

@@ -189,47 +189,7 @@ def splitstdata(lijst):
return [np.array(t),np.array(latlong)] return [np.array(t),np.array(latlong)]
from utils import geo_distance
def geo_distance(lat1,lon1,lat2,lon2):
""" Approximate distance and bearing between two points
defined by lat1,lon1 and lat2,lon2
This is a slight underestimate but is close enough for our purposes,
We're never moving more than 10 meters between trackpoints
Bearing calculation fails if one of the points is a pole.
(Hey, from the North pole you can walk South, East, North and end up
on the same spot!)
"""
# radius of our earth in km --> should be moved to settings if
# rowing takes off on other planets
R = 6373.0
# pi
pi = math.pi
lat1 = math.radians(lat1)
lat2 = math.radians(lat2)
lon1 = math.radians(lon1)
lon2 = math.radians(lon2)
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
distance = R * c
tc1 = atan2(sin(lon2-lon1)*cos(lat2),
cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1))
tc1 = tc1 % (2*pi)
bearing = math.degrees(tc1)
return [distance,bearing]
# Check if a user is a Pro member # Check if a user is a Pro member
def promember(user): def promember(user):