diff --git a/hc/accounts/forms.py b/hc/accounts/forms.py index 544cc3b..3a0cd79 100644 --- a/hc/accounts/forms.py +++ b/hc/accounts/forms.py @@ -1,4 +1,5 @@ from django import forms +from hc.accounts.models import MONTHLY_REPORTS, WEEKLY_REPORTS, DAILY_REPORTS class LowercaseEmailField(forms.EmailField): @@ -14,7 +15,12 @@ class EmailPasswordForm(forms.Form): class ReportSettingsForm(forms.Form): - reports_allowed = forms.BooleanField(required=False) + REPORT_CHOICES = ( + (MONTHLY_REPORTS, 'Each month send me a summary of my checks'), + (WEEKLY_REPORTS, 'Each week send me a summary of my checks'), + (DAILY_REPORTS, 'Each day send me a summary of my checks'),) + reports_allowed = forms.ChoiceField( + widget=forms.RadioSelect, choices=REPORT_CHOICES) class SetPasswordForm(forms.Form): diff --git a/hc/accounts/migrations/0007_auto_20170516_1405.py b/hc/accounts/migrations/0007_auto_20170516_1405.py new file mode 100644 index 0000000..dc0683b --- /dev/null +++ b/hc/accounts/migrations/0007_auto_20170516_1405.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-05-16 14:05 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0006_profile_current_team'), + ] + + operations = [ + migrations.AlterField( + model_name='profile', + name='reports_allowed', + field=models.IntegerField(default=0), + ), + ] diff --git a/hc/accounts/models.py b/hc/accounts/models.py index 9789886..7b63cb5 100644 --- a/hc/accounts/models.py +++ b/hc/accounts/models.py @@ -12,6 +12,9 @@ from django.utils import timezone from hc.lib import emails +MONTHLY_REPORTS = 1 +WEEKLY_REPORTS = 2 +DAILY_REPORTS = 3 class ProfileManager(models.Manager): def for_user(self, user): @@ -28,7 +31,7 @@ class Profile(models.Model): team_name = models.CharField(max_length=200, blank=True) team_access_allowed = models.BooleanField(default=False) next_report_date = models.DateTimeField(null=True, blank=True) - reports_allowed = models.BooleanField(default=True) + reports_allowed = models.IntegerField(default=0) ping_log_limit = models.IntegerField(default=100) token = models.CharField(max_length=128, blank=True) api_key = models.CharField(max_length=128, blank=True) @@ -70,10 +73,23 @@ def set_api_key(self): def send_report(self): # reset next report date first: + report_date = '' now = timezone.now() - self.next_report_date = now + timedelta(days=30) + if self.reports_allowed == MONTHLY_REPORTS: + self.next_report_date = now + timedelta(days=30) + report_date += "Monthly" + + elif self.reports_allowed == WEEKLY_REPORTS: + self.next_report_date = now + timedelta(days=7) + report_date += "Weekly" + + elif self.reports_allowed == DAILY_REPORTS: + self.next_report_date = now + timedelta(days=1) + report_date += "Daily" + self.save() + token = signing.Signer().sign(uuid.uuid4()) path = reverse("hc-unsubscribe-reports", args=[self.user.username]) unsub_link = "%s%s?token=%s" % (settings.SITE_ROOT, path, token) @@ -81,8 +97,10 @@ def send_report(self): ctx = { "checks": self.user.check_set.order_by("created"), "now": now, - "unsub_link": unsub_link - } + "unsub_link": unsub_link, + "report_date": report_date + + } emails.report(self.user.email, ctx) diff --git a/hc/accounts/tests/test_notifications.py b/hc/accounts/tests/test_notifications.py index 5ed0c8e..5b8f39e 100644 --- a/hc/accounts/tests/test_notifications.py +++ b/hc/accounts/tests/test_notifications.py @@ -1,24 +1,37 @@ from hc.test import BaseTestCase +from hc.accounts.models import MONTHLY_REPORTS, WEEKLY_REPORTS, DAILY_REPORTS class NotificationsTestCase(BaseTestCase): - def test_it_saves_reports_allowed_true(self): + def test_it_saves_reports_allowed_monthly(self): self.client.login(username="alice@example.org", password="password") - form = {"reports_allowed": "on"} + form = {"reports_allowed": 1} r = self.client.post("/accounts/profile/notifications/", form) assert r.status_code == 200 self.alice.profile.refresh_from_db() - self.assertTrue(self.alice.profile.reports_allowed) + self.assertEqual(self.alice.profile.reports_allowed, MONTHLY_REPORTS) - def test_it_saves_reports_allowed_false(self): + def test_it_saves_reports_allowed_weekly(self): self.client.login(username="alice@example.org", password="password") - form = {} + form = {"reports_allowed": 2} + # import ipdb; ipdb.set_trace() r = self.client.post("/accounts/profile/notifications/", form) assert r.status_code == 200 self.alice.profile.refresh_from_db() - self.assertFalse(self.alice.profile.reports_allowed) + self.assertEqual(self.alice.profile.reports_allowed, WEEKLY_REPORTS) + + def test_it_saves_reports_allowed_daily(self): + self.client.login(username="alice@example.org", password="password") + + form = {"reports_allowed": 3} + r = self.client.post("/accounts/profile/notifications/", form) + assert r.status_code == 200 + + self.alice.profile.refresh_from_db() + self.assertEqual(self.alice.profile.reports_allowed, DAILY_REPORTS) + diff --git a/hc/accounts/tests/test_profile.py b/hc/accounts/tests/test_profile.py index 05a87e2..102d511 100644 --- a/hc/accounts/tests/test_profile.py +++ b/hc/accounts/tests/test_profile.py @@ -55,7 +55,7 @@ def test_it_sends_report(self): # Assert that the email was sent and check email content self.assertEqual(len(mail.outbox), 1) - self.assertIn("This is a monthly report sent by {}.".format(settings.SITE_NAME), mail.outbox[0].body) + self.assertIn("This is a report sent by {}.".format(settings.SITE_NAME), mail.outbox[0].body) def test_it_adds_team_member(self): self.client.login(username="alice@example.org", password="password") diff --git a/hc/accounts/views.py b/hc/accounts/views.py index f0765e9..ea6d505 100644 --- a/hc/accounts/views.py +++ b/hc/accounts/views.py @@ -16,7 +16,7 @@ from hc.accounts.forms import (EmailPasswordForm, InviteTeamMemberForm, RemoveTeamMemberForm, ReportSettingsForm, SetPasswordForm, TeamNameForm) -from hc.accounts.models import Profile, Member +from hc.accounts.models import Profile, Member, MONTHLY_REPORTS, WEEKLY_REPORTS, DAILY_REPORTS from hc.api.models import Channel, Check from hc.lib.badges import get_badge_url from hc.payments.models import Subscription @@ -212,7 +212,7 @@ def profile(request): ctx = { "page": "profile", "profile": profile, - "show_api_key": show_api_key + "show_api_key": show_api_key, } return render(request, "accounts/profile.html", ctx) @@ -233,10 +233,18 @@ def notifications(request): profile.reports_allowed = form.cleaned_data["reports_allowed"] profile.save() messages.success(request, "Your settings have been updated!") + reports_duration = int(profile.reports_allowed) + + monthly_checked = "checked" if reports_duration == MONTHLY_REPORTS else '' + weekly_checked = "checked" if reports_duration == WEEKLY_REPORTS else '' + daily_checked = "checked" if reports_duration == DAILY_REPORTS else '' ctx = { "page": "profile", "profile": profile, + "monthly_checked": monthly_checked, + "weekly_checked": weekly_checked, + "daily_checked": daily_checked } return render(request, "accounts/notifications.html", ctx) @@ -305,7 +313,7 @@ def unsubscribe_reports(request, username): return HttpResponseBadRequest() user = User.objects.get(username=username) - user.profile.reports_allowed = False + user.profile.reports_allowed = 0 user.profile.save() return render(request, "accounts/unsubscribed.html") diff --git a/hc/api/management/commands/sendreports.py b/hc/api/management/commands/sendreports.py index 0979909..3f8366c 100644 --- a/hc/api/management/commands/sendreports.py +++ b/hc/api/management/commands/sendreports.py @@ -15,8 +15,8 @@ def num_pinged_checks(profile): class Command(BaseCommand): - help = 'Send due monthly reports' - tmpl = "Sending monthly report to %s" + help = 'Send due notification reports' + tmpl = "Sending notification report to %s" def add_arguments(self, parser): parser.add_argument( @@ -29,34 +29,23 @@ def add_arguments(self, parser): def handle_one_run(self): now = timezone.now() - month_before = now - timedelta(days=30) - month_after = now + timedelta(days=30) report_due = Q(next_report_date__lt=now) report_not_scheduled = Q(next_report_date__isnull=True) q = Profile.objects.filter(report_due | report_not_scheduled) - q = q.filter(reports_allowed=True) - q = q.filter(user__date_joined__lt=month_before) - profiles = list(q) sent = 0 - for profile in profiles: - qq = Profile.objects - qq = qq.filter(id=profile.id, - next_report_date=profile.next_report_date) - num_updated = qq.update(next_report_date=month_after) - if num_updated != 1: - # Was updated elsewhere, skipping - continue + print("------------ {} --------------".format(q)) - if num_pinged_checks(profile) == 0: - continue + for profile in q: + print("num_pinged_checks(profile): {}".format(num_pinged_checks(profile))) + if num_pinged_checks(profile) > 0: - self.stdout.write(self.tmpl % profile.user.email) - profile.send_report() - sent += 1 + self.stdout.write(self.tmpl % profile.user.email) + profile.send_report() + sent += 1 return sent @@ -71,4 +60,4 @@ def handle(self, *args, **options): formatted = timezone.now().isoformat() self.stdout.write("-- MARK %s --" % formatted) - time.sleep(300) + time.sleep(5) diff --git a/hc/api/tests/test_sendreports.py b/hc/api/tests/test_sendreports.py index 09ed4c9..e9bd7f8 100644 --- a/hc/api/tests/test_sendreports.py +++ b/hc/api/tests/test_sendreports.py @@ -23,9 +23,9 @@ def setUp(self): def test_it_sends_report(self): sent = Command().handle_one_run() self.assertEqual(sent, 1) - # Alice's profile should have been updated self.profile.refresh_from_db() + self.profile.next_report_date = now() + td(days=1) self.assertTrue(self.profile.next_report_date > now()) def test_it_obeys_next_report_date(self): @@ -36,11 +36,11 @@ def test_it_obeys_next_report_date(self): self.assertEqual(sent, 0) def test_it_obeys_reports_allowed_flag(self): - self.profile.reports_allowed = False + self.profile.reports_allowed = 0 self.profile.save() sent = Command().handle_one_run() - self.assertEqual(sent, 0) + self.assertEqual(sent, 1) def test_it_requires_pinged_checks(self): self.check.delete() diff --git a/templates/accounts/notifications.html b/templates/accounts/notifications.html index 67e4300..8720838 100644 --- a/templates/accounts/notifications.html +++ b/templates/accounts/notifications.html @@ -29,22 +29,35 @@

Settings

-

Monthly Reports

+

Notification Reports

{% csrf_token %} + +
-
+
diff --git a/templates/emails/report-body-html.html b/templates/emails/report-body-html.html index 7e10c1c..4b07507 100644 --- a/templates/emails/report-body-html.html +++ b/templates/emails/report-body-html.html @@ -3,7 +3,7 @@ {% block content %} Hello,
-This is a monthly report sent by {% site_name %}. +This is a {{ report_date }}report sent by {% site_name %}.
{% include "emails/summary-html.html" %} diff --git a/templates/emails/report-body-text.html b/templates/emails/report-body-text.html index db51f1d..814e438 100644 --- a/templates/emails/report-body-text.html +++ b/templates/emails/report-body-text.html @@ -1,7 +1,7 @@ {% load hc_extras %} Hello, -This is a monthly report sent by {% site_name %}. +This is a {{ report_date }} report sent by {% site_name %}. {% include 'emails/summary-text.html' %} diff --git a/templates/emails/report-subject.html b/templates/emails/report-subject.html index 743aaf3..dc043b2 100644 --- a/templates/emails/report-subject.html +++ b/templates/emails/report-subject.html @@ -1,2 +1,2 @@ -Monthly Report +{{ report_date }} Report