diff --git a/hc/accounts/views.py b/hc/accounts/views.py index 184b7f17..f7f39dac 100644 --- a/hc/accounts/views.py +++ b/hc/accounts/views.py @@ -289,7 +289,11 @@ def badges(request): ctx = { "page": "profile", - "urls": urls + "urls": urls, + "master": { + "svg": get_badge_url(username, "*"), + "json": get_badge_url(username, "*", format="json") + } } return render(request, "accounts/badges.html", ctx) diff --git a/hc/api/urls.py b/hc/api/urls.py index 17b56f2e..dc974a77 100644 --- a/hc/api/urls.py +++ b/hc/api/urls.py @@ -13,8 +13,15 @@ urlpatterns = [ url(r'^badge/([\w-]+)/([\w-]{8})/([\w-]+).svg$', views.badge, name="hc-badge"), + + url(r'^badge/([\w-]+)/([\w-]{8}).svg$', views.badge, + {"tag": "*"}, name="hc-badge-all"), + url(r'^badge/([\w-]+)/([\w-]{8})/([\w-]+).json$', views.badge, - {"format": "json"}, name="hc-badge-json", ), + {"format": "json"}, name="hc-badge-json"), + + url(r'^badge/([\w-]+)/([\w-]{8}).json$', views.badge, + {"format": "json", "tag": "*"}, name="hc-badge-json-all"), url(r'^api/v1/status/$', views.status), ] diff --git a/hc/api/views.py b/hc/api/views.py index 9da65f36..44ee5f97 100644 --- a/hc/api/views.py +++ b/hc/api/views.py @@ -1,5 +1,6 @@ from datetime import timedelta as td +from django.conf import settings from django.db import connection from django.http import (HttpResponse, HttpResponseForbidden, HttpResponseNotFound, JsonResponse) @@ -168,9 +169,15 @@ def badge(request, username, signature, tag, format="svg"): return HttpResponseNotFound() status = "up" - q = Check.objects.filter(user__username=username, tags__contains=tag) + q = Check.objects.filter(user__username=username) + if tag != "*": + q = q.filter(tags__contains=tag) + label = tag + else: + label = settings.MASTER_BADGE_LABEL + for check in q: - if tag not in check.tags_list(): + if tag != "*" and tag not in check.tags_list(): continue if status == "up" and check.in_grace_period(): @@ -183,7 +190,7 @@ def badge(request, username, signature, tag, format="svg"): if format == "json": return JsonResponse({"status": status}) - svg = get_badge_svg(tag, status) + svg = get_badge_svg(label, status) return HttpResponse(svg, content_type="image/svg+xml") diff --git a/hc/lib/badges.py b/hc/lib/badges.py index 78ab327f..21777535 100644 --- a/hc/lib/badges.py +++ b/hc/lib/badges.py @@ -50,7 +50,13 @@ def check_signature(username, tag, sig): def get_badge_url(username, tag, format="svg"): - view = "hc-badge-json" if format == "json" else "hc-badge" sig = base64_hmac(str(username), tag, settings.SECRET_KEY) - url = reverse(view, args=[username, sig[:8], tag]) + + if tag == "*": + view = "hc-badge-json-all" if format == "json" else "hc-badge-all" + url = reverse(view, args=[username, sig[:8]]) + else: + view = "hc-badge-json" if format == "json" else "hc-badge" + url = reverse(view, args=[username, sig[:8], tag]) + return settings.SITE_ROOT + url diff --git a/hc/settings.py b/hc/settings.py index 2f2be05a..65e68e5e 100644 --- a/hc/settings.py +++ b/hc/settings.py @@ -121,7 +121,7 @@ USE_L10N = True USE_TZ = True SITE_ROOT = "http://localhost:8000" -SITE_NAME = "healthchecks.io" +SITE_NAME = MASTER_BADGE_LABEL = "healthchecks.io" PING_ENDPOINT = SITE_ROOT + "/ping/" PING_EMAIL_DOMAIN = HOST STATIC_URL = '/static/' diff --git a/static/css/settings.css b/static/css/settings.css index ebbc8a6f..61e41c3f 100644 --- a/static/css/settings.css +++ b/static/css/settings.css @@ -29,6 +29,11 @@ background-color: #ffebea; } +.table td.overall-status { + padding-top: 32px; + border-top: 0; +} + #badges-json { display: none; } diff --git a/templates/accounts/badges.html b/templates/accounts/badges.html index 58a78be2..73cd4294 100644 --- a/templates/accounts/badges.html +++ b/templates/accounts/badges.html @@ -51,6 +51,17 @@ {% endfor %} + + Overall status: + + + + + + + {{ master.svg }} + + {% for urldict in urls %} @@ -62,6 +73,15 @@ {% endfor %} + + + + + +
Overall status:
+ + {{ master.json }} +
{% else %}