Browse Source

Set Pushover alert priorities for "down" and "up" events separately. Fixes #204

pull/211/head
Pēteris Caune 6 years ago
parent
commit
fb45b67892
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
10 changed files with 122 additions and 71 deletions
  1. +4
    -0
      CHANGELOG.md
  2. +4
    -4
      hc/api/models.py
  3. +15
    -0
      hc/api/tests/test_notify.py
  4. +7
    -1
      hc/api/transports.py
  5. +13
    -2
      hc/front/tests/test_add_pushover.py
  6. +6
    -1
      hc/front/views.py
  7. +1
    -6
      static/css/add_pushover.css
  8. BIN
      static/img/integrations/setup_pushover_1.png
  9. +1
    -1
      templates/front/channels.html
  10. +71
    -56
      templates/integrations/add_pushover.html

+ 4
- 0
CHANGELOG.md View File

@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
## Unreleased ## Unreleased
### Improvements
- Set Pushover alert priorities for "down" and "up" events separately
### Bug Fixes ### Bug Fixes
- Fix after-login redirects for users landing in the "Add Slack" page - Fix after-login redirects for users landing in the "Add Slack" page


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

@ -339,11 +339,11 @@ class Channel(models.Model):
return 'img/integrations/%s.png' % self.kind return 'img/integrations/%s.png' % self.kind
@property @property
def po_value(self):
def po_priority(self):
assert self.kind == "po" assert self.kind == "po"
user_key, prio = self.value.split("|")
prio = int(prio)
return user_key, prio, PO_PRIORITIES[prio]
parts = self.value.split("|")
prio = int(parts[1])
return PO_PRIORITIES[prio]
@property @property
def url_down(self): def url_down(self):


+ 15
- 0
hc/api/tests/test_notify.py View File

@ -405,6 +405,21 @@ class NotifyTestCase(BaseTestCase):
payload = kwargs["data"] payload = kwargs["data"]
self.assertIn("DOWN", payload["title"]) self.assertIn("DOWN", payload["title"])
@patch("hc.api.transports.requests.request")
def test_pushover_up_priority(self, mock_post):
self._setup_data("po", "123|0|2", status="up")
mock_post.return_value.status_code = 200
self.channel.notify(self.check)
assert Notification.objects.count() == 1
args, kwargs = mock_post.call_args
payload = kwargs["data"]
self.assertIn("UP", payload["title"])
self.assertEqual(payload["priority"], 2)
self.assertIn("retry", payload)
self.assertIn("expire", payload)
@patch("hc.api.transports.requests.request") @patch("hc.api.transports.requests.request")
def test_victorops(self, mock_post): def test_victorops(self, mock_post):
self._setup_data("victorops", "123") self._setup_data("victorops", "123")


+ 7
- 1
hc/api/transports.py View File

