def email_milestones_changed(request, group, changes, states): def wrap_up_email(addrs, text): subject = u"Milestones changed for %s %s" % (group.acronym, group.type.name) if re.search("Added .* for review, due", text): subject = u"Review Required - " + subject text = wordwrap(strip_tags(text), 78) text += "\n\n" text += u"URL: %s" % (settings.IDTRACKER_BASE_URL + group.about_url()) send_mail_text(request, addrs.to, None, subject, text, cc=addrs.cc) # first send to those who should see any edits (such as management and chairs) addrs = gather_address_lists('group_milestones_edited', group=group) if addrs.to or addrs.cc: wrap_up_email(addrs, u"\n\n".join(c + "." for c in changes)) # then send only the approved milestones to those who shouldn't be # bothered with milestones pending approval addrs = gather_address_lists('group_approved_milestones_edited', group=group) msg = u"\n\n".join(c + "." for c, s in zip(changes, states) if not s == "review") if (addrs.to or addrs.cc) and msg: wrap_up_email(addrs, msg)
def send_review_possibly_replaces_request(request, doc, submitter_info): addrs = gather_address_lists('doc_replacement_suggested', doc=doc) to = set(addrs.to) cc = set(addrs.cc) possibly_replaces = Document.objects.filter(name__in=[ alias.name for alias in doc.related_that_doc("possibly-replaces") ]) for other_doc in possibly_replaces: (other_to, other_cc) = gather_address_lists('doc_replacement_suggested', doc=other_doc) to.update(other_to) cc.update(other_cc) send_mail( request, list(to), settings.DEFAULT_FROM_EMAIL, 'Review of suggested possible replacements for %s-%s needed' % (doc.name, doc.rev), 'doc/mail/review_possibly_replaces_request.txt', dict(doc=doc, submitter_info=submitter_info, possibly_replaces=doc.related_that_doc("possibly-replaces"), review_url=settings.IDTRACKER_BASE_URL + urlreverse('ietf.doc.views_draft.review_possibly_replaces', kwargs={"name": doc.name})), cc=list(cc), )
def set_replaces_for_document(request, doc, new_replaces, by, email_subject, comment=""): addrs = gather_address_lists('doc_replacement_changed',doc=doc) to = set(addrs.to) cc = set(addrs.cc) relationship = DocRelationshipName.objects.get(slug='replaces') old_replaces = doc.related_that_doc("replaces") events = [] e = DocEvent(doc=doc, rev=doc.rev, by=by, type='changed_document') new_replaces_names = u", ".join(d.name for d in new_replaces) or u"None" old_replaces_names = u", ".join(d.name for d in old_replaces) or u"None" e.desc = u"This document now replaces <b>%s</b> instead of %s" % (new_replaces_names, old_replaces_names) e.save() events.append(e) if comment: events.append(DocEvent.objects.create(doc=doc, rev=doc.rev, by=by, type="added_comment", desc=comment)) for d in old_replaces: if d not in new_replaces: other_addrs = gather_address_lists('doc_replacement_changed',doc=d.document) to.update(other_addrs.to) cc.update(other_addrs.cc) RelatedDocument.objects.filter(source=doc, target=d, relationship=relationship).delete() if not RelatedDocument.objects.filter(target=d, relationship=relationship): s = 'active' if d.document.expires > datetime.datetime.now() else 'expired' d.document.set_state(State.objects.get(type='draft', slug=s)) for d in new_replaces: if d not in old_replaces: other_addrs = gather_address_lists('doc_replacement_changed',doc=d.document) to.update(other_addrs.to) cc.update(other_addrs.cc) RelatedDocument.objects.create(source=doc, target=d, relationship=relationship) d.document.set_state(State.objects.get(type='draft', slug='repl')) # make sure there are no lingering suggestions duplicating new replacements RelatedDocument.objects.filter(source=doc, target__in=new_replaces, relationship="possibly-replaces").delete() email_desc = e.desc.replace(", ", "\n ") if comment: email_desc += "\n" + comment from ietf.doc.mails import html_to_text send_mail(request, list(to), "DraftTracker Mail System <*****@*****.**>", email_subject, "doc/mail/change_notice.txt", dict(text=html_to_text(email_desc), doc=doc, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc=list(cc)) return events
def set_replaces_for_document(request, doc, new_replaces, by, email_subject, email_comment=""): addrs = gather_address_lists('doc_replacement_changed',doc=doc) to = set(addrs.to) cc = set(addrs.cc) relationship = DocRelationshipName.objects.get(slug='replaces') old_replaces = doc.related_that_doc("replaces") for d in old_replaces: if d not in new_replaces: other_addrs = gather_address_lists('doc_replacement_changed',doc=d.document) to.update(other_addrs.to) cc.update(other_addrs.cc) RelatedDocument.objects.filter(source=doc, target=d, relationship=relationship).delete() if not RelatedDocument.objects.filter(target=d, relationship=relationship): s = 'active' if d.document.expires > datetime.datetime.now() else 'expired' d.document.set_state(State.objects.get(type='draft', slug=s)) for d in new_replaces: if d not in old_replaces: other_addrs = gather_address_lists('doc_replacement_changed',doc=d.document) to.update(other_addrs.to) cc.update(other_addrs.cc) RelatedDocument.objects.create(source=doc, target=d, relationship=relationship) d.document.set_state(State.objects.get(type='draft', slug='repl')) e = DocEvent(doc=doc, by=by, type='changed_document') new_replaces_names = u", ".join(d.name for d in new_replaces) or u"None" old_replaces_names = u", ".join(d.name for d in old_replaces) or u"None" e.desc = u"This document now replaces <b>%s</b> instead of %s" % (new_replaces_names, old_replaces_names) e.save() # make sure there are no lingering suggestions duplicating new replacements RelatedDocument.objects.filter(source=doc, target__in=new_replaces, relationship="possibly-replaces").delete() email_desc = e.desc.replace(", ", "\n ") if email_comment: email_desc += "\n" + email_comment from ietf.doc.mails import html_to_text send_mail(request, list(to), "DraftTracker Mail System <*****@*****.**>", email_subject, "doc/mail/change_notice.txt", dict(text=html_to_text(email_desc), doc=doc, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc=list(cc))
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 = [] addrs = gather_address_lists('ipr_posting_confirmation',ipr=ipr).as_strings(compact=False) context = dict( to_email=addrs.to, to_name=ipr.submitter_name, cc_email=addrs.cc, 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(): messages.extend(get_document_emails(ipr)) # if Generic disclosure add message for General Area AD if isinstance(ipr, (GenericIprDisclosure,NonDocSpecificIprDisclosure)): role = Role.objects.filter(group__acronym='gen',name='ad').first() context = dict( to_email=role.email.address, to_name=role.person.name, ipr=ipr) text = render_to_string('ipr/posted_generic_email.txt',context) messages.append(text) return messages
def email_charter_internal_review(request, charter): addrs = gather_address_lists('charter_internal_review',doc=charter,group=charter.group) filename = '%s-%s.txt' % (charter.canonical_name(),charter.rev) charter_text = get_document_content( filename, os.path.join(settings.CHARTER_PATH,filename), split=False, markup=False, ) send_mail(request, addrs.to, settings.DEFAULT_FROM_EMAIL, 'Internal %s Review: %s (%s)'%(charter.group.type.name,charter.group.name,charter.group.acronym), 'doc/mail/charter_internal_review.txt', dict(charter=charter, charter_text=charter_text, review_type = "new" if charter.group.state_id == "proposed" else "recharter", charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(), chairs=charter.group.role_set.filter(name="chair"), secr=charter.group.role_set.filter(name="secr"), ads=charter.group.role_set.filter(name='ad').values_list('person__name',flat=True), techadv=charter.group.role_set.filter(name="techadv"), milestones=charter.group.groupmilestone_set.filter(state="charter"), ), cc=addrs.cc, extra={'Reply-To':"*****@*****.**"}, )
def get_announcement_initial(meeting, is_change=False): '''Returns a dictionary suitable to initialize an InterimAnnouncementForm (Message ModelForm)''' group = meeting.session_set.first().group in_person = bool(meeting.city) initial = {} addrs = gather_address_lists('interim_announced',group=group).as_strings() initial['to'] = addrs.to initial['cc'] = addrs.cc initial['frm'] = settings.INTERIM_ANNOUNCE_FROM_EMAIL if in_person: desc = 'Interim' else: desc = 'Virtual' if is_change: change = ' CHANGED' else: change = '' if group.type.slug == 'rg': type = 'RG' elif group.type.slug == 'wg' and group.state.slug == 'bof': type = 'BOF' else: type = 'WG' initial['subject'] = '{name} ({acronym}) {type} {desc} Meeting: {date}{change}'.format( name=group.name, acronym=group.acronym, type=type, desc=desc, date=meeting.date, change=change) body = render_to_string('meeting/interim_announcement.txt', locals()) initial['body'] = body return initial
def make_nomineeposition_for_newperson(nomcom, candidate_name, candidate_email, position, author): # This is expected to fail if called with an existing email address email = Email.objects.create(address=candidate_email) person = Person.objects.create(name=candidate_name, ascii=unidecode_name(candidate_name), address=candidate_email) email.person = person email.save() # send email to secretariat and nomcomchair to warn about the new person subject = 'New person is created' from_email = settings.NOMCOM_FROM_EMAIL.format(year=nomcom.year()) (to_email, cc) = gather_address_lists('nomination_created_person', nomcom=nomcom) context = { 'email': email.address, 'fullname': email.person.name, 'person_id': email.person.id, 'year': nomcom.year(), } nomcom_template_path = '/nomcom/%s/' % nomcom.group.acronym path = nomcom_template_path + INEXISTENT_PERSON_TEMPLATE send_mail(None, to_email, from_email, subject, path, context, cc=cc) return make_nomineeposition(nomcom, email.person, position, author)
def get_document_emails(ipr): """Returns a list of messages to inform document authors that a new IPR disclosure has been posted""" messages = [] for rel in ipr.iprdocrel_set.all(): doc = rel.document.document authors = doc.authors.all() if is_draft(doc): doc_info = 'Internet-Draft entitled "{}" ({})'.format(doc.title,doc.name) else: doc_info = 'RFC entitled "{}" (RFC{})'.format(doc.title,get_rfc_num(doc)) addrs = gather_address_lists('ipr_posted_on_doc',doc=doc).as_strings(compact=False) author_names = ', '.join([a.person.name for a in authors]) context = dict( doc_info=doc_info, to_email=addrs.to, to_name=author_names, cc_email=addrs.cc, ipr=ipr) text = render_to_string('ipr/posted_document_email.txt',context) messages.append(text) return messages
def send_interim_approval_request(meetings): """Sends an email to the secretariat, group chairs, and resposnible area director or the IRTF chair noting that approval has been requested for a new interim meeting. Takes a list of one or more meetings.""" group = meetings[0].session_set.first().group requester = meetings[0].session_set.first().requested_by (to_email, cc_list) = gather_address_lists('session_requested',group=group,person=requester) from_email = (settings.SESSION_REQUEST_FROM_EMAIL) subject = '{group} - New Interim Meeting Request'.format(group=group.acronym) template = 'meeting/interim_approval_request.txt' approval_urls = [] for meeting in meetings: url = settings.IDTRACKER_BASE_URL + reverse('ietf.meeting.views.interim_request_details', kwargs={'number': meeting.number}) approval_urls.append(url) if len(meetings) > 1: is_series = True else: is_series = False context = locals() send_mail(None, to_email, from_email, subject, template, context, cc=cc_list)
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 = [] addrs = gather_address_lists('ipr_posting_confirmation', ipr=ipr).as_strings(compact=False) context = dict(to_email=addrs.to, to_name=ipr.submitter_name, cc_email=addrs.cc, 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(): messages.extend(get_document_emails(ipr)) # if Generic disclosure add message for General Area AD if isinstance(ipr, (GenericIprDisclosure, NonDocSpecificIprDisclosure)): role = Role.objects.filter(group__acronym='gen', name='ad').first() context = dict(to_email=role.email.address, to_name=role.person.name, ipr=ipr) text = render_to_string('ipr/posted_generic_email.txt', context) messages.append(text) return messages
def default_review_text(group, charter, by): now = datetime.datetime.now() addrs=gather_address_lists('charter_external_review',group=group).as_strings(compact=False) e1 = WriteupDocEvent(doc=charter, by=by) e1.by = by e1.type = "changed_review_announcement" e1.desc = "%s review text was changed" % group.type.name e1.text = render_to_string("doc/charter/review_text.txt", dict(group=group, charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(), charter_text=read_charter_text(charter), chairs=group.role_set.filter(name="chair"), secr=group.role_set.filter(name="secr"), techadv=group.role_set.filter(name="techadv"), milestones=group.groupmilestone_set.filter(state="charter"), review_date=(datetime.date.today() + datetime.timedelta(weeks=1)).isoformat(), review_type="new" if group.state_id == "proposed" else "recharter", to=addrs.to, cc=addrs.cc, ) ) e1.time = now e1.save() e2 = WriteupDocEvent(doc=charter, by=by) e2.by = by e2.type = "changed_new_work_text" e2.desc = "%s review text was changed" % group.type.name e2.text = derive_new_work_text(e1.text,group) e2.time = now e2.save() return (e1,e2)
def send_sdo_reminder(sdo): roles = Role.objects.filter(name="liaiman", group=sdo) if not roles: # no manager to contact return None manager_role = roles[0] subject = 'Request for update of list of authorized individuals' (to_email, cc) = gather_address_lists('liaison_manager_update_request', group=sdo) name = manager_role.person.plain_name() authorized_list = Role.objects.filter( group=sdo, name='auth').select_related("person").distinct() body = render_to_string( 'liaisons/sdo_reminder.txt', dict( manager_name=name, sdo_name=sdo.name, individuals=authorized_list, )) send_mail_text(None, to_email, settings.LIAISON_UNIVERSAL_FROM, subject, body, cc=cc) return body
def generate_last_call_announcement(request, doc): expiration_date = datetime.date.today() + datetime.timedelta(days=14) if doc.group.type_id in ("individ", "area"): group = "an individual submitter" expiration_date += datetime.timedelta(days=14) else: group = "the %s %s (%s)" % (doc.group.name, doc.group.type.name, doc.group.acronym) doc.filled_title = textwrap.fill(doc.title, width=70, subsequent_indent=" " * 3) iprs = iprs_from_docs( related_docs(DocAlias.objects.get(name=doc.canonical_name()))) if iprs: ipr_links = [ urlreverse("ietf.ipr.views.show", kwargs=dict(id=i.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 downrefs = [ rel for rel in doc.relateddocument_set.all() if rel.is_downref() and not rel.is_approved_downref() ] addrs = gather_address_lists('last_call_issued', doc=doc).as_strings() mail = render_to_string( "doc/mail/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"), to=addrs.to, cc=addrs.cc, group=group, docs=[doc], urls=[settings.IDTRACKER_BASE_URL + doc.get_absolute_url()], ipr_links=ipr_links, downrefs=downrefs, )) e = WriteupDocEvent() e.type = "changed_last_call_text" e.by = request.user.person e.doc = doc e.rev = doc.rev e.desc = u"Last call announcement was generated" e.text = unicode(mail) # caller is responsible for saving, if necessary return e
def send_manual_post_request(request, submission, errors): subject = u'Manual Post Requested for %s' % submission.name from_email = settings.IDSUBMIT_FROM_EMAIL (to_email, cc) = gather_address_lists('sub_manual_post_requested', submission=submission) checker = DraftIdnitsChecker( options=[]) # don't use the default --submitcheck limitation file_name = os.path.join(settings.IDSUBMIT_STAGING_PATH, '%s-%s.txt' % (submission.name, submission.rev)) nitspass, nitsmsg, nitserr, nitswarn, nitsresult = checker.check_file_txt( file_name) send_mail(request, to_email, from_email, subject, 'submit/manual_post_request.txt', { 'submission': submission, 'url': settings.IDTRACKER_BASE_URL + urlreverse('ietf.submit.views.submission_status', kwargs=dict(submission_id=submission.pk)), 'errors': errors, 'idnits': nitsmsg, }, cc=cc)
def default_action_text(group, charter, by): if next_approved_revision(group.charter.rev) == "01": action = "Formed" else: action = "Rechartered" addrs = gather_address_lists('ballot_approved_charter',doc=charter,group=group).as_strings(compact=False) e = WriteupDocEvent(doc=charter, by=by) e.by = by e.type = "changed_action_announcement" e.desc = "%s action text was changed" % group.type.name e.text = render_to_string("doc/charter/action_text.txt", dict(group=group, charter_url=settings.IDTRACKER_BASE_URL + charter.get_absolute_url(), charter_text=read_charter_text(charter), chairs=group.role_set.filter(name="chair"), secr=group.role_set.filter(name="secr"), techadv=group.role_set.filter(name="techadv"), milestones=group.groupmilestone_set.filter(state="charter"), action_type=action, to=addrs.to, cc=addrs.cc, )) e.save() return e
def email_stream_changed(request, doc, old_stream, new_stream, text=""): """Email the change text to the notify group and to the stream chairs""" streams = [] if old_stream: streams.append(old_stream.slug) if new_stream: streams.append(new_stream.slug) (to, cc) = gather_address_lists('doc_stream_changed', doc=doc, streams=streams) if not to: return if not text: text = u"Stream changed to <b>%s</b> from %s" % (new_stream, old_stream) text = strip_tags(text) send_mail(request, to, None, "ID Tracker Stream Change Notice: %s" % doc.file_tag(), "doc/mail/stream_changed_email.txt", dict(text=text, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc=cc)
def send_submission_confirmation(request, submission, chair_notice=False): subject = 'Confirm submission of I-D %s' % submission.name from_email = settings.IDSUBMIT_FROM_EMAIL (to_email, cc) = gather_address_lists('sub_confirmation_requested', submission=submission) confirm_url = settings.IDTRACKER_BASE_URL + urlreverse( 'ietf.submit.views.confirm_submission', kwargs=dict(submission_id=submission.pk, auth_token=generate_access_token(submission.auth_key))) status_url = settings.IDTRACKER_BASE_URL + urlreverse( 'ietf.submit.views.submission_status', kwargs=dict(submission_id=submission.pk, access_token=submission.access_token())) send_mail(request, to_email, from_email, subject, 'submit/confirm_submission.txt', { 'submission': submission, 'confirm_url': confirm_url, 'status_url': status_url, 'chair_notice': chair_notice, }, cc=cc) all_addrs = to_email all_addrs.extend(cc) return all_addrs
def send_interim_cancellation_notice(meeting): """Sends an email that a scheduled interim meeting has been cancelled.""" session = meeting.session_set.first() group = session.group (to_email, cc_list) = gather_address_lists('interim_cancelled',group=group) from_email = settings.INTERIM_ANNOUNCE_FROM_EMAIL subject = '{group} ({acronym}) {type} Interim Meeting Cancelled (was {date})'.format( group=group.name, acronym=group.acronym, type=group.type.slug.upper(), date=meeting.date.strftime('%Y-%m-%d')) start_time = session.official_timeslotassignment().timeslot.time end_time = start_time + session.requested_duration if meeting.session_set.filter(status='sched').count() > 1: is_multi_day = True else: is_multi_day = False template = 'meeting/interim_cancellation_notice.txt' context = locals() send_mail(None, to_email, from_email, subject, template, context, cc=cc_list)
def default_approval_text(review): filename = "%s-%s.txt" % (review.canonical_name(), review.rev) current_text = get_document_content(filename, os.path.join(settings.CONFLICT_REVIEW_PATH, filename), split=False, markup=False) conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document if conflictdoc.stream_id=='ise': receiver = 'Independent Submissions Editor' elif conflictdoc.stream_id=='irtf': receiver = 'IRTF' else: receiver = 'recipient' addrs = gather_address_lists('ballot_approved_conflrev',doc=review).as_strings(compact=False) text = render_to_string("doc/conflict_review/approval_text.txt", dict(review=review, review_url = settings.IDTRACKER_BASE_URL+review.get_absolute_url(), conflictdoc = conflictdoc, conflictdoc_url = settings.IDTRACKER_BASE_URL+conflictdoc.get_absolute_url(), receiver=receiver, approved_review = current_text, to = addrs.to, cc = addrs.cc, ) ) return text
def possibly_send_deadline_reminder(liaison): PREVIOUS_DAYS = { 14: 'in two weeks', 7: 'in one week', 4: 'in four days', 3: 'in three days', 2: 'in two days', 1: 'tomorrow', 0: 'today' } days_to_go = (liaison.deadline - datetime.date.today()).days if not (days_to_go < 0 or days_to_go in PREVIOUS_DAYS.keys()): return None # no reminder if days_to_go < 0: subject = '[Liaison OUT OF DATE] %s' % liaison.title days_msg = 'is out of date for %s days' % (-days_to_go) else: subject = '[Liaison deadline %s] %s' % (PREVIOUS_DAYS[days_to_go], liaison.title) days_msg = 'expires %s' % PREVIOUS_DAYS[days_to_go] from_email = settings.LIAISON_UNIVERSAL_FROM (to_email, cc) = gather_address_lists('liaison_deadline_soon',liaison=liaison) bcc = '*****@*****.**' body = render_to_string('liaisons/liaison_deadline_mail.txt', dict(liaison=liaison,days_msg=days_msg,)) send_mail_text(None, to_email, from_email, subject, body, cc=cc, bcc=bcc) return body
def default_approval_text(status_change,relateddoc): filename = "%s-%s.txt" % (status_change.canonical_name(), status_change.rev) current_text = get_document_content(filename, os.path.join(settings.STATUS_CHANGE_PATH, filename), split=False, markup=False) if relateddoc.target.document.std_level.slug in ('std','ps','ds','bcp',): action = "Protocol Action" else: action = "Document Action" addrs = gather_address_lists('ballot_approved_status_change',doc=status_change).as_strings(compact=False) text = render_to_string("doc/status_change/approval_text.txt", dict(status_change=status_change, status_change_url = settings.IDTRACKER_BASE_URL+status_change.get_absolute_url(), relateddoc= relateddoc, relateddoc_url = settings.IDTRACKER_BASE_URL+relateddoc.target.document.get_absolute_url(), approved_text = current_text, action=action, newstatus=newstatus(relateddoc), to=addrs.to, cc=addrs.cc, ) ) return text
def save(self, commit=True): # Create nomination nomination = super(NominateNewPersonForm, self).save(commit=False) nominator_email = self.cleaned_data.get('nominator_email', None) candidate_email = self.cleaned_data['candidate_email'] candidate_name = self.cleaned_data['candidate_name'] position = self.cleaned_data['position'] qualifications = self.cleaned_data['qualifications'] confirmation = self.cleaned_data.get('confirmation', False) share_nominator = self.cleaned_data['share_nominator'] nomcom_template_path = '/nomcom/%s/' % self.nomcom.group.acronym author = None if self.public: author = get_user_email(self.user) else: if nominator_email: emails = Email.objects.filter(address=nominator_email) author = emails and emails[0] or None ## This is where it should change - validation of the email field should fail if the email exists ## The function should become make_nominee_from_newperson) nominee = make_nomineeposition_for_newperson(self.nomcom, candidate_name, candidate_email, position, author) # Complete nomination data feedback = Feedback.objects.create(nomcom=self.nomcom, comments=qualifications, type=FeedbackTypeName.objects.get(slug='nomina'), user=self.user) feedback.positions.add(position) feedback.nominees.add(nominee) if author: nomination.nominator_email = author.address feedback.author = author.address feedback.save() nomination.nominee = nominee nomination.comments = feedback nomination.share_nominator = share_nominator nomination.user = self.user if commit: nomination.save() # send receipt email to nominator if confirmation: if author: subject = 'Nomination receipt' from_email = settings.NOMCOM_FROM_EMAIL.format(year=self.nomcom.year()) (to_email, cc) = gather_address_lists('nomination_receipt_requested',nominator=author.address) context = {'nominee': nominee.email.person.name, 'comments': qualifications, 'position': position.name, 'year': self.nomcom.year(), } path = nomcom_template_path + NOMINATION_RECEIPT_TEMPLATE send_mail(None, to_email, from_email, subject, path, context, cc=cc) return nomination
def email_personnel_change(request, group, text, changed_personnel): (to, cc) = gather_address_lists('group_personnel_change', group=group, changed_personnel=changed_personnel) full_subject = u"Personnel change for %s %s" % (group.acronym, group.type.name) send_mail_text(request, to, None, full_subject, text, cc=cc)
def get_document_emails(ipr): """Returns a list of messages to inform document authors that a new IPR disclosure has been posted""" messages = [] for rel in ipr.iprdocrel_set.all(): doc = rel.document.document if is_draft(doc): doc_info = 'Internet-Draft entitled "{}" ({})'.format( doc.title, doc.name) else: doc_info = 'RFC entitled "{}" (RFC{})'.format( doc.title, get_rfc_num(doc)) addrs = gather_address_lists('ipr_posted_on_doc', doc=doc).as_strings(compact=False) author_names = ', '.join( a.person.name for a in doc.documentauthor_set.select_related("person")) context = dict(doc_info=doc_info, to_email=addrs.to, to_name=author_names, cc_email=addrs.cc, ipr=ipr) text = render_to_string('ipr/posted_document_email.txt', context) messages.append(text) return messages
def send_conflict_eval_email(request,review): msg = render_to_string("doc/eval_email.txt", dict(doc=review, doc_url = settings.IDTRACKER_BASE_URL+review.get_absolute_url(), ) ) addrs = gather_address_lists('ballot_issued',doc=review).as_strings() override = {'To':addrs.to} if addrs.cc: override['Cc']=addrs.cc send_mail_preformatted(request,msg,override=override) addrs = gather_address_lists('ballot_issued_iana',doc=review).as_strings() email_iana(request, review.relateddocument_set.get(relationship__slug='conflrev').target.document, addrs.to, msg, addrs.cc)
def send_liaison_by_email(request, liaison): subject = u'New Liaison Statement, "%s"' % (liaison.title) from_email = settings.LIAISON_UNIVERSAL_FROM (to_email, cc) = gather_address_lists('liaison_statement_posted',liaison=liaison) bcc = ['*****@*****.**'] body = render_to_string('liaisons/liaison_mail.txt', dict(liaison=liaison)) send_mail_text(request, to_email, from_email, subject, body, cc=", ".join(cc), bcc=", ".join(bcc))
def email_iesg_processing_document(request, doc, changes): addrs = gather_address_lists('doc_iesg_processing_started',doc=doc) send_mail(request, addrs.to, None, 'IESG processing details changed for %s' % doc.name, 'doc/mail/email_iesg_processing.txt', dict(doc=doc, changes=changes), cc=addrs.cc)
def save(self, commit=True): # Create nomination nomination = super(NominateNewPersonForm, self).save(commit=False) nominator_email = self.cleaned_data.get('nominator_email', None) candidate_email = self.cleaned_data['candidate_email'] candidate_name = self.cleaned_data['candidate_name'] position = self.cleaned_data['position'] qualifications = self.cleaned_data['qualifications'] confirmation = self.cleaned_data.get('confirmation', False) share_nominator = self.cleaned_data['share_nominator'] nomcom_template_path = '/nomcom/%s/' % self.nomcom.group.acronym author = None if self.public: author = get_user_email(self.user) else: if nominator_email: emails = Email.objects.filter(address=nominator_email) author = emails and emails[0] or None ## This is where it should change - validation of the email field should fail if the email exists ## The function should become make_nominee_from_newperson) nominee = make_nomineeposition_for_newperson(self.nomcom, candidate_name, candidate_email, position, author) # Complete nomination data feedback = Feedback.objects.create(nomcom=self.nomcom, comments=qualifications, type=FeedbackTypeName.objects.get(slug='nomina'), user=self.user) feedback.positions.add(position) feedback.nominees.add(nominee) if author: nomination.nominator_email = author.address feedback.author = author.address feedback.save() nomination.nominee = nominee nomination.comments = feedback nomination.share_nominator = share_nominator nomination.user = self.user if commit: nomination.save() # send receipt email to nominator if confirmation: if author: subject = 'Nomination receipt' from_email = settings.NOMCOM_FROM_EMAIL (to_email, cc) = gather_address_lists('nomination_receipt_requested',nominator=author.address) context = {'nominee': nominee.email.person.name, 'comments': qualifications, 'position': position.name} path = nomcom_template_path + NOMINATION_RECEIPT_TEMPLATE send_mail(None, to_email, from_email, subject, path, context, cc=cc) return nomination
def save(self): primary_person = self.cleaned_data.get("primary_person") duplicate_persons = self.cleaned_data.get("duplicate_persons") subject = "Request to merge Person records" from_email = settings.NOMCOM_FROM_EMAIL.format(year=self.nomcom.year()) (to_email, cc) = gather_address_lists('person_merge_requested') context = {'primary_person':primary_person, 'duplicate_persons':duplicate_persons, 'year': self.nomcom.year(), } send_mail(None, to_email, from_email, subject, 'nomcom/merge_request.txt', context, cc=cc)
def send_manual_post_request(request, submission, errors): subject = u'Manual Post Requested for %s' % submission.name from_email = settings.IDSUBMIT_FROM_EMAIL (to_email,cc) = gather_address_lists('sub_manual_post_requested',submission=submission) send_mail(request, to_email, from_email, subject, 'submit/manual_post_request.txt', { 'submission': submission, 'url': settings.IDTRACKER_BASE_URL + urlreverse('submit_submission_status', kwargs=dict(submission_id=submission.pk)), 'errors': errors, }, cc=cc)
def notify_pending_by_email(request, liaison): '''Send mail requesting approval of pending liaison statement. Send mail to the intersection of approvers for all from_groups ''' subject = u'New Liaison Statement, "%s" needs your approval' % (liaison.title) from_email = settings.LIAISON_UNIVERSAL_FROM (to, cc) = gather_address_lists('liaison_approval_requested',liaison=liaison) body = render_to_string('liaisons/pending_liaison_mail.txt', dict(liaison=liaison)) send_mail_text(request, to, from_email, subject, body, cc=cc)
def email_iesg_processing_document(request, doc, changes): addrs = gather_address_lists('doc_iesg_processing_started', doc=doc) send_mail(request, addrs.to, None, 'IESG processing details changed for %s' % doc.name, 'doc/mail/email_iesg_processing.txt', dict(doc=doc, changes=changes), cc=addrs.cc)
def save(self): primary_person = self.cleaned_data.get("primary_person") duplicate_persons = self.cleaned_data.get("duplicate_persons") subject = "Request to merge Person records" from_email = settings.NOMCOM_FROM_EMAIL (to_email, cc) = gather_address_lists('person_merge_requested') context = {'primary_person':primary_person, 'duplicate_persons':duplicate_persons} send_mail(None, to_email, from_email, subject, 'nomcom/merge_request.txt', context, cc=cc)
def send_notifications(meeting, groups, person): ''' Send session scheduled email notifications for each group in groups. Person is the user who initiated this action, request.uesr.get_profile(). ''' session_info_template = '''{0} Session {1} ({2}) {3}, {4} {5} Room Name: {6} --------------------------------------------- ''' now = datetime.datetime.now() for group in groups: sessions = group.session_set.filter(meeting=meeting) addrs = gather_address_lists('session_scheduled',group=group,session=sessions[0]) from_email = ('"IETF Secretariat"','*****@*****.**') if len(sessions) == 1: subject = '%s - Requested session has been scheduled for IETF %s' % (group.acronym, meeting.number) else: subject = '%s - Requested sessions have been scheduled for IETF %s' % (group.acronym, meeting.number) template = 'meetings/session_schedule_notification.txt' # easier to populate template from timeslot perspective. assuming one-to-one timeslot-session count = 0 session_info = '' data = [ (s,get_timeslot(s)) for s in sessions ] data = [ (s,t) for s,t in data if t ] for s,t in data: count += 1 session_info += session_info_template.format(group.acronym, count, s.requested_duration, t.time.strftime('%A'), t.name, '%s-%s' % (t.time.strftime('%H%M'),(t.time + t.duration).strftime('%H%M')), t.location) # send email context = {} context['to_name'] = sessions[0].requested_by context['agenda_note'] = sessions[0].agenda_note context['session'] = get_initial_session(sessions) context['session_info'] = session_info context['group'] = group context['login'] = sessions[0].requested_by send_mail(None, addrs.to, from_email, subject, template, context, cc=addrs.cc) # create sent_notification event GroupEvent.objects.create(group=group,time=now,type='sent_notification', by=person,desc='sent scheduled notification for %s' % meeting)
def send_review_possibly_replaces_request(request, doc, submitter_info): addrs = gather_address_lists('doc_replacement_suggested',doc=doc) to = set(addrs.to) cc = set(addrs.cc) possibly_replaces = Document.objects.filter(name__in=[alias.name for alias in doc.related_that_doc("possibly-replaces")]) for other_doc in possibly_replaces: (other_to, other_cc) = gather_address_lists('doc_replacement_suggested',doc=other_doc) to.update(other_to) cc.update(other_cc) send_mail(request, list(to), settings.DEFAULT_FROM_EMAIL, 'Review of suggested possible replacements for %s-%s needed' % (doc.name, doc.rev), 'doc/mail/review_possibly_replaces_request.txt', dict(doc= doc, submitter_info=submitter_info, possibly_replaces=doc.related_that_doc("possibly-replaces"), review_url=settings.IDTRACKER_BASE_URL + urlreverse("doc_review_possibly_replaces", kwargs={ "name": doc.name })), cc=list(cc),)
def announce_new_version(request, submission, draft, state_change_msg): (to_email,cc) = gather_address_lists('sub_new_version',doc=draft,submission=submission) if to_email: subject = 'New Version Notification - %s-%s.txt' % (submission.name, submission.rev) from_email = settings.IDSUBMIT_ANNOUNCE_FROM_EMAIL send_mail(request, to_email, from_email, subject, 'submit/announce_new_version.txt', {'submission': submission, 'msg': state_change_msg}, cc=cc)
def email_resurrection_completed(request, doc, requester): (to, cc) = gather_address_lists('resurrection_completed',doc=doc) frm = "I-D Administrator <*****@*****.**>" send_mail(request, to, frm, "I-D Resurrection Completed - %s" % doc.file_tag(), "doc/mail/resurrect_completed_email.txt", dict(doc=doc, by=frm, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc=cc)
def derive_new_work_text(review_text,group): addrs= gather_address_lists('charter_external_review_new_work',group=group).as_strings() (m,_,_) = parse_preformatted(review_text, override={'To':addrs.to, 'Cc':addrs.cc, 'From':'The IESG <*****@*****.**>', 'Reply_to':'<*****@*****.**>'}) if not addrs.cc: del m['Cc'] return m.as_string()
def generate_issue_ballot_mail(request, doc, ballot): addrs=gather_address_lists('ballot_issued',doc=doc).as_strings() return render_to_string("doc/charter/issue_ballot_mail.txt", dict(doc=doc, doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), to = addrs.to, cc = addrs.cc, ) )
def send_status_change_eval_email(request,doc): msg = render_to_string("doc/eval_email.txt", dict(doc=doc, doc_url = settings.IDTRACKER_BASE_URL+doc.get_absolute_url(), ) ) addrs = gather_address_lists('ballot_issued',doc=doc) override = {'To':addrs.to } if addrs.cc: override['Cc'] = addrs.cc send_mail_preformatted(request,msg,override=override)
def send_last_call_request(request, doc): (to, cc) = gather_address_lists('last_call_requested',doc=doc) frm = '"DraftTracker Mail System" <*****@*****.**>' send_mail(request, to, frm, "Last Call: %s" % doc.file_tag(), "doc/mail/last_call_request.txt", dict(docs=[doc], doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), ), cc=cc)
def email_ballot_undeferred(request, doc, by, telechat_date): (to, cc) = gather_address_lists('ballot_deferred',doc=doc) frm = "DraftTracker Mail System <*****@*****.**>" send_mail(request, to, frm, "IESG Undeferred Ballot notification: %s" % doc.file_tag(), "doc/mail/ballot_deferred_email.txt", dict(doc=doc, by=by, action='undeferred', telechat_date=telechat_date), cc=cc)
def email(request, id): """Send an email regarding this disclosure""" ipr = get_object_or_404(IprDisclosureBase, id=id).get_child() if request.method == 'POST': button_text = request.POST.get('submit', '') if button_text == 'Cancel': return redirect("ipr_show", id=ipr.id) form = MessageModelForm(request.POST) if form.is_valid(): # create Message msg = Message.objects.create( by = request.user.person, subject = form.cleaned_data['subject'], frm = form.cleaned_data['frm'], to = form.cleaned_data['to'], cc = form.cleaned_data['cc'], bcc = form.cleaned_data['bcc'], reply_to = form.cleaned_data['reply_to'], body = form.cleaned_data['body'] ) # create IprEvent IprEvent.objects.create( type_id = 'msgout', by = request.user.person, disclosure = ipr, response_due = form.cleaned_data['response_due'], message = msg, ) # send email send_mail_message(None,msg) messages.success(request, 'Email sent.') return redirect('ipr_show', id=ipr.id) else: reply_to = get_reply_to() addrs = gather_address_lists('ipr_disclosure_followup',ipr=ipr).as_strings(compact=False) initial = { 'to': addrs.to, 'cc': addrs.cc, 'frm': settings.IPR_EMAIL_FROM, 'subject': 'Regarding {}'.format(ipr.title), 'reply_to': reply_to, } form = MessageModelForm(initial=initial) return render(request, "ipr/email.html", { 'ipr': ipr, 'form':form })
def generate_issue_ballot_mail(request, doc, ballot): addrs = gather_address_lists('ballot_issued', doc=doc).as_strings() return render_to_string( "doc/charter/issue_ballot_mail.txt", dict( doc=doc, doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), to=addrs.to, cc=addrs.cc, ))
def email_resurrection_completed(request, doc, requester): (to, cc) = gather_address_lists('resurrection_completed', doc=doc) frm = "I-D Administrator <*****@*****.**>" send_mail(request, to, frm, "I-D Resurrection Completed - %s" % doc.file_tag(), "doc/mail/resurrect_completed_email.txt", dict(doc=doc, by=frm, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc=cc)
def send_conflict_review_started_email(request, review): addrs = gather_address_lists('conflrev_requested',doc=review).as_strings(compact=False) msg = render_to_string("doc/conflict_review/review_started.txt", dict(frm = settings.DEFAULT_FROM_EMAIL, to = addrs.to, cc = addrs.cc, by = request.user.person, review = review, reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target.document, review_url = settings.IDTRACKER_BASE_URL+review.get_absolute_url(), ) ) if not has_role(request.user,"Secretariat"): send_mail_preformatted(request,msg) addrs = gather_address_lists('conflrev_requested_iana',doc=review).as_strings(compact=False) email_iana(request, review.relateddocument_set.get(relationship__slug='conflrev').target.document, addrs.to, msg, cc=addrs.cc)
def email_state_changed(request, doc, text, mailtrigger_id=None): (to,cc) = gather_address_lists(mailtrigger_id or 'doc_state_edited',doc=doc) if not to: return text = strip_tags(text) send_mail(request, to, None, "ID Tracker State Update Notice: %s" % doc.file_tag(), "doc/mail/state_changed_email.txt", dict(text=text, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc=cc)
def notify_pending_by_email(request, liaison): '''Send mail requesting approval of pending liaison statement. Send mail to the intersection of approvers for all from_groups ''' subject = u'New Liaison Statement, "%s" needs your approval' % ( liaison.title) from_email = settings.LIAISON_UNIVERSAL_FROM (to, cc) = gather_address_lists('liaison_approval_requested', liaison=liaison) body = render_to_string('liaisons/pending_liaison_mail.txt', dict(liaison=liaison)) send_mail_text(request, to, from_email, subject, body, cc=cc)
def send_status_change_eval_email(request, doc): msg = render_to_string( "doc/eval_email.txt", dict( doc=doc, doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), )) addrs = gather_address_lists('ballot_issued', doc=doc) override = {'To': addrs.to} if addrs.cc: override['Cc'] = addrs.cc send_mail_preformatted(request, msg, override=override)
def email_comment(request, doc, comment): (to, cc) = gather_address_lists('doc_added_comment',doc=doc) send_mail(request, to, None, "Comment added to %s history"%doc.name, "doc/mail/comment_added_email.txt", dict( comment=comment, doc=doc, by=request.user.person, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), ), cc = cc)
def send_notification(group,meeting,login,session,action): ''' This function generates email notifications for various session request activities. session argument is a dictionary of fields from the session request form action argument is a string [new|update]. ''' (to_email, cc_list) = gather_address_lists('session_requested',group=group,person=login) from_email = (settings.SESSION_REQUEST_FROM_EMAIL) subject = '%s - New Meeting Session Request for IETF %s' % (group.acronym, meeting.number) template = 'sreq/session_request_notification.txt' # send email context = {} context['session'] = session context['group'] = group context['meeting'] = meeting context['login'] = login context['header'] = 'A new' context['requester'] = get_requester_text(login,group) # update overrides if action == 'update': subject = '%s - Update to a Meeting Session Request for IETF %s' % (group.acronym, meeting.number) context['header'] = 'An update to a' # if third session requested approval is required # change headers TO=ADs, CC=session-request, submitter and cochairs if session.get('length_session3',None): context['session']['num_session'] = 3 (to_email, cc_list) = gather_address_lists('session_requested_long',group=group,person=login) subject = '%s - Request for meeting session approval for IETF %s' % (group.acronym, meeting.number) template = 'sreq/session_approval_notification.txt' #status_text = 'the %s Directors for approval' % group.parent send_mail(None, to_email, from_email, subject, template, context, cc=cc_list)
def send_notification(group,meeting,login,session,action): ''' This function generates email notifications for various session request activities. session argument is a dictionary of fields from the session request form action argument is a string [new|update]. ''' (to_email, cc_list) = gather_address_lists('session_requested',group=group,person=login) from_email = ('"IETF Meeting Session Request Tool"','*****@*****.**') subject = '%s - New Meeting Session Request for IETF %s' % (group.acronym, meeting.number) template = 'sreq/session_request_notification.txt' # send email context = {} context['session'] = session context['group'] = group context['meeting'] = meeting context['login'] = login context['header'] = 'A new' context['requester'] = get_requester_text(login,group) # update overrides if action == 'update': subject = '%s - Update to a Meeting Session Request for IETF %s' % (group.acronym, meeting.number) context['header'] = 'An update to a' # if third session requested approval is required # change headers TO=ADs, CC=session-request, submitter and cochairs if session.get('length_session3',None): context['session']['num_session'] = 3 (to_email, cc_list) = gather_address_lists('session_requested_long',group=group,person=login) subject = '%s - Request for meeting session approval for IETF %s' % (group.acronym, meeting.number) template = 'sreq/session_approval_notification.txt' #status_text = 'the %s Directors for approval' % group.parent send_mail(None, to_email, from_email, subject, template, context, cc=cc_list)
def derive_new_work_text(review_text, group): addrs = gather_address_lists('charter_external_review_new_work', group=group).as_strings() (m, _, _) = parse_preformatted(review_text, override={ 'To': addrs.to, 'Cc': addrs.cc, 'From': 'The IESG <*****@*****.**>', 'Reply_to': '<*****@*****.**>' }) if not addrs.cc: del m['Cc'] return smart_text(m.as_string())
def email_intended_status_changed(request, doc, text): (to,cc) = gather_address_lists('doc_intended_status_changed',doc=doc) if not to: return text = strip_tags(text) send_mail(request, to, None, "Intended Status for %s changed to %s" % (doc.file_tag(),doc.intended_std_level), "doc/mail/intended_status_changed_email.txt", dict(text=text, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc=cc)
def email_pulled_from_rfc_queue(request, doc, comment, prev_state, next_state): extra=extra_automation_headers(doc) addrs = gather_address_lists('doc_pulled_from_rfc_queue',doc=doc) extra['Cc'] = addrs.as_strings().cc send_mail(request, addrs.to , None, "%s changed state from %s to %s" % (doc.name, prev_state.name, next_state.name), "doc/mail/pulled_from_rfc_queue_email.txt", dict(doc=doc, prev_state=prev_state, next_state=next_state, comment=comment, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), extra=extra)
def email_ballot_undeferred(request, doc, by, telechat_date): (to, cc) = gather_address_lists('ballot_deferred', doc=doc) frm = "DraftTracker Mail System <*****@*****.**>" send_mail(request, to, frm, "IESG Undeferred Ballot notification: %s" % doc.file_tag(), "doc/mail/ballot_deferred_email.txt", dict(doc=doc, by=by, action='undeferred', telechat_date=telechat_date), cc=cc)
def email_update_telechat(request, doc, text): (to, cc) = gather_address_lists('doc_telechat_details_changed',doc=doc) if not to: return text = strip_tags(text) send_mail(request, to, None, "Telechat update notice: %s" % doc.file_tag(), "doc/mail/update_telechat.txt", dict(text=text, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc=cc)
def email(request, id): """Send an email regarding this disclosure""" ipr = get_object_or_404(IprDisclosureBase, id=id).get_child() if request.method == 'POST': button_text = request.POST.get('submit', '') if button_text == 'Cancel': return redirect("ietf.ipr.views.show", id=ipr.id) form = MessageModelForm(request.POST) if form.is_valid(): # create Message msg = Message.objects.create( by=request.user.person, subject=form.cleaned_data['subject'], frm=form.cleaned_data['frm'], to=form.cleaned_data['to'], cc=form.cleaned_data['cc'], bcc=form.cleaned_data['bcc'], reply_to=form.cleaned_data['reply_to'], body=form.cleaned_data['body']) # create IprEvent IprEvent.objects.create( type_id='msgout', by=request.user.person, disclosure=ipr, response_due=form.cleaned_data['response_due'], message=msg, ) # send email send_mail_message(None, msg) messages.success(request, 'Email sent.') return redirect('ietf.ipr.views.show', id=ipr.id) else: reply_to = get_reply_to() addrs = gather_address_lists('ipr_disclosure_followup', ipr=ipr).as_strings(compact=False) initial = { 'to': addrs.to, 'cc': addrs.cc, 'frm': settings.IPR_EMAIL_FROM, 'subject': u'Regarding {}'.format(ipr.title), 'reply_to': reply_to, } form = MessageModelForm(initial=initial) return render(request, "ipr/email.html", {'ipr': ipr, 'form': form})