Ejemplo n.º 1
0
def change_state(request, name, option=None):
    """Change state of an IESG review for IETF conflicts in other stream's documents, notifying parties as necessary
    and logging the change as a comment."""
    review = get_object_or_404(Document, type="conflrev", name=name)

    login = request.user.get_profile()

    if request.method == 'POST':
        form = ChangeStateForm(request.POST)
        if form.is_valid():
            clean = form.cleaned_data
            review_state = clean['review_state']
            comment = clean['comment'].rstrip()

            if comment:
                c = DocEvent(type="added_comment", doc=review, by=login)
                c.desc = comment
                c.save()

            if review_state != review.get_state():
                save_document_in_history(review)

                old_description = review.friendly_state()
                review.set_state(review_state)
                new_description = review.friendly_state()

                log_state_changed(request, review, login, new_description, old_description)

                review.time = datetime.datetime.now()
                review.save()

                if review_state.slug == "iesgeval":
                    create_ballot_if_not_open(review, login, "conflrev")
                    ballot = review.latest_event(BallotDocEvent, type="created_ballot")
                    if has_role(request.user, "Area Director") and not review.latest_event(BallotPositionDocEvent, ad=login, ballot=ballot, type="changed_ballot_position"):

                        # The AD putting a conflict review into iesgeval who doesn't already have a position is saying "yes"
                        pos = BallotPositionDocEvent(doc=review, 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()
                    send_conflict_eval_email(request,review)


            return redirect('doc_view', name=review.name)
    else:
        s = review.get_state()
        init = dict(review_state=s.pk if s else None)
        form = ChangeStateForm(initial=init)

    return render_to_response('doc/change_state.html',
                              dict(form=form,
                                   doc=review,
                                   login=login,
                                   help_url=reverse('help_conflict_review_states'),
                                   ),
                              context_instance=RequestContext(request))
Ejemplo n.º 2
0
    def test_approve(self):
        doc = Document.objects.get(name='status-change-imaginary-mid-review')
        url = urlreverse('status_change_approve', kwargs=dict(name=doc.name))

        login_testing_unauthorized(self, "secretary", url)

        # Some additional setup
        doc.relateddocument_set.create(
            target=DocAlias.objects.get(name='rfc9999'),
            relationship_id='tois')
        doc.relateddocument_set.create(
            target=DocAlias.objects.get(name='rfc9998'),
            relationship_id='tohist')
        create_ballot_if_not_open(doc, Person.objects.get(name="Sec Retary"),
                                  "statchg")
        doc.set_state(State.objects.get(slug='appr-pend', type='statchg'))
        doc.save()

        # get
        r = self.client.get(url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEquals(len(q('form.approve')), 1)
        # There should be two messages to edit
        self.assertEquals(q('input#id_form-TOTAL_FORMS').val(), '2')
        self.assertTrue('(rfc9999) to Internet Standard' in ''.join(
            wrap(r.content, 2**16)))
        self.assertTrue(
            '(rfc9998) to Historic' in ''.join(wrap(r.content, 2**16)))

        # submit
        messages_before = len(outbox)
        msg0 = default_approval_text(doc, doc.relateddocument_set.all()[0])
        msg1 = default_approval_text(doc, doc.relateddocument_set.all()[1])
        r = self.client.post(
            url, {
                'form-0-announcement_text': msg0,
                'form-1-announcement_text': msg1,
                'form-TOTAL_FORMS': '2',
                'form-INITIAL_FORMS': '2',
                'form-MAX_NUM_FORMS': ''
            })
        self.assertEquals(r.status_code, 302)

        doc = Document.objects.get(name='status-change-imaginary-mid-review')
        self.assertEquals(doc.get_state_slug(), 'appr-sent')
        self.assertFalse(doc.ballot_open("statchg"))

        self.assertEquals(len(outbox), messages_before + 2)
        self.assertTrue('Action:' in outbox[-1]['Subject'])
        self.assertTrue('(rfc9999) to Internet Standard' in ''.join(
            wrap(unicode(outbox[-1]) + unicode(outbox[-2]), 2**16)))
        self.assertTrue('(rfc9998) to Historic' in ''.join(
            wrap(unicode(outbox[-1]) + unicode(outbox[-2]), 2**16)))

        self.assertTrue(
            doc.latest_event(DocEvent, type="added_comment").desc.startswith(
                'The following approval message was sent'))
Ejemplo n.º 3
0
def change_state(request, name, option=None):
    """Change state of an IESG review for IETF conflicts in other stream's documents, notifying parties as necessary
    and logging the change as a comment."""
    review = get_object_or_404(Document, type="conflrev", name=name)

    login = request.user.person

    if request.method == 'POST':
        form = ChangeStateForm(request.POST)
        if form.is_valid():
            clean = form.cleaned_data
            new_state = clean['review_state']
            comment = clean['comment'].rstrip()

            if comment:
                c = DocEvent(type="added_comment", doc=review, rev=review.rev, by=login)
                c.desc = comment
                c.save()

            prev_state = review.get_state()
            if new_state != prev_state:
                events = []

                review.set_state(new_state)
                events.append(add_state_change_event(review, login, prev_state, new_state))

                review.save_with_history(events)

                if new_state.slug == "iesgeval":
                    create_ballot_if_not_open(review, login, "conflrev")
                    ballot = review.latest_event(BallotDocEvent, type="created_ballot")
                    if has_role(request.user, "Area Director") and not review.latest_event(BallotPositionDocEvent, ad=login, ballot=ballot, type="changed_ballot_position"):

                        # The AD putting a conflict review into iesgeval who doesn't already have a position is saying "yes"
                        pos = BallotPositionDocEvent(doc=review, rev=review.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 that position to 'ballot_saved'
                    send_conflict_eval_email(request,review)


            return redirect('ietf.doc.views_doc.document_main', name=review.name)
    else:
        s = review.get_state()
        init = dict(review_state=s.pk if s else None)
        form = ChangeStateForm(initial=init)

    return render(request, 'doc/change_state.html',
                              dict(form=form,
                                   doc=review,
                                   login=login,
                                   help_url=reverse('ietf.doc.views_help.state_help', kwargs=dict(type="conflict-review")),
                                   ))
Ejemplo n.º 4
0
def clear_ballot(request, name):
    """Clear all positions and discusses on every open ballot for a document."""
    doc = get_object_or_404(Document, name=name)
    if request.method == 'POST':
        by = request.user.person
        for t in BallotType.objects.filter(doc_type=doc.type_id):
            close_ballot(doc, by, t.slug)
            create_ballot_if_not_open(doc, by, t.slug)
        if doc.get_state('draft-iesg').slug == 'defer':
            do_undefer_ballot(request, doc)
        return redirect("ietf.doc.views_doc.document_main", name=doc.name)

    return render(request, 'doc/ballot/clear_ballot.html',
                  dict(doc=doc, back_url=doc.get_absolute_url()))
Ejemplo n.º 5
0
    def approve_test_helper(self, approve_type):

        doc = Document.objects.get(
            name='conflict-review-imaginary-irtf-submission')
        url = urlreverse('conflict_review_approve', kwargs=dict(name=doc.name))

        login_testing_unauthorized(self, "secretary", url)

        # Some additional setup
        create_ballot_if_not_open(doc, Person.objects.get(name="Sec Retary"),
                                  "conflrev")
        doc.set_state(
            State.objects.get(used=True,
                              slug=approve_type + '-pend',
                              type='conflrev'))
        doc.save()

        # get
        r = self.client.get(url)
        self.assertEquals(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEquals(len(q('form.approve')), 1)
        if approve_type == 'appr-noprob':
            self.assertTrue(
                'IESG has no problem' in ''.join(wrap(r.content, 2**16)))
        else:
            self.assertTrue(
                'NOT be published' in ''.join(wrap(r.content, 2**16)))

        # submit
        messages_before = len(outbox)
        r = self.client.post(
            url, dict(announcement_text=default_approval_text(doc)))
        self.assertEquals(r.status_code, 302)

        doc = Document.objects.get(
            name='conflict-review-imaginary-irtf-submission')
        self.assertEquals(doc.get_state_slug(), approve_type + '-sent')
        self.assertFalse(doc.ballot_open("conflrev"))

        self.assertEquals(len(outbox), messages_before + 1)
        self.assertTrue(
            'Results of IETF-conflict review' in outbox[-1]['Subject'])
        if approve_type == 'appr-noprob':
            self.assertTrue('IESG has no problem' in ''.join(
                wrap(unicode(outbox[-1]), 2**16)))
        else:
            self.assertTrue('NOT be published' in ''.join(
                wrap(unicode(outbox[-1]), 2**16)))
Ejemplo n.º 6
0
def clear_ballot(request, name):
    """Clear all positions and discusses on every open ballot for a document."""
    doc = get_object_or_404(Document, name=name)
    if request.method == 'POST':
        by = request.user.person
        for t in BallotType.objects.filter(doc_type=doc.type_id):
            close_ballot(doc, by, t.slug)
            create_ballot_if_not_open(doc, by, t.slug)
        if doc.get_state('draft-iesg').slug == 'defer':
            do_undefer_ballot(request,doc)
        return redirect("doc_view", name=doc.name)

    return render_to_response('doc/ballot/clear_ballot.html',
                              dict(doc=doc,
                                   back_url=doc.get_absolute_url()),
                              context_instance=RequestContext(request))
Ejemplo n.º 7
0
    def test_approve(self):
        doc = Document.objects.get(name='status-change-imaginary-mid-review')
        url = urlreverse('status_change_approve',kwargs=dict(name=doc.name))

        login_testing_unauthorized(self, "secretary", url)
        
        # Some additional setup
        doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois')
        doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist')
        create_ballot_if_not_open(doc,Person.objects.get(name="Sec Retary"),"statchg")
        doc.set_state(State.objects.get(slug='appr-pend',type='statchg'))
        doc.save()

        # get
        r = self.client.get(url)
        self.assertEqual(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEqual(len(q('[type=submit]:contains("Send announcement")')), 1)
        # There should be two messages to edit
        self.assertEqual(q('input#id_form-TOTAL_FORMS').val(),'2')
        self.assertTrue( '(rfc9999) to Internet Standard' in ''.join(wrap(r.content,2**16)))
        self.assertTrue( '(rfc9998) to Historic' in ''.join(wrap(r.content,2**16)))
        
        # submit
        messages_before = len(outbox)
        msg0=default_approval_text(doc,doc.relateddocument_set.all()[0])
        msg1=default_approval_text(doc,doc.relateddocument_set.all()[1])
        r = self.client.post(url,{'form-0-announcement_text':msg0,'form-1-announcement_text':msg1,'form-TOTAL_FORMS':'2','form-INITIAL_FORMS':'2','form-MAX_NUM_FORMS':''})
        self.assertEqual(r.status_code, 302)

        doc = Document.objects.get(name='status-change-imaginary-mid-review')
        self.assertEqual(doc.get_state_slug(),'appr-sent')
        self.assertFalse(doc.ballot_open("statchg"))
        
        self.assertEqual(len(outbox), messages_before + 2)
        self.assertTrue('Action:' in outbox[-1]['Subject'])
        self.assertTrue('ietf-announce' in outbox[-1]['To'])
        self.assertTrue('rfc-editor' in outbox[-1]['Cc'])
        self.assertTrue('(rfc9998) to Historic' in ''.join(wrap(unicode(outbox[-1])+unicode(outbox[-2]),2**16)))
        self.assertTrue('(rfc9999) to Internet Standard' in ''.join(wrap(unicode(outbox[-1])+unicode(outbox[-2]),2**16)))

        self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('The following approval message was sent'))       
Ejemplo n.º 8
0
    def approve_test_helper(self,approve_type):

        doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
        url = urlreverse('conflict_review_approve',kwargs=dict(name=doc.name))

        login_testing_unauthorized(self, "secretary", url)
        
        # Some additional setup
        create_ballot_if_not_open(doc,Person.objects.get(name="Sec Retary"),"conflrev")
        doc.set_state(State.objects.get(used=True, slug=approve_type+'-pend',type='conflrev'))
        doc.save()

        # get
        r = self.client.get(url)
        self.assertEqual(r.status_code, 200)
        q = PyQuery(r.content)
        self.assertEqual(len(q('[type=submit]:contains("Send announcement")')), 1)
        if approve_type == 'appr-noprob':
            self.assertTrue( 'IESG has no problem' in ''.join(wrap(r.content,2**16)))
        else:
            self.assertTrue( 'NOT be published' in ''.join(wrap(r.content,2**16)))
        
        # submit
        empty_outbox()
        r = self.client.post(url,dict(announcement_text=default_approval_text(doc)))
        self.assertEqual(r.status_code, 302)

        doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
        self.assertEqual(doc.get_state_slug(),approve_type+'-sent')
        self.assertFalse(doc.ballot_open("conflrev"))
        
        self.assertEqual(len(outbox), 1)
        self.assertTrue('Results of IETF-conflict review' in outbox[0]['Subject'])
        self.assertTrue('irtf-chair' in outbox[0]['To'])
        self.assertTrue('ietf-announce@' in outbox[0]['Cc'])
        self.assertTrue('iana@' in outbox[0]['Cc'])
        if approve_type == 'appr-noprob':
            self.assertTrue( 'IESG has no problem' in ''.join(wrap(unicode(outbox[0]),2**16)))
        else:
            self.assertTrue( 'NOT be published' in ''.join(wrap(unicode(outbox[0]),2**16)))
Ejemplo n.º 9
0
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,
        ))
Ejemplo n.º 10
0
def change_state(request, name, option=None):
    """Change state of an status-change document, notifying parties as necessary
       and logging the change as a comment."""
    status_change = get_object_or_404(Document, type="statchg", name=name)

    login = request.user.person

    if request.method == 'POST':
        form = ChangeStateForm(request.POST)
        if form.is_valid():
            clean = form.cleaned_data
            new_state = clean['new_state']
            comment = clean['comment'].rstrip()

            if comment:
                c = DocEvent(type="added_comment", doc=status_change, by=login)
                c.desc = comment
                c.save()

            prev_state = status_change.get_state()
            if new_state != prev_state:
                save_document_in_history(status_change)

                status_change.set_state(new_state)
                e = add_state_change_event(status_change, login, prev_state, new_state)

                status_change.time = e.time
                status_change.save()

                if new_state.slug == "iesgeval":
                    create_ballot_if_not_open(status_change, login, "statchg", e.time)
                    ballot = status_change.latest_event(BallotDocEvent, type="created_ballot")
                    if has_role(request.user, "Area Director") and not status_change.latest_event(BallotPositionDocEvent, ad=login, ballot=ballot, type="changed_ballot_position"):

                        # The AD putting a status change into iesgeval who doesn't already have a position is saying "yes"
                        pos = BallotPositionDocEvent(doc=status_change, 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()

                    send_status_change_eval_email(request,status_change)


                if new_state.slug == "lc-req":
                    request_last_call(request, status_change)
                    return render_to_response('doc/draft/last_call_requested.html',
                                              dict(doc=status_change,
                                                   url = status_change.get_absolute_url(),
                                                  ),
                                              context_instance=RequestContext(request))

            return redirect('doc_view', name=status_change.name)
    else:
        s = status_change.get_state()
        init = dict(new_state=s.pk if s else None,
                    type='statchg',
                    label='Status Change Evaluation State',
                   )
        form = ChangeStateForm(initial=init)

    return render_to_response('doc/change_state.html',
                              dict(form=form,
                                   doc=status_change,
                                   login=login,
                                   help_url=reverse('state_help', kwargs=dict(type="status-change")),
                                   ),
                              context_instance=RequestContext(request))
Ejemplo n.º 11
0
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))
Ejemplo n.º 12
0
def change_state(request, name, option=None):
    """Change state of an IESG review for IETF conflicts in other stream's documents, notifying parties as necessary
    and logging the change as a comment."""
    review = get_object_or_404(Document, type="conflrev", name=name)

    login = request.user.get_profile()

    if request.method == 'POST':
        form = ChangeStateForm(request.POST)
        if form.is_valid():
            clean = form.cleaned_data
            review_state = clean['review_state']
            comment = clean['comment'].rstrip()

            if comment:
                c = DocEvent(type="added_comment", doc=review, by=login)
                c.desc = comment
                c.save()

            if review_state != review.get_state():
                save_document_in_history(review)

                old_description = review.friendly_state()
                review.set_state(review_state)
                new_description = review.friendly_state()

                log_state_changed(request, review, login, new_description,
                                  old_description)

                review.time = datetime.datetime.now()
                review.save()

                if review_state.slug == "iesgeval":
                    create_ballot_if_not_open(review, login, "conflrev")
                    ballot = review.latest_event(BallotDocEvent,
                                                 type="created_ballot")
                    if has_role(request.user,
                                "Area Director") and not review.latest_event(
                                    BallotPositionDocEvent,
                                    ad=login,
                                    ballot=ballot,
                                    type="changed_ballot_position"):

                        # The AD putting a conflict review into iesgeval who doesn't already have a position is saying "yes"
                        pos = BallotPositionDocEvent(doc=review, 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()
                    send_conflict_eval_email(request, review)

            return redirect('doc_view', name=review.name)
    else:
        s = review.get_state()
        init = dict(review_state=s.pk if s else None)
        form = ChangeStateForm(initial=init)

    return render_to_response(
        'doc/change_state.html',
        dict(
            form=form,
            doc=review,
            login=login,
            help_url=reverse('help_conflict_review_states'),
        ),
        context_instance=RequestContext(request))
Ejemplo n.º 13
0
def change_state(request, name, option=None):
    """Change state of an status-change document, notifying parties as necessary
       and logging the change as a comment."""
    status_change = get_object_or_404(Document, type="statchg", name=name)

    login = request.user.person

    if request.method == 'POST':
        form = ChangeStateForm(request.POST)
        if form.is_valid():
            clean = form.cleaned_data
            new_state = clean['new_state']
            comment = clean['comment'].rstrip()

            if comment:
                c = DocEvent(type="added_comment",
                             doc=status_change,
                             rev=status_change.rev,
                             by=login)
                c.desc = comment
                c.save()

            prev_state = status_change.get_state()
            if new_state != prev_state:
                status_change.set_state(new_state)
                events = []
                events.append(
                    add_state_change_event(status_change, login, prev_state,
                                           new_state))
                status_change.save_with_history(events)

                if new_state.slug == "iesgeval":
                    create_ballot_if_not_open(status_change, login, "statchg",
                                              status_change.time)
                    ballot = status_change.latest_event(BallotDocEvent,
                                                        type="created_ballot")
                    if has_role(request.user, "Area Director"
                                ) and not status_change.latest_event(
                                    BallotPositionDocEvent,
                                    ad=login,
                                    ballot=ballot,
                                    type="changed_ballot_position"):

                        # The AD putting a status change into iesgeval who doesn't already have a position is saying "yes"
                        pos = BallotPositionDocEvent(doc=status_change,
                                                     rev=status_change.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()

                    send_status_change_eval_email(request, status_change)

                if new_state.slug == "lc-req":
                    request_last_call(request, status_change)
                    return render(
                        request, 'doc/draft/last_call_requested.html',
                        dict(
                            doc=status_change,
                            url=status_change.get_absolute_url(),
                        ))

            return redirect('ietf.doc.views_doc.document_main',
                            name=status_change.name)
    else:
        s = status_change.get_state()
        init = dict(
            new_state=s.pk if s else None,
            type='statchg',
            label='Status Change Evaluation State',
        )
        form = ChangeStateForm(initial=init)

    return render(
        request, 'doc/change_state.html',
        dict(
            form=form,
            doc=status_change,
            login=login,
            help_url=reverse('ietf.doc.views_help.state_help',
                             kwargs=dict(type="status-change")),
        ))
Ejemplo n.º 14
0
def change_state(request, name, option=None):
    """Change state of charter, notifying parties as necessary and
    logging the change as a comment."""
    charter = get_object_or_404(Document, type="charter", name=name)
    group = charter.group

    if not can_manage_group_type(request.user, group.type_id):
        return HttpResponseForbidden("You don't have permission to access this view")

    chartering_type = get_chartering_type(charter)

    initial_review = charter.latest_event(InitialReviewDocEvent, type="initial_review")
    if charter.get_state_slug() != "infrev" or (initial_review and initial_review.expires < datetime.datetime.now()) or chartering_type == "rechartering":
        initial_review = None

    login = request.user.person

    if request.method == 'POST':
        form = ChangeStateForm(request.POST, group=group)
        if form.is_valid():
            clean = form.cleaned_data
            charter_rev = charter.rev

            if option in ("initcharter", "recharter"):
                if group.type_id == "wg":
                    charter_state = State.objects.get(used=True, type="charter", slug="infrev")
                else:
                    charter_state = clean['charter_state']

                # make sure we have the latest revision set, if we
                # abandoned a charter before, we could have reset the
                # revision to latest approved
                prev_revs = charter.history_set.order_by('-rev')[:1]
                if prev_revs and prev_revs[0].rev > charter_rev:
                    charter_rev = prev_revs[0].rev

                if "-" not in charter_rev:
                    charter_rev = charter_rev + "-00"
            elif option == "abandon":
                oldstate = group.state
                if oldstate.slug in ("proposed", "bof", "unknown"):
                    charter_state = State.objects.get(used=True, type="charter", slug="notrev")
                    #TODO : set an abandoned state and leave some comments here
                    group.state = GroupStateName.objects.get(slug='abandon')
                    group.save()
                    e = ChangeStateGroupEvent(group=group, type="changed_state")
                    e.time = group.time
                    e.by = login
                    e.state_id = group.state.slug
                    e.desc = "Group state changed to %s from %s" % (group.state, oldstate)
                    e.save()

                else:
                    charter_state = State.objects.get(used=True, type="charter", slug="approved")
                    charter_rev = approved_revision(charter.rev)
            else:
                charter_state = clean['charter_state']

            comment = clean['comment'].rstrip()
            message = clean['message']

            if charter_state != charter.get_state():
                # Charter state changed
                save_document_in_history(charter)

                prev_state = charter.get_state()
                new_state = charter_state
                charter.set_state(new_state)
                charter.rev = charter_rev

                if option != "abandon":
                    add_state_change_event(charter, login, prev_state, new_state)
                else:
                    # kill hanging ballots
                    close_open_ballots(charter, login)

                    # Special log for abandoned efforts
                    e = DocEvent(type="changed_document", doc=charter, by=login)
                    e.desc = "IESG has abandoned the chartering effort"
                    e.save()

                if comment:
                    c = DocEvent(type="added_comment", doc=charter, by=login)
                    c.desc = comment
                    c.save()

                charter.time = datetime.datetime.now()
                charter.save()

                if charter_state.slug == 'intrev':
                    email_charter_internal_review(request,charter)

                if message or charter_state.slug == "intrev" or charter_state.slug == "extrev":
                    email_admin_re_charter(request, group, "Charter state changed to %s" % charter_state.name, message,'charter_state_edit_admin_needed')

                # TODO - do we need a seperate set of recipients for state changes to charters vrs other kind of documents
                email_state_changed(request, charter, "State changed to %s." % charter_state, 'doc_state_edited')

                if charter_state.slug == "intrev" and group.type_id == "wg":
                    if request.POST.get("ballot_wo_extern"):
                        create_ballot_if_not_open(charter, login, "r-wo-ext")
                    else:
                        create_ballot_if_not_open(charter, login, "r-extrev")
                    default_review_text(group, charter, login)
                    default_action_text(group, charter, login)
                elif charter_state.slug == "iesgrev":
                    create_ballot_if_not_open(charter, login, "approve")
                elif charter_state.slug == "approved":
                    change_group_state_after_charter_approval(group, login)
                    fix_charter_revision_after_approval(charter, login)

            if charter_state.slug == "infrev" and clean["initial_time"] and clean["initial_time"] != 0:
                e = InitialReviewDocEvent(type="initial_review", by=login, doc=charter)
                e.expires = datetime.datetime.now() + datetime.timedelta(weeks=clean["initial_time"])
                e.desc = "Initial review time expires %s" % e.expires.strftime("%Y-%m-%d")
                e.save()

            return redirect('doc_view', name=charter.name)
    else:
        hide = ['initial_time']
        s = charter.get_state()
        init = dict(charter_state=s.pk if s and option != "recharter" else None)

        if option == "abandon":
            hide = ['initial_time', 'charter_state']

        if group.type_id == "wg":
            if option == "recharter":
                hide = ['initial_time', 'charter_state', 'message']
                init = dict()
            elif option == "initcharter":
                hide = ['charter_state']
                init = dict(initial_time=1, message='%s has initiated chartering of the proposed %s:\n "%s" (%s).' % (login.plain_name(), group.type.name, group.name, group.acronym))
            elif option == "abandon":
                hide = ['initial_time', 'charter_state']
                init = dict(message='%s has abandoned the chartering effort on the %s:\n "%s" (%s).' % (login.plain_name(), group.type.name, group.name, group.acronym))
        form = ChangeStateForm(hide=hide, initial=init, group=group)

    prev_charter_state = None
    charter_hists = DocHistory.objects.filter(doc=charter).exclude(states__type="charter", states__slug=charter.get_state_slug()).order_by("-time")[:1]
    if charter_hists:
        prev_charter_state = charter_hists[0].get_state()

    title = {
        "initcharter": "Initiate chartering of %s %s" % (group.acronym, group.type.name),
        "recharter": "Recharter %s %s" % (group.acronym, group.type.name),
        "abandon": "Abandon effort on %s %s" % (group.acronym, group.type.name),
        }.get(option)
    if not title:
        title = "Change chartering state of %s %s" % (group.acronym, group.type.name)

    def state_pk(slug):
        return State.objects.get(used=True, type="charter", slug=slug).pk

    info_msg = {}
    if group.type_id == "wg":
        info_msg[state_pk("infrev")] = 'The proposed charter for %s "%s" (%s) has been set to Informal IESG review by %s.' % (group.type.name, group.name, group.acronym, login.plain_name())
        info_msg[state_pk("intrev")] = 'The proposed charter for %s "%s" (%s) has been set to Internal review by %s.\nPlease place it on the next IESG telechat if it has not already been placed.' % (group.type.name, group.name, group.acronym, login.plain_name())
        info_msg[state_pk("extrev")] = 'The proposed charter for %s "%s" (%s) has been set to External review by %s.\nPlease send out the external review announcement to the appropriate lists.\n\nSend the announcement to other SDOs: Yes\nAdditional recipients of the announcement: ' % (group.type.name, group.name, group.acronym, login.plain_name())

    states_for_ballot_wo_extern = State.objects.none()
    if group.type_id == "wg":
        states_for_ballot_wo_extern = State.objects.filter(used=True, type="charter", slug="intrev").values_list("pk", flat=True)

    return render_to_response('doc/charter/change_state.html',
                              dict(form=form,
                                   doc=group.charter,
                                   login=login,
                                   option=option,
                                   prev_charter_state=prev_charter_state,
                                   title=title,
                                   initial_review=initial_review,
                                   chartering_type=chartering_type,
                                   info_msg=json.dumps(info_msg),
                                   states_for_ballot_wo_extern=json.dumps(list(states_for_ballot_wo_extern)),
                                   ),
                              context_instance=RequestContext(request))
Ejemplo n.º 15
0
def change_state(request, name, option=None):
    """Change state of charter, notifying parties as necessary and
    logging the change as a comment."""
    charter = get_object_or_404(Document, type="charter", name=name)
    group = charter.group

    if not can_manage_group_type(request.user, group):
        return HttpResponseForbidden(
            "You don't have permission to access this view")

    chartering_type = get_chartering_type(charter)

    initial_review = charter.latest_event(InitialReviewDocEvent,
                                          type="initial_review")
    if charter.get_state_slug() != "infrev" or (
            initial_review and initial_review.expires <
            datetime.datetime.now()) or chartering_type == "rechartering":
        initial_review = None

    by = request.user.person

    if request.method == 'POST':
        form = ChangeStateForm(request.POST, group=group)
        if form.is_valid():
            clean = form.cleaned_data
            charter_rev = charter.rev

            if option in ("initcharter", "recharter"):
                if group.type_id == "wg":
                    charter_state = State.objects.get(used=True,
                                                      type="charter",
                                                      slug="infrev")
                else:
                    charter_state = clean['charter_state']

                # make sure we have the latest revision set, if we
                # abandoned a charter before, we could have reset the
                # revision to latest approved
                prev_revs = charter.history_set.order_by('-rev')[:1]
                if prev_revs and prev_revs[0].rev > charter_rev:
                    charter_rev = prev_revs[0].rev

                if "-" not in charter_rev:
                    charter_rev = charter_rev + "-00"
            elif option == "abandon":
                oldstate = group.state
                if oldstate.slug in ("proposed", "bof", "unknown"):
                    charter_state = State.objects.get(used=True,
                                                      type="charter",
                                                      slug="notrev")
                    #TODO : set an abandoned state and leave some comments here
                    group.state = GroupStateName.objects.get(slug='abandon')
                    group.save()
                    e = ChangeStateGroupEvent(group=group,
                                              type="changed_state")
                    e.time = group.time
                    e.by = by
                    e.state_id = group.state.slug
                    e.desc = "Group state changed to \"%s\" from \"%s\"" % (
                        group.state, oldstate)
                    e.save()

                else:
                    charter_state = State.objects.get(used=True,
                                                      type="charter",
                                                      slug="approved")
                    charter_rev = approved_revision(charter.rev)
            else:
                charter_state = clean['charter_state']

            comment = clean['comment'].rstrip()
            message = clean['message']

            if charter_state != charter.get_state():
                events = []
                prev_state = charter.get_state()
                new_state = charter_state
                charter.set_state(new_state)
                charter.rev = charter_rev

                if option != "abandon":
                    e = add_state_change_event(charter, by, prev_state,
                                               new_state)
                    if e:
                        events.append(e)
                else:
                    # kill hanging ballots
                    close_open_ballots(charter, by)

                    # Special log for abandoned efforts
                    e = DocEvent(type="changed_document",
                                 doc=charter,
                                 rev=charter.rev,
                                 by=by)
                    e.desc = "Chartering effort abandoned"
                    e.save()
                    events.append(e)

                if comment:
                    events.append(
                        DocEvent.objects.create(type="added_comment",
                                                doc=charter,
                                                rev=charter.rev,
                                                by=by,
                                                desc=comment))

                charter.save_with_history(events)

                if charter_state.slug == 'intrev':
                    email_charter_internal_review(request, charter)

                if message or charter_state.slug == "intrev" or charter_state.slug == "extrev":
                    email_admin_re_charter(
                        request, group,
                        "Charter state changed to \"%s\"" % charter_state.name,
                        message, 'charter_state_edit_admin_needed')

                # TODO - do we need a seperate set of recipients for state changes to charters vrs other kind of documents
                email_state_changed(request, charter,
                                    "State changed to %s." % charter_state,
                                    'doc_state_edited')

                if charter_state.slug == "intrev" and group.type_id == "wg":
                    if request.POST.get("ballot_wo_extern"):
                        create_ballot_if_not_open(charter, by, "r-wo-ext")
                    else:
                        create_ballot_if_not_open(charter, by, "r-extrev")
                    (e1, e2) = default_review_text(group, charter, by)
                    e1.save()
                    e2.save()
                    e = default_action_text(group, charter, by)
                    e.save()
                elif charter_state.slug in ["extrev", "iesgrev"]:
                    create_ballot_if_not_open(charter, by, "approve")
                elif charter_state.slug == "approved":
                    change_group_state_after_charter_approval(group, by)
                    fix_charter_revision_after_approval(charter, by)

            if charter_state.slug == "infrev" and clean[
                    "initial_time"] and clean["initial_time"] != 0:
                e = InitialReviewDocEvent(type="initial_review",
                                          by=by,
                                          doc=charter,
                                          rev=charter.rev)
                e.expires = datetime.datetime.now() + datetime.timedelta(
                    weeks=clean["initial_time"])
                e.desc = "Initial review time expires %s" % e.expires.strftime(
                    "%Y-%m-%d")
                e.save()

            return redirect('ietf.doc.views_doc.document_main',
                            name=charter.name)
    else:
        hide = ['initial_time']
        s = charter.get_state()
        init = dict(
            charter_state=s.pk if s and option != "recharter" else None)

        if option == "abandon":
            hide = ['initial_time', 'charter_state']

        if group.type_id == "wg":
            if option == "recharter":
                hide = ['initial_time', 'charter_state', 'message']
                init = dict()
            elif option == "initcharter":
                hide = ['charter_state']
                init = dict(
                    initial_time=1,
                    message=
                    '%s has initiated chartering of the proposed %s:\n "%s" (%s).'
                    % (by.plain_name(), group.type.name, group.name,
                       group.acronym))
            elif option == "abandon":
                hide = ['initial_time', 'charter_state']
                init = dict(
                    message=
                    '%s has abandoned the chartering effort on the %s:\n "%s" (%s).'
                    % (by.plain_name(), group.type.name, group.name,
                       group.acronym))
        form = ChangeStateForm(hide=hide, initial=init, group=group)

    prev_charter_state = None
    charter_hists = DocHistory.objects.filter(doc=charter).exclude(
        states__type="charter",
        states__slug=charter.get_state_slug()).order_by("-time")[:1]
    if charter_hists:
        prev_charter_state = charter_hists[0].get_state()

    title = {
        "initcharter":
        "Initiate chartering of %s %s" % (group.acronym, group.type.name),
        "recharter":
        "Recharter %s %s" % (group.acronym, group.type.name),
        "abandon":
        "Abandon effort on %s %s" % (group.acronym, group.type.name),
    }.get(option)
    if not title:
        title = "Change chartering state of %s %s" % (group.acronym,
                                                      group.type.name)

    def state_pk(slug):
        return State.objects.get(used=True, type="charter", slug=slug).pk

    info_msg = {}
    if group.type_id == "wg":
        info_msg[state_pk(
            "infrev"
        )] = 'The proposed charter for %s "%s" (%s) has been set to Informal IESG review by %s.' % (
            group.type.name, group.name, group.acronym, by.plain_name())
        info_msg[state_pk(
            "intrev"
        )] = 'The proposed charter for %s "%s" (%s) has been set to Internal review by %s.\nPlease place it on the next IESG telechat if it has not already been placed.' % (
            group.type.name, group.name, group.acronym, by.plain_name())
        info_msg[state_pk(
            "extrev"
        )] = 'The proposed charter for %s "%s" (%s) has been set to External review by %s.\nPlease send out the external review announcement to the appropriate lists.\n\nSend the announcement to other SDOs: Yes\nAdditional recipients of the announcement: ' % (
            group.type.name, group.name, group.acronym, by.plain_name())

    states_for_ballot_wo_extern = State.objects.none()
    if group.type_id == "wg":
        states_for_ballot_wo_extern = State.objects.filter(
            used=True, type="charter", slug="intrev").values_list("pk",
                                                                  flat=True)

    return render(
        request, 'doc/charter/change_state.html',
        dict(
            form=form,
            doc=group.charter,
            option=option,
            prev_charter_state=prev_charter_state,
            title=title,
            initial_review=initial_review,
            chartering_type=chartering_type,
            info_msg=json.dumps(info_msg),
            states_for_ballot_wo_extern=json.dumps(
                list(states_for_ballot_wo_extern)),
        ))