From 882933668a3ca583082566c1ed8cfa828d9d17be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C4=93teris=20Caune?= Date: Sun, 15 Oct 2017 13:34:34 +0300 Subject: [PATCH] Natural sort for check names, fixes #136. Apply the user's chosen sort order in emails also. --- hc/accounts/models.py | 7 ++++--- hc/api/transports.py | 9 +++++++++ hc/front/templatetags/hc_extras.py | 27 ++++++++++++++++++++++++++ hc/front/views.py | 4 +--- static/css/my_checks_desktop.css | 8 +++++++- templates/emails/alert-body-html.html | 2 +- templates/emails/summary-html.html | 2 +- templates/front/my_checks_desktop.html | 4 ++-- templates/front/my_checks_mobile.html | 2 +- 9 files changed, 53 insertions(+), 12 deletions(-) diff --git a/hc/accounts/models.py b/hc/accounts/models.py index c41bc8a4..e8885fc0 100644 --- a/hc/accounts/models.py +++ b/hc/accounts/models.py @@ -141,12 +141,13 @@ class Profile(models.Model): path = reverse("hc-unsubscribe-reports", args=[self.user.username]) unsub_link = "%s%s?token=%s" % (settings.SITE_ROOT, path, token) - # Sort checks by team name, then by email, and then by creation date: - checks = checks.order_by( - "user__profile__team_name", "user__email", "created") + # Sort checks by owner. Need this because will group by owner in + # template. + checks = checks.order_by("user_id") ctx = { "checks": checks, + "sort": self.sort, "now": timezone.now(), "unsub_link": unsub_link, "notifications_url": self.notifications_url, diff --git a/hc/api/transports.py b/hc/api/transports.py index 2c7dae8f..8293a498 100644 --- a/hc/api/transports.py +++ b/hc/api/transports.py @@ -52,9 +52,18 @@ class Email(Transport): headers = {"X-Bounce-Url": bounce_url} + try: + # Look up the sorting preference for this email address + p = Profile.objects.get(user__email=self.channel.value) + sort = p.sort + except Profile.DoesNotExist: + # Default sort order is by check's creation time + sort = "created" + ctx = { "check": check, "checks": self.checks(), + "sort": sort, "now": timezone.now(), "unsub_link": self.channel.get_unsub_link() } diff --git a/hc/front/templatetags/hc_extras.py b/hc/front/templatetags/hc_extras.py index 06c52695..e0a107d8 100644 --- a/hc/front/templatetags/hc_extras.py +++ b/hc/front/templatetags/hc_extras.py @@ -1,3 +1,5 @@ +import re + from django import template from django.conf import settings from django.utils.html import escape @@ -31,3 +33,28 @@ def mangle_link(s): @register.simple_tag def site_root(): return settings.SITE_ROOT + + +def naturalize_int_match(match): + return '%08d' % (int(match.group(0)),) + + +def natural_name_key(check): + s = check.name.lower().strip() + return re.sub(r'\d+', naturalize_int_match, s) + + +def last_ping_key(check): + return check.last_ping.isoformat() if check.last_ping else "9999" + + +@register.filter +def sortchecks(checks, key): + if key == "created": + checks.sort(key=lambda check: check.created) + elif key.endswith("name"): + checks.sort(key=natural_name_key, reverse=key.startswith("-")) + elif key.endswith("last_ping"): + checks.sort(key=last_ping_key, reverse=key.startswith("-")) + + return checks diff --git a/hc/front/views.py b/hc/front/views.py index 151cbff8..22853577 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -40,9 +40,7 @@ def my_checks(request): request.profile.sort = request.GET["sort"] request.profile.save() - q = Check.objects.filter(user=request.team.user) - q = q.order_by(request.profile.sort) - checks = list(q) + checks = list(Check.objects.filter(user=request.team.user)) tags, down_tags, grace_tags = set(), set(), set() for check in checks: diff --git a/static/css/my_checks_desktop.css b/static/css/my_checks_desktop.css index fe4a509b..37fd4e18 100644 --- a/static/css/my_checks_desktop.css +++ b/static/css/my_checks_desktop.css @@ -52,7 +52,8 @@ table.table tr > th.th-name { cursor: pointer; } -#checks-table > tbody > tr > th.th-period, #checks-table > tbody > tr > th.th-last-ping { +#checks-table > tbody > tr > th.th-period, +#checks-table > tbody > tr > th.th-last-ping { padding-left: 15px; } @@ -80,6 +81,11 @@ table.table tr > th.th-name { padding: 6px; } +#checks-table .last-ping-never { + padding: 7px; +} + + #checks-table tr:hover .last-ping { border: 1px dotted #AAA; cursor: pointer; diff --git a/templates/emails/alert-body-html.html b/templates/emails/alert-body-html.html index c626420c..7f719d98 100644 --- a/templates/emails/alert-body-html.html +++ b/templates/emails/alert-body-html.html @@ -10,7 +10,7 @@ The check {{ check.name_then_code }} has gone {{ check.status|upper }}.

-Here is a summary of all your checks: +Here is a summary of your checks:
{% include "emails/summary-html.html" %} diff --git a/templates/emails/summary-html.html b/templates/emails/summary-html.html index 23100f2c..f9df7a31 100644 --- a/templates/emails/summary-html.html +++ b/templates/emails/summary-html.html @@ -8,7 +8,7 @@ Last Ping - {% for check in group.list %} + {% for check in group.list|sortchecks:sort %} diff --git a/templates/front/my_checks_desktop.html b/templates/front/my_checks_desktop.html index 877e3efd..ae2a553b 100644 --- a/templates/front/my_checks_desktop.html +++ b/templates/front/my_checks_desktop.html @@ -27,7 +27,7 @@ - {% for check in checks %} + {% for check in checks|sortchecks:sort %}
{% if check.get_status == "new" %} @@ -94,7 +94,7 @@ {% endif %} {% else %} - Never +
Never
{% endif %}
diff --git a/templates/front/my_checks_mobile.html b/templates/front/my_checks_mobile.html index c9f85195..6670a025 100644 --- a/templates/front/my_checks_mobile.html +++ b/templates/front/my_checks_mobile.html @@ -1,7 +1,7 @@ {% load hc_extras humanize %}
    - {% for check in checks %} + {% for check in checks|sortchecks:sort %}