Merge branch 'develop' into feature/stravaapi
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user