Skip to content

Commit 7e00fa1

Browse files
committed
Move the Secretariat group email utility to wginfo and the rest of the wgcharter stuff to doc/(views|urls|utils)_charter.py alongside the other document types
- Legacy-Id: 7121
1 parent c4313a4 commit 7e00fa1

31 files changed

Lines changed: 172 additions & 294 deletions
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from ietf.name.models import *
2020
from ietf.person.models import *
2121
from ietf.iesg.models import TelechatDate
22-
from ietf.wgcharter.utils import *
22+
from ietf.doc.utils_charter import *
2323

2424
class EditCharterTests(TestCase):
2525
def setUp(self):
@@ -71,13 +71,13 @@ def test_change_state(self):
7171
def find_event(t):
7272
return [e for e in charter.docevent_set.all()[:events_now - events_before] if e.type == t]
7373

74-
self.assertTrue("State changed" in find_event("changed_document")[0].desc)
74+
self.assertTrue("state changed" in find_event("changed_document")[0].desc.lower())
7575

7676
if slug in ("intrev", "iesgrev"):
7777
self.assertTrue(find_event("created_ballot"))
7878

7979
self.assertEqual(len(outbox), mailbox_before + 1)
80-
self.assertTrue("State changed" in outbox[-1]['Subject'])
80+
self.assertTrue("state changed" in outbox[-1]['Subject'].lower())
8181

8282
def test_edit_telechat_date(self):
8383
make_test_data()
@@ -272,7 +272,7 @@ def test_approve(self):
272272

273273
self.assertEqual(len(outbox), mailbox_before + 2)
274274
self.assertTrue("WG Action" in outbox[-1]['Subject'])
275-
self.assertTrue("Charter approved" in outbox[-2]['Subject'])
275+
self.assertTrue("approved" in outbox[-2]['Subject'].lower())
276276

277277
self.assertEqual(group.groupmilestone_set.filter(state="charter").count(), 0)
278278
self.assertEqual(group.groupmilestone_set.filter(state="active").count(), 2)

ietf/doc/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696

9797
url(r'^help/state/(?P<type>[\w-]+)/$', 'ietf.doc.views_help.state_help', name="state_help"),
9898

99-
(r'^(?P<name>charter-[A-Za-z0-9._+-]+)/', include('ietf.wgcharter.urls')),
99+
(r'^(?P<name>charter-[A-Za-z0-9._+-]+)/', include('ietf.doc.urls_charter')),
100100
(r'^(?P<name>[A-Za-z0-9._+-]+)/conflict-review/', include('ietf.doc.urls_conflict_review')),
101101
(r'^(?P<name>[A-Za-z0-9._+-]+)/status-change/', include('ietf.doc.urls_status_change')),
102102
)

ietf/doc/urls_charter.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright The IETF Trust 2011, All Rights Reserved
2+
3+
from django.conf.urls import patterns, url
4+
5+
urlpatterns = patterns('',
6+
url(r'^state/$', "ietf.doc.views_charter.change_state", name='charter_change_state'),
7+
url(r'^(?P<option>initcharter|recharter|abandon)/$', "ietf.doc.views_charter.change_state", name='charter_startstop_process'),
8+
url(r'^telechat/$', "ietf.doc.views_charter.telechat_date", name='charter_telechat_date'),
9+
url(r'^notify/$', "ietf.doc.views_charter.edit_notify", name='charter_edit_notify'),
10+
url(r'^ad/$', "ietf.doc.views_charter.edit_ad", name='charter_edit_ad'),
11+
url(r'^(?P<ann>action|review)/$', "ietf.doc.views_charter.announcement_text", name="charter_edit_announcement"),
12+
url(r'^ballotwriteupnotes/$', "ietf.doc.views_charter.ballot_writeupnotes"),
13+
url(r'^approve/$', "ietf.doc.views_charter.approve", name='charter_approve'),
14+
url(r'^submit/$', "ietf.doc.views_charter.submit", name='charter_submit'),
15+
url(r'^submit/(?P<option>initcharter|recharter)/$', "ietf.doc.views_charter.submit", name='charter_submit'), # shouldn't be here
16+
url(r'^withmilestones-(?P<rev>[0-9-]+).txt$', "ietf.doc.views_charter.charter_with_milestones_txt", name='charter_with_milestones_txt'),
17+
)
Lines changed: 114 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,120 @@
1-
# generation of mails
2-
3-
import textwrap, datetime
1+
import re, datetime, os, textwrap
42

