Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:andela/hc-june-bunnies into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
karanjaE committed Jul 13, 2018
2 parents 45d38a0 + 45ffb01 commit b706e85
Show file tree
Hide file tree
Showing 17 changed files with 301 additions and 14 deletions.
10 changes: 8 additions & 2 deletions hc/api/management/commands/sendalerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ def handle_many(self):
now = timezone.now()
going_down = query.filter(alert_after__lt=now, status="up")
going_up = query.filter(alert_after__gt=now, status="down")
nag = query.filter(nag_after__lt=now, nag_status=True, status="down")
# Don't combine this in one query so Postgres can query using index:
checks = list(going_down.iterator()) + list(going_up.iterator())
checks = list(going_down.iterator()) + list(going_up.iterator()) + list(nag.iterator())
if not checks:
return False

Expand All @@ -40,9 +41,14 @@ def handle_one(self, check):
"""

# Save the new status. If sendalerts crashes,
# Saves the new status. If sendalerts crashes,
# it won't process this check again.
check.status = check.get_status()
now = timezone.now()
# Set the next nag time
if check.nag() == "nag":
interval = check.new_nag_after
check.nag_after = now + interval
check.save()

tmpl = "\nSending alert, status=%s, code=%s\n"
Expand Down
30 changes: 30 additions & 0 deletions hc/api/migrations/0027_auto_20180712_0652.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2018-07-12 06:52
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0026_auto_20160415_1824'),
]

operations = [
migrations.AddField(
model_name='check',
name='nag_after',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name='check',
name='nag_status',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='check',
name='status',
field=models.CharField(choices=[('up', 'Up'), ('down', 'Down'), ('new', 'New'), ('paused', 'Paused'), ('nag', 'Nag')], default='new', max_length=6),
),
]
21 changes: 21 additions & 0 deletions hc/api/migrations/0028_check_new_nag_after.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2018-07-12 12:21
from __future__ import unicode_literals

import datetime
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0027_auto_20180712_0652'),
]

operations = [
migrations.AddField(
model_name='check',
name='new_nag_after',
field=models.DurationField(default=datetime.timedelta(1, 3600)),
),
]
16 changes: 16 additions & 0 deletions hc/api/migrations/0031_merge_20180713_0904.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2018-07-13 09:04
from __future__ import unicode_literals

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('api', '0028_check_new_nag_after'),
('api', '0030_remove_check_profile'),
]

operations = [
]
11 changes: 10 additions & 1 deletion hc/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
("up", "Up"),
("down", "Down"),
("new", "New"),
("paused", "Paused")
("paused", "Paused"),
("nag", "Nag")
)
DEFAULT_TIMEOUT = td(days=1)
DEFAULT_GRACE = td(hours=1)
Expand Down Expand Up @@ -52,6 +53,9 @@ class Meta:
last_ping = models.DateTimeField(null=True, blank=True)
alert_after = models.DateTimeField(null=True, blank=True, editable=False)
status = models.CharField(max_length=6, choices=STATUSES, default="new")
nag_after = models.DateTimeField(null=True, blank=True)
nag_status = models.BooleanField(default=False)
new_nag_after = models.DurationField(default=DEFAULT_GRACE+DEFAULT_TIMEOUT)

def name_then_code(self):
if self.name:
Expand Down Expand Up @@ -130,6 +134,11 @@ def to_dict(self):

return result

def nag(self):
"""Sends a nag to the client if the service is still down"""
if self.get_status() == 'down' and self.nag_status:
return "nag"


class Ping(models.Model):
n = models.IntegerField(null=True)
Expand Down
22 changes: 22 additions & 0 deletions hc/api/tests/test_prunechecks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from datetime import timedelta

from django.utils import timezone
from hc.api.management.commands.prunechecks import Command
from hc.api.models import Check
from hc.test import BaseTestCase
from mock import patch


class PruneChecksTestCase(BaseTestCase):

@patch("hc.api.management.commands.sendalerts.Command.handle_one")
def test_it_reaches_prunes(self, mock):
check = Check(user=None)
check.created = timezone.now() - timedelta(days=1, minutes=30)
check.save()

# Expect no exceptions--

result = Command().handle(check)
self.assertEqual(result, "Done! Pruned 0 checks.")

6 changes: 4 additions & 2 deletions hc/api/tests/test_sendalerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def test_it_handles_grace_period(self):
result = Command().handle_one(check)
self.assertEqual(True, result, "handle_one should return True")


@patch("hc.api.management.commands.sendalerts.Command.handle_one")
def test_handle_many_true(self, mock):
"""Assert when Command's handle many that when handle_many should return True"""
Expand All @@ -51,9 +52,10 @@ def test_handle_many_true(self, mock):
check = Check(user=self.bob, name=name)
check.alert_after = time
check.status = "up"
check.nag_status=True
check.save()
result = Command().handle_many()
self.assertEqual(result, True, "handle_many should return True")



12 changes: 8 additions & 4 deletions hc/front/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ def clean_tags(self):


class TimeoutForm(forms.Form):
"""Increase timeout and grace maximum value from 30days to 6 months in value of seconds"""
timeout = forms.IntegerField(min_value=60, max_value=15552000)
grace = forms.IntegerField(min_value=60, max_value=15552000)

timeout = forms.IntegerField(min_value=60, max_value=2592000)
grace = forms.IntegerField(min_value=60, max_value=2592000)
new_nag_after = forms.IntegerField(min_value=60, max_value=2592000)

