Skip to content

Commit f0f5a51

Browse files
committed
(Rocky) merge forward.
- Legacy-Id: 10157
2 parents c438eb0 + 9d1ff92 commit f0f5a51

File tree

89 files changed

+4449
-1338
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+4449
-1338
lines changed

2015-08-28-scrub-notify.py

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#!/usr/bin/env python
2+
3+
import os, sys, re
4+
5+
from copy import copy
6+
7+
import datetime
8+
9+
# boilerplate
10+
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../web/"))
11+
sys.path = [ basedir ] + sys.path
12+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ietf.settings")
13+
14+
import django
15+
16+
django.setup()
17+
18+
from django.db.models import F
19+
from django.template import Template,Context
20+
from ietf.doc.models import Document, DocEvent
21+
from ietf.person.models import Person
22+
from ietf.utils.mail import send_mail_text
23+
24+
def message_body_template():
25+
return Template("""{% filter wordwrap:72 %}The Notify field for the document{{ count|pluralize }} listed at the end of this message {% if count > 1 %}were{% else %}was{% endif %} changed by removing the chair, shepherd, author, and similar addresses (in direct or alias form) to the point they could be identified.
26+
27+
The Datatracker now includes those addresses explicitly in each message it sends as appropriate. You can review where the datatracker sends messages for a given action in general using <https://datatracker.ietf.org/mailtoken/token>. You can review the expansions for a specific document by the new Email expansions tab on the document's page. Note that the addresses included for any given action are much more comprehensive than they were before this release.
28+
29+
Please review each new Notify field, and help remove any remaining addresses that will normally be copied per the configuration shown at https://datatracker.ietf.org/mailtoken/token. The field should now only contain exceptional addresses - parties you wish to be notified that aren't part of the new normal recipient set.
30+
31+
You can see exactly how the Notify field was changed for a given document by looking in the document's history.{% endfilter %}
32+
33+
{% if non_empty%}The document{{non_empty|length|pluralize }} with non-empty new Notify fields are:{% for doc in non_empty %}
34+
https://datatracker.ietf.org{{doc.get_absolute_url}}{% endfor %}{% endif %}
35+
36+
{% if empty%}The document{{non_empty|length|pluralize }} with empty new Notify fields are:{% for doc in empty %}
37+
https://datatracker.ietf.org{{doc.get_absolute_url}}{% endfor %}{% endif %}
38+
39+
""")
40+
41+
def other_addrs(addr):
42+
person = Person.objects.filter(email__address__iexact=addr).first()
43+
if not person:
44+
return None
45+
return [x.lower() for x in person.email_set.values_list('address',flat=True)]
46+
47+
def prep(item):
48+
retval = item.lower()
49+
if '<' in retval:
50+
if not '>' in retval:
51+
raise "Bad item: "+item
52+
start=retval.index('<')+1
53+
stop=retval.index('>')
54+
retval = retval[start:stop]
55+
return retval
56+
57+
def is_management(item, doc):
58+
59+
item = prep(item)
60+
61+
if any([
62+
item == '%s.chairs@ietf.org'%doc.name,
63+
item == '%s.ad@ietf.org'%doc.name,
64+
item == '%s.shepherd@ietf.org'%doc.name,
65+
item == '%s.chairs@tools.ietf.org'%doc.name,
66+
item == '%s.ad@tools.ietf.org'%doc.name,
67+
item == '%s.shepherd@tools.ietf.org'%doc.name,
68+
doc.ad and item == doc.ad.email_address().lower(),
69+
doc.shepherd and item == doc.shepherd.address.lower(),
70+
]):
71+
return True
72+
73+
if doc.group:
74+
if any([
75+
item == '%s-chairs@ietf.org'%doc.group.acronym,
76+
item == '%s-ads@ietf.org'%doc.group.acronym,
77+
item == '%s-chairs@tools.ietf.org'%doc.group.acronym,
78+
item == '%s-ads@tools.ietf.org'%doc.group.acronym,
79+
]):
80+
return True
81+
for addr in doc.group.role_set.filter(name__in=['chair','ad','delegate']).values_list('email__address',flat=True):
82+
other = other_addrs(addr)
83+
if item == addr.lower() or item in other:
84+
return True
85+
if doc.group.parent:
86+
if item == '%s-ads@ietf.org'%doc.group.parent.acronym or item == '%s-ads@tools.ietf.org'%doc.group.parent.acronym:
87+
return True
88+
89+
return False
90+
91+
def is_author(item, doc):
92+
item = prep(item)
93+
94+
if item == '%s@ietf.org' % doc.name or item == '%s@tools.ietf.org' % doc.name:
95+
return True
96+
97+
for addr in doc.authors.values_list('address',flat=True):
98+
other = other_addrs(addr)
99+
if item == addr.lower() or item in other:
100+
return True
101+
102+
return False
103+
104+
msg_template = message_body_template()
105+
by = Person.objects.get(name="(System)")
106+
active_ads = list(Person.objects.filter(role__name="ad", role__group__state="active", role__group__type="area"))
107+
108+
affected = set()
109+
empty = dict()
110+
non_empty = dict()
111+
changed = 0
112+
emptied = 0
113+
114+
qs = Document.objects.exclude(notify__isnull=True).exclude(notify='')
115+
for doc in qs:
116+
doc.notify = doc.notify.replace(';', ',')
117+
items = set([ i.strip() for i in doc.notify.split(',') if i.strip() and '@' in i])
118+
original_items = copy(items)
119+
for item in original_items:
120+
if any([
121+
doc.group and doc.group.list_email and item.lower() == doc.group.list_email.lower(),
122+
is_management(item,doc),
123+
is_author(item,doc),
124+
]):
125+
items.discard(item)
126+
if original_items != items:
127+
changed += 1
128+
if len(list(items))==0:
129+
emptied += 1
130+
131+
to = []
132+
if doc.ad and doc.ad in active_ads:
133+
to.append(doc.ad.email_address())
134+
if doc.group and doc.group.state_id=='active':
135+
to.extend(doc.group.role_set.filter(name__in=['chair','ad']).values_list('email__address',flat=True))
136+
if not to:
137+
to = ['iesg@ietf.org']
138+
139+
to = ", ".join(sorted(to))
140+
affected.add(to)
141+
empty.setdefault(to,[])
142+
non_empty.setdefault(to,[])
143+
if len(list(items))==0:
144+
empty[to].append(doc)
145+
else:
146+
non_empty[to].append(doc)
147+
original_notify = doc.notify
148+
new_notify = ', '.join(list(items))
149+
doc.notify = new_notify
150+
doc.time = datetime.datetime.now()
151+
doc.save()
152+
e = DocEvent(type="added_comment",doc=doc,time=doc.time,by=by)
153+
e.desc = "Notify list changed from %s to %s"% (original_notify, new_notify if new_notify else '(None)')
154+
e.save()
155+
156+
for a in list(affected):
157+
158+
txt = msg_template.render(Context({'count':len(empty[a])+len(non_empty[a]),'empty':empty[a],'non_empty':non_empty[a]}))
159+
send_mail_text(None, to=a, frm=None, subject='Document Notify fields changed to match new Datatracker addressing defaults',txt =txt)
160+
161+
print "Changed",changed,"documents.",emptied,"of those had their notify field emptied"
162+
print "Sent email to ",len(affected),"different sets of addresses"
163+

