Browse Source

Better welcome page.

pull/7/head
Pēteris Caune 10 years ago
parent
commit
7db4185267
17 changed files with 243 additions and 46 deletions
  1. +1
    -0
      .gitignore
  2. +9
    -0
      hc/accounts/views.py
  3. +20
    -0
      hc/api/migrations/0005_auto_20150630_2021.py
  4. +1
    -1
      hc/api/models.py
  5. +1
    -0
      hc/front/urls.py
  6. +48
    -2
      hc/front/views.py
  7. +8
    -6
      static/css/style.css
  8. +0
    -1
      static/js/checks.js
  9. +45
    -0
      static/js/index.js
  10. +10
    -3
      templates/about.html
  11. +1
    -1
      templates/base.html
  12. +7
    -3
      templates/front/index.html
  13. +5
    -0
      templates/front/snippets/bash.txt
  14. +3
    -0
      templates/front/snippets/browser.txt
  15. +2
    -0
      templates/front/snippets/crontab.txt
  16. +7
    -0
      templates/front/snippets/python.txt
  17. +75
    -29
      templates/index.html

+ 1
- 0
.gitignore View File

@ -1 +1,2 @@
__pycache__/ __pycache__/
local_settings.py

+ 9
- 0
hc/accounts/views.py View File

@ -10,6 +10,7 @@ from django.http import HttpResponseBadRequest
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from hc.accounts.forms import EmailForm from hc.accounts.forms import EmailForm
from hc.api.models import Check
def _make_user(email): def _make_user(email):
@ -20,6 +21,13 @@ def _make_user(email):
return user 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): def login(request):
if request.method == 'POST': if request.method == 'POST':
form = EmailForm(request.POST) form = EmailForm(request.POST)
@ -29,6 +37,7 @@ def login(request):
user = User.objects.get(email=email) user = User.objects.get(email=email)
except User.DoesNotExist: except User.DoesNotExist:
user = _make_user(email) user = _make_user(email)
_associate_demo_check(request, user)
# We don't want to reset passwords of staff users :-) # We don't want to reset passwords of staff users :-)
if user.is_staff: if user.is_staff:


+ 20
- 0
hc/api/migrations/0005_auto_20150630_2021.py View File

@ -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),
),
]

+ 1
- 1
hc/api/models.py View File

@ -11,7 +11,7 @@ DEFAULT_TIMEOUT = td(days=1)
class Check(models.Model): class Check(models.Model):
name = models.CharField(max_length=100, blank=True) name = models.CharField(max_length=100, blank=True)
code = models.UUIDField(default=uuid.uuid4, editable=False) 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) created = models.DateTimeField(auto_now_add=True)
timeout = models.DurationField(default=DEFAULT_TIMEOUT) timeout = models.DurationField(default=DEFAULT_TIMEOUT)
last_ping = models.DateTimeField(null=True, blank=True) last_ping = models.DateTimeField(null=True, blank=True)


+ 1
- 0
hc/front/urls.py View File

@ -11,4 +11,5 @@ urlpatterns = [
url(r'^pricing/$', views.pricing, name="hc-pricing"), url(r'^pricing/$', views.pricing, name="hc-pricing"),
url(r'^docs/$', views.docs, name="hc-docs"), url(r'^docs/$', views.docs, name="hc-docs"),
url(r'^about/$', views.about, name="hc-about"), url(r'^about/$', views.about, name="hc-about"),
url(r'^welcome/timer/$', views.welcome_timer, name="hc-welcome-timer"),
] ]

+ 48
- 2
hc/front/views.py View File

@ -1,5 +1,8 @@
import json
from django.contrib.auth.decorators import login_required 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.shortcuts import redirect, render
from django.utils import timezone from django.utils import timezone
@ -8,7 +11,32 @@ from hc.front.forms import TimeoutForm, TIMEOUT_CHOICES
def index(request): 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): def pricing(request):
@ -23,6 +51,24 @@ def about(request):
return render(request, "about.html", {"page": "about"}) 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 @login_required
def checks(request): def checks(request):


+ 8
- 6
static/css/style.css View File

@ -4,18 +4,20 @@ html, body {
#pitch { #pitch {
text-align: center; text-align: center;
padding: 2em 0 3em 0;
padding: 2em 0 2em 0;
} }
.step-number {
#pitch-subtitle {
text-align: center; 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; margin-top: 4em;
} }


+ 0
- 1
static/js/checks.js View File

@ -34,7 +34,6 @@ $(function () {
}); });
$(".timeout-edit-cancel").click(function() { $(".timeout-edit-cancel").click(function() {
console.log("aaa");
$(this).parents("td").addClass("inactive"); $(this).parents("td").addClass("inactive");
return false; return false;
}); });


+ 45
- 0
static/js/index.js View File

@ -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);
});

+ 10
- 3
templates/about.html View File

@ -9,15 +9,22 @@
Hello, my name is Pēteris Caune, I live in Riga, Latvia and do programming for living. Hello, my name is Pēteris Caune, I live in Riga, Latvia and do programming for living.
You can contact me <a href="mailto:[email protected]">via email</a>. You can contact me <a href="mailto:[email protected]">via email</a>.
</p> </p>
<p>
Code is on
<a href="https://github.com/healthchecks/healthchecks">GitHub</a>.
</p>
<h3>Reliability Guarantees</h3> <h3>Reliability Guarantees</h3>
<p> <p>
Health Checks is currently at a very early stage as you can probably tell. Health Checks is currently at a very early stage as you can probably tell.
</p> </p>
<p> <p>
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. <!-- User data should be safe however,
as we are doing regular database backups to Amazon S3. -->
</p> </p>
<p> <p>
If all this does not sound very inspiring, If all this does not sound very inspiring,
there are also alternative services: there are also alternative services:


