Private
Public Access
1
0

Merge branch 'develop' into feature/idoklad

This commit is contained in:
2024-12-06 16:48:06 +01:00
2 changed files with 96 additions and 2 deletions

View File

@@ -254,6 +254,8 @@ urlpatterns = [
name='strokedatajson_v3'),
re_path(r'^api/TCX/workouts/$', views.strokedata_tcx,
name='strokedata_tcx'),
re_path(r'^api/FIT/workouts/$', views.strokedata_fit,
name='strokedata_fit'),
re_path(r'^api/rowingdata/workouts/$', views.strokedata_rowingdata,
name='strokedata_rowingdata'),
re_path(r'^api/rowingdata/$', views.strokedata_rowingdata_apikey,

View File

@@ -20,10 +20,25 @@ from datetime import datetime as dt
import rowingdata.tcxtools as tcxtools
from rowingdata import TCXParser, rowingdata
from rowingdata import FITParser as FP
import arrow
import base64
# create a FITParser which parses the application/octet-stream and creates a fit file
class FITParser(BaseParser):
media_type = "application/octet-stream"
def parse(self, stream, media_type=None, parser_context=None):
try:
return stream.read()
except Exception as e:
dologging("apilog.log", "FIT Parser")
dolofging("apilog.log", e)
raise ValueError(f"Failed to read FIT file: {str(e)}")
return stream.read()
class XMLParser(BaseParser):
media_type = "application/xml"
@@ -32,10 +47,10 @@ class XMLParser(BaseParser):
try:
s = ET.parse(stream).getroot()
except ET.XMLSyntaxError:
return HttpResponse(status=400)
raise ValueError("XML Syntax Error")
except Exception as e: # pragma: no cover
dologging("apilog.log",e)
return HttpResponse(status=500)
raise ValueError(f"Failed to parse XML file: {str(e)}")
return s
# Stroke data form to test API upload
@@ -530,6 +545,83 @@ def strokedata_rowingdata_apikey(request):
response.status_code = 201
return response
@csrf_exempt
@api_view(["POST"])
@permission_required('rower.is_not_freecoach', fn=get_user_by_userid, raise_exception=True)
@permission_classes([IsAuthenticated])
@parser_classes([FITParser])
def strokedata_fit(request):
"""
Handle a POST request to upload a binary FIT file and save it locally.
"""
if request.method != 'POST':
return HttpResponseBadRequest("Only POST requests are allowed.")
try:
fit_data = request.data
# Ensure the media directory exists
media_dir = 'media'
os.makedirs(media_dir, exist_ok=True)
# Generate a unique filename for the FIT file
fit_filename = os.path.join(media_dir, f'{uuid4().hex[:16]}.fit')
# Save the FIT file locally
with open(fit_filename, 'wb') as fit_file:
fit_file.write(fit_data)
except Exception as e:
return JsonResponse({
"status": "error",
"message": f"An error occurred while saving the FIT file: {str(e)}"
}, status=500)
try:
# Parse the FIT file
row = FP(fit_filename)
rowdata = rowingdata(df=row.df)
duration = totaltime_sec_to_string(rowdata.duration)
title = "ActiveSpeed water"
w = Workout.objects.create(user=request.user.rower,
duration=duration,
name=title,)
uploadoptions = {
'secret': UPLOAD_SERVICE_SECRET,
'user': request.user.id,
'file': fit_filename,
'workouttype': 'water',
'boattype': '1x',
'title': title,
'rpe': 0,
'notes': '',
'workoutid': w.id,
'offline': False,
}
url = UPLOAD_SERVICE_URL
_ = myqueue(queuehigh,
handle_request_post,
url,
uploadoptions)
return JsonResponse(
{"status": "success",
"workout public id": encoder.encode_hex(w.id),
"workout id": w.id,
})
except Exception as e:
dologging('apilog.log','FIT API endpoint')
dologging('apilog.log',e)
_ = myqueue(queuehigh, handle_sendemail_unrecognized, fit_filename, "fit parser")
return HttpResponse(status=500)
@csrf_exempt
#@login_required()