# 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 import time # 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 import sys import urllib from requests import Request, Session 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): scope = "results:write,user:read" 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'} url = "https://log.concept2.com/oauth/access_token" s = Session() req = Request('POST',url, data=post_data, headers=headers) # response = requests.post("https://log.concept2.com/oauth/access_token", # data=post_data, # data=post_data, # headers=headers) prepped = req.prepare() prepped.body+="&scope=" prepped.body+=scope response = s.send(prepped) token_json = response.json() try: thetoken = token_json['access_token'] expires_in = token_json['expires_in'] refresh_token = token_json['refresh_token'] except: with open("media/c2errors.log","a") as errorlog: errorstring = str(sys.exc_info()[0]) timestr = time.strftime("%Y%m%d-%H%M%S") errorlog.write(timestr+errorstring+"\r\n") errorlog.write(str(token_json)+"\r\n") thetoken = None expires_in = None refresh_token = None return [thetoken,expires_in,refresh_token] def get_token(code): scope = "user:read,results:write" client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET) post_data = {"grant_type": "authorization_code", "code": code, # "scope": scope, "redirect_uri": C2_REDIRECT_URI, "client_secret": C2_CLIENT_SECRET, "client_id":C2_CLIENT_ID, } headers = {'user-agent': 'sanderroosendaal'} url = "https://log.concept2.com/oauth/access_token" s = Session() req = Request('POST',url, data=post_data, headers=headers) prepped = req.prepare() prepped.body+="&scope=" prepped.body+=scope response = s.send(prepped) # 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()) scope = "user:read,results:write" params = {"client_id": CLIENT_ID, "response_type": "code", "redirect_uri": REDIRECT_URI} url = "https://log.concept2.com/oauth/authorize?"+ urllib.urlencode(params) url += "&scope="+scope 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