From b53b56f909bcc8566a71353c8d109afd061009fd Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 21 May 2021 11:30:57 +0200 Subject: [PATCH] runkeeper retired, updated sporttraclks --- filename | 29 ++ rowers/admin.py | 2 - rowers/c2stuff.py | 9 +- rowers/models.py | 11 - rowers/runkeeperstuff.py | 530 --------------------- rowers/sporttracksstuff.py | 9 +- rowers/tasks.py | 1 - rowers/templates/menu_workout.html | 15 - rowers/templates/menu_workouts.html | 1 - rowers/templates/rower_exportsettings.html | 4 - rowers/templatetags/rowerfilters.py | 13 +- rowers/tests/statements.py | 1 - rowers/tests/test_imports.py | 116 +---- rowers/traverselinktest.py | 1 - rowers/uploads.py | 15 - rowers/urls.py | 4 - rowers/utils.py | 2 +- rowers/views/importviews.py | 186 +------- rowers/views/statements.py | 3 - rowers/views/workoutviews.py | 27 -- rowsandall_app/urls.py | 1 - 21 files changed, 74 insertions(+), 906 deletions(-) create mode 100644 filename delete mode 100644 rowers/runkeeperstuff.py diff --git a/filename b/filename new file mode 100644 index 00000000..c4492c6b --- /dev/null +++ b/filename @@ -0,0 +1,29 @@ + +May-21-2021 08:41:39 Upload to C2 user 1 +May-21-2021 08:41:39 {"type": "water", "date": "2016-05-20 13:50:26", "stroke_count": 189, "timezone": "Europe/Amsterdam", "distance": 2000, "time": 5400, "weight_class": "H", "comments": null, "stroke_rate": 21, "drag_factor": 104, "heart_rate": {"average": 148, "max": 156}, "stroke_data": [{"t": 32, "d": 131, "p": 2628, "spm": 19, "hr": 127}, {"t": 32, "d": 131, "p": 2394, "spm": 19, "hr": 127}, {"t": 61, "d": 210, "p": 1991, "spm": 20, "hr": 128}, {"t": 92, "d": 303, "p": 1764, "spm": 20, "hr": 129}, {"t": 121, "d": 390, "p": 1685, "spm": 20, "hr": 130}, {"t": 151, "d": 482, "p": 1639, "spm": 21, "hr": 131}, {"t": 181, "d": 576, "p": 1620, "spm": 20, "hr": 131}, {"t": 209, "d": 664, "p": 1597, "spm": 20, "hr": 132}, {"t": 238, "d": 755, "p": 1601, "spm": 21, "hr": 132}, {"t": 269, "d": 851, "p": 1589, "spm": 20, "hr": 132}, {"t": 296, "d": 950, "p": 1524, "spm": 21, "hr": 132}, {"t": 323, "d": 1050, "p": 1408, "spm": 22, "hr": 133}, {"t": 351, "d": 1153, "p": 1379, "spm": 21, "hr": 134}, {"t": 380, "d": 1258, "p": 1365, "spm": 21, "hr": 135}, {"t": 408, "d": 1366, "p": 1342, "spm": 21, "hr": 136}, {"t": 436, "d": 1472, "p": 1331, "spm": 22, "hr": 137}, {"t": 464, "d": 1576, "p": 1324, "spm": 22, "hr": 139}, {"t": 491, "d": 1678, "p": 1344, "spm": 21, "hr": 140}, {"t": 519, "d": 1785, "p": 1332, "spm": 22, "hr": 140}, {"t": 546, "d": 1885, "p": 1317, "spm": 21, "hr": 141}, {"t": 575, "d": 1993, "p": 1338, "spm": 21, "hr": 141}, {"t": 602, "d": 2094, "p": 1328, "spm": 22, "hr": 142}, {"t": 628, "d": 2194, "p": 1328, "spm": 22, "hr": 142}, {"t": 657, "d": 2302, "p": 1337, "spm": 22, "hr": 143}, {"t": 683, "d": 2402, "p": 1340, "spm": 22, "hr": 144}, {"t": 710, "d": 2501, "p": 1331, "spm": 23, "hr": 145}, {"t": 734, "d": 2596, "p": 1326, "spm": 23, "hr": 145}, {"t": 763, "d": 2703, "p": 1324, "spm": 23, "hr": 145}, {"t": 790, "d": 2806, "p": 1332, "spm": 22, "hr": 145}, {"t": 817, "d": 2907, "p": 1331, "spm": 22, "hr": 144}, {"t": 844, "d": 3008, "p": 1333, "spm": 23, "hr": 145}, {"t": 871, "d": 3111, "p": 1325, "spm": 22, "hr": 145}, {"t": 897, "d": 3212, "p": 1312, "spm": 22, "hr": 145}, {"t": 926, "d": 3319, "p": 1330, "spm": 21, "hr": 145}, {"t": 953, "d": 3420, "p": 1328, "spm": 22, "hr": 146}, {"t": 980, "d": 3524, "p": 1328, "spm": 22, "hr": 146}, {"t": 1008, "d": 3630, "p": 1321, "spm": 22, "hr": 146}, {"t": 1036, "d": 3734, "p": 1324, "spm": 22, "hr": 147}, {"t": 1063, "d": 3839, "p": 1322, "spm": 22, "hr": 147}, {"t": 1092, "d": 3946, "p": 1326, "spm": 22, "hr": 147}, {"t": 1119, "d": 4050, "p": 1335, "spm": 21, "hr": 147}, {"t": 1146, "d": 4153, "p": 1325, "spm": 22, "hr": 148}, {"t": 1176, "d": 4260, "p": 1329, "spm": 22, "hr": 148}, {"t": 1203, "d": 4365, "p": 1333, "spm": 21, "hr": 148}, {"t": 1231, "d": 4469, "p": 1335, "spm": 22, "hr": 148}, {"t": 1256, "d": 4569, "p": 1312, "spm": 22, "hr": 149}, {"t": 1284, "d": 4676, "p": 1316, "spm": 22, "hr": 149}, {"t": 1313, "d": 4785, "p": 1315, "spm": 22, "hr": 150}, {"t": 1341, "d": 4890, "p": 1318, "spm": 21, "hr": 150}, {"t": 1367, "d": 4991, "p": 1336, "spm": 21, "hr": 150}, {"t": 1397, "d": 5100, "p": 1329, "spm": 22, "hr": 150}, {"t": 1423, "d": 5199, "p": 1323, "spm": 22, "hr": 149}, {"t": 1451, "d": 5306, "p": 1327, "spm": 22, "hr": 149}, {"t": 1478, "d": 5408, "p": 1337, "spm": 22, "hr": 149}, {"t": 1505, "d": 5508, "p": 1334, "spm": 22, "hr": 148}, {"t": 1532, "d": 5608, "p": 1348, "spm": 22, "hr": 148}, {"t": 1559, "d": 5710, "p": 1333, "spm": 22, "hr": 147}, {"t": 1584, "d": 5807, "p": 1330, "spm": 22, "hr": 147}, {"t": 1612, "d": 5912, "p": 1329, "spm": 22, "hr": 147}, {"t": 1639, "d": 6014, "p": 1330, "spm": 22, "hr": 147}, {"t": 1666, "d": 6114, "p": 1321, "spm": 23, "hr": 147}, {"t": 1693, "d": 6218, "p": 1328, "spm": 23, "hr": 147}, {"t": 1720, "d": 6321, "p": 1317, "spm": 22, "hr": 147}, {"t": 1747, "d": 6423, "p": 1319, "spm": 22, "hr": 147}, {"t": 1772, "d": 6520, "p": 1310, "spm": 23, "hr": 148}, {"t": 1801, "d": 6627, "p": 1297, "spm": 23, "hr": 148}, {"t": 1826, "d": 6731, "p": 1296, "spm": 23, "hr": 148}, {"t": 1854, "d": 6836, "p": 1295, "spm": 22, "hr": 149}, {"t": 1880, "d": 6938, "p": 1297, "spm": 22, "hr": 149}, {"t": 1905, "d": 7038, "p": 1292, "spm": 22, "hr": 149}, {"t": 1934, "d": 7147, "p": 1297, "spm": 23, "hr": 150}, {"t": 1960, "d": 7249, "p": 1296, "spm": 22, "hr": 150}, {"t": 1987, "d": 7352, "p": 1306, "spm": 23, "hr": 151}, {"t": 2014, "d": 7454, "p": 1307, "spm": 22, "hr": 151}, {"t": 2041, "d": 7560, "p": 1291, "spm": 23, "hr": 151}, {"t": 2067, "d": 7663, "p": 1294, "spm": 22, "hr": 150}, {"t": 2094, "d": 7765, "p": 1300, "spm": 22, "hr": 150}, {"t": 2120, "d": 7869, "p": 1295, "spm": 23, "hr": 150}, {"t": 2147, "d": 7972, "p": 1290, "spm": 22, "hr": 150}, {"t": 2174, "d": 8078, "p": 1288, "spm": 23, "hr": 150}, {"t": 2201, "d": 8182, "p": 1286, "spm": 23, "hr": 150}, {"t": 2226, "d": 8284, "p": 1282, "spm": 22, "hr": 150}, {"t": 2254, "d": 8392, "p": 1279, "spm": 23, "hr": 150}, {"t": 2281, "d": 8496, "p": 1288, "spm": 23, "hr": 151}, {"t": 2307, "d": 8601, "p": 1272, "spm": 22, "hr": 151}, {"t": 2333, "d": 8703, "p": 1272, "spm": 22, "hr": 152}, {"t": 2361, "d": 8811, "p": 1280, "spm": 22, "hr": 152}, {"t": 2388, "d": 8917, "p": 1284, "spm": 23, "hr": 152}, {"t": 2415, "d": 9021, "p": 1293, "spm": 22, "hr": 152}, {"t": 2444, "d": 9131, "p": 1299, "spm": 22, "hr": 152}, {"t": 2472, "d": 9239, "p": 1309, "spm": 22, "hr": 153}, {"t": 2500, "d": 9346, "p": 1307, "spm": 21, "hr": 154}, {"t": 2528, "d": 9454, "p": 1320, "spm": 21, "hr": 154}, {"t": 2556, "d": 9560, "p": 1318, "spm": 21, "hr": 155}, {"t": 2585, "d": 9667, "p": 1326, "spm": 21, "hr": 155}, {"t": 2613, "d": 9774, "p": 1330, "spm": 21, "hr": 156}, {"t": 2641, "d": 9881, "p": 1310, "spm": 21, "hr": 156}, {"t": 2669, "d": 9988, "p": 1316, "spm": 21, "hr": 156}, {"t": 2698, "d": 10096, "p": 1327, "spm": 21, "hr": 156}, {"t": 2727, "d": 10206, "p": 1338, "spm": 21, "hr": 156}, {"t": 2757, "d": 10315, "p": 1345, "spm": 20, "hr": 156}, {"t": 2786, "d": 10425, "p": 1347, "spm": 21, "hr": 156}, {"t": 2815, "d": 10533, "p": 1347, "spm": 20, "hr": 155}, {"t": 2844, "d": 10641, "p": 1339, "spm": 21, "hr": 155}, {"t": 2874, "d": 10753, "p": 1354, "spm": 20, "hr": 155}, {"t": 2904, "d": 10861, "p": 1375, "spm": 20, "hr": 155}, {"t": 2935, "d": 10975, "p": 1359, "spm": 21, "hr": 155}, {"t": 2964, "d": 11085, "p": 1344, "spm": 20, "hr": 155}, {"t": 2993, "d": 11192, "p": 1353, "spm": 20, "hr": 155}, {"t": 3024, "d": 11306, "p": 1353, "spm": 20, "hr": 155}, {"t": 3054, "d": 11413, "p": 1353, "spm": 20, "hr": 155}, {"t": 3083, "d": 11524, "p": 1354, "spm": 21, "hr": 155}, {"t": 3113, "d": 11633, "p": 1367, "spm": 20, "hr": 155}, {"t": 3140, "d": 11738, "p": 1360, "spm": 20, "hr": 154}, {"t": 3170, "d": 11848, "p": 1342, "spm": 21, "hr": 154}, {"t": 3200, "d": 11958, "p": 1343, "spm": 21, "hr": 153}, {"t": 3229, "d": 12066, "p": 1357, "spm": 21, "hr": 152}, {"t": 3259, "d": 12173, "p": 1358, "spm": 21, "hr": 153}, {"t": 3287, "d": 12278, "p": 1363, "spm": 21, "hr": 152}, {"t": 3315, "d": 12387, "p": 1354, "spm": 21, "hr": 152}, {"t": 3345, "d": 12495, "p": 1334, "spm": 21, "hr": 151}, {"t": 3374, "d": 12601, "p": 1359, "spm": 20, "hr": 151}, {"t": 3403, "d": 12709, "p": 1357, "spm": 21, "hr": 151}, {"t": 3432, "d": 12818, "p": 1346, "spm": 21, "hr": 150}, {"t": 3461, "d": 12927, "p": 1355, "spm": 20, "hr": 151}, {"t": 3490, "d": 13034, "p": 1358, "spm": 20, "hr": 151}, {"t": 3519, "d": 13143, "p": 1357, "spm": 21, "hr": 151}, {"t": 3549, "d": 13252, "p": 1343, "spm": 21, "hr": 151}, {"t": 3578, "d": 13361, "p": 1352, "spm": 20, "hr": 152}, {"t": 3607, "d": 13469, "p": 1348, "spm": 21, "hr": 152}, {"t": 3636, "d": 13574, "p": 1358, "spm": 20, "hr": 152}, {"t": 3665, "d": 13681, "p": 1368, "spm": 21, "hr": 152}, {"t": 3694, "d": 13790, "p": 1355, "spm": 20, "hr": 152}, {"t": 3723, "d": 13895, "p": 1346, "spm": 21, "hr": 153}, {"t": 3751, "d": 13999, "p": 1369, "spm": 21, "hr": 152}, {"t": 3780, "d": 14107, "p": 1367, "spm": 20, "hr": 152}, {"t": 3811, "d": 14220, "p": 1364, "spm": 20, "hr": 152}, {"t": 3840, "d": 14328, "p": 1358, "spm": 20, "hr": 151}, {"t": 3869, "d": 14436, "p": 1344, "spm": 21, "hr": 151}, {"t": 3898, "d": 14544, "p": 1353, "spm": 20, "hr": 152}, {"t": 3927, "d": 14651, "p": 1351, "spm": 21, "hr": 151}, {"t": 3956, "d": 14759, "p": 1345, "spm": 21, "hr": 152}, {"t": 3984, "d": 14866, "p": 1336, "spm": 21, "hr": 152}, {"t": 4014, "d": 14974, "p": 1354, "spm": 21, "hr": 153}, {"t": 4043, "d": 15082, "p": 1363, "spm": 20, "hr": 153}, {"t": 4073, "d": 15192, "p": 1350, "spm": 20, "hr": 154}, {"t": 4102, "d": 15300, "p": 1351, "spm": 21, "hr": 154}, {"t": 4131, "d": 15409, "p": 1357, "spm": 20, "hr": 153}, {"t": 4159, "d": 15513, "p": 1351, "spm": 21, "hr": 153}, {"t": 4190, "d": 15626, "p": 1343, "spm": 21, "hr": 153}, {"t": 4219, "d": 15733, "p": 1359, "spm": 20, "hr": 153}, {"t": 4248, "d": 15842, "p": 1364, "spm": 20, "hr": 152}, {"t": 4276, "d": 15946, "p": 1345, "spm": 21, "hr": 152}, {"t": 4307, "d": 16060, "p": 1351, "spm": 21, "hr": 152}, {"t": 4334, "d": 16162, "p": 1369, "spm": 20, "hr": 152}, {"t": 4365, "d": 16274, "p": 1362, "spm": 21, "hr": 152}, {"t": 4394, "d": 16380, "p": 1349, "spm": 21, "hr": 152}, {"t": 4424, "d": 16492, "p": 1353, "spm": 20, "hr": 151}, {"t": 4453, "d": 16602, "p": 1353, "spm": 20, "hr": 152}, {"t": 4482, "d": 16708, "p": 1357, "spm": 20, "hr": 151}, {"t": 4511, "d": 16814, "p": 1361, "spm": 21, "hr": 151}, {"t": 4540, "d": 16921, "p": 1361, "spm": 21, "hr": 151}, {"t": 4568, "d": 17025, "p": 1358, "spm": 21, "hr": 150}, {"t": 4598, "d": 17137, "p": 1349, "spm": 21, "hr": 150}, {"t": 4627, "d": 17244, "p": 1344, "spm": 21, "hr": 150}, {"t": 4656, "d": 17351, "p": 1358, "spm": 20, "hr": 150}, {"t": 4685, "d": 17456, "p": 1361, "spm": 21, "hr": 150}, {"t": 4713, "d": 17563, "p": 1358, "spm": 21, "hr": 150}, {"t": 4740, "d": 17662, "p": 1357, "spm": 20, "hr": 151}, {"t": 4770, "d": 17771, "p": 1369, "spm": 22, "hr": 150}, {"t": 4798, "d": 17875, "p": 1369, "spm": 21, "hr": 150}, {"t": 4826, "d": 17977, "p": 1362, "spm": 22, "hr": 150}, {"t": 4855, "d": 18084, "p": 1361, "spm": 21, "hr": 150}, {"t": 4882, "d": 18184, "p": 1367, "spm": 21, "hr": 149}, {"t": 4910, "d": 18289, "p": 1344, "spm": 22, "hr": 149}, {"t": 4940, "d": 18399, "p": 1356, "spm": 21, "hr": 149}, {"t": 4968, "d": 18505, "p": 1357, "spm": 21, "hr": 148}, {"t": 4997, "d": 18612, "p": 1346, "spm": 21, "hr": 148}, {"t": 5027, "d": 18719, "p": 1354, "spm": 21, "hr": 147}, {"t": 5056, "d": 18826, "p": 1366, "spm": 20, "hr": 147}, {"t": 5084, "d": 18933, "p": 1363, "spm": 20, "hr": 148}, {"t": 5114, "d": 19043, "p": 1348, "spm": 21, "hr": 149}, {"t": 5144, "d": 19154, "p": 1336, "spm": 20, "hr": 149}, {"t": 5174, "d": 19262, "p": 1364, "spm": 20, "hr": 150}, {"t": 5203, "d": 19373, "p": 1361, "spm": 20, "hr": 151}, {"t": 5231, "d": 19478, "p": 1348, "spm": 20, "hr": 152}, {"t": 5262, "d": 19591, "p": 1355, "spm": 20, "hr": 152}, {"t": 5291, "d": 19698, "p": 1361, "spm": 20, "hr": 153}, {"t": 5320, "d": 19806, "p": 1353, "spm": 21, "hr": 153}, {"t": 5349, "d": 19914, "p": 1353, "spm": 21, "hr": 153}, {"t": 5372, "d": 20000, "p": 1340, "spm": 21, "hr": 154}], "workout": {"splits": [{"type": "distance", "time": 1397, "distance": 510, "heart_rate": {"average": 141}, "stroke_rate": 21}, {"type": "distance", "time": 1301, "distance": 499, "heart_rate": {"average": 150}, "stroke_rate": 22}, {"type": "distance", "time": 1344, "distance": 498, "heart_rate": {"average": 152}, "stroke_rate": 20}, {"type": "distance", "time": 1328, "distance": 491, "heart_rate": {"average": 150}, "stroke_rate": 20}]}} +May-21-2021 08:41:40 User 1, C2 ID 33991243 +May-21-2021 08:41:40 {"distance": 13878, "user_id": 457764, "ranked": false, "weight_class": "L", "verified": false, "workout_type": false, "comments": "\n from speedcoach2v2.15 via rowsandall.com", "heart_rate": {"max": 158, "average": 156}, "source": "rowingdata", "date_utc": "2018-06-30 05:31:01", "time_formatted": "1:21:16.7", "time": 48767, "date": "2018-06-30 07:31:01", "timezone": "Europe/Prague", "type": "water", "id": 33991243, "stroke_data": true} +May-21-2021 08:41:40 Time zone Europe/Prague, stardatetime 2018-06-30 06:09:44.300000+02:00, duration 01:21:16.6 +May-21-2021 08:49:18 Upload to C2 user 1 +May-21-2021 08:49:18 {"type": "water", "date": "2016-05-20 13:50:26", "stroke_count": 189, "timezone": "Europe/Amsterdam", "distance": 2000, "time": 5400, "weight_class": "H", "comments": null, "stroke_rate": 21, "drag_factor": 104, "heart_rate": {"average": 148, "max": 156}, "stroke_data": [{"t": 32, "d": 131, "p": 2628, "spm": 19, "hr": 127}, {"t": 32, "d": 131, "p": 2394, "spm": 19, "hr": 127}, {"t": 61, "d": 210, "p": 1991, "spm": 20, "hr": 128}, {"t": 92, "d": 303, "p": 1764, "spm": 20, "hr": 129}, {"t": 121, "d": 390, "p": 1685, "spm": 20, "hr": 130}, {"t": 151, "d": 482, "p": 1639, "spm": 21, "hr": 131}, {"t": 181, "d": 576, "p": 1620, "spm": 20, "hr": 131}, {"t": 209, "d": 664, "p": 1597, "spm": 20, "hr": 132}, {"t": 238, "d": 755, "p": 1601, "spm": 21, "hr": 132}, {"t": 269, "d": 851, "p": 1589, "spm": 20, "hr": 132}, {"t": 296, "d": 950, "p": 1524, "spm": 21, "hr": 132}, {"t": 323, "d": 1050, "p": 1408, "spm": 22, "hr": 133}, {"t": 351, "d": 1153, "p": 1379, "spm": 21, "hr": 134}, {"t": 380, "d": 1258, "p": 1365, "spm": 21, "hr": 135}, {"t": 408, "d": 1366, "p": 1342, "spm": 21, "hr": 136}, {"t": 436, "d": 1472, "p": 1331, "spm": 22, "hr": 137}, {"t": 464, "d": 1576, "p": 1324, "spm": 22, "hr": 139}, {"t": 491, "d": 1678, "p": 1344, "spm": 21, "hr": 140}, {"t": 519, "d": 1785, "p": 1332, "spm": 22, "hr": 140}, {"t": 546, "d": 1885, "p": 1317, "spm": 21, "hr": 141}, {"t": 575, "d": 1993, "p": 1338, "spm": 21, "hr": 141}, {"t": 602, "d": 2094, "p": 1328, "spm": 22, "hr": 142}, {"t": 628, "d": 2194, "p": 1328, "spm": 22, "hr": 142}, {"t": 657, "d": 2302, "p": 1337, "spm": 22, "hr": 143}, {"t": 683, "d": 2402, "p": 1340, "spm": 22, "hr": 144}, {"t": 710, "d": 2501, "p": 1331, "spm": 23, "hr": 145}, {"t": 734, "d": 2596, "p": 1326, "spm": 23, "hr": 145}, {"t": 763, "d": 2703, "p": 1324, "spm": 23, "hr": 145}, {"t": 790, "d": 2806, "p": 1332, "spm": 22, "hr": 145}, {"t": 817, "d": 2907, "p": 1331, "spm": 22, "hr": 144}, {"t": 844, "d": 3008, "p": 1333, "spm": 23, "hr": 145}, {"t": 871, "d": 3111, "p": 1325, "spm": 22, "hr": 145}, {"t": 897, "d": 3212, "p": 1312, "spm": 22, "hr": 145}, {"t": 926, "d": 3319, "p": 1330, "spm": 21, "hr": 145}, {"t": 953, "d": 3420, "p": 1328, "spm": 22, "hr": 146}, {"t": 980, "d": 3524, "p": 1328, "spm": 22, "hr": 146}, {"t": 1008, "d": 3630, "p": 1321, "spm": 22, "hr": 146}, {"t": 1036, "d": 3734, "p": 1324, "spm": 22, "hr": 147}, {"t": 1063, "d": 3839, "p": 1322, "spm": 22, "hr": 147}, {"t": 1092, "d": 3946, "p": 1326, "spm": 22, "hr": 147}, {"t": 1119, "d": 4050, "p": 1335, "spm": 21, "hr": 147}, {"t": 1146, "d": 4153, "p": 1325, "spm": 22, "hr": 148}, {"t": 1176, "d": 4260, "p": 1329, "spm": 22, "hr": 148}, {"t": 1203, "d": 4365, "p": 1333, "spm": 21, "hr": 148}, {"t": 1231, "d": 4469, "p": 1335, "spm": 22, "hr": 148}, {"t": 1256, "d": 4569, "p": 1312, "spm": 22, "hr": 149}, {"t": 1284, "d": 4676, "p": 1316, "spm": 22, "hr": 149}, {"t": 1313, "d": 4785, "p": 1315, "spm": 22, "hr": 150}, {"t": 1341, "d": 4890, "p": 1318, "spm": 21, "hr": 150}, {"t": 1367, "d": 4991, "p": 1336, "spm": 21, "hr": 150}, {"t": 1397, "d": 5100, "p": 1329, "spm": 22, "hr": 150}, {"t": 1423, "d": 5199, "p": 1323, "spm": 22, "hr": 149}, {"t": 1451, "d": 5306, "p": 1327, "spm": 22, "hr": 149}, {"t": 1478, "d": 5408, "p": 1337, "spm": 22, "hr": 149}, {"t": 1505, "d": 5508, "p": 1334, "spm": 22, "hr": 148}, {"t": 1532, "d": 5608, "p": 1348, "spm": 22, "hr": 148}, {"t": 1559, "d": 5710, "p": 1333, "spm": 22, "hr": 147}, {"t": 1584, "d": 5807, "p": 1330, "spm": 22, "hr": 147}, {"t": 1612, "d": 5912, "p": 1329, "spm": 22, "hr": 147}, {"t": 1639, "d": 6014, "p": 1330, "spm": 22, "hr": 147}, {"t": 1666, "d": 6114, "p": 1321, "spm": 23, "hr": 147}, {"t": 1693, "d": 6218, "p": 1328, "spm": 23, "hr": 147}, {"t": 1720, "d": 6321, "p": 1317, "spm": 22, "hr": 147}, {"t": 1747, "d": 6423, "p": 1319, "spm": 22, "hr": 147}, {"t": 1772, "d": 6520, "p": 1310, "spm": 23, "hr": 148}, {"t": 1801, "d": 6627, "p": 1297, "spm": 23, "hr": 148}, {"t": 1826, "d": 6731, "p": 1296, "spm": 23, "hr": 148}, {"t": 1854, "d": 6836, "p": 1295, "spm": 22, "hr": 149}, {"t": 1880, "d": 6938, "p": 1297, "spm": 22, "hr": 149}, {"t": 1905, "d": 7038, "p": 1292, "spm": 22, "hr": 149}, {"t": 1934, "d": 7147, "p": 1297, "spm": 23, "hr": 150}, {"t": 1960, "d": 7249, "p": 1296, "spm": 22, "hr": 150}, {"t": 1987, "d": 7352, "p": 1306, "spm": 23, "hr": 151}, {"t": 2014, "d": 7454, "p": 1307, "spm": 22, "hr": 151}, {"t": 2041, "d": 7560, "p": 1291, "spm": 23, "hr": 151}, {"t": 2067, "d": 7663, "p": 1294, "spm": 22, "hr": 150}, {"t": 2094, "d": 7765, "p": 1300, "spm": 22, "hr": 150}, {"t": 2120, "d": 7869, "p": 1295, "spm": 23, "hr": 150}, {"t": 2147, "d": 7972, "p": 1290, "spm": 22, "hr": 150}, {"t": 2174, "d": 8078, "p": 1288, "spm": 23, "hr": 150}, {"t": 2201, "d": 8182, "p": 1286, "spm": 23, "hr": 150}, {"t": 2226, "d": 8284, "p": 1282, "spm": 22, "hr": 150}, {"t": 2254, "d": 8392, "p": 1279, "spm": 23, "hr": 150}, {"t": 2281, "d": 8496, "p": 1288, "spm": 23, "hr": 151}, {"t": 2307, "d": 8601, "p": 1272, "spm": 22, "hr": 151}, {"t": 2333, "d": 8703, "p": 1272, "spm": 22, "hr": 152}, {"t": 2361, "d": 8811, "p": 1280, "spm": 22, "hr": 152}, {"t": 2388, "d": 8917, "p": 1284, "spm": 23, "hr": 152}, {"t": 2415, "d": 9021, "p": 1293, "spm": 22, "hr": 152}, {"t": 2444, "d": 9131, "p": 1299, "spm": 22, "hr": 152}, {"t": 2472, "d": 9239, "p": 1309, "spm": 22, "hr": 153}, {"t": 2500, "d": 9346, "p": 1307, "spm": 21, "hr": 154}, {"t": 2528, "d": 9454, "p": 1320, "spm": 21, "hr": 154}, {"t": 2556, "d": 9560, "p": 1318, "spm": 21, "hr": 155}, {"t": 2585, "d": 9667, "p": 1326, "spm": 21, "hr": 155}, {"t": 2613, "d": 9774, "p": 1330, "spm": 21, "hr": 156}, {"t": 2641, "d": 9881, "p": 1310, "spm": 21, "hr": 156}, {"t": 2669, "d": 9988, "p": 1316, "spm": 21, "hr": 156}, {"t": 2698, "d": 10096, "p": 1327, "spm": 21, "hr": 156}, {"t": 2727, "d": 10206, "p": 1338, "spm": 21, "hr": 156}, {"t": 2757, "d": 10315, "p": 1345, "spm": 20, "hr": 156}, {"t": 2786, "d": 10425, "p": 1347, "spm": 21, "hr": 156}, {"t": 2815, "d": 10533, "p": 1347, "spm": 20, "hr": 155}, {"t": 2844, "d": 10641, "p": 1339, "spm": 21, "hr": 155}, {"t": 2874, "d": 10753, "p": 1354, "spm": 20, "hr": 155}, {"t": 2904, "d": 10861, "p": 1375, "spm": 20, "hr": 155}, {"t": 2935, "d": 10975, "p": 1359, "spm": 21, "hr": 155}, {"t": 2964, "d": 11085, "p": 1344, "spm": 20, "hr": 155}, {"t": 2993, "d": 11192, "p": 1353, "spm": 20, "hr": 155}, {"t": 3024, "d": 11306, "p": 1353, "spm": 20, "hr": 155}, {"t": 3054, "d": 11413, "p": 1353, "spm": 20, "hr": 155}, {"t": 3083, "d": 11524, "p": 1354, "spm": 21, "hr": 155}, {"t": 3113, "d": 11633, "p": 1367, "spm": 20, "hr": 155}, {"t": 3140, "d": 11738, "p": 1360, "spm": 20, "hr": 154}, {"t": 3170, "d": 11848, "p": 1342, "spm": 21, "hr": 154}, {"t": 3200, "d": 11958, "p": 1343, "spm": 21, "hr": 153}, {"t": 3229, "d": 12066, "p": 1357, "spm": 21, "hr": 152}, {"t": 3259, "d": 12173, "p": 1358, "spm": 21, "hr": 153}, {"t": 3287, "d": 12278, "p": 1363, "spm": 21, "hr": 152}, {"t": 3315, "d": 12387, "p": 1354, "spm": 21, "hr": 152}, {"t": 3345, "d": 12495, "p": 1334, "spm": 21, "hr": 151}, {"t": 3374, "d": 12601, "p": 1359, "spm": 20, "hr": 151}, {"t": 3403, "d": 12709, "p": 1357, "spm": 21, "hr": 151}, {"t": 3432, "d": 12818, "p": 1346, "spm": 21, "hr": 150}, {"t": 3461, "d": 12927, "p": 1355, "spm": 20, "hr": 151}, {"t": 3490, "d": 13034, "p": 1358, "spm": 20, "hr": 151}, {"t": 3519, "d": 13143, "p": 1357, "spm": 21, "hr": 151}, {"t": 3549, "d": 13252, "p": 1343, "spm": 21, "hr": 151}, {"t": 3578, "d": 13361, "p": 1352, "spm": 20, "hr": 152}, {"t": 3607, "d": 13469, "p": 1348, "spm": 21, "hr": 152}, {"t": 3636, "d": 13574, "p": 1358, "spm": 20, "hr": 152}, {"t": 3665, "d": 13681, "p": 1368, "spm": 21, "hr": 152}, {"t": 3694, "d": 13790, "p": 1355, "spm": 20, "hr": 152}, {"t": 3723, "d": 13895, "p": 1346, "spm": 21, "hr": 153}, {"t": 3751, "d": 13999, "p": 1369, "spm": 21, "hr": 152}, {"t": 3780, "d": 14107, "p": 1367, "spm": 20, "hr": 152}, {"t": 3811, "d": 14220, "p": 1364, "spm": 20, "hr": 152}, {"t": 3840, "d": 14328, "p": 1358, "spm": 20, "hr": 151}, {"t": 3869, "d": 14436, "p": 1344, "spm": 21, "hr": 151}, {"t": 3898, "d": 14544, "p": 1353, "spm": 20, "hr": 152}, {"t": 3927, "d": 14651, "p": 1351, "spm": 21, "hr": 151}, {"t": 3956, "d": 14759, "p": 1345, "spm": 21, "hr": 152}, {"t": 3984, "d": 14866, "p": 1336, "spm": 21, "hr": 152}, {"t": 4014, "d": 14974, "p": 1354, "spm": 21, "hr": 153}, {"t": 4043, "d": 15082, "p": 1363, "spm": 20, "hr": 153}, {"t": 4073, "d": 15192, "p": 1350, "spm": 20, "hr": 154}, {"t": 4102, "d": 15300, "p": 1351, "spm": 21, "hr": 154}, {"t": 4131, "d": 15409, "p": 1357, "spm": 20, "hr": 153}, {"t": 4159, "d": 15513, "p": 1351, "spm": 21, "hr": 153}, {"t": 4190, "d": 15626, "p": 1343, "spm": 21, "hr": 153}, {"t": 4219, "d": 15733, "p": 1359, "spm": 20, "hr": 153}, {"t": 4248, "d": 15842, "p": 1364, "spm": 20, "hr": 152}, {"t": 4276, "d": 15946, "p": 1345, "spm": 21, "hr": 152}, {"t": 4307, "d": 16060, "p": 1351, "spm": 21, "hr": 152}, {"t": 4334, "d": 16162, "p": 1369, "spm": 20, "hr": 152}, {"t": 4365, "d": 16274, "p": 1362, "spm": 21, "hr": 152}, {"t": 4394, "d": 16380, "p": 1349, "spm": 21, "hr": 152}, {"t": 4424, "d": 16492, "p": 1353, "spm": 20, "hr": 151}, {"t": 4453, "d": 16602, "p": 1353, "spm": 20, "hr": 152}, {"t": 4482, "d": 16708, "p": 1357, "spm": 20, "hr": 151}, {"t": 4511, "d": 16814, "p": 1361, "spm": 21, "hr": 151}, {"t": 4540, "d": 16921, "p": 1361, "spm": 21, "hr": 151}, {"t": 4568, "d": 17025, "p": 1358, "spm": 21, "hr": 150}, {"t": 4598, "d": 17137, "p": 1349, "spm": 21, "hr": 150}, {"t": 4627, "d": 17244, "p": 1344, "spm": 21, "hr": 150}, {"t": 4656, "d": 17351, "p": 1358, "spm": 20, "hr": 150}, {"t": 4685, "d": 17456, "p": 1361, "spm": 21, "hr": 150}, {"t": 4713, "d": 17563, "p": 1358, "spm": 21, "hr": 150}, {"t": 4740, "d": 17662, "p": 1357, "spm": 20, "hr": 151}, {"t": 4770, "d": 17771, "p": 1369, "spm": 22, "hr": 150}, {"t": 4798, "d": 17875, "p": 1369, "spm": 21, "hr": 150}, {"t": 4826, "d": 17977, "p": 1362, "spm": 22, "hr": 150}, {"t": 4855, "d": 18084, "p": 1361, "spm": 21, "hr": 150}, {"t": 4882, "d": 18184, "p": 1367, "spm": 21, "hr": 149}, {"t": 4910, "d": 18289, "p": 1344, "spm": 22, "hr": 149}, {"t": 4940, "d": 18399, "p": 1356, "spm": 21, "hr": 149}, {"t": 4968, "d": 18505, "p": 1357, "spm": 21, "hr": 148}, {"t": 4997, "d": 18612, "p": 1346, "spm": 21, "hr": 148}, {"t": 5027, "d": 18719, "p": 1354, "spm": 21, "hr": 147}, {"t": 5056, "d": 18826, "p": 1366, "spm": 20, "hr": 147}, {"t": 5084, "d": 18933, "p": 1363, "spm": 20, "hr": 148}, {"t": 5114, "d": 19043, "p": 1348, "spm": 21, "hr": 149}, {"t": 5144, "d": 19154, "p": 1336, "spm": 20, "hr": 149}, {"t": 5174, "d": 19262, "p": 1364, "spm": 20, "hr": 150}, {"t": 5203, "d": 19373, "p": 1361, "spm": 20, "hr": 151}, {"t": 5231, "d": 19478, "p": 1348, "spm": 20, "hr": 152}, {"t": 5262, "d": 19591, "p": 1355, "spm": 20, "hr": 152}, {"t": 5291, "d": 19698, "p": 1361, "spm": 20, "hr": 153}, {"t": 5320, "d": 19806, "p": 1353, "spm": 21, "hr": 153}, {"t": 5349, "d": 19914, "p": 1353, "spm": 21, "hr": 153}, {"t": 5372, "d": 20000, "p": 1340, "spm": 21, "hr": 154}], "workout": {"splits": [{"type": "distance", "time": 1397, "distance": 510, "heart_rate": {"average": 141}, "stroke_rate": 21}, {"type": "distance", "time": 1301, "distance": 499, "heart_rate": {"average": 150}, "stroke_rate": 22}, {"type": "distance", "time": 1344, "distance": 498, "heart_rate": {"average": 152}, "stroke_rate": 20}, {"type": "distance", "time": 1328, "distance": 491, "heart_rate": {"average": 150}, "stroke_rate": 20}]}} +May-21-2021 08:49:18 User 1, C2 ID 33991243 +May-21-2021 08:49:18 {"distance": 13878, "user_id": 457764, "ranked": false, "weight_class": "L", "verified": false, "workout_type": false, "comments": "\n from speedcoach2v2.15 via rowsandall.com", "heart_rate": {"max": 158, "average": 156}, "source": "rowingdata", "date_utc": "2018-06-30 05:31:01", "time_formatted": "1:21:16.7", "time": 48767, "date": "2018-06-30 07:31:01", "timezone": "Europe/Prague", "type": "water", "id": 33991243, "stroke_data": true} +May-21-2021 08:49:18 Time zone Europe/Prague, stardatetime 2018-06-30 06:09:44.300000+02:00, duration 01:21:16.6 +May-21-2021 08:52:05 Upload to C2 user 1 +May-21-2021 08:52:05 {"type": "water", "date": "2016-05-20 13:50:26", "stroke_count": 189, "timezone": "Europe/Amsterdam", "distance": 2000, "time": 5400, "weight_class": "H", "comments": null, "stroke_rate": 21, "drag_factor": 104, "heart_rate": {"average": 148, "max": 156}, "stroke_data": [{"t": 32, "d": 131, "p": 2628, "spm": 19, "hr": 127}, {"t": 32, "d": 131, "p": 2394, "spm": 19, "hr": 127}, {"t": 61, "d": 210, "p": 1991, "spm": 20, "hr": 128}, {"t": 92, "d": 303, "p": 1764, "spm": 20, "hr": 129}, {"t": 121, "d": 390, "p": 1685, "spm": 20, "hr": 130}, {"t": 151, "d": 482, "p": 1639, "spm": 21, "hr": 131}, {"t": 181, "d": 576, "p": 1620, "spm": 20, "hr": 131}, {"t": 209, "d": 664, "p": 1597, "spm": 20, "hr": 132}, {"t": 238, "d": 755, "p": 1601, "spm": 21, "hr": 132}, {"t": 269, "d": 851, "p": 1589, "spm": 20, "hr": 132}, {"t": 296, "d": 950, "p": 1524, "spm": 21, "hr": 132}, {"t": 323, "d": 1050, "p": 1408, "spm": 22, "hr": 133}, {"t": 351, "d": 1153, "p": 1379, "spm": 21, "hr": 134}, {"t": 380, "d": 1258, "p": 1365, "spm": 21, "hr": 135}, {"t": 408, "d": 1366, "p": 1342, "spm": 21, "hr": 136}, {"t": 436, "d": 1472, "p": 1331, "spm": 22, "hr": 137}, {"t": 464, "d": 1576, "p": 1324, "spm": 22, "hr": 139}, {"t": 491, "d": 1678, "p": 1344, "spm": 21, "hr": 140}, {"t": 519, "d": 1785, "p": 1332, "spm": 22, "hr": 140}, {"t": 546, "d": 1885, "p": 1317, "spm": 21, "hr": 141}, {"t": 575, "d": 1993, "p": 1338, "spm": 21, "hr": 141}, {"t": 602, "d": 2094, "p": 1328, "spm": 22, "hr": 142}, {"t": 628, "d": 2194, "p": 1328, "spm": 22, "hr": 142}, {"t": 657, "d": 2302, "p": 1337, "spm": 22, "hr": 143}, {"t": 683, "d": 2402, "p": 1340, "spm": 22, "hr": 144}, {"t": 710, "d": 2501, "p": 1331, "spm": 23, "hr": 145}, {"t": 734, "d": 2596, "p": 1326, "spm": 23, "hr": 145}, {"t": 763, "d": 2703, "p": 1324, "spm": 23, "hr": 145}, {"t": 790, "d": 2806, "p": 1332, "spm": 22, "hr": 145}, {"t": 817, "d": 2907, "p": 1331, "spm": 22, "hr": 144}, {"t": 844, "d": 3008, "p": 1333, "spm": 23, "hr": 145}, {"t": 871, "d": 3111, "p": 1325, "spm": 22, "hr": 145}, {"t": 897, "d": 3212, "p": 1312, "spm": 22, "hr": 145}, {"t": 926, "d": 3319, "p": 1330, "spm": 21, "hr": 145}, {"t": 953, "d": 3420, "p": 1328, "spm": 22, "hr": 146}, {"t": 980, "d": 3524, "p": 1328, "spm": 22, "hr": 146}, {"t": 1008, "d": 3630, "p": 1321, "spm": 22, "hr": 146}, {"t": 1036, "d": 3734, "p": 1324, "spm": 22, "hr": 147}, {"t": 1063, "d": 3839, "p": 1322, "spm": 22, "hr": 147}, {"t": 1092, "d": 3946, "p": 1326, "spm": 22, "hr": 147}, {"t": 1119, "d": 4050, "p": 1335, "spm": 21, "hr": 147}, {"t": 1146, "d": 4153, "p": 1325, "spm": 22, "hr": 148}, {"t": 1176, "d": 4260, "p": 1329, "spm": 22, "hr": 148}, {"t": 1203, "d": 4365, "p": 1333, "spm": 21, "hr": 148}, {"t": 1231, "d": 4469, "p": 1335, "spm": 22, "hr": 148}, {"t": 1256, "d": 4569, "p": 1312, "spm": 22, "hr": 149}, {"t": 1284, "d": 4676, "p": 1316, "spm": 22, "hr": 149}, {"t": 1313, "d": 4785, "p": 1315, "spm": 22, "hr": 150}, {"t": 1341, "d": 4890, "p": 1318, "spm": 21, "hr": 150}, {"t": 1367, "d": 4991, "p": 1336, "spm": 21, "hr": 150}, {"t": 1397, "d": 5100, "p": 1329, "spm": 22, "hr": 150}, {"t": 1423, "d": 5199, "p": 1323, "spm": 22, "hr": 149}, {"t": 1451, "d": 5306, "p": 1327, "spm": 22, "hr": 149}, {"t": 1478, "d": 5408, "p": 1337, "spm": 22, "hr": 149}, {"t": 1505, "d": 5508, "p": 1334, "spm": 22, "hr": 148}, {"t": 1532, "d": 5608, "p": 1348, "spm": 22, "hr": 148}, {"t": 1559, "d": 5710, "p": 1333, "spm": 22, "hr": 147}, {"t": 1584, "d": 5807, "p": 1330, "spm": 22, "hr": 147}, {"t": 1612, "d": 5912, "p": 1329, "spm": 22, "hr": 147}, {"t": 1639, "d": 6014, "p": 1330, "spm": 22, "hr": 147}, {"t": 1666, "d": 6114, "p": 1321, "spm": 23, "hr": 147}, {"t": 1693, "d": 6218, "p": 1328, "spm": 23, "hr": 147}, {"t": 1720, "d": 6321, "p": 1317, "spm": 22, "hr": 147}, {"t": 1747, "d": 6423, "p": 1319, "spm": 22, "hr": 147}, {"t": 1772, "d": 6520, "p": 1310, "spm": 23, "hr": 148}, {"t": 1801, "d": 6627, "p": 1297, "spm": 23, "hr": 148}, {"t": 1826, "d": 6731, "p": 1296, "spm": 23, "hr": 148}, {"t": 1854, "d": 6836, "p": 1295, "spm": 22, "hr": 149}, {"t": 1880, "d": 6938, "p": 1297, "spm": 22, "hr": 149}, {"t": 1905, "d": 7038, "p": 1292, "spm": 22, "hr": 149}, {"t": 1934, "d": 7147, "p": 1297, "spm": 23, "hr": 150}, {"t": 1960, "d": 7249, "p": 1296, "spm": 22, "hr": 150}, {"t": 1987, "d": 7352, "p": 1306, "spm": 23, "hr": 151}, {"t": 2014, "d": 7454, "p": 1307, "spm": 22, "hr": 151}, {"t": 2041, "d": 7560, "p": 1291, "spm": 23, "hr": 151}, {"t": 2067, "d": 7663, "p": 1294, "spm": 22, "hr": 150}, {"t": 2094, "d": 7765, "p": 1300, "spm": 22, "hr": 150}, {"t": 2120, "d": 7869, "p": 1295, "spm": 23, "hr": 150}, {"t": 2147, "d": 7972, "p": 1290, "spm": 22, "hr": 150}, {"t": 2174, "d": 8078, "p": 1288, "spm": 23, "hr": 150}, {"t": 2201, "d": 8182, "p": 1286, "spm": 23, "hr": 150}, {"t": 2226, "d": 8284, "p": 1282, "spm": 22, "hr": 150}, {"t": 2254, "d": 8392, "p": 1279, "spm": 23, "hr": 150}, {"t": 2281, "d": 8496, "p": 1288, "spm": 23, "hr": 151}, {"t": 2307, "d": 8601, "p": 1272, "spm": 22, "hr": 151}, {"t": 2333, "d": 8703, "p": 1272, "spm": 22, "hr": 152}, {"t": 2361, "d": 8811, "p": 1280, "spm": 22, "hr": 152}, {"t": 2388, "d": 8917, "p": 1284, "spm": 23, "hr": 152}, {"t": 2415, "d": 9021, "p": 1293, "spm": 22, "hr": 152}, {"t": 2444, "d": 9131, "p": 1299, "spm": 22, "hr": 152}, {"t": 2472, "d": 9239, "p": 1309, "spm": 22, "hr": 153}, {"t": 2500, "d": 9346, "p": 1307, "spm": 21, "hr": 154}, {"t": 2528, "d": 9454, "p": 1320, "spm": 21, "hr": 154}, {"t": 2556, "d": 9560, "p": 1318, "spm": 21, "hr": 155}, {"t": 2585, "d": 9667, "p": 1326, "spm": 21, "hr": 155}, {"t": 2613, "d": 9774, "p": 1330, "spm": 21, "hr": 156}, {"t": 2641, "d": 9881, "p": 1310, "spm": 21, "hr": 156}, {"t": 2669, "d": 9988, "p": 1316, "spm": 21, "hr": 156}, {"t": 2698, "d": 10096, "p": 1327, "spm": 21, "hr": 156}, {"t": 2727, "d": 10206, "p": 1338, "spm": 21, "hr": 156}, {"t": 2757, "d": 10315, "p": 1345, "spm": 20, "hr": 156}, {"t": 2786, "d": 10425, "p": 1347, "spm": 21, "hr": 156}, {"t": 2815, "d": 10533, "p": 1347, "spm": 20, "hr": 155}, {"t": 2844, "d": 10641, "p": 1339, "spm": 21, "hr": 155}, {"t": 2874, "d": 10753, "p": 1354, "spm": 20, "hr": 155}, {"t": 2904, "d": 10861, "p": 1375, "spm": 20, "hr": 155}, {"t": 2935, "d": 10975, "p": 1359, "spm": 21, "hr": 155}, {"t": 2964, "d": 11085, "p": 1344, "spm": 20, "hr": 155}, {"t": 2993, "d": 11192, "p": 1353, "spm": 20, "hr": 155}, {"t": 3024, "d": 11306, "p": 1353, "spm": 20, "hr": 155}, {"t": 3054, "d": 11413, "p": 1353, "spm": 20, "hr": 155}, {"t": 3083, "d": 11524, "p": 1354, "spm": 21, "hr": 155}, {"t": 3113, "d": 11633, "p": 1367, "spm": 20, "hr": 155}, {"t": 3140, "d": 11738, "p": 1360, "spm": 20, "hr": 154}, {"t": 3170, "d": 11848, "p": 1342, "spm": 21, "hr": 154}, {"t": 3200, "d": 11958, "p": 1343, "spm": 21, "hr": 153}, {"t": 3229, "d": 12066, "p": 1357, "spm": 21, "hr": 152}, {"t": 3259, "d": 12173, "p": 1358, "spm": 21, "hr": 153}, {"t": 3287, "d": 12278, "p": 1363, "spm": 21, "hr": 152}, {"t": 3315, "d": 12387, "p": 1354, "spm": 21, "hr": 152}, {"t": 3345, "d": 12495, "p": 1334, "spm": 21, "hr": 151}, {"t": 3374, "d": 12601, "p": 1359, "spm": 20, "hr": 151}, {"t": 3403, "d": 12709, "p": 1357, "spm": 21, "hr": 151}, {"t": 3432, "d": 12818, "p": 1346, "spm": 21, "hr": 150}, {"t": 3461, "d": 12927, "p": 1355, "spm": 20, "hr": 151}, {"t": 3490, "d": 13034, "p": 1358, "spm": 20, "hr": 151}, {"t": 3519, "d": 13143, "p": 1357, "spm": 21, "hr": 151}, {"t": 3549, "d": 13252, "p": 1343, "spm": 21, "hr": 151}, {"t": 3578, "d": 13361, "p": 1352, "spm": 20, "hr": 152}, {"t": 3607, "d": 13469, "p": 1348, "spm": 21, "hr": 152}, {"t": 3636, "d": 13574, "p": 1358, "spm": 20, "hr": 152}, {"t": 3665, "d": 13681, "p": 1368, "spm": 21, "hr": 152}, {"t": 3694, "d": 13790, "p": 1355, "spm": 20, "hr": 152}, {"t": 3723, "d": 13895, "p": 1346, "spm": 21, "hr": 153}, {"t": 3751, "d": 13999, "p": 1369, "spm": 21, "hr": 152}, {"t": 3780, "d": 14107, "p": 1367, "spm": 20, "hr": 152}, {"t": 3811, "d": 14220, "p": 1364, "spm": 20, "hr": 152}, {"t": 3840, "d": 14328, "p": 1358, "spm": 20, "hr": 151}, {"t": 3869, "d": 14436, "p": 1344, "spm": 21, "hr": 151}, {"t": 3898, "d": 14544, "p": 1353, "spm": 20, "hr": 152}, {"t": 3927, "d": 14651, "p": 1351, "spm": 21, "hr": 151}, {"t": 3956, "d": 14759, "p": 1345, "spm": 21, "hr": 152}, {"t": 3984, "d": 14866, "p": 1336, "spm": 21, "hr": 152}, {"t": 4014, "d": 14974, "p": 1354, "spm": 21, "hr": 153}, {"t": 4043, "d": 15082, "p": 1363, "spm": 20, "hr": 153}, {"t": 4073, "d": 15192, "p": 1350, "spm": 20, "hr": 154}, {"t": 4102, "d": 15300, "p": 1351, "spm": 21, "hr": 154}, {"t": 4131, "d": 15409, "p": 1357, "spm": 20, "hr": 153}, {"t": 4159, "d": 15513, "p": 1351, "spm": 21, "hr": 153}, {"t": 4190, "d": 15626, "p": 1343, "spm": 21, "hr": 153}, {"t": 4219, "d": 15733, "p": 1359, "spm": 20, "hr": 153}, {"t": 4248, "d": 15842, "p": 1364, "spm": 20, "hr": 152}, {"t": 4276, "d": 15946, "p": 1345, "spm": 21, "hr": 152}, {"t": 4307, "d": 16060, "p": 1351, "spm": 21, "hr": 152}, {"t": 4334, "d": 16162, "p": 1369, "spm": 20, "hr": 152}, {"t": 4365, "d": 16274, "p": 1362, "spm": 21, "hr": 152}, {"t": 4394, "d": 16380, "p": 1349, "spm": 21, "hr": 152}, {"t": 4424, "d": 16492, "p": 1353, "spm": 20, "hr": 151}, {"t": 4453, "d": 16602, "p": 1353, "spm": 20, "hr": 152}, {"t": 4482, "d": 16708, "p": 1357, "spm": 20, "hr": 151}, {"t": 4511, "d": 16814, "p": 1361, "spm": 21, "hr": 151}, {"t": 4540, "d": 16921, "p": 1361, "spm": 21, "hr": 151}, {"t": 4568, "d": 17025, "p": 1358, "spm": 21, "hr": 150}, {"t": 4598, "d": 17137, "p": 1349, "spm": 21, "hr": 150}, {"t": 4627, "d": 17244, "p": 1344, "spm": 21, "hr": 150}, {"t": 4656, "d": 17351, "p": 1358, "spm": 20, "hr": 150}, {"t": 4685, "d": 17456, "p": 1361, "spm": 21, "hr": 150}, {"t": 4713, "d": 17563, "p": 1358, "spm": 21, "hr": 150}, {"t": 4740, "d": 17662, "p": 1357, "spm": 20, "hr": 151}, {"t": 4770, "d": 17771, "p": 1369, "spm": 22, "hr": 150}, {"t": 4798, "d": 17875, "p": 1369, "spm": 21, "hr": 150}, {"t": 4826, "d": 17977, "p": 1362, "spm": 22, "hr": 150}, {"t": 4855, "d": 18084, "p": 1361, "spm": 21, "hr": 150}, {"t": 4882, "d": 18184, "p": 1367, "spm": 21, "hr": 149}, {"t": 4910, "d": 18289, "p": 1344, "spm": 22, "hr": 149}, {"t": 4940, "d": 18399, "p": 1356, "spm": 21, "hr": 149}, {"t": 4968, "d": 18505, "p": 1357, "spm": 21, "hr": 148}, {"t": 4997, "d": 18612, "p": 1346, "spm": 21, "hr": 148}, {"t": 5027, "d": 18719, "p": 1354, "spm": 21, "hr": 147}, {"t": 5056, "d": 18826, "p": 1366, "spm": 20, "hr": 147}, {"t": 5084, "d": 18933, "p": 1363, "spm": 20, "hr": 148}, {"t": 5114, "d": 19043, "p": 1348, "spm": 21, "hr": 149}, {"t": 5144, "d": 19154, "p": 1336, "spm": 20, "hr": 149}, {"t": 5174, "d": 19262, "p": 1364, "spm": 20, "hr": 150}, {"t": 5203, "d": 19373, "p": 1361, "spm": 20, "hr": 151}, {"t": 5231, "d": 19478, "p": 1348, "spm": 20, "hr": 152}, {"t": 5262, "d": 19591, "p": 1355, "spm": 20, "hr": 152}, {"t": 5291, "d": 19698, "p": 1361, "spm": 20, "hr": 153}, {"t": 5320, "d": 19806, "p": 1353, "spm": 21, "hr": 153}, {"t": 5349, "d": 19914, "p": 1353, "spm": 21, "hr": 153}, {"t": 5372, "d": 20000, "p": 1340, "spm": 21, "hr": 154}], "workout": {"splits": [{"type": "distance", "time": 1397, "distance": 510, "heart_rate": {"average": 141}, "stroke_rate": 21}, {"type": "distance", "time": 1301, "distance": 499, "heart_rate": {"average": 150}, "stroke_rate": 22}, {"type": "distance", "time": 1344, "distance": 498, "heart_rate": {"average": 152}, "stroke_rate": 20}, {"type": "distance", "time": 1328, "distance": 491, "heart_rate": {"average": 150}, "stroke_rate": 20}]}} +May-21-2021 08:52:06 User 1, C2 ID 33991243 +May-21-2021 08:52:06 {"distance": 13878, "user_id": 457764, "ranked": false, "weight_class": "L", "verified": false, "workout_type": false, "comments": "\n from speedcoach2v2.15 via rowsandall.com", "heart_rate": {"max": 158, "average": 156}, "source": "rowingdata", "date_utc": "2018-06-30 05:31:01", "time_formatted": "1:21:16.7", "time": 48767, "date": "2018-06-30 07:31:01", "timezone": "Europe/Prague", "type": "water", "id": 33991243, "stroke_data": true} +May-21-2021 08:52:06 Time zone Europe/Prague, stardatetime 2018-06-30 06:09:44.300000+02:00, duration 01:21:16.6 +May-21-2021 08:55:14 User 1, C2 ID 54440491 +May-21-2021 08:55:14 {"id": 54440491, "user_id": 457764, "date": "2021-05-20 05:01:31", "timezone": "Europe/Amsterdam", "date_utc": "2021-05-20 03:01:31", "distance": 13008, "type": "water", "time": 40825, "time_formatted": "1:08:02.5", "workout_type": false, "source": "rowingdata", "weight_class": "H", "verified": false, "ranked": false, "comments": null, "stroke_data": true, "stroke_count": 1345, "stroke_rate": 20, "heart_rate": {"average": 153, "max": 174}, "workout": {"splits": [{"type": "distance", "time": 40826, "distance": 13008, "stroke_rate": 20, "heart_rate": {"average": 153}}]}} +May-21-2021 08:55:14 Time zone Europe/Amsterdam, stardatetime 2021-05-20 03:53:28.500000+02:00, duration 01:08:02.5 +May-21-2021 09:06:14 Upload to C2 user 1 +May-21-2021 09:06:14 {"type": "water", "date": "2016-05-20 13:50:26", "stroke_count": 189, "timezone": "Europe/Amsterdam", "distance": 2000, "time": 5400, "weight_class": "H", "comments": null, "stroke_rate": 21, "drag_factor": 104, "heart_rate": {"average": 148, "max": 156}, "stroke_data": [{"t": 32, "d": 131, "p": 2628, "spm": 19, "hr": 127}, {"t": 32, "d": 131, "p": 2394, "spm": 19, "hr": 127}, {"t": 61, "d": 210, "p": 1991, "spm": 20, "hr": 128}, {"t": 92, "d": 303, "p": 1764, "spm": 20, "hr": 129}, {"t": 121, "d": 390, "p": 1685, "spm": 20, "hr": 130}, {"t": 151, "d": 482, "p": 1639, "spm": 21, "hr": 131}, {"t": 181, "d": 576, "p": 1620, "spm": 20, "hr": 131}, {"t": 209, "d": 664, "p": 1597, "spm": 20, "hr": 132}, {"t": 238, "d": 755, "p": 1601, "spm": 21, "hr": 132}, {"t": 269, "d": 851, "p": 1589, "spm": 20, "hr": 132}, {"t": 296, "d": 950, "p": 1524, "spm": 21, "hr": 132}, {"t": 323, "d": 1050, "p": 1408, "spm": 22, "hr": 133}, {"t": 351, "d": 1153, "p": 1379, "spm": 21, "hr": 134}, {"t": 380, "d": 1258, "p": 1365, "spm": 21, "hr": 135}, {"t": 408, "d": 1366, "p": 1342, "spm": 21, "hr": 136}, {"t": 436, "d": 1472, "p": 1331, "spm": 22, "hr": 137}, {"t": 464, "d": 1576, "p": 1324, "spm": 22, "hr": 139}, {"t": 491, "d": 1678, "p": 1344, "spm": 21, "hr": 140}, {"t": 519, "d": 1785, "p": 1332, "spm": 22, "hr": 140}, {"t": 546, "d": 1885, "p": 1317, "spm": 21, "hr": 141}, {"t": 575, "d": 1993, "p": 1338, "spm": 21, "hr": 141}, {"t": 602, "d": 2094, "p": 1328, "spm": 22, "hr": 142}, {"t": 628, "d": 2194, "p": 1328, "spm": 22, "hr": 142}, {"t": 657, "d": 2302, "p": 1337, "spm": 22, "hr": 143}, {"t": 683, "d": 2402, "p": 1340, "spm": 22, "hr": 144}, {"t": 710, "d": 2501, "p": 1331, "spm": 23, "hr": 145}, {"t": 734, "d": 2596, "p": 1326, "spm": 23, "hr": 145}, {"t": 763, "d": 2703, "p": 1324, "spm": 23, "hr": 145}, {"t": 790, "d": 2806, "p": 1332, "spm": 22, "hr": 145}, {"t": 817, "d": 2907, "p": 1331, "spm": 22, "hr": 144}, {"t": 844, "d": 3008, "p": 1333, "spm": 23, "hr": 145}, {"t": 871, "d": 3111, "p": 1325, "spm": 22, "hr": 145}, {"t": 897, "d": 3212, "p": 1312, "spm": 22, "hr": 145}, {"t": 926, "d": 3319, "p": 1330, "spm": 21, "hr": 145}, {"t": 953, "d": 3420, "p": 1328, "spm": 22, "hr": 146}, {"t": 980, "d": 3524, "p": 1328, "spm": 22, "hr": 146}, {"t": 1008, "d": 3630, "p": 1321, "spm": 22, "hr": 146}, {"t": 1036, "d": 3734, "p": 1324, "spm": 22, "hr": 147}, {"t": 1063, "d": 3839, "p": 1322, "spm": 22, "hr": 147}, {"t": 1092, "d": 3946, "p": 1326, "spm": 22, "hr": 147}, {"t": 1119, "d": 4050, "p": 1335, "spm": 21, "hr": 147}, {"t": 1146, "d": 4153, "p": 1325, "spm": 22, "hr": 148}, {"t": 1176, "d": 4260, "p": 1329, "spm": 22, "hr": 148}, {"t": 1203, "d": 4365, "p": 1333, "spm": 21, "hr": 148}, {"t": 1231, "d": 4469, "p": 1335, "spm": 22, "hr": 148}, {"t": 1256, "d": 4569, "p": 1312, "spm": 22, "hr": 149}, {"t": 1284, "d": 4676, "p": 1316, "spm": 22, "hr": 149}, {"t": 1313, "d": 4785, "p": 1315, "spm": 22, "hr": 150}, {"t": 1341, "d": 4890, "p": 1318, "spm": 21, "hr": 150}, {"t": 1367, "d": 4991, "p": 1336, "spm": 21, "hr": 150}, {"t": 1397, "d": 5100, "p": 1329, "spm": 22, "hr": 150}, {"t": 1423, "d": 5199, "p": 1323, "spm": 22, "hr": 149}, {"t": 1451, "d": 5306, "p": 1327, "spm": 22, "hr": 149}, {"t": 1478, "d": 5408, "p": 1337, "spm": 22, "hr": 149}, {"t": 1505, "d": 5508, "p": 1334, "spm": 22, "hr": 148}, {"t": 1532, "d": 5608, "p": 1348, "spm": 22, "hr": 148}, {"t": 1559, "d": 5710, "p": 1333, "spm": 22, "hr": 147}, {"t": 1584, "d": 5807, "p": 1330, "spm": 22, "hr": 147}, {"t": 1612, "d": 5912, "p": 1329, "spm": 22, "hr": 147}, {"t": 1639, "d": 6014, "p": 1330, "spm": 22, "hr": 147}, {"t": 1666, "d": 6114, "p": 1321, "spm": 23, "hr": 147}, {"t": 1693, "d": 6218, "p": 1328, "spm": 23, "hr": 147}, {"t": 1720, "d": 6321, "p": 1317, "spm": 22, "hr": 147}, {"t": 1747, "d": 6423, "p": 1319, "spm": 22, "hr": 147}, {"t": 1772, "d": 6520, "p": 1310, "spm": 23, "hr": 148}, {"t": 1801, "d": 6627, "p": 1297, "spm": 23, "hr": 148}, {"t": 1826, "d": 6731, "p": 1296, "spm": 23, "hr": 148}, {"t": 1854, "d": 6836, "p": 1295, "spm": 22, "hr": 149}, {"t": 1880, "d": 6938, "p": 1297, "spm": 22, "hr": 149}, {"t": 1905, "d": 7038, "p": 1292, "spm": 22, "hr": 149}, {"t": 1934, "d": 7147, "p": 1297, "spm": 23, "hr": 150}, {"t": 1960, "d": 7249, "p": 1296, "spm": 22, "hr": 150}, {"t": 1987, "d": 7352, "p": 1306, "spm": 23, "hr": 151}, {"t": 2014, "d": 7454, "p": 1307, "spm": 22, "hr": 151}, {"t": 2041, "d": 7560, "p": 1291, "spm": 23, "hr": 151}, {"t": 2067, "d": 7663, "p": 1294, "spm": 22, "hr": 150}, {"t": 2094, "d": 7765, "p": 1300, "spm": 22, "hr": 150}, {"t": 2120, "d": 7869, "p": 1295, "spm": 23, "hr": 150}, {"t": 2147, "d": 7972, "p": 1290, "spm": 22, "hr": 150}, {"t": 2174, "d": 8078, "p": 1288, "spm": 23, "hr": 150}, {"t": 2201, "d": 8182, "p": 1286, "spm": 23, "hr": 150}, {"t": 2226, "d": 8284, "p": 1282, "spm": 22, "hr": 150}, {"t": 2254, "d": 8392, "p": 1279, "spm": 23, "hr": 150}, {"t": 2281, "d": 8496, "p": 1288, "spm": 23, "hr": 151}, {"t": 2307, "d": 8601, "p": 1272, "spm": 22, "hr": 151}, {"t": 2333, "d": 8703, "p": 1272, "spm": 22, "hr": 152}, {"t": 2361, "d": 8811, "p": 1280, "spm": 22, "hr": 152}, {"t": 2388, "d": 8917, "p": 1284, "spm": 23, "hr": 152}, {"t": 2415, "d": 9021, "p": 1293, "spm": 22, "hr": 152}, {"t": 2444, "d": 9131, "p": 1299, "spm": 22, "hr": 152}, {"t": 2472, "d": 9239, "p": 1309, "spm": 22, "hr": 153}, {"t": 2500, "d": 9346, "p": 1307, "spm": 21, "hr": 154}, {"t": 2528, "d": 9454, "p": 1320, "spm": 21, "hr": 154}, {"t": 2556, "d": 9560, "p": 1318, "spm": 21, "hr": 155}, {"t": 2585, "d": 9667, "p": 1326, "spm": 21, "hr": 155}, {"t": 2613, "d": 9774, "p": 1330, "spm": 21, "hr": 156}, {"t": 2641, "d": 9881, "p": 1310, "spm": 21, "hr": 156}, {"t": 2669, "d": 9988, "p": 1316, "spm": 21, "hr": 156}, {"t": 2698, "d": 10096, "p": 1327, "spm": 21, "hr": 156}, {"t": 2727, "d": 10206, "p": 1338, "spm": 21, "hr": 156}, {"t": 2757, "d": 10315, "p": 1345, "spm": 20, "hr": 156}, {"t": 2786, "d": 10425, "p": 1347, "spm": 21, "hr": 156}, {"t": 2815, "d": 10533, "p": 1347, "spm": 20, "hr": 155}, {"t": 2844, "d": 10641, "p": 1339, "spm": 21, "hr": 155}, {"t": 2874, "d": 10753, "p": 1354, "spm": 20, "hr": 155}, {"t": 2904, "d": 10861, "p": 1375, "spm": 20, "hr": 155}, {"t": 2935, "d": 10975, "p": 1359, "spm": 21, "hr": 155}, {"t": 2964, "d": 11085, "p": 1344, "spm": 20, "hr": 155}, {"t": 2993, "d": 11192, "p": 1353, "spm": 20, "hr": 155}, {"t": 3024, "d": 11306, "p": 1353, "spm": 20, "hr": 155}, {"t": 3054, "d": 11413, "p": 1353, "spm": 20, "hr": 155}, {"t": 3083, "d": 11524, "p": 1354, "spm": 21, "hr": 155}, {"t": 3113, "d": 11633, "p": 1367, "spm": 20, "hr": 155}, {"t": 3140, "d": 11738, "p": 1360, "spm": 20, "hr": 154}, {"t": 3170, "d": 11848, "p": 1342, "spm": 21, "hr": 154}, {"t": 3200, "d": 11958, "p": 1343, "spm": 21, "hr": 153}, {"t": 3229, "d": 12066, "p": 1357, "spm": 21, "hr": 152}, {"t": 3259, "d": 12173, "p": 1358, "spm": 21, "hr": 153}, {"t": 3287, "d": 12278, "p": 1363, "spm": 21, "hr": 152}, {"t": 3315, "d": 12387, "p": 1354, "spm": 21, "hr": 152}, {"t": 3345, "d": 12495, "p": 1334, "spm": 21, "hr": 151}, {"t": 3374, "d": 12601, "p": 1359, "spm": 20, "hr": 151}, {"t": 3403, "d": 12709, "p": 1357, "spm": 21, "hr": 151}, {"t": 3432, "d": 12818, "p": 1346, "spm": 21, "hr": 150}, {"t": 3461, "d": 12927, "p": 1355, "spm": 20, "hr": 151}, {"t": 3490, "d": 13034, "p": 1358, "spm": 20, "hr": 151}, {"t": 3519, "d": 13143, "p": 1357, "spm": 21, "hr": 151}, {"t": 3549, "d": 13252, "p": 1343, "spm": 21, "hr": 151}, {"t": 3578, "d": 13361, "p": 1352, "spm": 20, "hr": 152}, {"t": 3607, "d": 13469, "p": 1348, "spm": 21, "hr": 152}, {"t": 3636, "d": 13574, "p": 1358, "spm": 20, "hr": 152}, {"t": 3665, "d": 13681, "p": 1368, "spm": 21, "hr": 152}, {"t": 3694, "d": 13790, "p": 1355, "spm": 20, "hr": 152}, {"t": 3723, "d": 13895, "p": 1346, "spm": 21, "hr": 153}, {"t": 3751, "d": 13999, "p": 1369, "spm": 21, "hr": 152}, {"t": 3780, "d": 14107, "p": 1367, "spm": 20, "hr": 152}, {"t": 3811, "d": 14220, "p": 1364, "spm": 20, "hr": 152}, {"t": 3840, "d": 14328, "p": 1358, "spm": 20, "hr": 151}, {"t": 3869, "d": 14436, "p": 1344, "spm": 21, "hr": 151}, {"t": 3898, "d": 14544, "p": 1353, "spm": 20, "hr": 152}, {"t": 3927, "d": 14651, "p": 1351, "spm": 21, "hr": 151}, {"t": 3956, "d": 14759, "p": 1345, "spm": 21, "hr": 152}, {"t": 3984, "d": 14866, "p": 1336, "spm": 21, "hr": 152}, {"t": 4014, "d": 14974, "p": 1354, "spm": 21, "hr": 153}, {"t": 4043, "d": 15082, "p": 1363, "spm": 20, "hr": 153}, {"t": 4073, "d": 15192, "p": 1350, "spm": 20, "hr": 154}, {"t": 4102, "d": 15300, "p": 1351, "spm": 21, "hr": 154}, {"t": 4131, "d": 15409, "p": 1357, "spm": 20, "hr": 153}, {"t": 4159, "d": 15513, "p": 1351, "spm": 21, "hr": 153}, {"t": 4190, "d": 15626, "p": 1343, "spm": 21, "hr": 153}, {"t": 4219, "d": 15733, "p": 1359, "spm": 20, "hr": 153}, {"t": 4248, "d": 15842, "p": 1364, "spm": 20, "hr": 152}, {"t": 4276, "d": 15946, "p": 1345, "spm": 21, "hr": 152}, {"t": 4307, "d": 16060, "p": 1351, "spm": 21, "hr": 152}, {"t": 4334, "d": 16162, "p": 1369, "spm": 20, "hr": 152}, {"t": 4365, "d": 16274, "p": 1362, "spm": 21, "hr": 152}, {"t": 4394, "d": 16380, "p": 1349, "spm": 21, "hr": 152}, {"t": 4424, "d": 16492, "p": 1353, "spm": 20, "hr": 151}, {"t": 4453, "d": 16602, "p": 1353, "spm": 20, "hr": 152}, {"t": 4482, "d": 16708, "p": 1357, "spm": 20, "hr": 151}, {"t": 4511, "d": 16814, "p": 1361, "spm": 21, "hr": 151}, {"t": 4540, "d": 16921, "p": 1361, "spm": 21, "hr": 151}, {"t": 4568, "d": 17025, "p": 1358, "spm": 21, "hr": 150}, {"t": 4598, "d": 17137, "p": 1349, "spm": 21, "hr": 150}, {"t": 4627, "d": 17244, "p": 1344, "spm": 21, "hr": 150}, {"t": 4656, "d": 17351, "p": 1358, "spm": 20, "hr": 150}, {"t": 4685, "d": 17456, "p": 1361, "spm": 21, "hr": 150}, {"t": 4713, "d": 17563, "p": 1358, "spm": 21, "hr": 150}, {"t": 4740, "d": 17662, "p": 1357, "spm": 20, "hr": 151}, {"t": 4770, "d": 17771, "p": 1369, "spm": 22, "hr": 150}, {"t": 4798, "d": 17875, "p": 1369, "spm": 21, "hr": 150}, {"t": 4826, "d": 17977, "p": 1362, "spm": 22, "hr": 150}, {"t": 4855, "d": 18084, "p": 1361, "spm": 21, "hr": 150}, {"t": 4882, "d": 18184, "p": 1367, "spm": 21, "hr": 149}, {"t": 4910, "d": 18289, "p": 1344, "spm": 22, "hr": 149}, {"t": 4940, "d": 18399, "p": 1356, "spm": 21, "hr": 149}, {"t": 4968, "d": 18505, "p": 1357, "spm": 21, "hr": 148}, {"t": 4997, "d": 18612, "p": 1346, "spm": 21, "hr": 148}, {"t": 5027, "d": 18719, "p": 1354, "spm": 21, "hr": 147}, {"t": 5056, "d": 18826, "p": 1366, "spm": 20, "hr": 147}, {"t": 5084, "d": 18933, "p": 1363, "spm": 20, "hr": 148}, {"t": 5114, "d": 19043, "p": 1348, "spm": 21, "hr": 149}, {"t": 5144, "d": 19154, "p": 1336, "spm": 20, "hr": 149}, {"t": 5174, "d": 19262, "p": 1364, "spm": 20, "hr": 150}, {"t": 5203, "d": 19373, "p": 1361, "spm": 20, "hr": 151}, {"t": 5231, "d": 19478, "p": 1348, "spm": 20, "hr": 152}, {"t": 5262, "d": 19591, "p": 1355, "spm": 20, "hr": 152}, {"t": 5291, "d": 19698, "p": 1361, "spm": 20, "hr": 153}, {"t": 5320, "d": 19806, "p": 1353, "spm": 21, "hr": 153}, {"t": 5349, "d": 19914, "p": 1353, "spm": 21, "hr": 153}, {"t": 5372, "d": 20000, "p": 1340, "spm": 21, "hr": 154}], "workout": {"splits": [{"type": "distance", "time": 1397, "distance": 510, "heart_rate": {"average": 141}, "stroke_rate": 21}, {"type": "distance", "time": 1301, "distance": 499, "heart_rate": {"average": 150}, "stroke_rate": 22}, {"type": "distance", "time": 1344, "distance": 498, "heart_rate": {"average": 152}, "stroke_rate": 20}, {"type": "distance", "time": 1328, "distance": 491, "heart_rate": {"average": 150}, "stroke_rate": 20}]}} +May-21-2021 09:06:14 User 1, C2 ID 33991243 +May-21-2021 09:06:14 {"distance": 13878, "user_id": 457764, "ranked": false, "weight_class": "L", "verified": false, "workout_type": false, "comments": "\n from speedcoach2v2.15 via rowsandall.com", "heart_rate": {"max": 158, "average": 156}, "source": "rowingdata", "date_utc": "2018-06-30 05:31:01", "time_formatted": "1:21:16.7", "time": 48767, "date": "2018-06-30 07:31:01", "timezone": "Europe/Prague", "type": "water", "id": 33991243, "stroke_data": true} +May-21-2021 09:06:14 Time zone Europe/Prague, stardatetime 2018-06-30 06:09:44.300000+02:00, duration 01:21:16.6 +May-21-2021 09:30:31 Upload to C2 user 1 +May-21-2021 09:30:31 {"type": "water", "date": "2016-05-20 13:50:26", "stroke_count": 189, "timezone": "Europe/Amsterdam", "distance": 2000, "time": 5400, "weight_class": "H", "comments": null, "stroke_rate": 21, "drag_factor": 104, "heart_rate": {"average": 148, "max": 156}, "stroke_data": [{"t": 32, "d": 131, "p": 2628, "spm": 19, "hr": 127}, {"t": 32, "d": 131, "p": 2394, "spm": 19, "hr": 127}, {"t": 61, "d": 210, "p": 1991, "spm": 20, "hr": 128}, {"t": 92, "d": 303, "p": 1764, "spm": 20, "hr": 129}, {"t": 121, "d": 390, "p": 1685, "spm": 20, "hr": 130}, {"t": 151, "d": 482, "p": 1639, "spm": 21, "hr": 131}, {"t": 181, "d": 576, "p": 1620, "spm": 20, "hr": 131}, {"t": 209, "d": 664, "p": 1597, "spm": 20, "hr": 132}, {"t": 238, "d": 755, "p": 1601, "spm": 21, "hr": 132}, {"t": 269, "d": 851, "p": 1589, "spm": 20, "hr": 132}, {"t": 296, "d": 950, "p": 1524, "spm": 21, "hr": 132}, {"t": 323, "d": 1050, "p": 1408, "spm": 22, "hr": 133}, {"t": 351, "d": 1153, "p": 1379, "spm": 21, "hr": 134}, {"t": 380, "d": 1258, "p": 1365, "spm": 21, "hr": 135}, {"t": 408, "d": 1366, "p": 1342, "spm": 21, "hr": 136}, {"t": 436, "d": 1472, "p": 1331, "spm": 22, "hr": 137}, {"t": 464, "d": 1576, "p": 1324, "spm": 22, "hr": 139}, {"t": 491, "d": 1678, "p": 1344, "spm": 21, "hr": 140}, {"t": 519, "d": 1785, "p": 1332, "spm": 22, "hr": 140}, {"t": 546, "d": 1885, "p": 1317, "spm": 21, "hr": 141}, {"t": 575, "d": 1993, "p": 1338, "spm": 21, "hr": 141}, {"t": 602, "d": 2094, "p": 1328, "spm": 22, "hr": 142}, {"t": 628, "d": 2194, "p": 1328, "spm": 22, "hr": 142}, {"t": 657, "d": 2302, "p": 1337, "spm": 22, "hr": 143}, {"t": 683, "d": 2402, "p": 1340, "spm": 22, "hr": 144}, {"t": 710, "d": 2501, "p": 1331, "spm": 23, "hr": 145}, {"t": 734, "d": 2596, "p": 1326, "spm": 23, "hr": 145}, {"t": 763, "d": 2703, "p": 1324, "spm": 23, "hr": 145}, {"t": 790, "d": 2806, "p": 1332, "spm": 22, "hr": 145}, {"t": 817, "d": 2907, "p": 1331, "spm": 22, "hr": 144}, {"t": 844, "d": 3008, "p": 1333, "spm": 23, "hr": 145}, {"t": 871, "d": 3111, "p": 1325, "spm": 22, "hr": 145}, {"t": 897, "d": 3212, "p": 1312, "spm": 22, "hr": 145}, {"t": 926, "d": 3319, "p": 1330, "spm": 21, "hr": 145}, {"t": 953, "d": 3420, "p": 1328, "spm": 22, "hr": 146}, {"t": 980, "d": 3524, "p": 1328, "spm": 22, "hr": 146}, {"t": 1008, "d": 3630, "p": 1321, "spm": 22, "hr": 146}, {"t": 1036, "d": 3734, "p": 1324, "spm": 22, "hr": 147}, {"t": 1063, "d": 3839, "p": 1322, "spm": 22, "hr": 147}, {"t": 1092, "d": 3946, "p": 1326, "spm": 22, "hr": 147}, {"t": 1119, "d": 4050, "p": 1335, "spm": 21, "hr": 147}, {"t": 1146, "d": 4153, "p": 1325, "spm": 22, "hr": 148}, {"t": 1176, "d": 4260, "p": 1329, "spm": 22, "hr": 148}, {"t": 1203, "d": 4365, "p": 1333, "spm": 21, "hr": 148}, {"t": 1231, "d": 4469, "p": 1335, "spm": 22, "hr": 148}, {"t": 1256, "d": 4569, "p": 1312, "spm": 22, "hr": 149}, {"t": 1284, "d": 4676, "p": 1316, "spm": 22, "hr": 149}, {"t": 1313, "d": 4785, "p": 1315, "spm": 22, "hr": 150}, {"t": 1341, "d": 4890, "p": 1318, "spm": 21, "hr": 150}, {"t": 1367, "d": 4991, "p": 1336, "spm": 21, "hr": 150}, {"t": 1397, "d": 5100, "p": 1329, "spm": 22, "hr": 150}, {"t": 1423, "d": 5199, "p": 1323, "spm": 22, "hr": 149}, {"t": 1451, "d": 5306, "p": 1327, "spm": 22, "hr": 149}, {"t": 1478, "d": 5408, "p": 1337, "spm": 22, "hr": 149}, {"t": 1505, "d": 5508, "p": 1334, "spm": 22, "hr": 148}, {"t": 1532, "d": 5608, "p": 1348, "spm": 22, "hr": 148}, {"t": 1559, "d": 5710, "p": 1333, "spm": 22, "hr": 147}, {"t": 1584, "d": 5807, "p": 1330, "spm": 22, "hr": 147}, {"t": 1612, "d": 5912, "p": 1329, "spm": 22, "hr": 147}, {"t": 1639, "d": 6014, "p": 1330, "spm": 22, "hr": 147}, {"t": 1666, "d": 6114, "p": 1321, "spm": 23, "hr": 147}, {"t": 1693, "d": 6218, "p": 1328, "spm": 23, "hr": 147}, {"t": 1720, "d": 6321, "p": 1317, "spm": 22, "hr": 147}, {"t": 1747, "d": 6423, "p": 1319, "spm": 22, "hr": 147}, {"t": 1772, "d": 6520, "p": 1310, "spm": 23, "hr": 148}, {"t": 1801, "d": 6627, "p": 1297, "spm": 23, "hr": 148}, {"t": 1826, "d": 6731, "p": 1296, "spm": 23, "hr": 148}, {"t": 1854, "d": 6836, "p": 1295, "spm": 22, "hr": 149}, {"t": 1880, "d": 6938, "p": 1297, "spm": 22, "hr": 149}, {"t": 1905, "d": 7038, "p": 1292, "spm": 22, "hr": 149}, {"t": 1934, "d": 7147, "p": 1297, "spm": 23, "hr": 150}, {"t": 1960, "d": 7249, "p": 1296, "spm": 22, "hr": 150}, {"t": 1987, "d": 7352, "p": 1306, "spm": 23, "hr": 151}, {"t": 2014, "d": 7454, "p": 1307, "spm": 22, "hr": 151}, {"t": 2041, "d": 7560, "p": 1291, "spm": 23, "hr": 151}, {"t": 2067, "d": 7663, "p": 1294, "spm": 22, "hr": 150}, {"t": 2094, "d": 7765, "p": 1300, "spm": 22, "hr": 150}, {"t": 2120, "d": 7869, "p": 1295, "spm": 23, "hr": 150}, {"t": 2147, "d": 7972, "p": 1290, "spm": 22, "hr": 150}, {"t": 2174, "d": 8078, "p": 1288, "spm": 23, "hr": 150}, {"t": 2201, "d": 8182, "p": 1286, "spm": 23, "hr": 150}, {"t": 2226, "d": 8284, "p": 1282, "spm": 22, "hr": 150}, {"t": 2254, "d": 8392, "p": 1279, "spm": 23, "hr": 150}, {"t": 2281, "d": 8496, "p": 1288, "spm": 23, "hr": 151}, {"t": 2307, "d": 8601, "p": 1272, "spm": 22, "hr": 151}, {"t": 2333, "d": 8703, "p": 1272, "spm": 22, "hr": 152}, {"t": 2361, "d": 8811, "p": 1280, "spm": 22, "hr": 152}, {"t": 2388, "d": 8917, "p": 1284, "spm": 23, "hr": 152}, {"t": 2415, "d": 9021, "p": 1293, "spm": 22, "hr": 152}, {"t": 2444, "d": 9131, "p": 1299, "spm": 22, "hr": 152}, {"t": 2472, "d": 9239, "p": 1309, "spm": 22, "hr": 153}, {"t": 2500, "d": 9346, "p": 1307, "spm": 21, "hr": 154}, {"t": 2528, "d": 9454, "p": 1320, "spm": 21, "hr": 154}, {"t": 2556, "d": 9560, "p": 1318, "spm": 21, "hr": 155}, {"t": 2585, "d": 9667, "p": 1326, "spm": 21, "hr": 155}, {"t": 2613, "d": 9774, "p": 1330, "spm": 21, "hr": 156}, {"t": 2641, "d": 9881, "p": 1310, "spm": 21, "hr": 156}, {"t": 2669, "d": 9988, "p": 1316, "spm": 21, "hr": 156}, {"t": 2698, "d": 10096, "p": 1327, "spm": 21, "hr": 156}, {"t": 2727, "d": 10206, "p": 1338, "spm": 21, "hr": 156}, {"t": 2757, "d": 10315, "p": 1345, "spm": 20, "hr": 156}, {"t": 2786, "d": 10425, "p": 1347, "spm": 21, "hr": 156}, {"t": 2815, "d": 10533, "p": 1347, "spm": 20, "hr": 155}, {"t": 2844, "d": 10641, "p": 1339, "spm": 21, "hr": 155}, {"t": 2874, "d": 10753, "p": 1354, "spm": 20, "hr": 155}, {"t": 2904, "d": 10861, "p": 1375, "spm": 20, "hr": 155}, {"t": 2935, "d": 10975, "p": 1359, "spm": 21, "hr": 155}, {"t": 2964, "d": 11085, "p": 1344, "spm": 20, "hr": 155}, {"t": 2993, "d": 11192, "p": 1353, "spm": 20, "hr": 155}, {"t": 3024, "d": 11306, "p": 1353, "spm": 20, "hr": 155}, {"t": 3054, "d": 11413, "p": 1353, "spm": 20, "hr": 155}, {"t": 3083, "d": 11524, "p": 1354, "spm": 21, "hr": 155}, {"t": 3113, "d": 11633, "p": 1367, "spm": 20, "hr": 155}, {"t": 3140, "d": 11738, "p": 1360, "spm": 20, "hr": 154}, {"t": 3170, "d": 11848, "p": 1342, "spm": 21, "hr": 154}, {"t": 3200, "d": 11958, "p": 1343, "spm": 21, "hr": 153}, {"t": 3229, "d": 12066, "p": 1357, "spm": 21, "hr": 152}, {"t": 3259, "d": 12173, "p": 1358, "spm": 21, "hr": 153}, {"t": 3287, "d": 12278, "p": 1363, "spm": 21, "hr": 152}, {"t": 3315, "d": 12387, "p": 1354, "spm": 21, "hr": 152}, {"t": 3345, "d": 12495, "p": 1334, "spm": 21, "hr": 151}, {"t": 3374, "d": 12601, "p": 1359, "spm": 20, "hr": 151}, {"t": 3403, "d": 12709, "p": 1357, "spm": 21, "hr": 151}, {"t": 3432, "d": 12818, "p": 1346, "spm": 21, "hr": 150}, {"t": 3461, "d": 12927, "p": 1355, "spm": 20, "hr": 151}, {"t": 3490, "d": 13034, "p": 1358, "spm": 20, "hr": 151}, {"t": 3519, "d": 13143, "p": 1357, "spm": 21, "hr": 151}, {"t": 3549, "d": 13252, "p": 1343, "spm": 21, "hr": 151}, {"t": 3578, "d": 13361, "p": 1352, "spm": 20, "hr": 152}, {"t": 3607, "d": 13469, "p": 1348, "spm": 21, "hr": 152}, {"t": 3636, "d": 13574, "p": 1358, "spm": 20, "hr": 152}, {"t": 3665, "d": 13681, "p": 1368, "spm": 21, "hr": 152}, {"t": 3694, "d": 13790, "p": 1355, "spm": 20, "hr": 152}, {"t": 3723, "d": 13895, "p": 1346, "spm": 21, "hr": 153}, {"t": 3751, "d": 13999, "p": 1369, "spm": 21, "hr": 152}, {"t": 3780, "d": 14107, "p": 1367, "spm": 20, "hr": 152}, {"t": 3811, "d": 14220, "p": 1364, "spm": 20, "hr": 152}, {"t": 3840, "d": 14328, "p": 1358, "spm": 20, "hr": 151}, {"t": 3869, "d": 14436, "p": 1344, "spm": 21, "hr": 151}, {"t": 3898, "d": 14544, "p": 1353, "spm": 20, "hr": 152}, {"t": 3927, "d": 14651, "p": 1351, "spm": 21, "hr": 151}, {"t": 3956, "d": 14759, "p": 1345, "spm": 21, "hr": 152}, {"t": 3984, "d": 14866, "p": 1336, "spm": 21, "hr": 152}, {"t": 4014, "d": 14974, "p": 1354, "spm": 21, "hr": 153}, {"t": 4043, "d": 15082, "p": 1363, "spm": 20, "hr": 153}, {"t": 4073, "d": 15192, "p": 1350, "spm": 20, "hr": 154}, {"t": 4102, "d": 15300, "p": 1351, "spm": 21, "hr": 154}, {"t": 4131, "d": 15409, "p": 1357, "spm": 20, "hr": 153}, {"t": 4159, "d": 15513, "p": 1351, "spm": 21, "hr": 153}, {"t": 4190, "d": 15626, "p": 1343, "spm": 21, "hr": 153}, {"t": 4219, "d": 15733, "p": 1359, "spm": 20, "hr": 153}, {"t": 4248, "d": 15842, "p": 1364, "spm": 20, "hr": 152}, {"t": 4276, "d": 15946, "p": 1345, "spm": 21, "hr": 152}, {"t": 4307, "d": 16060, "p": 1351, "spm": 21, "hr": 152}, {"t": 4334, "d": 16162, "p": 1369, "spm": 20, "hr": 152}, {"t": 4365, "d": 16274, "p": 1362, "spm": 21, "hr": 152}, {"t": 4394, "d": 16380, "p": 1349, "spm": 21, "hr": 152}, {"t": 4424, "d": 16492, "p": 1353, "spm": 20, "hr": 151}, {"t": 4453, "d": 16602, "p": 1353, "spm": 20, "hr": 152}, {"t": 4482, "d": 16708, "p": 1357, "spm": 20, "hr": 151}, {"t": 4511, "d": 16814, "p": 1361, "spm": 21, "hr": 151}, {"t": 4540, "d": 16921, "p": 1361, "spm": 21, "hr": 151}, {"t": 4568, "d": 17025, "p": 1358, "spm": 21, "hr": 150}, {"t": 4598, "d": 17137, "p": 1349, "spm": 21, "hr": 150}, {"t": 4627, "d": 17244, "p": 1344, "spm": 21, "hr": 150}, {"t": 4656, "d": 17351, "p": 1358, "spm": 20, "hr": 150}, {"t": 4685, "d": 17456, "p": 1361, "spm": 21, "hr": 150}, {"t": 4713, "d": 17563, "p": 1358, "spm": 21, "hr": 150}, {"t": 4740, "d": 17662, "p": 1357, "spm": 20, "hr": 151}, {"t": 4770, "d": 17771, "p": 1369, "spm": 22, "hr": 150}, {"t": 4798, "d": 17875, "p": 1369, "spm": 21, "hr": 150}, {"t": 4826, "d": 17977, "p": 1362, "spm": 22, "hr": 150}, {"t": 4855, "d": 18084, "p": 1361, "spm": 21, "hr": 150}, {"t": 4882, "d": 18184, "p": 1367, "spm": 21, "hr": 149}, {"t": 4910, "d": 18289, "p": 1344, "spm": 22, "hr": 149}, {"t": 4940, "d": 18399, "p": 1356, "spm": 21, "hr": 149}, {"t": 4968, "d": 18505, "p": 1357, "spm": 21, "hr": 148}, {"t": 4997, "d": 18612, "p": 1346, "spm": 21, "hr": 148}, {"t": 5027, "d": 18719, "p": 1354, "spm": 21, "hr": 147}, {"t": 5056, "d": 18826, "p": 1366, "spm": 20, "hr": 147}, {"t": 5084, "d": 18933, "p": 1363, "spm": 20, "hr": 148}, {"t": 5114, "d": 19043, "p": 1348, "spm": 21, "hr": 149}, {"t": 5144, "d": 19154, "p": 1336, "spm": 20, "hr": 149}, {"t": 5174, "d": 19262, "p": 1364, "spm": 20, "hr": 150}, {"t": 5203, "d": 19373, "p": 1361, "spm": 20, "hr": 151}, {"t": 5231, "d": 19478, "p": 1348, "spm": 20, "hr": 152}, {"t": 5262, "d": 19591, "p": 1355, "spm": 20, "hr": 152}, {"t": 5291, "d": 19698, "p": 1361, "spm": 20, "hr": 153}, {"t": 5320, "d": 19806, "p": 1353, "spm": 21, "hr": 153}, {"t": 5349, "d": 19914, "p": 1353, "spm": 21, "hr": 153}, {"t": 5372, "d": 20000, "p": 1340, "spm": 21, "hr": 154}], "workout": {"splits": [{"type": "distance", "time": 1397, "distance": 510, "heart_rate": {"average": 141}, "stroke_rate": 21}, {"type": "distance", "time": 1301, "distance": 499, "heart_rate": {"average": 150}, "stroke_rate": 22}, {"type": "distance", "time": 1344, "distance": 498, "heart_rate": {"average": 152}, "stroke_rate": 20}, {"type": "distance", "time": 1328, "distance": 491, "heart_rate": {"average": 150}, "stroke_rate": 20}]}} +May-21-2021 09:30:32 User 1, C2 ID 33991243 +May-21-2021 09:30:32 {"distance": 13878, "user_id": 457764, "ranked": false, "weight_class": "L", "verified": false, "workout_type": false, "comments": "\n from speedcoach2v2.15 via rowsandall.com", "heart_rate": {"max": 158, "average": 156}, "source": "rowingdata", "date_utc": "2018-06-30 05:31:01", "time_formatted": "1:21:16.7", "time": 48767, "date": "2018-06-30 07:31:01", "timezone": "Europe/Prague", "type": "water", "id": 33991243, "stroke_data": true} +May-21-2021 09:30:32 Time zone Europe/Prague, stardatetime 2018-06-30 06:09:44.300000+02:00, duration 01:21:16.6 \ No newline at end of file diff --git a/rowers/admin.py b/rowers/admin.py index 5c179e88..46ee9a17 100644 --- a/rowers/admin.py +++ b/rowers/admin.py @@ -46,7 +46,6 @@ class RowerInline(admin.StackedInline): 'sporttrackstoken','sporttrackstokenexpirydate', 'sporttracksrefreshtoken', 'sporttracks_auto_export', - 'mapmyfitness_auto_export', 'tptoken','tptokenexpirydate','tprefreshtoken', 'trainingpeaks_auto_export', 'polartoken','polartokenexpirydate', @@ -55,7 +54,6 @@ class RowerInline(admin.StackedInline): 'stravatoken','stravatokenexpirydate','stravarefreshtoken', 'stravaexportas','strava_auto_export', 'strava_auto_import', - 'runkeepertoken','runkeeper_auto_export', 'garmintoken','garminrefreshtoken')}), ('Team', {'fields':('friends','privacy','team')}), diff --git a/rowers/c2stuff.py b/rowers/c2stuff.py index e533a713..02cf4410 100644 --- a/rowers/c2stuff.py +++ b/rowers/c2stuff.py @@ -825,14 +825,9 @@ def make_authorization_url(request): # pragma: no cover return HttpResponseRedirect(url) # Get workout from C2 ID -def get_workout(user,c2id,do_async=False): +def get_workout(user,c2id,do_async=True): r = Rower.objects.get(user=user) - if (r.c2token == '') or (r.c2token is None): # pragma: no cover - s = "Token doesn't exist. Need to authorize" - return custom_exception_handler(401,s) ,0 - elif (timezone.now()>r.tokenexpirydate): - s = "Token expired. Needs to refresh." - return custom_exception_handler(401,s),0 + thetoken = c2_open(user) job = myqueue(queuehigh, handle_c2_getworkout, diff --git a/rowers/models.py b/rowers/models.py index 7b72f243..fc6150e0 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -988,7 +988,6 @@ class Rower(models.Model): sporttracksrefreshtoken = models.CharField(default='',max_length=200, blank=True,null=True) sporttracks_auto_export = models.BooleanField(default=False) - mapmyfitness_auto_export = models.BooleanField(default=False) tptoken = models.CharField(default='',max_length=1000,blank=True,null=True) tptokenexpirydate = models.DateTimeField(blank=True,null=True) tprefreshtoken = models.CharField(default='',max_length=1000, @@ -1037,9 +1036,6 @@ class Rower(models.Model): strava_auto_export = models.BooleanField(default=False) strava_auto_import = models.BooleanField(default=False) strava_auto_delete = models.BooleanField(default=False) - runkeepertoken = models.CharField(default='',max_length=200, - blank=True,null=True) - runkeeper_auto_export = models.BooleanField(default=False) privacychoices = ( @@ -3198,7 +3194,6 @@ class Workout(models.Model): uploadedtostrava = models.BigIntegerField(default=0) uploadedtosporttracks = models.BigIntegerField(default=0) uploadedtotp = models.BigIntegerField(default=0) - uploadedtorunkeeper = models.BigIntegerField(default=0) uploadedtogarmin = models.BigIntegerField(default=0) uploadedtorp3 = models.BigIntegerField(default=0) uploadedtonk = models.BigIntegerField(default=0) @@ -3279,7 +3274,6 @@ class TombStone(models.Model): uploadedtostrava = models.BigIntegerField(default=0) uploadedtosporttracks = models.BigIntegerField(default=0) uploadedtotp = models.BigIntegerField(default=0) - uploadedtorunkeeper = models.BigIntegerField(default=0) uploadedtonk = models.BigIntegerField(default=0) @receiver(models.signals.pre_delete,sender=Workout) @@ -3289,7 +3283,6 @@ def create_tombstone_on_delete(sender, instance, **kwargs): uploadedtoc2 = instance.uploadedtoc2, uploadedtostrava = instance.uploadedtostrava, uploadedtotp = instance.uploadedtotp, - uploadedtorunkeeper = instance.uploadedtorunkeeper, uploadedtonk = instance.uploadedtonk ) t.save() @@ -3864,8 +3857,6 @@ class RowerExportForm(ModelForm): 'c2_auto_export', 'c2_auto_import', 'nk_auto_import', - 'mapmyfitness_auto_export', - 'runkeeper_auto_export', 'sporttracks_auto_export', 'strava_auto_export', 'strava_auto_import', @@ -4208,8 +4199,6 @@ class RowerImportExportForm(ModelForm): 'polar_auto_import', 'c2_auto_export', 'c2_auto_import', - 'mapmyfitness_auto_export', - 'runkeeper_auto_export', 'sporttracks_auto_export', 'strava_auto_export', 'strava_auto_import', diff --git a/rowers/runkeeperstuff.py b/rowers/runkeeperstuff.py deleted file mode 100644 index cc3b6998..00000000 --- a/rowers/runkeeperstuff.py +++ /dev/null @@ -1,530 +0,0 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import unicode_literals, absolute_import -# All the functionality needed to connect to Runkeeper -from rowers.imports import * -import re - -import django_rq -queue = django_rq.get_queue('default') -queuelow = django_rq.get_queue('low') -queuehigh = django_rq.get_queue('low') -from rowers.utils import myqueue - -from rowers.rower_rules import is_workout_user - -from rowsandall_app.settings import ( - C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, - STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET, - RUNKEEPER_CLIENT_ID, RUNKEEPER_CLIENT_SECRET,RUNKEEPER_REDIRECT_URI, - ) - -from rowers.tasks import handle_runkeeper_sync - -oauth_data = { - 'client_id': RUNKEEPER_CLIENT_ID, - 'client_secret': RUNKEEPER_CLIENT_SECRET, - 'redirect_uri': RUNKEEPER_REDIRECT_URI, - 'autorization_uri': "https://www.runkeeper.com/apps/authorize", - 'content_type': 'application/x-www-form-urlencoded', - 'tokenname': 'runkeepertoken', - 'refreshtokenname': None, - 'expirydatename': None, - 'bearer_auth': True, - 'base_url': "https://runkeeper.com/apps/token", - 'headers': {'user-agent': 'sanderroosendaal'}, - 'scope':'write', - } - - -import numpy - -def splitrunkeeperlatlongdata(lijst,tname,latname,lonname): - t = [] - lat = [] - lon = [] - for d in lijst: - t.append(d[tname]) - lat.append(d[latname]) - lon.append(d[lonname]) - - return [np.array(t),np.array(lat),np.array(lon)] - -def splitrunkeeperdata(lijst,xname,yname): - x = [] - y = [] - for d in lijst: - x.append(d[xname]) - y.append(d[yname]) - - return [np.array(x),np.array(y)] - - -# Checks if user has SportTracks token, renews them if they are expired -def runkeeper_open(user): - return imports_open(user,oauth_data) - -# Exchange access code for long-lived access token -def get_token(code): - return imports_get_token(code,oauth_data) - -# Make authorization URL including random string -def make_authorization_url(request): # pragma: no cover - return imports_make_authorization_url(oauth_data) - -# Get list of workouts available on Runkeeper -def get_runkeeper_workout_list(user): - r = Rower.objects.get(user=user) - if (r.runkeepertoken == '') or (r.runkeepertoken is None): - s = "Token doesn't exist. Need to authorize" - return custom_exception_handler(401,s) - else: - # ready to fetch. Hurray - authorizationstring = str('Bearer ' + r.runkeepertoken) - headers = {'Authorization': authorizationstring, - 'user-agent': 'sanderroosendaal', - 'Content-Type': 'application/json'} - url = "https://api.runkeeper.com/fitnessActivities" - s = requests.get(url,headers=headers) - - return s - -# Get workout summary data by Runkeeper ID -def get_workout(user,runkeeperid,do_async=False): - r = Rower.objects.get(user=user) - if (r.runkeepertoken == '') or (r.runkeepertoken is None): # pragma: no cover - return custom_exception_handler(401,s) - s = "Token doesn't exist. Need to authorize" - else: - # ready to fetch. Hurray - authorizationstring = str('Bearer ' + r.runkeepertoken) - headers = {'Authorization': authorizationstring, - 'user-agent': 'sanderroosendaal', - 'Content-Type': 'application/json'} - url = "https://api.runkeeper.com/fitnessActivities/"+str(runkeeperid) - s = requests.get(url,headers=headers) - - try: - data = s.json() - except ValueError: # pragma: no cover - data = {} - return data,"Something went wrong with the workout import" - - strokedata = pd.DataFrame.from_dict({ - key: pd.Series(value) for key, value in data.items() - }) - - return data,strokedata - -# Create Workout Data for upload to SportTracks -def createrunkeeperworkoutdata(w): - filename = w.csvfilename - try: - row = rowingdata(csvfile=filename) - except: # pragma: no cover - return 0 - - try: - averagehr = int(row.df[' HRCur (bpm)'].mean()) - maxhr = int(row.df[' HRCur (bpm)'].max()) - except KeyError: # pragma: no cover - averagehr = 0 - maxhr = 0 - - duration = w.duration.hour*3600 - duration += w.duration.minute*60 - duration += w.duration.second - duration += +1.0e-6*w.duration.microsecond - - try: - t = row.df.loc[:,'TimeStamp (sec)'].values-row.df.loc[:,'TimeStamp (sec)'].iloc[0] - except KeyError: # pragma: no cover - return pd.DataFrame() - - t[0] = t[1] - - d = row.df.loc[:,'cum_dist'].values - d[0] = d[1] - t = t.astype(int) - d = d.astype(int) - spm = row.df[' Cadence (stokes/min)'].astype(int) - spm[0] = spm[1] - hr = row.df[' HRCur (bpm)'].astype(int) - - haslatlon=1 - - try: - lat = row.df[' latitude'].values - lon = row.df[' longitude'].values - if not lat.std() and not lon.std(): # pragma: no cover - haslatlon = 0 - except KeyError: # pragma: no cover - haslatlon = 0 - - t = t.tolist() - hr = hr.tolist() - d = d.tolist() - - # path data - if haslatlon: - lat = lat.tolist() - lon = lon.tolist() - locdata = [] - for e in zip(t,lat,lon): - point = {'timestamp':e[0], - 'latitude':e[1], - 'longitude':e[2], - 'altitude':0, - "type":"gps"} - locdata.append(point) - - hrdata = [] - for e in zip(t,hr): - point = {'timestamp':e[0], - 'heart_rate':e[1] - } - hrdata.append(point) - - distancedata = [] - for e in zip(t,d): - point = {'timestamp':e[0], - 'distance':e[1] - } - distancedata.append(point) - - st = w.startdatetime.astimezone(pytz.timezone(w.timezone)) - start_time = st.strftime("%a, %d %b %Y %H:%M:%S") - - try: - newnotes = w.notes+'\n from '+w.workoutsource+' via rowsandall.com' - except TypeError: - newnotes = 'from '+w.workoutsource+' via rowsandall.com' - - if haslatlon: - data = { - "type": "Rowing", - "start_time": start_time, - "total_distance": int(w.distance), - "duration": duration, - "notes": newnotes, - "average_heart_rate": averagehr, - "path": locdata, - "distance": distancedata, - "heart_rate": hrdata, - "post_to_twitter":"false", - "post_to_facebook":"false", - } - else: - data = { - "type": "Rowing", - "start_time": start_time, - "total_distance": int(w.distance), - "duration": duration, - "notes": newnotes, - "avg_heartrate": averagehr, - "distance": distancedata, - "heart_rate": hrdata, - "post_to_twitter":"false", - "post_to_facebook":"false", - } - - - return data - -# Obtain Runkeeper Workout ID from the response returned on successful -# upload -def getidfromresponse(response): - uri = response.headers["Location"] - - tester = re.compile('^\/fitnessActivities\/(\d+)$') - id = int(tester.match(uri).group(1)) - - return int(id) - -def geturifromid(access_token,id): # pragma: no cover - authorizationstring = str('Bearer ' + access_token) - headers = {'Authorization': authorizationstring, - 'user-agent': 'sanderroosendaal', - 'Content-Type': 'application/json'} - import urllib - url = "https://api.runkeeper.com/fitnessActivities/"+str(id) - response = requests.get(url,headers=headers) - try: - me_json = response.json() - except: - return '' - - try: - res = me_json['uri'] - except KeyError: - res = '' - - return res - - -# Get user id, having access token -# Handy for checking if the API access is working -def get_userid(access_token): - authorizationstring = str('Bearer ' + access_token) - headers = {'Authorization': authorizationstring, - 'user-agent': 'sanderroosendaal', - 'Content-Type': 'application/json'} - import urllib - url = "https://api.runkeeper.com/user" - response = requests.get(url,headers=headers) - - - try: - me_json = response.json() - except: # pragma: no cover - return '' - - try: - res = me_json['userID'] - except KeyError: # pragma: no cover - res = '' - - return str(res) - -def default(o): # pragma: no cover - if isinstance(o, numpy.int64): return int(o) - raise TypeError - -def workout_runkeeper_upload(user,w,asynchron=False): # pragma: no cover - message = "Uploading to Runkeeper" - rkid = 0 - - r = w.user - - - thetoken = runkeeper_open(r.user) - - # ready to upload. Hurray - - if (is_workout_user(user,w)): - data = createrunkeeperworkoutdata(w) - if not data: - message = "Data error in Runkeeper Upload" - rkid = 0 - return message, rkid - - authorizationstring = str('Bearer ' + thetoken) - headers = {'Authorization': authorizationstring, - 'user-agent': 'sanderroosendaal', - 'Content-Type': 'application/vnd.com.runkeeper.NewFitnessActivity+json', - 'Content-Length':'nnn'} - - url = "https://api.runkeeper.com/fitnessActivities" - if asynchron: - job = myqueue(queue,handle_runkeeper_sync, - w.id,url,headers,json.dumps(data,default=default)) - return "Asynchronous sync",0 - response = requests.post(url,headers=headers,data=json.dumps(data,default=default)) - - # check for duplicate error first - if (response.status_code == 409 ): - message = "Duplicate error" - w.uploadedtorunkeeper = -1 - rkid = -1 - w.save() - return message, rkid - elif (response.status_code == 201 or response.status_code==200): - rkid = getidfromresponse(response) - rkuri = geturifromid(thetoken,rkid) - w.uploadedtorunkeeper = rkid - w.save() - return 'Successfully synchronized to Runkeeper',rkid - else: - s = response - message = "Something went wrong in workout_runkeeper_upload_view: %s - %s" % (s.reason,s.text) - rkid = 0 - return message, rkid - - else: - message = "You are not authorized to upload this workout" - rkid = 0 - return message, rkid - - return message,rkid - -# Create workout from RunKeeper Data -def add_workout_from_data(user,importid,data,strokedata,source='runkeeper', - workoutsource='runkeeper'): - # To Do - add utcoffset to time - workouttype = data['type'] - if workouttype not in [x[0] for x in Workout.workouttypes]: - workouttype = 'other' - try: - comments = data['notes'] - except: # pragma: no cover - comments = '' - - try: - utcoffset = tz(data['utcoffset']) - except: - utcoffset = 0 - - r = Rower.objects.get(user=user) - - try: - rowdatetime = iso8601.parse_date(data['start_time']) - except iso8601.ParseError: - try: # pragma: no cover - rowdatetime = datetime.strptime(data['start_time'],"%Y-%m-%d %H:%M:%S") - rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc) - except ValueError: - try: - rowdatetime = parser.parse(data['start_time']) - #rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc) - except: # pragma: no cover - rowdatetime = datetime.strptime(data['date'],"%Y-%m-%d %H:%M:%S") - rowdatetime = thetimezone.localize(rowdatetime).astimezone(utc) - starttimeunix = arrow.get(rowdatetime).timestamp() - #starttimeunix = mktime(rowdatetime.utctimetuple()) - starttimeunix += utcoffset*3600 - - - try: - title = data['name'] - except: - title = "Imported data" - - - - res = splitrunkeeperdata(data['distance'],'timestamp','distance') - - distance = res[1] - times_distance = res[0] - - try: - l = data['path'] - - res = splitrunkeeperlatlongdata(l,'timestamp','latitude','longitude') - times_location = res[0] - latcoord = res[1] - loncoord = res[2] - - except: # pragma: no cover - times_location = times_distance - latcoord = np.zeros(len(times_distance)) - loncoord = np.zeros(len(times_distance)) - if workouttype in types.otwtypes: - workouttype = 'rower' - - try: # pragma: no cover - res = splitrunkeeperdata(data['cadence'],'timestamp','cadence') - times_spm = res[0] - spm = res[1] - except KeyError: - times_spm = times_distance - spm = 0*times_distance - - try: - res = splitrunkeeperdata(data['heart_rate'],'timestamp','heart_rate') - hr = res[1] - times_hr = res[0] - except KeyError: # pragma: no cover - times_hr = times_distance - hr = 0*times_distance - - - # create data series and remove duplicates - distseries = pd.Series(distance,index=times_distance) - distseries = distseries.groupby(distseries.index).first() - latseries = pd.Series(latcoord,index=times_location) - try: - latseries = latseries.groupby(latseries.index).first() - except TypeError: # pragma: no cover - latseries = 0.0*distseries - - lonseries = pd.Series(loncoord,index=times_location) - try: - lonseries = lonseries.groupby(lonseries.index).first() - except TypeError: # pragma: no cover - lonseries = 0.0*distseries - - spmseries = pd.Series(spm,index=times_spm) - spmseries = spmseries.groupby(spmseries.index).first() - hrseries = pd.Series(hr,index=times_hr) - try: - hrseries = hrseries.groupby(hrseries.index).first() - except TypeError: # pragma: no cover - hrseries = 0*distseries - - - # Create dicts and big dataframe - d = { - ' Horizontal (meters)': distseries, - ' latitude': latseries, - ' longitude': lonseries, - ' Cadence (stokes/min)': spmseries, - ' HRCur (bpm)' : hrseries, - } - - - - df = pd.DataFrame(d) - - df = df.groupby(level=0).last() - - cum_time = df.index.values - df[' ElapsedTime (sec)'] = cum_time - - velo = df[' Horizontal (meters)'].diff()/df[' ElapsedTime (sec)'].diff() - - df[' Power (watts)'] = 0.0*velo - - nr_rows = len(velo.values) - - df[' DriveLength (meters)'] = np.zeros(nr_rows) - df[' StrokeDistance (meters)'] = np.zeros(nr_rows) - df[' DriveTime (ms)'] = np.zeros(nr_rows) - df[' StrokeRecoveryTime (ms)'] = np.zeros(nr_rows) - df[' AverageDriveForce (lbs)'] = np.zeros(nr_rows) - df[' PeakDriveForce (lbs)'] = np.zeros(nr_rows) - df[' lapIdx'] = np.zeros(nr_rows) - - - - unixtime = cum_time+starttimeunix - try: - unixtime[0] = starttimeunix - except IndexError: # pragma: no cover - return (0,'No data to import') - - df['TimeStamp (sec)'] = unixtime - - - dt = np.diff(cum_time).mean() - wsize = round(5./dt) - - # velo2 = stravastuff.ewmovingaverage(velo,wsize) - - # df[' Stroke500mPace (sec/500m)'] = 500./velo2 - - - df = df.fillna(0) - - df.sort_values(by='TimeStamp (sec)',ascending=True) - - timestr = strftime("%Y%m%d-%H%M%S") - -# csvfilename ='media/Import_'+str(importid)+'.csv' - csvfilename ='media/{code}_{importid}.csv'.format( - importid=importid, - code = uuid4().hex[:16] - ) - - res = df.to_csv(csvfilename+'.gz',index_label='index', - compression='gzip') - - id,message = dataprep.save_workout_database(csvfilename,r, - workouttype=workouttype, - workoutsource='runkeeper', - title=title, - dosmooth=r.dosmooth, - notes=comments) - - return (id,message) diff --git a/rowers/sporttracksstuff.py b/rowers/sporttracksstuff.py index 09c54675..56ce890e 100644 --- a/rowers/sporttracksstuff.py +++ b/rowers/sporttracksstuff.py @@ -120,7 +120,14 @@ def get_workout(user,sporttracksid,do_async=False): key: pd.Series(value) for key, value in data.items() }) - return data,strokedata + id,message = add_workout_from_data( + user, + sporttracksid,data, + strokedata, + source='sporttracks', + workoutsource='sporttracks') + + return id # Create Workout Data for upload to SportTracks def createsporttracksworkoutdata(w): diff --git a/rowers/tasks.py b/rowers/tasks.py index df1a1c5d..35293887 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -25,7 +25,6 @@ from rowingdata import rowingdata as rdata from datetime import timedelta from sqlalchemy import create_engine -from rowers.imports import splituadata #from celery import app from rowers.celery import app diff --git a/rowers/templates/menu_workout.html b/rowers/templates/menu_workout.html index 2b77156f..1a10cc85 100644 --- a/rowers/templates/menu_workout.html +++ b/rowers/templates/menu_workout.html @@ -192,21 +192,6 @@ {% endif %} -
  • - {% if workout.uploadedtorunkeeper %} - - Runkeeper - - {% elif user.rower.runkeepertoken == None or user.rower.runkeepertoken == '' %} - - Connect to Runkeeper - - {% else %} - - Runkeeper - - {% endif %} -
  • {% if workout.uploadedtotp %} diff --git a/rowers/templates/menu_workouts.html b/rowers/templates/menu_workouts.html index 82045548..4d0e2d02 100644 --- a/rowers/templates/menu_workouts.html +++ b/rowers/templates/menu_workouts.html @@ -40,7 +40,6 @@
  • Concept2
  • Strava
  • -
  • RunKeeper
  • SportTracks
  • Polar
  • RP3
  • diff --git a/rowers/templates/rower_exportsettings.html b/rowers/templates/rower_exportsettings.html index d6aabe5d..7f77f1d2 100644 --- a/rowers/templates/rower_exportsettings.html +++ b/rowers/templates/rower_exportsettings.html @@ -29,9 +29,6 @@ {% if rower.stravatoken is not None and rower.stravatoken != '' %} Strava, {% endif %} - {% if rower.runkeepertoken is not None and rower.runkeepertoken != '' %} - Runkeeper, - {% endif %} {% if rower.rp3token is not None and rower.rp3token != '' %} RP3 {% endif %} @@ -76,7 +73,6 @@

    connect with Concept2

    connect with NK Logbook

    connect with SportTracks

    -

    connect with RunKeeper

    connect with Polar

    \d+)/',views.workout_polarimport_view,name='workout_polarimport_view'), - re_path(r'^workout/runkeeperimport/$',views.workout_runkeeperimport_view,name='workout_runkeeperimport_view'), - re_path(r'^workout/runkeeperimport/user/(?P\d+)/$',views.workout_runkeeperimport_view,name='workout_runkeeperimport_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/c2uploadw/$',views.workout_c2_upload_view,name='workout_c2_upload_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/stravauploadw/$',views.workout_strava_upload_view,name='workout_strava_upload_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/recalcsummary/$',views.workout_recalcsummary_view,name='workout_recalcsummary_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/sporttracksuploadw/$',views.workout_sporttracks_upload_view,name='workout_sporttracks_upload_view'), - re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/runkeeperuploadw/$',views.workout_runkeeper_upload_view,name='workout_runkeeper_upload_view'), re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/tpuploadw/$',views.workout_tp_upload_view,name='workout_tp_upload_view'), re_path(r'^multi-compare/workout/(?P\b[0-9A-Fa-f]+\b)/user/(?P\d+)/$',views.multi_compare_view, name='multi_compare_view'), @@ -599,7 +596,6 @@ urlpatterns = [ re_path(r'^me/sporttracksauthorize/$',views.rower_sporttracks_authorize,name='rower_sporttracks_authorize'), re_path(r'^me/tpauthorize/$',views.rower_tp_authorize,name='rower_tp_authorize'), re_path(r'^me/rp3authorize/$',views.rower_rp3_authorize,name='rower_rp3_authorize'), - re_path(r'^me/runkeeperauthorize/$',views.rower_runkeeper_authorize,name='rower_runkeeper_authorize'), re_path(r'^me/sporttracksrefresh/$',views.rower_sporttracks_token_refresh,name='rower_sporttracks_token_refresh'), re_path(r'^me/tprefresh/$',views.rower_tp_token_refresh,name='rower_tp_token_refresh'), re_path(r'^me/c2refresh/$',views.rower_c2_token_refresh,name='rower_c2_token_refresh'), diff --git a/rowers/utils.py b/rowers/utils.py index 2722def7..bd24e3f6 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -15,7 +15,7 @@ import uuid import datetime import json - +import time from fitparse import FitFile from django.conf import settings diff --git a/rowers/views/importviews.py b/rowers/views/importviews.py index c1740e50..7fd0d483 100644 --- a/rowers/views/importviews.py +++ b/rowers/views/importviews.py @@ -225,67 +225,6 @@ def workout_c2_upload_view(request,id=0): return response -# Upload workout to RunKeeper -@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True) -def workout_runkeeper_upload_view(request,id=0): - message = "" - w = get_workout(id) - r = w.user - - try: - thetoken = runkeeper_open(r.user) - except NoTokenError: # pragma: no cover - return HttpResponseRedirect("/rowers/me/runkeeperauthorize/") - - # ready to upload. Hurray - - - data = runkeeperstuff.createrunkeeperworkoutdata(w) - if not data: # pragma: no cover - message = "Data error" - messages.error(request,message) - url = reverse(r.defaultlandingpage, - kwargs = { - 'id':id, - }) - return HttpResponseRedirect(url) - - authorizationstring = str('Bearer ' + thetoken) - headers = {'Authorization': authorizationstring, - 'user-agent': 'sanderroosendaal', - 'Content-Type': 'application/vnd.com.runkeeper.NewFitnessActivity+json', - 'Content-Length':'nnn'} - - url = "https://api.runkeeper.com/fitnessActivities" - response = requests.post(url,headers=headers,data=json.dumps(data,default=default)) - - # check for duplicate error first - if (response.status_code == 409 ): # pragma: no cover # pragma: no cover - message = "Duplicate error" - messages.error(request,message) - w.uploadedtorunkeeper = -1 - w.save() - elif (response.status_code == 201 or response.status_code==200): - runkeeperid = runkeeperstuff.getidfromresponse(response) - w.uploadedtorunkeeper = runkeeperid - w.save() - url = reverse('workout_edit_view', - kwargs={'id':encoder.encode_hex(w.id)}) - - return HttpResponseRedirect(url) - else: # pragma: no cover - s = response - message = "Something went wrong in workout_runkeeper_upload_view: %s - %s" % (s.reason,s.text) - messages.error(request,message) - - - url = reverse(r.defaultlandingpage, - kwargs = { - 'id':encoder.encode_hex(w.id), - }) # pragma: no cover - - return HttpResponseRedirect(url) # pragma: no cover - # Upload workout to SportTracks @permission_required('workout.change_workout',fn=get_workout_by_opaqueid) @@ -384,6 +323,7 @@ def rower_c2_authorize(request): # pragma: no cover "redirect_uri": C2_REDIRECT_URI} url = "http://log.concept2.com/oauth/authorize?"+ urllib.parse.urlencode(params) url += "&scope="+scope + return HttpResponseRedirect(url) # Garmin authorization @@ -429,23 +369,6 @@ def rower_polar_authorize(request): # pragma: no cover -# Runkeeper authorization -@login_required() -def rower_runkeeper_authorize(request): # pragma: no cover - # Generate a random string for the state parameter - # Save it for use later to prevent xsrf attacks - - state = str(uuid4()) - - params = {"client_id": RUNKEEPER_CLIENT_ID, - "response_type": "code", - "state": state, - "redirect_uri": RUNKEEPER_REDIRECT_URI} - - url = "https://runkeeper.com/apps/authorize?"+ urllib.parse.urlencode(params) - - - return HttpResponseRedirect(url) # SportTracks Authorization @login_required() @@ -923,31 +846,6 @@ def rower_process_stravacallback(request): return HttpResponseRedirect(url) -# Process Runkeeper callback -@login_required() -def rower_process_runkeepercallback(request): - code = request.GET['code'] - res = runkeeperstuff.get_token(code) - access_token = res[0] - - if access_token == 0:# pragma: no cover - messages.error(request,"Something went wrong importing the token") - url = reverse('workouts_view') - - return HttpResponseRedirect(url) - - - - r = getrower(request.user) - r.runkeepertoken = access_token - - r.save() - - successmessage = "Tokens stored. Good to go. Please check your import/export settings" - messages.info(request,successmessage) - url = reverse('rower_exportsettings_view') - return HttpResponseRedirect(url) - # Process SportTracks callback @@ -1498,61 +1396,6 @@ def garmin_details_view(request): return HttpResponse(status=200) -# The page where you select which RunKeeper workout to import -@login_required() -@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) -def workout_runkeeperimport_view(request,message="",userid=0): - res = runkeeperstuff.get_runkeeper_workout_list(request.user) - if (res.status_code != 200): - if (res.status_code == 401): - r = getrower(request.user) - if (r.runkeepertoken == '') or (r.runkeepertoken is None): - s = "Token doesn't exist. Need to authorize" - return HttpResponseRedirect("/rowers/me/runkeeperauthorize/") - message = "Something went wrong in workout_runkeeperimport_view" # pragma: no cover - messages.error(request,message) # pragma: no cover - - if settings.DEBUG: # pragma: no cover - return HttpResponse(res) - else: # pragma: no cover - url = reverse('workouts_view') - return HttpResponseRedirect(url) - - workouts = [] - for item in res.json()['items']: - d = int(float(item['total_distance'])) - i = getidfromuri(item['uri']) - ttot = str(datetime.timedelta(seconds=int(float(item['duration'])))) - s = item['start_time'] - r = item['type'] - keys = ['id','distance','duration','starttime','type'] - values = [i,d,ttot,s,r] - - res = dict(zip(keys,values)) - workouts.append(res) - - breadcrumbs = [ - { - 'url':'/rowers/list-workouts/', - 'name':'Workouts' - }, - { - 'url':reverse('workout_runkeeperimport_view'), - 'name':'Runkeeper' - } - ] - - r = getrower(request.user) - - return render(request,'runkeeper_list_import.html', - {'workouts':workouts, - 'rower':r, - 'active':'nav-workouts', - 'breadcrumbs':breadcrumbs, - 'teams':get_my_teams(request.user), - }) - - return HttpResponse(res) # pragma: no cover # the page where you select which Polar workout to Import @@ -1853,18 +1696,26 @@ importlistviews = { 'strava':'workout_stravaimport_view', 'polar':'workout_polarimport_view', 'ownapi':'workout_view', - 'runkeeper':'workout_runkeeperimport_view', 'sporttracks':'workout_sporttracksimport_view', 'trainingpeaks':'workout_view', 'nk':'workout_nkimport_view', } +importauthorizeviews = { + 'c2':'rower_c2_authorize', + 'strava':'rower_strava_authorize', + 'polar':'rower_polar_authorize', + 'ownapi':'workout_view', + 'sporttracks':'rower_sporttracks_authorize', + 'trainingpeaks':'rower_tp_authorize', + 'nk':'rower_nk_authorize', +} + importsources = { 'c2':c2stuff, 'strava':stravastuff, 'polar':polarstuff, 'ownapi':ownapistuff, - 'runkeeper':runkeeperstuff, 'sporttracks':sporttracksstuff, 'trainingpeaks':tpstuff, 'nk':nkstuff, @@ -1894,8 +1745,12 @@ def workout_getrp3importview(request,externalid): @login_required() def workout_getimportview(request,externalid,source = 'c2',do_async=True): - result = importsources[source].get_workout(request.user,externalid, - do_async=do_async) + try: + result = importsources[source].get_workout(request.user,externalid, + do_async=do_async) + except NoTokenError: + + return HttpResponseRedirect(reverse(importauthorizeviews[source])) if result: # pragma: no cover messages.info(request,"Your workout will be imported in the background") @@ -1919,14 +1774,11 @@ def workout_getsporttracksworkout_all(request): ]) newids = [stid for stid in stids if not stid in knownstids] for sporttracksid in newids: - data,strokedata = sporttracksstuff.get_workout( + id = sporttracksstuff.get_workout( request.user,sporttracksid) - id,message = sporttracksstuff.add_workout_from_data( - request.user,sporttracksid,data,strokedata - ) if id==0: # pragma: no cover - messages.error(request,message) + messages.error(request,"Something went wrong with workout {id}".format(id=sporttracksid)) else: w = Workout.objects.get(id=id) diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 4b8c9ff1..db7dc791 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -158,7 +158,6 @@ import rowers.nkstuff as nkstuff from rowers.c2stuff import c2_open from rowers.nkstuff import nk_open from rowers.rp3stuff import rp3_open -from rowers.runkeeperstuff import runkeeper_open from rowers.sporttracksstuff import sporttracks_open from rowers.tpstuff import tp_open from iso8601 import ParseError @@ -170,7 +169,6 @@ import rowers.sporttracksstuff as sporttracksstuff import rowers.tpstuff as tpstuff -import rowers.runkeeperstuff as runkeeperstuff import rowers.rp3stuff as rp3stuff import rowers.ownapistuff as ownapistuff from rowers.ownapistuff import TEST_CLIENT_ID, TEST_CLIENT_SECRET, TEST_REDIRECT_URI @@ -180,7 +178,6 @@ from rowsandall_app.settings import ( POLAR_CLIENT_ID, POLAR_REDIRECT_URI, POLAR_CLIENT_SECRET, SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI, SPORTTRACKS_CLIENT_SECRET, - RUNKEEPER_CLIENT_ID,RUNKEEPER_REDIRECT_URI,RUNKEEPER_CLIENT_SECRET, TP_CLIENT_ID,TP_REDIRECT_URI,TP_CLIENT_KEY,TP_CLIENT_SECRET, RP3_CLIENT_ID,RP3_REDIRECT_URI,RP3_CLIENT_KEY,RP3_CLIENT_SECRET, BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY, diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index 8f23454d..394d10f1 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -4864,8 +4864,6 @@ def workout_upload_api(request): upload_to_c2 = optionsform.cleaned_data['upload_to_C2'] upload_to_strava = optionsform.cleaned_data['upload_to_Strava'] upload_to_st = optionsform.cleaned_data['upload_to_SportTracks'] - upload_to_rk = optionsform.cleaned_data['upload_to_RunKeeper'] - upload_to_ua = optionsform.cleaned_data['upload_to_MapMyFitness'] upload_to_tp = optionsform.cleaned_data['upload_to_TrainingPeaks'] makeprivate = optionsform.cleaned_data['makeprivate'] else: # pragma: no cover @@ -5042,8 +5040,6 @@ def workout_upload_view(request, upload_to_c2 = uploadoptions.get('upload_to_C2',False) upload_to_strava = uploadoptions.get('upload_to_Strava',False) upload_to_st = uploadoptions.get('upload_to_SportTracks',False) - upload_to_rk = uploadoptions.get('upload_to_RunKeeper',False) - upload_to_ua = uploadoptions.get('upload_to_MapMyFitness',False) upload_to_tp = uploadoptions.get('upload_to_TrainingPeaks',False) response = {} @@ -5093,8 +5089,6 @@ def workout_upload_view(request, upload_to_c2 = optionsform.cleaned_data['upload_to_C2'] upload_to_strava = optionsform.cleaned_data['upload_to_Strava'] upload_to_st = optionsform.cleaned_data['upload_to_SportTracks'] - upload_to_rk = optionsform.cleaned_data['upload_to_RunKeeper'] - upload_to_ua = optionsform.cleaned_data['upload_to_MapMyFitness'] upload_to_tp = optionsform.cleaned_data['upload_to_TrainingPeaks'] makeprivate = optionsform.cleaned_data['makeprivate'] landingpage = optionsform.cleaned_data['landingpage'] @@ -5112,8 +5106,6 @@ def workout_upload_view(request, 'upload_to_C2':upload_to_c2, 'upload_to_Strava':upload_to_strava, 'upload_to_SportTracks':upload_to_st, - 'upload_to_RunKeeper':upload_to_rk, - 'upload_to_MapMyFitness':upload_to_ua, 'upload_to_TrainingPeaks':upload_to_tp, 'landingpage':landingpage, 'boattype': boattype, @@ -5255,20 +5247,6 @@ def workout_upload_view(request, else: messages.error(request,message) - if (upload_to_rk): # pragma: no cover - try: - message,id = runkeeperstuff.workout_runkeeper_upload( - request.user,w - ) - except NoTokenError: - message = "Please connect to Runkeeper first" - id = 0 - - if id>1: - messages.info(request,message) - else: - messages.error(request,message) - if (upload_to_tp): # pragma: no cover try: @@ -5447,14 +5425,9 @@ def workout_upload_view(request, if r.sporttracks_auto_export and ispromember(r.user): # pragma: no cover uploadoptions['upload_to_SportTracks'] = True - if r.runkeeper_auto_export and ispromember(r.user): # pragma: no cover - uploadoptions['upload_to_RunKeeper'] = True - if r.trainingpeaks_auto_export and ispromember(r.user): # pragma: no cover uploadoptions['upload_to_TrainingPeaks'] = True - if r.mapmyfitness_auto_export and ispromember(r.user): # pragma: no cover - uploadoptions['upload_to_MapMyFitness'] = True form = DocumentsForm(initial=docformoptions) optionsform = UploadOptionsForm(initial=uploadoptions, diff --git a/rowsandall_app/urls.py b/rowsandall_app/urls.py index 6cf79af8..db752767 100644 --- a/rowsandall_app/urls.py +++ b/rowsandall_app/urls.py @@ -75,7 +75,6 @@ urlpatterns += [ re_path(r'^garmin\_callback',rowersviews.rower_process_garmincallback), re_path(r'^sporttracks\_callback',rowersviews.rower_process_sporttrackscallback), re_path(r'^polarflowcallback',rowersviews.rower_process_polarcallback), - re_path(r'^runkeeper\_callback',rowersviews.rower_process_runkeepercallback), re_path(r'^tp\_callback',rowersviews.rower_process_tpcallback), re_path(r'^rp3\_callback',rowersviews.rower_process_rp3callback), re_path(r'^twitter\_callback',rowersviews.rower_process_twittercallback),