API: only one column to store record values
This commit is contained in:
parent
5d6a095348
commit
55c2cd54a3
@ -1,6 +1,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from mpwo_api import db
|
from mpwo_api import db
|
||||||
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
from sqlalchemy.types import Enum
|
from sqlalchemy.types import Enum
|
||||||
|
|
||||||
record_types = [
|
record_types = [
|
||||||
@ -64,8 +65,8 @@ class Activity(db.Model):
|
|||||||
max_alt = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
max_alt = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
||||||
descent = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
descent = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
||||||
ascent = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
ascent = db.Column(db.Numeric(5, 2), nullable=True) # meters
|
||||||
max_speed = db.Column(db.Numeric(5, 3), nullable=True) # km/h
|
max_speed = db.Column(db.Numeric(5, 2), nullable=True) # km/h
|
||||||
ave_speed = db.Column(db.Numeric(5, 3), nullable=True) # km/h
|
ave_speed = db.Column(db.Numeric(5, 2), nullable=True) # km/h
|
||||||
records = db.relationship('Record',
|
records = db.relationship('Record',
|
||||||
lazy=True,
|
lazy=True,
|
||||||
backref=db.backref('activities', lazy='joined'))
|
backref=db.backref('activities', lazy='joined'))
|
||||||
@ -125,8 +126,7 @@ class Record(db.Model):
|
|||||||
nullable=False)
|
nullable=False)
|
||||||
record_type = db.Column(Enum(*record_types, name="record_types"))
|
record_type = db.Column(Enum(*record_types, name="record_types"))
|
||||||
activity_date = db.Column(db.DateTime, nullable=False)
|
activity_date = db.Column(db.DateTime, nullable=False)
|
||||||
value_interval = db.Column(db.Interval, nullable=True)
|
_value = db.Column("value", db.Integer, nullable=True)
|
||||||
value_float = db.Column(db.Numeric(5, 3), nullable=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.sports.label) + \
|
return str(self.sports.label) + \
|
||||||
@ -140,7 +140,36 @@ class Record(db.Model):
|
|||||||
self.record_type = record_type
|
self.record_type = record_type
|
||||||
self.activity_date = activity.activity_date
|
self.activity_date = activity.activity_date
|
||||||
|
|
||||||
|
@hybrid_property
|
||||||
|
def value(self):
|
||||||
|
if self._value is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if self.record_type == 'LD':
|
||||||
|
return datetime.timedelta(seconds=self._value)
|
||||||
|
elif self.record_type in ['AS', 'MS']:
|
||||||
|
return float(self._value / 100)
|
||||||
|
else: # 'FD'
|
||||||
|
return float(self._value / 1000)
|
||||||
|
|
||||||
|
@value.setter
|
||||||
|
def value(self, val):
|
||||||
|
if self.record_type == 'LD':
|
||||||
|
hours, minutes, seconds = str(val).split(':')
|
||||||
|
self._value = int(hours) * 3600 + int(minutes) * 60 + int(seconds)
|
||||||
|
elif self.record_type in ['AS', 'MS']:
|
||||||
|
self._value = int(val * 100)
|
||||||
|
else: # 'FD'
|
||||||
|
self._value = int(val * 1000)
|
||||||
|
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
|
if self.value is None:
|
||||||
|
value = None
|
||||||
|
elif self.record_type in ['AS', 'FD', 'MS']:
|
||||||
|
value = float(self.value)
|
||||||
|
else: # 'LD'
|
||||||
|
value = str(self.value)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"user_id": self.user_id,
|
"user_id": self.user_id,
|
||||||
@ -148,8 +177,5 @@ class Record(db.Model):
|
|||||||
"activity_id": self.activity_id,
|
"activity_id": self.activity_id,
|
||||||
"record_type": self.record_type,
|
"record_type": self.record_type,
|
||||||
"activity_date": self.activity_date,
|
"activity_date": self.activity_date,
|
||||||
"value_interval": str(
|
"value": value,
|
||||||
self.value_interval) if self.value_interval else None,
|
|
||||||
"value_float": str(
|
|
||||||
self.value_float) if self.value_float else None,
|
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,11 @@ def test_add_an_activity_gpx(app):
|
|||||||
assert 1 == data['data']['activities'][0]['sport_id']
|
assert 1 == data['data']['activities'][0]['sport_id']
|
||||||
assert '0:04:10' == data['data']['activities'][0]['duration']
|
assert '0:04:10' == data['data']['activities'][0]['duration']
|
||||||
assert data['data']['activities'][0]['ascent'] == 0.4
|
assert data['data']['activities'][0]['ascent'] == 0.4
|
||||||
assert data['data']['activities'][0]['ave_speed'] == 4.602
|
assert data['data']['activities'][0]['ave_speed'] == 4.6
|
||||||
assert data['data']['activities'][0]['descent'] == 23.4
|
assert data['data']['activities'][0]['descent'] == 23.4
|
||||||
assert data['data']['activities'][0]['distance'] == 0.32
|
assert data['data']['activities'][0]['distance'] == 0.32
|
||||||
assert data['data']['activities'][0]['max_alt'] == 998.0
|
assert data['data']['activities'][0]['max_alt'] == 998.0
|
||||||
assert data['data']['activities'][0]['max_speed'] == 5.086
|
assert data['data']['activities'][0]['max_speed'] == 5.09
|
||||||
assert data['data']['activities'][0]['min_alt'] == 975.0
|
assert data['data']['activities'][0]['min_alt'] == 975.0
|
||||||
assert data['data']['activities'][0]['moving'] == '0:04:10'
|
assert data['data']['activities'][0]['moving'] == '0:04:10'
|
||||||
assert data['data']['activities'][0]['pauses'] is None
|
assert data['data']['activities'][0]['pauses'] is None
|
||||||
@ -99,11 +99,11 @@ def test_get_an_activity_with_gpx(app):
|
|||||||
assert 1 == data['data']['activities'][0]['sport_id']
|
assert 1 == data['data']['activities'][0]['sport_id']
|
||||||
assert '0:04:10' == data['data']['activities'][0]['duration']
|
assert '0:04:10' == data['data']['activities'][0]['duration']
|
||||||
assert data['data']['activities'][0]['ascent'] == 0.4
|
assert data['data']['activities'][0]['ascent'] == 0.4
|
||||||
assert data['data']['activities'][0]['ave_speed'] == 4.602
|
assert data['data']['activities'][0]['ave_speed'] == 4.6
|
||||||
assert data['data']['activities'][0]['descent'] == 23.4
|
assert data['data']['activities'][0]['descent'] == 23.4
|
||||||
assert data['data']['activities'][0]['distance'] == 0.32
|
assert data['data']['activities'][0]['distance'] == 0.32
|
||||||
assert data['data']['activities'][0]['max_alt'] == 998.0
|
assert data['data']['activities'][0]['max_alt'] == 998.0
|
||||||
assert data['data']['activities'][0]['max_speed'] == 5.086
|
assert data['data']['activities'][0]['max_speed'] == 5.09
|
||||||
assert data['data']['activities'][0]['min_alt'] == 975.0
|
assert data['data']['activities'][0]['min_alt'] == 975.0
|
||||||
assert data['data']['activities'][0]['moving'] == '0:04:10'
|
assert data['data']['activities'][0]['moving'] == '0:04:10'
|
||||||
assert data['data']['activities'][0]['pauses'] is None
|
assert data['data']['activities'][0]['pauses'] is None
|
||||||
|
@ -58,11 +58,11 @@ def test_edit_an_activity_with_gpx(app):
|
|||||||
assert 2 == data['data']['activities'][0]['sport_id']
|
assert 2 == data['data']['activities'][0]['sport_id']
|
||||||
assert '0:04:10' == data['data']['activities'][0]['duration']
|
assert '0:04:10' == data['data']['activities'][0]['duration']
|
||||||
assert data['data']['activities'][0]['ascent'] == 0.4
|
assert data['data']['activities'][0]['ascent'] == 0.4
|
||||||
assert data['data']['activities'][0]['ave_speed'] == 4.602
|
assert data['data']['activities'][0]['ave_speed'] == 4.6
|
||||||
assert data['data']['activities'][0]['descent'] == 23.4
|
assert data['data']['activities'][0]['descent'] == 23.4
|
||||||
assert data['data']['activities'][0]['distance'] == 0.32
|
assert data['data']['activities'][0]['distance'] == 0.32
|
||||||
assert data['data']['activities'][0]['max_alt'] == 998.0
|
assert data['data']['activities'][0]['max_alt'] == 998.0
|
||||||
assert data['data']['activities'][0]['max_speed'] == 5.086
|
assert data['data']['activities'][0]['max_speed'] == 5.09
|
||||||
assert data['data']['activities'][0]['min_alt'] == 975.0
|
assert data['data']['activities'][0]['min_alt'] == 975.0
|
||||||
assert data['data']['activities'][0]['moving'] == '0:04:10'
|
assert data['data']['activities'][0]['moving'] == '0:04:10'
|
||||||
assert data['data']['activities'][0]['pauses'] is None
|
assert data['data']['activities'][0]['pauses'] is None
|
||||||
@ -263,11 +263,11 @@ def test_edit_an_activity_wo_gpx_partial(app):
|
|||||||
assert data['data']['activities'][0]['sport_id'] == 1
|
assert data['data']['activities'][0]['sport_id'] == 1
|
||||||
assert data['data']['activities'][0]['duration'] == '0:17:04'
|
assert data['data']['activities'][0]['duration'] == '0:17:04'
|
||||||
assert data['data']['activities'][0]['ascent'] is None
|
assert data['data']['activities'][0]['ascent'] is None
|
||||||
assert data['data']['activities'][0]['ave_speed'] == 35.156
|
assert data['data']['activities'][0]['ave_speed'] == 35.16
|
||||||
assert data['data']['activities'][0]['descent'] is None
|
assert data['data']['activities'][0]['descent'] is None
|
||||||
assert data['data']['activities'][0]['distance'] == 10.0
|
assert data['data']['activities'][0]['distance'] == 10.0
|
||||||
assert data['data']['activities'][0]['max_alt'] is None
|
assert data['data']['activities'][0]['max_alt'] is None
|
||||||
assert data['data']['activities'][0]['max_speed'] == 35.156
|
assert data['data']['activities'][0]['max_speed'] == 35.16
|
||||||
assert data['data']['activities'][0]['min_alt'] is None
|
assert data['data']['activities'][0]['min_alt'] is None
|
||||||
assert data['data']['activities'][0]['moving'] is None # no calculated
|
assert data['data']['activities'][0]['moving'] is None # no calculated
|
||||||
assert data['data']['activities'][0]['pauses'] is None
|
assert data['data']['activities'][0]['pauses'] is None
|
||||||
|
@ -65,13 +65,11 @@ def test_get_all_activities_for_authenticated_user(app):
|
|||||||
assert 1 == data['data']['records'][0]['sport_id']
|
assert 1 == data['data']['records'][0]['sport_id']
|
||||||
assert 3 == data['data']['records'][0]['activity_id']
|
assert 3 == data['data']['records'][0]['activity_id']
|
||||||
assert 'FD' == data['data']['records'][0]['record_type']
|
assert 'FD' == data['data']['records'][0]['record_type']
|
||||||
assert 'value_interval' in data['data']['records'][0]
|
assert 'value' in data['data']['records'][0]
|
||||||
assert 'value_float' in data['data']['records'][0]
|
|
||||||
|
|
||||||
assert 'Mon, 01 Jan 2018 00:00:00 GMT' == data['data']['records'][1]['activity_date'] # noqa
|
assert 'Mon, 01 Jan 2018 00:00:00 GMT' == data['data']['records'][1]['activity_date'] # noqa
|
||||||
assert 1 == data['data']['records'][1]['user_id']
|
assert 1 == data['data']['records'][1]['user_id']
|
||||||
assert 2 == data['data']['records'][1]['sport_id']
|
assert 2 == data['data']['records'][1]['sport_id']
|
||||||
assert 1 == data['data']['records'][1]['activity_id']
|
assert 1 == data['data']['records'][1]['activity_id']
|
||||||
assert 'LD' == data['data']['records'][1]['record_type']
|
assert 'LD' == data['data']['records'][1]['record_type']
|
||||||
assert 'value_interval' in data['data']['records'][1]
|
assert 'value' in data['data']['records'][1]
|
||||||
assert 'value_float' in data['data']['records'][1]
|
|
||||||
|
@ -23,3 +23,148 @@ def test_add_record(app):
|
|||||||
assert 'LD' == record.record_type
|
assert 'LD' == record.record_type
|
||||||
assert '2018-01-01 13:36:00' == str(record.activity_date)
|
assert '2018-01-01 13:36:00' == str(record.activity_date)
|
||||||
assert 'cycling - LD - 2018-01-01' == str(record)
|
assert 'cycling - LD - 2018-01-01' == str(record)
|
||||||
|
|
||||||
|
record_serialize = record.serialize()
|
||||||
|
assert 'id' in record_serialize
|
||||||
|
assert 'user_id' in record_serialize
|
||||||
|
assert 'sport_id' in record_serialize
|
||||||
|
assert 'activity_id' in record_serialize
|
||||||
|
assert 'record_type' in record_serialize
|
||||||
|
assert 'activity_date' in record_serialize
|
||||||
|
assert 'value' in record_serialize
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_records_no_value(app):
|
||||||
|
add_user('test', 'test@test.com', '12345678')
|
||||||
|
add_sport('cycling')
|
||||||
|
|
||||||
|
activity = add_activity(
|
||||||
|
user_id=1,
|
||||||
|
sport_id=1,
|
||||||
|
activity_date=datetime.datetime.strptime('01/01/2018 13:36', '%d/%m/%Y %H:%M'), # noqa
|
||||||
|
distance=10,
|
||||||
|
duration=datetime.timedelta(seconds=1024)
|
||||||
|
)
|
||||||
|
record = add_record(1, 1, activity, 'AS')
|
||||||
|
|
||||||
|
assert record.value is None
|
||||||
|
assert record._value is None
|
||||||
|
|
||||||
|
record_serialize = record.serialize()
|
||||||
|
assert record_serialize.get('value') is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_as_records(app):
|
||||||
|
add_user('test', 'test@test.com', '12345678')
|
||||||
|
add_sport('cycling')
|
||||||
|
|
||||||
|
activity = add_activity(
|
||||||
|
user_id=1,
|
||||||
|
sport_id=1,
|
||||||
|
activity_date=datetime.datetime.strptime('01/01/2018 13:36', '%d/%m/%Y %H:%M'), # noqa
|
||||||
|
distance=10,
|
||||||
|
duration=datetime.timedelta(seconds=1024)
|
||||||
|
)
|
||||||
|
record = add_record(1, 1, activity, 'AS')
|
||||||
|
# record.value = 4.6
|
||||||
|
record.value = 4.61
|
||||||
|
|
||||||
|
assert isinstance(record.value, float)
|
||||||
|
assert record.value == 4.61
|
||||||
|
assert record._value == 461
|
||||||
|
|
||||||
|
record_serialize = record.serialize()
|
||||||
|
assert record_serialize.get('value') == 4.61
|
||||||
|
assert isinstance(record_serialize.get('value'), float)
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_fd_records(app):
|
||||||
|
add_user('test', 'test@test.com', '12345678')
|
||||||
|
add_sport('cycling')
|
||||||
|
|
||||||
|
activity = add_activity(
|
||||||
|
user_id=1,
|
||||||
|
sport_id=1,
|
||||||
|
activity_date=datetime.datetime.strptime('01/01/2018 13:36', '%d/%m/%Y %H:%M'), # noqa
|
||||||
|
distance=10,
|
||||||
|
duration=datetime.timedelta(seconds=1024)
|
||||||
|
)
|
||||||
|
record = add_record(1, 1, activity, 'FD')
|
||||||
|
record.value = 0.322
|
||||||
|
|
||||||
|
assert isinstance(record.value, float)
|
||||||
|
assert record.value == 0.322
|
||||||
|
assert record._value == 322
|
||||||
|
|
||||||
|
record_serialize = record.serialize()
|
||||||
|
assert record_serialize.get('value') == 0.322
|
||||||
|
assert isinstance(record_serialize.get('value'), float)
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_ld_records(app):
|
||||||
|
add_user('test', 'test@test.com', '12345678')
|
||||||
|
add_sport('cycling')
|
||||||
|
|
||||||
|
activity = add_activity(
|
||||||
|
user_id=1,
|
||||||
|
sport_id=1,
|
||||||
|
activity_date=datetime.datetime.strptime('01/01/2018 13:36', '%d/%m/%Y %H:%M'), # noqa
|
||||||
|
distance=10,
|
||||||
|
duration=datetime.timedelta(seconds=1024)
|
||||||
|
)
|
||||||
|
record = add_record(1, 1, activity, 'LD')
|
||||||
|
record.value = activity.duration
|
||||||
|
|
||||||
|
assert isinstance(record.value, datetime.timedelta)
|
||||||
|
assert str(record.value) == '0:17:04'
|
||||||
|
assert record._value == 1024
|
||||||
|
|
||||||
|
record_serialize = record.serialize()
|
||||||
|
assert record_serialize.get('value') == '0:17:04'
|
||||||
|
assert isinstance(record_serialize.get('value'), str)
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_ld_records_zero(app):
|
||||||
|
add_user('test', 'test@test.com', '12345678')
|
||||||
|
add_sport('cycling')
|
||||||
|
|
||||||
|
activity = add_activity(
|
||||||
|
user_id=1,
|
||||||
|
sport_id=1,
|
||||||
|
activity_date=datetime.datetime.strptime('01/01/2018 13:36', '%d/%m/%Y %H:%M'), # noqa
|
||||||
|
distance=10,
|
||||||
|
duration=datetime.timedelta(seconds=0)
|
||||||
|
)
|
||||||
|
record = add_record(1, 1, activity, 'LD')
|
||||||
|
record.value = activity.duration
|
||||||
|
|
||||||
|
assert isinstance(record.value, datetime.timedelta)
|
||||||
|
assert str(record.value) == '0:00:00'
|
||||||
|
assert record._value == 0
|
||||||
|
|
||||||
|
record_serialize = record.serialize()
|
||||||
|
assert record_serialize.get('value') == '0:00:00'
|
||||||
|
assert isinstance(record_serialize.get('value'), str)
|
||||||
|
|
||||||
|
|
||||||
|
def test_add_ms_records_no_value(app):
|
||||||
|
add_user('test', 'test@test.com', '12345678')
|
||||||
|
add_sport('cycling')
|
||||||
|
|
||||||
|
activity = add_activity(
|
||||||
|
user_id=1,
|
||||||
|
sport_id=1,
|
||||||
|
activity_date=datetime.datetime.strptime('01/01/2018 13:36', '%d/%m/%Y %H:%M'), # noqa
|
||||||
|
distance=10,
|
||||||
|
duration=datetime.timedelta(seconds=1024)
|
||||||
|
)
|
||||||
|
record = add_record(1, 1, activity, 'MS')
|
||||||
|
record.value = 23.5
|
||||||
|
|
||||||
|
assert isinstance(record.value, float)
|
||||||
|
assert record.value == 23.5
|
||||||
|
assert record._value == 2350
|
||||||
|
|
||||||
|
record_serialize = record.serialize()
|
||||||
|
assert record_serialize.get('value') == 23.5
|
||||||
|
assert isinstance(record_serialize.get('value'), float)
|
||||||
|
@ -4,4 +4,3 @@ from mpwo_api.tests.utils import add_user
|
|||||||
def test_add_user(app):
|
def test_add_user(app):
|
||||||
user = add_user('test', 'test@test.com', '12345678')
|
user = add_user('test', 'test@test.com', '12345678')
|
||||||
assert '<User \'test\'>' == str(user)
|
assert '<User \'test\'>' == str(user)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user