From 7db41852673492dad998f1443631e272e3f47d32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C4=93teris=20Caune?=
Date: Wed, 1 Jul 2015 00:28:13 +0300
Subject: [PATCH] Better welcome page.
---
.gitignore | 1 +
hc/accounts/views.py | 9 ++
hc/api/migrations/0005_auto_20150630_2021.py | 20 ++++
hc/api/models.py | 2 +-
hc/front/urls.py | 1 +
hc/front/views.py | 50 ++++++++-
static/css/style.css | 14 +--
static/js/checks.js | 1 -
static/js/index.js | 45 ++++++++
templates/about.html | 13 ++-
templates/base.html | 2 +-
templates/front/index.html | 10 +-
templates/front/snippets/bash.txt | 5 +
templates/front/snippets/browser.txt | 3 +
templates/front/snippets/crontab.txt | 2 +
templates/front/snippets/python.txt | 7 ++
templates/index.html | 104 +++++++++++++------
17 files changed, 243 insertions(+), 46 deletions(-)
create mode 100644 hc/api/migrations/0005_auto_20150630_2021.py
create mode 100644 static/js/index.js
create mode 100644 templates/front/snippets/bash.txt
create mode 100644 templates/front/snippets/browser.txt
create mode 100644 templates/front/snippets/crontab.txt
create mode 100644 templates/front/snippets/python.txt
diff --git a/.gitignore b/.gitignore
index c18dd8d8..99c06936 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
__pycache__/
+local_settings.py
\ No newline at end of file
diff --git a/hc/accounts/views.py b/hc/accounts/views.py
index 1fa776cf..5a789087 100644
--- a/hc/accounts/views.py
+++ b/hc/accounts/views.py
@@ -10,6 +10,7 @@ from django.http import HttpResponseBadRequest
from django.shortcuts import redirect, render
from hc.accounts.forms import EmailForm
+from hc.api.models import Check
def _make_user(email):
@@ -20,6 +21,13 @@ def _make_user(email):
return user
+def _associate_demo_check(request, user):
+ if "welcome_code" in request.session:
+ check = Check.objects.get(code=request.session["welcome_code"])
+ check.user = user
+ check.save()
+
+
def login(request):
if request.method == 'POST':
form = EmailForm(request.POST)
@@ -29,6 +37,7 @@ def login(request):
user = User.objects.get(email=email)
except User.DoesNotExist:
user = _make_user(email)
+ _associate_demo_check(request, user)
# We don't want to reset passwords of staff users :-)
if user.is_staff:
diff --git a/hc/api/migrations/0005_auto_20150630_2021.py b/hc/api/migrations/0005_auto_20150630_2021.py
new file mode 100644
index 00000000..02620d22
--- /dev/null
+++ b/hc/api/migrations/0005_auto_20150630_2021.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+from django.conf import settings
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('api', '0004_auto_20150616_1319'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='check',
+ name='user',
+ field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True),
+ ),
+ ]
diff --git a/hc/api/models.py b/hc/api/models.py
index 31b9ff89..e5b2e53b 100644
--- a/hc/api/models.py
+++ b/hc/api/models.py
@@ -11,7 +11,7 @@ DEFAULT_TIMEOUT = td(days=1)
class Check(models.Model):
name = models.CharField(max_length=100, blank=True)
code = models.UUIDField(default=uuid.uuid4, editable=False)
- user = models.ForeignKey(User)
+ user = models.ForeignKey(User, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
timeout = models.DurationField(default=DEFAULT_TIMEOUT)
last_ping = models.DateTimeField(null=True, blank=True)
diff --git a/hc/front/urls.py b/hc/front/urls.py
index c7f2fc58..8a11152d 100644
--- a/hc/front/urls.py
+++ b/hc/front/urls.py
@@ -11,4 +11,5 @@ urlpatterns = [
url(r'^pricing/$', views.pricing, name="hc-pricing"),
url(r'^docs/$', views.docs, name="hc-docs"),
url(r'^about/$', views.about, name="hc-about"),
+ url(r'^welcome/timer/$', views.welcome_timer, name="hc-welcome-timer"),
]
diff --git a/hc/front/views.py b/hc/front/views.py
index 4b47e3e8..10cc3f61 100644
--- a/hc/front/views.py
+++ b/hc/front/views.py
@@ -1,5 +1,8 @@
+import json
+
from django.contrib.auth.decorators import login_required
-from django.http import HttpResponseForbidden
+from django.contrib.humanize.templatetags.humanize import naturaltime
+from django.http import HttpResponse, HttpResponseForbidden
from django.shortcuts import redirect, render
from django.utils import timezone
@@ -8,7 +11,32 @@ from hc.front.forms import TimeoutForm, TIMEOUT_CHOICES
def index(request):
- return render(request, "index.html", {"page": "welcome"})
+ if "welcome_code" not in request.session:
+ check = Check()
+ check.save()
+ code = str(check.code)
+ request.session["welcome_code"] = code
+ else:
+ code = request.session["welcome_code"]
+ check = Check.objects.get(code=code)
+
+ if check.alert_after:
+ duration = check.alert_after - timezone.now()
+ timer = int(duration.total_seconds())
+ timer_formatted = "%dh %dm %ds" % (timer / 3600, (timer / 60) % 60, timer % 60)
+ else:
+ timer = 0
+ timer_formatted = "Never"
+
+ ctx = {
+ "page": "welcome",
+ "check": check,
+ "timer": timer,
+ "timer_formatted": timer_formatted,
+ "ping_url": "http://healthchecks.io/ping/%s/" % check.code
+ }
+
+ return render(request, "index.html", ctx)
def pricing(request):
@@ -23,6 +51,24 @@ def about(request):
return render(request, "about.html", {"page": "about"})
+def welcome_timer(request):
+ code = request.session["welcome_code"]
+
+ check = Check.objects.get(code=code)
+ if check.last_ping and check.alert_after:
+ duration = check.alert_after - timezone.now()
+ response = {
+ "last_ping": check.last_ping.isoformat(),
+ "last_ping_human": naturaltime(check.last_ping),
+ "timer": int(duration.total_seconds())
+ }
+ else:
+ response = {"last_ping": None, "timer": None}
+
+ return HttpResponse(json.dumps(response),
+ content_type="application/javascript")
+
+
@login_required
def checks(request):
diff --git a/static/css/style.css b/static/css/style.css
index 1c3069e3..be8bca50 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -4,18 +4,20 @@ html, body {
#pitch {
text-align: center;
- padding: 2em 0 3em 0;
+ padding: 2em 0 2em 0;
}
-.step-number {
+#pitch-subtitle {
text-align: center;
- font-size: 48px;
- font-weight: bold;
- color: #777;
+}
+#pitch-url {
+ text-align: center;
+ font-family: monospace;
+ padding-bottom: 2em;
}
-#get-started {
+#welcome-status, #get-started {
margin-top: 4em;
}
diff --git a/static/js/checks.js b/static/js/checks.js
index a22a7c24..eca84fe1 100644
--- a/static/js/checks.js
+++ b/static/js/checks.js
@@ -34,7 +34,6 @@ $(function () {
});
$(".timeout-edit-cancel").click(function() {
- console.log("aaa");
$(this).parents("td").addClass("inactive");
return false;
});
diff --git a/static/js/index.js b/static/js/index.js
new file mode 100644
index 00000000..0c4d4105
--- /dev/null
+++ b/static/js/index.js
@@ -0,0 +1,45 @@
+$(function () {
+ $('[data-toggle="tooltip"]').tooltip();
+
+ var url = $("#pitch-url").text();
+ var lastPing = null;
+ var lastPingHuman = null;
+
+ $("#run-it").click(function() {
+ $.get(url);
+ });
+
+ function checkLastPing() {
+ $.getJSON("/welcome/timer/", function(data) {
+ if (data.last_ping != lastPing) {
+ lastPing = data.last_ping;
+ $("#timer").data("timer", data.timer);
+ }
+
+ if (data.last_ping_human.indexOf("seconds ago") > 0)
+ data.last_ping_human = "seconds ago";
+
+ if (data.last_ping_human != lastPingHuman) {
+ lastPingHuman = data.last_ping_human;
+ $("#last-ping").text(lastPingHuman);
+ }
+ });
+ }
+
+ function updateTimer() {
+ var timer = parseInt($("#timer").data("timer"));
+ if (timer == 0)
+ return;
+
+ var s = timer % 60;
+ var m = parseInt(timer / 60) % 60;
+ var h = parseInt(timer / 3600);
+ $("#timer").text(h + "h " + m + "m " + s + "s");
+
+ $("#timer").data("timer", timer - 1);
+ }
+
+ setInterval(checkLastPing, 3000);
+ setInterval(updateTimer, 1000);
+
+});
\ No newline at end of file
diff --git a/templates/about.html b/templates/about.html
index bd0e7902..60acf33d 100644
--- a/templates/about.html
+++ b/templates/about.html
@@ -9,15 +9,22 @@
Hello, my name is PÄ“teris Caune, I live in Riga, Latvia and do programming for living.
You can contact me via email.
+
+ Code is on
+ GitHub.
+
+
Reliability Guarantees
Health Checks is currently at a very early stage as you can probably tell.
- The service is currently run on single $5 Digital Ocean box. The service
- can and will have ocassional outages. User data should be safe however,
- as we are doing regular database backups to Amazon S3.
+ The service is currently run on single $5 Digital Ocean box.
+ It can and will have ocassional outages.
+
+
If all this does not sound very inspiring,
there are also alternative services:
diff --git a/templates/base.html b/templates/base.html
index 3ea5e167..990c083b 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -57,6 +57,6 @@
-
+ {% block scripts %}{% endblock %}