Private
Public Access
1
0

alerts, analysis, api tested

This commit is contained in:
2024-04-21 10:56:37 +02:00
parent 85bd89d3d2
commit 409f4aff63
8 changed files with 124 additions and 117 deletions

View File

@@ -1,6 +1,6 @@
from rowers.models import Alert, Condition, User, Rower, Workout from rowers.models import Alert, Condition, User, Rower, Workout
from rowers.teams import coach_getcoachees from rowers.teams import coach_getcoachees
from rowers.dataprep import getsmallrowdata_db, getrowdata_db from rowers.dataprep import getrowdata_db, read_data, remove_nulls_pl
import datetime import datetime
import numpy as np import numpy as np
import math import math
@@ -101,8 +101,9 @@ def alert_get_stats(alert, nperiod=0): # pragma: no cover
ids = [w.id for w in workouts] ids = [w.id for w in workouts]
try: try:
df = getsmallrowdata_db(columns, ids=ids, doclean=True, df = read_data(columns, ids=ids, doclean=True,
workstrokesonly=workstrokesonly) workstrokesonly=workstrokesonly)
df = remove_nulls_pl(df)
except: except:
return { return {
'workouts': workouts.count(), 'workouts': workouts.count(),

View File

@@ -1417,10 +1417,10 @@ def update_strokedata(id, df, debug=False):
def testdata(time, distance, pace, spm): # pragma: no cover def testdata(time, distance, pace, spm): # pragma: no cover
t1 = np.issubdtype(time, np.number) t1 = time.dtype in pl.NUMERIC_DTYPES
t2 = np.issubdtype(distance, np.number) t2 = distance.dtype in pl.NUMERIC_DTYPES
t3 = np.issubdtype(pace, np.number) t3 = pace.dtype in pl.NUMERIC_DTYPES
t4 = np.issubdtype(spm, np.number) t4 = spm.dtype in pl.NUMERIC_DTYPES
return t1 and t2 and t3 and t4 return t1 and t2 and t3 and t4
@@ -1630,7 +1630,7 @@ def read_data(columns, ids=[], doclean=True, workstrokesonly=True, debug=False,
return datadf return datadf
def getsmallrowdata_db(columns, ids=[], doclean=True, workstrokesonly=True, compute=True, def getsmallrowdata_pd(columns, ids=[], doclean=True, workstrokesonly=True, compute=True,
debug=False, for_chart=False): debug=False, for_chart=False):
# prepmultipledata(ids) # prepmultipledata(ids)

View File

@@ -130,7 +130,8 @@ from rowers import mytypes
from rowers.dataroutines import ( from rowers.dataroutines import (
getsmallrowdata_db, updatecpdata_sql, update_c2id_sql, getsmallrowdata_pd, updatecpdata_sql, update_c2id_sql,
read_data,
#update_workout_field_sql, #update_workout_field_sql,
update_agegroup_db, update_strokedata, update_agegroup_db, update_strokedata,
add_c2_stroke_data_db, totaltime_sec_to_string, add_c2_stroke_data_db, totaltime_sec_to_string,

View File

@@ -43,10 +43,10 @@ class ListWorkoutTest(TestCase):
pass pass
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.read_data')
@patch('rowers.dataprep.myqueue') @patch('rowers.dataprep.myqueue')
def test_list_workouts(self, mocked_sqlalchemy, def test_list_workouts(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db, mocked_read_data,
mocked_myqueue): mocked_myqueue):
login = self.c.login(username=self.u.username, password=self.password) login = self.c.login(username=self.u.username, password=self.password)
@@ -170,7 +170,7 @@ class ForcecurveTest(TestCase):
@patch('rowers.dataprep.read_data',side_effect = mocked_read_data) @patch('rowers.dataprep.read_data',side_effect = mocked_read_data)
def test_forcecurve_plot(self, mocked_getsmallrowdata_db): def test_forcecurve_plot(self, mocked_read_data):
login = self.c.login(username=self.u.username, password = self.password) login = self.c.login(username=self.u.username, password = self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -296,9 +296,9 @@ class WorkoutCompareTestNew(TestCase):
pass pass
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.read_data')
def test_workouts_compare(self, mocked_sqlalchemy, def test_workouts_compare(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username, password=self.password) login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -309,9 +309,9 @@ class WorkoutCompareTestNew(TestCase):
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) @patch('rowers.dataprep.read_data', side_effect=mocked_read_data)
def test_workouts_compare_submit(self, mocked_sqlalchemy, def test_workouts_compare_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -398,9 +398,9 @@ class WorkoutBoxPlotTestNew(TestCase):
pass pass
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.read_data')
def test_workouts_boxplot(self, mocked_sqlalchemy, def test_workouts_boxplot(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username, password=self.password) login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -411,9 +411,9 @@ class WorkoutBoxPlotTestNew(TestCase):
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) @patch('rowers.dataprep.read_data', side_effect=mocked_read_data)
def test_workouts_boxplot_submit(self, mocked_sqlalchemy, def test_workouts_boxplot_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -499,9 +499,9 @@ class WorkoutHistoTestNew(TestCase):
pass pass
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.read_data')
def test_workouts_histo(self, mocked_sqlalchemy, def test_workouts_histo(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username, password=self.password) login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -512,9 +512,9 @@ class WorkoutHistoTestNew(TestCase):
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) @patch('rowers.dataprep.read_data', side_effect=mocked_read_data)
def test_workouts_histo_submit(self, mocked_sqlalchemy, def test_workouts_histo_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -618,9 +618,9 @@ class History(TestCase):
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) @patch('rowers.dataprep.read_data', side_effect=mocked_read_data)
def test_workouts_history_submit(self, mocked_sqlalchemy, def test_workouts_history_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -713,9 +713,9 @@ class GoldMedalScores(TestCase):
pass pass
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.read_data')
def test_workouts_goldmedalscores(self, mocked_sqlalchemy, def test_workouts_goldmedalscores(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
ws = Workout.objects.filter(rankingpiece=True) ws = Workout.objects.filter(rankingpiece=True)
self.assertEqual(ws.count(),2) self.assertEqual(ws.count(),2)
@@ -729,9 +729,9 @@ class GoldMedalScores(TestCase):
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) @patch('rowers.dataprep.read_data', side_effect=mocked_read_data)
def test_workouts_goldmedalscores_submit(self, mocked_sqlalchemy, def test_workouts_goldmedalscores_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -795,9 +795,9 @@ class WorkoutFlexallTestNew(TestCase):
pass pass
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.read_data')
def test_workouts_flexall(self, mocked_sqlalchemy, def test_workouts_flexall(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username, password=self.password) login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -808,9 +808,9 @@ class WorkoutFlexallTestNew(TestCase):
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) @patch('rowers.dataprep.read_data', side_effect=mocked_read_data)
def test_workouts_flexall_submit(self, mocked_sqlalchemy, def test_workouts_flexall_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -903,9 +903,9 @@ class WorkoutStatsTestNew(TestCase):
pass pass
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.read_data')
def test_workouts_stats(self, mocked_sqlalchemy, def test_workouts_stats(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username, password=self.password) login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -920,7 +920,7 @@ class WorkoutStatsTestNew(TestCase):
@patch('rowers.dataprep.read_cols_df_sql', side_effect=mocked_read_cols_df_sql) @patch('rowers.dataprep.read_cols_df_sql', side_effect=mocked_read_cols_df_sql)
def test_analysis_data(self, def test_analysis_data(self,
mocked_sqlalchemy, mocked_sqlalchemy,
mocked_getsmallrowdata_db, mocked_read_data,
mocked_read_cols_df_sql, mocked_read_cols_df_sql,
): ):
@@ -979,11 +979,11 @@ class WorkoutStatsTestNew(TestCase):
script, div = comparisondata(workouts,options) script, div = comparisondata(workouts,options)
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) @patch('rowers.dataprep.read_data', side_effect=mocked_read_data)
@patch('rowers.dataprep.read_cols_df_sql', side_effect=mocked_read_cols_df_sql) @patch('rowers.dataprep.read_cols_df_sql', side_effect=mocked_read_cols_df_sql)
def test_analysis_data2(self, def test_analysis_data2(self,
mocked_sqlalchemy, mocked_sqlalchemy,
mocked_getsmallrowdata_db, mocked_read_data,
mocked_read_cols_df_sql, mocked_read_cols_df_sql,
): ):
@@ -1042,11 +1042,11 @@ class WorkoutStatsTestNew(TestCase):
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) @patch('rowers.dataprep.read_data', side_effect=mocked_read_data)
@patch('rowers.dataprep.read_cols_df_sql', side_effect=mocked_read_cols_df_sql) @patch('rowers.dataprep.read_cols_df_sql', side_effect=mocked_read_cols_df_sql)
def test_analysis_data2(self, def test_analysis_data2(self,
mocked_sqlalchemy, mocked_sqlalchemy,
mocked_getsmallrowdata_db, mocked_read_data,
mocked_read_cols_df_sql, mocked_read_cols_df_sql,
): ):
@@ -1120,9 +1120,9 @@ class WorkoutStatsTestNew(TestCase):
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) @patch('rowers.dataprep.read_data', side_effect=mocked_read_data)
def test_workouts_stats_submit(self, mocked_sqlalchemy, def test_workouts_stats_submit(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -1241,9 +1241,9 @@ class MarkerPerformanceTest(TestCase):
pass pass
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.read_data')
def test_create_marker_workouts(self, mocked_sqlalchemy, def test_create_marker_workouts(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -1326,9 +1326,9 @@ class MarkerPerformanceTest(TestCase):
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.read_data')
def test_performancemanager_view(self, mocked_sqlalchemy, def test_performancemanager_view(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)
@@ -1413,9 +1413,9 @@ class AlertTest(TestCase):
pass pass
@patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.create_engine')
@patch('rowers.alerts.getsmallrowdata_db') @patch('rowers.alerts.read_data')
def test_alerts(self, mocked_sqlalchemy, def test_alerts(self, mocked_sqlalchemy,
mocked_getsmallrowdata_db): mocked_read_data):
login = self.c.login(username=self.u.username,password=self.password) login = self.c.login(username=self.u.username,password=self.password)
self.assertTrue(login) self.assertTrue(login)

View File

@@ -67,10 +67,11 @@ class OwnApi(TestCase):
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
# response must be json # response must be json
strokedata = json.loads(response.content) strokedata = json.loads(response.content)
df = pd.DataFrame(strokedata) df = pl.from_dict(strokedata)
self.assertFalse(df.empty) self.assertFalse(df.is_empty())
form_data = { form_data = {
"distance": [23, 46, 48], "distance": [23, 46, 48],
@@ -124,8 +125,8 @@ class OwnApi(TestCase):
# response must be json # response must be json
strokedata = json.loads(response.content) strokedata = json.loads(response.content)
df = pd.DataFrame(strokedata) df = pl.from_dicts(strokedata['data'])
self.assertFalse(df.empty) self.assertFalse(df.is_empty())
form_data = { form_data = {

View File

@@ -612,7 +612,7 @@ def histodata(workouts, options):
if savedata: # pragma: no cover if savedata: # pragma: no cover
workstrokesonly = not includereststrokes workstrokesonly = not includereststrokes
ids = [int(w.id) for w in workouts] ids = [int(w.id) for w in workouts]
df = dataprep.getsmallrowdata_db([plotfield], ids=ids, df = dataprep.read_data([plotfield], ids=ids,
workstrokesonly=workstrokesonly, workstrokesonly=workstrokesonly,
doclean=True, doclean=True,
) )
@@ -885,7 +885,7 @@ def comparisondata(workouts, options):
'time', 'pace', 'workoutstate', 'time', 'pace', 'workoutstate',
'workoutid'] 'workoutid']
df = dataprep.getsmallrowdata_db(columns, ids=ids, df = dataprep.read_data(columns, ids=ids,
workstrokesonly=workstrokesonly, workstrokesonly=workstrokesonly,
doclean=True, doclean=True,
) )

View File

@@ -68,102 +68,102 @@ def strokedataform(request, id=0):
def api_get_dataframe(startdatetime, df): def api_get_dataframe(startdatetime, df):
try: try:
time = df['time']/1.e3 time = df['time']/1.e3
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
try: try:
time = df['t']/10. time = df['t']/10.
except KeyError: except (KeyError, ColumnNotFoundError):
return 400, "Missing time", pd.DataFrame() return 400, "Missing time", pl.DataFrame()
try: try:
spm = df['spm'] spm = df['spm']
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
return 400, "Missing spm", pd.DataFrame() return 400, "Missing spm", pl.DataFrame()
try: try:
distance = df['distance'] distance = df['distance']
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
try: try:
distance = df['d']/10. distance = df['d']/10.
except KeyError: except (KeyError, ColumnNotFoundError):
return 400, "Missing distance", pd.DataFrame() return 400, "Missing distance", pl.DataFrame()
try: try:
pace = df['pace']/1.e3 pace = df['pace']/1.e3
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
try: try:
pace = df['p']/10. pace = df['p']/10.
except KeyError: except (KeyError, ColumnNotFoundError):
return 400, "Missing pace", pd.DataFrame() return 400, "Missing pace", pl.DataFrame()
try: try:
power = df['power'] power = df['power']
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
power = 0*time power = 0*time
try: try:
drivelength = df['drivelength'] drivelength = df['drivelength']
except KeyError: except (KeyError, ColumnNotFoundError):
drivelength = 0*time drivelength = 0*time
try: try:
dragfactor = df['dragfactor'] dragfactor = df['dragfactor']
except KeyError: except (KeyError, ColumnNotFoundError):
dragfactor = 0*time dragfactor = 0*time
try: try:
drivetime = df['drivetime'] drivetime = df['drivetime']
except KeyError: except (KeyError, ColumnNotFoundError):
drivetime = 0*time drivetime = 0*time
try: try:
strokerecoverytime = df['strokerecoverytime'] strokerecoverytime = df['strokerecoverytime']
except KeyError: except (KeyError, ColumnNotFoundError):
strokerecoverytime = 0*time strokerecoverytime = 0*time
try: try:
averagedriveforce = df['averagedriveforce'] averagedriveforce = df['averagedriveforce']
except KeyError: except (KeyError, ColumnNotFoundError):
averagedriveforce = 0*time averagedriveforce = 0*time
try: try:
peakdriveforce = df['peakdriveforce'] peakdriveforce = df['peakdriveforce']
except KeyError: except (KeyError, ColumnNotFoundError):
peakdriveforce = 0*time peakdriveforce = 0*time
try: try:
wash = df['wash'] wash = df['wash']
except KeyError: except (KeyError, ColumnNotFoundError):
wash = 0*time wash = 0*time
try: try:
catch = df['catch'] catch = df['catch']
except KeyError: except (KeyError, ColumnNotFoundError):
catch = 0*time catch = 0*time
try: try:
finish = df['finish'] finish = df['finish']
except KeyError: except (KeyError, ColumnNotFoundError):
finish = 0*time finish = 0*time
try: try:
peakforceangle = df['peakforceangle'] peakforceangle = df['peakforceangle']
except KeyError: except (KeyError, ColumnNotFoundError):
peakforceangle = 0*time peakforceangle = 0*time
try: try:
driveenergy = df['driveenergy'] driveenergy = df['driveenergy']
except KeyError: except (KeyError, ColumnNotFoundError):
driveenergy = 60.*power/spm driveenergy = 60.*power/spm
try: try:
slip = df['slip'] slip = df['slip']
except KeyError: except (KeyError, ColumnNotFoundError):
slip = 0*time slip = 0*time
try: try:
lapidx = df['lapidx'] lapidx = df['lapidx']
except KeyError: except (KeyError, ColumnNotFoundError):
lapidx = 0*time lapidx = 0*time
try: try:
hr = df['hr'] hr = df['hr']
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
hr = 0*df['time'] hr = 0*df['time']
try: try:
latitude = df['latitude'] latitude = df['latitude']
except KeyError: except (KeyError, ColumnNotFoundError):
latitude = 0*df['time'] latitude = 0*df['time']
try: try:
longitude = df['longitude'] longitude = df['longitude']
except KeyError: except (KeyError, ColumnNotFoundError):
longitude = 0*df['time'] longitude = 0*df['time']
starttime = totimestamp(startdatetime)+time[0] starttime = totimestamp(startdatetime)+time[0]
@@ -171,7 +171,7 @@ def api_get_dataframe(startdatetime, df):
dologging('apilog.log',"(strokedatajson_v2/3 POST - data parsed)") dologging('apilog.log',"(strokedatajson_v2/3 POST - data parsed)")
data = pd.DataFrame({'TimeStamp (sec)': unixtime, data = pl.DataFrame({'TimeStamp (sec)': unixtime,
' Horizontal (meters)': distance, ' Horizontal (meters)': distance,
' Cadence (stokes/min)': spm, ' Cadence (stokes/min)': spm,
' HRCur (bpm)': hr, ' HRCur (bpm)': hr,
@@ -522,7 +522,7 @@ def strokedatajson_v3(request):
title = request.data.get('name','') title = request.data.get('name','')
try: try:
elapsedTime = request.data['elapsedTime'] elapsedTime = request.data['elapsedTime']
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
try: try:
duration = request.data['duration'] duration = request.data['duration']
try: try:
@@ -534,7 +534,7 @@ def strokedatajson_v3(request):
return HttpResponse("Missing Elapsed Time", status=400) return HttpResponse("Missing Elapsed Time", status=400)
try: try:
totalDistance = request.data['distance'] totalDistance = request.data['distance']
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
return HttpResponse("Missing Total Distance", status=400) return HttpResponse("Missing Total Distance", status=400)
timeZone = request.data.get('timezone','UTC') timeZone = request.data.get('timezone','UTC')
workouttype = request.data.get('workouttype','rower') workouttype = request.data.get('workouttype','rower')
@@ -552,23 +552,21 @@ def strokedatajson_v3(request):
dologging('apilog.log',totalDistance) dologging('apilog.log',totalDistance)
dologging('apilog.log',elapsedTime) dologging('apilog.log',elapsedTime)
df = pd.DataFrame() df = pl.DataFrame()
try: try:
strokes = request.data['strokes'] strokes = request.data['strokes']
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
return HttpResponse("No Stroke Data in JSON", status=400) return HttpResponse("No Stroke Data in JSON", status=400)
try: try:
df = pd.DataFrame(strokes['data']) df = pl.DataFrame(strokes['data'])
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
try: try:
df = pd.DataFrame(request.data['strokedata']) df = pl.DataFrame(request.data['strokedata'])
except: except:
return HttpResponse("No JSON Object could be decoded", status=400) return HttpResponse("No JSON Object could be decoded", status=400)
df.index = df.index.astype(int) df = df.sort("time")
df.sort_index(inplace=True)
status, comment, data = api_get_dataframe(startdatetime, df) status, comment, data = api_get_dataframe(startdatetime, df)
if status != 200: # pragma: no cover if status != 200: # pragma: no cover
@@ -576,7 +574,8 @@ def strokedatajson_v3(request):
csvfilename = 'media/{code}.csv.gz'.format(code=uuid4().hex[:16]) csvfilename = 'media/{code}.csv.gz'.format(code=uuid4().hex[:16])
_ = data.to_csv(csvfilename, index_label='index', compression='gzip') with gzip.open(csvfilename, 'w') as f:
_ = data.write_csv(f)
duration = datetime.time(0,0,1) duration = datetime.time(0,0,1)
w = Workout( w = Workout(
@@ -667,10 +666,11 @@ def strokedatajson_v2(request, id):
if request.method == 'GET': if request.method == 'GET':
columns = ['spm', 'time', 'hr', 'pace', 'power', 'distance'] columns = ['spm', 'time', 'hr', 'pace', 'power', 'distance']
datadf = dataprep.getsmallrowdata_db(columns, ids=[id]) datadf = dataprep.read_data(columns, ids=[id])
datadf = dataprep.remove_nulls_pl(datadf)
dologging('apilog.log',request.user.username+"(strokedatajson_v2 GET)") dologging('apilog.log',request.user.username+"(strokedatajson_v2 GET)")
data = datadf.to_json(orient='records') data = datadf.write_json(row_oriented=True)
data2 = json.loads(data) data2 = json.loads(data)
data2 = {"data": data2} data2 = {"data": data2}
@@ -681,28 +681,27 @@ def strokedatajson_v2(request, id):
try: try:
for d in request.data['data']: for d in request.data['data']:
dologging('apilog.log',json.dumps(d)) dologging('apilog.log',json.dumps(d))
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
try: try:
for d in request.data['strokedata']: for d in request.data['strokedata']:
dologging('apilog.log',json.dumps(d)) dologging('apilog.log',json.dumps(d))
except KeyError: except (KeyError, ColumnNotFoundError):
dologging('apilog.log','No data in request.data') dologging('apilog.log','No data in request.data')
checkdata, r = dataprep.getrowdata_db(id=row.id) checkdata, r = dataprep.getrowdata_db(id=row.id)
if not checkdata.empty: # pragma: no cover if not checkdata.empty: # pragma: no cover
return HttpResponse("Duplicate Error", status=409) return HttpResponse("Duplicate Error", status=409)
df = pd.DataFrame() df = pl.DataFrame()
try: try:
df = pd.DataFrame(request.data['data']) df = pl.DataFrame(request.data['data'])
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
try: try:
df = pd.DataFrame(request.data['strokedata']) df = pl.DataFrame(request.data['strokedata'])
except: except:
return HttpResponse("No JSON object could be decoded", status=400) return HttpResponse("No JSON object could be decoded", status=400)
df.index = df.index.astype(int) df = df.sort("time")
df.sort_index(inplace=True)
status, comment, data = api_get_dataframe(row.startdatetime, df) status, comment, data = api_get_dataframe(row.startdatetime, df)
if status != 200: # pragma: no cover if status != 200: # pragma: no cover
@@ -724,7 +723,8 @@ def strokedatajson_v2(request, id):
row.duplicate = True row.duplicate = True
row.save() row.save()
_ = data.to_csv(csvfilename+'.gz', index_label='index', compression='gzip') with gzip.open(csvfilename+'.gz', 'w') as f:
_ = data.write_csv(f)
row.csvfilename = csvfilename row.csvfilename = csvfilename
row.save() row.save()
@@ -796,7 +796,11 @@ def strokedatajson(request, id=0):
if request.method == 'GET': if request.method == 'GET':
# currently only returns a subset. # currently only returns a subset.
columns = ['spm', 'time', 'hr', 'pace', 'power', 'distance'] columns = ['spm', 'time', 'hr', 'pace', 'power', 'distance']
datadf = dataprep.getsmallrowdata_db(columns, ids=[id])
datadf = dataprep.read_data(columns, ids=[id])
datadf = dataprep.remove_nulls_pl(datadf)
datadf = datadf.to_pandas()
dologging("apilog.log",request.user.username+"(strokedatajson GET) ") dologging("apilog.log",request.user.username+"(strokedatajson GET) ")
return JSONResponse(datadf) return JSONResponse(datadf)
@@ -817,14 +821,13 @@ def strokedatajson(request, id=0):
return HttpResponse("No JSON object could be decoded", status=400) return HttpResponse("No JSON object could be decoded", status=400)
try: try:
df = pd.DataFrame(strokedata) df = pl.DataFrame(strokedata)
except ValueError: # pragma: no cover except ValueError: # pragma: no cover
return HttpResponse("Arrays must all be same length", status=400) return HttpResponse("Arrays must all be same length", status=400)
df.index = df.index.astype(int) df = df.sort("time")
df.sort_index(inplace=True)
try: try:
time = df['time']/1.e3 time = df['time']/1.e3
except KeyError: # pragma: no cover except (KeyError, ColumnNotFoundError): # pragma: no cover
return HttpResponse("There must be time values", status=400) return HttpResponse("There must be time values", status=400)
aantal = len(time) aantal = len(time)
pace = df['pace']/1.e3 pace = df['pace']/1.e3
@@ -863,7 +866,7 @@ def strokedatajson(request, id=0):
dologging("apilog.log",request.user.username+"(POST)") dologging("apilog.log",request.user.username+"(POST)")
data = pd.DataFrame({'TimeStamp (sec)': unixtime, data = pl.DataFrame({'TimeStamp (sec)': unixtime,
' Horizontal (meters)': distance, ' Horizontal (meters)': distance,
' Cadence (stokes/min)': spm, ' Cadence (stokes/min)': spm,
' HRCur (bpm)': hr, ' HRCur (bpm)': hr,
@@ -890,8 +893,8 @@ def strokedatajson(request, id=0):
timestr = row.startdatetime.strftime("%Y%m%d-%H%M%S") timestr = row.startdatetime.strftime("%Y%m%d-%H%M%S")
csvfilename = 'media/Import_'+timestr+'.csv' csvfilename = 'media/Import_'+timestr+'.csv'
res = data.to_csv(csvfilename+'.gz', index_label='index', with gzip.open(csvfilename+'.gz','w') as f:
compression='gzip') res = data.write_csv(f)
row.csvfilename = csvfilename row.csvfilename = csvfilename
row.save() row.save()

View File

@@ -16,7 +16,7 @@ from rowers.utils import (
from rowers.celery import result as celery_result from rowers.celery import result as celery_result
from rowers.interactiveplots import * from rowers.interactiveplots import *
from scipy.interpolate import griddata from scipy.interpolate import griddata
from rowers.dataprep import getsmallrowdata_db, read_data from rowers.dataprep import getsmallrowdata_pd, read_data
from rowers.dataprep import timedeltaconv from rowers.dataprep import timedeltaconv
from scipy.special import lambertw from scipy.special import lambertw
from io import BytesIO from io import BytesIO
@@ -35,6 +35,7 @@ import threading
import redis import redis
import colorsys import colorsys
import re import re
import gzip
import zipfile import zipfile
import bleach import bleach
import arrow import arrow
@@ -1345,9 +1346,9 @@ def trydf(df, aantal, column): # pragma: no cover
s = df[column] s = df[column]
if len(s) != aantal: if len(s) != aantal:
return np.zeros(aantal) return np.zeros(aantal)
if not np.issubdtype(s, np.number): if not s.dtype in pl.NUMERIC_DTYPES:
return np.zeros(aantal) return np.zeros(aantal)
except KeyError: except (KeyError, ColumnNotFoundError):
s = np.zeros(aantal) s = np.zeros(aantal)
return s return s