Removed some duplication between doc/util and doc/models by moving things into doc/models. Fixes bug #857
- Legacy-Id: 4750
This commit is contained in:
parent
ada1e4eb56
commit
fb2b9c9e6c
|
@ -259,11 +259,17 @@ class Document(DocumentInfo):
|
|||
return self.latest_event(type="changed_document", desc__startswith="State changed to <b>IESG Evaluation - Defer</b>")
|
||||
return None
|
||||
|
||||
# This, and several other ballot related functions here, assume that there is only one active ballot for a document at any point in time.
|
||||
# If that assumption is violated, they will only expose the most recently created ballot
|
||||
def ballot_open(self, ballot_type_slug):
|
||||
e = self.latest_event(BallotDocEvent, ballot_type__slug=ballot_type_slug)
|
||||
return e and not e.type == "closed_ballot"
|
||||
|
||||
def active_ballot(self):
|
||||
"""Returns the most recently created ballot if it isn't closed."""
|
||||
ballot = self.latest_event(BallotDocEvent, type="created_ballot")
|
||||
e = self.latest_event(BallotDocEvent, ballot_type__slug=ballot.ballot_type.slug) if ballot else None
|
||||
open = e and not e.type == "closed_ballot"
|
||||
return ballot.ballot_type if open else None
|
||||
open = self.ballot_open(ballot.ballot_type.slug) if ballot else False
|
||||
return ballot if open else None
|
||||
|
||||
def active_ballot_positions(self):
|
||||
"""Return dict mapping each active AD to a current ballot position (or None if they haven't voted)."""
|
||||
|
@ -281,7 +287,7 @@ class Document(DocumentInfo):
|
|||
if ad not in res:
|
||||
res[ad] = None
|
||||
|
||||
return res.values()
|
||||
return res
|
||||
|
||||
def displayname_with_link(self):
|
||||
return '<a href="%s">%s-%s</a>' % (self.get_absolute_url(), self.name , self.rev)
|
||||
|
|
|
@ -550,10 +550,9 @@ class InternetDraft(Document):
|
|||
def active_positions(self):
|
||||
"""Returns a list of dicts, with AD and Position tuples"""
|
||||
from ietf.person.proxy import IESGLogin as IESGLoginProxy
|
||||
from ietf.doc.utils import active_ballot_positions
|
||||
|
||||
res = []
|
||||
for ad, pos in active_ballot_positions(self).iteritems():
|
||||
for ad, pos in self.active_ballot_positions().iteritems():
|
||||
res.append(dict(ad=IESGLoginProxy().from_object(ad), pos=Position().from_object(pos) if pos else None))
|
||||
|
||||
res.sort(key=lambda x: x["ad"].last_name)
|
||||
|
|
|
@ -13,7 +13,7 @@ from django.core.urlresolvers import reverse as urlreverse
|
|||
from ietf.utils.test_utils import login_testing_unauthorized
|
||||
from ietf.utils.test_data import make_test_data
|
||||
from ietf.utils.mail import outbox
|
||||
from ietf.doc.utils import active_ballot, create_ballot_if_not_open, ballot_open
|
||||
from ietf.doc.utils import create_ballot_if_not_open
|
||||
from ietf.doc.views_conflict_review import default_approval_text
|
||||
|
||||
from ietf.doc.models import Document,DocEvent,NewRevisionDocEvent,BallotPositionDocEvent,TelechatDocEvent,DocAlias,State
|
||||
|
@ -105,7 +105,7 @@ class ConflictReviewTestCase(django.test.TestCase):
|
|||
review_doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
|
||||
self.assertEquals(review_doc.get_state('conflrev').slug,'adrev')
|
||||
self.assertTrue(review_doc.latest_event(DocEvent,type="added_comment").desc.startswith('RDNK84ZD'))
|
||||
self.assertFalse(active_ballot(review_doc))
|
||||
self.assertFalse(review_doc.active_ballot())
|
||||
|
||||
# successful change to IESG Evaluation
|
||||
iesgeval_pk = str(State.objects.get(slug='iesgeval',type__slug='conflrev').pk)
|
||||
|
@ -114,7 +114,7 @@ class ConflictReviewTestCase(django.test.TestCase):
|
|||
review_doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
|
||||
self.assertEquals(review_doc.get_state('conflrev').slug,'iesgeval')
|
||||
self.assertTrue(review_doc.latest_event(DocEvent,type="added_comment").desc.startswith('TGmZtEjt'))
|
||||
self.assertTrue(active_ballot(review_doc))
|
||||
self.assertTrue(review_doc.active_ballot())
|
||||
self.assertEquals(review_doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position").pos_id,'yes')
|
||||
|
||||
|
||||
|
@ -234,7 +234,7 @@ class ConflictReviewTestCase(django.test.TestCase):
|
|||
|
||||
doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission')
|
||||
self.assertEquals(doc.get_state_slug(),approve_type+'-sent')
|
||||
self.assertFalse(ballot_open(doc, "conflrev"))
|
||||
self.assertFalse(doc.ballot_open("conflrev"))
|
||||
|
||||
self.assertEquals(len(outbox), messages_before + 1)
|
||||
self.assertTrue('Results of IETF-conflict review' in outbox[-1]['Subject'])
|
||||
|
|
|
@ -36,34 +36,6 @@ def get_tags_for_stream_id(stream_id):
|
|||
else:
|
||||
return []
|
||||
|
||||
# This, and several other utilities here, assume that there is only one active ballot for a document at any point in time.
|
||||
# If that assumption is violated, they will only expose the most recently created ballot
|
||||
def active_ballot(doc):
|
||||
"""Returns the most recently created ballot if it isn't closed."""
|
||||
ballot = doc.latest_event(BallotDocEvent, type="created_ballot")
|
||||
open = ballot_open(doc,ballot.ballot_type.slug) if ballot else False
|
||||
return ballot if open else None
|
||||
|
||||
|
||||
def active_ballot_positions(doc, ballot=None):
|
||||
"""Return dict mapping each active AD to a current ballot position (or None if they haven't voted)."""
|
||||
active_ads = list(Person.objects.filter(role__name="ad", role__group__state="active"))
|
||||
res = {}
|
||||
|
||||
if not ballot:
|
||||
ballot = doc.latest_event(BallotDocEvent, type="created_ballot")
|
||||
positions = BallotPositionDocEvent.objects.filter(doc=doc, type="changed_ballot_position", ad__in=active_ads, ballot=ballot).select_related('ad', 'pos').order_by("-time", "-id")
|
||||
|
||||
for pos in positions:
|
||||
if pos.ad not in res:
|
||||
res[pos.ad] = pos
|
||||
|
||||
for ad in active_ads:
|
||||
if ad not in res:
|
||||
res[ad] = None
|
||||
|
||||
return res
|
||||
|
||||
def needed_ballot_positions(doc, active_positions):
|
||||
'''Returns text answering the question "what does this document
|
||||
need to pass?". The return value is only useful if the document
|
||||
|
@ -102,12 +74,8 @@ def needed_ballot_positions(doc, active_positions):
|
|||
|
||||
return " ".join(answer)
|
||||
|
||||
def ballot_open(doc, ballot_type_slug):
|
||||
e = doc.latest_event(BallotDocEvent, ballot_type__slug=ballot_type_slug)
|
||||
return e and not e.type == "closed_ballot"
|
||||
|
||||
def create_ballot_if_not_open(doc, by, ballot_type_slug):
|
||||
if not ballot_open(doc, ballot_type_slug):
|
||||
if not doc.ballot_open(ballot_type_slug):
|
||||
e = BallotDocEvent(type="created_ballot", by=by, doc=doc)
|
||||
e.ballot_type = BallotType.objects.get(doc_type=doc.type, slug=ballot_type_slug)
|
||||
e.desc = u'Created "%s" ballot' % e.ballot_type.name
|
||||
|
@ -115,7 +83,7 @@ def create_ballot_if_not_open(doc, by, ballot_type_slug):
|
|||
|
||||
def close_open_ballots(doc, by):
|
||||
for t in BallotType.objects.filter(doc_type=doc.type_id):
|
||||
if ballot_open(doc, t.slug):
|
||||
if doc.ballot_open(t.slug):
|
||||
e = BallotDocEvent(type="closed_ballot", doc=doc, by=by)
|
||||
e.ballot_type = t
|
||||
e.desc = 'Closed "%s" ballot' % t.name
|
||||
|
|
|
@ -37,7 +37,6 @@ from ietf.idtracker.models import IDInternal, BallotInfo
|
|||
from ietf.idrfc.idrfc_wrapper import position_to_string, BALLOT_ACTIVE_STATES
|
||||
from ietf.idtracker.templatetags.ietf_filters import in_group, timesince_days
|
||||
from ietf.ietfauth.decorators import has_role
|
||||
from ietf.doc.utils import active_ballot_positions
|
||||
from ietf.doc.models import BallotDocEvent
|
||||
|
||||
register = template.Library()
|
||||
|
@ -83,7 +82,7 @@ def render_ballot_icon(user, doc):
|
|||
else:
|
||||
return (1, pos.pos.order)
|
||||
|
||||
positions = list(active_ballot_positions(doc, ballot).items())
|
||||
positions = list(doc.active_ballot_positions().items())
|
||||
positions.sort(key=sort_key)
|
||||
|
||||
cm = ""
|
||||
|
|
|
@ -38,7 +38,6 @@ from ietf.idtracker.models import IDInternal, BallotInfo
|
|||
from ietf.idrfc.idrfc_wrapper import position_to_string, BALLOT_ACTIVE_STATES
|
||||
from ietf.idtracker.templatetags.ietf_filters import in_group, timesince_days
|
||||
from ietf.ietfauth.decorators import has_role
|
||||
from ietf.doc.utils import active_ballot_positions, active_ballot
|
||||
from ietf.doc.models import BallotDocEvent, BallotPositionDocEvent
|
||||
|
||||
from datetime import date
|
||||
|
@ -90,7 +89,7 @@ def render_ballot_icon(user, doc):
|
|||
else:
|
||||
return (1, pos.pos.order)
|
||||
|
||||
positions = list(active_ballot_positions(doc, ballot).items())
|
||||
positions = list(doc.active_ballot_positions().items())
|
||||
positions.sort(key=sort_key)
|
||||
|
||||
cm = ""
|
||||
|
@ -144,7 +143,7 @@ def my_position(doc, user):
|
|||
return None
|
||||
if not in_group(user, "Area_Director"):
|
||||
return None
|
||||
ballot = active_ballot(doc)
|
||||
ballot = doc.active_ballot()
|
||||
pos = "No Record"
|
||||
if ballot:
|
||||
changed_pos = doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position", ad__name=user_name, ballot=ballot)
|
||||
|
|
|
@ -143,7 +143,7 @@ def document_main(request, name, rev=None):
|
|||
|
||||
ballot_summary = None
|
||||
if doc.get_state_slug() in ("intrev", "iesgrev"):
|
||||
ballot_summary = needed_ballot_positions(doc, active_ballot_positions(doc).values())
|
||||
ballot_summary = needed_ballot_positions(doc, doc.active_ballot_positions().values())
|
||||
|
||||
return render_to_response("idrfc/document_charter.html",
|
||||
dict(doc=doc,
|
||||
|
@ -171,7 +171,7 @@ def document_main(request, name, rev=None):
|
|||
|
||||
ballot_summary = None
|
||||
if doc.get_state_slug() in ("iesgeval"):
|
||||
ballot_summary = needed_ballot_positions(doc, active_ballot_positions(doc).values())
|
||||
ballot_summary = needed_ballot_positions(doc, doc.active_ballot_positions().values())
|
||||
|
||||
return render_to_response("idrfc/document_conflict_review.html",
|
||||
dict(doc=doc,
|
||||
|
|
|
@ -17,7 +17,6 @@ from ietf.ietfauth.decorators import has_role
|
|||
|
||||
from ietf.doc.models import *
|
||||
from ietf.person.models import Person, Alias, Email
|
||||
from ietf.doc.utils import active_ballot_positions
|
||||
from ietf.message.models import Message
|
||||
|
||||
# Some useful states
|
||||
|
@ -262,7 +261,7 @@ def announce_new_versionREDESIGN(request, submission, draft, state_change_msg):
|
|||
if draft.ad:
|
||||
to_email.append(draft.ad.role_email("ad").address)
|
||||
|
||||
for ad, pos in active_ballot_positions(draft).iteritems():
|
||||
for ad, pos in draft.active_ballot_positions().iteritems():
|
||||
if pos and pos.pos_id == "discuss":
|
||||
to_email.append(ad.role_email("ad").address)
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
|
|||
{% if doc.obj.active_ballot %}
|
||||
<br/><b>Discusses/comments</b> <a href="http://datatracker.ietf.org/idtracker/ballot/{{doc.obj.canonical_name}}/">[ballot]</a>:
|
||||
<ul>
|
||||
{% for p in doc.obj.active_ballot_positions %}
|
||||
{% for p in doc.obj.active_ballot_positions.values %}
|
||||
{% if p.pos %}
|
||||
{% if p.discuss %}
|
||||
<li>
|
||||
|
|
|
@ -40,7 +40,7 @@ Some parts Copyright (c) 2009 The IETF Trust, all rights reserved.
|
|||
|
||||
{% if doc.obj.active_ballot %}
|
||||
<ul>
|
||||
{% for p in doc.obj.active_ballot_positions %}
|
||||
{% for p in doc.obj.active_ballot_positions.values %}
|
||||
{% if p.pos and p.discuss %}
|
||||
<li>
|
||||
<a name="{{doc.obj.name}}+{{p.ad|slugify}}+discuss">{{ p.ad }}: Discuss [{{ p.discuss_time }}]</a>:
|
||||
|
|
|
@ -224,7 +224,7 @@ class CharterApproveBallotTestCase(django.test.TestCase):
|
|||
|
||||
charter = Document.objects.get(name=charter.name)
|
||||
self.assertEquals(charter.get_state_slug(), "approved")
|
||||
self.assertTrue(not ballot_open(charter, "approve"))
|
||||
self.assertTrue(not charter.ballot_open("approve"))
|
||||
|
||||
self.assertEquals(charter.rev, "01")
|
||||
self.assertTrue(os.path.exists(os.path.join(self.charter_dir, "charter-ietf-%s-%s.txt" % (group.acronym, charter.rev))))
|
||||
|
|
Loading…
Reference in a new issue