53
from django.template.loader import render_to_string
64
from django.utils.html import strip_tags
75
from django.conf import settings
86
from django.core.urlresolvers import reverse as urlreverse
97

10-
from ietf.utils.mail import send_mail, send_mail_text
11-
from ietf.ipr.search import iprs_from_docs
12-
from ietf.doc.models import WriteupDocEvent, DocAlias, BallotPositionDocEvent
8+
from ietf.utils.mail import send_mail_text
139
from ietf.person.models import Person
14-
from ietf.wgcharter.utils import *
15-
16-
def email_secretariat(request, group, type, text):
17-
to = ["iesg-secretary@ietf.org"]
18-
19-
types = {}
20-
types['state'] = "State changed"
21-
types['state-notrev'] = "State changed to Not currently under review"
22-
types['state-infrev'] = "State changed to Informal review"
23-
types['state-intrev'] = "State changed to Internal review"
24-
types['state-extrev'] = "State changed to External review"
25-
types['state-iesgrev'] = "State changed to IESG review"
26-
types['state-approved'] = "Charter approved"
27-
types['conclude'] = "Request closing of group"
28-
29-
subject = u"Regarding %s %s: %s" % (group.type.name, group.acronym, types[type])
10+
from ietf.group.models import GroupEvent, ChangeStateGroupEvent
11+
from ietf.doc.models import Document, DocAlias, DocHistory, RelatedDocument, DocumentAuthor
12+
from ietf.doc.models import DocEvent, NewRevisionDocEvent, WriteupDocEvent, BallotPositionDocEvent
13+
from ietf.utils.history import find_history_active_at
14+
15+
16+
def log_state_changed(request, doc, by, prev_state):
17+
e = DocEvent(doc=doc, by=by)
18+
e.type = "changed_document"
19+
e.desc = u"State changed to <b>%s</b> from %s" % (
20+
doc.get_state().name,
21+
prev_state.name if prev_state else "None")
22+
e.save()
23+
return e
24+
25+
def next_revision(rev):
26+
if rev == "":
27+
return "00-00"
28+
m = re.match(r"(?P<major>[0-9][0-9])(-(?P<minor>[0-9][0-9]))?", rev)
29+
if m.group('minor'):
30+
return "%s-%#02d" % (m.group('major'), int(m.group('minor')) + 1)
31+
else:
32+
return "%s-00" % (m.group('major'))
33+
34+
def approved_revision(rev):
35+
if rev == "":
36+
return ""
37+
m = re.match(r"(?P<major>[0-9][0-9])(-(?P<minor>[0-9][0-9]))?", rev)
38+
return m.group('major')
39+
40+
def next_approved_revision(rev):
41+
if rev == "":
42+
return "01"
43+
m = re.match(r"(?P<major>[0-9][0-9])(-(?P<minor>[0-9][0-9]))?", rev)
44+
return "%#02d" % (int(m.group('major')) + 1)
45+
46+
def read_charter_text(doc):
47+
filename = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev))
48+
try:
49+
with open(filename, 'r') as f:
50+
return f.read()
51+
except IOError:
52+
return "Error: couldn't read charter text"
53+
54+
def historic_milestones_for_charter(charter, rev):
55+
"""Return GroupMilestone/GroupMilestoneHistory objects for charter
56+
document at rev by looking through the history."""
57+
58+
chartering = "-" in rev
59+
if chartering:
60+
need_state = "charter"
61+
else:
62+
need_state = "active"
63+
64+
# slight complication - we can assign milestones to a revision up
65+
# until the point where the next superseding revision is
66+
# published, so that time shall be our limit
67+
revision_event = charter.latest_event(NewRevisionDocEvent, type="new_revision", rev=rev)
68+
if not revision_event:
69+
return []
70+
71+
e = charter.docevent_set.filter(time__gt=revision_event.time, type="new_revision").order_by("time")
72+
if not chartering:
73+
e = e.exclude(newrevisiondocevent__rev__contains="-")
74+
75+
if e:
76+
# subtract a margen of error to avoid collisions with
77+
# milestones being published at the same time as the new
78+
# revision (when approving a charter)
79+
just_before_next_rev = e[0].time - datetime.timedelta(seconds=5)
80+
else:
81+
just_before_next_rev = datetime.datetime.now()
82+
83+
res = []
84+
for m in charter.chartered_group.groupmilestone_set.all():
85+
mh = find_history_active_at(m, just_before_next_rev)
86+
if mh and mh.state_id == need_state:
87+
res.append(mh)
88+
89+
return res
3090

