Profile.next_nag_date tracks when the next hourly/daily reminder
should be sent. Normally, sendalerts sets this field when
a check goes down, and sendreports clears it out whenever
it is about to send a reminder but realizes all checks are up.
The problem: sendalerts can set next_nag_date to a non-null
value, but it does not clear it out when all checks are up.
This can result in a hourly/daily reminder being sent out
at the wrong time. Specific example, assuming hourly reminders:
13:00: Check A goes down. next_nag_date gets set to 14:00.
13:05: Check A goes up. next_nag_date remains set to 14:00.
13:55: Check B goes down. next_nag_date remains set to 14:00.
14:00: Healthchecks sends a hourly reminder, just 5 minutes
after Check B going down. It should have sent the reminder
at 13:55 + 1 hour = 14:55
The fix: sendalerts can now both set and clear the next_nag_date
field. The main changes are in Project.update_next_nag_dates()
and in Profile.update_next_nag_date(). With the fix:
13:00: Check A goes down. next_nag_date gets set to 14:00.
13:05: Check A goes up. next_nag_date gets set to null.
13:55: Check B goes down. next_nag_date gets set to 14:55.
14:55: Healthchecks sends a hourly reminder.
If the notification does not exist, or is more than a hour
old, return HTTP 200 (instead of 400 or 404) so the other
party doesn't retry over and over again.
Problem: if you use uBlock Origin, and enable the
"Fanboy's Social" filter list, Healthchecks does not show
Telegram or WhatsApp icons. This is because the filter list
contains "##.icon-telegram" and "##.icon-whatsapp" entries.
This commit changes the CSS class prefix to "ic-". So we're
now using icon classes like "ic-telegram" and "ic-whatsapp".
As a bonus, we save 2 bytes in HTML per displayed icon :-)
Previously, I had changed the default value to "", to force
users to set the SECRET_KEY value (the app refuses to start
if SECRET_KEY is empty).
The problem with that is, out of the box, with the default
configuration, the tests also don't run and complain about the
empty SECRET_KEY.
So, a compromise: revert back to the default value "---".
At runtime, if SECRET_KEY has the default value, show a warning
at the top of every page.
To send notifications, sendalerts calls Flip.send_alerts().
I updated Flip.send_alerts() to be a generator, and to yield
a (channel, error, send_time_in_seconds) triple per sent
notification.