diff --git a/mpwo_api/migrations/versions/b7cfe0c17708_.py b/mpwo_api/migrations/versions/b7cfe0c17708_.py index d2e3d618..8ea38239 100644 --- a/mpwo_api/migrations/versions/b7cfe0c17708_.py +++ b/mpwo_api/migrations/versions/b7cfe0c17708_.py @@ -28,6 +28,7 @@ def upgrade(): sa.Column('id', sa.Integer(), nullable=False), sa.Column('user_id', sa.Integer(), nullable=False), sa.Column('sport_id', sa.Integer(), nullable=False), + sa.Column('title', sa.String(length=255), nullable=True), sa.Column('gpx', sa.String(length=255), nullable=True), sa.Column('creation_date', sa.DateTime(), nullable=True), sa.Column('modification_date', sa.DateTime(), nullable=True), @@ -40,8 +41,8 @@ def upgrade(): sa.Column('max_alt', sa.Numeric(precision=5, scale=2), nullable=True), sa.Column('descent', sa.Numeric(precision=5, scale=2), nullable=True), sa.Column('ascent', sa.Numeric(precision=5, scale=2), nullable=True), - sa.Column('max_speed', sa.Numeric(precision=5, scale=3), nullable=True), - sa.Column('ave_speed', sa.Numeric(precision=5, scale=3), nullable=True), + sa.Column('max_speed', sa.Numeric(precision=5, scale=2), nullable=True), + sa.Column('ave_speed', sa.Numeric(precision=5, scale=2), nullable=True), sa.ForeignKeyConstraint(['sport_id'], ['sports.id'], ), sa.ForeignKeyConstraint(['user_id'], ['users.id'], ), sa.PrimaryKeyConstraint('id') diff --git a/mpwo_api/mpwo_api/activities/models.py b/mpwo_api/mpwo_api/activities/models.py index b48d9003..b389f25d 100644 --- a/mpwo_api/mpwo_api/activities/models.py +++ b/mpwo_api/mpwo_api/activities/models.py @@ -24,7 +24,7 @@ class Sport(db.Model): backref=db.backref('sports', lazy='joined')) def __repr__(self): - return self.label + return ''.format(self.label) def __init__(self, label): self.label = label @@ -51,6 +51,7 @@ class Activity(db.Model): db.Integer, db.ForeignKey('sports.id'), nullable=False) + title = db.Column(db.String(255), nullable=True) gpx = db.Column(db.String(255), nullable=True) creation_date = db.Column( db.DateTime, default=datetime.datetime.utcnow) @@ -72,8 +73,8 @@ class Activity(db.Model): backref=db.backref('activities', lazy='joined')) def __str__(self): - return str(self.sports.label) + \ - " - " + self.activity_date.strftime('%Y-%m-%d %H:%M:%S') + return ''.format( + self.sports.label, self.activity_date, ) def __init__(self, user_id, sport_id, activity_date, distance, duration): self.user_id = user_id @@ -87,6 +88,7 @@ class Activity(db.Model): "id": self.id, "user_id": self.user_id, "sport_id": self.sport_id, + "title": self.title, "creation_date": self.creation_date, "modification_date": self.modification_date, "activity_date": self.activity_date, @@ -129,9 +131,11 @@ class Record(db.Model): _value = db.Column("value", db.Integer, nullable=True) def __str__(self): - return str(self.sports.label) + \ - " - " + self.record_type + \ - " - " + self.activity_date.strftime('%Y-%m-%d') + return ''.format( + self.sports.label, + self.record_type, + self.activity_date.strftime('%Y-%m-%d') + ) def __init__(self, user_id, sport_id, activity, record_type): self.user_id = user_id diff --git a/mpwo_api/mpwo_api/activities/utils.py b/mpwo_api/mpwo_api/activities/utils.py index 915eac6c..984c5c4d 100644 --- a/mpwo_api/mpwo_api/activities/utils.py +++ b/mpwo_api/mpwo_api/activities/utils.py @@ -7,7 +7,7 @@ from flask import current_app from mpwo_api import appLog from werkzeug.utils import secure_filename -from .models import Activity +from .models import Activity, Sport def create_activity( @@ -19,6 +19,8 @@ def create_activity( else timedelta(seconds=activity_data.get('duration')) distance = gpx_data['distance'] if gpx_data \ else activity_data.get('distance') + title = gpx_data['name'] if gpx_data \ + else activity_data.get('title') new_activity = Activity( user_id=auth_user_id, @@ -28,6 +30,13 @@ def create_activity( duration=duration ) + if title is not None: + new_activity.title = title + else: + sport = Sport.query.filter_by(id=new_activity.sport_id).first() + new_activity.title = '{} - {}'.format(sport.label, + new_activity.activity_date) + if gpx_data: new_activity.gpx = gpx_data['filename'] new_activity.pauses = gpx_data['stop_time'] @@ -48,12 +57,15 @@ def create_activity( def edit_activity(activity, activity_data): activity.sport_id = activity_data.get('sport_id') + if activity_data.get('title'): + activity.title = activity_data.get('title') if not activity.gpx: if activity_data.get('activity_date'): activity.activity_date = datetime.strptime( activity_data.get('activity_date'), '%Y-%m-%d %H:%M') if activity_data.get('duration'): - activity.duration = timedelta(seconds=activity_data.get('duration')) # noqa + activity.duration = timedelta( + seconds=activity_data.get('duration')) activity.moving = activity.duration if activity_data.get('distance'): activity.distance = activity_data.get('distance') @@ -64,7 +76,6 @@ def edit_activity(activity, activity_data): def get_gpx_data(parsed_gpx, max_speed, start): - gpx_data = {'max_speed': (max_speed / 1000) * 3600, 'start': start} duration = parsed_gpx.get_duration() @@ -91,7 +102,6 @@ def get_gpx_data(parsed_gpx, max_speed, start): def get_gpx_info(gpx_file): - gpx_file = open(gpx_file, 'r') try: @@ -167,5 +177,6 @@ def get_new_file_path(auth_user_id, activity_date, activity_file, sport): current_app.config['UPLOAD_FOLDER'], 'activities', str(auth_user_id)) if not os.path.exists(dir_path): os.makedirs(dir_path) - file_path = os.path.join(dir_path, new_filename.replace('/tmp/', '')) # noqa + file_path = os.path.join(dir_path, + new_filename.replace('/tmp/', '')) return file_path diff --git a/mpwo_api/mpwo_api/tests/test_activities_api_1_post.py b/mpwo_api/mpwo_api/tests/test_activities_api_1_post.py index 8f805447..f97a869d 100644 --- a/mpwo_api/mpwo_api/tests/test_activities_api_1_post.py +++ b/mpwo_api/mpwo_api/tests/test_activities_api_1_post.py @@ -41,6 +41,7 @@ def test_add_an_activity_gpx(app): assert 1 == data['data']['activities'][0]['user_id'] assert 1 == data['data']['activities'][0]['sport_id'] assert '0:04:10' == data['data']['activities'][0]['duration'] + assert 'cycling - 2018-03-13 12:44:45' == data['data']['activities'][0]['title'] # noqa assert data['data']['activities'][0]['ascent'] == 0.4 assert data['data']['activities'][0]['ave_speed'] == 4.6 assert data['data']['activities'][0]['descent'] == 23.4 @@ -98,6 +99,7 @@ def test_get_an_activity_with_gpx(app): assert 1 == data['data']['activities'][0]['user_id'] assert 1 == data['data']['activities'][0]['sport_id'] assert '0:04:10' == data['data']['activities'][0]['duration'] + assert 'cycling - 2018-03-13 12:44:45' == data['data']['activities'][0]['title'] # noqa assert data['data']['activities'][0]['ascent'] == 0.4 assert data['data']['activities'][0]['ave_speed'] == 4.6 assert data['data']['activities'][0]['descent'] == 23.4 @@ -280,6 +282,7 @@ def test_add_an_activity_no_gpx(app): assert data['data']['activities'][0]['user_id'] == 1 assert data['data']['activities'][0]['sport_id'] == 1 assert data['data']['activities'][0]['duration'] == '1:00:00' + assert data['data']['activities'][0]['title'] == 'cycling - 2018-05-15 14:05:00' # noqa assert data['data']['activities'][0]['ascent'] is None assert data['data']['activities'][0]['ave_speed'] == 10.0 assert data['data']['activities'][0]['descent'] is None @@ -338,6 +341,7 @@ def test_get_an_activity_wo_gpx(app): assert data['data']['activities'][0]['user_id'] == 1 assert data['data']['activities'][0]['sport_id'] == 1 assert data['data']['activities'][0]['duration'] == '1:00:00' + assert data['data']['activities'][0]['title'] == 'cycling - 2018-05-15 14:05:00' # noqa assert data['data']['activities'][0]['ascent'] is None assert data['data']['activities'][0]['ave_speed'] == 10.0 assert data['data']['activities'][0]['descent'] is None diff --git a/mpwo_api/mpwo_api/tests/test_activities_api_2_patch.py b/mpwo_api/mpwo_api/tests/test_activities_api_2_patch.py index e947f467..d18f56fe 100644 --- a/mpwo_api/mpwo_api/tests/test_activities_api_2_patch.py +++ b/mpwo_api/mpwo_api/tests/test_activities_api_2_patch.py @@ -11,6 +11,71 @@ def test_edit_an_activity_with_gpx(app): add_sport('cycling') add_sport('running') + client = app.test_client() + resp_login = client.post( + '/api/auth/login', + data=json.dumps(dict( + email='test@test.com', + password='12345678' + )), + content_type='application/json' + ) + client.post( + '/api/activities', + data=dict( + file=(BytesIO(str.encode(gpx_file)), 'example.gpx'), + data='{"sport_id": 1}' + ), + headers=dict( + content_type='multipart/form-data', + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) + response = client.patch( + '/api/activities/1', + content_type='application/json', + data=json.dumps(dict( + sport_id=2, + title="Activity test", + )), + headers=dict( + Authorization='Bearer ' + json.loads( + resp_login.data.decode() + )['auth_token'] + ) + ) + + data = json.loads(response.data.decode()) + + assert response.status_code == 200 + assert 'success' in data['status'] + assert len(data['data']['activities']) == 1 + + assert 'creation_date' in data['data']['activities'][0] + assert 'Tue, 13 Mar 2018 12:44:45 GMT' == data['data']['activities'][0]['activity_date'] # noqa + assert 1 == data['data']['activities'][0]['user_id'] + assert 2 == data['data']['activities'][0]['sport_id'] + assert '0:04:10' == data['data']['activities'][0]['duration'] + assert data['data']['activities'][0]['title'] == 'Activity test' + assert data['data']['activities'][0]['ascent'] == 0.4 + assert data['data']['activities'][0]['ave_speed'] == 4.6 + assert data['data']['activities'][0]['descent'] == 23.4 + assert data['data']['activities'][0]['distance'] == 0.32 + assert data['data']['activities'][0]['max_alt'] == 998.0 + assert data['data']['activities'][0]['max_speed'] == 5.09 + assert data['data']['activities'][0]['min_alt'] == 975.0 + assert data['data']['activities'][0]['moving'] == '0:04:10' + assert data['data']['activities'][0]['pauses'] is None + assert data['data']['activities'][0]['with_gpx'] is True + + +def test_edit_an_activity_with_gpx_partial(app): + add_user('test', 'test@test.com', '12345678') + add_sport('cycling') + add_sport('running') + client = app.test_client() resp_login = client.post( '/api/auth/login', @@ -57,6 +122,7 @@ def test_edit_an_activity_with_gpx(app): assert 1 == data['data']['activities'][0]['user_id'] assert 2 == data['data']['activities'][0]['sport_id'] assert '0:04:10' == data['data']['activities'][0]['duration'] + assert data['data']['activities'][0]['title'] == 'cycling - 2018-03-13 12:44:45' # noqa assert data['data']['activities'][0]['ascent'] == 0.4 assert data['data']['activities'][0]['ave_speed'] == 4.6 assert data['data']['activities'][0]['descent'] == 23.4 @@ -163,13 +229,14 @@ def test_edit_an_activity_with_gpx_incorrect_data(app): def test_edit_an_activity_wo_gpx(app): add_user('test', 'test@test.com', '12345678') add_sport('cycling') - add_activity( + activity = add_activity( user_id=1, sport_id=1, activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'), distance=10, duration=datetime.timedelta(seconds=1024) ) + activity.title = 'cycling - 2018-01-01 00:00:00' client = app.test_client() resp_login = client.post( @@ -187,7 +254,8 @@ def test_edit_an_activity_wo_gpx(app): sport_id=1, duration=3600, activity_date='2018-05-15 14:05', - distance=10 + distance=10, + title='Activity test' )), headers=dict( Authorization='Bearer ' + json.loads( @@ -206,6 +274,7 @@ def test_edit_an_activity_wo_gpx(app): assert data['data']['activities'][0]['user_id'] == 1 assert data['data']['activities'][0]['sport_id'] == 1 assert data['data']['activities'][0]['duration'] == '1:00:00' + assert data['data']['activities'][0]['title'] == 'Activity test' # noqa assert data['data']['activities'][0]['ascent'] is None assert data['data']['activities'][0]['ave_speed'] == 10.0 assert data['data']['activities'][0]['descent'] is None @@ -221,13 +290,14 @@ def test_edit_an_activity_wo_gpx(app): def test_edit_an_activity_wo_gpx_partial(app): add_user('test', 'test@test.com', '12345678') add_sport('cycling') - add_activity( + activity = add_activity( user_id=1, sport_id=1, activity_date=datetime.datetime.strptime('01/01/2018', '%d/%m/%Y'), distance=10, duration=datetime.timedelta(seconds=1024) ) + activity.title = 'cycling - 2018-01-01 00:00:00' client = app.test_client() resp_login = client.post( @@ -262,6 +332,7 @@ def test_edit_an_activity_wo_gpx_partial(app): assert data['data']['activities'][0]['user_id'] == 1 assert data['data']['activities'][0]['sport_id'] == 1 assert data['data']['activities'][0]['duration'] == '0:17:04' + assert data['data']['activities'][0]['title'] == 'cycling - 2018-01-01 00:00:00' # noqa assert data['data']['activities'][0]['ascent'] is None assert data['data']['activities'][0]['ave_speed'] == 35.16 assert data['data']['activities'][0]['descent'] is None diff --git a/mpwo_api/mpwo_api/tests/test_activities_model.py b/mpwo_api/mpwo_api/tests/test_activities_model.py index 511bf2a9..b4def9a4 100644 --- a/mpwo_api/mpwo_api/tests/test_activities_model.py +++ b/mpwo_api/mpwo_api/tests/test_activities_model.py @@ -13,6 +13,7 @@ def test_add_activity(app): distance=10, duration=datetime.timedelta(seconds=1024) ) + activity.title = 'Test' assert 1 == activity.id assert 1 == activity.user_id @@ -20,4 +21,5 @@ def test_add_activity(app): assert '2018-01-01 13:36:00' == str(activity.activity_date) assert 10.0 == float(activity.distance) assert '0:17:04' == str(activity.duration) - assert 'cycling - 2018-01-01 13:36:00' == str(activity) + assert 'Test' == activity.title + assert '' == str(activity) diff --git a/mpwo_api/mpwo_api/tests/test_records_model.py b/mpwo_api/mpwo_api/tests/test_records_model.py index 52b90ac4..295e8199 100644 --- a/mpwo_api/mpwo_api/tests/test_records_model.py +++ b/mpwo_api/mpwo_api/tests/test_records_model.py @@ -22,7 +22,7 @@ def test_add_record(app): assert 1 == record.activity_id assert 'LD' == record.record_type assert '2018-01-01 13:36:00' == str(record.activity_date) - assert 'cycling - LD - 2018-01-01' == str(record) + assert '' == str(record) record_serialize = record.serialize() assert 'id' in record_serialize diff --git a/mpwo_api/mpwo_api/tests/test_sports_model.py b/mpwo_api/mpwo_api/tests/test_sports_model.py index ef1adf18..a304a7a7 100644 --- a/mpwo_api/mpwo_api/tests/test_sports_model.py +++ b/mpwo_api/mpwo_api/tests/test_sports_model.py @@ -7,4 +7,4 @@ def test_add_sport(app): assert 1 == sport.id assert 'cycling' == sport.label - assert 'cycling' == str(sport) + assert '' == str(sport) diff --git a/mpwo_client/src/components/Activities/ActivityForms/FormWithGpx.jsx b/mpwo_client/src/components/Activities/ActivityForms/FormWithGpx.jsx index 985fbc3e..0c3d0466 100644 --- a/mpwo_client/src/components/Activities/ActivityForms/FormWithGpx.jsx +++ b/mpwo_client/src/components/Activities/ActivityForms/FormWithGpx.jsx @@ -32,7 +32,18 @@ function FormWithGpx (props) { - {!activity && ( + {activity ? ( +
+ +
+ ) : (