Private
Public Access
1
0

intervals.icu fixes

This commit is contained in:
2024-12-28 15:13:04 +01:00
parent f36c98fe56
commit 63202ac2f1
6 changed files with 129 additions and 27 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)

Binary file not shown.

View File

@@ -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)

View File

@@ -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)