datatracker/ietf/idrfc/mails.py
Ole Laursen f05bc8cf1f Add "Assigned to area" select box to individually submitted documents
in the AD edit form, change search to define area = doc.group or
doc.group.parent (so don't take AD into account), plus a bunch of
small tweaks to make a document with an area set as group behave like
an individually submitted document, at least for the time being (they
are presented as "Individual in xyz area" on their document page)
 - Legacy-Id: 3968
2012-02-25 01:48:33 +00:00

675 lines
28 KiB
Python

# generation of mails
import textwrap
from datetime import datetime, date, time, timedelta
from django.template.loader import render_to_string
from django.utils.html import strip_tags
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.idtracker.models import *
from ietf.ipr.search import iprs_from_docs
from ietf.ietfworkflows.streams import (get_stream_from_draft)
from ietf.ietfworkflows.models import (Stream)
from ietf.doc.models import WriteupDocEvent, BallotPositionDocEvent, LastCallDocEvent, DocAlias
from ietf.person.models import Person
from ietf.group.models import Group
def email_state_changed(request, doc, text):
to = [x.strip() for x in doc.idinternal.state_change_notice_to.replace(';', ',').split(',')]
if to:
send_mail(request, to, None,
"ID Tracker State Update Notice: %s" % doc.file_tag(),
"idrfc/state_changed_email.txt",
dict(text=text,
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
def email_state_changedREDESIGN(request, doc, text):
to = [x.strip() for x in doc.notify.replace(';', ',').split(',')]
if not to:
return
text = strip_tags(text)
send_mail(request, to, None,
"ID Tracker State Update Notice: %s" % doc.file_tag(),
"idrfc/state_changed_email.txt",
dict(text=text,
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
email_state_changed = email_state_changedREDESIGN
def html_to_text(html):
return strip_tags(html.replace("&lt;", "<").replace("&gt;", ">").replace("&amp;", "&").replace("<br>", "\n"))
def email_owner(request, doc, owner, changed_by, text, subject=None):
if not owner or not changed_by or owner == changed_by:
return
to = u"%s <%s>" % owner.person.email()
send_mail(request, to,
"DraftTracker Mail System <iesg-secretary@ietf.org>",
"%s updated by %s" % (doc.file_tag(), changed_by),
"idrfc/change_notice.txt",
dict(text=html_to_text(text),
doc=doc,
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
def email_adREDESIGN(request, doc, ad, changed_by, text, subject=None):
if not ad or not changed_by or ad == changed_by:
return
to = ad.role_email("ad").formatted_email()
send_mail(request, to,
"DraftTracker Mail System <iesg-secretary@ietf.org>",
"%s updated by %s" % (doc.file_tag(), changed_by.plain_name()),
"idrfc/change_notice.txt",
dict(text=html_to_text(text),
doc=doc,
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
email_owner = email_adREDESIGN
def full_intended_status(intended_status):
s = str(intended_status)
# FIXME: this should perhaps be defined in the db
if "Informational" in s:
return "an Informational RFC"
elif "Experimental" in s:
return "an Experimental RFC"
elif "Proposed" in s:
return "a Proposed Standard"
elif "Draft" in s:
return "a Draft Standard"
elif "BCP" in s:
return "a BCP"
elif "Standard" in s:
return "a Full Standard"
elif "Request" in s or "None" in s:
return "*** YOU MUST SELECT AN INTENDED STATUS FOR THIS DRAFT AND REGENERATE THIS TEXT ***"
else:
return "a %s" % s
def generate_ballot_writeup(request, doc):
e = WriteupDocEvent()
e.type = "changed_ballot_writeup_text"
e.by = request.user.get_profile()
e.doc = doc
e.desc = u"Ballot writeup was generated"
e.text = unicode(render_to_string("idrfc/ballot_writeup.txt"))
e.save()
return e
def generate_last_call_announcement(request, doc):
status = full_intended_status(doc.intended_status).replace("a ", "").replace("an ", "")
expiration_date = date.today() + timedelta(days=14)
cc = []
if doc.group.acronym_id == Acronym.INDIVIDUAL_SUBMITTER:
group = "an individual submitter"
expiration_date += timedelta(days=14)
else:
group = "the %s WG (%s)" % (doc.group.name, doc.group.acronym)
cc.append(doc.group.ietfwg.email_address)
urls = []
docs = [d.document() for d in doc.idinternal.ballot_set()]
for d in docs:
d.full_status = full_intended_status(d.intended_status)
d.filled_title = textwrap.fill(d.title, width=70, subsequent_indent=" " * 3)
urls.append(settings.IDTRACKER_BASE_URL + d.idinternal.get_absolute_url())
iprs, docs = iprs_from_docs(docs)
if iprs:
ipr_links = [ urlreverse("ietf.ipr.views.show", kwargs=dict(ipr_id=i.ipr_id)) for i in iprs]
ipr_links = [ settings.IDTRACKER_BASE_URL+url if not url.startswith("http") else url for url in ipr_links ]
else:
ipr_links = None
return render_to_string("idrfc/last_call_announcement.txt",
dict(doc=doc,
doc_url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url(),
expiration_date=expiration_date.strftime("%Y-%m-%d"), #.strftime("%B %-d, %Y"),
cc=", ".join("<%s>" % e for e in cc),
group=group,
docs=docs,
urls=urls,
status=status,
impl_report="Draft" in status or "Full" in status,
ipr_links=ipr_links,
)
)
def generate_last_call_announcementREDESIGN(request, doc):
doc.full_status = full_intended_status(doc.intended_std_level)
status = doc.full_status.replace("a ", "").replace("an ", "")
expiration_date = date.today() + timedelta(days=14)
cc = []
if doc.group.type_id in ("individ", "area"):
group = "an individual submitter"
expiration_date += timedelta(days=14)
else:
group = "the %s WG (%s)" % (doc.group.name, doc.group.acronym)
if doc.group.list_email:
cc.append(doc.group.list_email)
doc.filled_title = textwrap.fill(doc.title, width=70, subsequent_indent=" " * 3)
iprs, _ = iprs_from_docs([ DocAlias.objects.get(name=doc.canonical_name()) ])
if iprs:
ipr_links = [ urlreverse("ietf.ipr.views.show", kwargs=dict(ipr_id=i.ipr_id)) for i in iprs]
ipr_links = [ settings.IDTRACKER_BASE_URL+url if not url.startswith("http") else url for url in ipr_links ]
else:
ipr_links = None
mail = render_to_string("idrfc/last_call_announcement.txt",
dict(doc=doc,
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url() + "ballot/",
expiration_date=expiration_date.strftime("%Y-%m-%d"), #.strftime("%B %-d, %Y"),
cc=", ".join("<%s>" % e for e in cc),
group=group,
docs=[ doc ],
urls=[ settings.IDTRACKER_BASE_URL + doc.get_absolute_url() ],
status=status,
impl_report="Draft" in status or "Full" in status,
ipr_links=ipr_links,
)
)
e = WriteupDocEvent()
e.type = "changed_last_call_text"
e.by = request.user.get_profile()
e.doc = doc
e.desc = u"Last call announcement was generated"
e.text = unicode(mail)
e.save()
return e
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
generate_last_call_announcement = generate_last_call_announcementREDESIGN
def generate_approval_mail(request, doc):
if doc.idinternal.cur_state_id in IDState.DO_NOT_PUBLISH_STATES or doc.idinternal.via_rfc_editor:
return generate_approval_mail_rfc_editor(request, doc)
status = full_intended_status(doc.intended_status).replace("a ", "").replace("an ", "")
if "an " in full_intended_status(doc.intended_status):
action_type = "Document"
else:
action_type = "Protocol"
cc = settings.DOC_APPROVAL_EMAIL_CC
if doc.group.ietfwg.group_type.type != "AG" and not doc.group.name.endswith("Working Group"):
doc.group.name_with_wg = doc.group.name + " Working Group"
cc.append("%s mailing list <%s>" % (doc.group.acronym, doc.group.ietfwg.email_address))
cc.append("%s chair <%s-chairs@tools.ietf.org>" % (doc.group.acronym, doc.group.acronym))
else:
doc.group.name_with_wg = doc.group.name
docs = [d.document() for d in doc.idinternal.ballot_set()]
for d in docs:
d.full_status = full_intended_status(d.intended_status)
d.filled_title = textwrap.fill(d.title, width=70, subsequent_indent=" " * 3)
if doc.group.acronym_id == Acronym.INDIVIDUAL_SUBMITTER:
if len(docs) > 1:
made_by = "These documents have been reviewed in the IETF but are not the products of an IETF Working Group."
else:
made_by = "This document has been reviewed in the IETF but is not the product of an IETF Working Group."
else:
if len(docs) > 1:
made_by = "These documents are products of the %s." % doc.group.name_with_wg
else:
made_by = "This document is the product of the %s." % doc.group.name_with_wg
director = doc.idinternal.job_owner
other_director = IESGLogin.objects.filter(person__in=[ad.person for ad in doc.group.ietfwg.area_directors()]).exclude(id=doc.idinternal.job_owner_id)
if doc.group.acronym_id != Acronym.INDIVIDUAL_SUBMITTER and other_director:
contacts = "The IESG contact persons are %s and %s." % (director, other_director[0])
else:
contacts = "The IESG contact person is %s." % director
doc_type = "RFC" if type(doc) == Rfc else "Internet Draft"
return render_to_string("idrfc/approval_mail.txt",
dict(doc=doc,
doc_url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url(),
cc=",\n ".join(cc),
docs=docs,
doc_type=doc_type,
made_by=made_by,
contacts=contacts,
status=status,
action_type=action_type,
)
)
def generate_approval_mail_rfc_editor(request, doc):
full_status = full_intended_status(doc.intended_status)
status = full_status.replace("a ", "").replace("an ", "")
disapproved = doc.idinternal.cur_state_id in IDState.DO_NOT_PUBLISH_STATES
doc_type = "RFC" if type(doc) == Rfc else "Internet Draft"
stream = get_stream_from_draft(doc)
to = ", ".join([u"%s <%s>" % x.email() for x in stream.get_chairs_for_document(doc) ])
if stream.name == "IRTF":
# also send to the IRSG
to += ", Internet Research Steering Group (IRSG) <irsg@irtf.org>"
return render_to_string("idrfc/approval_mail_rfc_editor.txt",
dict(doc=doc,
doc_url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url(),
doc_type=doc_type,
status=status,
full_status=full_status,
disapproved=disapproved,
to=to,
)
)
DO_NOT_PUBLISH_IESG_STATES = ("nopubadw", "nopubanw")
def generate_approval_mailREDESIGN(request, doc):
if doc.get_state_slug("draft-iesg") in DO_NOT_PUBLISH_IESG_STATES or doc.tags.filter(slug='via-rfc'):
mail = generate_approval_mail_rfc_editor(request, doc)
else:
mail = generate_approval_mail_approved(request, doc)
e = WriteupDocEvent()
e.type = "changed_ballot_approval_text"
e.by = request.user.get_profile()
e.doc = doc
e.desc = u"Ballot approval text was generated"
e.text = unicode(mail)
e.save()
return e
def generate_approval_mail_approved(request, doc):
doc.full_status = full_intended_status(doc.intended_std_level)
status = doc.full_status.replace("a ", "").replace("an ", "")
if doc.intended_std_level_id in ("std", "ds", "ps", "bcp"):
action_type = "Protocol"
else:
action_type = "Document"
cc = []
cc.extend(settings.DOC_APPROVAL_EMAIL_CC)
# the second check catches some area working groups (like
# Transport Area Working Group)
if doc.group.type_id not in ("area", "individ", "ag") and not doc.group.name.endswith("Working Group"):
doc.group.name_with_wg = doc.group.name + " Working Group"
if doc.group.list_email:
cc.append("%s mailing list <%s>" % (doc.group.acronym, doc.group.list_email))
cc.append("%s chair <%s-chairs@tools.ietf.org>" % (doc.group.acronym, doc.group.acronym))
else:
doc.group.name_with_wg = doc.group.name
doc.filled_title = textwrap.fill(doc.title, width=70, subsequent_indent=" " * 3)
if doc.group.type_id in ("individ", "area"):
made_by = "This document has been reviewed in the IETF but is not the product of an IETF Working Group."
else:
made_by = "This document is the product of the %s." % doc.group.name_with_wg
director = doc.ad
other_director = Person.objects.filter(role__group__role__person=director, role__group__role__name="ad").exclude(pk=director.pk)
if doc.group.type_id not in ("individ", "area") and other_director:
contacts = "The IESG contact persons are %s and %s." % (director.plain_name(), other_director[0].plain_name())
else:
contacts = "The IESG contact person is %s." % director.plain_name()
doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet Draft"
return render_to_string("idrfc/approval_mail.txt",
dict(doc=doc,
docs=[doc],
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
cc=",\n ".join(cc),
doc_type=doc_type,
made_by=made_by,
contacts=contacts,
status=status,
action_type=action_type,
)
)
def generate_approval_mail_rfc_editorREDESIGN(request, doc):
full_status = full_intended_status(doc.intended_std_level)
status = full_status.replace("a ", "").replace("an ", "")
disapproved = doc.get_state_slug("draft-iesg") in DO_NOT_PUBLISH_IESG_STATES
doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet Draft"
to = []
if doc.group.type_id != "individ":
for r in doc.group.role_set.filter(name="chair").select_related():
to.append(r.formatted_email())
if doc.stream_id in ("ise", "irtf"):
# include ISE/IRTF chairs
g = Group.objects.get(acronym=doc.stream_id)
for r in g.role_set.filter(name="chair").select_related():
to.append(r.formatted_email())
if doc.stream_id == "irtf":
# include IRSG
to.append('"Internet Research Steering Group" <irsg@irtf.org>')
return render_to_string("idrfc/approval_mail_rfc_editor.txt",
dict(doc=doc,
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
doc_type=doc_type,
status=status,
full_status=full_status,
disapproved=disapproved,
to=", ".join(to),
)
)
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
generate_approval_mail = generate_approval_mailREDESIGN
generate_approval_mail_rfc_editor = generate_approval_mail_rfc_editorREDESIGN
def send_last_call_request(request, doc, ballot):
to = "iesg-secretary@ietf.org"
frm = '"DraftTracker Mail System" <iesg-secretary@ietf.org>'
docs = [d.document() for d in doc.idinternal.ballot_set()]
send_mail(request, to, frm,
"Last Call: %s" % doc.file_tag(),
"idrfc/last_call_request.txt",
dict(docs=docs,
doc_url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
def send_last_call_requestREDESIGN(request, doc):
to = "iesg-secretary@ietf.org"
frm = '"DraftTracker Mail System" <iesg-secretary@ietf.org>'
send_mail(request, to, frm,
"Last Call: %s" % doc.file_tag(),
"idrfc/last_call_request.txt",
dict(docs=[doc],
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
send_last_call_request = send_last_call_requestREDESIGN
def email_resurrect_requested(request, doc, by):
to = "I-D Administrator <internet-drafts@ietf.org>"
frm = u"%s <%s>" % by.person.email()
send_mail(request, to, frm,
"I-D Resurrection Request",
"idrfc/resurrect_request_email.txt",
dict(doc=doc,
by=frm,
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
def email_resurrect_requestedREDESIGN(request, doc, by):
to = "I-D Administrator <internet-drafts@ietf.org>"
if by.role_set.filter(name="secr", group__acronym="secretariat"):
e = by.role_email("secr", group="secretariat")
else:
e = by.role_email("ad")
frm = e.address
send_mail(request, to, e.formatted_email(),
"I-D Resurrection Request",
"idrfc/resurrect_request_email.txt",
dict(doc=doc,
by=frm,
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
email_resurrect_requested = email_resurrect_requestedREDESIGN
def email_resurrection_completed(request, doc):
to = u"%s <%s>" % doc.idinternal.resurrect_requested_by.person.email()
frm = "I-D Administrator <internet-drafts-reply@ietf.org>"
send_mail(request, to, frm,
"I-D Resurrection Completed - %s" % doc.file_tag(),
"idrfc/resurrect_completed_email.txt",
dict(doc=doc,
by=frm,
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
def email_resurrection_completedREDESIGN(request, doc, requester):
if requester.role_set.filter(name="secr", group__acronym="secretariat"):
e = requester.role_email("secr", group="secretariat")
else:
e = requester.role_email("ad")
to = e.formatted_email()
frm = "I-D Administrator <internet-drafts-reply@ietf.org>"
send_mail(request, to, frm,
"I-D Resurrection Completed - %s" % doc.file_tag(),
"idrfc/resurrect_completed_email.txt",
dict(doc=doc,
by=frm,
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
email_resurrection_completed = email_resurrection_completedREDESIGN
def email_ballot_deferred(request, doc, by, telechat_date):
to = "iesg@ietf.org"
frm = "DraftTracker Mail System <iesg-secretary@ietf.org>"
send_mail(request, to, frm,
"IESG Deferred Ballot notification: %s" % doc.file_tag(),
"idrfc/ballot_deferred_email.txt",
dict(doc=doc,
by=by,
telechat_date=telechat_date))
def generate_issue_ballot_mail(request, doc):
full_status = full_intended_status(doc.intended_status)
status = full_status.replace("a ", "").replace("an ", "")
ads = IESGLogin.objects.filter(user_level__in=(IESGLogin.AD_LEVEL, IESGLogin.INACTIVE_AD_LEVEL)).order_by('user_level', 'last_name')
positions = dict((p.ad_id, p) for p in doc.idinternal.ballot.positions.all())
# format positions
ad_positions = []
for ad in ads:
p = positions.get(ad.id)
if not p:
continue
def formatted(val):
if val > 0:
return "[ X ]"
elif val < 0:
return "[ . ]"
else:
return "[ ]"
fmt = u"%-21s%-10s%-11s%-9s%-10s" % (
unicode(ad)[:21],
formatted(p.yes),
formatted(p.noobj),
formatted(p.discuss),
"[ R ]" if p.recuse else formatted(p.abstain),
)
ad_positions.append((ad, fmt))
active_ad_positions = filter(lambda t: t[0].user_level == IESGLogin.AD_LEVEL, ad_positions)
inactive_ad_positions = filter(lambda t: t[0].user_level == IESGLogin.INACTIVE_AD_LEVEL, ad_positions)
# arrange discusses and comments
ad_feedback = []
discusses = dict((p.ad_id, p) for p in doc.idinternal.ballot.discusses.all()
if p.ad_id in positions and positions[p.ad_id].discuss == 1)
comments = dict((p.ad_id, p) for p in doc.idinternal.ballot.comments.all())
for ad in ads:
d = discusses.get(ad.id)
c = comments.get(ad.id)
if ad.user_level != IESGLogin.AD_LEVEL or not (c or d):
continue
ad_feedback.append((ad, d, c))
return render_to_string("idrfc/issue_ballot_mail.txt",
dict(doc=doc,
doc_url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url(),
status=status,
active_ad_positions=active_ad_positions,
inactive_ad_positions=inactive_ad_positions,
ad_feedback=ad_feedback
)
)
def generate_issue_ballot_mailREDESIGN(request, doc):
full_status = full_intended_status(doc.intended_std_level)
status = full_status.replace("a ", "").replace("an ", "")
active_ads = Person.objects.filter(role__name="ad", role__group__state="active").distinct()
e = doc.latest_event(type="started_iesg_process")
positions = BallotPositionDocEvent.objects.filter(doc=doc, type="changed_ballot_position", time__gte=e.time).order_by("-time", '-id').select_related('ad')
# format positions and setup discusses and comments
ad_feedback = []
seen = set()
active_ad_positions = []
inactive_ad_positions = []
for p in positions:
if p.ad in seen:
continue
seen.add(p.ad)
def formatted(val):
if val:
return "[ X ]"
else:
return "[ ]"
fmt = u"%-21s%-10s%-11s%-9s%-10s" % (
p.ad.plain_name()[:21],
formatted(p.pos_id == "yes"),
formatted(p.pos_id == "noobj"),
formatted(p.pos_id == "discuss"),
"[ R ]" if p.pos_id == "recuse" else formatted(p.pos_id == "abstain"),
)
if p.ad in active_ads:
active_ad_positions.append(fmt)
if not p.pos_id == "discuss":
p.discuss = ""
if p.comment or p.discuss:
ad_feedback.append(p)
else:
inactive_ad_positions.append(fmt)
active_ad_positions.sort()
inactive_ad_positions.sort()
ad_feedback.sort(key=lambda p: p.ad.plain_name())
e = doc.latest_event(LastCallDocEvent, type="sent_last_call")
last_call_expires = e.expires if e else None
e = doc.latest_event(WriteupDocEvent, type="changed_ballot_approval_text")
approval_text = e.text if e else ""
e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
ballot_writeup = e.text if e else ""
# NOTE: according to Michelle Cotton <michelle.cotton@icann.org>
# (as per 2011-10-24) IANA is scraping these messages for
# information so would like to know beforehand if the format
# changes (perhaps RFC 6359 will change that)
return render_to_string("idrfc/issue_ballot_mailREDESIGN.txt",
dict(doc=doc,
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
status=status,
active_ad_positions=active_ad_positions,
inactive_ad_positions=inactive_ad_positions,
ad_feedback=ad_feedback,
last_call_expires=last_call_expires,
approval_text=approval_text,
ballot_writeup=ballot_writeup,
)
)
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
generate_issue_ballot_mail = generate_issue_ballot_mailREDESIGN
def email_iana(request, doc, to, msg):
# fix up message and send message to IANA for each in ballot set
import email
parsed_msg = email.message_from_string(msg.encode("utf-8"))
for i in doc.idinternal.ballot_set():
extra = {}
extra["Reply-To"] = "noreply@ietf.org"
extra["X-IETF-Draft-string"] = i.document().filename
extra["X-IETF-Draft-revision"] = i.document().revision_display()
send_mail_text(request, "To: IANA <%s>" % to,
parsed_msg["From"], parsed_msg["Subject"],
parsed_msg.get_payload(),
extra=extra,
bcc="fenner@research.att.com")
def email_ianaREDESIGN(request, doc, to, msg):
# fix up message and send it with extra info on doc in headers
import email
parsed_msg = email.message_from_string(msg.encode("utf-8"))
extra = {}
extra["Reply-To"] = "noreply@ietf.org"
extra["X-IETF-Draft-string"] = doc.name
extra["X-IETF-Draft-revision"] = doc.rev
send_mail_text(request, "IANA <%s>" % to,
parsed_msg["From"], parsed_msg["Subject"],
parsed_msg.get_payload(),
extra=extra,
bcc="fenner@research.att.com")
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
email_iana = email_ianaREDESIGN
def email_last_call_expired(doc):
text = "IETF Last Call has ended, and the state has been changed to\n%s." % doc.idinternal.cur_state.state
send_mail(None,
"iesg@ietf.org",
"DraftTracker Mail System <iesg-secretary@ietf.org>",
"Last Call Expired: %s" % doc.file_tag(),
"idrfc/change_notice.txt",
dict(text=text,
doc=doc,
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()),
cc="iesg-secretary@ietf.org")
def email_last_call_expiredREDESIGN(doc):
text = "IETF Last Call has ended, and the state has been changed to\n%s." % doc.get_state("draft-iesg").name
send_mail(None,
"iesg@ietf.org",
"DraftTracker Mail System <iesg-secretary@ietf.org>",
"Last Call Expired: %s" % doc.file_tag(),
"idrfc/change_notice.txt",
dict(text=text,
doc=doc,
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()),
cc="iesg-secretary@ietf.org")
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
email_last_call_expired = email_last_call_expiredREDESIGN