From 90c380f35abaeb62cc74c1502f9acf0664e29728 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 29 May 2018 12:53:13 +0200 Subject: [PATCH] API: refactor (wip) --- mpwo_api/mpwo_api/activities/activities.py | 59 +++++----------------- mpwo_api/mpwo_api/activities/utils.py | 59 ++++++++++++++++++---- 2 files changed, 62 insertions(+), 56 deletions(-) diff --git a/mpwo_api/mpwo_api/activities/activities.py b/mpwo_api/mpwo_api/activities/activities.py index bfe6bca7..d5fe4a63 100644 --- a/mpwo_api/mpwo_api/activities/activities.py +++ b/mpwo_api/mpwo_api/activities/activities.py @@ -4,13 +4,12 @@ import os from flask import Blueprint, jsonify, request from mpwo_api import appLog, db from sqlalchemy import exc -from werkzeug.utils import secure_filename from ..users.utils import authenticate, verify_extension -from .models import Activity, Sport +from .models import Activity from .utils import ( - create_activity, create_segment, edit_activity, get_chart_data, - get_file_path, get_gpx_info, get_new_file_path + ActivityException, create_activity, edit_activity, get_chart_data, + handle_one_activity ) activities_blueprint = Blueprint('activities', __name__) @@ -145,47 +144,11 @@ def post_activity(auth_user_id): return jsonify(response_object), 400 activity_file = request.files['file'] - filename = secure_filename(activity_file.filename) - file_path = get_file_path(auth_user_id, filename) try: - activity_file.save(file_path) - gpx_data = get_gpx_info(file_path) - - if gpx_data is None: - response_object = { - 'status': 'error', - 'message': 'Error during gpx file parsing.' - } - return jsonify(response_object), 500 - - sport = Sport.query.filter_by(id=activity_data.get('sport_id')).first() - new_filepath = get_new_file_path( - auth_user_id=auth_user_id, - activity_date=gpx_data['start'], - old_filename=filename, - sport=sport.label + new_activity = handle_one_activity( + auth_user_id, activity_file, activity_data ) - os.rename(file_path, new_filepath) - gpx_data['filename'] = new_filepath - except Exception as e: - appLog.error(e) - response_object = { - 'status': 'error', - 'message': 'Error during activity file save.' - } - return jsonify(response_object), 500 - - try: - new_activity = create_activity( - auth_user_id, activity_data, gpx_data) - db.session.add(new_activity) - db.session.flush() - - for segment_data in gpx_data['segments']: - new_segment = create_segment(new_activity.id, segment_data) - db.session.add(new_segment) - db.session.commit() response_object = { 'status': 'created', 'data': { @@ -193,14 +156,16 @@ def post_activity(auth_user_id): } } return jsonify(response_object), 201 - except (exc.IntegrityError, ValueError) as e: + except ActivityException as e: db.session.rollback() - appLog.error(e) + if e.e: + appLog.error(e.e) response_object = { - 'status': 'fail', - 'message': 'Error during activity save.' + 'status': e.status, + 'message': e.message, } - return jsonify(response_object), 500 + code = 500 if e.status == 'error' else 400 + return jsonify(response_object), code @activities_blueprint.route('/activities/no_gpx', methods=['POST']) diff --git a/mpwo_api/mpwo_api/activities/utils.py b/mpwo_api/mpwo_api/activities/utils.py index 09de64cf..91a453c4 100644 --- a/mpwo_api/mpwo_api/activities/utils.py +++ b/mpwo_api/mpwo_api/activities/utils.py @@ -4,11 +4,20 @@ from datetime import datetime, timedelta import gpxpy.gpx from flask import current_app -from mpwo_api import appLog +from mpwo_api import db +from sqlalchemy import exc +from werkzeug.utils import secure_filename from .models import Activity, ActivitySegment, Sport +class ActivityException(Exception): + def __init__(self, status, message, e): + self.status = status + self.message = message + self.e = e + + def update_activity_data(activity, gpx_data): """activity could be a complete activity or an activity segment""" activity.pauses = gpx_data['stop_time'] @@ -123,16 +132,9 @@ def get_gpx_data(parsed_gpx, max_speed, start): def open_gpx_file(gpx_file): gpx_file = open(gpx_file, 'r') - - try: - gpx = gpxpy.parse(gpx_file) - except gpxpy.gpx.GPXXMLSyntaxException as e: - appLog.error(e) - return None - + gpx = gpxpy.parse(gpx_file) if len(gpx.tracks) == 0: return None - return gpx @@ -242,3 +244,42 @@ def get_new_file_path(auth_user_id, activity_date, old_filename, sport): file_path = os.path.join(dir_path, new_filename.replace('/tmp/', '')) return file_path + + +def handle_one_activity(auth_user_id, activity_file, activity_data): + filename = secure_filename(activity_file.filename) + file_path = get_file_path(auth_user_id, filename) + + try: + activity_file.save(file_path) + gpx_data = get_gpx_info(file_path) + + sport = Sport.query.filter_by(id=activity_data.get('sport_id')).first() + new_filepath = get_new_file_path( + auth_user_id=auth_user_id, + activity_date=gpx_data['start'], + old_filename=filename, + sport=sport.label + ) + os.rename(file_path, new_filepath) + gpx_data['filename'] = new_filepath + except (gpxpy.gpx.GPXXMLSyntaxException, TypeError) as e: + raise ActivityException('error', 'Error during gpx file parsing.', e) + except Exception as e: + raise ActivityException('error', 'Error during activity file save.', e) + + try: + new_activity = create_activity( + auth_user_id, activity_data, gpx_data) + db.session.add(new_activity) + db.session.flush() + + for segment_data in gpx_data['segments']: + new_segment = create_segment(new_activity.id, segment_data) + db.session.add(new_segment) + db.session.commit() + return new_activity + except (exc.IntegrityError, ValueError) as e: + raise ActivityException( + 'fail', 'Error during activity save.', e + )