class AddChannelForm(forms.ModelForm):

Expand All @@ -42,3 +41,8 @@ class AddWebhookForm(forms.Form):

def get_value(self):
return "{value_down}\n{value_up}".format(**self.cleaned_data)


class NagUserForm(forms.Form):
"""Form for nagging the user"""
nag = forms.BooleanField(required=False)
5 changes: 3 additions & 2 deletions hc/front/tests/test_update_timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def setUp(self):

def test_it_works(self):
url = "/checks/%s/timeout/" % self.check.code
payload = {"timeout": 3600, "grace": 60}
payload = {"timeout": 3600, "grace": 60, "new_nag_after": 60}

self.client.login(username="alice@example.org", password="password")
r = self.client.post(url, data=payload)
Expand All @@ -20,10 +20,11 @@ def test_it_works(self):
check = Check.objects.get(code=self.check.code)
assert check.timeout.total_seconds() == 3600
assert check.grace.total_seconds() == 60
assert check.new_nag_after.total_seconds() == 60

def test_team_access_works(self):
url = "/checks/%s/timeout/" % self.check.code
payload = {"timeout": 7200, "grace": 60}
payload = {"timeout": 7200, "grace": 60, "new_nag_after": 60}

# Logging in as bob, not alice. Bob has team access so this
# should work.
Expand Down
1 change: 1 addition & 0 deletions hc/front/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
url(r'^pause/$', views.pause, name="hc-pause"),
url(r'^remove/$', views.remove_check, name="hc-remove-check"),
url(r'^log/$', views.log, name="hc-log"),
url(r'^nag_status/$', views.nag_user, name="hc-update-nag"),
]

channel_urls = [
Expand Down
23 changes: 21 additions & 2 deletions hc/front/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
from django.utils.six.moves.urllib.parse import urlencode
from hc.api.decorators import uuid_or_400
from hc.api.models import DEFAULT_GRACE, DEFAULT_TIMEOUT, Channel, Check, Ping
from hc.front.forms import (AddChannelForm, AddWebhookForm, NameTagsForm,
TimeoutForm)
from hc.front.forms import (AddChannelForm, AddWebhookForm, NameTagsForm,TimeoutForm, NagUserForm)
from hc.accounts.models import Member


# from itertools recipes:
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
Expand Down Expand Up @@ -173,6 +173,7 @@ def update_timeout(request, code):
if form.is_valid():
check.timeout = td(seconds=form.cleaned_data["timeout"])
check.grace = td(seconds=form.cleaned_data["grace"])
check.new_nag_after = td(seconds=form.cleaned_data["new_nag_after"])
check.save()

return redirect("hc-checks")
Expand Down Expand Up @@ -575,3 +576,21 @@ def privacy(request):

def terms(request):
return render(request, "front/terms.html", {})


@login_required
@uuid_or_400
def nag_user(request, code):
"""Function for updating the nag option"""
assert request.method == "POST"

check = get_object_or_404(Check, code=code)
if check.user_id != request.team.user.id:
return HttpResponseForbidden()

form = NagUserForm(request.POST)
if form.is_valid():
check.nag_status = form.cleaned_data["nag"]
check.save()

return redirect("hc-checks")
8 changes: 8 additions & 0 deletions static/css/my_checks.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@
#grace-slider.noUi-connect {
background: #f0ad4e;
}
/*Add nag slider*/
#nag-slider {
margin: 20px 50px 110px 50px;
}

#nag-slider.noUi-connect {
background: #f0ad4e;
}

#period-slider .noUi-value, #grace-slider .noUi-value {
width: 60px;
Expand Down
9 changes: 9 additions & 0 deletions static/css/my_checks_desktop.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ table.table tr > th.th-name {
padding: 6px;
display: block;
}
/* Add nag*/
#checks-table .timeout-nag {
border: 1px solid rgba(0, 0, 0, 0);
padding: 6px;
display: block;
}
#checks-table tr:hover .timeout-grace {
border: 1px dotted #AAA;
}

#checks-table tr:hover .timeout-grace {
border: 1px dotted #AAA;
Expand Down
39 changes: 39 additions & 0 deletions static/js/checks.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,34 @@ $(function () {
$("#update-timeout-grace").val(rounded);
});

var nagSlider = document.getElementById("nag-slider");
noUiSlider.create(nagSlider, {
start: [20],
connect: "lower",
range: {
'min': [60, 60],
'33%': [3600, 3600],
'66%': [86400, 86400],
'83%': [604800, 604800],
'max': 2592000,
},
pips: {
mode: 'values',
values: [60, 1800, 3600, 43200, 86400, 604800, 2592000],
density: 4,
format: {
to: secsToText,
from: function() {}
}
}
});

nagSlider.noUiSlider.on("update", function(a, b, value) {
var rounded = Math.round(value);
$("#nag-slider-value").text(secsToText(rounded));
$("#update-timeout-nag").val(rounded);
});


$('[data-toggle="tooltip"]').tooltip();

Expand Down Expand Up @@ -203,5 +231,16 @@ $(function () {
prompt("Press Ctrl+C to select:", text)
});

$(".update-nag").click(function() {
var $this = $(this);

$("#update-nag-form").attr("action", $this.data("url"));
$("#update-nag-input").val($this.data("nag"));
$('#update-nag-modal').modal("show");
$("#update-nag-input").focus();

return false;
});


});
Loading

0 comments on commit b706e85

Please sign in to comment.