def email_milestone_review_reminder(group, grace_period=7): """Email reminders about milestones needing review to AD.""" if not group.ad: return False to = [group.ad.role_email("ad").formatted_email()] cc = [r.formatted_email() for r in group.role_set.filter(name="chair")] now = datetime.datetime.now() too_early = True milestones = group.groupmilestone_set.filter(state="review") for m in milestones: e = m.milestonegroupevent_set.filter( type="changed_milestone").order_by("-time")[:1] m.days_ready = (now - e[0].time).days if e else None if m.days_ready == None or m.days_ready >= grace_period: too_early = False if too_early: return False subject = u"Reminder: Milestone%s needing review in %s %s" % ( "s" if len(milestones) > 1 else "", group.acronym, group.type.name) send_mail( None, to, None, subject, "wginfo/reminder_milestones_need_review.txt", dict(group=group, milestones=milestones, url=settings.IDTRACKER_BASE_URL + urlreverse( "wg_edit_milestones", kwargs=dict(acronym=group.acronym)))) return True
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 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 email_ballot_deferred(request, doc, by, telechat_date): to = "*****@*****.**" frm = "DraftTracker Mail System <*****@*****.**>" 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 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 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 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 password_reset(request): success = False if request.method == 'POST': form = ResetPasswordForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] auth = django.core.signing.dumps(username, salt="password_reset") domain = Site.objects.get_current().domain subject = 'Confirm password reset at %s' % domain from_email = settings.DEFAULT_FROM_EMAIL to_email = username # form validation makes sure that this is an email address send_mail( request, to_email, from_email, subject, 'registration/password_reset_email.txt', { 'domain': domain, 'auth': auth, 'username': username, 'expire': settings.DAYS_TO_EXPIRE_REGISTRATION_LINK, }) success = True else: form = ResetPasswordForm() return render(request, 'registration/password_reset.html', { 'form': form, 'success': success, })
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 email_stream_changed(request, doc, old_stream, new_stream, text=""): """Email the change text to the notify group and to the stream chairs""" to = [x.strip() for x in doc.notify.replace(';', ',').split(',')] from ietf.group.models import Role as RedesignRole # These use comprehension to deal with conditions when there might be more than one chair listed for a stream if old_stream: to.extend([ x.person.formatted_email() for x in RedesignRole.objects.filter( group__acronym=old_stream.slug, name='chair') ]) if new_stream: to.extend([ x.person.formatted_email() for x in RedesignRole.objects.filter( group__acronym=new_stream.slug, name='chair') ]) 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(), "idrfc/stream_changed_email.txt", dict(text=text, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
def announce_new_versionREDESIGN(request, submission, draft, state_change_msg): to_email = [] if draft.notify: to_email.append(draft.notify) if draft.ad: to_email.append(draft.ad.role_email("ad").address) if draft.stream_id == "iab": to_email.append("IAB Stream <*****@*****.**>") elif draft.stream_id == "ise": to_email.append( "Independent Submission Editor <*****@*****.**>") elif draft.stream_id == "irtf": to_email.append("IRSG <*****@*****.**>") # if it has been sent to the RFC Editor, keep them in the loop if draft.get_state_slug("draft-iesg") in ("ann", "rfcqueue"): to_email.append("RFC Editor <*****@*****.**>") active_ballot = draft.active_ballot() if active_ballot: for ad, pos in active_ballot.active_ad_positions().iteritems(): if pos and pos.pos_id == "discuss": to_email.append(ad.role_email("ad").address) if to_email: subject = 'New Version Notification - %s-%s.txt' % ( submission.filename, submission.revision) 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 })
def send_mail_to_secretariat(self, request): subject = 'Manual Post Requested for %s' % self.draft.filename from_email = settings.IDSUBMIT_FROM_EMAIL to_email = settings.IDSUBMIT_TO_EMAIL cc = [self.cleaned_data['email']] cc += [i['email'][1] for i in self.authors] if self.draft.group_acronym: cc += [ i.person.email()[1] for i in self.draft.group_acronym.wgchair_set.all() ] cc = list(set(cc)) submitter = self.draft.tempidauthors_set.get(author_order=0) send_mail(request, to_email, from_email, subject, 'submit/manual_post_mail.txt', { 'form': self, 'draft': self.draft, 'url': settings.IDTRACKER_BASE_URL + urlreverse( 'draft_status', kwargs=dict(submission_id=self.draft.submission_id)), 'submitter': submitter }, cc=cc)
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_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 send_expire_warning_for_draft(doc): if doc.get_state_slug("draft-iesg") == "dead": return # don't warn about dead documents expiration = doc.expires.date() to = [e.formatted_email() for e in doc.authors.all() if not e.address.startswith("unknown-email")] cc = None if doc.group.type_id in ("wg", "rg"): cc = [e.formatted_email() for e in Email.objects.filter(role__group=doc.group, role__name="chair") if not e.address.startswith("unknown-email")] s = doc.get_state("draft-iesg") state = s.name if s else "I-D Exists" frm = None request = None if to or cc: send_mail(request, to, frm, u"Expiration impending: %s" % doc.file_tag(), "idrfc/expire_warning_email.txt", dict(doc=doc, state=state, expiration=expiration ), cc=cc)
def announce_new_versionREDESIGN(request, submission, draft, state_change_msg): to_email = [] if draft.notify: to_email.append(draft.notify) if draft.ad: to_email.append(draft.ad.role_email("ad").address) if draft.stream_id == "iab": to_email.append("IAB Stream <*****@*****.**>") elif draft.stream_id == "ise": to_email.append("Independent Submission Editor <*****@*****.**>") elif draft.stream_id == "irtf": to_email.append("IRSG <*****@*****.**>") # if it has been sent to the RFC Editor, keep them in the loop if draft.get_state_slug("draft-iesg") in ("ann", "rfcqueue"): to_email.append("RFC Editor <*****@*****.**>") active_ballot = draft.active_ballot() if active_ballot: for ad, pos in active_ballot.active_ad_positions().iteritems(): if pos and pos.pos_id == "discuss": to_email.append(ad.role_email("ad").address) if to_email: subject = 'New Version Notification - %s-%s.txt' % (submission.filename, submission.revision) 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})
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 email_reviewer_reminder(review_request): team = review_request.team deadline_days = (review_request.deadline - datetime.date.today()).days subject = "Reminder: deadline for review of {} in {} is {}".format( review_request.doc_id, team.acronym, review_request.deadline.isoformat()) import ietf.ietfauth.views overview_url = urlreverse(ietf.ietfauth.views.review_overview) import ietf.doc.views_review request_url = urlreverse(ietf.doc.views_review.review_request, kwargs={ "name": review_request.doc_id, "request_id": review_request.pk }) domain = Site.objects.get_current().domain settings = ReviewerSettings.objects.filter( person=review_request.reviewer.person, team=team).first() remind_days = settings.remind_days_before_deadline if settings else 0 send_mail( None, [review_request.reviewer.formatted_email()], None, subject, "review/reviewer_reminder.txt", { "reviewer_overview_url": "https://{}{}".format( domain, overview_url), "review_request_url": "https://{}{}".format(domain, request_url), "review_request": review_request, "deadline_days": deadline_days, "remind_days": remind_days, })
def notify_event_to_subscribers(event): significant = event.type == "changed_state" and event.state_id in [ s.pk for s in states_of_significant_change() ] subscriptions = EmailSubscription.objects.filter( community_list__in=community_lists_tracking_doc(event.doc)).distinct() if not significant: subscriptions = subscriptions.filter(notify_on="all") for sub in subscriptions.select_related("community_list", "email"): clist = sub.community_list subject = '%s notification: Changes to %s' % (clist.long_name(), event.doc.name) send_mail(None, sub.email.address, settings.DEFAULT_FROM_EMAIL, subject, 'community/notification_email.txt', context={ 'event': event, 'clist': clist, })
def send_expire_warning_for_draft(doc): if doc.get_state_slug("draft-iesg") == "dead": return # don't warn about dead documents expiration = doc.expires.date() to = [e.formatted_email() for e in doc.authors.all() if not e.address.startswith("unknown-email")] cc = None if doc.group.type_id in ("wg", "rg"): cc = [e.formatted_email() for e in Email.objects.filter(role__group=doc.group, role__name="chair") if not e.address.startswith("unknown-email")] s = doc.get_state("draft-iesg") state = s.name if s else "I-D Exists" frm = None request = None if to or cc: send_mail(request, to, frm, u"Expiration impending: %s" % doc.file_tag(), "doc/draft/expire_warning_email.txt", dict(doc=doc, state=state, expiration=expiration ), cc=cc)
def email_secretariat(request, group, type, text): to = ["*****@*****.**"] types = {} types['state'] = "State changed" types['state-notrev'] = "State changed to Not currently under review" types['state-infrev'] = "State changed to Informal review" types['state-intrev'] = "State changed to Internal review" types['state-extrev'] = "State changed to External review" types['state-iesgrev'] = "State changed to IESG review" types['state-approved'] = "Charter approved" types['conclude'] = "Request closing of group" subject = u"Regarding %s %s: %s" % (group.type.name, group.acronym, types[type]) text = strip_tags(text) send_mail( request, to, None, subject, "wgcharter/email_secretariat.txt", dict( text=text, group=group, group_url=settings.IDTRACKER_BASE_URL + urlreverse('wg_charter', kwargs=dict(acronym=group.acronym)), charter_url=settings.IDTRACKER_BASE_URL + urlreverse('doc_view', kwargs=dict(name=group.charter.name)), ))
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 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_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 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) to_email = sessions[0].requested_by.role_email('chair').address # TODO confirm list, remove requested_by from cc, add [email protected]? cc_list = get_cc_list(group) 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, to_email, from_email, subject, template, context, cc=cc_list) # 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_last_call_requestREDESIGN(request, doc): to = "*****@*****.**" frm = '"DraftTracker Mail System" <*****@*****.**>' 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()))
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 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 send_audio_import_warning(unmatched_files): '''Send email to interested parties that some audio files weren't matched to timeslots''' send_mail(request = None, to = settings.AUDIO_IMPORT_EMAIL, frm = "IETF Secretariat <*****@*****.**>", subject = "Audio file import warning", template = "proceedings/audio_import_warning.txt", context = dict(unmatched_files=unmatched_files), extra = {})
def email_resurrection_completed(request, doc): to = u"%s <%s>" % doc.idinternal.resurrect_requested_by.person.email() frm = "I-D Administrator <*****@*****.**>" 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_resurrect_requested(request, doc, by): to = "I-D Administrator <*****@*****.**>" 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 save(self, commit=True): # Create nomination nomination = super(NominateForm, 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'] comments = self.cleaned_data['comments'] confirmation = self.cleaned_data['confirmation'] 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 nominee = get_or_create_nominee(self.nomcom, candidate_name, candidate_email, position, author) # Complete nomination data feedback = Feedback.objects.create( nomcom=self.nomcom, comments=comments, type=FeedbackType.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 feedback.save() nomination.nominee = nominee nomination.comments = feedback 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 = author.address context = { 'nominee': nominee.email.person.name, 'comments': comments, 'position': position.name } path = nomcom_template_path + NOMINATION_RECEIPT_TEMPLATE send_mail(None, to_email, from_email, subject, path, context) return nomination
def email_ballot_deferred(request, doc, by, telechat_date): to = "*****@*****.**" frm = "DraftTracker Mail System <*****@*****.**>" 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 update_tags(request, obj, comment, person, set_tags=[], reset_tags=[], extra_notify=[]): if settings.USE_DB_REDESIGN_PROXY_CLASSES: doc = Document.objects.get(pk=obj.pk) save_document_in_history(doc) obj.tags.remove(*reset_tags) obj.tags.add(*set_tags) doc.time = datetime.datetime.now() e = DocEvent(type="changed_document", time=doc.time, by=person, doc=doc) l = [] if set_tags: l.append(u"Annotation tag%s %s set." % (pluralize(set_tags), ", ".join(x.name for x in set_tags))) if reset_tags: l.append(u"Annotation tag%s %s cleared." % (pluralize(reset_tags), ", ".join(x.name for x in reset_tags))) e.desc = " ".join(l) e.save() receivers = get_notification_receivers(doc, extra_notify) send_mail(request, receivers, settings.DEFAULT_FROM_EMAIL, u"Annotations tags changed for draft %s" % doc.name, 'ietfworkflows/annotation_tags_updated_mail.txt', dict(doc=doc, entry=dict(setted=", ".join(x.name for x in set_tags), unsetted=", ".join(x.name for x in reset_tags), change_date=doc.time, person=person, comment=comment))) return ctype = ContentType.objects.get_for_model(obj) setted = [] resetted = [] for tag in set_tags: if isinstance(tag, basestring): if set_tag_by_name(obj, tag): setted.append(tag) else: if set_tag(obj, tag): setted.append(tag.name) for tag in reset_tags: if isinstance(tag, basestring): if reset_tag_by_name(obj, tag): resetted.append(tag) else: if reset_tag(obj, tag): resetted.append(tag.name) entry = ObjectAnnotationTagHistoryEntry.objects.create( content_type=ctype, content_id=obj.pk, setted=','.join(setted), unsetted=','.join(resetted), date=datetime.datetime.now(), comment=comment, person=person) notify_tag_entry(entry, extra_notify)
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_last_call_request(request, doc): to = "*****@*****.**" 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()))
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_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_last_call_request(request, doc, ballot): to = "*****@*****.**" frm = '"DraftTracker Mail System" <*****@*****.**>' 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 email_resurrection_completed(request, doc): to = u"%s <%s>" % doc.idinternal.resurrect_requested_by.person.email() frm = "I-D Administrator <*****@*****.**>" 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 send_confirmation_mail(self, request): subject = 'Confirmation for Auto-Post of I-D %s' % self.draft.filename from_email = settings.IDSUBMIT_FROM_EMAIL to_email = self.draft.confirmation_email_list() confirm_url = settings.IDTRACKER_BASE_URL + urlreverse('draft_confirm', kwargs=dict(submission_id=self.draft.submission_id, auth_key=self.draft.auth_key)) status_url = settings.IDTRACKER_BASE_URL + urlreverse('draft_status_by_hash', kwargs=dict(submission_id=self.draft.submission_id, submission_hash=self.draft.get_hash())) send_mail(request, to_email, from_email, subject, 'submit/confirm_autopost.txt', { 'draft': self.draft, 'confirm_url': confirm_url, 'status_url': status_url })
def email_pulled_from_rfc_queue(request, doc, comment, prev_state, next_state): send_mail(request, ["IANA <*****@*****.**>", "RFC Editor <*****@*****.**>"], 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_automation_headers(doc))
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 email_resurrect_requested(request, doc, by): to = "I-D Administrator <*****@*****.**>" 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 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 request_full_url(request, submission): subject = 'Full URL for managing submission of draft %s' % submission.filename from_email = settings.IDSUBMIT_FROM_EMAIL to_email = submission.confirmation_email_list() url = settings.IDTRACKER_BASE_URL + urlreverse('draft_status_by_hash', kwargs=dict(submission_id=submission.submission_id, submission_hash=submission.get_hash())) send_mail(request, to_email, from_email, subject, 'submit/request_full_url.txt', {'submission': submission, 'url': url})
def email_state_changed(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(), "doc/mail/state_changed_email.txt", dict(text=text, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
def send_last_call_request(request, doc, ballot): to = "*****@*****.**" frm = '"DraftTracker Mail System" <*****@*****.**>' 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 email_ad_approved_doc(request, doc, text): to = "*****@*****.**" bcc = "*****@*****.**" frm = request.user.person.formatted_email() send_mail(request, to, frm, "Approved: %s" % doc.filename_with_rev(), "doc/mail/ad_approval_email.txt", dict(text=text, docname=doc.filename_with_rev()), bcc=bcc)
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_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 <*****@*****.**>", "%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_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, "*****@*****.**", "DraftTracker Mail System <*****@*****.**>", "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="*****@*****.**")
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 email_ad(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 <*****@*****.**>", "%s updated by %s" % (doc.file_tag(), changed_by.plain_name()), "doc/mail/change_notice.txt", dict(text=html_to_text(text), doc=doc, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
def send_full_url(request, submission): subject = 'Full URL for managing submission of draft %s' % submission.name from_email = settings.IDSUBMIT_FROM_EMAIL to_email = submission_confirmation_email_list(submission) url = settings.IDTRACKER_BASE_URL + urlreverse('submit_submission_status_by_hash', kwargs=dict(submission_id=submission.pk, access_token=submission.access_token())) send_mail(request, to_email, from_email, subject, 'submit/full_url.txt', { 'submission': submission, 'url': url, }) return to_email
def email_discrepancies(receivers): sections = find_discrepancies() send_mail(None, receivers, None, "Datatracker Sync Discrepancies Report", "sync/discrepancies_report.txt", dict(sections=sections, url=settings.IDTRACKER_BASE_URL + urlreverse("ietf.sync.views.discrepancies"), base_url=settings.IDTRACKER_BASE_URL, ))
def save(self, commit=True): # Create nomination nomination = super(NominateForm, 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'] comments = self.cleaned_data['comments'] confirmation = self.cleaned_data['confirmation'] 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 nominee = get_or_create_nominee(self.nomcom, candidate_name, candidate_email, position, author) # Complete nomination data feedback = Feedback.objects.create(nomcom=self.nomcom, comments=comments, type=FeedbackType.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 feedback.save() nomination.nominee = nominee nomination.comments = feedback 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 = author.address context = {'nominee': nominee.email.person.name, 'comments': comments, 'position': position.name} path = nomcom_template_path + NOMINATION_RECEIPT_TEMPLATE send_mail(None, to_email, from_email, subject, path, context) return nomination