1- # generation of mails
2-
3- import textwrap , datetime
1+ import re , datetime , os , textwrap
42
53from django .template .loader import render_to_string
64from django .utils .html import strip_tags
75from django .conf import settings
86from 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
139from 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
41119def 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-
55132def 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+
0 commit comments