+ 1
- 1
templates/base.html View File

@ -57,6 +57,6 @@
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script> <script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script> <script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/checks.js' %}"></script>
{% block scripts %}{% endblock %}
</body> </body>
</html> </html>

+ 7
- 3
templates/front/index.html View File

@ -1,5 +1,5 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load humanize %}
{% load humanize staticfiles %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
@ -47,7 +47,7 @@
</form> </form>
</td> </td>
<td class="url-cell"> <td class="url-cell">
<code>https://healthchecks.io{% url 'hc-ping' check.code %}</code>
<code>http://healthchecks.io{% url 'hc-ping' check.code %}</code>
</td> </td>
<td class="timeout-cell inactive"> <td class="timeout-cell inactive">
<div class="timeout-dialog popover bottom"> <div class="timeout-dialog popover bottom">
@ -116,4 +116,8 @@
{% endblock %}
{% endblock %}
{% block scripts %}
<script src="{% static 'js/checks.js' %}"></script>
{% endblock %}

+ 5
- 0
templates/front/snippets/bash.txt View File

@ -0,0 +1,5 @@
# using curl:
curl {{ ping_url }}
# using wget:
wget {{ ping_url }} -O /dev/null

+ 3
- 0
templates/front/snippets/browser.txt View File

@ -0,0 +1,3 @@
var xhr = new XMLHttpRequest();
xhr.open('GET', '{{ ping_url }}', true);
xhr.send(null);

+ 2
- 0
templates/front/snippets/crontab.txt View File

@ -0,0 +1,2 @@
# m h dom mon dow command
8 6 * * * /home/user/tasks/backup_all.sh && curl {{ ping_url }}

+ 7
- 0
templates/front/snippets/python.txt View File

@ -0,0 +1,7 @@
>>> # using urllib2:
>>> import urllib2
>>> urllib2.urlopen("{{ ping_url }}")
>>> # using requests:
>>> import requests
>>> requests.get("{{ ping_url }}")

+ 75
- 29
templates/index.html View File

@ -1,5 +1,5 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load staticfiles %}
{% load humanize staticfiles %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
@ -9,47 +9,89 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-4">
<p class="step-number">1</p>
<p>
Create a ping URL on healtchecks.io
</p>
</div>
<div class="col-sm-4">
<p class="step-number">2</p>
Add a single line at the bottom of your batch processing task:
<div class="col-sm-12">
<h2 id="pitch-subtitle">Here's an unique ping address for you:</h2>
<div id="pitch-url">{{ ping_url }}</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<ul class="nav nav-tabs" role="tablist"> <ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#bash" aria-controls="home" role="tab" data-toggle="tab">Bash</a>
<li class="active">
<a href="#crontab" data-toggle="tab">Crontab</a>
</li>
<li>
<a href="#bash" data-toggle="tab">Bash</a>
</li>
<li>
<a href="#python" data-toggle="tab">Python</a>
</li>
<li>
<a href="#node" data-toggle="tab">Node.js</a>
</li> </li>
<li role="presentation">
<a href="#python" aria-controls="profile" role="tab" data-toggle="tab">Python</a>
<li>
<a href="#php" data-toggle="tab">PHP</a>
</li>
<li>
<a href="#browser" data-toggle="tab">Browser</a>
</li> </li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="bash">
<pre>wget https://healthchecks.io/ping/b2012751-c542-4deb-b054-ff51322102b9/ -O /dev/null
</pre>
<div role="tabpanel" class="tab-pane active" id="crontab">
<pre>{% include "front/snippets/crontab.txt" %}</pre>
</div>
<div role="tabpanel" class="tab-pane" id="bash">
<pre>{% include "front/snippets/bash.txt" %}</pre>
</div> </div>
<div role="tabpanel" class="tab-pane" id="python"> <div role="tabpanel" class="tab-pane" id="python">
<pre>
>>> import urllib2
>>> urllib2.urlopen("https://healthchecks.io/ping/b2012751-c542-4deb-b054-ff51322102b9/")
</pre>
<pre>{% include "front/snippets/python.txt" %}</pre>
</div>
<div class="tab-pane" id="browser">
<pre>{% include "front/snippets/browser.txt" %}</pre>
<div class="welcome-browser-controls">
<button id="run-it" class="btn btn-default">Run It!</button>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-4">
<p class="step-number">3</p>
Receive an email from healthchecks.io when the task has an issue
</div>
<div id="get-started" class="col-sm-6 col-sm-offset-3">
<h3>E-mail Address to Receive Notifications:</h3>
<div id="welcome-status" class="col-sm-6">
<h2>Status
<small>{{ check.code }}</small>
</h2>
<table class="table">
<tr>
<th>Last ping</th>
<th>Frequency</th>
<th>Alert in</th>
</tr>
<tr>
<td id="last-ping">
{% if check.last_ping %}
{{ check.last_ping|naturaltime }}
{% else %}
Never
{% endif %}
</td>
<td>1 day
<span
class="glyphicon glyphicon-question-sign"
data-toggle="tooltip"
title="Sign in to change frequency"></span>
</td>
<td id="timer" data-timer="{{ timer}}">
{{ timer_formatted }}
</td>
</tr>
</table>
</div>
<div id="get-started" class="col-sm-6">
<h3>E-mail Address to Receive Alerts:</h3>
<form action="{% url 'hc-login' %}" method="post"> <form action="{% url 'hc-login' %}" method="post">
{% csrf_token %} {% csrf_token %}
@ -75,4 +117,8 @@
</div> </div>
</div> </div>
{% endblock %}
{% endblock %}
{% block scripts %}
<script src="{% static 'js/index.js' %}"></script>
{% endblock %}

Loading…
Cancel
Save