31-
text = strip_tags(text)
32-
send_mail(request, to, None, subject,
33-
"wgcharter/email_secretariat.txt",
34-
dict(text=text,
35-
group=group,
36-
group_url=settings.IDTRACKER_BASE_URL + urlreverse('group_charter', kwargs=dict(acronym=group.acronym)),
37-
charter_url=settings.IDTRACKER_BASE_URL + urlreverse('doc_view', kwargs=dict(name=group.charter.name)),
38-
)
39-
)
91+
92+
def update_telechat(request, doc, by, new_telechat_date):
93+
# FIXME: reuse function in doc/utils.py instead of this one
94+
# (need to fix auto-setting returning item problem first though)
95+
from ietf.doc.models import TelechatDocEvent
96+
97+
on_agenda = bool(new_telechat_date)
98+
99+
prev = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
100+
prev_telechat = prev.telechat_date if prev else None
101+
prev_agenda = bool(prev_telechat)
102+
103+
e = TelechatDocEvent()
104+
e.type = "scheduled_for_telechat"
105+
e.by = by
106+
e.doc = doc
107+
e.telechat_date = new_telechat_date
108+
109+
if on_agenda != prev_agenda:
110+
if on_agenda:
111+
e.desc = "Placed on agenda for telechat - %s" % new_telechat_date
112+
else:
113+
e.desc = "Removed from agenda for telechat"
114+
e.save()
115+
elif on_agenda and new_telechat_date != prev_telechat:
116+
e.desc = "Telechat date has been changed to <b>%s</b> from <b>%s</b>" % (new_telechat_date, prev_telechat)
117+
e.save()
40118

41119
def email_state_changed(request, doc, text):
42120
to = [e.strip() for e in doc.notify.replace(';', ',').split(',')]
@@ -51,14 +129,13 @@ def email_state_changed(request, doc, text):
51129
"State changed: %s-%s" % (doc.canonical_name(), doc.rev),
52130
text)
53131

54-
55132
def generate_ballot_writeup(request, doc):
56133
e = WriteupDocEvent()
57134
e.type = "changed_ballot_writeup_text"
58135
e.by = request.user.person
59136
e.doc = doc
60137
e.desc = u"Ballot writeup was generated"
61-
e.text = unicode(render_to_string("wgcharter/ballot_writeup.txt"))
138+
e.text = unicode(render_to_string("doc/charter/ballot_writeup.txt"))
62139
e.save()
63140

