From 82d1418bcbaeaab49bd0c2ce7d809547f2ac15db Mon Sep 17 00:00:00 2001
From: Sander Roosendaal The workout summary data and the stroke data are obtained and sent
separately. Challenges are accessed through /rowers/api/challenges/
- and /rowers/api/challenges/{id} where {id} is the ID of the challenge. Allowed method
- is GET. Entries are accessed through /rowers/api/entries/
- and /rowers/api/entries/{id} where {id} is the ID of the entry.
- Allowed methods are GET. Charts are accessed through /rowers/api/charts/
- and /rowers/api/charts/{id} where {id} is the ID of the chart.
- Allowed method are GET, DELETE. Courses are accessed through /rowers/api/geocourses/
- and /rowers/api/geocourses/{id} where {id} is the ID of the Course.
- Allowed method are GET. Course Standard Collections are accessed through /rowers/api/standardcollections/
- and /rowers/api/standardcollections/{id} where {id} is the ID of the Standard Collection.
- Allowed method are GET. Individual Course Standards are accessed through /rowers/api/standards/{id} where {id} is the ID of the Course Standard.
- Allowed method are GET. Workouts are accessed through /rowers/api/workouts/
- and /rowers/api/workouts/{id} where {id} is the ID of the Workout.
- Allowed method are GET, POST, DELETE. You can only post stroke data to an existing workout with
- workout number {id}. If the workout already has stroke data, you
- will get a duplication error. This functionality will be expanded in the
- future to enable updating stroke data. Stroke data for workout {id} are
- posted to:
- POST stroke data - API
-
- API v1
-
-
-
-
The payload is application/json data and looks as follows:
- -
- {
- "distance": [5,12,19,27,35,43,51,59,67,75,82,90,100],
- "power": [112,221,511,673,744,754,754,749,729,729,726,709,707],
- "hr": [132,131,131,132,133,136,139,142,145,147,150,152,153],
- "pace": [145800,116400,88100,80400,77700,77400,77400,77600,78300,78300,78400,79000,79100],
- "spm": [11,41,56,59,55,48,48,48,48,48,48,48,49],
- "time": [0,2200,4599,7000,9599,12000,14400,16799,19400,21799,24200,26599,2900],
+
+ In the table below {id} indicates the ID of the item.
+
| Item | Access Points | Permissions | Example | +
|---|---|---|---|
| Workout | +/rowers/api/workouts/
+ + /rowers/api/workouts/{id} |
+ GET, POST, DELETE | +
+ {
+ "id": 18,
+ "name": "2x",
+ "date": "2020-10-15",
+ "workouttype": "water",
+ "starttime": "08:40:50",
+ "distance": 9751,
+ "duration": "00:52:40",
+ "averagehr": 104,
+ "maxhr": 122,
+ "notes": "",
+ "summary": "Workout Summary - media/97ec07a851-20201015-192157-95763ffd-fd4e-4b5f-bf5f-8a8495c16639.csv\n--|Total|-Total----|--Avg--|-Avg-|Avg-|-Avg-|-Max-|-Avg\n--|Dist-|-Time-----|-Pace--|-Pwr-|SPM-|-HR--|-HR--|-DPS\n--|09751|00:52:40.0|02:42.0|173.0|18.0|104.4|122.0|10.3\nW-|09751|00:52:40.0|02:42.0|173.0|18.0|104.4|122.0|10.3\nR-|00000|00:00:00.0|00:00.0|000.0|00.0|000.0|122.0|00.0\nWorkout Details\n#-|SDist|-Split-|-SPace-|-Pwr-|SPM-|AvgHR|MaxHR|DPS-\n00|09751|52:40.0|02:42.0|173.0|18.0|104.4|122.0|10.3\n",
+ "boattype": "2x",
+ "timezone": "Europe/Amsterdam",
+ "forceunit": "N",
+ "inboard": 0.88,
+ "oarlength": 2.89,
+ "privacy": "visible",
+ "rankingpiece": false
}
-
+
+ |
-
| Favorite Chart | +/rowers/api/charts/
+ + /rowers/api/charts/{id} |
+ GET, DELETE | +
+ {
+ "id": 7,
+ "xparam": "time",
+ "yparam1": "hr",
+ "yparam2": "power",
+ "plottype": "line",
+ "workouttype": "otw",
+ "reststrokes": true,
+ "user": 1
+}
+
+ |
-
| Challenge | +/rowers/api/challenges/
+ + /rowers/api/challenges/{id} |
+ GET | +
+
+{
+ "id": 1,
+ "name": "Alphen",
+ "course": 1,
+ "registration_closure": "2020-10-18T08:45:00+02:00",
+ "evaluation_closure": "2020-10-18T12:16:00+02:00",
+ "start_time": "08:45:00",
+ "end_time": "12:00:00",
+ "country": "Nederland",
+ "timezone": "Europe/Amsterdam",
+ "contact_phone": "",
+ "contact_email": "",
+ "entries": [
+ {
+ "id": 1,
+ "username": "Sander Roosendaal",
+ "teamname": null,
+ "boattype": "1x",
+ "sex": "male",
+ "age": 48,
+ "adaptiveclass": "None",
+ "skillclass": "Open",
+ "coursecompleted": false,
+ "distance": 0,
+ "duration": "00:00:00",
+ "points": 0.0,
+ "entrycategory": null
+ }
+ ],
+ "coursestandards": null
+}
+
+ |
-
| Challenge Entry | +/rowers/api/entries/
+ + /rowers/api/entries/{id} |
+ GET, POST | +
+ {
+ "id": 1,
+ "teamname": null,
+ "adaptiveclass": "None",
+ "skillclass": "Open",
+ "race": {
+ "id": 1,
+ "name": "Alphen",
+ "course": 1,
+ "registration_closure": "2020-10-18T08:45:00+02:00",
+ "evaluation_closure": "2020-10-18T12:16:00+02:00",
+ "start_time": "08:45:00",
+ "end_time": "12:00:00",
+ "country": "Nederland",
+ "timezone": "Europe/Amsterdam",
+ "contact_phone": "",
+ "contact_email": "",
+ "entries": [
+ {
+ "id": 1,
+ "username": "Sander Roosendaal",
+ "teamname": null,
+ "boattype": "1x",
+ "sex": "male",
+ "age": 48,
+ "adaptiveclass": "None",
+ "skillclass": "Open",
+ "coursecompleted": false,
+ "distance": 0,
+ "duration": "00:00:00",
+ "points": 0.0,
+ "entrycategory": null
+ }
+ ],
+ "coursestandards": null
+ },
+ "distance": 0,
+ "duration": "00:00:00",
+ "points": 0.0,
+ "boattype": "1x",
+ "sex": "male",
+ "age": 48,
+ "entrycategory": null
+}
+
+ |
-
| Course | +/rowers/api/geocourses/
+ + /rowers/api/geocourses/{id} |
+ GET | +
+ Example shortened for brevity (omitted gates 2-14):
+
+{
+ "id": 1,
+ "name": "Alphen - Alphen aan den Rijn",
+ "distance": 14847,
+ "country": "Nederland",
+ "notes": "\n\n",
+ "polygons": [
+ {
+ "id": 1,
+ "name": "Start",
+ "order_in_course": 0,
+ "points": [
+ {
+ "id": 1,
+ "latitude": 52.14611068342334,
+ "longitude": 4.704149601313898,
+ "order_in_poly": 0
+ },
+ {
+ "id": 2,
+ "latitude": 52.14606840788696,
+ "longitude": 4.704648516706039,
+ "order_in_poly": 1
+ },
+ {
+ "id": 3,
+ "latitude": 52.14626893773362,
+ "longitude": 4.704642182077736,
+ "order_in_poly": 2
+ },
+ {
+ "id": 4,
+ "latitude": 52.14628828501986,
+ "longitude": 4.704151599747837,
+ "order_in_poly": 3
+ },
+ {
+ "id": 5,
+ "latitude": 52.14611068342334,
+ "longitude": 4.704149601313898,
+ "order_in_poly": 4
+ }
+ ]
+ },
+ {
+ "id": 15,
+ "name": "Finish",
+ "order_in_course": 14,
+ "points": [
+ {
+ "id": 71,
+ "latitude": 52.1461319705247,
+ "longitude": 4.70414987291546,
+ "order_in_poly": 0
+ },
+ {
+ "id": 72,
+ "latitude": 52.14607111930849,
+ "longitude": 4.704561170436561,
+ "order_in_poly": 1
+ },
+ {
+ "id": 73,
+ "latitude": 52.14626893773362,
+ "longitude": 4.704642182077736,
+ "order_in_poly": 2
+ },
+ {
+ "id": 74,
+ "latitude": 52.14628831020436,
+ "longitude": 4.70415735390207,
+ "order_in_poly": 3
+ },
+ {
+ "id": 75,
+ "latitude": 52.1461319705247,
+ "longitude": 4.70414987291546,
+ "order_in_poly": 4
+ }
+ ]
+ }
]
}
-
+
+ |
-
| Course Time Standard Collection | +/rowers/api/standardcollections/
+ + /rowers/api/standarcollections/{id} |
+ GET | +
+ Example shortened for brevity (showing only first three):
+ {
+ "id": 1,
+ "name": "Charles River Times Standards",
+ "notes": "",
+ "active": true,
+ "standards": [
+ {
+ "id": 1,
+ "name": "M1x",
+ "coursedistance": 4700,
+ "coursetime": "17:15.0",
+ "agemin": 0,
+ "agemax": 120,
+ "boatclass": "water",
+ "boattype": "1x",
+ "sex": "male",
+ "weightclass": "hwt",
+ "adaptiveclass": "None",
+ "skillclass": "Open",
+ "standardcollection": 1
+ },
+ {
+ "id": 2,
+ "name": "MLW1x",
+ "coursedistance": 4700,
+ "coursetime": "17:15.0",
+ "agemin": 0,
+ "agemax": 120,
+ "boatclass": "water",
+ "boattype": "1x",
+ "sex": "male",
+ "weightclass": "lwt",
+ "adaptiveclass": "None",
+ "skillclass": "Open",
+ "standardcollection": 1
+ },
+ {
+ "id": 3,
+ "name": "MYouth1x",
+ "coursedistance": 4700,
+ "coursetime": "18:30.0",
+ "agemin": 15,
+ "agemax": 18,
+ "boatclass": "water",
+ "boattype": "1x",
+ "sex": "male",
+ "weightclass": "hwt",
+ "adaptiveclass": "None",
+ "skillclass": "Open",
+ "standardcollection": 1
+ },
+ ]
+}
+
+ |
+
+
| Individual Course Time Standard | +/rowers/api/standards/
+ + /rowers/api/standards/{id} |
+ GET, POST + |
+ {
+ "id": 1,
+ "name": "M1x",
+ "coursedistance": 4700,
+ "coursetime": "17:15.0",
+ "agemin": 0,
+ "agemax": 120,
+ "boatclass": "water",
+ "boattype": "1x",
+ "sex": "male",
+ "weightclass": "hwt",
+ "adaptiveclass": "None",
+ "skillclass": "Open",
+ "standardcollection": 1
+}
+
+ |
+
+
| Stroke Data (v1) | +/rowers/api/workouts/{id}/strokedata + | +GET, POST | +
+ {
+ "distance": [23, 46, 48],
+ "time": [3200, 6700, 10099],
+ "spm": [16.4, 21.2, 19.8],
+ "pace": [155068, 144402, 138830],
+ "power": [84,6, 117.2, 141.3],
+ "hr": [85, 91, 95]
+ }
+
+ You can only post stroke data to an existing workout with
+ workout number {id}. If the workout already has stroke data, you
+ will get a duplication error. This functionality will be expanded in the
+ future to enable updating stroke data.
+ + For both v1 and v2, mandatory data fields are: ++
Optional data fiels are: ++
For both API versions, consistency checks will be done and the stroke data will be + refused if the mandatory data fields don't pass the checks. + All mandatory data fields + must have the same number of records. If an optional data field + fails a test, its values are silently replaced by zeros. + |
+
| Stroke Data (v2) | +/rowers/api/v2/workouts/{id}/strokedata + | +GET, POST | +
+ [
+ "data": [
+ {
+ "time": 3200.0000476837,
+ "pace": 155068.4885951763,
+ "hr": 85.7857142857,
+ "power": 84.6531131591,
+ "distance": 23,
+ "spm": 16.380952381
+ },
+ {
+ "time": 6700.0000476837,
+ "pace" : 144402.6407586741,
+ "hr": 91.2142857143,
+ "power": 117.458827834,
+ "distance": 36,
+ "spm": 21.1666666667
+ },
+ {
+ "time": 10099.9999046326,
+ "pace": 138830.8712654931,
+ "hr": 95.7142857143,
+ "power": 141.31057207,
+ "distance": 48,
+ "spm": 19.8095238095
+ }
+ ]
+]
+
+ You can only post stroke data to an existing workout with
+ workout number {id}. If the workout already has stroke data, you
+ will get a duplication error. This functionality will be expanded in the
+ future to enable updating stroke data.
+ + For both v1 and v2, mandatory data fields are: ++
Optional data fiels are: ++
For both API versions, consistency checks will be done and the stroke data will be + refused if the mandatory data fields don't pass the checks. + All mandatory data fields + must have the same number of records. If an optional data field + fails a test, its values are silently replaced by zeros. + |
+
Optional data fiels are:
--
For both API versions, consistency checks will be done and the stroke data will be - refused if the mandatory data fields don't pass the checks. - All mandatory data fields - must have the same number of records. If an optional data field - fails a test, its values are silently replaced by zeros.
- diff --git a/rowers/urls.py b/rowers/urls.py index f395f590..fe50d571 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -115,7 +115,7 @@ class EntryViewSet(viewsets.ModelViewSet): except TypeError: return [] - http_method_names = ['get'] + http_method_names = ['get','post'] permission_classes = ( IsCompetitorOrNot, diff --git a/rowers/views/apiviews.py b/rowers/views/apiviews.py index 6bc75bab..1ba5441d 100644 --- a/rowers/views/apiviews.py +++ b/rowers/views/apiviews.py @@ -107,8 +107,10 @@ def strokedatajson_v2(request,id): logfile.write(request.user.username+"(GET) \n") data = datadf.to_json(orient='records') + data2 = json.loads(data) + data2 = {"data":data2} - return JSONResponse(data) + return JSONResponse(data2) if request.method == 'POST': with open('media/apilog.log','a') as logfile: