checkpoint

- Legacy-Id: 10029
This commit is contained in:
Robert Sparks 2015-08-19 19:53:09 +00:00
parent 093ff52eac
commit 5db9e0d6a8
9 changed files with 367 additions and 67 deletions

View file

@ -129,6 +129,8 @@ def get_update_submitter_emails(ipr):
else:
email_to_iprs[email] = [related.target]
# TODO: This has not been converted to use mailtoken. It is complicated.
# When converting it, it will need something like ipr_submitter_ietfer_or_holder perhaps
for email in email_to_iprs:
context = dict(
to_email=email,

View file

@ -92,6 +92,18 @@ class IprDisclosureBase(models.Model):
else:
return None
def recursively_updates(self,disc_set=None):
"""Returns the set of disclosures updated directly or transitively by this disclosure"""
if disc_set == None:
disc_set = set()
new_candidates = set([y.target.get_child() for y in self.updates])
unseen = new_candidates - disc_set
disc_set.update(unseen)
for disc in unseen:
disc_set.update(disc.recursively_updates(disc_set))
return disc_set
class HolderIprDisclosure(IprDisclosureBase):
ietfer_name = models.CharField(max_length=255, blank=True) # "Whose Personal Belief Triggered..."
ietfer_contact_email = models.EmailField(blank=True)

View file

@ -489,7 +489,7 @@ I would like to revoke this declaration.
self.assertEqual(r.status_code,302)
self.assertEqual(len(outbox),len_before+2)
self.assertTrue('george@acme.com' in outbox[len_before]['To'])
self.assertTrue('aread@ietf.org' in outbox[len_before+1]['To'])
self.assertTrue('draft-ietf-mars-test@ietf.org' in outbox[len_before+1]['To'])
self.assertTrue('mars-wg@ietf.org' in outbox[len_before+1]['Cc'])
def test_process_response_email(self):

View file

@ -16,8 +16,7 @@ from django.template.loader import render_to_string
from ietf.doc.models import DocAlias
from ietf.group.models import Role, Group
from ietf.ietfauth.utils import role_required, has_role
from ietf.ipr.mail import (message_from_message, get_reply_to, get_update_submitter_emails,
get_update_cc_addrs)
from ietf.ipr.mail import (message_from_message, get_reply_to, get_update_submitter_emails)
from ietf.ipr.fields import select2_id_ipr_title_json
from ietf.ipr.forms import (HolderIprDisclosureForm, GenericDisclosureForm,
ThirdPartyIprDisclosureForm, DraftForm, SearchForm, MessageModelForm,
@ -80,13 +79,13 @@ def get_document_emails(ipr):
else:
cc_list = get_wg_email_list(doc.group)
author_emails = ','.join([a.address for a in authors])
to_list = gather_addresses('ipr_posted_on_doc',doc=doc)
cc_list = gather_addresses('ipr_posted_on_doc_cc',doc=doc)
author_names = ', '.join([a.person.name for a in authors])
cc_list += ", ipr-announce@ietf.org"
context = dict(
doc_info=doc_info,
to_email=author_emails,
to_email=to_list,
to_name=author_names,
cc_email=cc_list,
ipr=ipr)
@ -99,16 +98,14 @@ def get_posted_emails(ipr):
"""Return a list of messages suitable to initialize a NotifyFormset for
the notify view when a new disclosure is posted"""
messages = []
# NOTE 1000+ legacy iprs have no submitter_email
# add submitter message
if True:
context = dict(
to_email=ipr.submitter_email,
to_name=ipr.submitter_name,
cc_email=get_update_cc_addrs(ipr),
ipr=ipr)
text = render_to_string('ipr/posted_submitter_email.txt',context)
messages.append(text)
context = dict(
to_email=gather_addresses('ipr_posting_confirmation',ipr=ipr),
to_name=ipr.submitter_name,
cc_email=gather_addresses('ipr_posting_confirmation_cc',ipr=ipr),
ipr=ipr)
text = render_to_string('ipr/posted_submitter_email.txt',context)
messages.append(text)
# add email to related document authors / parties
if ipr.iprdocrel_set.all():

View file

@ -7,16 +7,13 @@ from django.core.urlresolvers import reverse as urlreverse
from ietf.utils.mail import send_mail_text
from ietf.liaisons.utils import role_persons_with_fixed_email
from ietf.group.models import Role
from ietf.mailtoken.utils import gather_address_list
def send_liaison_by_email(request, liaison):
subject = u'New Liaison Statement, "%s"' % (liaison.title)
from_email = settings.LIAISON_UNIVERSAL_FROM
to_email = liaison.to_contact.split(',')
cc = liaison.cc.split(',')
if liaison.technical_contact:
cc += liaison.technical_contact.split(',')
if liaison.response_contact:
cc += liaison.response_contact.split(',')
to_email = gather_address_list('liaison_statement_posted',liaison=liaison)
cc = gather_address_list('liaison_statement_posted_cc',liaison=liaison)
bcc = ['statements@ietf.org']
body = render_to_string('liaisons/liaison_mail.txt', dict(
liaison=liaison,
@ -42,13 +39,14 @@ def notify_pending_by_email(request, liaison):
# to_email.append('%s <%s>' % person.email())
subject = u'New Liaison Statement, "%s" needs your approval' % (liaison.title)
from_email = settings.LIAISON_UNIVERSAL_FROM
to = gather_address_list('liaison_approval_requested',liaison=liaison)
body = render_to_string('liaisons/pending_liaison_mail.txt', dict(
liaison=liaison,
url=settings.IDTRACKER_BASE_URL + urlreverse("liaison_approval_detail", kwargs=dict(object_id=liaison.pk)),
referenced_url=settings.IDTRACKER_BASE_URL + urlreverse("liaison_detail", kwargs=dict(object_id=liaison.related_to.pk)) if liaison.related_to else None,
))
# send_mail_text(request, to_email, from_email, subject, body)
send_mail_text(request, ['statements@ietf.org'], from_email, subject, body)
send_mail_text(request, to, from_email, subject, body)
def send_sdo_reminder(sdo):
roles = Role.objects.filter(name="liaiman", group=sdo)
@ -58,7 +56,7 @@ def send_sdo_reminder(sdo):
manager_role = roles[0]
subject = 'Request for update of list of authorized individuals'
to_email = manager_role.email.address
to_email = gather_address_list('liaison_manager_update_request',group=sdo)
name = manager_role.person.plain_name()
authorized_list = role_persons_with_fixed_email(sdo, "auth")
@ -95,12 +93,8 @@ def possibly_send_deadline_reminder(liaison):
days_msg = 'expires %s' % PREVIOUS_DAYS[days_to_go]
from_email = settings.LIAISON_UNIVERSAL_FROM
to_email = liaison.to_contact.split(',')
cc = liaison.cc.split(',')
if liaison.technical_contact:
cc += liaison.technical_contact.split(',')
if liaison.response_contact:
cc += liaison.response_contact.split(',')
to_email = gather_address_list('liaison_deadline_soon',liaison=liaison)
cc = gather_address_list('liaison_deadline_soon_cc',liaison=liaison)
bcc = 'statements@ietf.org'
body = render_to_string('liaisons/liaison_deadline_mail.txt',
dict(liaison=liaison,

View file

@ -161,6 +161,10 @@ def make_recipients(apps):
desc="The session request ticketing system",
template='session-request@ietf.org')
rc(slug='logged_in_person',
desc="The person currently logged into the datatracker who initiated a given action",
template='{% if person and person.email_address %}{{ person.email_address }}{% endif %}')
rc(slug='ipr_requests',
desc="The ipr disclosure handling system",
template='ietf-ipr@ietf.org')
@ -169,9 +173,47 @@ def make_recipients(apps):
desc="The submitter of an IPR disclosure",
template='{% if ipr.submitter_email %}{{ ipr.submitter_email }}{% endif %}')
rc(slug='logged_in_person',
desc="The person currently logged into the datatracker who initiated a given action",
template='{% if person and person.email_address %}{{ person.email_address }}{% endif %}')
rc(slug='ipr_updatedipr_contacts',
desc="The submitter (or ietf participant if the submitter is not available) "
"of all IPR disclosures updated directly by this disclosure, without recursing "
"to what the updated disclosures might have updated.",
template=None)
rc(slug='ipr_updatedipr_holders',
desc="The holders of all IPR disclosures updated by disclosure and disclosures updated by those and so on.",
template=None)
rc(slug='ipr_announce',
desc="The IETF IPR announce list",
template='ipr-announce@ietf.org')
rc(slug='doc_ipr_group_or_ad',
desc="Leadership for a document that has a new IPR disclosure",
template=None)
rc(slug='liaison_to_contact',
desc="The addresses captured in the To field of the liaison statement form",
template='{{liaison.to_contact}}')
rc(slug='liaison_cc',
desc="The addresses captured in the Cc field of the liaison statement form",
template='{{liaison.cc}}')
rc(slug='liaison_technical_contact',
desc="The addresses captured in the technical contact field of the liaison statement form",
template='{{liaison.technical_contact}}')
rc(slug='liaison_response_contact',
desc="The addresses captured in the response contact field of the liaison statement form",
template='{{liaison.response_contact}}')
rc(slug='liaison_statements_list',
desc="The IETF liaison statement ticketing system",
template='statements@ietf.org')
rc(slug='liaison_manager',
desc="The assigned liaison manager for an external group ",
template=None)
def make_mailtokens(apps):
@ -645,6 +687,62 @@ def make_mailtokens(apps):
desc="Copied when the secretary follows up on an IPR disclosure submission",
recipient_slugs=[])
mt_factory(slug='ipr_posting_confirmation',
desc="Recipients for a message confirming that a disclosure has been posted",
recipient_slugs=['ipr_submitter',
])
mt_factory(slug='ipr_posting_confirmation_cc',
desc="Copied on a message confirming that a disclosure has been posted",
recipient_slugs=['ipr_updatedipr_contacts',
'ipr_updatedipr_holders',
])
mt_factory(slug='ipr_posted_on_doc',
desc="Recipients when an IPR disclosure calls out a given document",
recipient_slugs=['doc_authors',
])
mt_factory(slug='ipr_posted_on_doc_cc',
desc="Copied when an IPR disclosure calls out a given document",
recipient_slugs=['doc_ipr_group_or_ad',
'ipr_announce',
])
mt_factory(slug='liaison_statement_posted',
desc="Recipient for a message when a new liaison statement is posted",
recipient_slugs=['liaison_to_contact',
])
mt_factory(slug='liaison_statement_posted_cc',
desc="Copied on a message when a new liaison statement is posted",
recipient_slugs=['liaison_cc',
'liaison_technical_contact',
'liaison_response_contact',
])
mt_factory(slug='liaison_approval_requested',
desc="Recipients for a message that a pending liaison statement needs approval",
recipient_slugs=['liaison_statements_list',
])
mt_factory(slug='liaison_deadline_soon',
desc="Recipients for a message about a liaison statement deadline that is approaching.",
recipient_slugs=['liaison_to_contact',
])
mt_factory(slug='liaison_deadline_soon_cc',
desc="Copied on a message about a liaison statement deadline that is approaching.",
recipient_slugs=['liaison_cc',
'liaison_technical_contact',
'liaison_response_contact',
])
mt_factory(slug='liaison_manager_update_request',
desc="Recipients for a message requesting an updated list of authorized individuals",
recipient_slugs=['liaison_manager',
])
def forward(apps, schema_editor):
make_recipients(apps)

View file

@ -3,6 +3,8 @@
from django.db import models
from django.template import Template, Context
from ietf.group.models import Role
class MailToken(models.Model):
slug = models.CharField(max_length=32, primary_key=True)
desc = models.TextField(blank=True)
@ -206,3 +208,46 @@ class Recipient(models.Model):
if pos and pos.pos_id == "discuss":
addrs.append(ad.role_email("ad").address)
return addrs
def gather_ipr_updatedipr_contacts(self, **kwargs):
addrs=[]
if 'ipr' in kwargs:
ipr = kwargs['ipr']
for rel in ipr.updates:
if rel.target.submitter_email:
addrs.append(rel.target.submitter_email)
elif hasattr(rel.target,'ietfer_email') and rel.target.ietfer_email:
addrs.append(rel.target.ietfer_email)
return addrs
def gather_ipr_updatedipr_holders(self, **kwargs):
addrs=[]
if 'ipr' in kwargs:
ipr = kwargs['ipr']
for disc in ipr.recursively_updates():
if hasattr(ipr,'holder_contact_email') and ipr.holder_contact_email:
addrs.append(ipr.holder_contact_email)
return addrs
def gather_doc_ipr_group_or_ad(self, **kwargs):
"""A document's group email list if the document is a group document,
otherwise, the document's AD if the document is active, otherwise
the IETF chair"""
addrs=[]
if 'doc' in kwargs:
doc=kwargs['doc']
if doc.group and doc.group.acronym == 'none':
if doc.ad and doc.get_state_slug('draft')=='active':
addrs.extend(Recipient.objects.get(slug='doc_ad').gather(**kwargs))
else:
addrs.extend(Role.objects.filter(group__acronym='gen',name='ad').values_list('email__address',flat=True))
else:
addrs.extend(Recipient.objects.get(slug='doc_group_mail_list').gather(**kwargs))
return addrs
def gather_liaison_manager(self, **kwargs):
addrs=[]
if 'group' in kwargs:
group=kwargs['group']
addrs.extend(group.role_set.filter(name='liaiman').values_list('email__address',flat=True))
return addrs

View file

@ -4423,6 +4423,14 @@
"model": "mailtoken.recipient",
"pk": "doc_group_responsible_directors"
},
{
"fields": {
"template": null,
"desc": "Leadership for a document that has a new IPR disclosure"
},
"model": "mailtoken.recipient",
"pk": "doc_ipr_group_or_ad"
},
{
"fields": {
"template": null,
@ -4559,6 +4567,14 @@
"model": "mailtoken.recipient",
"pk": "internet_draft_requests"
},
{
"fields": {
"template": "ipr-announce@ietf.org",
"desc": "The IETF IPR announce list"
},
"model": "mailtoken.recipient",
"pk": "ipr_announce"
},
{
"fields": {
"template": "ietf-ipr@ietf.org",
@ -4575,6 +4591,70 @@
"model": "mailtoken.recipient",
"pk": "ipr_submitter"
},
{
"fields": {
"template": null,
"desc": "The submitter (or ietf participant if the submitter is not available) of all IPR disclosures updated directly by this disclosure, without recursing to what the updated disclosures might have updated."
},
"model": "mailtoken.recipient",
"pk": "ipr_updatedipr_contacts"
},
{
"fields": {
"template": null,
"desc": "The holders of all IPR disclosures updated by disclosure and disclosures updated by those and so on."
},
"model": "mailtoken.recipient",
"pk": "ipr_updatedipr_holders"
},
{
"fields": {
"template": "{{liaison.cc}}",
"desc": "The addresses captured in the Cc field of the liaison statement form"
},
"model": "mailtoken.recipient",
"pk": "liaison_cc"
},
{
"fields": {
"template": null,
"desc": "The assigned liaison manager for an external group "
},
"model": "mailtoken.recipient",
"pk": "liaison_manager"
},
{
"fields": {
"template": "{{liaison.response_contact}}",
"desc": "The addresses captured in the response contact field of the liaison statement form"
},
"model": "mailtoken.recipient",
"pk": "liaison_response_contact"
},
{
"fields": {
"template": "statements@ietf.org",
"desc": "The IETF liaison statement ticketing system"
},
"model": "mailtoken.recipient",
"pk": "liaison_statements_list"
},
{
"fields": {
"template": "{{liaison.technical_contact}}",
"desc": "The addresses captured in the technical contact field of the liaison statement form"
},
"model": "mailtoken.recipient",
"pk": "liaison_technical_contact"
},
{
"fields": {
"template": "{{liaison.to_contact}}",
"desc": "The addresses captured in the To field of the liaison statement form"
},
"model": "mailtoken.recipient",
"pk": "liaison_to_contact"
},
{
"fields": {
"template": "{% if person and person.email_address %}{{ person.email_address }}{% endif %}",
@ -5107,6 +5187,48 @@
"model": "mailtoken.mailtoken",
"pk": "ipr_disclosure_submitted"
},
{
"fields": {
"recipients": [
"doc_authors"
],
"desc": "Recipients when an IPR disclosure calls out a given document"
},
"model": "mailtoken.mailtoken",
"pk": "ipr_posted_on_doc"
},
{
"fields": {
"recipients": [
"doc_ipr_group_or_ad",
"ipr_announce"
],
"desc": "Copied when an IPR disclosure calls out a given document"
},
"model": "mailtoken.mailtoken",
"pk": "ipr_posted_on_doc_cc"
},
{
"fields": {
"recipients": [
"ipr_submitter"
],
"desc": "Recipients for a message confirming that a disclosure has been posted"
},
"model": "mailtoken.mailtoken",
"pk": "ipr_posting_confirmation"
},
{
"fields": {
"recipients": [
"ipr_updatedipr_contacts",
"ipr_updatedipr_holders"
],
"desc": "Copied on a message confirming that a disclosure has been posted"
},
"model": "mailtoken.mailtoken",
"pk": "ipr_posting_confirmation_cc"
},
{
"fields": {
"recipients": [
@ -5189,6 +5311,70 @@
"model": "mailtoken.mailtoken",
"pk": "last_call_requested_cc"
},
{
"fields": {
"recipients": [
"liaison_statements_list"
],
"desc": "Recipients for a message that a pending liaison statement needs approval"
},
"model": "mailtoken.mailtoken",
"pk": "liaison_approval_requested"
},
{
"fields": {
"recipients": [
"liaison_to_contact"
],
"desc": "Recipients for a message about a liaison statement deadline that is approaching."
},
"model": "mailtoken.mailtoken",
"pk": "liaison_deadline_soon"
},
{
"fields": {
"recipients": [
"liaison_cc",
"liaison_response_contact",
"liaison_technical_contact"
],
"desc": "Copied on a message about a liaison statement deadline that is approaching."
},
"model": "mailtoken.mailtoken",
"pk": "liaison_deadline_soon_cc"
},
{
"fields": {
"recipients": [
"liaison_manager"
],
"desc": "Recipients for a message requesting an updated list of authorized individuals"
},
"model": "mailtoken.mailtoken",
"pk": "liaison_manager_update_request"
},
{
"fields": {
"recipients": [
"liaison_to_contact"
],
"desc": "Recipient for a message when a new liaison statement is posted"
},
"model": "mailtoken.mailtoken",
"pk": "liaison_statement_posted"
},
{
"fields": {
"recipients": [
"liaison_cc",
"liaison_response_contact",
"liaison_technical_contact"
],
"desc": "Copied on a message when a new liaison statement is posted"
},
"model": "mailtoken.mailtoken",
"pk": "liaison_statement_posted_cc"
},
{
"fields": {
"recipients": [

View file

@ -1,34 +0,0 @@
def get_ad_email_list(group):
'''
This function takes a group and returns the Area Director email as a list.
NOTE: we still have custom logic here for IRTF groups, where the "Area Director"
is the chair of the parent group, 'irtf'.
'''
emails = []
if group.type.slug == 'wg':
emails.append('%s-ads@tools.ietf.org' % group.acronym)
elif group.type.slug == 'rg' and group.parent:
emails.append(group.parent.role_set.filter(name='chair')[0].email.address)
return emails
def get_cc_list(group, person=None):
'''
This function takes a Group and Person. It returns a list of emails for the ads and chairs of
the group and the person's email if it isn't already in the list.
Per Pete Resnick, at IETF 80 meeting, session request notifications
should go to chairs,ads lists not individuals.
'''
emails = []
emails.extend(get_ad_email_list(group))
emails.extend(get_chair_email_list(group))
if person and person.email_address() not in emails:
emails.append(person.email_address())
return emails
def get_chair_email_list(group):
'''
This function takes a group and returns chair email(s) as a list.
'''
return [ r.email.address for r in group.role_set.filter(name='chair') ]