@ -304,7 +304,13 @@ class Pushover(HttpTransport):
} }
text = tmpl("pushover_message.html", **ctx) text = tmpl("pushover_message.html", **ctx)
title = tmpl("pushover_title.html", **ctx) title = tmpl("pushover_title.html", **ctx)
user_key, prio = self.channel.value.split("|")
pieces = self.channel.value.split("|")
user_key, prio = pieces[0], pieces[1]
# The third element, if present, is the priority for "up" events
if len(pieces) == 3 and check.status == "up":
prio = pieces[2]
payload = { payload = {
"token": settings.PUSHOVER_API_TOKEN, "token": settings.PUSHOVER_API_TOKEN,
"user": user_key, "user": user_key,


+ 13
- 2
hc/front/tests/test_add_pushover.py View File

@ -39,13 +39,13 @@ class AddPushoverTestCase(BaseTestCase):
session["pushover"] = "foo" session["pushover"] = "foo"
session.save() session.save()
params = "pushover_user_key=a&state=foo&prio=0"
params = "pushover_user_key=a&state=foo&prio=0&prio_up=-1"
r = self.client.get("/integrations/add_pushover/?%s" % params) r = self.client.get("/integrations/add_pushover/?%s" % params)
self.assertEqual(r.status_code, 302) self.assertEqual(r.status_code, 302)
channels = list(Channel.objects.all()) channels = list(Channel.objects.all())
assert len(channels) == 1 assert len(channels) == 1
assert channels[0].value == "a|0"
assert channels[0].value == "a|0|-1"
def test_it_validates_priority(self): def test_it_validates_priority(self):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
@ -58,6 +58,17 @@ class AddPushoverTestCase(BaseTestCase):
r = self.client.get("/integrations/add_pushover/?%s" % params) r = self.client.get("/integrations/add_pushover/?%s" % params)
self.assertEqual(r.status_code, 400) self.assertEqual(r.status_code, 400)
def test_it_validates_priority_up(self):
self.client.login(username="[email protected]", password="password")
session = self.client.session
session["pushover"] = "foo"
session.save()
params = "pushover_user_key=a&state=foo&prio_up=abc"
r = self.client.get("/integrations/add_pushover/?%s" % params)
self.assertEqual(r.status_code, 400)
def test_it_validates_state(self): def test_it_validates_state(self):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")


+ 6
- 1
hc/front/views.py View File

@ -873,6 +873,7 @@ def add_pushover(request):
success_url = settings.SITE_ROOT + reverse("hc-add-pushover") + "?" + urlencode({ success_url = settings.SITE_ROOT + reverse("hc-add-pushover") + "?" + urlencode({
"state": state, "state": state,
"prio": request.POST.get("po_priority", "0"), "prio": request.POST.get("po_priority", "0"),
"prio_up": request.POST.get("po_priority_up", "0")
}) })
subscription_url = settings.PUSHOVER_SUBSCRIPTION_URL + "?" + urlencode({ subscription_url = settings.PUSHOVER_SUBSCRIPTION_URL + "?" + urlencode({
"success": success_url, "success": success_url,
@ -892,6 +893,10 @@ def add_pushover(request):
if prio not in ("-2", "-1", "0", "1", "2"): if prio not in ("-2", "-1", "0", "1", "2"):
return HttpResponseBadRequest() return HttpResponseBadRequest()
prio_up = request.GET.get("prio_up")
if prio_up not in ("-2", "-1", "0", "1", "2"):
return HttpResponseBadRequest()
if request.GET.get("pushover_unsubscribed") == "1": if request.GET.get("pushover_unsubscribed") == "1":
# Unsubscription: delete all Pushover channels for this user # Unsubscription: delete all Pushover channels for this user
Channel.objects.filter(user=request.user, kind="po").delete() Channel.objects.filter(user=request.user, kind="po").delete()
@ -899,7 +904,7 @@ def add_pushover(request):
# Subscription # Subscription
channel = Channel(user=request.team.user, kind="po") channel = Channel(user=request.team.user, kind="po")
channel.value = "%s|%s" % (key, prio)
channel.value = "%s|%s|%s" % (key, prio, prio_up)
channel.save() channel.save()
channel.assign_all_checks() channel.assign_all_checks()


+ 1
- 6
static/css/add_pushover.css View File

@ -1,8 +1,3 @@
#add-pushover .radio {
margin-bottom: 1em;
}
#add-pushover .help { #add-pushover .help {
display: block;
color: #888;
opacity: 0.6;
} }

BIN
static/img/integrations/setup_pushover_1.png View File

Before After
Width: 500  |  Height: 295  |  Size: 12 KiB Width: 500  |  Height: 149  |  Size: 20 KiB

+ 1
- 1
templates/front/channels.html View File

@ -54,7 +54,7 @@
{% elif ch.kind == "victorops" %} {% elif ch.kind == "victorops" %}
VictorOps VictorOps
{% elif ch.kind == "po" %} {% elif ch.kind == "po" %}
Pushover ({{ ch.po_value|last }} priority)
Pushover ({{ ch.po_priority }} priority)
{% elif ch.kind == "slack" %} {% elif ch.kind == "slack" %}
Slack Slack
{% if ch.slack_team %} {% if ch.slack_team %}


+ 71
- 56
templates/integrations/add_pushover.html View File

@ -1,5 +1,5 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load humanize static hc_extras %}
{% load compress humanize static hc_extras %}
{% block title %}Add Pushover - {% site_name %}{% endblock %} {% block title %}Add Pushover - {% site_name %}{% endblock %}
@ -56,7 +56,7 @@
<p> <p>
After logging in, go to "Integrations &rarr; Add Pushover". After logging in, go to "Integrations &rarr; Add Pushover".
Pushover supports different notification priorities from Pushover supports different notification priorities from
silent to "Emergency". Select your preferred priority
silent to "Emergency". Select your preferred priorities
and click "Subscribe with Pushover". and click "Subscribe with Pushover".
</p> </p>
</div> </div>
@ -106,65 +106,72 @@
{% else %} {% else %}
<h2>Integration Settings</h2> <h2>Integration Settings</h2>
<form method="post" id="add-pushover" class="form-horizontal" action="{% url 'hc-add-pushover' %}">
<form id="add-pushover" method="post" class="form-horizontal" action="{% url 'hc-add-pushover' %}">
{% csrf_token %} {% csrf_token %}
<div class="form-group"> <div class="form-group">
<label class="col-sm-2 control-label">Notification priority</label>
<div class="col-sm-6">
<div class="radio">
<label>
<input type="radio" name="po_priority" value="-2">
Lowest Priority.
<span class="help">
Generates no notification/alert on your device.
On iOS, the application badge number will be increased.
</span>
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="po_priority" value="-1">
Low Priority.
<span class="help">
Sends a quiet notification.
</span>
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="po_priority" value="0" checked>
Normal Priority.
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="po_priority" value="1">
<span class="text-warning">High Priority.</span>
<span class="help">
Bypasses user's quiet hours.
</span>
</label>
</div>
<label class="col-sm-3 control-label">Priority for "down" events</label>
<div class="col-sm-8">
<select name="po_priority" class="selectpicker form-control">
<option
value="-2"
data-content="Lowest Priority. <span class='help'>Generates no notification on your device.</span>">
Lowest Priority
</option>
<option
value="-1"
data-content="Low Priority. <span class='help'>Sends a quiet notification.</span>">
Low Priority
</option>
<option value="0" selected="selected">
Normal Priority
</option>
<option
value="1"
data-content="High Priority. <span class='help'>Bypasses user's quiet hours.</span>">
High Priority
</option>
<option
value="2"
data-content="Emergency Priority. <span class='help'>Repeated every {{po_retry_delay|hc_duration }} for at most {{ po_expiration|hc_duration }} until you acknowledge them.</span>">
Emergency Priority
</option>
</select>
</div>
</div>
<div class="radio">
<label>
<input type="radio" name="po_priority" value="2">
<span class="text-danger">Emergency Priority.</span>
<span class="help">
The notification is repeated every
{{po_retry_delay|hc_duration }} for at most
{{ po_expiration|hc_duration }} until you
acknowledge them.
</span>
</label>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Priority for "up" events</label>
<div class="col-sm-8">
<select name="po_priority_up" class="selectpicker form-control">
<option
value="-2"
data-content="Lowest Priority. <span class='help'>Generates no notification on your device.</span>">
Lowest Priority
</option>
<option
value="-1"
data-content="Low Priority. <span class='help'>Sends a quiet notification.</span>">
Low Priority
</option>
<option value="0" selected="selected">
Normal Priority
</option>
<option
value="1"
data-content="High Priority. <span class='help'>Bypasses user's quiet hours.</span>">
High Priority
</option>
<option
value="2"
data-content="Emergency Priority. <span class='help'>Repeated every {{po_retry_delay|hc_duration }} for at most {{ po_expiration|hc_duration }} until you acknowledge them.</span>">
Emergency Priority
</option>
</select>
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="col-sm-offset-3 col-sm-8">
<button type="submit" class="btn btn-default"> <button type="submit" class="btn btn-default">
<img class="ai-icon" src="{% static 'img/integrations/po.png' %}" alt="Pushover" /> <img class="ai-icon" src="{% static 'img/integrations/po.png' %}" alt="Pushover" />
Subscribe with Pushover Subscribe with Pushover
@ -176,3 +183,11 @@
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block scripts %}
{% compress js %}
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/bootstrap-select.min.js' %}"></script>
{% endcompress %}
{% endblock %}

Loading…
Cancel
Save