64141
return e
@@ -73,7 +150,7 @@ def default_action_text(group, charter, user):
73150
e.by = user
74151
e.type = "changed_action_announcement"
75152
e.desc = "%s action text was changed" % group.type.name
76-
e.text = render_to_string("wgcharter/action_text.txt",
153+
e.text = render_to_string("doc/charter/action_text.txt",
77154
dict(group=group,
78155
charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(),
79156
charter_text=read_charter_text(charter),
@@ -93,7 +170,7 @@ def default_review_text(group, charter, user):
93170
e.by = user
94171
e.type = "changed_review_announcement"
95172
e.desc = "%s review text was changed" % group.type.name
96-
e.text = render_to_string("wgcharter/review_text.txt",
173+
e.text = render_to_string("doc/charter/review_text.txt",
97174
dict(group=group,
98175
charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(),
99176
charter_text=read_charter_text(charter),
@@ -163,7 +240,7 @@ def formatted(val):
163240
e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
164241
ballot_writeup = e.text if e else ""
165242

166-
return render_to_string("wgcharter/issue_ballot_mail.txt",
243+
return render_to_string("doc/charter/issue_ballot_mail.txt",
167244
dict(doc=doc,
168245
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
169246
active_ad_positions=active_ad_positions,
@@ -174,3 +251,4 @@ def formatted(val):
174251
)
175252
)
176253

254+
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
from ietf.person.models import *
2424
from ietf.group.models import *
2525
from ietf.group.utils import save_group_in_history, save_milestone_in_history
26-
from ietf.wgcharter.mails import *
27-
from ietf.wgcharter.utils import *
26+
from ietf.wginfo.mails import email_secretariat
27+
from ietf.doc.utils_charter import *
2828

2929
import debug
3030

@@ -124,7 +124,7 @@ def change_state(request, name, option=None):
124124
charter.save()
125125

126126
if message:
127-
email_secretariat(request, group, "state-%s" % charter_state.slug, message)
127+
email_secretariat(request, group, "Charter state changed to %s" % charter_state.name, message)
128128

129129
email_state_changed(request, charter, "State changed to %s." % charter_state)
130130

@@ -185,7 +185,7 @@ def state_pk(slug):
185185

186186
states_for_ballot_wo_extern = State.objects.filter(used=True, type="charter", slug="intrev").values_list("pk", flat=True)
187187

188-
return render_to_response('wgcharter/change_state.html',
188+
return render_to_response('doc/charter/change_state.html',
189189
dict(form=form,
190190
doc=group.charter,
191191
login=login,
@@ -230,7 +230,7 @@ def telechat_date(request, name):
230230
else:
231231
form = TelechatForm(initial=initial)
232232

233-
return render_to_response('wgcharter/edit_telechat_date.html',
233+
return render_to_response('doc/charter/edit_telechat_date.html',
234234
dict(doc=doc,
235235
form=form,
236236
user=request.user,
@@ -274,7 +274,7 @@ def edit_notify(request, name):
274274
else:
275275
form = NotifyForm(initial=init)
276276

277-
return render_to_response('wgcharter/edit_notify.html',
277+
return render_to_response('doc/charter/edit_notify.html',
278278
dict(doc=doc,
279279
form=form,
280280
user=request.user,
@@ -322,7 +322,7 @@ def edit_ad(request, name):
322322
init = { "ad" : charter.ad_id }
323323
form = AdForm(initial=init)
324324

325-
return render_to_response('wgcharter/change_ad.html',
325+
return render_to_response('doc/charter/change_ad.html',
326326
{'form': form,
327327
'charter': charter,
328328
},
@@ -415,7 +415,7 @@ def submit(request, name=None, acronym=None, option=None):
415415
except IOError:
416416
pass
417417
form = UploadForm(initial=init)
418-
return render_to_response('wgcharter/submit.html',
418+
return render_to_response('doc/charter/submit.html',
419419
{'form': form,
420420
'next_rev': next_rev,
421421
'group': group },
@@ -481,7 +481,7 @@ def announcement_text(request, name, ann):
481481
messages.success(request, "The email To: '%s' with Subject: '%s' has been sent." % (parsed_msg["To"],parsed_msg["Subject"],))
482482
return redirect('doc_writeup', name=charter.name)
483483

484-
return render_to_response('wgcharter/announcement_text.html',
484+
return render_to_response('doc/charter/announcement_text.html',
485485
dict(charter=charter,
486486
announcement=ann,
487487
back_url=urlreverse("doc_writeup", kwargs=dict(name=charter.name)),
@@ -547,13 +547,13 @@ def ballot_writeupnotes(request, name):
547547
e.desc = "Ballot has been sent"
548548
e.save()
549549

550-
return render_to_response('wgcharter/ballot_issued.html',
550+
return render_to_response('doc/charter/ballot_issued.html',
551551
dict(doc=charter,
552552
),
553553
context_instance=RequestContext(request))
554554

555555

556-
return render_to_response('wgcharter/ballot_writeupnotes.html',
556+
return render_to_response('doc/charter/ballot_writeupnotes.html',
557557
dict(charter=charter,
558558
ballot_issued=bool(charter.latest_event(type="sent_ballot_announcement")),
559559
ballot_writeup_form=form,
@@ -632,7 +632,7 @@ def approve(request, name):
632632
charter.time = e.time
633633
charter.save()
634634

635-
email_secretariat(request, group, "state-%s" % new_charter_state.slug, change_description)
635+
email_secretariat(request, group, "Charter state changed to %s" % new_charter_state.name, change_description)
636636

637637
# move milestones over
638638
milestones_to_delete = list(group.groupmilestone_set.filter(state__in=("active", "review")))
@@ -689,7 +689,7 @@ def approve(request, name):
689689

690690
return HttpResponseRedirect(charter.get_absolute_url())
691691

692-
return render_to_response('wgcharter/approve.html',
692+
return render_to_response('doc/charter/approve.html',
693693
dict(charter=charter,
694694
announcement=announcement),
695695
context_instance=RequestContext(request))
@@ -720,7 +720,7 @@ def charter_with_milestones_txt(request, name, rev):
720720
for m in milestones:
721721
m.desc_filled = wrapper.fill(m.desc)
722722

723-
return render_to_response('wgcharter/charter_with_milestones.txt',
723+
return render_to_response('doc/charter/charter_with_milestones.txt',
724724
dict(charter_text=charter_text,
725725
milestones=milestones),
726726
context_instance=RequestContext(request),

0 commit comments

Comments
 (0)