API: refactor (wip)

This commit is contained in:
Sam 2018-05-29 12:53:13 +02:00
parent 3db20eced7
commit 90c380f35a
2 changed files with 62 additions and 56 deletions

View File

@ -4,13 +4,12 @@ import os
from flask import Blueprint, jsonify, request from flask import Blueprint, jsonify, request
from mpwo_api import appLog, db from mpwo_api import appLog, db
from sqlalchemy import exc from sqlalchemy import exc
from werkzeug.utils import secure_filename
from ..users.utils import authenticate, verify_extension from ..users.utils import authenticate, verify_extension
from .models import Activity, Sport from .models import Activity
from .utils import ( from .utils import (
create_activity, create_segment, edit_activity, get_chart_data, ActivityException, create_activity, edit_activity, get_chart_data,
get_file_path, get_gpx_info, get_new_file_path handle_one_activity
) )
activities_blueprint = Blueprint('activities', __name__) activities_blueprint = Blueprint('activities', __name__)
@ -145,47 +144,11 @@ def post_activity(auth_user_id):
return jsonify(response_object), 400 return jsonify(response_object), 400
activity_file = request.files['file'] activity_file = request.files['file']
filename = secure_filename(activity_file.filename)
file_path = get_file_path(auth_user_id, filename)
try: try:
activity_file.save(file_path) new_activity = handle_one_activity(
gpx_data = get_gpx_info(file_path) auth_user_id, activity_file, activity_data
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
) )
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 = { response_object = {
'status': 'created', 'status': 'created',
'data': { 'data': {
@ -193,14 +156,16 @@ def post_activity(auth_user_id):
} }
} }
return jsonify(response_object), 201 return jsonify(response_object), 201
except (exc.IntegrityError, ValueError) as e: except ActivityException as e:
db.session.rollback() db.session.rollback()
appLog.error(e) if e.e:
appLog.error(e.e)
response_object = { response_object = {
'status': 'fail', 'status': e.status,
'message': 'Error during activity save.' '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']) @activities_blueprint.route('/activities/no_gpx', methods=['POST'])

View File

@ -4,11 +4,20 @@ from datetime import datetime, timedelta
import gpxpy.gpx import gpxpy.gpx
from flask import current_app 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 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): def update_activity_data(activity, gpx_data):
"""activity could be a complete activity or an activity segment""" """activity could be a complete activity or an activity segment"""
activity.pauses = gpx_data['stop_time'] 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): def open_gpx_file(gpx_file):
gpx_file = open(gpx_file, 'r') gpx_file = open(gpx_file, 'r')
gpx = gpxpy.parse(gpx_file)
try:
gpx = gpxpy.parse(gpx_file)
except gpxpy.gpx.GPXXMLSyntaxException as e:
appLog.error(e)
return None
if len(gpx.tracks) == 0: if len(gpx.tracks) == 0:
return None return None
return gpx 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, file_path = os.path.join(dir_path,
new_filename.replace('/tmp/', '')) new_filename.replace('/tmp/', ''))
return file_path 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
)