ietf/bin/send-milestone-reminders

Lines changed: 0 additions & 46 deletions
This file was deleted.

ietf/doc/expire.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
from ietf.utils.mail import send_mail
99
from ietf.doc.models import Document, DocEvent, State, save_document_in_history, IESG_SUBSTATE_TAGS
10-
from ietf.person.models import Person, Email
10+
from ietf.person.models import Person
1111
from ietf.meeting.models import Meeting
1212
from ietf.doc.utils import add_state_change_event
13-
13+
from ietf.mailtrigger.utils import gather_address_lists
1414

1515

1616
def expirable_draft(draft):
@@ -70,10 +70,7 @@ def send_expire_warning_for_draft(doc):
7070

7171
expiration = doc.expires.date()
7272

73-
to = [e.formatted_email() for e in doc.authors.all() if not e.address.startswith("unknown-email")]
74-
cc = None
75-
if doc.group.type_id in ("wg", "rg"):
76-
cc = [e.formatted_email() for e in Email.objects.filter(role__group=doc.group, role__name="chair") if not e.address.startswith("unknown-email")]
73+
(to,cc) = gather_address_lists('doc_expires_soon',doc=doc)
7774

7875
s = doc.get_state("draft-iesg")
7976
state = s.name if s else "I-D Exists"
@@ -91,21 +88,22 @@ def send_expire_warning_for_draft(doc):
9188
cc=cc)
9289

9390
def send_expire_notice_for_draft(doc):
94-
if not doc.ad or doc.get_state_slug("draft-iesg") == "dead":
91+
if doc.get_state_slug("draft-iesg") == "dead":
9592
return
9693

9794
s = doc.get_state("draft-iesg")
9895
state = s.name if s else "I-D Exists"
9996

10097
request = None
101-
to = doc.ad.role_email("ad").formatted_email()
98+
(to,cc) = gather_address_lists('doc_expired',doc=doc)
10299
send_mail(request, to,
103100
"I-D Expiring System <ietf-secretariat-reply@ietf.org>",
104101
u"I-D was expired %s" % doc.file_tag(),
105102
"doc/draft/id_expired_email.txt",
106103
dict(doc=doc,
107104
state=state,
108-
))
105+
),
106+
cc=cc)
109107

110108
def move_draft_files_to_archive(doc, rev):
111109
def move_file(f):

0 commit comments

Comments
 (0)