from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals from __future__ import unicode_literals, absolute_import # All the functionality needed to connect to Strava # Python import oauth2 as oauth import cgi import requests import requests.auth import json from django.utils import timezone from datetime import datetime import numpy as np from dateutil import parser import time import math from math import sin,cos,atan2,sqrt import os,sys import gzip import base64 import yaml from uuid import uuid4 # 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 from rowers.models import Rower,Workout import rowers.dataprep as dataprep from rowers.dataprep import columndict from io import StringIO import stravalib from stravalib.exc import ActivityUploadFailed,TimeoutExceeded from django_mailbox.models import Message,Mailbox,MessageAttachment from rowsandall_app.settings import ( POLAR_CLIENT_ID, POLAR_REDIRECT_URI, POLAR_CLIENT_SECRET, ) #baseurl = 'https://polaraccesslink.com/v3-example' baseurl = 'https://polaraccesslink.com/v3' from rowers.utils import NoTokenError, custom_exception_handler import rowers.mytypes as mytypes # Exchange access code for long-lived access token def get_token(code): post_data = {"grant_type": "authorization_code", "code": code, "redirect_uri": POLAR_REDIRECT_URI, } auth_string = '{id}:{secret}'.format( id= POLAR_CLIENT_ID, secret=POLAR_CLIENT_SECRET ) try: headers = { 'Authorization': 'Basic %s' % base64.b64encode(auth_string) } print(headers,'aa') except TypeError: headers = { 'Authorization': 'Basic %s' % base64.b64encode( bytes(auth_string,'utf-8')).decode('utf-8') } response = requests.post("https://polarremote.com/v2/oauth2/token", data=post_data, headers=headers) try: token_json = response.json() thetoken = token_json['access_token'] expires_in = token_json['expires_in'] user_id = token_json['x_user_id'] except KeyError: thetoken = 0 expires_in = 0 user_id = 0 return [thetoken,expires_in,user_id] # Make authorization URL including random string def make_authorization_url(): # Generate a random string for the state parameter # Save it for use later to prevent xsrf attacks state = str(uuid4()) params = {"client_id": POLAR_CLIENT_ID, "response_type": "code", "redirect_uri": POLAR_REDIRECT_URI, "scope":"write"} import urllib url = "https://flow.polar.com/oauth2/authorization" +urllib.parse.urlencode(params) return HttpResponseRedirect(url) def get_polar_notifications(): url = baseurl+'/notifications' state = str(uuid4()) auth_string = '{id}:{secret}'.format( id= POLAR_CLIENT_ID, secret=POLAR_CLIENT_SECRET ) try: headers = { 'Authorization': 'Basic %s' % base64.b64encode(auth_string) } except TypeError: headers = { 'Authorization': 'Basic %s' % base64.b64encode( bytes(auth_string,'utf-8')).decode('utf-8') } response = requests.get(url, headers=headers) available_data = [] if response.status_code == 200: available_data = response.json()['available-user-data'] return available_data from rowers.rower_rules import ispromember def get_all_new_workouts(available_data,testing=False): for record in available_data: if testing: print(record) if record['data-type'] == 'EXERCISE': try: r = Rower.objects.get(polaruserid=record['user-id']) u = r.user if r.polar_auto_import and ispromember(u): exercise_list = get_polar_workouts(u) if testing: print(exercise_list) except Rower.DoesNotExist: pass return 1 def get_polar_workouts(user): r = Rower.objects.get(user=user) exercise_list = [] 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) else: authorizationstring = str('Bearer ' + r.polartoken) headers = {'Authorization':authorizationstring, 'Accept': 'application/json'} headers2 = { 'Authorization':authorizationstring, } url = baseurl+'/users/{userid}/exercise-transactions'.format( userid = r.polaruserid ) response = requests.post(url, headers=headers) if response.status_code == 201: workoutsbox = Mailbox.objects.filter(name='workouts')[0] uploadoptions = { 'makeprivate':False, } bodyyaml = yaml.safe_dump( uploadoptions, default_flow_style=False ) transactionid = response.json()['transaction-id'] url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}'.format( transactionid = transactionid, userid = r.polaruserid ) response = requests.get(url, headers=headers) if response.status_code == 200: exerciseurls = response.json()['exercises'] for exerciseurl in exerciseurls: response = requests.get(exerciseurl,headers=headers) if response.status_code == 200: exercise_dict = response.json() tcxuri = exerciseurl+'/tcx' response = requests.get(tcxuri,headers=headers2) if response.status_code == 200: filename = 'media/mailbox_attachments/{code}_{id}.tcx'.format( id = exercise_dict['id'], code = uuid4().hex[:16] ) with open(filename,'wb') as fop: fop.write(response.content) msg = Message(mailbox=workoutsbox, from_header=user.email, subject = 'Import from Polar Flow', body=bodyyaml) msg.save() a = MessageAttachment(message=msg,document=filename[6:]) a.save() exercise_dict['filename'] = filename else: exercise_dict['filename'] = '' exercise_list.append(exercise_dict) # commit transaction requests.put(url, headers=headers) return exercise_list def get_polar_user_info(user,physical=False): 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) else: authorizationstring = str('Bearer ' + r.polartoken) headers = { 'Authorization':authorizationstring, 'Accept': 'application/json' } params = { 'user-id': 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 ) if physical: response = requests.post(url, headers=headers) else: response = requests.get(url, headers=headers) return response def get_polar_workout(user,id,transactionid): 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) else: authorizationstring = str('Bearer ' + r.polartoken) headers = { 'Authorization':authorizationstring, 'Accept': 'application/json' } url = baseurl+'/users/{userid}/exercise-transactions'.format( userid = r.polaruserid ) response = requests.post(url, headers=headers) if response.status_code == 201: transactionid = response.json()['transaction-id'] url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}'.format( transactionid = transactionid, userid = r.polaruserid ) response = requests.get(url, headers=headers) if response.status_code == 200: exerciseurls = response.json()['exercises'] for exerciseurl in exerciseurls: response = requests.get(exerciseurl,headers=headers) if response.status_code == 200: exercise_dict = response.json() thisid = exercise_dict['id'] if thisid == id: url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}/exercises/{exerciseid}/tcx'.format( userid = r.polaruserid, transactionid = transactionid, exerciseid = id ) response = requests.get(url,headers = headers2) if response.status_code == 200: result = response.text # commit transaction response = requests.put(url,headers=headers) else: result = None return result return None