Skip to content

Commit

Permalink
API: timezone support for statistics - fix #11
Browse files Browse the repository at this point in the history
+ Client fix
  • Loading branch information
SamR1 committed Jun 11, 2018
1 parent 30a16f6 commit 859f690
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 11 deletions.
16 changes: 11 additions & 5 deletions fittrackee_api/fittrackee_api/activities/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from ..users.models import User
from ..users.utils import authenticate
from .models import Activity, Sport
from .utils import get_datetime_with_tz
from .utils_format import convert_timedelta_to_integer

stats_blueprint = Blueprint('stats', __name__)
Expand All @@ -23,7 +24,14 @@ def get_activities(user_id, type):

params = request.args.copy()
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')
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')
time = params.get('time')

Expand All @@ -41,11 +49,9 @@ def get_activities(user_id, type):

activities = Activity.query.filter(
Activity.user_id == user_id,
Activity.activity_date >= datetime.strptime(date_from, '%Y-%m-%d')
if date_from else True,
Activity.activity_date < (
datetime.strptime(date_to, '%Y-%m-%d') + timedelta(days=1)
) if date_to else True,
Activity.activity_date >= date_from if date_from else True,
Activity.activity_date < date_to + timedelta(seconds=1)
if date_to else True,
Activity.sport_id == sport_id if sport_id else True,
).order_by(
Activity.activity_date.asc()
Expand Down
184 changes: 182 additions & 2 deletions fittrackee_api/fittrackee_api/tests/test_stats_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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='[email protected]',
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(
app, user_1, sport_1_cycling, sport_2_running,
seven_activities_user_1, activity_running_user_1
Expand Down Expand Up @@ -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='[email protected]',
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(
app, user_1, sport_1_cycling, sport_2_running,
seven_activities_user_1, activity_running_user_1
Expand Down Expand Up @@ -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='[email protected]',
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(
app, user_1, sport_1_cycling, sport_2_running,
seven_activities_user_1, activity_running_user_1
Expand Down Expand Up @@ -442,7 +622,7 @@ def test_get_stats_by_month_all_activities_april_2018(


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
):
client = app.test_client()
Expand All @@ -455,7 +635,7 @@ def test_get_stats_by_week_all_activities(
content_type='application/json'
)
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(
Authorization='Bearer ' + json.loads(
resp_login.data.decode()
Expand Down
6 changes: 3 additions & 3 deletions fittrackee_client/src/components/Dashboard/Statistics.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from 'recharts'

import { getStats } from '../../actions/stats'
import { activityColors, formatStats } from '../../utils'
import { activityColors, formatDuration, formatStats } from '../../utils'


class Statistics extends React.Component {
Expand Down Expand Up @@ -90,7 +90,7 @@ class Statistics extends React.Component {
tickFormatter={value => displayedData === 'distance'
? `${value} km`
: displayedData === 'duration'
? format(new Date(value * 1000), 'HH:mm')
? format(formatDuration(value), 'HH:mm')
: value
}
/>
Expand All @@ -100,7 +100,7 @@ class Statistics extends React.Component {
key={s.id}
dataKey={s.label}
formatter={value => displayedData === 'duration'
? format(new Date(value * 1000), 'HH:mm')
? format(formatDuration(value), 'HH:mm')
: value
}
stackId="a"
Expand Down
2 changes: 1 addition & 1 deletion fittrackee_client/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export const formatRecord = (record, tz) => {
}
}

const formatDuration = seconds => {
export const formatDuration = seconds => {
let newDate = new Date(0)
newDate = subHours(newDate.setSeconds(seconds), 1)
return newDate.getTime()
Expand Down

0 comments on commit 859f690

Please sign in to comment.