rp3, untested
This commit is contained in:
252
rowers/integrations/rp3.py
Normal file
252
rowers/integrations/rp3.py
Normal file
@@ -0,0 +1,252 @@
|
||||
from .integrations import SyncIntegration, NoTokenError
|
||||
from rowers.models import User, Rower, Workout, TombStone
|
||||
|
||||
from rowers.tasks import handle_rp3_async_workout
|
||||
from rowsandall_app.settings import (
|
||||
RP3_CLIENT_ID, RP3_CLIENT_KEY, RP3_REDIRECT_URI, RP3_CLIENT_SECRET,
|
||||
UPLOAD_SERVICE_URL, UPLOAD_SERVICE_SECRET
|
||||
)
|
||||
|
||||
from rowers.utils import myqueue, NoTokenError, dologging, uniqify
|
||||
from django.utils import timezone
|
||||
import requests
|
||||
import pandas as pd
|
||||
import arrow
|
||||
import django_rq
|
||||
queue = django_rq.get_queue('default')
|
||||
queuelow = django_rq.get_queue('low')
|
||||
queuehigh = django_rq.get_queue('high')
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
graphql_url = "https://rp3rowing-app.com/graphql"
|
||||
|
||||
|
||||
class RP3Integration(SyncIntegration):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RP3Integration, self).__init__(*args, **kwargs)
|
||||
self.oauth_data = {
|
||||
'client_id': RP3_CLIENT_ID,
|
||||
'client_secret': RP3_CLIENT_SECRET,
|
||||
'redirect_uri': RP3_REDIRECT_URI,
|
||||
'autorization_uri': "https://rp3rowing-app.com/oauth/authorize?",
|
||||
'content_type': 'application/x-www-form-urlencoded',
|
||||
# 'content_type': 'application/json',
|
||||
'tokenname': 'rp3token',
|
||||
'refreshtokenname': 'rp3refreshtoken',
|
||||
'expirydatename': 'rp3tokenexpirydate',
|
||||
'bearer_auth': False,
|
||||
'base_url': "https://rp3rowing-app.com/oauth/token",
|
||||
'scope': 'read,write',
|
||||
}
|
||||
|
||||
|
||||
def createworkoutdata(self, w, *args, **kwargs):
|
||||
return None
|
||||
|
||||
|
||||
def workout_export(self, workout, *args, **kwargs) -> str:
|
||||
pass
|
||||
|
||||
|
||||
def get_workouts(self, *args, **kwargs) -> int:
|
||||
auth_token = self.open()
|
||||
|
||||
r = self.rower
|
||||
workouts_json = self.get_workout_list_json()
|
||||
|
||||
workouts_list = pd.json_normalize(workouts_json['data']['workouts'])
|
||||
|
||||
try:
|
||||
rp3ids = workouts_list['id'].values
|
||||
workouts_list.set_index('id',inpace=True)
|
||||
except (KeyError, IndexError):
|
||||
return 0
|
||||
|
||||
knownrp3ids = uniqify([
|
||||
w.uploadedtorp3 for w in Workout.objects.filter(user=rower)
|
||||
])
|
||||
|
||||
dologging('rp3_import.log',rp3ids)
|
||||
|
||||
newids = [rp3id for rp3id in rp3ids if rp3id not in knownrp3ids]
|
||||
|
||||
dologging('rp3_import.log',newids)
|
||||
|
||||
for id in newids:
|
||||
startdatetime = workouts_list.loc[id, 'executed_at_ios8601']
|
||||
dologging('rp3_import.log', startdatetime)
|
||||
|
||||
_ = myqueue(
|
||||
queuehigh,
|
||||
handle_rp3_async_workout,
|
||||
self.user.id,
|
||||
auth_token,
|
||||
id,
|
||||
startdatetime,
|
||||
20,
|
||||
{'timezone':self.rower.defaulttimezone}
|
||||
)
|
||||
|
||||
return 1
|
||||
|
||||
def get_workout(self, id, *args, **kwargs) -> int:
|
||||
startdatetime = kwargs.get('startdatetime', None)
|
||||
if not startdatetime:
|
||||
startdatetime = str(timezone.now())
|
||||
|
||||
auth_token = self.open()
|
||||
_ = myqueue(
|
||||
queuehigh,
|
||||
handle_rp3_async_workout,
|
||||
self.user.id,
|
||||
auth_token,
|
||||
id,
|
||||
startdatetime,
|
||||
20,
|
||||
timezone = self.rower.defaulttimezone
|
||||
)
|
||||
|
||||
def get_workout_schema(self, *args, **kwargs) -> dict:
|
||||
auth_token = self.open()
|
||||
headers = {'Authorization': 'Bearer ' + auth_token}
|
||||
get_schema = """{
|
||||
__type(name:"Workout") {
|
||||
name
|
||||
fields {
|
||||
name
|
||||
description
|
||||
type {
|
||||
name
|
||||
kind
|
||||
ofType {
|
||||
name
|
||||
kind
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
|
||||
response = requests.post(
|
||||
url = graphql_url,
|
||||
headers=headers,
|
||||
json={'query':get_schema}
|
||||
)
|
||||
return response.json()
|
||||
|
||||
def get_workout_list_json(self, *args, **kwargs) -> dict:
|
||||
auth_token = self.open()
|
||||
r = self.rower
|
||||
|
||||
headers = {'Authorization': 'Bearer ' + auth_token}
|
||||
|
||||
get_workouts_list = """{
|
||||
workouts{
|
||||
id
|
||||
executed_at_iso8601
|
||||
}
|
||||
}"""
|
||||
|
||||
response = requests.post(
|
||||
url=graphql_url,
|
||||
headers=headers,
|
||||
json={'query': get_workouts_list}
|
||||
)
|
||||
|
||||
if (response.status_code != 200): # pragma: no cover
|
||||
raise NoTokenError("Need to authorize")
|
||||
|
||||
return response.json()
|
||||
|
||||
def get_workout_list(self, *args, **kwargs) -> list:
|
||||
r = self.rower
|
||||
|
||||
workouts_json = self.get_workout_list_json(*args, **kwargs)
|
||||
|
||||
workouts_list = pd.json_normalize(workouts_json['data']['workouts'])
|
||||
|
||||
knownrp3ids = uniqify([
|
||||
w.uploadedtorp3 for w in Workout.objects.filter(user=r)
|
||||
])
|
||||
|
||||
workouts = []
|
||||
|
||||
for key, data in workouts_list.iterrows():
|
||||
print(data)
|
||||
try:
|
||||
i = data['id']
|
||||
except KeyError: # pragma: no cover
|
||||
i = 0
|
||||
if i in knownrp3ids: # pragma: no cover
|
||||
nnn = ''
|
||||
else:
|
||||
nnn = 'NEW'
|
||||
|
||||
try:
|
||||
s = arrow.get(data['executed_at_iso8601']).isoformat()
|
||||
except KeyError: # pragma: no cover
|
||||
s = ''
|
||||
|
||||
keys = ['id', 'distance', 'duration', 'starttime',
|
||||
'rowtype', 'source', 'name', 'new']
|
||||
values = [i, '', '', s, '', 'rp3', '', nnn]
|
||||
|
||||
res = dict(zip(keys, values))
|
||||
|
||||
workouts.append(res)
|
||||
|
||||
|
||||
return workouts
|
||||
|
||||
|
||||
def make_authorization_url(self, *args, **kwargs) -> str: # pragma: no cover
|
||||
return super(RP3Integration, self).make_authorization_url(*args, **krags)
|
||||
|
||||
def get_token(self, code, *args, **kwargs) -> (str, int, str):
|
||||
post_data = {
|
||||
"client_id": RP3_CLIENT_KEY,
|
||||
"grant_type": "authorization_code",
|
||||
"code": code,
|
||||
"redirect_uri": RP3_REDIRECT_URI,
|
||||
"client_secret": RP3_CLIENT_SECRET,
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
"https://rp3rowing-app.com/oauth/token",
|
||||
data=post_data, verify=False,
|
||||
)
|
||||
|
||||
try:
|
||||
token_json = response.json()
|
||||
thetoken = token_json['access_token']
|
||||
expires_in = token_json['expires_in']
|
||||
refresh_token = token_json['refresh_token']
|
||||
except KeyError:
|
||||
thetoken = ""
|
||||
expires_in = 0
|
||||
refresh_token = ""
|
||||
|
||||
return thetoken, expires_in, refresh_token
|
||||
|
||||
|
||||
def open(self, *args, **kwargs) -> str:
|
||||
tokenexpirydate = self.user.rower.rp3tokenexpirydate
|
||||
if tokenexpirydate is None:
|
||||
raise NoTokenError("No Token")
|
||||
if tokenexpirydate is not None and timezone.now()-timedelta(days=120)>tokenexpirydate:
|
||||
self.rower.rp3tokenexpirydate = timezone.now()-timedelta(days=1)
|
||||
self.rower.save()
|
||||
raise NoTokenError("No Token")
|
||||
return super(RP3Integration, self).open()
|
||||
|
||||
|
||||
def token_refresh(self, *args, **kwargs) -> str:
|
||||
return super(RP3Integration, self).token_refresh(*args, **kwargs)
|
||||
|
||||
|
||||
# just as a quick test during development
|
||||
u = User.objects.get(id=1)
|
||||
|
||||
integration_1 = RP3Integration(u)
|
||||
|
||||
Reference in New Issue
Block a user