Show all statistics fetched on the dashboard

We want to align all our stats to be for the last 7 days.

This means summing up the stats response from the API to make the Big
Number. Previously the big number was counting sent notifications as
successful. This commit changes it to only look at delivered
notifications.

Right now, the API doesn’t have a way of filtering to only show the last
7 days. So for the moment the dashboard will show statistics for all
time.

The upshot of this is that we can link from the dashboard to the
activity page when there are failures.
This commit is contained in:
Chris Hill-Scott
2016-04-19 12:57:55 +01:00
parent ddec619913
commit 5bf0d8fe70
5 changed files with 60 additions and 43 deletions

View File

@@ -1,6 +1,7 @@
from datetime import date
from collections import namedtuple
from itertools import groupby
from functools import reduce
from flask import (
render_template,
@@ -29,25 +30,21 @@ from app.utils import user_has_permissions
@login_required
@user_has_permissions('view_activity', admin_override=True)
def service_dashboard(service_id):
templates = service_api_client.get_service_templates(service_id)['data']
jobs = job_api_client.get_job(service_id)['data']
if session.get('invited_user'):
session.pop('invited_user', None)
return redirect(url_for("main.tour", service_id=service_id, page=1))
statistics = statistics_api_client.get_statistics_for_service(service_id)['data']
template_statistics = aggregate_usage(template_statistics_client.get_template_statistics_for_service(service_id))
return render_template(
'views/dashboard/dashboard.html',
jobs=jobs[:5],
more_jobs_to_show=(len(jobs) > 5),
free_text_messages_remaining='250,000',
spent_this_month='0.00',
statistics=add_rates_to(statistics),
templates=templates,
template_statistics=template_statistics)
statistics=add_rates_to(
statistics_api_client.get_statistics_for_service(service_id)['data']
),
templates=service_api_client.get_service_templates(service_id)['data'],
template_statistics=aggregate_usage(
template_statistics_client.get_template_statistics_for_service(service_id)
)
)
@main.route("/services/<service_id>/dashboard.json")
@@ -60,8 +57,12 @@ def service_dashboard_updates(service_id):
return jsonify(**{
'today': render_template(
'views/dashboard/today.html',
statistics=add_rates_to(statistics),
template_statistics=template_statistics
statistics=add_rates_to(
statistics_api_client.get_statistics_for_service(service_id)['data']
),
template_statistics=aggregate_usage(
template_statistics_client.get_template_statistics_for_service(service_id)
)
)
})
@@ -71,24 +72,32 @@ def add_rates_to(delivery_statistics):
if not delivery_statistics or not delivery_statistics[0]:
return {}
today = None
latest_stats = {}
if delivery_statistics[0]['day'] == date.today().strftime('%Y-%m-%d'):
today = delivery_statistics[0]
latest_stats = delivery_statistics[0]
sum_of_statistics = reduce(
lambda x, y: {
key: x.get(key, 0) + y.get(key, 0)
for key in [
'emails_delivered',
'emails_requested',
'emails_failed',
'sms_requested',
'sms_delivered',
'sms_failed'
]
},
delivery_statistics
)
latest_stats.update({
'emails_failure_rate': (
"{0:.1f}".format((float(today['emails_failed']) / today['emails_requested'] * 100))
if today and today['emails_requested'] else 0
return dict(
emails_failure_rate=(
"{0:.1f}".format((float(sum_of_statistics['emails_failed']) / sum_of_statistics['emails_requested'] * 100))
if sum_of_statistics.get('emails_requested') else 0
),
'sms_failure_rate': (
"{0:.1f}".format((float(today['sms_failed']) / today['sms_requested'] * 100))
if today and today['sms_requested'] else 0
)
})
return latest_stats
sms_failure_rate=(
"{0:.1f}".format((float(sum_of_statistics['sms_failed']) / sum_of_statistics['sms_requested'] * 100))
if sum_of_statistics.get('sms_requested') else 0
),
**sum_of_statistics
)
def aggregate_usage(template_statistics):

View File

@@ -6,12 +6,18 @@
{% endmacro %}
{% macro big_number_with_status(number, label, failures, failure_percentage, danger_zone=False) %}
{% macro big_number_with_status(number, label, failures, failure_percentage, danger_zone=False, failure_link=None) %}
<div class="big-number-with-status">
{{ big_number(number, label) }}
<div class="big-number-status{% if danger_zone %}-failing{% endif %}">
{% if failures %}
{{ failures }} failed {{ failure_percentage }}%
{% if failure_link %}
<a href="{{ failure_link }}">
{{ failures }} failed {{ failure_percentage }}%
</a>
{% else %}
{{ failures }} failed {{ failure_percentage }}%
{% endif %}
{% else %}
No failures
{% endif %}

View File

@@ -1,9 +1,10 @@
{% from "components/table.html" import list_table, field, hidden_field_heading, right_aligned_field_heading %}
{% call(item, row_number) list_table(
template_statistics,
caption="In the last 7 days",
caption="By template",
caption_visible=False,
empty_message='You havent set up any templates yet',
field_headings=['Template', hidden_field_heading('Type'), right_aligned_field_heading('Messages sent')]
field_headings=['Template', hidden_field_heading('Type'), right_aligned_field_heading('Messages processed')]
) %}
{% call field() %}
<a href="{{ url_for('.view_template', service_id=current_service.id, template_id=item.template.id) }}">

View File

@@ -1,16 +1,17 @@
{% from "components/big-number.html" import big_number_with_status %}
<h2 class="heading-medium">
Sent today
In the last 7 days
</h2>
<div class="grid-row">
<div class="grid-row bottom-gutter">
<div class="column-half">
{{ big_number_with_status(
statistics.get('emails_requested', 0),
'email' if statistics.get('emails_requested') == 1 else 'emails',
statistics.get('emails_delivered', 0),
'email' if statistics.get('emails_delivered') == 1 else 'emails',
statistics.get('emails_failed'),
statistics.get('emails_failure_rate', 0.0),
statistics.get('emails_failure_rate', 0)|float > 3
statistics.get('emails_failure_rate', 0)|float > 3,
failure_link=url_for(".view_notifications", service_id=current_service.id, template_type='email', status='failed')
) }}
</div>
<div class="column-half">
@@ -19,10 +20,10 @@
'text message' if statistics.get('sms_requested') == 1 else 'text messages',
statistics.get('sms_failed'),
statistics.get('sms_failure_rate', 0.0),
statistics.get('sms_failure_rate', 0)|float > 3
statistics.get('sms_failure_rate', 0)|float > 3,
failure_link=url_for(".view_notifications", service_id=current_service.id, template_type='sms', status='failed')
) }}
</div>
</div>
{% include 'views/dashboard/template-statistics.html' %}

View File

@@ -83,9 +83,9 @@ def test_should_show_recent_templates_on_dashboard(app_,
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
headers = [header.text.strip() for header in page.find_all('h2')]
assert 'Test Service' in headers
assert 'Sent today' in headers
assert 'In the last 7 days' in headers
template_usage_headers = [th.text.strip() for th in page.thead.find_all('th')]
for th in ['Template', 'Type', 'Messages sent']:
for th in ['Template', 'Type', 'Messages processed']:
assert th in template_usage_headers
table_rows = page.tbody.find_all('tr')