intervals.icu fixes
This commit is contained in:
@@ -1406,7 +1406,12 @@ def get_title_from_fit(filename):
|
||||
|
||||
return title
|
||||
|
||||
def get_workouttype_from_fit(filename, workouttype='water'):
|
||||
def get_workouttype_from_fit(filename, workouttype=None):
|
||||
if workouttype is None:
|
||||
workouttype = 'water'
|
||||
workouttype_orig = ''
|
||||
else:
|
||||
workouttype_orig = workouttype
|
||||
try:
|
||||
fitfile = FitFile(filename, check_crc=False)
|
||||
except FitHeaderError: # pragma: no cover
|
||||
@@ -1435,6 +1440,8 @@ def get_workouttype_from_fit(filename, workouttype='water'):
|
||||
workouttype = mytypes.fitmappinginv[fittype]
|
||||
except KeyError:
|
||||
pass
|
||||
if workouttype_orig in ['water', 'rower']:
|
||||
workouttype = workouttype_orig
|
||||
|
||||
return workouttype
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
from .integrations import SyncIntegration, NoTokenError, create_or_update_syncrecord, get_known_ids
|
||||
from rowers.models import Rower, User, Workout, TombStone, PlannedSession
|
||||
from rowingdata import rowingdata
|
||||
from rowingdata import FITParser as FP
|
||||
from rowingdata.otherparsers import FitSummaryData
|
||||
from rowers.rower_rules import user_is_not_basic, user_is_coachee
|
||||
|
||||
from rowers import mytypes
|
||||
|
||||
import shutil
|
||||
from rowers.rower_rules import is_workout_user, ispromember
|
||||
from rowers.utils import myqueue, dologging, custom_exception_handler
|
||||
from rowers.tasks import handle_intervals_getworkout
|
||||
@@ -22,7 +24,8 @@ import rowers.dataprep as dataprep
|
||||
from rowers.opaque import encoder
|
||||
|
||||
from rowsandall_app.settings import (
|
||||
INTERVALS_CLIENT_ID, INTERVALS_REDIRECT_URI, INTERVALS_CLIENT_SECRET, SITE_URL
|
||||
INTERVALS_CLIENT_ID, INTERVALS_REDIRECT_URI, INTERVALS_CLIENT_SECRET, SITE_URL,
|
||||
UPLOAD_SERVICE_SECRET, UPLOAD_SERVICE_URL
|
||||
)
|
||||
|
||||
import django_rq
|
||||
@@ -272,12 +275,103 @@ class IntervalsIntegration(SyncIntegration):
|
||||
|
||||
|
||||
return workouts
|
||||
|
||||
|
||||
def update_workout(self, id, *args, **kwargs) -> int:
|
||||
_ = self.open()
|
||||
r = self.rower
|
||||
|
||||
headers = {
|
||||
'Authorization': 'Bearer ' + r.intervals_token,
|
||||
}
|
||||
url = self.oauth_data['base_url'] + 'activity/' + str(id)
|
||||
response = requests.get(url, headers=headers)
|
||||
if response.status_code != 200:
|
||||
dologging('intervals.icu.log', response.text)
|
||||
return 0
|
||||
|
||||
data = response.json()
|
||||
ws = Workout.objects.filter(uploadedtointervals=id)
|
||||
|
||||
for w in ws:
|
||||
try:
|
||||
w.name = data['name']
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
w.notes = data['description']
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
w.workouttype = mytypes.intervalsmappinginv[data['type']]
|
||||
except KeyError:
|
||||
pass
|
||||
w.save()
|
||||
|
||||
# we stop here now
|
||||
return 1
|
||||
|
||||
url = self.oauth_data['base_url'] + 'activity/' + str(id) + '/fit-file'
|
||||
response = requests.get(url, headers=headers)
|
||||
if response.status_code != 200:
|
||||
dologging('intervals.icu.log', response.text)
|
||||
return 0
|
||||
|
||||
try:
|
||||
fit_data = response.content
|
||||
fit_filename = 'media/intervals_' + str(id) + '.fit'
|
||||
with open(fit_filename, 'wb') as f:
|
||||
f.write(fit_data)
|
||||
except:
|
||||
return 0
|
||||
|
||||
try:
|
||||
row = FP(fit_filename)
|
||||
rowdata = rowingdata(df=row.df)
|
||||
rowsummary = FitSummaryData(fit_filename)
|
||||
except Exception as e:
|
||||
dologging('intervals.icu.log', e)
|
||||
return 0
|
||||
|
||||
for w in ws:
|
||||
# copy fit_file to random file name using shutil
|
||||
temp_filename = 'media/' + str(uuid4()) + '.fit'
|
||||
try:
|
||||
shutil.copy(fit_filename, temp_filename)
|
||||
|
||||
|
||||
uploadoptions = {
|
||||
'secret': UPLOAD_SERVICE_SECRET,
|
||||
'user': self.rower.user.id,
|
||||
'boattype': '1x',
|
||||
'workouttype': w.workouttype,
|
||||
'file': temp_filename,
|
||||
'intervalsid': id,
|
||||
'id': w.id,
|
||||
}
|
||||
url = UPLOAD_SERVICE_URL
|
||||
response = requests.post(url, data=uploadoptions)
|
||||
except FileNotFoundError:
|
||||
return 0
|
||||
except Exception as e:
|
||||
dologging('intervals.icu.log', e)
|
||||
|
||||
# remove fit_file
|
||||
try:
|
||||
os.remove(fit_filename)
|
||||
except:
|
||||
pass
|
||||
|
||||
return 1
|
||||
|
||||
def get_workout(self, id, *args, **kwargs) -> int:
|
||||
_ = self.open()
|
||||
r = self.rower
|
||||
|
||||
# check if workout with this id already exists
|
||||
known_interval_ids = get_known_ids(r, 'intervalsid')
|
||||
if id in known_interval_ids:
|
||||
return self.update_workout(id)
|
||||
|
||||
record = create_or_update_syncrecord(r, None, intervalsid=id)
|
||||
|
||||
_ = myqueue(queuehigh,
|
||||
@@ -583,8 +677,8 @@ class IntervalsIntegration(SyncIntegration):
|
||||
id = record['id']
|
||||
try:
|
||||
ws = Workout.objects.filter(uploadedtointervals=id)
|
||||
if w.user == self.rower:
|
||||
for w in ws:
|
||||
for w in ws:
|
||||
if w.user == self.rower:
|
||||
w.delete()
|
||||
except Workout.DoesNotExist:
|
||||
pass
|
||||
@@ -592,3 +686,17 @@ class IntervalsIntegration(SyncIntegration):
|
||||
pass
|
||||
|
||||
return 1
|
||||
|
||||
def update_activities(self, event, *args, **kwargs):
|
||||
try:
|
||||
record = event["activity"]
|
||||
except KeyError:
|
||||
records = []
|
||||
|
||||
try:
|
||||
id = record['id']
|
||||
result = self.update_workout(id)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return 1
|
||||
|
||||
@@ -3582,7 +3582,6 @@ def handle_intervals_getworkout(rower, intervalstoken, workoutid, debug=False, *
|
||||
except KeyError:
|
||||
workouttype = 'water'
|
||||
|
||||
|
||||
url = "https://intervals.icu/api/v1/activity/{workoutid}/fit-file".format(workoutid=workoutid)
|
||||
|
||||
response = requests.get(url, headers=headers)
|
||||
|
||||
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
BIN
rowers/tests/testdata/testdata.tcx.gz
vendored
Binary file not shown.
@@ -942,7 +942,6 @@ def intervals_webhook_view(request):
|
||||
|
||||
webhook_type = None
|
||||
|
||||
|
||||
for event in events:
|
||||
try:
|
||||
athlete_id = event['athlete_id']
|
||||
@@ -964,6 +963,9 @@ def intervals_webhook_view(request):
|
||||
if webhook_type.lower() == 'activity_uploaded':
|
||||
integration.import_activities(event)
|
||||
|
||||
if webhook_type.lower() == 'activity_updated':
|
||||
integration.update_activities(event)
|
||||
|
||||
if webhook_type.lower() == 'activity_deleted':
|
||||
integration.delete_activities(event)
|
||||
|
||||
|
||||
@@ -1131,20 +1131,10 @@ def workouts_join_select(request,
|
||||
|
||||
r = getrequestrower(request, userid=userid)
|
||||
|
||||
if 'waterboattype' in request.session:
|
||||
waterboattype = request.session['waterboattype']
|
||||
else:
|
||||
waterboattype = mytypes.waterboattype+mytypes.ergtype
|
||||
waterboattype = mytypes.waterboattype+mytypes.ergtype
|
||||
|
||||
if 'modalities' in request.session:
|
||||
modalities = request.session['modalities']
|
||||
if len(modalities) > 1: # pragma: no cover
|
||||
modality = 'all'
|
||||
else:
|
||||
modality = modalities[0]
|
||||
else:
|
||||
modalities = [m[0] for m in mytypes.workouttypes]
|
||||
modality = 'all'
|
||||
modalities = [m[0] for m in mytypes.workouttypes]
|
||||
modality = 'all'
|
||||
|
||||
if request.method == 'POST':
|
||||
dateform = DateRangeForm(request.POST)
|
||||
@@ -1154,8 +1144,6 @@ def workouts_join_select(request,
|
||||
enddate = dateform.cleaned_data['enddate']
|
||||
startdatestring = startdate.strftime('%Y-%m-%d')
|
||||
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||
request.session['startdate'] = startdatestring
|
||||
request.session['enddate'] = enddatestring
|
||||
if modalityform.is_valid():
|
||||
modality = modalityform.cleaned_data['modality']
|
||||
waterboattype = modalityform.cleaned_data['waterboattype']
|
||||
@@ -1164,11 +1152,7 @@ def workouts_join_select(request,
|
||||
else:
|
||||
modalities = [modality]
|
||||
|
||||
if modality != 'water': # pragma: no cover
|
||||
waterboattype = [b[0] for b in mytypes.boattypes]
|
||||
|
||||
request.session['modalities'] = modalities
|
||||
request.session['waterboattype'] = waterboattype
|
||||
else:
|
||||
dateform = DateRangeForm(initial={
|
||||
'startdate': startdate,
|
||||
@@ -1211,6 +1195,7 @@ def workouts_join_select(request,
|
||||
startdatetime__lte=enddate,
|
||||
workouttype__in=modalities).order_by("-date", "-starttime").exclude(boattype__in=negtypes)
|
||||
|
||||
|
||||
query = request.GET.get('q')
|
||||
if query: # pragma: no cover
|
||||
query_list = query.split()
|
||||
@@ -4954,6 +4939,7 @@ def workout_upload_api(request):
|
||||
message = {'status': 'false', 'message': 'invalid credentials'}
|
||||
return JSONResponse(status=403, data=message)
|
||||
|
||||
|
||||
form = DocumentsForm(post_data)
|
||||
optionsform = TeamUploadOptionsForm(post_data)
|
||||
rowerform = TeamInviteForm(post_data)
|
||||
|
||||
Reference in New Issue
Block a user