parent
30a16f64b0
commit
859f690ba4
@ -6,6 +6,7 @@ from flask import Blueprint, jsonify, request
|
|||||||
from ..users.models import User
|
from ..users.models import User
|
||||||
from ..users.utils import authenticate
|
from ..users.utils import authenticate
|
||||||
from .models import Activity, Sport
|
from .models import Activity, Sport
|
||||||
|
from .utils import get_datetime_with_tz
|
||||||
from .utils_format import convert_timedelta_to_integer
|
from .utils_format import convert_timedelta_to_integer
|
||||||
|
|
||||||
stats_blueprint = Blueprint('stats', __name__)
|
stats_blueprint = Blueprint('stats', __name__)
|
||||||
@ -23,7 +24,14 @@ def get_activities(user_id, type):
|
|||||||
|
|
||||||
params = request.args.copy()
|
params = request.args.copy()
|
||||||
date_from = params.get('from')
|
date_from = params.get('from')
|
||||||
|
if date_from:
|
||||||
|
date_from = datetime.strptime(date_from, '%Y-%m-%d')
|
||||||
|
_, date_from = get_datetime_with_tz(user_id, date_from)
|
||||||
date_to = params.get('to')
|
date_to = params.get('to')
|
||||||
|
if date_to:
|
||||||
|
date_to = datetime.strptime(f'{date_to} 23:59:59',
|
||||||
|
'%Y-%m-%d %H:%M:%S')
|
||||||
|
_, date_to = get_datetime_with_tz(user_id, date_to)
|
||||||
sport_id = params.get('sport_id')
|
sport_id = params.get('sport_id')
|
||||||
time = params.get('time')
|
time = params.get('time')
|
||||||
|
|
||||||
@ -41,11 +49,9 @@ def get_activities(user_id, type):
|
|||||||
|
|
||||||
activities = Activity.query.filter(
|
activities = Activity.query.filter(
|
||||||
Activity.user_id == user_id,
|
Activity.user_id == user_id,
|
||||||
Activity.activity_date >= datetime.strptime(date_from, '%Y-%m-%d')
|
Activity.activity_date >= date_from if date_from else True,
|
||||||
if date_from else True,
|
Activity.activity_date < date_to + timedelta(seconds=1)
|
||||||
Activity.activity_date < (
|
if date_to else True,
|
||||||
datetime.strptime(date_to, '%Y-%m-%d') + timedelta(days=1)
|
|
||||||
) if date_to else True,
|
|
||||||
Activity.sport_id == sport_id if sport_id else True,
|
Activity.sport_id == sport_id if sport_id else True,
|
||||||
).order_by(
|
).order_by(
|
||||||
Activity.activity_date.asc()
|
Activity.activity_date.asc()
|
||||||
|
@ -207,6 +207,51 @@ def test_get_stats_by_time_all_activities_april_2018(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_stats_by_time_all_activities_april_2018_paris(
|
||||||
|
app, user_1_paris, sport_1_cycling, sport_2_running,
|
||||||
|
seven_activities_user_1, activity_running_user_1
|
||||||
|
):
|
||||||
|
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'
|
||||||
|
)
|
||||||
|
response = client.get(
|
||||||
|
f'/api/stats/{user_1_paris.id}/by_time?from=2018-04-01&to=2018-04-30',
|
||||||
|
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 data['data']['statistics'] == \
|
||||||
|
{
|
||||||
|
'2018':
|
||||||
|
{
|
||||||
|
'1':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 8.0,
|
||||||
|
'total_duration': 6000
|
||||||
|
},
|
||||||
|
'2':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 12.0,
|
||||||
|
'total_duration': 6000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_get_stats_by_year_all_activities(
|
def test_get_stats_by_year_all_activities(
|
||||||
app, user_1, sport_1_cycling, sport_2_running,
|
app, user_1, sport_1_cycling, sport_2_running,
|
||||||
seven_activities_user_1, activity_running_user_1
|
seven_activities_user_1, activity_running_user_1
|
||||||
@ -306,6 +351,51 @@ def test_get_stats_by_year_all_activities_april_2018(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_stats_by_year_all_activities_april_2018_paris(
|
||||||
|
app, user_1_paris, sport_1_cycling, sport_2_running,
|
||||||
|
seven_activities_user_1, activity_running_user_1
|
||||||
|
):
|
||||||
|
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'
|
||||||
|
)
|
||||||
|
response = client.get(
|
||||||
|
f'/api/stats/{user_1_paris.id}/by_time?from=2018-04-01&to=2018-04-30&time=year', # noqa
|
||||||
|
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 data['data']['statistics'] == \
|
||||||
|
{
|
||||||
|
'2018':
|
||||||
|
{
|
||||||
|
'1':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 8.0,
|
||||||
|
'total_duration': 6000
|
||||||
|
},
|
||||||
|
'2':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 12.0,
|
||||||
|
'total_duration': 6000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_get_stats_by_month_all_activities(
|
def test_get_stats_by_month_all_activities(
|
||||||
app, user_1, sport_1_cycling, sport_2_running,
|
app, user_1, sport_1_cycling, sport_2_running,
|
||||||
seven_activities_user_1, activity_running_user_1
|
seven_activities_user_1, activity_running_user_1
|
||||||
@ -396,6 +486,96 @@ def test_get_stats_by_month_all_activities(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_stats_by_month_all_activities_new_york(
|
||||||
|
app, user_1_full, sport_1_cycling, sport_2_running,
|
||||||
|
seven_activities_user_1, activity_running_user_1
|
||||||
|
):
|
||||||
|
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'
|
||||||
|
)
|
||||||
|
response = client.get(
|
||||||
|
f'/api/stats/{user_1_full.id}/by_time?time=month',
|
||||||
|
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 data['data']['statistics'] == \
|
||||||
|
{
|
||||||
|
'2017-03':
|
||||||
|
{
|
||||||
|
'1':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 5.0,
|
||||||
|
'total_duration': 1024
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'2017-06':
|
||||||
|
{
|
||||||
|
'1':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 10.0,
|
||||||
|
'total_duration': 3456
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'2018-01':
|
||||||
|
{
|
||||||
|
'1':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 10.0,
|
||||||
|
'total_duration': 1024
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'2018-02':
|
||||||
|
{
|
||||||
|
'1':
|
||||||
|
{
|
||||||
|
'nb_activities': 2,
|
||||||
|
'total_distance': 11.0,
|
||||||
|
'total_duration': 1600
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'2018-04':
|
||||||
|
{
|
||||||
|
'1':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 8.0,
|
||||||
|
'total_duration': 6000
|
||||||
|
},
|
||||||
|
'2':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 12.0,
|
||||||
|
'total_duration': 6000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'2018-05':
|
||||||
|
{
|
||||||
|
'1':
|
||||||
|
{
|
||||||
|
'nb_activities': 1,
|
||||||
|
'total_distance': 10.0,
|
||||||
|
'total_duration': 3000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_get_stats_by_month_all_activities_april_2018(
|
def test_get_stats_by_month_all_activities_april_2018(
|
||||||
app, user_1, sport_1_cycling, sport_2_running,
|
app, user_1, sport_1_cycling, sport_2_running,
|
||||||
seven_activities_user_1, activity_running_user_1
|
seven_activities_user_1, activity_running_user_1
|
||||||
@ -442,7 +622,7 @@ def test_get_stats_by_month_all_activities_april_2018(
|
|||||||
|
|
||||||
|
|
||||||
def test_get_stats_by_week_all_activities(
|
def test_get_stats_by_week_all_activities(
|
||||||
app, user_1, sport_1_cycling, sport_2_running,
|
app, user_1_full, sport_1_cycling, sport_2_running,
|
||||||
seven_activities_user_1, activity_running_user_1
|
seven_activities_user_1, activity_running_user_1
|
||||||
):
|
):
|
||||||
client = app.test_client()
|
client = app.test_client()
|
||||||
@ -455,7 +635,7 @@ def test_get_stats_by_week_all_activities(
|
|||||||
content_type='application/json'
|
content_type='application/json'
|
||||||
)
|
)
|
||||||
response = client.get(
|
response = client.get(
|
||||||
f'/api/stats/{user_1.id}/by_time?time=week',
|
f'/api/stats/{user_1_full.id}/by_time?time=week',
|
||||||
headers=dict(
|
headers=dict(
|
||||||
Authorization='Bearer ' + json.loads(
|
Authorization='Bearer ' + json.loads(
|
||||||
resp_login.data.decode()
|
resp_login.data.decode()
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
} from 'recharts'
|
} from 'recharts'
|
||||||
|
|
||||||
import { getStats } from '../../actions/stats'
|
import { getStats } from '../../actions/stats'
|
||||||
import { activityColors, formatStats } from '../../utils'
|
import { activityColors, formatDuration, formatStats } from '../../utils'
|
||||||
|
|
||||||
|
|
||||||
class Statistics extends React.Component {
|
class Statistics extends React.Component {
|
||||||
@ -90,7 +90,7 @@ class Statistics extends React.Component {
|
|||||||
tickFormatter={value => displayedData === 'distance'
|
tickFormatter={value => displayedData === 'distance'
|
||||||
? `${value} km`
|
? `${value} km`
|
||||||
: displayedData === 'duration'
|
: displayedData === 'duration'
|
||||||
? format(new Date(value * 1000), 'HH:mm')
|
? format(formatDuration(value), 'HH:mm')
|
||||||
: value
|
: value
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -100,7 +100,7 @@ class Statistics extends React.Component {
|
|||||||
key={s.id}
|
key={s.id}
|
||||||
dataKey={s.label}
|
dataKey={s.label}
|
||||||
formatter={value => displayedData === 'duration'
|
formatter={value => displayedData === 'duration'
|
||||||
? format(new Date(value * 1000), 'HH:mm')
|
? format(formatDuration(value), 'HH:mm')
|
||||||
: value
|
: value
|
||||||
}
|
}
|
||||||
stackId="a"
|
stackId="a"
|
||||||
|
@ -117,7 +117,7 @@ export const formatRecord = (record, tz) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatDuration = seconds => {
|
export const formatDuration = seconds => {
|
||||||
let newDate = new Date(0)
|
let newDate = new Date(0)
|
||||||
newDate = subHours(newDate.setSeconds(seconds), 1)
|
newDate = subHours(newDate.setSeconds(seconds), 1)
|
||||||
return newDate.getTime()
|
return newDate.getTime()
|
||||||
|
Loading…
Reference in New Issue
Block a user