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(), ) ) send_mail_preformatted(request,msg)
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(), )) send_mail_preformatted(request, msg)
def approve(request, name): """Approve this conflict review, setting the appropriate state and send the announcement to the right parties.""" review = get_object_or_404(Document, type="conflrev", name=name) if review.get_state('conflrev').slug not in ('appr-reqnopub-pend','appr-noprob-pend'): raise Http404 login = request.user.get_profile() if request.method == 'POST': form = AnnouncementForm(request.POST) if form.is_valid(): new_state_slug = 'appr-reqnopub-sent' if review.get_state('conflrev').slug=='appr-reqnopub-pend' else 'appr-noprob-sent' new_review_state = State.objects.get(used=True, type="conflrev", slug=new_state_slug) save_document_in_history(review) old_description = review.friendly_state() review.set_state(new_review_state) new_description = review.friendly_state() log_state_changed(request, review, login, new_description, old_description) close_open_ballots(review, login) e = DocEvent(doc=review, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the conflict review response" e.save() review.time = e.time review.save() # send announcement send_mail_preformatted(request, form.cleaned_data['announcement_text']) c = DocEvent(type="added_comment", doc=review, by=login) c.desc = "The following approval message was sent\n"+form.cleaned_data['announcement_text'] c.save() return HttpResponseRedirect(review.get_absolute_url()) else: init = { "announcement_text" : default_approval_text(review) } form = AnnouncementForm(initial=init) return render_to_response('doc/conflict_review/approve.html', dict( review = review, conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document, form = form, ), context_instance=RequestContext(request))
def approve(request, name): """Approve this conflict review, setting the appropriate state and send the announcement to the right parties.""" review = get_object_or_404(Document, type="conflrev", name=name) if review.get_state('conflrev').slug not in ('appr-reqnopub-pend','appr-noprob-pend'): raise Http404 login = request.user.person if request.method == 'POST': form = AnnouncementForm(request.POST) if form.is_valid(): prev_state = review.get_state() events = [] new_state_slug = 'appr-reqnopub-sent' if prev_state.slug == 'appr-reqnopub-pend' else 'appr-noprob-sent' new_state = State.objects.get(used=True, type="conflrev", slug=new_state_slug) review.set_state(new_state) e = add_state_change_event(review, login, prev_state, new_state) events.append(e) close_open_ballots(review, login) e = DocEvent(doc=review, rev=review.rev, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the conflict review response" e.save() events.append(e) review.save_with_history(events) # send announcement send_mail_preformatted(request, form.cleaned_data['announcement_text']) c = DocEvent(type="added_comment", doc=review, rev=review.rev, by=login) c.desc = "The following approval message was sent\n"+form.cleaned_data['announcement_text'] c.save() return HttpResponseRedirect(review.get_absolute_url()) else: init = { "announcement_text" : default_approval_text(review) } form = AnnouncementForm(initial=init) return render(request, 'doc/conflict_review/approve.html', dict( review = review, conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document, form = form, ))
def save(self, *args, **kwargs): created = not self.pk super(Alias, self).save(*args, **kwargs) if created: if Alias.objects.filter(name=self.name).exclude(person=self.person).count() > 0 : msg = render_to_string('person/mail/possible_duplicates.txt', dict(name=self.name, persons=Person.objects.filter(alias__name=self.name), settings=settings )) send_mail_preformatted(None, msg)
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_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(), ) ) send_mail_preformatted(request,msg) email_iana(request, review.relateddocument_set.get(relationship__slug='conflrev').target.document, settings.IANA_EVAL_EMAIL, msg)
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_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(), )) send_mail_preformatted(request, msg) email_iana( request, review.relateddocument_set.get( relationship__slug='conflrev').target.document, '*****@*****.**', msg)
def save(self, *args, **kwargs): created = not self.pk super(Alias, self).save(*args, **kwargs) if created: if Alias.objects.filter(name=self.name).exclude( person=self.person).count() > 0: msg = render_to_string( 'person/mail/possible_duplicates.txt', dict(name=self.name, persons=Person.objects.filter( alias__name=self.name).distinct(), settings=settings)) send_mail_preformatted(None, msg)
def save(self, *args, **kwargs): created = not self.pk super(Person, self).save(*args, **kwargs) if created: if Person.objects.filter(name=self.name).count() > 1 : msg = render_to_string('person/mail/possible_duplicates.txt', dict(name=self.name, persons=Person.objects.filter(name=self.name), settings=settings )) send_mail_preformatted(None, msg) self.alias_set.get_or_create(name=self.name) if self.ascii and self.name != self.ascii: self.alias_set.get_or_create(name=self.ascii)
def send_conflict_review_started_email(request, review): msg = render_to_string("doc/conflict_review/review_started.txt", dict(frm = settings.DEFAULT_FROM_EMAIL, 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) email_iana(request, review.relateddocument_set.get(relationship__slug='conflrev').target.document, settings.IANA_EVAL_EMAIL, msg)
def announcement_text(request, name, ann): """Editing of announcement text""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group login = request.user.person if ann in ("action", "review"): existing = charter.latest_event(WriteupDocEvent, type="changed_%s_announcement" % ann) if not existing: if ann == "action": existing = default_action_text(group, charter, login) elif ann == "review": existing = default_review_text(group, charter, login) if not existing: raise Http404 form = AnnouncementTextForm(initial=dict(announcement_text=existing.text)) if request.method == 'POST': form = AnnouncementTextForm(request.POST) if "save_text" in request.POST and form.is_valid(): t = form.cleaned_data['announcement_text'] if t != existing.text: e = WriteupDocEvent(doc=charter, by=login) e.by = login e.type = "changed_%s_announcement" % ann e.desc = "%s %s text was changed" % (group.type.name, ann) e.text = t e.save() charter.time = e.time charter.save() if request.GET.get("next", "") == "approve": return redirect('charter_approve', name=charter.canonical_name()) return redirect('doc_writeup', name=charter.canonical_name()) if "regenerate_text" in request.POST: if ann == "action": e = default_action_text(group, charter, login) elif ann == "review": e = default_review_text(group, charter, login) # make sure form has the updated text form = AnnouncementTextForm(initial=dict(announcement_text=e.text)) if "send_text" in request.POST and form.is_valid(): parsed_msg = send_mail_preformatted(request, form.cleaned_data['announcement_text']) messages.success(request, "The email To: '%s' with Subject: '%s' has been sent." % (parsed_msg["To"],parsed_msg["Subject"],)) return redirect('doc_writeup', name=charter.name) return render_to_response('doc/charter/announcement_text.html', dict(charter=charter, announcement=ann, back_url=urlreverse("doc_writeup", kwargs=dict(name=charter.name)), announcement_text_form=form, ), context_instance=RequestContext(request))
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 save(self, *args, **kwargs): created = not self.pk super(Person, self).save(*args, **kwargs) if created: if Person.objects.filter(name=self.name).count() > 1: msg = render_to_string( 'person/mail/possible_duplicates.txt', dict(name=self.name, persons=Person.objects.filter(name=self.name), settings=settings)) send_mail_preformatted(None, msg) if not self.name in [ a.name for a in self.alias_set.filter(name=self.name) ]: self.alias_set.create(name=self.name) if self.ascii and self.name != self.ascii: if not self.ascii in [ a.name for a in self.alias_set.filter(name=self.ascii) ]: self.alias_set.create(name=self.ascii)
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 approve(request, name): """Approve this status change, setting the appropriate state and send the announcements to the right parties.""" status_change = get_object_or_404(Document, type="statchg", name=name) if status_change.get_state('statchg').slug not in ('appr-pend'): raise Http404 login = request.user.get_profile() AnnouncementFormSet = formset_factory(AnnouncementForm,extra=0) if request.method == 'POST': formset = AnnouncementFormSet(request.POST) if formset.is_valid(): save_document_in_history(status_change) old_description = status_change.friendly_state() status_change.set_state(State.objects.get(type='statchg', slug='appr-sent')) new_description = status_change.friendly_state() log_state_changed(request, status_change, login, new_description, old_description) close_open_ballots(status_change, login) e = DocEvent(doc=status_change, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the status change" e.save() status_change.time = e.time status_change.save() for form in formset.forms: send_mail_preformatted(request,form.cleaned_data['announcement_text']) c = DocEvent(type="added_comment", doc=status_change, by=login) c.desc = "The following approval message was sent\n"+form.cleaned_data['announcement_text'] c.save() for rel in status_change.relateddocument_set.filter(relationship__slug__in=RELATION_SLUGS): # Add a document event to each target c = DocEvent(type="added_comment", doc=rel.target.document, by=login) c.desc = "New status of %s approved by the IESG\n%s%s" % (newstatus(rel), settings.IDTRACKER_BASE_URL,reverse('doc_view', kwargs={'name': status_change.name})) c.save() return HttpResponseRedirect(status_change.get_absolute_url()) else: init = [] for rel in status_change.relateddocument_set.filter(relationship__slug__in=RELATION_SLUGS): init.append({"announcement_text" : default_approval_text(status_change,rel), "label": "Announcement text for %s to %s"%(rel.target.document.canonical_name(),newstatus(rel)), }) formset = AnnouncementFormSet(initial=init) for form in formset.forms: form.fields['announcement_text'].label=form.label return render_to_response('doc/status_change/approve.html', dict( doc = status_change, formset = formset, ), context_instance=RequestContext(request))
def approve(request, name): """Approve charter, changing state, fixing revision, copying file to final location.""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group login = request.user.get_profile() e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not e: announcement = default_action_text(group, charter, login).text else: announcement = e.text if request.method == 'POST': new_charter_state = State.objects.get(used=True, type="charter", slug="approved") prev_charter_state = charter.get_state() save_document_in_history(charter) charter.set_state(new_charter_state) close_open_ballots(charter, login) # approve e = DocEvent(doc=charter, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the charter" e.save() change_description = e.desc new_state = GroupStateName.objects.get(slug="active") if group.state != new_state: save_group_in_history(group) prev_state = group.state group.state = new_state group.time = e.time group.save() # create an event for the wg state change, too e = ChangeStateGroupEvent(group=group, type="changed_state") e.time = group.time e.by = login e.state_id = "active" e.desc = "Charter approved, group active" e.save() change_description += " and %s state has been changed to %s" % (group.type.name, new_state.name) e = log_state_changed(request, charter, login, prev_charter_state) # according to spec, 00-02 becomes 01, so copy file and record new revision try: old = os.path.join(charter.get_file_path(), '%s-%s.txt' % (charter.canonical_name(), charter.rev)) new = os.path.join(charter.get_file_path(), '%s-%s.txt' % (charter.canonical_name(), next_approved_revision(charter.rev))) shutil.copy(old, new) except IOError: return HttpResponse("There was an error copying %s to %s" % ('%s-%s.txt' % (charter.canonical_name(), charter.rev), '%s-%s.txt' % (charter.canonical_name(), next_approved_revision(charter.rev)))) e = NewRevisionDocEvent(doc=charter, by=login, type="new_revision") e.rev = next_approved_revision(charter.rev) e.desc = "New version available: <b>%s-%s.txt</b>" % (charter.canonical_name(), e.rev) e.save() charter.rev = e.rev charter.time = e.time charter.save() email_secretariat(request, group, "state-%s" % new_charter_state.slug, change_description) # move milestones over milestones_to_delete = list(group.groupmilestone_set.filter(state__in=("active", "review"))) for m in group.groupmilestone_set.filter(state="charter"): # see if we got this milestone already (i.e. it was copied # verbatim to the charter) found = False for i, o in enumerate(milestones_to_delete): if o.desc == m.desc and o.due == m.due and set(o.docs.all()) == set(m.docs.all()): found = True break if found: # keep existing, whack charter milestone if not o.state_id == "active": save_milestone_in_history(o) o.state_id = "active" o.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Changed milestone \"%s\", set state to active from review" % o.desc, milestone=o) del milestones_to_delete[i] # don't generate a DocEvent for this, it's implicit in the approval event save_milestone_in_history(m) m.state_id = "deleted" m.save() else: # move charter milestone save_milestone_in_history(m) m.state_id = "active" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Added milestone \"%s\", due %s, from approved charter" % (m.desc, m.due), milestone=m) for m in milestones_to_delete: save_milestone_in_history(m) m.state_id = "deleted" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Deleted milestone \"%s\", not present in approved charter" % m.desc, milestone=m) # send announcement send_mail_preformatted(request, announcement) return HttpResponseRedirect(charter.get_absolute_url()) return render_to_response('wgcharter/approve.html', dict(charter=charter, announcement=announcement), context_instance=RequestContext(request))
def review_announcement_text(request, name): """Editing of review announcement text""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group by = request.user.person existing = charter.latest_event(WriteupDocEvent, type="changed_review_announcement") existing_new_work = charter.latest_event(WriteupDocEvent, type="changed_new_work_text") if not existing: (existing, existing_new_work) = default_review_text(group, charter, by) if not existing: raise Http404 if not existing_new_work: existing_new_work = WriteupDocEvent(doc=charter, rev=charter.rev) existing_new_work.by = by existing_new_work.type = "changed_new_work_text" existing_new_work.desc = "%s review text was changed" % group.type.name existing_new_work.text = derive_new_work_text(existing.text, group) existing_new_work.time = datetime.datetime.now() form = ReviewAnnouncementTextForm(initial=dict( announcement_text=existing.text, new_work_text=existing_new_work.text)) if request.method == 'POST': form = ReviewAnnouncementTextForm(request.POST) if "save_text" in request.POST and form.is_valid(): now = datetime.datetime.now() events = [] t = form.cleaned_data['announcement_text'] if t != existing.text: e = WriteupDocEvent(doc=charter, rev=charter.rev) e.by = by e.type = "changed_review_announcement" e.desc = "%s review text was changed" % (group.type.name) e.text = t e.time = now e.save() events.append(e) elif existing.pk is None: existing.save() events.append(existing) t = form.cleaned_data['new_work_text'] if t != existing_new_work.text: e = WriteupDocEvent(doc=charter, rev=charter.rev) e.by = by e.type = "changed_new_work_text" e.desc = "%s new work message text was changed" % ( group.type.name) e.text = t e.time = now e.save() elif existing_new_work.pk is None: existing_new_work.save() events.append(existing_new_work) if events: charter.save_with_history(events) if request.GET.get("next", "") == "approve": return redirect('ietf.doc.views_charter.approve', name=charter.canonical_name()) return redirect('ietf.doc.views_doc.document_writeup', name=charter.canonical_name()) if "regenerate_text" in request.POST: (existing, existing_new_work) = default_review_text(group, charter, by) existing.save() existing_new_work.save() form = ReviewAnnouncementTextForm( initial=dict(announcement_text=existing.text, new_work_text=existing_new_work.text)) if any(x in request.POST for x in ['send_annc_only', 'send_nw_only', 'send_both' ]) and form.is_valid(): if any(x in request.POST for x in ['send_annc_only', 'send_both']): parsed_msg = send_mail_preformatted( request, form.cleaned_data['announcement_text']) messages.success( request, "The email To: '%s' with Subject: '%s' has been sent." % ( parsed_msg["To"], parsed_msg["Subject"], )) if any(x in request.POST for x in ['send_nw_only', 'send_both']): parsed_msg = send_mail_preformatted( request, form.cleaned_data['new_work_text']) messages.success( request, "The email To: '%s' with Subject: '%s' has been sent." % ( parsed_msg["To"], parsed_msg["Subject"], )) return redirect('ietf.doc.views_doc.document_writeup', name=charter.name) return render( request, 'doc/charter/review_announcement_text.html', dict( charter=charter, back_url=urlreverse('ietf.doc.views_doc.document_writeup', kwargs=dict(name=charter.name)), announcement_text_form=form, ))
def approve(request, name): """Approve charter, changing state, fixing revision, copying file to final location.""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group login = request.user.get_profile() e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not e: announcement = default_action_text(group, charter, login).text else: announcement = e.text if request.method == 'POST': new_charter_state = State.objects.get(used=True, type="charter", slug="approved") prev_charter_state = charter.get_state() save_document_in_history(charter) charter.set_state(new_charter_state) close_open_ballots(charter, login) # approve e = DocEvent(doc=charter, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the charter" e.save() change_description = e.desc new_state = GroupStateName.objects.get(slug="active") if group.state != new_state: save_group_in_history(group) prev_state = group.state group.state = new_state group.time = e.time group.save() # create an event for the wg state change, too e = ChangeStateGroupEvent(group=group, type="changed_state") e.time = group.time e.by = login e.state_id = "active" e.desc = "Charter approved, group active" e.save() change_description += " and %s state has been changed to %s" % ( group.type.name, new_state.name) e = log_state_changed(request, charter, login, prev_charter_state) # according to spec, 00-02 becomes 01, so copy file and record new revision try: old = os.path.join( charter.get_file_path(), '%s-%s.txt' % (charter.canonical_name(), charter.rev)) new = os.path.join( charter.get_file_path(), '%s-%s.txt' % (charter.canonical_name(), next_approved_revision(charter.rev))) shutil.copy(old, new) except IOError: return HttpResponse( "There was an error copying %s to %s" % ('%s-%s.txt' % (charter.canonical_name(), charter.rev), '%s-%s.txt' % (charter.canonical_name(), next_approved_revision( charter.rev)))) e = NewRevisionDocEvent(doc=charter, by=login, type="new_revision") e.rev = next_approved_revision(charter.rev) e.desc = "New version available: <b>%s-%s.txt</b>" % ( charter.canonical_name(), e.rev) e.save() charter.rev = e.rev charter.time = e.time charter.save() email_secretariat(request, group, "state-%s" % new_charter_state.slug, change_description) # move milestones over milestones_to_delete = list( group.groupmilestone_set.filter(state__in=("active", "review"))) for m in group.groupmilestone_set.filter(state="charter"): # see if we got this milestone already (i.e. it was copied # verbatim to the charter) found = False for i, o in enumerate(milestones_to_delete): if o.desc == m.desc and o.due == m.due and set( o.docs.all()) == set(m.docs.all()): found = True break if found: # keep existing, whack charter milestone if not o.state_id == "active": save_milestone_in_history(o) o.state_id = "active" o.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc= "Changed milestone \"%s\", set state to active from review" % o.desc, milestone=o) del milestones_to_delete[i] # don't generate a DocEvent for this, it's implicit in the approval event save_milestone_in_history(m) m.state_id = "deleted" m.save() else: # move charter milestone save_milestone_in_history(m) m.state_id = "active" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Added milestone \"%s\", due %s, from approved charter" % (m.desc, m.due), milestone=m) for m in milestones_to_delete: save_milestone_in_history(m) m.state_id = "deleted" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Deleted milestone \"%s\", not present in approved charter" % m.desc, milestone=m) # send announcement send_mail_preformatted(request, announcement) return HttpResponseRedirect(charter.get_absolute_url()) return render_to_response('wgcharter/approve.html', dict(charter=charter, announcement=announcement), context_instance=RequestContext(request))
def ballot_writeupnotes(request, name): """Editing of ballot write-up and notes""" charter = get_object_or_404(Document, type="charter", name=name) ballot = charter.latest_event(BallotDocEvent, type="created_ballot") if not ballot: raise Http404 login = request.user.person approval = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") existing = charter.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") if not existing: existing = generate_ballot_writeup(request, charter) reissue = charter.latest_event(DocEvent, type="sent_ballot_announcement") form = BallotWriteupForm(initial=dict(ballot_writeup=existing.text)) if request.method == 'POST' and ("save_ballot_writeup" in request.POST or "send_ballot" in request.POST): form = BallotWriteupForm(request.POST) if form.is_valid(): t = form.cleaned_data["ballot_writeup"] if t != existing.text: e = WriteupDocEvent(doc=charter, by=login) e.by = login e.type = "changed_ballot_writeup_text" e.desc = "Ballot writeup was changed" e.text = t e.save() existing = e if "send_ballot" in request.POST and approval: if has_role(request.user, "Area Director") and not charter.latest_event(BallotPositionDocEvent, type="changed_ballot_position", ad=login, ballot=ballot): # sending the ballot counts as a yes pos = BallotPositionDocEvent(doc=charter, by=login) pos.type = "changed_ballot_position" pos.ad = login pos.pos_id = "yes" pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.plain_name()) pos.save() # Consider mailing this position to 'ballot_saved' msg = generate_issue_ballot_mail(request, charter, ballot) send_mail_preformatted(request, msg) e = DocEvent(doc=charter, by=login) e.by = login e.type = "sent_ballot_announcement" e.desc = "Ballot has been sent" e.save() return render_to_response('doc/charter/ballot_issued.html', dict(doc=charter, ), context_instance=RequestContext(request)) return render_to_response('doc/charter/ballot_writeupnotes.html', dict(charter=charter, ballot_issued=bool(charter.latest_event(type="sent_ballot_announcement")), ballot_writeup_form=form, reissue=reissue, approval=approval, ), context_instance=RequestContext(request))
def action_announcement_text(request, name): """Editing of action announcement text""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group by = request.user.person existing = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not existing: existing = default_action_text(group, charter, by) if not existing: raise Http404 form = ActionAnnouncementTextForm(initial=dict( announcement_text=existing.text)) if request.method == 'POST': form = ActionAnnouncementTextForm(request.POST) if "save_text" in request.POST and form.is_valid(): t = form.cleaned_data['announcement_text'] if t != existing.text: e = WriteupDocEvent(doc=charter, rev=charter.rev) e.by = by e.type = "changed_action_announcement" e.desc = "%s action text was changed" % group.type.name e.text = t e.save() elif existing.pk == None: existing.save() if request.GET.get("next", "") == "approve": return redirect('ietf.doc.views_charter.approve', name=charter.canonical_name()) return redirect('ietf.doc.views_doc.document_writeup', name=charter.canonical_name()) if "regenerate_text" in request.POST: e = default_action_text(group, charter, by) e.save() form = ActionAnnouncementTextForm(initial=dict( announcement_text=e.text)) if "send_text" in request.POST and form.is_valid(): parsed_msg = send_mail_preformatted( request, form.cleaned_data['announcement_text']) messages.success( request, "The email To: '%s' with Subject: '%s' has been sent." % ( parsed_msg["To"], parsed_msg["Subject"], )) return redirect('ietf.doc.views_doc.document_writeup', name=charter.name) return render( request, 'doc/charter/action_announcement_text.html', dict( charter=charter, back_url=urlreverse('ietf.doc.views_doc.document_writeup', kwargs=dict(name=charter.name)), announcement_text_form=form, ))
def ballot_writeupnotes(request, name): """Editing of ballot write-up and notes""" doc = get_object_or_404(Document, docalias__name=name) login = request.user.person existing = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") if not existing: existing = generate_ballot_writeup(request, doc) form = BallotWriteupForm(initial=dict(ballot_writeup=existing.text)) if request.method == 'POST' and "save_ballot_writeup" in request.POST or "issue_ballot" in request.POST: form = BallotWriteupForm(request.POST) if form.is_valid(): t = form.cleaned_data["ballot_writeup"] if t != existing.text: e = WriteupDocEvent(doc=doc, by=login) e.by = login e.type = "changed_ballot_writeup_text" e.desc = "Ballot writeup was changed" e.text = t e.save() if "issue_ballot" in request.POST: create_ballot_if_not_open(doc, login, "approve") ballot = doc.latest_event(BallotDocEvent, type="created_ballot") if has_role(request.user, "Area Director") and not doc.latest_event(BallotPositionDocEvent, ad=login, ballot=ballot): # sending the ballot counts as a yes pos = BallotPositionDocEvent(doc=doc, by=login) pos.ballot = ballot pos.type = "changed_ballot_position" pos.ad = login pos.pos_id = "yes" pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % (pos.pos.name, pos.ad.plain_name()) pos.save() approval = doc.latest_event(WriteupDocEvent, type="changed_ballot_approval_text") if not approval: approval = generate_approval_mail(request, doc) msg = generate_issue_ballot_mail(request, doc, ballot) send_mail_preformatted(request, msg) send_mail_preformatted(request, msg, extra=extra_automation_headers(doc), override={ "To": "IANA <%s>"%settings.IANA_EVAL_EMAIL, "CC": None, "Bcc": None , "Reply-To": None}) e = DocEvent(doc=doc, by=login) e.by = login e.type = "sent_ballot_announcement" e.desc = "Ballot has been issued" e.save() return render_to_response('doc/ballot/ballot_issued.html', dict(doc=doc, back_url=doc.get_absolute_url()), context_instance=RequestContext(request)) need_intended_status = "" if not doc.intended_std_level: need_intended_status = doc.file_tag() return render_to_response('doc/ballot/writeupnotes.html', dict(doc=doc, back_url=doc.get_absolute_url(), ballot_issued=bool(doc.latest_event(type="sent_ballot_announcement")), ballot_writeup_form=form, need_intended_status=need_intended_status, ), context_instance=RequestContext(request))
def ballot_writeupnotes(request, name): """Editing of ballot write-up and notes""" doc = get_object_or_404(InternetDraft, filename=name) if not doc.idinternal: raise Http404() login = IESGLogin.objects.get(login_name=request.user.username) try: ballot = doc.idinternal.ballot except BallotInfo.DoesNotExist: ballot = generate_ballot(request, doc) ballot_writeup_form = BallotWriteupForm(instance=ballot) if request.method == 'POST': if "save_ballot_writeup" in request.POST: ballot_writeup_form = BallotWriteupForm(request.POST, instance=ballot) if ballot_writeup_form.is_valid(): ballot.ballot_writeup = ballot_writeup_form.cleaned_data["ballot_writeup"] add_document_comment(request, doc, "Ballot writeup text changed") ballot.save() if "issue_ballot" in request.POST: ballot_writeup_form = BallotWriteupForm(request.POST, instance=ballot) approval_text_form = ApprovalTextForm(request.POST, instance=ballot) if ballot_writeup_form.is_valid() and approval_text_form.is_valid(): ballot.ballot_writeup = ballot_writeup_form.cleaned_data["ballot_writeup"] ballot.approval_text = approval_text_form.cleaned_data["approval_text"] ballot.active = True ballot.ballot_issued = True ballot.save() if not Position.objects.filter(ballot=ballot, ad=login): pos = Position() pos.ballot = ballot pos.ad = login pos.yes = 1 pos.noobj = pos.abstain = pos.approve = pos.discuss = pos.recuse = 0 pos.save() msg = generate_issue_ballot_mail(request, doc) send_mail_preformatted(request, msg) # email_iana(request, doc, '*****@*****.**', msg) doc.b_sent_date = date.today() doc.save() add_document_comment(request, doc, "Ballot has been issued") doc.idinternal.event_date = date.today() doc.idinternal.save() return render_to_response('idrfc/ballot_issued.html', dict(doc=doc, back_url=doc.idinternal.get_absolute_url()), context_instance=RequestContext(request)) doc.idinternal.event_date = date.today() doc.idinternal.save() docs_with_invalid_status = [d.document().file_tag() for d in doc.idinternal.ballot_set() if "None" in d.document().intended_status.intended_status or "Request" in d.document().intended_status.intended_status] need_intended_status = ", ".join(docs_with_invalid_status) return render_to_response('idrfc/ballot_writeupnotes.html', dict(doc=doc, ballot=ballot, ballot_writeup_form=ballot_writeup_form, need_intended_status=need_intended_status, ), context_instance=RequestContext(request))
def approve(request, name): """Approve charter, changing state, fixing revision, copying file to final location.""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group by = request.user.person e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not e: announcement = default_action_text(group, charter, by).text else: announcement = e.text if request.method == 'POST': new_charter_state = State.objects.get(used=True, type="charter", slug="approved") prev_charter_state = charter.get_state() charter.set_state(new_charter_state) close_open_ballots(charter, by) events = [] # approve e = DocEvent(doc=charter, rev=charter.rev, by=by) e.type = "iesg_approved" e.desc = "IESG has approved the charter" e.save() events.append(e) change_description = e.desc group_state_change_event = change_group_state_after_charter_approval( group, by) if group_state_change_event: change_description += " and group state has been changed to %s" % group.state.name e = add_state_change_event(charter, by, prev_charter_state, new_charter_state) if e: events.append(e) fix_charter_revision_after_approval(charter, by) charter.save_with_history(events) email_admin_re_charter( request, group, "Charter state changed to \"%s\"" % new_charter_state.name, change_description, 'charter_state_edit_admin_needed') # move milestones over milestones_to_delete = list( group.groupmilestone_set.filter(state__in=("active", "review"))) for m in group.groupmilestone_set.filter(state="charter"): # see if we got this milestone already (i.e. it was copied # verbatim to the charter) found = False for i, o in enumerate(milestones_to_delete): if o.desc == m.desc and o.due == m.due and set( o.docs.all()) == set(m.docs.all()): found = True break if found: # keep existing, whack charter milestone if not o.state_id == "active": save_milestone_in_history(o) o.state_id = "active" o.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=by, desc= "Changed milestone \"%s\", set state to active from review" % o.desc, milestone=o) del milestones_to_delete[i] # don't generate a DocEvent for this, it's implicit in the approval event save_milestone_in_history(m) m.state_id = "deleted" m.save() else: # move charter milestone save_milestone_in_history(m) m.state_id = "active" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=by, desc="Added milestone \"%s\", due %s, from approved charter" % (m.desc, m.due), milestone=m) for m in milestones_to_delete: save_milestone_in_history(m) m.state_id = "deleted" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=by, desc="Deleted milestone \"%s\", not present in approved charter" % m.desc, milestone=m) # send announcement send_mail_preformatted(request, announcement) return HttpResponseRedirect(charter.get_absolute_url()) return render(request, 'doc/charter/approve.html', dict(charter=charter, announcement=announcement))
def approve_ballot(request, name): """Approve ballot, sending out announcement, changing state.""" doc = get_object_or_404(InternetDraft, filename=name) if not doc.idinternal: raise Http404() login = IESGLogin.objects.get(login_name=request.user.username) ballot = doc.idinternal.ballot if "To: RFC Editor" in ballot.approval_text: action = "to_rfc_editor" elif "NOT be published" in ballot.approval_text: action = "do_not_publish" else: action = "to_announcement_list" announcement = ballot.approval_text + "\n\n" + ballot.ballot_writeup if request.method == 'POST': for i in doc.idinternal.ballot_set(): if action == "do_not_publish": new_state = IDState.DEAD else: new_state = IDState.APPROVED_ANNOUNCEMENT_SENT i.change_state(IDState.objects.get(document_state_id=new_state), None) if action == "do_not_publish": i.dnp = True i.dnp_date = date.today() i.noproblem = False if action == "to_rfc_editor": i.noproblem = True i.event_date = date.today() i.save() i.document().b_approve_date = date.today() i.document().save() if action == "do_not_publish": comment = "Do Not Publish note has been sent to RFC Editor" else: comment = "IESG has approved" comment += " and state has been changed to %s" % i.cur_state.state add_document_comment(request, i.document(), comment) email_owner(request, i.document(), i.job_owner, login, comment) email_state_changed(request, i.document(), strip_tags(comment)) send_mail_preformatted(request, announcement) ballot.an_sent = True ballot.an_sent_date = date.today() ballot.an_sent_by = login ballot.save() if action == "to_announcement_list": email_iana(request, doc, "*****@*****.**", announcement) return HttpResponseRedirect(doc.idinternal.get_absolute_url()) return render_to_response('idrfc/approve_ballot.html', dict(doc=doc, action=action, announcement=announcement), context_instance=RequestContext(request))
def approve_ballot(request, name): """Approve ballot, sending out announcement, changing state.""" doc = get_object_or_404(Document, docalias__name=name) if not doc.get_state("draft-iesg"): raise Http404 login = request.user.person approval_mail_event = doc.latest_event(WriteupDocEvent, type="changed_ballot_approval_text") if not approval_mail_event: approval_mail_event = generate_approval_mail(request, doc) approval_text = approval_mail_event.text ballot_writeup_event = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") if not ballot_writeup_event: ballot_writeup_event = generate_ballot_writeup(request, doc) ballot_writeup = ballot_writeup_event.text error_duplicate_rfc_editor_note = False e = doc.latest_event(WriteupDocEvent, type="changed_rfc_editor_note_text") if e and (e.text != ""): if "RFC Editor Note" in ballot_writeup: error_duplicate_rfc_editor_note = True ballot_writeup += "\n\n" + e.text if error_duplicate_rfc_editor_note: return render(request, 'doc/draft/rfceditor_note_duplicate_error.html', {'doc': doc}) if "NOT be published" in approval_text: action = "do_not_publish" elif "To: RFC Editor" in approval_text: action = "to_rfc_editor" else: action = "to_announcement_list" # NOTE: according to Michelle Cotton <*****@*****.**> # (as per 2011-10-24) IANA is scraping these messages for # information so would like to know beforehand if the format # changes announcement = approval_text + "\n\n" + ballot_writeup if request.method == 'POST': if action == "do_not_publish": new_state = State.objects.get(used=True, type="draft-iesg", slug="dead") else: new_state = State.objects.get(used=True, type="draft-iesg", slug="ann") prev_state = doc.get_state("draft-iesg") prev_tags = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS) events = [] if approval_mail_event.pk == None: approval_mail_event.save() if ballot_writeup_event.pk == None: ballot_writeup_event.save() if new_state.slug == "ann" and new_state.slug != prev_state.slug and not request.POST.get( "skiprfceditorpost"): # start by notifying the RFC Editor import ietf.sync.rfceditor response, error = ietf.sync.rfceditor.post_approved_draft( settings.RFC_EDITOR_SYNC_NOTIFICATION_URL, doc.name) if error: return render( request, 'doc/draft/rfceditor_post_approved_draft_failed.html', dict(name=doc.name, response=response, error=error)) doc.set_state(new_state) doc.tags.remove(*prev_tags) # fixup document close_open_ballots(doc, login) e = DocEvent(doc=doc, rev=doc.rev, by=login) if action == "do_not_publish": e.type = "iesg_disapproved" e.desc = "Do Not Publish note has been sent to the RFC Editor" else: e.type = "iesg_approved" e.desc = "IESG has approved the document" e.save() events.append(e) e = add_state_change_event(doc, login, prev_state, new_state, prev_tags=prev_tags, new_tags=[]) if e: events.append(e) doc.save_with_history(events) # send announcement send_mail_preformatted(request, announcement) if action == "to_announcement_list": addrs = gather_address_lists( 'ballot_approved_ietf_stream_iana').as_strings(compact=False) send_mail_preformatted(request, announcement, extra=extra_automation_headers(doc), override={ "To": addrs.to, "CC": addrs.cc, "Bcc": None, "Reply-To": None }) msg = infer_message(announcement) msg.by = login msg.save() msg.related_docs.add(doc) return HttpResponseRedirect(doc.get_absolute_url()) return render(request, 'doc/ballot/approve_ballot.html', dict(doc=doc, action=action, announcement=announcement))
def review_announcement_text(request, name): """Editing of review announcement text""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group login = request.user.person existing = charter.latest_event(WriteupDocEvent, type="changed_review_announcement") existing_new_work = charter.latest_event(WriteupDocEvent, type="changed_new_work_text") if not existing: (existing, existing_new_work) = default_review_text(group, charter, login) if not existing: raise Http404 if not existing_new_work: existing_new_work = WriteupDocEvent(doc=charter, by=login) existing_new_work.by = login existing_new_work.type = "changed_new_work_text" existing_new_work.desc = "%s review text was changed" % group.type.name existing_new_work.text = derive_new_work_text(existing.text,group) existing_new_work.time = datetime.datetime.now() existing_new_work.save() new_work_text = existing_new_work.text form = ReviewAnnouncementTextForm(initial=dict(announcement_text=existing.text,new_work_text=new_work_text)) if request.method == 'POST': form = ReviewAnnouncementTextForm(request.POST) if "save_text" in request.POST and form.is_valid(): now = datetime.datetime.now() (e1, e2) = (None, None) t = form.cleaned_data['announcement_text'] if t != existing.text: e1 = WriteupDocEvent(doc=charter, by=login) e1.by = login e1.type = "changed_review_announcement" e1.desc = "%s review text was changed" % (group.type.name) e1.text = t e1.time = now e1.save() t = form.cleaned_data['new_work_text'] if t != new_work_text: e2 = WriteupDocEvent(doc=charter, by=login) e2.by = login e2.type = "changed_new_work_text" e2.desc = "%s new work message text was changed" % (group.type.name) e2.text = t e2.time = now e2.save() if e1 or e2: charter.time = now charter.save() if request.GET.get("next", "") == "approve": return redirect('charter_approve', name=charter.canonical_name()) return redirect('doc_writeup', name=charter.canonical_name()) if "regenerate_text" in request.POST: (e1, e2) = default_review_text(group, charter, login) form = ReviewAnnouncementTextForm(initial=dict(announcement_text=e1.text,new_work_text=e2.text)) if any([x in request.POST for x in ['send_annc_only','send_nw_only','send_both']]) and form.is_valid(): if any([x in request.POST for x in ['send_annc_only','send_both']]): parsed_msg = send_mail_preformatted(request, form.cleaned_data['announcement_text']) messages.success(request, "The email To: '%s' with Subject: '%s' has been sent." % (parsed_msg["To"],parsed_msg["Subject"],)) if any([x in request.POST for x in ['send_nw_only','send_both']]): parsed_msg = send_mail_preformatted(request, form.cleaned_data['new_work_text']) messages.success(request, "The email To: '%s' with Subject: '%s' has been sent." % (parsed_msg["To"],parsed_msg["Subject"],)) return redirect('doc_writeup', name=charter.name) return render_to_response('doc/charter/review_announcement_text.html', dict(charter=charter, back_url=urlreverse("doc_writeup", kwargs=dict(name=charter.name)), announcement_text_form=form, ), context_instance=RequestContext(request))
def announcement_text(request, name, ann): """Editing of announcement text""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group login = request.user.get_profile() if ann in ("action", "review"): existing = charter.latest_event(WriteupDocEvent, type="changed_%s_announcement" % ann) if not existing: if ann == "action": existing = default_action_text(group, charter, login) elif ann == "review": existing = default_review_text(group, charter, login) if not existing: raise Http404 form = AnnouncementTextForm(initial=dict(announcement_text=existing.text)) if request.method == 'POST': form = AnnouncementTextForm(request.POST) if "save_text" in request.POST and form.is_valid(): t = form.cleaned_data['announcement_text'] if t != existing.text: e = WriteupDocEvent(doc=charter, by=login) e.by = login e.type = "changed_%s_announcement" % ann e.desc = "%s %s text was changed" % (group.type.name, ann) e.text = t e.save() charter.time = e.time charter.save() if request.GET.get("next", "") == "approve": return redirect('charter_approve', name=charter.canonical_name()) return redirect('doc_writeup', name=charter.canonical_name()) if "regenerate_text" in request.POST: if ann == "action": e = default_action_text(group, charter, login) elif ann == "review": e = default_review_text(group, charter, login) # make sure form has the updated text form = AnnouncementTextForm(initial=dict(announcement_text=e.text)) if "send_text" in request.POST and form.is_valid(): parsed_msg = send_mail_preformatted( request, form.cleaned_data['announcement_text']) messages.success( request, "The email To: '%s' with Subjet: '%s' has been sent." % ( parsed_msg["To"], parsed_msg["Subject"], )) return redirect('doc_writeup', name=charter.name) return render_to_response('wgcharter/announcement_text.html', dict( charter=charter, announcement=ann, back_url=urlreverse( "doc_writeup", kwargs=dict(name=charter.name)), announcement_text_form=form, ), context_instance=RequestContext(request))
def approve_ballot(request, name): """Approve ballot, sending out announcement, changing state.""" doc = get_object_or_404(Document, docalias__name=name) if not doc.get_state("draft-iesg"): raise Http404() login = request.user.person e = doc.latest_event(WriteupDocEvent, type="changed_ballot_approval_text") if not e: e = generate_approval_mail(request, doc) approval_text = e.text e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") if not e: e = generate_ballot_writeup(request, doc) ballot_writeup = e.text if "NOT be published" in approval_text: action = "do_not_publish" elif "To: RFC Editor" in approval_text: action = "to_rfc_editor" else: action = "to_announcement_list" # NOTE: according to Michelle Cotton <*****@*****.**> # (as per 2011-10-24) IANA is scraping these messages for # information so would like to know beforehand if the format # changes announcement = approval_text + "\n\n" + ballot_writeup if request.method == 'POST': if action == "do_not_publish": new_state = State.objects.get(used=True, type="draft-iesg", slug="dead") else: new_state = State.objects.get(used=True, type="draft-iesg", slug="ann") prev_state = doc.get_state("draft-iesg") prev_tags = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS) if new_state.slug == "ann" and new_state.slug != prev_state.slug and not request.REQUEST.get("skiprfceditorpost"): # start by notifying the RFC Editor import ietf.sync.rfceditor response, error = ietf.sync.rfceditor.post_approved_draft(settings.RFC_EDITOR_SYNC_NOTIFICATION_URL, doc.name) if error: return render_to_response('doc/draft/rfceditor_post_approved_draft_failed.html', dict(name=doc.name, response=response, error=error), context_instance=RequestContext(request)) save_document_in_history(doc) doc.set_state(new_state) doc.tags.remove(*prev_tags) # fixup document close_open_ballots(doc, login) e = DocEvent(doc=doc, by=login) if action == "do_not_publish": e.type = "iesg_disapproved" e.desc = "Do Not Publish note has been sent to the RFC Editor" else: e.type = "iesg_approved" e.desc = "IESG has approved the document" e.save() change_description = e.desc + " and state has been changed to %s" % doc.get_state("draft-iesg").name e = add_state_change_event(doc, login, prev_state, new_state, prev_tags=prev_tags, new_tags=[]) doc.time = (e and e.time) or datetime.datetime.now() doc.save() email_state_changed(request, doc, change_description) email_ad(request, doc, doc.ad, login, change_description) # send announcement send_mail_preformatted(request, announcement) if action == "to_announcement_list": send_mail_preformatted(request, announcement, extra=extra_automation_headers(doc), override={ "To": "IANA <%s>"%settings.IANA_APPROVE_EMAIL, "CC": None, "Bcc": None, "Reply-To": None}) msg = infer_message(announcement) msg.by = login msg.save() msg.related_docs.add(doc) return HttpResponseRedirect(doc.get_absolute_url()) return render_to_response('doc/ballot/approve_ballot.html', dict(doc=doc, action=action, announcement=announcement), context_instance=RequestContext(request))
def ballot_writeupnotes(request, name): """Editing of ballot write-up and notes""" charter = get_object_or_404(Document, type="charter", name=name) ballot = charter.latest_event(BallotDocEvent, type="created_ballot") if not ballot: raise Http404() login = request.user.get_profile() approval = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") existing = charter.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") if not existing: existing = generate_ballot_writeup(request, charter) reissue = charter.latest_event(DocEvent, type="sent_ballot_announcement") form = BallotWriteupForm(initial=dict(ballot_writeup=existing.text)) if request.method == 'POST' and ("save_ballot_writeup" in request.POST or "send_ballot" in request.POST): form = BallotWriteupForm(request.POST) if form.is_valid(): t = form.cleaned_data["ballot_writeup"] if t != existing.text: e = WriteupDocEvent(doc=charter, by=login) e.by = login e.type = "changed_ballot_writeup_text" e.desc = "Ballot writeup was changed" e.text = t e.save() if "send_ballot" in request.POST and approval: if has_role(request.user, "Area Director") and not charter.latest_event( BallotPositionDocEvent, type="changed_ballot_position", ad=login, ballot=ballot): # sending the ballot counts as a yes pos = BallotPositionDocEvent(doc=charter, by=login) pos.type = "changed_ballot_position" pos.ad = login pos.pos_id = "yes" pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % ( pos.pos.name, pos.ad.plain_name()) pos.save() msg = generate_issue_ballot_mail(request, charter, ballot) send_mail_preformatted(request, msg) e = DocEvent(doc=charter, by=login) e.by = login e.type = "sent_ballot_announcement" e.desc = "Ballot has been sent" e.save() return render_to_response( 'wgcharter/ballot_issued.html', dict(doc=charter, ), context_instance=RequestContext(request)) return render_to_response( 'wgcharter/ballot_writeupnotes.html', dict( charter=charter, ballot_issued=bool( charter.latest_event(type="sent_ballot_announcement")), ballot_writeup_form=form, reissue=reissue, approval=approval, ), context_instance=RequestContext(request))
def make_last_call(request, name): """Make last call for Internet Draft, sending out announcement.""" doc = get_object_or_404(Document, docalias__name=name) if not (doc.get_state("draft-iesg") or doc.get_state("statchg")): raise Http404 login = request.user.person e = doc.latest_event(WriteupDocEvent, type="changed_last_call_text") if not e: if doc.type.slug != 'draft': raise Http404 e = generate_last_call_announcement(request, doc) announcement = e.text if request.method == 'POST': form = MakeLastCallForm(request.POST) if form.is_valid(): send_mail_preformatted(request, announcement) if doc.type.slug == 'draft': send_mail_preformatted(request, announcement, extra=extra_automation_headers(doc), override={ "To": "IANA <*****@*****.**>", "CC": None, "Bcc": None, "Reply-To": None}) msg = infer_message(announcement) msg.by = login msg.save() msg.related_docs.add(doc) save_document_in_history(doc) new_state = doc.get_state() prev_tags = new_tags = [] if doc.type.slug == 'draft': new_state = State.objects.get(used=True, type="draft-iesg", slug='lc') prev_tags = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS) elif doc.type.slug == 'statchg': new_state = State.objects.get(used=True, type="statchg", slug='in-lc') prev_state = doc.get_state(new_state.type_id) doc.set_state(new_state) doc.tags.remove(*prev_tags) e = add_state_change_event(doc, login, prev_state, new_state, prev_tags=prev_tags, new_tags=new_tags) doc.time = (e and e.time) or datetime.datetime.now() doc.save() change_description = "Last call has been made for %s and state has been changed to %s" % (doc.name, new_state.name) email_state_changed(request, doc, change_description) email_ad(request, doc, doc.ad, login, change_description) e = LastCallDocEvent(doc=doc, by=login) e.type = "sent_last_call" e.desc = "The following Last Call announcement was sent out:<br><br>" e.desc += announcement if form.cleaned_data['last_call_sent_date'] != e.time.date(): e.time = datetime.datetime.combine(form.cleaned_data['last_call_sent_date'], e.time.time()) e.expires = form.cleaned_data['last_call_expiration_date'] e.save() # update IANA Review state if doc.type.slug == 'draft': prev_state = doc.get_state("draft-iana-review") if not prev_state: next_state = State.objects.get(used=True, type="draft-iana-review", slug="need-rev") doc.set_state(next_state) add_state_change_event(doc, login, prev_state, next_state) return HttpResponseRedirect(doc.get_absolute_url()) else: initial = {} initial["last_call_sent_date"] = datetime.date.today() if doc.type.slug == 'draft': # This logic is repeated in the code that edits last call text - why? expire_days = 14 if doc.group.type_id in ("individ", "area"): expire_days = 28 templ = 'doc/draft/make_last_call.html' else: expire_days=28 templ = 'doc/status_change/make_last_call.html' initial["last_call_expiration_date"] = datetime.date.today() + datetime.timedelta(days=expire_days) form = MakeLastCallForm(initial=initial) return render_to_response(templ, dict(doc=doc, form=form, announcement=announcement, ), context_instance=RequestContext(request))
def ballot_writeupnotes(request, name): """Editing of ballot write-up and notes""" doc = get_object_or_404(Document, docalias__name=name) login = request.user.person existing = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text") if not existing: existing = generate_ballot_writeup(request, doc) form = BallotWriteupForm(initial=dict(ballot_writeup=existing.text)) if request.method == 'POST' and "save_ballot_writeup" in request.POST or "issue_ballot" in request.POST: form = BallotWriteupForm(request.POST) if form.is_valid(): t = form.cleaned_data["ballot_writeup"] if t != existing.text: e = WriteupDocEvent(doc=doc, rev=doc.rev, by=login) e.by = login e.type = "changed_ballot_writeup_text" e.desc = "Ballot writeup was changed" e.text = t e.save() elif existing.pk == None: existing.save() if "issue_ballot" in request.POST: create_ballot_if_not_open(doc, login, "approve") ballot = doc.latest_event(BallotDocEvent, type="created_ballot") if has_role( request.user, "Area Director") and not doc.latest_event( BallotPositionDocEvent, ad=login, ballot=ballot): # sending the ballot counts as a yes pos = BallotPositionDocEvent(doc=doc, rev=doc.rev, by=login) pos.ballot = ballot pos.type = "changed_ballot_position" pos.ad = login pos.pos_id = "yes" pos.desc = "[Ballot Position Update] New position, %s, has been recorded for %s" % ( pos.pos.name, pos.ad.plain_name()) pos.save() # Consider mailing this position to 'ballot_saved' approval = doc.latest_event( WriteupDocEvent, type="changed_ballot_approval_text") if not approval: approval = generate_approval_mail(request, doc) approval.save() msg = generate_issue_ballot_mail(request, doc, ballot) addrs = gather_address_lists('ballot_issued', doc=doc).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=doc).as_strings() override = { "To": "IANA <%s>" % settings.IANA_EVAL_EMAIL, "Bcc": None, "Reply-To": None } if addrs.cc: override['CC'] = addrs.cc send_mail_preformatted(request, msg, extra=extra_automation_headers(doc), override={ "To": "IANA <%s>" % settings.IANA_EVAL_EMAIL, "CC": None, "Bcc": None, "Reply-To": None }) e = DocEvent(doc=doc, rev=doc.rev, by=login) e.by = login e.type = "sent_ballot_announcement" e.desc = "Ballot has been issued" e.save() return render(request, 'doc/ballot/ballot_issued.html', dict(doc=doc, back_url=doc.get_absolute_url())) need_intended_status = "" if not doc.intended_std_level: need_intended_status = doc.file_tag() return render( request, 'doc/ballot/writeupnotes.html', dict( doc=doc, back_url=doc.get_absolute_url(), ballot_issued=bool( doc.latest_event(type="sent_ballot_announcement")), ballot_writeup_form=form, need_intended_status=need_intended_status, ))
def approve(request, name): """Approve charter, changing state, fixing revision, copying file to final location.""" charter = get_object_or_404(Document, type="charter", name=name) group = charter.group login = request.user.person e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement") if not e: announcement = default_action_text(group, charter, login).text else: announcement = e.text if request.method == 'POST': new_charter_state = State.objects.get(used=True, type="charter", slug="approved") prev_charter_state = charter.get_state() save_document_in_history(charter) charter.set_state(new_charter_state) close_open_ballots(charter, login) # approve e = DocEvent(doc=charter, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the charter" e.save() change_description = e.desc group_state_change_event = change_group_state_after_charter_approval(group, login) if group_state_change_event: change_description += " and group state has been changed to %s" % group.state.name add_state_change_event(charter, login, prev_charter_state, new_charter_state) fix_charter_revision_after_approval(charter, login) email_admin_re_charter(request, group, "Charter state changed to %s" % new_charter_state.name, change_description,'charter_state_edit_admin_needed') # move milestones over milestones_to_delete = list(group.groupmilestone_set.filter(state__in=("active", "review"))) for m in group.groupmilestone_set.filter(state="charter"): # see if we got this milestone already (i.e. it was copied # verbatim to the charter) found = False for i, o in enumerate(milestones_to_delete): if o.desc == m.desc and o.due == m.due and set(o.docs.all()) == set(m.docs.all()): found = True break if found: # keep existing, whack charter milestone if not o.state_id == "active": save_milestone_in_history(o) o.state_id = "active" o.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Changed milestone \"%s\", set state to active from review" % o.desc, milestone=o) del milestones_to_delete[i] # don't generate a DocEvent for this, it's implicit in the approval event save_milestone_in_history(m) m.state_id = "deleted" m.save() else: # move charter milestone save_milestone_in_history(m) m.state_id = "active" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Added milestone \"%s\", due %s, from approved charter" % (m.desc, m.due), milestone=m) for m in milestones_to_delete: save_milestone_in_history(m) m.state_id = "deleted" m.save() MilestoneGroupEvent.objects.create( group=group, type="changed_milestone", by=login, desc="Deleted milestone \"%s\", not present in approved charter" % m.desc, milestone=m) # send announcement send_mail_preformatted(request, announcement) return HttpResponseRedirect(charter.get_absolute_url()) return render_to_response('doc/charter/approve.html', dict(charter=charter, announcement=announcement), context_instance=RequestContext(request))
def make_last_call(request, name): """Make last call for Internet Draft, sending out announcement.""" doc = get_object_or_404(Document, docalias__name=name) if not (doc.get_state("draft-iesg") or doc.get_state("statchg")): raise Http404 login = request.user.person announcement_event = doc.latest_event(WriteupDocEvent, type="changed_last_call_text") if not announcement_event: if doc.type_id != 'draft': raise Http404 announcement_event = generate_last_call_announcement(request, doc) announcement = announcement_event.text if request.method == 'POST': form = MakeLastCallForm(request.POST) if form.is_valid(): if announcement_event.pk == None: announcement_event.save() send_mail_preformatted(request, announcement) if doc.type.slug == 'draft': addrs = gather_address_lists('last_call_issued_iana', doc=doc).as_strings(compact=False) send_mail_preformatted(request, announcement, extra=extra_automation_headers(doc), override={ "To": addrs.to, "CC": addrs.cc, "Bcc": None, "Reply-To": None }) msg = infer_message(announcement) msg.by = login msg.save() msg.related_docs.add(doc) new_state = doc.get_state() prev_tags = [] new_tags = [] events = [] if doc.type.slug == 'draft': new_state = State.objects.get(used=True, type="draft-iesg", slug='lc') prev_tags = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS) elif doc.type.slug == 'statchg': new_state = State.objects.get(used=True, type="statchg", slug='in-lc') prev_state = doc.get_state(new_state.type_id) doc.set_state(new_state) doc.tags.remove(*prev_tags) e = add_state_change_event(doc, login, prev_state, new_state, prev_tags=prev_tags, new_tags=new_tags) if e: events.append(e) expiration_date = form.cleaned_data['last_call_expiration_date'] e = LastCallDocEvent(doc=doc, rev=doc.rev, by=login) e.type = "sent_last_call" e.desc = "The following Last Call announcement was sent out (ends %s):<br><br>" % expiration_date e.desc += announcement if form.cleaned_data['last_call_sent_date'] != e.time.date(): e.time = datetime.datetime.combine( form.cleaned_data['last_call_sent_date'], e.time.time()) e.expires = expiration_date e.save() events.append(e) # update IANA Review state if doc.type.slug == 'draft': prev_state = doc.get_state("draft-iana-review") if not prev_state: next_state = State.objects.get(used=True, type="draft-iana-review", slug="need-rev") doc.set_state(next_state) e = add_state_change_event(doc, login, prev_state, next_state) if e: events.append(e) doc.save_with_history(events) return HttpResponseRedirect(doc.get_absolute_url()) else: initial = {} initial["last_call_sent_date"] = datetime.date.today() if doc.type.slug == 'draft': # This logic is repeated in the code that edits last call text - why? expire_days = 14 if doc.group.type_id in ("individ", "area"): expire_days = 28 templ = 'doc/draft/make_last_call.html' else: expire_days = 28 templ = 'doc/status_change/make_last_call.html' initial["last_call_expiration_date"] = datetime.date.today( ) + datetime.timedelta(days=expire_days) form = MakeLastCallForm(initial=initial) return render(request, templ, dict( doc=doc, form=form, announcement=announcement, ))
def approve(request, name): """Approve this status change, setting the appropriate state and send the announcements to the right parties.""" status_change = get_object_or_404(Document, type="statchg", name=name) if status_change.get_state('statchg').slug not in ('appr-pend'): raise Http404 login = request.user.person AnnouncementFormSet = formset_factory(AnnouncementForm, extra=0) if request.method == 'POST': formset = AnnouncementFormSet(request.POST) if formset.is_valid(): prev_state = status_change.get_state() new_state = State.objects.get(type='statchg', slug='appr-sent') status_change.set_state(new_state) events = [] events.append( add_state_change_event(status_change, login, prev_state, new_state)) close_open_ballots(status_change, login) e = DocEvent(doc=status_change, rev=status_change.rev, by=login) e.type = "iesg_approved" e.desc = "IESG has approved the status change" e.save() events.append(e) status_change.save_with_history(events) for form in formset.forms: send_mail_preformatted(request, form.cleaned_data['announcement_text']) c = DocEvent(type="added_comment", doc=status_change, rev=status_change.rev, by=login) c.desc = "The following approval message was sent\n" + form.cleaned_data[ 'announcement_text'] c.save() for rel in status_change.relateddocument_set.filter( relationship__slug__in=STATUSCHANGE_RELATIONS): # Add a document event to each target c = DocEvent(type="added_comment", doc=rel.target.document, rev=rel.target.document.rev, by=login) c.desc = "New status of %s approved by the IESG\n%s%s" % ( newstatus(rel), settings.IDTRACKER_BASE_URL, reverse('ietf.doc.views_doc.document_main', kwargs={'name': status_change.name})) c.save() return HttpResponseRedirect(status_change.get_absolute_url()) else: init = [] for rel in status_change.relateddocument_set.filter( relationship__slug__in=STATUSCHANGE_RELATIONS): init.append({ "announcement_text": default_approval_text(status_change, rel), "label": "Announcement text for %s to %s" % (rel.target.document.canonical_name(), newstatus(rel)), }) formset = AnnouncementFormSet(initial=init) for form in formset.forms: form.fields['announcement_text'].label = form.label return render(request, 'doc/status_change/approve.html', dict( doc=status_change, formset=formset, ))