removed all the milestone reminder machinery
- Legacy-Id: 10091
This commit is contained in:
parent
f5b6465e81
commit
dbe4e3789d
|
@ -1,46 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# This script will send various milestone reminders. It's supposed to
|
||||
# be run daily, and will then send reminders weekly/monthly as
|
||||
# appropriate.
|
||||
|
||||
import datetime, os
|
||||
import syslog
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ietf.settings")
|
||||
|
||||
syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_LOCAL0)
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
||||
from ietf.group.mails import *
|
||||
|
||||
today = datetime.date.today()
|
||||
|
||||
MONDAY = 1
|
||||
FIRST_DAY_OF_MONTH = 1
|
||||
|
||||
if today.isoweekday() == MONDAY:
|
||||
# send milestone review reminders - ideally we'd keep track of
|
||||
# exactly when we sent one last time for a group, but it's a bit
|
||||
# complicated because people can change the milestones in the mean
|
||||
# time, so dodge all of this by simply sending once a week only
|
||||
for g in groups_with_milestones_needing_review():
|
||||
mail_sent = email_milestone_review_reminder(g, grace_period=7)
|
||||
if mail_sent:
|
||||
syslog.syslog("Sent milestone review reminder for %s %s" % (g.acronym, g.type.name))
|
||||
|
||||
|
||||
early_warning_days = 30
|
||||
|
||||
# send any milestones due reminders
|
||||
for g in groups_needing_milestones_due_reminder(early_warning_days):
|
||||
email_milestones_due(g, early_warning_days)
|
||||
syslog.syslog("Sent milestones due reminder for %s %s" % (g.acronym, g.type.name))
|
||||
|
||||
if today.day == FIRST_DAY_OF_MONTH:
|
||||
# send milestone overdue reminders - once a month
|
||||
for g in groups_needing_milestones_overdue_reminder(grace_period=30):
|
||||
email_milestones_overdue(g)
|
||||
syslog.syslog("Sent milestones overdue reminder for %s %s" % (g.acronym, g.type.name))
|
|
@ -1,6 +1,5 @@
|
|||
# generation of mails
|
||||
|
||||
import datetime
|
||||
import re
|
||||
|
||||
|
||||
|
@ -10,8 +9,6 @@ from django.conf import settings
|
|||
from django.core.urlresolvers import reverse as urlreverse
|
||||
|
||||
from ietf.utils.mail import send_mail, send_mail_text
|
||||
from ietf.group.models import Group
|
||||
from ietf.group.utils import milestone_reviewer_for_group_type
|
||||
from ietf.mailtrigger.utils import gather_address_lists
|
||||
|
||||
def email_admin_re_charter(request, group, subject, text, mailtrigger):
|
||||
|
@ -61,97 +58,3 @@ def email_milestones_changed(request, group, changes):
|
|||
if (addrs.to or addrs.cc) and msg:
|
||||
wrap_up_email(addrs, msg)
|
||||
|
||||
|
||||
def email_milestone_review_reminder(group, grace_period=7):
|
||||
"""Email reminders about milestones needing review to management."""
|
||||
(to, cc) = gather_address_lists('milestone_review_reminder',group=group)
|
||||
|
||||
if not to:
|
||||
return False
|
||||
|
||||
now = datetime.datetime.now()
|
||||
too_early = True
|
||||
|
||||
milestones = group.groupmilestone_set.filter(state="review")
|
||||
for m in milestones:
|
||||
e = m.milestonegroupevent_set.filter(type="changed_milestone").order_by("-time")[:1]
|
||||
m.days_ready = (now - e[0].time).days if e else None
|
||||
|
||||
if m.days_ready == None or m.days_ready >= grace_period:
|
||||
too_early = False
|
||||
|
||||
if too_early:
|
||||
return False
|
||||
|
||||
subject = u"Reminder: Milestone%s needing review in %s %s" % ("s" if len(milestones) > 1 else "", group.acronym, group.type.name)
|
||||
|
||||
send_mail(None, to, None,
|
||||
subject,
|
||||
"group/reminder_milestones_need_review.txt",
|
||||
dict(group=group,
|
||||
milestones=milestones,
|
||||
reviewer=milestone_reviewer_for_group_type(group.type_id),
|
||||
url=settings.IDTRACKER_BASE_URL + urlreverse("group_edit_milestones", kwargs=dict(group_type=group.type_id, acronym=group.acronym)),
|
||||
),
|
||||
cc=cc,
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
def groups_with_milestones_needing_review():
|
||||
return Group.objects.filter(groupmilestone__state="review").distinct()
|
||||
|
||||
def email_milestones_due(group, early_warning_days):
|
||||
(to, cc) = gather_address_lists('milestones_due_soon',group=group)
|
||||
|
||||
today = datetime.date.today()
|
||||
early_warning = today + datetime.timedelta(days=early_warning_days)
|
||||
|
||||
milestones = group.groupmilestone_set.filter(due__in=[today, early_warning],
|
||||
resolved="", state="active")
|
||||
|
||||
subject = u"Reminder: Milestone%s are soon due in %s %s" % ("s" if len(milestones) > 1 else "", group.acronym, group.type.name)
|
||||
|
||||
send_mail(None, to, None,
|
||||
subject,
|
||||
"group/reminder_milestones_due.txt",
|
||||
dict(group=group,
|
||||
milestones=milestones,
|
||||
today=today,
|
||||
early_warning_days=early_warning_days,
|
||||
url=settings.IDTRACKER_BASE_URL + group.about_url(),
|
||||
),
|
||||
cc=cc,
|
||||
)
|
||||
|
||||
def groups_needing_milestones_due_reminder(early_warning_days):
|
||||
"""Return groups having milestones that are either
|
||||
early_warning_days from being due or are due today."""
|
||||
today = datetime.date.today()
|
||||
return Group.objects.filter(state="active", groupmilestone__due__in=[today, today + datetime.timedelta(days=early_warning_days)], groupmilestone__resolved="", groupmilestone__state="active").distinct()
|
||||
|
||||
def email_milestones_overdue(group):
|
||||
(to, cc) = gather_address_lists('milestones_overdue',group=group)
|
||||
|
||||
today = datetime.date.today()
|
||||
|
||||
milestones = group.groupmilestone_set.filter(due__lt=today, resolved="", state="active")
|
||||
for m in milestones:
|
||||
m.months_overdue = (today - m.due).days // 30
|
||||
|
||||
subject = u"Reminder: Milestone%s overdue in %s %s" % ("s" if len(milestones) > 1 else "", group.acronym, group.type.name)
|
||||
|
||||
send_mail(None, to, None,
|
||||
subject,
|
||||
"group/reminder_milestones_overdue.txt",
|
||||
dict(group=group,
|
||||
milestones=milestones,
|
||||
url=settings.IDTRACKER_BASE_URL + group.about_url(),
|
||||
),
|
||||
cc=cc,
|
||||
)
|
||||
|
||||
def groups_needing_milestones_overdue_reminder(grace_period=30):
|
||||
cut_off = datetime.date.today() - datetime.timedelta(days=grace_period)
|
||||
return Group.objects.filter(state="active", groupmilestone__due__lt=cut_off, groupmilestone__resolved="", groupmilestone__state="active").distinct()
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ from django.conf import settings
|
|||
from django.core.urlresolvers import reverse as urlreverse
|
||||
|
||||
from ietf.doc.models import Document, DocAlias, DocEvent, State
|
||||
from ietf.group.models import Group, GroupEvent, GroupMilestone, GroupStateTransitions, MilestoneGroupEvent
|
||||
from ietf.group.models import Group, GroupEvent, GroupMilestone, GroupStateTransitions
|
||||
from ietf.group.utils import save_group_in_history
|
||||
from ietf.name.models import DocTagName, GroupStateName
|
||||
from ietf.person.models import Person, Email
|
||||
|
@ -20,9 +20,6 @@ from ietf.utils.test_utils import TestCase
|
|||
from ietf.utils.mail import outbox, empty_outbox
|
||||
from ietf.utils.test_data import make_test_data
|
||||
from ietf.utils.test_utils import login_testing_unauthorized
|
||||
from ietf.group.mails import ( email_milestone_review_reminder, email_milestones_due,
|
||||
email_milestones_overdue, groups_needing_milestones_due_reminder,
|
||||
groups_needing_milestones_overdue_reminder, groups_with_milestones_needing_review )
|
||||
|
||||
class GroupPagesTests(TestCase):
|
||||
def setUp(self):
|
||||
|
@ -786,137 +783,6 @@ class MilestoneTests(TestCase):
|
|||
|
||||
self.assertEqual(group.charter.docevent_set.count(), events_before + 2) # 1 delete, 1 add
|
||||
|
||||
def test_send_review_needed_reminders(self):
|
||||
make_test_data()
|
||||
|
||||
group = Group.objects.get(acronym="mars")
|
||||
person = Person.objects.get(user__username="marschairman")
|
||||
|
||||
m1 = GroupMilestone.objects.create(group=group,
|
||||
desc="Test 1",
|
||||
due=datetime.date.today(),
|
||||
resolved="",
|
||||
state_id="review")
|
||||
MilestoneGroupEvent.objects.create(
|
||||
group=group, type="changed_milestone",
|
||||
by=person, desc='Added milestone "%s"' % m1.desc, milestone=m1,
|
||||
time=datetime.datetime.now() - datetime.timedelta(seconds=60))
|
||||
|
||||
# send
|
||||
mailbox_before = len(outbox)
|
||||
for g in groups_with_milestones_needing_review():
|
||||
email_milestone_review_reminder(g)
|
||||
|
||||
self.assertEqual(len(outbox), mailbox_before) # too early to send reminder
|
||||
|
||||
|
||||
# add earlier added milestone
|
||||
m2 = GroupMilestone.objects.create(group=group,
|
||||
desc="Test 2",
|
||||
due=datetime.date.today(),
|
||||
resolved="",
|
||||
state_id="review")
|
||||
MilestoneGroupEvent.objects.create(
|
||||
group=group, type="changed_milestone",
|
||||
by=person, desc='Added milestone "%s"' % m2.desc, milestone=m2,
|
||||
time=datetime.datetime.now() - datetime.timedelta(days=10))
|
||||
|
||||
# send
|
||||
mailbox_before = len(outbox)
|
||||
for g in groups_with_milestones_needing_review():
|
||||
email_milestone_review_reminder(g)
|
||||
|
||||
self.assertEqual(len(outbox), mailbox_before + 1)
|
||||
self.assertTrue(group.acronym in outbox[-1]["Subject"])
|
||||
self.assertTrue(m1.desc in unicode(outbox[-1]))
|
||||
self.assertTrue(m2.desc in unicode(outbox[-1]))
|
||||
|
||||
def test_send_milestones_due_reminders(self):
|
||||
make_test_data()
|
||||
|
||||
group = Group.objects.get(acronym="mars")
|
||||
|
||||
early_warning_days = 30
|
||||
|
||||
# due dates here aren't aligned on the last day of the month,
|
||||
# but everything should still work
|
||||
|
||||
m1 = GroupMilestone.objects.create(group=group,
|
||||
desc="Test 1",
|
||||
due=datetime.date.today(),
|
||||
resolved="Done",
|
||||
state_id="active")
|
||||
m2 = GroupMilestone.objects.create(group=group,
|
||||
desc="Test 2",
|
||||
due=datetime.date.today() + datetime.timedelta(days=early_warning_days - 10),
|
||||
resolved="",
|
||||
state_id="active")
|
||||
|
||||
# send
|
||||
mailbox_before = len(outbox)
|
||||
for g in groups_needing_milestones_due_reminder(early_warning_days):
|
||||
email_milestones_due(g, early_warning_days)
|
||||
|
||||
self.assertEqual(len(outbox), mailbox_before) # none found
|
||||
|
||||
m1.resolved = ""
|
||||
m1.save()
|
||||
|
||||
m2.due = datetime.date.today() + datetime.timedelta(days=early_warning_days)
|
||||
m2.save()
|
||||
|
||||
# send
|
||||
mailbox_before = len(outbox)
|
||||
for g in groups_needing_milestones_due_reminder(early_warning_days):
|
||||
email_milestones_due(g, early_warning_days)
|
||||
|
||||
self.assertEqual(len(outbox), mailbox_before + 1)
|
||||
self.assertTrue(group.acronym in outbox[-1]["Subject"])
|
||||
self.assertTrue(m1.desc in unicode(outbox[-1]))
|
||||
self.assertTrue(m2.desc in unicode(outbox[-1]))
|
||||
|
||||
def test_send_milestones_overdue_reminders(self):
|
||||
make_test_data()
|
||||
|
||||
group = Group.objects.get(acronym="mars")
|
||||
|
||||
# due dates here aren't aligned on the last day of the month,
|
||||
# but everything should still work
|
||||
|
||||
m1 = GroupMilestone.objects.create(group=group,
|
||||
desc="Test 1",
|
||||
due=datetime.date.today() - datetime.timedelta(days=200),
|
||||
resolved="Done",
|
||||
state_id="active")
|
||||
m2 = GroupMilestone.objects.create(group=group,
|
||||
desc="Test 2",
|
||||
due=datetime.date.today() - datetime.timedelta(days=10),
|
||||
resolved="",
|
||||
state_id="active")
|
||||
|
||||
# send
|
||||
mailbox_before = len(outbox)
|
||||
for g in groups_needing_milestones_overdue_reminder(grace_period=30):
|
||||
email_milestones_overdue(g)
|
||||
|
||||
self.assertEqual(len(outbox), mailbox_before) # none found
|
||||
|
||||
m1.resolved = ""
|
||||
m1.save()
|
||||
|
||||
m2.due = self.last_day_of_month(datetime.date.today() - datetime.timedelta(days=300))
|
||||
m2.save()
|
||||
|
||||
# send
|
||||
mailbox_before = len(outbox)
|
||||
for g in groups_needing_milestones_overdue_reminder(grace_period=30):
|
||||
email_milestones_overdue(g)
|
||||
|
||||
self.assertEqual(len(outbox), mailbox_before + 1)
|
||||
self.assertTrue(group.acronym in outbox[-1]["Subject"])
|
||||
self.assertTrue(m1.desc in unicode(outbox[-1]))
|
||||
self.assertTrue(m2.desc in unicode(outbox[-1]))
|
||||
|
||||
class CustomizeWorkflowTests(TestCase):
|
||||
def test_customize_workflow(self):
|
||||
make_test_data()
|
||||
|
|
|
@ -628,20 +628,6 @@ def make_mailtriggers(apps):
|
|||
'doc_discussing_ads',
|
||||
])
|
||||
|
||||
mt_factory(slug='milestone_review_reminder',
|
||||
desc="Recipients for reminder message that unapproved milestone changes need review",
|
||||
to_slugs=['group_responsible_directors',],
|
||||
cc_slugs=['group_chairs', ],
|
||||
)
|
||||
|
||||
mt_factory(slug='milestones_due_soon',
|
||||
desc="Recipients for reminder message for milestones about to become overdue",
|
||||
to_slugs=['group_chairs', ])
|
||||
|
||||
mt_factory(slug='milestones_overdue',
|
||||
desc="Recipients for message about milestones that are overdue",
|
||||
to_slugs=['group_chairs', ])
|
||||
|
||||
mt_factory(slug='group_personnel_change',
|
||||
desc="Recipients for a message noting changes in a group's personnel",
|
||||
to_slugs=['iesg_secretary',
|
||||
|
|
|
@ -5459,41 +5459,6 @@
|
|||
"model": "mailtrigger.mailtrigger",
|
||||
"pk": "liaison_statement_posted"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"cc": [],
|
||||
"to": [
|
||||
"group_chairs"
|
||||
],
|
||||
"desc": "Recipients for reminder message for milestones about to become overdue"
|
||||
},
|
||||
"model": "mailtrigger.mailtrigger",
|
||||
"pk": "milestones_due_soon"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"cc": [],
|
||||
"to": [
|
||||
"group_chairs"
|
||||
],
|
||||
"desc": "Recipients for message about milestones that are overdue"
|
||||
},
|
||||
"model": "mailtrigger.mailtrigger",
|
||||
"pk": "milestones_overdue"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"cc": [
|
||||
"group_chairs"
|
||||
],
|
||||
"to": [
|
||||
"group_responsible_directors"
|
||||
],
|
||||
"desc": "Recipients for reminder message that unapproved milestone changes need review"
|
||||
},
|
||||
"model": "mailtrigger.mailtrigger",
|
||||
"pk": "milestone_review_reminder"
|
||||
},
|
||||
{
|
||||
"fields": {
|
||||
"cc": [],
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{% autoescape off %}{% filter wordwrap:73 %}This is a reminder that milestones in "{{ group.name }}" are soon due.
|
||||
|
||||
{% for m in milestones %}"{{ m.desc }}" is due {% if m.due == today %}today!{% else %}in {{ early_warning_days }} days.{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
URL: {{ url }}
|
||||
{% endfilter %}{% endautoescape %}
|
|
@ -1,10 +0,0 @@
|
|||
{% autoescape off %}{% filter wordwrap:73 %}{{ milestones|length }} new milestone{{ milestones|pluralize }} in "{{ group.name }}" {% if milestones|length > 1 %}need{% else %}needs{%endif %} review by the {{ reviewer }}:
|
||||
|
||||
{% for m in milestones %}"{{ m.desc }}"{% if m.days_ready != None %}
|
||||
Waiting for {{ m.days_ready }} day{{ m.days_ready|pluralize }}.{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
Go here to either accept or reject the new milestones:
|
||||
|
||||
{{ url }}
|
||||
{% endfilter %}{% endautoescape %}
|
|
@ -1,7 +0,0 @@
|
|||
{% autoescape off %}{% filter wordwrap:73 %}This is a reminder that milestones in "{{ group.name }}" are overdue.
|
||||
|
||||
{% for m in milestones %}"{{ m.desc }}" is overdue{% if m.months_overdue > 0 %} with {{ m.months_overdue }} month{{ m.months_overdue|pluralize }}{% endif %}!
|
||||
|
||||
{% endfor %}
|
||||
URL: {{ url }}
|
||||
{% endfilter %}{% endautoescape %}
|
Loading…
Reference in a new issue