# Python import oauth2 as oauth import cgi import requests import requests.auth import json from django.utils import timezone from datetime import datetime from datetime import timedelta # Django from django.shortcuts import render_to_response from django.http import HttpResponseRedirect, HttpResponse,JsonResponse from django.conf import settings from django.contrib.auth import authenticate, login, logout from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required # Project # from .models import Profile from rowingdata import rowingdata import pandas as pd import numpy as np from rowers.models import Rower,Workout from rowsandall_app.settings import C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET class C2NoTokenError(Exception): def __init__(self,value): self.value=value def __str__(self): return repr(self.value) def custom_exception_handler(exc,message): response = { "errors": [ { "code": str(exc), "detail": message, } ] } res = HttpResponse(message) res.status_code = 401 res.json = json.dumps(response) return res def checkworkoutuser(user,workout): try: r = Rower.objects.get(user=user) return (workout.user == r) except Rower.DoesNotExist: return(False) def makeseconds(t): seconds = t.hour*3600.+t.minute*60.+t.second+0.1*int(t.microsecond/1.e5) return seconds def c2wc(weightclass): if (weightclass=="lwt"): res = "L" else: res = "H" return res def createc2workoutdata_as_splits(w): filename = w.csvfilename row = rowingdata(filename) # resize per minute df = row.df.groupby(lambda x:x/60).mean() averagehr = int(df[' HRCur (bpm)'].mean()) maxhr = int(df[' HRCur (bpm)'].max()) # adding diff, trying to see if this is valid t = 10*df.ix[:,' ElapsedTime (sec)'].diff().values t[0] = t[1] d = df.ix[:,' Horizontal (meters)'].diff().values d[0] = d[1] p = 10*df.ix[:,' Stroke500mPace (sec/500m)'].values t = t.astype(int) d = d.astype(int) p = p.astype(int) spm = df[' Cadence (stokes/min)'].astype(int) spm[0] = spm[1] hr = df[' HRCur (bpm)'].astype(int) split_data = [] for i in range(len(t)): thisrecord = {"time":t[i],"distance":d[i],"stroke_rate":spm[i], "heart_rate":{ "average:":hr[i] } } split_data.append(thisrecord) try: durationstr = datetime.strptime(str(w.duration),"%H:%M:%S.%f") except ValueError: durationstr = datetime.strptime(str(w.duration),"%H:%M:%S") data = { "type": w.workouttype, # "date": str(w.date)+" "+str(w.starttime), "date": w.startdatetime.isoformat(), "distance": int(w.distance), "time": int(10*makeseconds(durationstr)), "timezone": "Etc/UTC", "weight_class": c2wc(w.weightcategory), "comments": w.notes, "heart_rate": { "average": averagehr, "max": maxhr, }, "splits": split_data, } return data def createc2workoutdata_grouped(w): filename = w.csvfilename row = rowingdata(filename) # resize per minute df = row.df.groupby(lambda x:x/10).mean() averagehr = int(df[' HRCur (bpm)'].mean()) maxhr = int(df[' HRCur (bpm)'].max()) # adding diff, trying to see if this is valid t = 10*df.ix[:,' ElapsedTime (sec)'].values t[0] = t[1] d = df.ix[:,' Horizontal (meters)'].values d[0] = d[1] p = 10*df.ix[:,' Stroke500mPace (sec/500m)'].values t = t.astype(int) d = d.astype(int) p = p.astype(int) spm = df[' Cadence (stokes/min)'].astype(int) spm[0] = spm[1] hr = df[' HRCur (bpm)'].astype(int) stroke_data = [] for i in range(len(t)): thisrecord = {"t":t[i],"d":d[i],"p":p[i],"spm":spm[i],"hr":hr[i]} stroke_data.append(thisrecord) try: durationstr = datetime.strptime(str(w.duration),"%H:%M:%S.%f") except ValueError: durationstr = datetime.strptime(str(w.duration),"%H:%M:%S") data = { "type": w.workouttype, # "date": str(w.date)+" "+str(w.starttime), "date": w.startdatetime.isoformat(), "distance": int(w.distance), "time": int(10*makeseconds(durationstr)), "weight_class": c2wc(w.weightcategory), "timezone": "Etc/UTC", "comments": w.notes, "heart_rate": { "average": averagehr, "max": maxhr, }, "stroke_data": stroke_data, } return data def createc2workoutdata(w): filename = w.csvfilename row = rowingdata(filename) averagehr = int(row.df[' HRCur (bpm)'].mean()) maxhr = int(row.df[' HRCur (bpm)'].max()) # adding diff, trying to see if this is valid t = 10*row.df.ix[:,'TimeStamp (sec)'].values-10*row.df.ix[0,'TimeStamp (sec)'] t[0] = t[1] d = 10*row.df.ix[:,' Horizontal (meters)'].values d[0] = d[1] p = abs(10*row.df.ix[:,' Stroke500mPace (sec/500m)'].values) p = np.clip(p,0,3600) t = t.astype(int) d = d.astype(int) p = p.astype(int) spm = row.df[' Cadence (stokes/min)'].astype(int) spm[0] = spm[1] hr = row.df[' HRCur (bpm)'].astype(int) stroke_data = [] for i in range(len(t)): thisrecord = {"t":t[i],"d":d[i],"p":p[i],"spm":spm[i],"hr":hr[i]} stroke_data.append(thisrecord) try: durationstr = datetime.strptime(str(w.duration),"%H:%M:%S.%f") except ValueError: durationstr = datetime.strptime(str(w.duration),"%H:%M:%S") data = { "type": w.workouttype, # "date": str(w.date)+" "+str(w.starttime), "date": w.startdatetime.isoformat(), "timezone": "Etc/UTC", "distance": int(w.distance), "time": int(10*makeseconds(durationstr)), "weight_class": c2wc(w.weightcategory), "comments": w.notes, "heart_rate": { "average": averagehr, "max": maxhr, }, "stroke_data": stroke_data, } return data def do_refresh_token(refreshtoken): client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET) post_data = {"grant_type": "refresh_token", "client_secret": C2_CLIENT_SECRET, "client_id":C2_CLIENT_ID, "refresh_token": refreshtoken, } headers = {'user-agent': 'sanderroosendaal'} response = requests.post("https://log.concept2.com/oauth/access_token", data=post_data, headers=headers) token_json = response.json() thetoken = token_json['access_token'] expires_in = token_json['expires_in'] refresh_token = token_json['refresh_token'] return [thetoken,expires_in,refresh_token] def get_token(code): client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET) post_data = {"grant_type": "authorization_code", "code": code, "redirect_uri": C2_REDIRECT_URI, "client_secret": C2_CLIENT_SECRET, "client_id":C2_CLIENT_ID, } headers = {'user-agent': 'sanderroosendaal'} response = requests.post("https://log.concept2.com/oauth/access_token", data=post_data, headers=headers) token_json = response.json() thetoken = token_json['access_token'] expires_in = token_json['expires_in'] refresh_token = token_json['refresh_token'] return [thetoken,expires_in,refresh_token] def make_authorization_url(request): # Generate a random string for the state parameter # Save it for use later to prevent xsrf attacks from uuid import uuid4 state = str(uuid4()) params = {"client_id": CLIENT_ID, "response_type": "code", "redirect_uri": REDIRECT_URI} import urllib url = "https://log.concept2.com/oauth/authorize?"+ urllib.urlencode(params) # url = "https://ssl.reddit.com/api/v1/authorize?" + urllib.urlencode(params) return HttpResponseRedirect(url) def get_c2_workout(user,c2id): r = Rower.objects.get(user=user) if (r.c2token == '') or (r.c2token is None): s = "Token doesn't exist. Need to authorize" return custom_exception_handler(401,s) elif (timezone.now()>r.tokenexpirydate): s = "Token expired. Needs to refresh." return custom_exception_handler(401,s) else: # ready to fetch. Hurray authorizationstring = str('Bearer ' + r.c2token) headers = {'Authorization': authorizationstring, 'user-agent': 'sanderroosendaal', 'Content-Type': 'application/json'} url = "https://log.concept2.com/api/users/me/results/"+str(c2id) s = requests.get(url,headers=headers) return s def get_c2_workout_strokes(user,c2id): r = Rower.objects.get(user=user) if (r.c2token == '') or (r.c2token is None): return custom_exception_handler(401,s) s = "Token doesn't exist. Need to authorize" elif (timezone.now()>r.tokenexpirydate): s = "Token expired. Needs to refresh." return custom_exception_handler(401,s) else: # ready to fetch. Hurray authorizationstring = str('Bearer ' + r.c2token) headers = {'Authorization': authorizationstring, 'user-agent': 'sanderroosendaal', 'Content-Type': 'application/json'} url = "https://log.concept2.com/api/users/me/results/"+str(c2id)+"/strokes" s = requests.get(url,headers=headers) return s def get_c2_workout_list(user): r = Rower.objects.get(user=user) if (r.c2token == '') or (r.c2token is None): s = "Token doesn't exist. Need to authorize" return custom_exception_handler(401,s) elif (timezone.now()>r.tokenexpirydate): s = "Token expired. Needs to refresh." return custom_exception_handler(401,s) else: # ready to fetch. Hurray authorizationstring = str('Bearer ' + r.c2token) headers = {'Authorization': authorizationstring, 'user-agent': 'sanderroosendaal', 'Content-Type': 'application/json'} url = "https://log.concept2.com/api/users/me/results" s = requests.get(url,headers=headers) return s def get_username(access_token): authorizationstring = str('Bearer ' + access_token) headers = {'Authorization': authorizationstring, 'user-agent': 'sanderroosendaal', 'Content-Type': 'application/json'} import urllib url = "https://log.concept2.com/api/users/me" response = requests.get(url,headers=headers) me_json = response.json() return me_json['data']['username'] def get_userid(access_token): authorizationstring = str('Bearer ' + access_token) headers = {'Authorization': authorizationstring, 'user-agent': 'sanderroosendaal', 'Content-Type': 'application/json'} import urllib url = "https://log.concept2.com/api/users/me" response = requests.get(url,headers=headers) me_json = response.json() return me_json['data']['id'] def process_callback(request): # need error handling code = request.GET['code'] access_token = get_token(code) username = get_username(access_token) return HttpResponse("got a user name: %s" % username) def workout_c2_upload(user,w): response = 'trying C2 upload' r = Rower.objects.get(user=user) if (r.c2token == '') or (r.c2token is None): s = "Token doesn't exist. Need to authorize" return custom_exception_handler(401,s) elif (timezone.now()>r.tokenexpirydate): s = "Token expired. Needs to refresh." return custom_exception_handler(401,s) else: # ready to upload. Hurray if (checkworkoutuser(user,w)): c2userid = get_userid(r.c2token) data = createc2workoutdata(w) # if (w.workouttype=='water'): # data = createc2workoutdata_as_splits(w) authorizationstring = str('Bearer ' + r.c2token) headers = {'Authorization': authorizationstring, 'user-agent': 'sanderroosendaal', 'Content-Type': 'application/json'} import urllib url = "https://log.concept2.com/api/users/%s/results" % (c2userid) response = requests.post(url,headers=headers,data=json.dumps(data)) if (response.status_code == 201): s= json.loads(response.text) c2id = s['data']['id'] w.uploadedtoc2 = c2id w.save() else: response = "You are not authorized to upload this workout" return response def rower_c2_token_refresh(user): r = Rower.objects.get(user=user) res = do_refresh_token(r.c2refreshtoken) access_token = res[0] expires_in = res[1] refresh_token = res[2] expirydatetime = timezone.now()+timedelta(seconds=expires_in) r = Rower.objects.get(user=user) r.c2token = access_token r.tokenexpirydate = expirydatetime r.c2refreshtoken = refresh_token r.save() return r.c2token