API & Client: filter activities - fix #3
This commit is contained in:
parent
f45db7b969
commit
76b2d5aad2
@ -10,9 +10,10 @@ from sqlalchemy import exc
|
||||
from ..users.utils import authenticate, verify_extension
|
||||
from .models import Activity
|
||||
from .utils import (
|
||||
ActivityException, convert_in_duration, create_activity, edit_activity,
|
||||
get_chart_data, process_files
|
||||
ActivityException, create_activity, edit_activity, get_chart_data,
|
||||
process_files
|
||||
)
|
||||
from .utils_format import convert_in_duration
|
||||
|
||||
activities_blueprint = Blueprint('activities', __name__)
|
||||
|
||||
@ -62,7 +63,8 @@ def get_activities(auth_user_id):
|
||||
response_object = {
|
||||
'status': 'success',
|
||||
'data': {
|
||||
'activities': [activity.serialize() for activity in activities]
|
||||
'activities': [activity.serialize(params)
|
||||
for activity in activities]
|
||||
}
|
||||
}
|
||||
code = 200
|
||||
|
@ -8,6 +8,8 @@ from sqlalchemy.ext.hybrid import hybrid_property
|
||||
from sqlalchemy.orm.session import object_session
|
||||
from sqlalchemy.types import Enum
|
||||
|
||||
from .utils_format import convert_in_duration, convert_value_to_integer
|
||||
|
||||
record_types = [
|
||||
'AS', # 'Best Average Speed'
|
||||
'FD', # 'Farthest Distance'
|
||||
@ -16,23 +18,6 @@ record_types = [
|
||||
]
|
||||
|
||||
|
||||
def convert_timedelta_to_integer(value):
|
||||
hours, minutes, seconds = str(value).split(':')
|
||||
return int(hours) * 3600 + int(minutes) * 60 + int(seconds)
|
||||
|
||||
|
||||
def convert_value_to_integer(record_type, val):
|
||||
if val is None:
|
||||
return None
|
||||
|
||||
if record_type == 'LD':
|
||||
return convert_timedelta_to_integer(val)
|
||||
elif record_type in ['AS', 'MS']:
|
||||
return int(val * 100)
|
||||
else: # 'FD'
|
||||
return int(val * 1000)
|
||||
|
||||
|
||||
def update_records(user_id, sport_id, connection, session):
|
||||
record_table = Record.__table__
|
||||
new_records = Activity.get_user_activity_records(
|
||||
@ -161,18 +146,61 @@ class Activity(db.Model):
|
||||
self.distance = distance
|
||||
self.duration = duration
|
||||
|
||||
def serialize(self):
|
||||
def serialize(self, params=None):
|
||||
date_from = params.get('from') if params else None
|
||||
date_to = params.get('to') if params else None
|
||||
distance_from = params.get('distance_from') if params else None
|
||||
distance_to = params.get('distance_to') if params else None
|
||||
duration_from = params.get('duration_from') if params else None
|
||||
duration_to = params.get('duration_to') if params else None
|
||||
ave_speed_from = params.get('ave_speed_from') if params else None
|
||||
ave_speed_to = params.get('ave_speed_to') if params else None
|
||||
sport_id = params.get('sport_id') if params else None
|
||||
previous_activity = Activity.query.filter(
|
||||
Activity.id != self.id,
|
||||
Activity.user_id == self.user_id,
|
||||
Activity.activity_date <= self.activity_date
|
||||
Activity.sport_id == sport_id if sport_id else True,
|
||||
Activity.activity_date <= self.activity_date,
|
||||
Activity.activity_date >= datetime.datetime.strptime(
|
||||
date_from, '%Y-%m-%d'
|
||||
) if date_from else True,
|
||||
Activity.activity_date <= datetime.datetime.strptime(
|
||||
date_to, '%Y-%m-%d'
|
||||
) if date_to else True,
|
||||
Activity.distance >= int(distance_from) if distance_from else True,
|
||||
Activity.distance <= int(distance_to) if distance_to else True,
|
||||
Activity.duration >= convert_in_duration(duration_from)
|
||||
if duration_from else True,
|
||||
Activity.duration <= convert_in_duration(duration_to)
|
||||
if duration_to else True,
|
||||
Activity.ave_speed >= float(ave_speed_from)
|
||||
if ave_speed_from else True,
|
||||
Activity.ave_speed <= float(ave_speed_to)
|
||||
if ave_speed_to else True,
|
||||
).order_by(
|
||||
Activity.activity_date.desc()
|
||||
).first()
|
||||
next_activity = Activity.query.filter(
|
||||
Activity.id != self.id,
|
||||
Activity.user_id == self.user_id,
|
||||
Activity.activity_date >= self.activity_date
|
||||
Activity.sport_id == sport_id if sport_id else True,
|
||||
Activity.activity_date >= self.activity_date,
|
||||
Activity.activity_date >= datetime.datetime.strptime(
|
||||
date_from, '%Y-%m-%d'
|
||||
) if date_from else True,
|
||||
Activity.activity_date <= datetime.datetime.strptime(
|
||||
date_to, '%Y-%m-%d'
|
||||
) if date_to else True,
|
||||
Activity.distance >= int(distance_from) if distance_from else True,
|
||||
Activity.distance <= int(distance_to) if distance_to else True,
|
||||
Activity.duration >= convert_in_duration(duration_from)
|
||||
if duration_from else True,
|
||||
Activity.duration <= convert_in_duration(duration_to)
|
||||
if duration_to else True,
|
||||
Activity.ave_speed >= float(ave_speed_from)
|
||||
if ave_speed_from else True,
|
||||
Activity.ave_speed <= float(ave_speed_to)
|
||||
if ave_speed_to else True,
|
||||
).order_by(
|
||||
Activity.activity_date.asc()
|
||||
).first()
|
||||
|
@ -5,7 +5,8 @@ from flask import Blueprint, jsonify, request
|
||||
|
||||
from ..users.models import User
|
||||
from ..users.utils import authenticate
|
||||
from .models import Activity, Sport, convert_timedelta_to_integer
|
||||
from .models import Activity, Sport
|
||||
from .utils_format import convert_timedelta_to_integer
|
||||
|
||||
stats_blueprint = Blueprint('stats', __name__)
|
||||
|
||||
|
@ -360,9 +360,3 @@ def process_files(auth_user_id, activity_data, activity_file, folders):
|
||||
return [process_one_gpx_file(common_params, filename)]
|
||||
else:
|
||||
return process_zip_archive(common_params, folders['extract_dir'])
|
||||
|
||||
|
||||
def convert_in_duration(value):
|
||||
hours = int(value.split(':')[0])
|
||||
minutes = int(value.split(':')[1])
|
||||
return timedelta(seconds=(hours*3600 + minutes*60))
|
||||
|
24
fittrackee_api/fittrackee_api/activities/utils_format.py
Normal file
24
fittrackee_api/fittrackee_api/activities/utils_format.py
Normal file
@ -0,0 +1,24 @@
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
def convert_in_duration(value):
|
||||
hours = int(value.split(':')[0])
|
||||
minutes = int(value.split(':')[1])
|
||||
return timedelta(seconds=(hours*3600 + minutes*60))
|
||||
|
||||
|
||||
def convert_timedelta_to_integer(value):
|
||||
hours, minutes, seconds = str(value).split(':')
|
||||
return int(hours) * 3600 + int(minutes) * 60 + int(seconds)
|
||||
|
||||
|
||||
def convert_value_to_integer(record_type, val):
|
||||
if val is None:
|
||||
return None
|
||||
|
||||
if record_type == 'LD':
|
||||
return convert_timedelta_to_integer(val)
|
||||
elif record_type in ['AS', 'MS']:
|
||||
return int(val * 100)
|
||||
else: # 'FD'
|
||||
return int(val * 1000)
|
@ -6,7 +6,7 @@ export default function ActivitiesList (props) {
|
||||
const { activities, sports } = props
|
||||
return (
|
||||
<div className="card">
|
||||
<div className="card-bord">
|
||||
<div className="card-body">
|
||||
<table className="table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { connect } from 'react-redux'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
import ActivitiesFilter from './ActivitiesFilter'
|
||||
import ActivitiesList from './ActivitiesList'
|
||||
@ -75,6 +76,16 @@ class Activities extends React.Component {
|
||||
}}
|
||||
/>
|
||||
}
|
||||
{activities.length === 0 && (
|
||||
<div className="card text-center">
|
||||
<div className="card-body">
|
||||
No workouts. {' '}
|
||||
<Link to={{ pathname: '/activities/add' }}>
|
||||
Upload one !
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -54,7 +54,7 @@ function NavBar(props) {
|
||||
pathname: '/activities/add',
|
||||
}}
|
||||
>
|
||||
Add workout
|
||||
<strong>Add workout</strong>
|
||||
</Link>
|
||||
</li>
|
||||
)}
|
||||
|
Loading…
Reference in New Issue
Block a user