Merged in branch/iola/shimfree@6083. This cleans up and moves relevant code from idrfc/ to doc/. There should now only be a bit of old wrapper code left in idrfc; that will go away when the remaining models which use it are cleaned up.
- Legacy-Id: 6117
This commit is contained in:
commit
2a2389d17f
|
@ -9,7 +9,7 @@ management.setup_environ(settings)
|
|||
|
||||
syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER)
|
||||
|
||||
from ietf.idrfc.expire import *
|
||||
from ietf.doc.expire import *
|
||||
|
||||
if not in_draft_expire_freeze():
|
||||
for doc in get_expired_drafts():
|
||||
|
|
|
@ -9,7 +9,7 @@ management.setup_environ(settings)
|
|||
|
||||
syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER)
|
||||
|
||||
from ietf.idrfc.lastcall import *
|
||||
from ietf.doc.lastcall import *
|
||||
|
||||
drafts = get_expired_last_calls()
|
||||
for doc in drafts:
|
||||
|
|
|
@ -6,7 +6,7 @@ from ietf import settings
|
|||
from django.core import management
|
||||
management.setup_environ(settings)
|
||||
|
||||
from ietf.idrfc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft
|
||||
from ietf.doc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft
|
||||
|
||||
|
||||
# notify about documents that expire within the next 2 weeks
|
||||
|
|
|
@ -64,7 +64,7 @@ while urls:
|
|||
print "was fetching", url
|
||||
sys.exit(1)
|
||||
except:
|
||||
print "FAIL", url
|
||||
print 500, "%.3fs" % (datetime.datetime.now() - timestamp).total_seconds(), url, "FAIL (from %s)" % referrer
|
||||
print "============="
|
||||
print traceback.format_exc()
|
||||
print "============="
|
||||
|
@ -82,9 +82,15 @@ while urls:
|
|||
ctype = ctype[:ctype.index(";")]
|
||||
|
||||
if ctype == "text/html":
|
||||
for u in extract_html_urls(r.content):
|
||||
if u not in visited and u not in urls:
|
||||
urls[u] = url
|
||||
try:
|
||||
for u in extract_html_urls(r.content):
|
||||
if u not in visited and u not in urls:
|
||||
urls[u] = url
|
||||
except:
|
||||
print "error extracting HTML urls from", url
|
||||
print "============="
|
||||
print traceback.format_exc()
|
||||
print "============="
|
||||
else:
|
||||
tags.append(u"FAIL (from %s)" % referrer)
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@ from django.conf import settings
|
|||
from django.template.loader import render_to_string
|
||||
from django.db.models import Q
|
||||
|
||||
import datetime, os, shutil, glob, re, itertools
|
||||
import datetime, os, shutil, glob, re
|
||||
|
||||
from ietf.utils.mail import send_mail, send_mail_subj
|
||||
from ietf.idrfc.utils import log_state_changed
|
||||
from ietf.doc.models import Document, DocEvent, State, save_document_in_history, IESG_SUBSTATE_TAGS
|
||||
from ietf.person.models import Person, Email
|
||||
from ietf.meeting.models import Meeting
|
||||
from ietf.doc.utils import log_state_changed
|
||||
|
||||
def expirable_draft(draft):
|
||||
"""Return whether draft is in an expirable state or not. This is
|
||||
|
@ -82,7 +82,7 @@ def send_expire_warning_for_draft(doc):
|
|||
if to or cc:
|
||||
send_mail(request, to, frm,
|
||||
u"Expiration impending: %s" % doc.file_tag(),
|
||||
"idrfc/expire_warning_email.txt",
|
||||
"doc/draft/expire_warning_email.txt",
|
||||
dict(doc=doc,
|
||||
state=state,
|
||||
expiration=expiration
|
||||
|
@ -101,7 +101,7 @@ def send_expire_notice_for_draft(doc):
|
|||
send_mail(request, to,
|
||||
"I-D Expiring System <ietf-secretariat-reply@ietf.org>",
|
||||
u"I-D was expired %s" % doc.file_tag(),
|
||||
"idrfc/id_expired_email.txt",
|
||||
"doc/draft/id_expired_email.txt",
|
||||
dict(doc=doc,
|
||||
state=state,
|
||||
))
|
||||
|
@ -128,14 +128,14 @@ def expire_draft(doc):
|
|||
save_document_in_history(doc)
|
||||
if doc.latest_event(type='started_iesg_process'):
|
||||
dead_state = State.objects.get(used=True, type="draft-iesg", slug="dead")
|
||||
prev = doc.get_state("draft-iesg")
|
||||
prev_state = doc.friendly_state()
|
||||
prev_tag = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
|
||||
prev_tag = prev_tag[0] if prev_tag else None
|
||||
if prev != dead_state:
|
||||
if doc.get_state("draft-iesg") != dead_state:
|
||||
doc.set_state(dead_state)
|
||||
if prev_tag:
|
||||
doc.tags.remove(prev_tag)
|
||||
log_state_changed(None, doc, system, prev, prev_tag)
|
||||
log_state_changed(None, doc, system, doc.friendly_state(), prev_state)
|
||||
|
||||
e = DocEvent(doc=doc, by=system)
|
||||
e.type = "expired_document"
|
|
@ -12,7 +12,7 @@ from django.utils.text import truncate_words
|
|||
|
||||
from ietf.doc.models import *
|
||||
from ietf.doc.utils import augment_events_with_revision
|
||||
from ietf.idtracker.templatetags.ietf_filters import format_textarea
|
||||
from ietf.doc.templatetags.ietf_filters import format_textarea
|
||||
|
||||
class DocumentChanges(Feed):
|
||||
feed_type = Atom1Feed
|
||||
|
|
|
@ -3,26 +3,13 @@
|
|||
import datetime
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
|
||||
from ietf.idtracker.models import InternetDraft, DocumentComment, BallotInfo
|
||||
from ietf.idrfc.mails import *
|
||||
from ietf.idrfc.utils import *
|
||||
from ietf.doc.models import *
|
||||
from ietf.person.models import Person
|
||||
|
||||
import debug
|
||||
from ietf.doc.utils import log_state_changed
|
||||
from ietf.doc.mails import *
|
||||
|
||||
def request_last_call(request, doc):
|
||||
try:
|
||||
ballot = doc.idinternal.ballot
|
||||
except BallotInfo.DoesNotExist:
|
||||
ballot = generate_ballot(request, doc)
|
||||
|
||||
send_last_call_request(request, doc, ballot)
|
||||
add_document_comment(request, doc, "Last Call was requested")
|
||||
|
||||
def request_last_callREDESIGN(request, doc):
|
||||
if not doc.latest_event(type="changed_ballot_writeup_text"):
|
||||
generate_ballot_writeup(request, doc)
|
||||
if not doc.latest_event(type="changed_ballot_approval_text"):
|
||||
|
@ -39,14 +26,7 @@ def request_last_callREDESIGN(request, doc):
|
|||
e.desc = "Last call was requested"
|
||||
e.save()
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
request_last_call = request_last_callREDESIGN
|
||||
|
||||
def get_expired_last_calls():
|
||||
return InternetDraft.objects.filter(lc_expiration_date__lte=datetime.date.today(),
|
||||
idinternal__cur_state__document_state_id=IDState.IN_LAST_CALL)
|
||||
|
||||
def get_expired_last_callsREDESIGN():
|
||||
today = datetime.date.today()
|
||||
for d in Document.objects.filter(Q(states__type="draft-iesg", states__slug="lc")
|
||||
| Q(states__type="statchg", states__slug="in-lc")):
|
||||
|
@ -55,24 +35,6 @@ def get_expired_last_callsREDESIGN():
|
|||
yield d
|
||||
|
||||
def expire_last_call(doc):
|
||||
state = IDState.WAITING_FOR_WRITEUP
|
||||
|
||||
try:
|
||||
ballot = doc.idinternal.ballot
|
||||
if ballot.ballot_writeup and "Relevant content can frequently be found in the abstract" not in ballot.ballot_writeup:
|
||||
state = IDState.WAITING_FOR_AD_GO_AHEAD
|
||||
except BallotInfo.DoesNotExist:
|
||||
pass
|
||||
|
||||
doc.idinternal.change_state(IDState.objects.get(document_state_id=state), None)
|
||||
doc.idinternal.event_date = datetime.date.today()
|
||||
doc.idinternal.save()
|
||||
|
||||
log_state_changed(None, doc, by="system", email_watch_list=False)
|
||||
|
||||
email_last_call_expired(doc)
|
||||
|
||||
def expire_last_callREDESIGN(doc):
|
||||
if doc.type_id == 'draft':
|
||||
state = State.objects.get(used=True, type="draft-iesg", slug="writeupw")
|
||||
e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
|
||||
|
@ -87,8 +49,9 @@ def expire_last_callREDESIGN(doc):
|
|||
else:
|
||||
raise ValueError("Unexpected document type to expire_last_call(): %s" % doc.type)
|
||||
|
||||
save_document_in_history(doc)
|
||||
prev_state = doc.friendly_state()
|
||||
|
||||
save_document_in_history(doc)
|
||||
doc.set_state(state)
|
||||
|
||||
prev_tag = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
|
||||
|
@ -96,14 +59,9 @@ def expire_last_callREDESIGN(doc):
|
|||
if prev_tag:
|
||||
doc.tags.remove(prev_tag)
|
||||
|
||||
e = log_state_changed(None, doc, Person.objects.get(name="(System)"), prev, prev_tag)
|
||||
|
||||
e = log_state_changed(None, doc, Person.objects.get(name="(System)"), doc.friendly_state(), prev_state)
|
||||
|
||||
doc.time = e.time
|
||||
doc.save()
|
||||
|
||||
email_last_call_expired(doc)
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
get_expired_last_calls = get_expired_last_callsREDESIGN
|
||||
expire_last_call = expire_last_callREDESIGN
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
# generation of mails
|
||||
|
||||
import textwrap
|
||||
from datetime import datetime, date, time, timedelta
|
||||
import textwrap, datetime
|
||||
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.html import strip_tags
|
||||
|
@ -9,23 +8,12 @@ from django.conf import settings
|
|||
from django.core.urlresolvers import reverse as urlreverse
|
||||
|
||||
from ietf.utils.mail import send_mail, send_mail_text
|
||||
from ietf.idtracker.models import *
|
||||
from ietf.ipr.search import iprs_from_docs, related_docs
|
||||
#from ietf.doc.models import *
|
||||
from ietf.doc.models import WriteupDocEvent, BallotPositionDocEvent, LastCallDocEvent, DocAlias, ConsensusDocEvent
|
||||
from ietf.person.models import Person
|
||||
from ietf.group.models import Group
|
||||
from ietf.group.models import Group, Role
|
||||
|
||||
def email_state_changed(request, doc, text):
|
||||
to = [x.strip() for x in doc.idinternal.state_change_notice_to.replace(';', ',').split(',')]
|
||||
if to:
|
||||
send_mail(request, to, None,
|
||||
"ID Tracker State Update Notice: %s" % doc.file_tag(),
|
||||
"idrfc/state_changed_email.txt",
|
||||
dict(text=text,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
|
||||
|
||||
def email_state_changedREDESIGN(request, doc, text):
|
||||
to = [x.strip() for x in doc.notify.replace(';', ',').split(',')]
|
||||
if not to:
|
||||
return
|
||||
|
@ -33,41 +21,37 @@ def email_state_changedREDESIGN(request, doc, text):
|
|||
text = strip_tags(text)
|
||||
send_mail(request, to, None,
|
||||
"ID Tracker State Update Notice: %s" % doc.file_tag(),
|
||||
"idrfc/state_changed_email.txt",
|
||||
"doc/mail/state_changed_email.txt",
|
||||
dict(text=text,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
email_state_changed = email_state_changedREDESIGN
|
||||
|
||||
def email_stream_changed(request, doc, old_stream, new_stream, text=""):
|
||||
"""Email the change text to the notify group and to the stream chairs"""
|
||||
to = [x.strip() for x in doc.notify.replace(';', ',').split(',')]
|
||||
from ietf.group.models import Role as RedesignRole
|
||||
|
||||
# These use comprehension to deal with conditions when there might be more than one chair listed for a stream
|
||||
if old_stream:
|
||||
to.extend([x.person.formatted_email() for x in RedesignRole.objects.filter(group__acronym=old_stream.slug,name='chair')])
|
||||
to.extend([x.person.formatted_email() for x in Role.objects.filter(group__acronym=old_stream.slug,name='chair')])
|
||||
if new_stream:
|
||||
to.extend([x.person.formatted_email() for x in RedesignRole.objects.filter(group__acronym=new_stream.slug,name='chair')])
|
||||
to.extend([x.person.formatted_email() for x in Role.objects.filter(group__acronym=new_stream.slug,name='chair')])
|
||||
|
||||
if not to:
|
||||
return
|
||||
|
||||
if not text:
|
||||
text = u"Stream changed to <b>%s</b> from %s"% (new_stream,old_stream)
|
||||
text = u"Stream changed to <b>%s</b> from %s" % (new_stream, old_stream)
|
||||
text = strip_tags(text)
|
||||
|
||||
send_mail(request, to, None,
|
||||
"ID Tracker Stream Change Notice: %s" % doc.file_tag(),
|
||||
"idrfc/stream_changed_email.txt",
|
||||
"doc/mail/stream_changed_email.txt",
|
||||
dict(text=text,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
|
||||
|
||||
def email_pulled_from_rfc_queue(request, doc, comment, prev_state, next_state):
|
||||
send_mail(request, ["IANA <iana@iana.org>", "RFC Editor <rfc-editor@rfc-editor.org>"], None,
|
||||
"%s changed state from %s to %s" % (doc.name, prev_state.name, next_state.name),
|
||||
"idrfc/pulled_from_rfc_queue_email.txt",
|
||||
"doc/mail/pulled_from_rfc_queue_email.txt",
|
||||
dict(doc=doc,
|
||||
prev_state=prev_state,
|
||||
next_state=next_state,
|
||||
|
@ -86,20 +70,7 @@ def email_authors(request, doc, subject, text):
|
|||
def html_to_text(html):
|
||||
return strip_tags(html.replace("<", "<").replace(">", ">").replace("&", "&").replace("<br>", "\n"))
|
||||
|
||||
def email_owner(request, doc, owner, changed_by, text, subject=None):
|
||||
if not owner or not changed_by or owner == changed_by:
|
||||
return
|
||||
|
||||
to = u"%s <%s>" % owner.person.email()
|
||||
send_mail(request, to,
|
||||
"DraftTracker Mail System <iesg-secretary@ietf.org>",
|
||||
"%s updated by %s" % (doc.file_tag(), changed_by),
|
||||
"idrfc/change_notice.txt",
|
||||
dict(text=html_to_text(text),
|
||||
doc=doc,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
|
||||
|
||||
def email_adREDESIGN(request, doc, ad, changed_by, text, subject=None):
|
||||
def email_ad(request, doc, ad, changed_by, text, subject=None):
|
||||
if not ad or not changed_by or ad == changed_by:
|
||||
return
|
||||
|
||||
|
@ -107,14 +78,11 @@ def email_adREDESIGN(request, doc, ad, changed_by, text, subject=None):
|
|||
send_mail(request, to,
|
||||
"DraftTracker Mail System <iesg-secretary@ietf.org>",
|
||||
"%s updated by %s" % (doc.file_tag(), changed_by.plain_name()),
|
||||
"idrfc/change_notice.txt",
|
||||
"doc/mail/change_notice.txt",
|
||||
dict(text=html_to_text(text),
|
||||
doc=doc,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
email_owner = email_adREDESIGN
|
||||
|
||||
|
||||
def generate_ballot_writeup(request, doc):
|
||||
e = doc.latest_event(type="iana_review")
|
||||
|
@ -125,21 +93,17 @@ def generate_ballot_writeup(request, doc):
|
|||
e.by = request.user.get_profile()
|
||||
e.doc = doc
|
||||
e.desc = u"Ballot writeup was generated"
|
||||
e.text = unicode(render_to_string("idrfc/ballot_writeup.txt", {'iana': iana}))
|
||||
e.text = unicode(render_to_string("doc/mail/ballot_writeup.txt", {'iana': iana}))
|
||||
e.save()
|
||||
|
||||
return e
|
||||
|
||||
def generate_last_call_announcement(request, doc):
|
||||
pass
|
||||
|
||||
def generate_last_call_announcementREDESIGN(request, doc):
|
||||
|
||||
expiration_date = date.today() + timedelta(days=14)
|
||||
expiration_date = datetime.date.today() + datetime.timedelta(days=14)
|
||||
cc = []
|
||||
if doc.group.type_id in ("individ", "area"):
|
||||
group = "an individual submitter"
|
||||
expiration_date += timedelta(days=14)
|
||||
expiration_date += datetime.timedelta(days=14)
|
||||
else:
|
||||
group = "the %s WG (%s)" % (doc.group.name, doc.group.acronym)
|
||||
if doc.group.list_email:
|
||||
|
@ -154,7 +118,7 @@ def generate_last_call_announcementREDESIGN(request, doc):
|
|||
else:
|
||||
ipr_links = None
|
||||
|
||||
mail = render_to_string("idrfc/last_call_announcement.txt",
|
||||
mail = render_to_string("doc/mail/last_call_announcement.txt",
|
||||
dict(doc=doc,
|
||||
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url() + "ballot/",
|
||||
expiration_date=expiration_date.strftime("%Y-%m-%d"), #.strftime("%B %-d, %Y"),
|
||||
|
@ -177,18 +141,9 @@ def generate_last_call_announcementREDESIGN(request, doc):
|
|||
return e
|
||||
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
generate_last_call_announcement = generate_last_call_announcementREDESIGN
|
||||
|
||||
def generate_approval_mail(request, doc):
|
||||
pass
|
||||
|
||||
def generate_approval_mail_rfc_editor(request, doc):
|
||||
pass
|
||||
|
||||
DO_NOT_PUBLISH_IESG_STATES = ("nopubadw", "nopubanw")
|
||||
|
||||
def generate_approval_mailREDESIGN(request, doc):
|
||||
def generate_approval_mail(request, doc):
|
||||
if doc.get_state_slug("draft-iesg") in DO_NOT_PUBLISH_IESG_STATES or doc.stream_id in ('ise','irtf'):
|
||||
mail = generate_approval_mail_rfc_editor(request, doc)
|
||||
else:
|
||||
|
@ -241,7 +196,7 @@ def generate_approval_mail_approved(request, doc):
|
|||
|
||||
doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet Draft"
|
||||
|
||||
return render_to_string("idrfc/approval_mail.txt",
|
||||
return render_to_string("doc/mail/approval_mail.txt",
|
||||
dict(doc=doc,
|
||||
docs=[doc],
|
||||
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
|
||||
|
@ -253,7 +208,7 @@ def generate_approval_mail_approved(request, doc):
|
|||
)
|
||||
)
|
||||
|
||||
def generate_approval_mail_rfc_editorREDESIGN(request, doc):
|
||||
def generate_approval_mail_rfc_editor(request, doc):
|
||||
disapproved = doc.get_state_slug("draft-iesg") in DO_NOT_PUBLISH_IESG_STATES
|
||||
doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet Draft"
|
||||
|
||||
|
@ -272,7 +227,7 @@ def generate_approval_mail_rfc_editorREDESIGN(request, doc):
|
|||
# include IRSG
|
||||
to.append('"Internet Research Steering Group" <irsg@irtf.org>')
|
||||
|
||||
return render_to_string("idrfc/approval_mail_rfc_editor.txt",
|
||||
return render_to_string("doc/mail/approval_mail_rfc_editor.txt",
|
||||
dict(doc=doc,
|
||||
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
|
||||
doc_type=doc_type,
|
||||
|
@ -281,10 +236,6 @@ def generate_approval_mail_rfc_editorREDESIGN(request, doc):
|
|||
)
|
||||
)
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
generate_approval_mail = generate_approval_mailREDESIGN
|
||||
generate_approval_mail_rfc_editor = generate_approval_mail_rfc_editorREDESIGN
|
||||
|
||||
def generate_publication_request(request, doc):
|
||||
group_description = ""
|
||||
if doc.group and doc.group.acronym != "none":
|
||||
|
@ -300,7 +251,7 @@ def generate_publication_request(request, doc):
|
|||
approving_body = str(doc.stream)
|
||||
consensus_body = approving_body
|
||||
|
||||
return render_to_string("idrfc/publication_request.txt",
|
||||
return render_to_string("doc/mail/publication_request.txt",
|
||||
dict(doc=doc,
|
||||
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
|
||||
group_description=group_description,
|
||||
|
@ -310,42 +261,18 @@ def generate_publication_request(request, doc):
|
|||
)
|
||||
)
|
||||
|
||||
def send_last_call_request(request, doc, ballot):
|
||||
to = "iesg-secretary@ietf.org"
|
||||
frm = '"DraftTracker Mail System" <iesg-secretary@ietf.org>'
|
||||
docs = [d.document() for d in doc.idinternal.ballot_set()]
|
||||
|
||||
send_mail(request, to, frm,
|
||||
"Last Call: %s" % doc.file_tag(),
|
||||
"idrfc/last_call_request.txt",
|
||||
dict(docs=docs,
|
||||
doc_url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
|
||||
|
||||
def send_last_call_requestREDESIGN(request, doc):
|
||||
def send_last_call_request(request, doc):
|
||||
to = "iesg-secretary@ietf.org"
|
||||
frm = '"DraftTracker Mail System" <iesg-secretary@ietf.org>'
|
||||
|
||||
send_mail(request, to, frm,
|
||||
"Last Call: %s" % doc.file_tag(),
|
||||
"idrfc/last_call_request.txt",
|
||||
"doc/mail/last_call_request.txt",
|
||||
dict(docs=[doc],
|
||||
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
send_last_call_request = send_last_call_requestREDESIGN
|
||||
|
||||
def email_resurrect_requested(request, doc, by):
|
||||
to = "I-D Administrator <internet-drafts@ietf.org>"
|
||||
frm = u"%s <%s>" % by.person.email()
|
||||
send_mail(request, to, frm,
|
||||
"I-D Resurrection Request",
|
||||
"idrfc/resurrect_request_email.txt",
|
||||
dict(doc=doc,
|
||||
by=frm,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
|
||||
|
||||
def email_resurrect_requestedREDESIGN(request, doc, by):
|
||||
to = "I-D Administrator <internet-drafts@ietf.org>"
|
||||
|
||||
if by.role_set.filter(name="secr", group__acronym="secretariat"):
|
||||
e = by.role_email("secr", group="secretariat")
|
||||
|
@ -355,25 +282,12 @@ def email_resurrect_requestedREDESIGN(request, doc, by):
|
|||
|
||||
send_mail(request, to, e.formatted_email(),
|
||||
"I-D Resurrection Request",
|
||||
"idrfc/resurrect_request_email.txt",
|
||||
"doc/mail/resurrect_request_email.txt",
|
||||
dict(doc=doc,
|
||||
by=frm,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
email_resurrect_requested = email_resurrect_requestedREDESIGN
|
||||
|
||||
def email_resurrection_completed(request, doc):
|
||||
to = u"%s <%s>" % doc.idinternal.resurrect_requested_by.person.email()
|
||||
frm = "I-D Administrator <internet-drafts-reply@ietf.org>"
|
||||
send_mail(request, to, frm,
|
||||
"I-D Resurrection Completed - %s" % doc.file_tag(),
|
||||
"idrfc/resurrect_completed_email.txt",
|
||||
dict(doc=doc,
|
||||
by=frm,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()))
|
||||
|
||||
def email_resurrection_completedREDESIGN(request, doc, requester):
|
||||
def email_resurrection_completed(request, doc, requester):
|
||||
if requester.role_set.filter(name="secr", group__acronym="secretariat"):
|
||||
e = requester.role_email("secr", group="secretariat")
|
||||
else:
|
||||
|
@ -383,28 +297,22 @@ def email_resurrection_completedREDESIGN(request, doc, requester):
|
|||
frm = "I-D Administrator <internet-drafts-reply@ietf.org>"
|
||||
send_mail(request, to, frm,
|
||||
"I-D Resurrection Completed - %s" % doc.file_tag(),
|
||||
"idrfc/resurrect_completed_email.txt",
|
||||
"doc/mail/resurrect_completed_email.txt",
|
||||
dict(doc=doc,
|
||||
by=frm,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
email_resurrection_completed = email_resurrection_completedREDESIGN
|
||||
|
||||
def email_ballot_deferred(request, doc, by, telechat_date):
|
||||
to = "iesg@ietf.org"
|
||||
frm = "DraftTracker Mail System <iesg-secretary@ietf.org>"
|
||||
send_mail(request, to, frm,
|
||||
"IESG Deferred Ballot notification: %s" % doc.file_tag(),
|
||||
"idrfc/ballot_deferred_email.txt",
|
||||
"doc/mail/ballot_deferred_email.txt",
|
||||
dict(doc=doc,
|
||||
by=by,
|
||||
telechat_date=telechat_date))
|
||||
|
||||
def generate_issue_ballot_mail(request, doc):
|
||||
pass
|
||||
|
||||
def generate_issue_ballot_mailREDESIGN(request, doc, ballot):
|
||||
def generate_issue_ballot_mail(request, doc, ballot):
|
||||
active_ads = Person.objects.filter(role__name="ad", role__group__state="active").distinct()
|
||||
|
||||
positions = BallotPositionDocEvent.objects.filter(doc=doc, type="changed_ballot_position", ballot=ballot).order_by("-time", '-id').select_related('ad')
|
||||
|
@ -456,7 +364,7 @@ def generate_issue_ballot_mailREDESIGN(request, doc, ballot):
|
|||
e = doc.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text")
|
||||
ballot_writeup = e.text if e else ""
|
||||
|
||||
return render_to_string("idrfc/issue_ballot_mailREDESIGN.txt",
|
||||
return render_to_string("doc/mail/issue_ballot_mail.txt",
|
||||
dict(doc=doc,
|
||||
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
|
||||
active_ad_positions=active_ad_positions,
|
||||
|
@ -468,9 +376,6 @@ def generate_issue_ballot_mailREDESIGN(request, doc, ballot):
|
|||
)
|
||||
)
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
generate_issue_ballot_mail = generate_issue_ballot_mailREDESIGN
|
||||
|
||||
def email_iana(request, doc, to, msg):
|
||||
# fix up message and send it with extra info on doc in headers
|
||||
import email
|
||||
|
@ -494,19 +399,6 @@ def extra_automation_headers(doc):
|
|||
return extra
|
||||
|
||||
def email_last_call_expired(doc):
|
||||
text = "IETF Last Call has ended, and the state has been changed to\n%s." % doc.idinternal.cur_state.state
|
||||
|
||||
send_mail(None,
|
||||
"iesg@ietf.org",
|
||||
"DraftTracker Mail System <iesg-secretary@ietf.org>",
|
||||
"Last Call Expired: %s" % doc.file_tag(),
|
||||
"idrfc/change_notice.txt",
|
||||
dict(text=text,
|
||||
doc=doc,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.idinternal.get_absolute_url()),
|
||||
cc="iesg-secretary@ietf.org")
|
||||
|
||||
def email_last_call_expiredREDESIGN(doc):
|
||||
text = "IETF Last Call has ended, and the state has been changed to\n%s." % doc.get_state("draft-iesg").name
|
||||
|
||||
to = [x.strip() for x in doc.notify.replace(';', ',').split(',')]
|
||||
|
@ -516,12 +408,8 @@ def email_last_call_expiredREDESIGN(doc):
|
|||
to,
|
||||
"DraftTracker Mail System <iesg-secretary@ietf.org>",
|
||||
"Last Call Expired: %s" % doc.file_tag(),
|
||||
"idrfc/change_notice.txt",
|
||||
"doc/mail/change_notice.txt",
|
||||
dict(text=text,
|
||||
doc=doc,
|
||||
url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()),
|
||||
cc="iesg-secretary@ietf.org")
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
email_last_call_expired = email_last_call_expiredREDESIGN
|
||||
|
|
@ -355,7 +355,6 @@ class Document(DocumentInfo):
|
|||
iesg_state = self.get_state("draft-iesg")
|
||||
iesg_state_summary = None
|
||||
if iesg_state:
|
||||
# This knowledge about which tags are reportable IESG substate tags is duplicated in idrfc
|
||||
iesg_substate = self.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
|
||||
# There really shouldn't be more than one tag in iesg_substate, but this will do something sort-of-sensible if there is
|
||||
iesg_state_summary = iesg_state.name
|
||||
|
|
|
@ -84,7 +84,7 @@ def render_ballot_icon(user, doc):
|
|||
|
||||
edit_position_url = ""
|
||||
if has_role(user, "Area Director"):
|
||||
edit_position_url = urlreverse('ietf.idrfc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk))
|
||||
edit_position_url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk))
|
||||
|
||||
title = "IESG positions (click to show more%s)" % (", right-click to edit position" if edit_position_url else "")
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
from django import template
|
||||
from django.core.cache import cache
|
||||
from django.template import loader
|
||||
from ietf.idtracker.models import Area
|
||||
|
||||
register = template.Library()
|
||||
|
|
@ -33,7 +33,8 @@
|
|||
from django import template
|
||||
from django.core.cache import cache
|
||||
from django.template import loader
|
||||
from ietf.idtracker.models import Area
|
||||
|
||||
from ietf.group.models import Group
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
@ -42,26 +43,27 @@ area_short_names = {
|
|||
'rai':'RAI'
|
||||
}
|
||||
|
||||
def get_short_name(area):
|
||||
if area.area_acronym.acronym in area_short_names:
|
||||
return area_short_names[area.area_acronym.acronym]
|
||||
else:
|
||||
area_name = area.area_acronym.name
|
||||
if area_name.endswith(" Area"):
|
||||
area_name = area_name[:-5]
|
||||
return area_name
|
||||
|
||||
class WgMenuNode(template.Node):
|
||||
def __init__(self):
|
||||
pass
|
||||
def render(self, context):
|
||||
x = cache.get('idrfc_wgmenu')
|
||||
x = cache.get('base_left_wgmenu')
|
||||
if x:
|
||||
return x
|
||||
areas = [{'area':x, 'short_name':get_short_name(x)} for x in Area.active_areas()]
|
||||
x = loader.render_to_string('base_wgmenu.html', {'areas':areas})
|
||||
cache.set('idrfc_wgmenu', x, 30*60)
|
||||
return x
|
||||
|
||||
areas = Group.objects.filter(type="area", state="active").order_by('acronym')
|
||||
groups = Group.objects.filter(type="wg", state="active", parent__in=areas).order_by("acronym")
|
||||
|
||||
for a in areas:
|
||||
a.short_area_name = area_short_names.get(a.acronym) or a.name
|
||||
if a.short_area_name.endswith(" Area"):
|
||||
a.short_area_name = a.short_area_name[:-len(" Area")]
|
||||
|
||||
a.active_groups = [g for g in groups if g.parent_id == a.id]
|
||||
|
||||
areas = [a for a in areas if a.active_groups]
|
||||
|
||||
res = loader.render_to_string('base_wgmenu.html', {'areas':areas})
|
||||
cache.set('base_left_wgmenu', x, 30*60)
|
||||
return res
|
||||
|
||||
def do_wg_menu(parser, token):
|
||||
return WgMenuNode()
|
|
@ -17,7 +17,10 @@ from ietf.meeting.models import Meeting, MeetingTypeName
|
|||
from ietf.iesg.models import TelechatDate
|
||||
|
||||
# extra tests
|
||||
from ietf.doc.tests_draft import *
|
||||
from ietf.doc.tests_ballot import *
|
||||
from ietf.doc.tests_conflict_review import *
|
||||
from ietf.doc.tests_status_change import *
|
||||
|
||||
|
||||
class SearchTestCase(django.test.TestCase):
|
||||
|
@ -243,3 +246,49 @@ class DocTestCase(django.test.TestCase):
|
|||
|
||||
r = self.client.get(urlreverse("ietf.doc.views_doc.document_json", kwargs=dict(name=doc.name)))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
|
||||
class AddCommentTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_add_comment(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_add_comment', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form textarea[name=comment]')), 1)
|
||||
|
||||
# request resurrect
|
||||
events_before = draft.docevent_set.count()
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(comment="This is a test."))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 1)
|
||||
self.assertEquals("This is a test.", draft.latest_event().desc)
|
||||
self.assertEquals("added_comment", draft.latest_event().type)
|
||||
self.assertEquals(len(outbox), mailbox_before + 1)
|
||||
self.assertTrue("updated" in outbox[-1]['Subject'])
|
||||
self.assertTrue(draft.name in outbox[-1]['Subject'])
|
||||
|
||||
# Make sure we can also do it as IANA
|
||||
self.client.login(remote_user="iana")
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form textarea[name=comment]')), 1)
|
||||
|
||||
|
||||
class TemplateTagTest(unittest.TestCase):
|
||||
def test_template_tags(self):
|
||||
import doctest
|
||||
from ietf.doc.templatetags import ietf_filters
|
||||
failures, tests = doctest.testmod(ietf_filters)
|
||||
self.assertEqual(failures, 0)
|
||||
|
|
495
ietf/doc/tests_ballot.py
Normal file
495
ietf/doc/tests_ballot.py
Normal file
|
@ -0,0 +1,495 @@
|
|||
import unittest
|
||||
import StringIO
|
||||
import os, shutil
|
||||
from datetime import date, timedelta, time
|
||||
|
||||
import django.test
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
from django.conf import settings
|
||||
|
||||
from pyquery import PyQuery
|
||||
import debug
|
||||
|
||||
from ietf.doc.models import *
|
||||
from ietf.name.models import *
|
||||
from ietf.group.models import *
|
||||
from ietf.person.models import *
|
||||
from ietf.meeting.models import Meeting, MeetingTypeName
|
||||
from ietf.iesg.models import TelechatDate
|
||||
from ietf.utils.test_utils import login_testing_unauthorized
|
||||
from ietf.utils.test_data import make_test_data
|
||||
from ietf.utils.mail import outbox
|
||||
|
||||
class EditPositionTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_edit_position(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=draft.name,
|
||||
ballot_id=draft.latest_event(BallotDocEvent, type="created_ballot").pk))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
ad = Person.objects.get(name="Aread Irector")
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(len(q('form input[name=position]')) > 0)
|
||||
self.assertEquals(len(q('form textarea[name=comment]')), 1)
|
||||
|
||||
# vote
|
||||
events_before = draft.docevent_set.count()
|
||||
|
||||
r = self.client.post(url, dict(position="discuss",
|
||||
discuss=" This is a discussion test. \n ",
|
||||
comment=" This is a test. \n "))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "discuss")
|
||||
self.assertTrue(" This is a discussion test." in pos.discuss)
|
||||
self.assertTrue(pos.discuss_time != None)
|
||||
self.assertTrue(" This is a test." in pos.comment)
|
||||
self.assertTrue(pos.comment_time != None)
|
||||
self.assertTrue("New position" in pos.desc)
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 3)
|
||||
|
||||
# recast vote
|
||||
events_before = draft.docevent_set.count()
|
||||
r = self.client.post(url, dict(position="noobj"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "noobj")
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 1)
|
||||
self.assertTrue("Position for" in pos.desc)
|
||||
|
||||
# clear vote
|
||||
events_before = draft.docevent_set.count()
|
||||
r = self.client.post(url, dict(position="norecord"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "norecord")
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 1)
|
||||
self.assertTrue("Position for" in pos.desc)
|
||||
|
||||
# change comment
|
||||
events_before = draft.docevent_set.count()
|
||||
r = self.client.post(url, dict(position="norecord", comment="New comment."))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "norecord")
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 2)
|
||||
self.assertTrue("Ballot comment text updated" in pos.desc)
|
||||
|
||||
def test_edit_position_as_secretary(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=draft.name,
|
||||
ballot_id=draft.latest_event(BallotDocEvent, type="created_ballot").pk))
|
||||
ad = Person.objects.get(name="Aread Irector")
|
||||
url += "?ad=%s" % ad.pk
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(len(q('form input[name=position]')) > 0)
|
||||
|
||||
# vote on behalf of AD
|
||||
events_before = draft.docevent_set.count()
|
||||
r = self.client.post(url, dict(position="discuss", discuss="Test discuss text"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "discuss")
|
||||
self.assertEquals(pos.discuss, "Test discuss text")
|
||||
self.assertTrue("New position" in pos.desc)
|
||||
self.assertTrue("by Sec" in pos.desc)
|
||||
|
||||
def test_cannot_edit_position_as_pre_ad(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=draft.name,
|
||||
ballot_id=draft.latest_event(BallotDocEvent, type="created_ballot").pk))
|
||||
|
||||
# transform to pre-ad
|
||||
ad_role = Role.objects.filter(name="ad")[0]
|
||||
ad_role.name_id = "pre-ad"
|
||||
ad_role.save()
|
||||
|
||||
# we can see
|
||||
login_testing_unauthorized(self, ad_role.person.user.username, url)
|
||||
|
||||
# but not touch
|
||||
r = self.client.post(url, dict(position="discuss", discuss="Test discuss text"))
|
||||
self.assertEquals(r.status_code, 403)
|
||||
|
||||
def test_send_ballot_comment(self):
|
||||
draft = make_test_data()
|
||||
draft.notify = "somebody@example.com"
|
||||
draft.save()
|
||||
|
||||
ad = Person.objects.get(name="Aread Irector")
|
||||
|
||||
ballot = draft.latest_event(BallotDocEvent, type="created_ballot")
|
||||
|
||||
BallotPositionDocEvent.objects.create(
|
||||
doc=draft, type="changed_ballot_position",
|
||||
by=ad, ad=ad, ballot=ballot, pos=BallotPositionName.objects.get(slug="discuss"),
|
||||
discuss="This draft seems to be lacking a clearer title?",
|
||||
discuss_time=datetime.datetime.now(),
|
||||
comment="Test!",
|
||||
comment_time=datetime.datetime.now())
|
||||
|
||||
url = urlreverse('doc_send_ballot_comment', kwargs=dict(name=draft.name,
|
||||
ballot_id=ballot.pk))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(len(q('form input[name="cc"]')) > 0)
|
||||
|
||||
# send
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(cc="test@example.com", cc_state_change="1"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
self.assertEquals(len(outbox), mailbox_before + 1)
|
||||
m = outbox[-1]
|
||||
self.assertTrue("COMMENT" in m['Subject'])
|
||||
self.assertTrue("DISCUSS" in m['Subject'])
|
||||
self.assertTrue(draft.name in m['Subject'])
|
||||
self.assertTrue("clearer title" in str(m))
|
||||
self.assertTrue("Test!" in str(m))
|
||||
|
||||
|
||||
class DeferBallotTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_defer_ballot(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
|
||||
|
||||
url = urlreverse('doc_defer_ballot', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
|
||||
# defer
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict())
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "defer")
|
||||
|
||||
self.assertEquals(len(outbox), mailbox_before + 2)
|
||||
self.assertTrue("State Update" in outbox[-2]['Subject'])
|
||||
self.assertTrue("Deferred" in outbox[-1]['Subject'])
|
||||
self.assertTrue(draft.file_tag() in outbox[-1]['Subject'])
|
||||
|
||||
def test_undefer_ballot(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="defer"))
|
||||
|
||||
url = urlreverse('doc_undefer_ballot', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
|
||||
# undefer
|
||||
r = self.client.post(url, dict())
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "iesg-eva")
|
||||
|
||||
class BallotWriteupsTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_edit_last_call_text(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_lastcall', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('textarea[name=last_call_text]')), 1)
|
||||
self.assertEquals(len(q('input[type=submit][value*="Save Last Call"]')), 1)
|
||||
# we're secretariat, so we got The Link
|
||||
self.assertEquals(len(q('a:contains("Make Last Call")')), 1)
|
||||
|
||||
# subject error
|
||||
r = self.client.post(url, dict(
|
||||
last_call_text="Subject: test\r\nhello\r\n\r\n",
|
||||
save_last_call_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(len(q('ul.errorlist')) > 0)
|
||||
|
||||
# save
|
||||
r = self.client.post(url, dict(
|
||||
last_call_text="This is a simple test.",
|
||||
save_last_call_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("This is a simple test" in draft.latest_event(WriteupDocEvent, type="changed_last_call_text").text)
|
||||
|
||||
# test regenerate
|
||||
r = self.client.post(url, dict(
|
||||
last_call_text="This is a simple test.",
|
||||
regenerate_last_call_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("Subject: Last Call" in draft.latest_event(WriteupDocEvent, type="changed_last_call_text").text)
|
||||
|
||||
|
||||
def test_request_last_call(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_lastcall', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# give us an announcement to send
|
||||
r = self.client.post(url, dict(regenerate_last_call_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
# send
|
||||
r = self.client.post(url, dict(
|
||||
last_call_text=draft.latest_event(WriteupDocEvent, type="changed_last_call_text").text,
|
||||
send_last_call_request="1"))
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "lc-req")
|
||||
self.assertEquals(len(outbox), mailbox_before + 3)
|
||||
self.assertTrue("Last Call" in outbox[-1]['Subject'])
|
||||
self.assertTrue(draft.name in outbox[-1]['Subject'])
|
||||
|
||||
def test_edit_ballot_writeup(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_writeupnotes', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# add a IANA review note
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iana-review", slug="not-ok"))
|
||||
DocEvent.objects.create(type="iana_review",
|
||||
doc=draft,
|
||||
by=Person.objects.get(user__username="iana"),
|
||||
desc="IANA does not approve of this document, it does not make sense.",
|
||||
)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('textarea[name=ballot_writeup]')), 1)
|
||||
self.assertEquals(len(q('input[type=submit][value*="Save Ballot Writeup"]')), 1)
|
||||
self.assertTrue("IANA does not" in r.content)
|
||||
|
||||
# save
|
||||
r = self.client.post(url, dict(
|
||||
ballot_writeup="This is a simple test.",
|
||||
save_ballot_writeup="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("This is a simple test" in draft.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text").text)
|
||||
|
||||
def test_issue_ballot(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_writeupnotes', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
ballot = draft.latest_event(BallotDocEvent, type="created_ballot")
|
||||
|
||||
def create_pos(num, vote, comment="", discuss=""):
|
||||
ad = Person.objects.get(name="Ad No%s" % num)
|
||||
e = BallotPositionDocEvent()
|
||||
e.doc = draft
|
||||
e.ballot = ballot
|
||||
e.by = ad
|
||||
e.ad = ad
|
||||
e.pos = BallotPositionName.objects.get(slug=vote)
|
||||
e.type = "changed_ballot_position"
|
||||
e.comment = comment
|
||||
if e.comment:
|
||||
e.comment_time = datetime.datetime.now()
|
||||
e.discuss = discuss
|
||||
if e.discuss:
|
||||
e.discuss_time = datetime.datetime.now()
|
||||
e.save()
|
||||
|
||||
# active
|
||||
create_pos(1, "yes", discuss="discuss1 " * 20)
|
||||
create_pos(2, "noobj", comment="comment2 " * 20)
|
||||
create_pos(3, "discuss", discuss="discuss3 " * 20, comment="comment3 " * 20)
|
||||
create_pos(4, "abstain")
|
||||
create_pos(5, "recuse")
|
||||
|
||||
# inactive
|
||||
create_pos(9, "yes")
|
||||
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(
|
||||
ballot_writeup="This is a test.",
|
||||
issue_ballot="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
|
||||
self.assertTrue(draft.latest_event(type="sent_ballot_announcement"))
|
||||
self.assertEquals(len(outbox), mailbox_before + 2)
|
||||
issue_email = outbox[-2]
|
||||
self.assertTrue("Evaluation:" in issue_email['Subject'])
|
||||
self.assertTrue("comment1" not in str(issue_email))
|
||||
self.assertTrue("comment2" in str(issue_email))
|
||||
self.assertTrue("comment3" in str(issue_email))
|
||||
self.assertTrue("discuss3" in str(issue_email))
|
||||
self.assertTrue("This is a test" in str(issue_email))
|
||||
self.assertTrue("The IESG has approved" in str(issue_email))
|
||||
|
||||
def test_edit_approval_text(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_approvaltext', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('textarea[name=approval_text]')), 1)
|
||||
self.assertEquals(len(q('input[type=submit][value*="Save Approval"]')), 1)
|
||||
|
||||
# save
|
||||
r = self.client.post(url, dict(
|
||||
approval_text="This is a simple test.",
|
||||
save_approval_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("This is a simple test" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
|
||||
|
||||
# test regenerate
|
||||
r = self.client.post(url, dict(regenerate_approval_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("Subject: Protocol Action" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
|
||||
|
||||
# test regenerate when it's a disapprove
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="nopubadw"))
|
||||
|
||||
r = self.client.post(url, dict(regenerate_approval_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("NOT be published" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
|
||||
|
||||
# test regenerate when it's a conflict review
|
||||
draft.group = Group.objects.get(type="individ")
|
||||
draft.stream_id = "irtf"
|
||||
draft.save()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
|
||||
|
||||
r = self.client.post(url, dict(regenerate_approval_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("Subject: Results of IETF-conflict review" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
|
||||
|
||||
class ApproveBallotTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_approve_ballot(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva")) # make sure it's approvable
|
||||
|
||||
url = urlreverse('doc_approve_ballot', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue("send out the announcement" in q('.actions input[type=submit]')[0].get('value').lower())
|
||||
self.assertEquals(len(q('.announcement pre:contains("Subject: Protocol Action")')), 1)
|
||||
|
||||
# approve
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(skiprfceditorpost="1"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "ann")
|
||||
self.assertEquals(len(outbox), mailbox_before + 4)
|
||||
self.assertTrue("Protocol Action" in outbox[-2]['Subject'])
|
||||
# the IANA copy
|
||||
self.assertTrue("Protocol Action" in outbox[-1]['Subject'])
|
||||
self.assertTrue(not outbox[-1]['CC'])
|
||||
self.assertTrue("Protocol Action" in draft.message_set.order_by("-time")[0].subject)
|
||||
|
||||
def test_disapprove_ballot(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="nopubadw"))
|
||||
|
||||
url = urlreverse('doc_approve_ballot', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# disapprove (the Martians aren't going to be happy)
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict())
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "dead")
|
||||
self.assertEquals(len(outbox), mailbox_before + 3)
|
||||
self.assertTrue("NOT be published" in str(outbox[-1]))
|
||||
|
||||
class MakeLastCallTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_make_last_call(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="lc-req"))
|
||||
|
||||
url = urlreverse('doc_make_last_call', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('input[name=last_call_sent_date]')), 1)
|
||||
|
||||
# make last call
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
expire_date = q('input[name=last_call_expiration_date]')[0].get("value")
|
||||
|
||||
r = self.client.post(url,
|
||||
dict(last_call_sent_date=q('input[name=last_call_sent_date]')[0].get("value"),
|
||||
last_call_expiration_date=expire_date
|
||||
))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "lc")
|
||||
self.assertEquals(draft.latest_event(LastCallDocEvent, "sent_last_call").expires.strftime("%Y-%m-%d"), expire_date)
|
||||
self.assertEquals(len(outbox), mailbox_before + 4)
|
||||
|
||||
self.assertTrue("Last Call" in outbox[-4]['Subject'])
|
||||
# the IANA copy
|
||||
self.assertTrue("Last Call" in outbox[-3]['Subject'])
|
||||
self.assertTrue("Last Call" in draft.message_set.order_by("-time")[0].subject)
|
||||
|
|
@ -1,35 +1,3 @@
|
|||
# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
# All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# * Neither the name of the Nokia Corporation and/or its
|
||||
# subsidiary(-ies) nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import unittest
|
||||
import StringIO
|
||||
import os, shutil
|
||||
|
@ -48,15 +16,10 @@ from ietf.group.models import *
|
|||
from ietf.person.models import *
|
||||
from ietf.meeting.models import Meeting, MeetingTypeName
|
||||
from ietf.iesg.models import TelechatDate
|
||||
from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest, login_testing_unauthorized
|
||||
from ietf.utils.test_utils import login_testing_unauthorized
|
||||
from ietf.utils.test_data import make_test_data
|
||||
from ietf.utils.mail import outbox
|
||||
|
||||
class IdRfcUrlTestCase(SimpleUrlTestCase):
|
||||
def testUrls(self):
|
||||
#self.doTestUrls(__file__)
|
||||
self.doTestUrls(os.path.join(os.path.dirname(os.path.abspath(__file__)), "testurlREDESIGN.list"))
|
||||
|
||||
|
||||
class ChangeStateTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
@ -443,556 +406,7 @@ class ResurrectTestCase(django.test.TestCase):
|
|||
self.assertEquals(draft.get_state_slug(), "active")
|
||||
self.assertTrue(draft.expires >= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1))
|
||||
self.assertEquals(len(outbox), mailbox_before + 1)
|
||||
|
||||
class AddCommentTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_add_comment(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_add_comment', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form textarea[name=comment]')), 1)
|
||||
|
||||
# request resurrect
|
||||
events_before = draft.docevent_set.count()
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(comment="This is a test."))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 1)
|
||||
self.assertEquals("This is a test.", draft.latest_event().desc)
|
||||
self.assertEquals("added_comment", draft.latest_event().type)
|
||||
self.assertEquals(len(outbox), mailbox_before + 1)
|
||||
self.assertTrue("updated" in outbox[-1]['Subject'])
|
||||
self.assertTrue(draft.name in outbox[-1]['Subject'])
|
||||
|
||||
# Make sure we can also do it as IANA
|
||||
self.client.login(remote_user="iana")
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('form textarea[name=comment]')), 1)
|
||||
|
||||
|
||||
class EditPositionTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_edit_position(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('ietf.idrfc.views_ballot.edit_position', kwargs=dict(name=draft.name,
|
||||
ballot_id=draft.latest_event(BallotDocEvent, type="created_ballot").pk))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
ad = Person.objects.get(name="Aread Irector")
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(len(q('form input[name=position]')) > 0)
|
||||
self.assertEquals(len(q('form textarea[name=comment]')), 1)
|
||||
|
||||
# vote
|
||||
events_before = draft.docevent_set.count()
|
||||
|
||||
r = self.client.post(url, dict(position="discuss",
|
||||
discuss=" This is a discussion test. \n ",
|
||||
comment=" This is a test. \n "))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "discuss")
|
||||
self.assertTrue(" This is a discussion test." in pos.discuss)
|
||||
self.assertTrue(pos.discuss_time != None)
|
||||
self.assertTrue(" This is a test." in pos.comment)
|
||||
self.assertTrue(pos.comment_time != None)
|
||||
self.assertTrue("New position" in pos.desc)
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 3)
|
||||
|
||||
# recast vote
|
||||
events_before = draft.docevent_set.count()
|
||||
r = self.client.post(url, dict(position="noobj"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "noobj")
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 1)
|
||||
self.assertTrue("Position for" in pos.desc)
|
||||
|
||||
# clear vote
|
||||
events_before = draft.docevent_set.count()
|
||||
r = self.client.post(url, dict(position="norecord"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "norecord")
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 1)
|
||||
self.assertTrue("Position for" in pos.desc)
|
||||
|
||||
# change comment
|
||||
events_before = draft.docevent_set.count()
|
||||
r = self.client.post(url, dict(position="norecord", comment="New comment."))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "norecord")
|
||||
self.assertEquals(draft.docevent_set.count(), events_before + 2)
|
||||
self.assertTrue("Ballot comment text updated" in pos.desc)
|
||||
|
||||
def test_edit_position_as_secretary(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('ietf.idrfc.views_ballot.edit_position', kwargs=dict(name=draft.name,
|
||||
ballot_id=draft.latest_event(BallotDocEvent, type="created_ballot").pk))
|
||||
ad = Person.objects.get(name="Aread Irector")
|
||||
url += "?ad=%s" % ad.pk
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(len(q('form input[name=position]')) > 0)
|
||||
|
||||
# vote on behalf of AD
|
||||
events_before = draft.docevent_set.count()
|
||||
r = self.client.post(url, dict(position="discuss", discuss="Test discuss text"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
pos = draft.latest_event(BallotPositionDocEvent, ad=ad)
|
||||
self.assertEquals(pos.pos.slug, "discuss")
|
||||
self.assertEquals(pos.discuss, "Test discuss text")
|
||||
self.assertTrue("New position" in pos.desc)
|
||||
self.assertTrue("by Sec" in pos.desc)
|
||||
|
||||
def test_cannot_edit_position_as_pre_ad(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('ietf.idrfc.views_ballot.edit_position', kwargs=dict(name=draft.name,
|
||||
ballot_id=draft.latest_event(BallotDocEvent, type="created_ballot").pk))
|
||||
|
||||
# transform to pre-ad
|
||||
ad_role = Role.objects.filter(name="ad")[0]
|
||||
ad_role.name_id = "pre-ad"
|
||||
ad_role.save()
|
||||
|
||||
# we can see
|
||||
login_testing_unauthorized(self, ad_role.person.user.username, url)
|
||||
|
||||
# but not touch
|
||||
r = self.client.post(url, dict(position="discuss", discuss="Test discuss text"))
|
||||
self.assertEquals(r.status_code, 403)
|
||||
|
||||
def test_send_ballot_comment(self):
|
||||
draft = make_test_data()
|
||||
draft.notify = "somebody@example.com"
|
||||
draft.save()
|
||||
|
||||
ad = Person.objects.get(name="Aread Irector")
|
||||
|
||||
ballot = draft.latest_event(BallotDocEvent, type="created_ballot")
|
||||
|
||||
BallotPositionDocEvent.objects.create(
|
||||
doc=draft, type="changed_ballot_position",
|
||||
by=ad, ad=ad, ballot=ballot, pos=BallotPositionName.objects.get(slug="discuss"),
|
||||
discuss="This draft seems to be lacking a clearer title?",
|
||||
discuss_time=datetime.datetime.now(),
|
||||
comment="Test!",
|
||||
comment_time=datetime.datetime.now())
|
||||
|
||||
url = urlreverse('doc_send_ballot_comment', kwargs=dict(name=draft.name,
|
||||
ballot_id=ballot.pk))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(len(q('form input[name="cc"]')) > 0)
|
||||
|
||||
# send
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(cc="test@example.com", cc_state_change="1"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
self.assertEquals(len(outbox), mailbox_before + 1)
|
||||
m = outbox[-1]
|
||||
self.assertTrue("COMMENT" in m['Subject'])
|
||||
self.assertTrue("DISCUSS" in m['Subject'])
|
||||
self.assertTrue(draft.name in m['Subject'])
|
||||
self.assertTrue("clearer title" in str(m))
|
||||
self.assertTrue("Test!" in str(m))
|
||||
|
||||
|
||||
class DeferBallotTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_defer_ballot(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
|
||||
|
||||
url = urlreverse('doc_defer_ballot', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
|
||||
# defer
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict())
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "defer")
|
||||
|
||||
self.assertEquals(len(outbox), mailbox_before + 2)
|
||||
self.assertTrue("State Update" in outbox[-2]['Subject'])
|
||||
self.assertTrue("Deferred" in outbox[-1]['Subject'])
|
||||
self.assertTrue(draft.file_tag() in outbox[-1]['Subject'])
|
||||
|
||||
def test_undefer_ballot(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="defer"))
|
||||
|
||||
url = urlreverse('doc_undefer_ballot', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
|
||||
# undefer
|
||||
r = self.client.post(url, dict())
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "iesg-eva")
|
||||
|
||||
class BallotWriteupsTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_edit_last_call_text(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_lastcall', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('textarea[name=last_call_text]')), 1)
|
||||
self.assertEquals(len(q('input[type=submit][value*="Save Last Call"]')), 1)
|
||||
# we're secretariat, so we got The Link
|
||||
self.assertEquals(len(q('a:contains("Make Last Call")')), 1)
|
||||
|
||||
# subject error
|
||||
r = self.client.post(url, dict(
|
||||
last_call_text="Subject: test\r\nhello\r\n\r\n",
|
||||
save_last_call_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue(len(q('ul.errorlist')) > 0)
|
||||
|
||||
# save
|
||||
r = self.client.post(url, dict(
|
||||
last_call_text="This is a simple test.",
|
||||
save_last_call_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("This is a simple test" in draft.latest_event(WriteupDocEvent, type="changed_last_call_text").text)
|
||||
|
||||
# test regenerate
|
||||
r = self.client.post(url, dict(
|
||||
last_call_text="This is a simple test.",
|
||||
regenerate_last_call_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("Subject: Last Call" in draft.latest_event(WriteupDocEvent, type="changed_last_call_text").text)
|
||||
|
||||
|
||||
def test_request_last_call(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_lastcall', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# give us an announcement to send
|
||||
r = self.client.post(url, dict(regenerate_last_call_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
# send
|
||||
r = self.client.post(url, dict(
|
||||
last_call_text=draft.latest_event(WriteupDocEvent, type="changed_last_call_text").text,
|
||||
send_last_call_request="1"))
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "lc-req")
|
||||
self.assertEquals(len(outbox), mailbox_before + 3)
|
||||
self.assertTrue("Last Call" in outbox[-1]['Subject'])
|
||||
self.assertTrue(draft.name in outbox[-1]['Subject'])
|
||||
|
||||
def test_edit_ballot_writeup(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_writeupnotes', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# add a IANA review note
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iana-review", slug="not-ok"))
|
||||
DocEvent.objects.create(type="iana_review",
|
||||
doc=draft,
|
||||
by=Person.objects.get(user__username="iana"),
|
||||
desc="IANA does not approve of this document, it does not make sense.",
|
||||
)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('textarea[name=ballot_writeup]')), 1)
|
||||
self.assertEquals(len(q('input[type=submit][value*="Save Ballot Writeup"]')), 1)
|
||||
self.assertTrue("IANA does not" in r.content)
|
||||
|
||||
# save
|
||||
r = self.client.post(url, dict(
|
||||
ballot_writeup="This is a simple test.",
|
||||
save_ballot_writeup="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("This is a simple test" in draft.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text").text)
|
||||
|
||||
def test_issue_ballot(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_writeupnotes', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "ad", url)
|
||||
|
||||
ballot = draft.latest_event(BallotDocEvent, type="created_ballot")
|
||||
|
||||
def create_pos(num, vote, comment="", discuss=""):
|
||||
ad = Person.objects.get(name="Ad No%s" % num)
|
||||
e = BallotPositionDocEvent()
|
||||
e.doc = draft
|
||||
e.ballot = ballot
|
||||
e.by = ad
|
||||
e.ad = ad
|
||||
e.pos = BallotPositionName.objects.get(slug=vote)
|
||||
e.type = "changed_ballot_position"
|
||||
e.comment = comment
|
||||
if e.comment:
|
||||
e.comment_time = datetime.datetime.now()
|
||||
e.discuss = discuss
|
||||
if e.discuss:
|
||||
e.discuss_time = datetime.datetime.now()
|
||||
e.save()
|
||||
|
||||
# active
|
||||
create_pos(1, "yes", discuss="discuss1 " * 20)
|
||||
create_pos(2, "noobj", comment="comment2 " * 20)
|
||||
create_pos(3, "discuss", discuss="discuss3 " * 20, comment="comment3 " * 20)
|
||||
create_pos(4, "abstain")
|
||||
create_pos(5, "recuse")
|
||||
|
||||
# inactive
|
||||
create_pos(9, "yes")
|
||||
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(
|
||||
ballot_writeup="This is a test.",
|
||||
issue_ballot="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
|
||||
self.assertTrue(draft.latest_event(type="sent_ballot_announcement"))
|
||||
self.assertEquals(len(outbox), mailbox_before + 2)
|
||||
issue_email = outbox[-2]
|
||||
self.assertTrue("Evaluation:" in issue_email['Subject'])
|
||||
self.assertTrue("comment1" not in str(issue_email))
|
||||
self.assertTrue("comment2" in str(issue_email))
|
||||
self.assertTrue("comment3" in str(issue_email))
|
||||
self.assertTrue("discuss3" in str(issue_email))
|
||||
self.assertTrue("This is a test" in str(issue_email))
|
||||
self.assertTrue("The IESG has approved" in str(issue_email))
|
||||
|
||||
def test_edit_approval_text(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_approvaltext', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('textarea[name=approval_text]')), 1)
|
||||
self.assertEquals(len(q('input[type=submit][value*="Save Approval"]')), 1)
|
||||
|
||||
# save
|
||||
r = self.client.post(url, dict(
|
||||
approval_text="This is a simple test.",
|
||||
save_approval_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("This is a simple test" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
|
||||
|
||||
# test regenerate
|
||||
r = self.client.post(url, dict(regenerate_approval_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("Subject: Protocol Action" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
|
||||
|
||||
# test regenerate when it's a disapprove
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="nopubadw"))
|
||||
|
||||
r = self.client.post(url, dict(regenerate_approval_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("NOT be published" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
|
||||
|
||||
# test regenerate when it's a conflict review
|
||||
draft.group = Group.objects.get(type="individ")
|
||||
draft.stream_id = "irtf"
|
||||
draft.save()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
|
||||
|
||||
r = self.client.post(url, dict(regenerate_approval_text="1"))
|
||||
self.assertEquals(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("Subject: Results of IETF-conflict review" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
|
||||
|
||||
class ApproveBallotTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_approve_ballot(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva")) # make sure it's approvable
|
||||
|
||||
url = urlreverse('doc_approve_ballot', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertTrue("send out the announcement" in q('.actions input[type=submit]')[0].get('value').lower())
|
||||
self.assertEquals(len(q('.announcement pre:contains("Subject: Protocol Action")')), 1)
|
||||
|
||||
# approve
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(skiprfceditorpost="1"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "ann")
|
||||
self.assertEquals(len(outbox), mailbox_before + 4)
|
||||
self.assertTrue("Protocol Action" in outbox[-2]['Subject'])
|
||||
# the IANA copy
|
||||
self.assertTrue("Protocol Action" in outbox[-1]['Subject'])
|
||||
self.assertTrue(not outbox[-1]['CC'])
|
||||
self.assertTrue("Protocol Action" in draft.message_set.order_by("-time")[0].subject)
|
||||
|
||||
def test_disapprove_ballot(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="nopubadw"))
|
||||
|
||||
url = urlreverse('doc_approve_ballot', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# disapprove (the Martians aren't going to be happy)
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict())
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "dead")
|
||||
self.assertEquals(len(outbox), mailbox_before + 3)
|
||||
self.assertTrue("NOT be published" in str(outbox[-1]))
|
||||
|
||||
class MakeLastCallTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_make_last_call(self):
|
||||
draft = make_test_data()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="lc-req"))
|
||||
|
||||
url = urlreverse('doc_make_last_call', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEquals(len(q('input[name=last_call_sent_date]')), 1)
|
||||
|
||||
# make last call
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
expire_date = q('input[name=last_call_expiration_date]')[0].get("value")
|
||||
|
||||
r = self.client.post(url,
|
||||
dict(last_call_sent_date=q('input[name=last_call_sent_date]')[0].get("value"),
|
||||
last_call_expiration_date=expire_date
|
||||
))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-iesg"), "lc")
|
||||
self.assertEquals(draft.latest_event(LastCallDocEvent, "sent_last_call").expires.strftime("%Y-%m-%d"), expire_date)
|
||||
self.assertEquals(len(outbox), mailbox_before + 4)
|
||||
|
||||
self.assertTrue("Last Call" in outbox[-4]['Subject'])
|
||||
# the IANA copy
|
||||
self.assertTrue("Last Call" in outbox[-3]['Subject'])
|
||||
self.assertTrue("Last Call" in draft.message_set.order_by("-time")[0].subject)
|
||||
|
||||
class RequestPublicationTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_request_publication(self):
|
||||
draft = make_test_data()
|
||||
draft.stream = StreamName.objects.get(slug="iab")
|
||||
draft.group = Group.objects.get(acronym="iab")
|
||||
draft.intended_std_level = IntendedStdLevelName.objects.get(slug="inf")
|
||||
draft.save()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-stream-iab", slug="approved"))
|
||||
|
||||
url = urlreverse('doc_request_publication', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "iabchair", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
subject = q('input#id_subject')[0].get("value")
|
||||
self.assertTrue("Document Action" in subject)
|
||||
body = q('.request-publication #id_body').text()
|
||||
self.assertTrue("Informational" in body)
|
||||
self.assertTrue("IAB" in body)
|
||||
|
||||
# approve
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(subject=subject, body=body, skiprfceditorpost="1"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-stream-iab"), "rfc-edit")
|
||||
self.assertEquals(len(outbox), mailbox_before + 2)
|
||||
self.assertTrue("Document Action" in outbox[-2]['Subject'])
|
||||
self.assertTrue("Document Action" in draft.message_set.order_by("-time")[0].subject)
|
||||
# the IANA copy
|
||||
self.assertTrue("Document Action" in outbox[-1]['Subject'])
|
||||
self.assertTrue(not outbox[-1]['CC'])
|
||||
|
||||
class ExpireIDsTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
@ -1019,7 +433,7 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
f.close()
|
||||
|
||||
def test_in_draft_expire_freeze(self):
|
||||
from ietf.idrfc.expire import in_draft_expire_freeze
|
||||
from ietf.doc.expire import in_draft_expire_freeze
|
||||
|
||||
Meeting.objects.create(number="123",
|
||||
type=MeetingTypeName.objects.get(slug="ietf"),
|
||||
|
@ -1034,7 +448,7 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(ietf_monday, time(0, 0, 0))))
|
||||
|
||||
def test_warn_expirable_drafts(self):
|
||||
from ietf.idrfc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft
|
||||
from ietf.doc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft
|
||||
|
||||
draft = make_test_data()
|
||||
|
||||
|
@ -1057,7 +471,7 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
self.assertTrue("wgchairman@ietf.org" in str(outbox[-1]))
|
||||
|
||||
def test_expire_drafts(self):
|
||||
from ietf.idrfc.expire import get_expired_drafts, send_expire_notice_for_draft, expire_draft
|
||||
from ietf.doc.expire import get_expired_drafts, send_expire_notice_for_draft, expire_draft
|
||||
|
||||
draft = make_test_data()
|
||||
|
||||
|
@ -1102,7 +516,7 @@ class ExpireIDsTestCase(django.test.TestCase):
|
|||
def test_clean_up_draft_files(self):
|
||||
draft = make_test_data()
|
||||
|
||||
from ietf.idrfc.expire import clean_up_draft_files
|
||||
from ietf.doc.expire import clean_up_draft_files
|
||||
|
||||
# put unknown file
|
||||
unknown = "draft-i-am-unknown-01.txt"
|
||||
|
@ -1180,7 +594,7 @@ class ExpireLastCallTestCase(django.test.TestCase):
|
|||
fixtures = ['names']
|
||||
|
||||
def test_expire_last_call(self):
|
||||
from ietf.idrfc.lastcall import get_expired_last_calls, expire_last_call
|
||||
from ietf.doc.lastcall import get_expired_last_calls, expire_last_call
|
||||
|
||||
# check that non-expirable drafts aren't expired
|
||||
|
||||
|
@ -1430,7 +844,6 @@ class IndividualInfoFormsTestCase(django.test.TestCase):
|
|||
|
||||
# direct edit
|
||||
r = self.client.post(url,dict(content='here is a new writeup',submit_response="1"))
|
||||
print r.content
|
||||
self.assertEquals(r.status_code,302)
|
||||
self.doc = Document.objects.get(name=self.docname)
|
||||
self.assertTrue(self.doc.latest_event(WriteupDocEvent,type="changed_protocol_writeup").text.startswith('here is a new writeup'))
|
||||
|
@ -1454,3 +867,41 @@ class IndividualInfoFormsTestCase(django.test.TestCase):
|
|||
self.docname='draft-ietf-mars-test'
|
||||
self.doc = Document.objects.get(name=self.docname)
|
||||
|
||||
class RequestPublicationTestCase(django.test.TestCase):
|
||||
fixtures = ['names']
|
||||
|
||||
def test_request_publication(self):
|
||||
draft = make_test_data()
|
||||
draft.stream = StreamName.objects.get(slug="iab")
|
||||
draft.group = Group.objects.get(acronym="iab")
|
||||
draft.intended_std_level = IntendedStdLevelName.objects.get(slug="inf")
|
||||
draft.save()
|
||||
draft.set_state(State.objects.get(used=True, type="draft-stream-iab", slug="approved"))
|
||||
|
||||
url = urlreverse('doc_request_publication', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "iabchair", url)
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEquals(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
subject = q('input#id_subject')[0].get("value")
|
||||
self.assertTrue("Document Action" in subject)
|
||||
body = q('.request-publication #id_body').text()
|
||||
self.assertTrue("Informational" in body)
|
||||
self.assertTrue("IAB" in body)
|
||||
|
||||
# approve
|
||||
mailbox_before = len(outbox)
|
||||
|
||||
r = self.client.post(url, dict(subject=subject, body=body, skiprfceditorpost="1"))
|
||||
self.assertEquals(r.status_code, 302)
|
||||
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertEquals(draft.get_state_slug("draft-stream-iab"), "rfc-edit")
|
||||
self.assertEquals(len(outbox), mailbox_before + 2)
|
||||
self.assertTrue("Document Action" in outbox[-2]['Subject'])
|
||||
self.assertTrue("Document Action" in draft.message_set.order_by("-time")[0].subject)
|
||||
# the IANA copy
|
||||
self.assertTrue("Document Action" in outbox[-1]['Subject'])
|
||||
self.assertTrue(not outbox[-1]['CC'])
|
|
@ -31,8 +31,8 @@
|
|||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from django.conf.urls.defaults import patterns, url, include
|
||||
from ietf.idrfc import views_search, views_edit, views_ballot, views
|
||||
from ietf.doc.models import State
|
||||
from ietf.doc import views_search, views_draft, views_ballot
|
||||
from ietf.doc import views_status_change
|
||||
from ietf.doc import views_doc
|
||||
|
||||
|
@ -65,23 +65,23 @@ urlpatterns = patterns('',
|
|||
(r'^(?P<name>[A-Za-z0-9._+-]+)/ballotpopup/(?P<ballot_id>[0-9]+)/$', views_doc.ballot_popup),
|
||||
#(r'^(?P<name>[A-Za-z0-9._+-]+)/ballot.json$', views_doc.ballot_json), # legacy view
|
||||
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/state/$', views_edit.change_state, name='doc_change_state'), # IESG state
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/state/(?P<state_type>iana-action|iana-review)/$', views_edit.change_iana_state, name='doc_change_iana_state'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/info/$', views_edit.edit_info, name='doc_edit_info'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/requestresurrect/$', views_edit.request_resurrect, name='doc_request_resurrect'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/resurrect/$', views_edit.resurrect, name='doc_resurrect'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/addcomment/$', views_edit.add_comment, name='doc_add_comment'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/state/$', views_draft.change_state, name='doc_change_state'), # IESG state
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/state/(?P<state_type>iana-action|iana-review)/$', views_draft.change_iana_state, name='doc_change_iana_state'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/info/$', views_draft.edit_info, name='doc_edit_info'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/requestresurrect/$', views_draft.request_resurrect, name='doc_request_resurrect'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/resurrect/$', views_draft.resurrect, name='doc_resurrect'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/addcomment/$', views_doc.add_comment, name='doc_add_comment'),
|
||||
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/stream/$', views_edit.change_stream, name='doc_change_stream'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/notify/$', views_edit.edit_notices, name='doc_change_notify'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/status/$', views_edit.change_intention, name='doc_change_intended_status'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/telechat/$', views_edit.telechat_date, name='doc_change_telechat_date'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/iesgnote/$', views_edit.edit_iesg_note, name='doc_change_iesg_note'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/ad/$', views_edit.edit_ad, name='doc_change_ad'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/consensus/$', views_edit.edit_consensus, name='doc_edit_consensus'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/shepherd/$', views_edit.edit_shepherd, name='doc_edit_shepherd'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/shepherdwriteup/$', views_edit.edit_shepherd_writeup, name='doc_edit_shepherd_writeup'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/requestpublication/$', views_edit.request_publication, name='doc_request_publication'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/stream/$', views_draft.change_stream, name='doc_change_stream'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/notify/$', views_draft.edit_notices, name='doc_change_notify'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/status/$', views_draft.change_intention, name='doc_change_intended_status'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/telechat/$', views_draft.telechat_date, name='doc_change_telechat_date'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/iesgnote/$', views_draft.edit_iesg_note, name='doc_change_iesg_note'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/ad/$', views_draft.edit_ad, name='doc_change_ad'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/consensus/$', views_draft.edit_consensus, name='doc_edit_consensus'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/shepherd/$', views_draft.edit_shepherd, name='doc_edit_shepherd'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/shepherdwriteup/$', views_draft.edit_shepherd_writeup, name='doc_edit_shepherd_writeup'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/requestpublication/$', views_draft.request_publication, name='doc_request_publication'),
|
||||
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/clearballot/$', views_ballot.clear_ballot, name='doc_clear_ballot'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/deferballot/$', views_ballot.defer_ballot, name='doc_defer_ballot'),
|
||||
|
@ -98,10 +98,3 @@ urlpatterns = patterns('',
|
|||
(r'^(?P<name>[A-Za-z0-9._+-]+)/conflict-review/', include('ietf.doc.urls_conflict_review')),
|
||||
(r'^(?P<name>[A-Za-z0-9._+-]+)/status-change/', include('ietf.doc.urls_status_change')),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('django.views.generic.simple',
|
||||
url(r'^help/state/charter/$', 'direct_to_template', { 'template': 'doc/states.html', 'extra_context': { 'states': State.objects.filter(used=True, type="charter"),'title':"Charter" } }, name='help_charter_states'),
|
||||
url(r'^help/state/conflict-review/$', 'direct_to_template', { 'template': 'doc/states.html', 'extra_context': { 'states': State.objects.filter(used=True, type="conflrev").order_by("order"),'title':"Conflict Review" } }, name='help_conflict_review_states'),
|
||||
url(r'^help/state/status-change/$', 'direct_to_template', { 'template': 'doc/states.html', 'extra_context': { 'states': State.objects.filter(type="statchg").order_by("order"),'title':"RFC Status Change" } }, name='help_status_change_states'),
|
||||
)
|
||||
|
|
@ -3,9 +3,7 @@ import math
|
|||
|
||||
from django.conf import settings
|
||||
|
||||
# Should this move from idrfc to doc?
|
||||
from ietf.idrfc import markup_txt
|
||||
|
||||
from ietf.utils import markup_txt
|
||||
from ietf.doc.models import *
|
||||
|
||||
def get_state_types(doc):
|
||||
|
@ -241,3 +239,54 @@ def nice_consensus(consensus):
|
|||
False: "No"
|
||||
}
|
||||
return mapping[consensus]
|
||||
|
||||
def update_telechat(request, doc, by, new_telechat_date, new_returning_item=None):
|
||||
from ietf.doc.models import TelechatDocEvent
|
||||
|
||||
on_agenda = bool(new_telechat_date)
|
||||
|
||||
prev = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
|
||||
prev_returning = bool(prev and prev.returning_item)
|
||||
prev_telechat = prev.telechat_date if prev else None
|
||||
prev_agenda = bool(prev_telechat)
|
||||
|
||||
returning_item_changed = bool(new_returning_item != None and new_returning_item != prev_returning)
|
||||
|
||||
if new_returning_item == None:
|
||||
returning = prev_returning
|
||||
else:
|
||||
returning = new_returning_item
|
||||
|
||||
if returning == prev_returning and new_telechat_date == prev_telechat:
|
||||
# fully updated, nothing to do
|
||||
return
|
||||
|
||||
# auto-update returning item
|
||||
if (not returning_item_changed and on_agenda and prev_agenda
|
||||
and new_telechat_date != prev_telechat):
|
||||
returning = True
|
||||
|
||||
e = TelechatDocEvent()
|
||||
e.type = "scheduled_for_telechat"
|
||||
e.by = by
|
||||
e.doc = doc
|
||||
e.returning_item = returning
|
||||
e.telechat_date = new_telechat_date
|
||||
|
||||
if on_agenda != prev_agenda:
|
||||
if on_agenda:
|
||||
e.desc = "Placed on agenda for telechat - %s" % (new_telechat_date)
|
||||
else:
|
||||
e.desc = "Removed from agenda for telechat"
|
||||
elif on_agenda and new_telechat_date != prev_telechat:
|
||||
e.desc = "Telechat date has been changed to <b>%s</b> from <b>%s</b>" % (
|
||||
new_telechat_date, prev_telechat)
|
||||
else:
|
||||
# we didn't reschedule but flipped returning item bit - let's
|
||||
# just explain that
|
||||
if returning:
|
||||
e.desc = "Set telechat returning item indication"
|
||||
else:
|
||||
e.desc = "Removed telechat returning item indication"
|
||||
|
||||
e.save()
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# ballot management (voting, commenting, writeups, ...) for Area
|
||||
# Directors and Secretariat
|
||||
|
||||
import re, os
|
||||
from datetime import datetime, date, time, timedelta
|
||||
import re, os, datetime
|
||||
|
||||
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
|
@ -16,16 +16,12 @@ from django.conf import settings
|
|||
import debug
|
||||
|
||||
from ietf.utils.mail import send_mail_text, send_mail_preformatted
|
||||
from ietf.ietfauth.decorators import group_required, role_required
|
||||
from ietf.idtracker.templatetags.ietf_filters import in_group
|
||||
from ietf.ietfauth.decorators import has_role, role_required
|
||||
from ietf.idtracker.models import *
|
||||
from ietf.iesg.models import *
|
||||
from ietf.iesg.models import TelechatDate
|
||||
from ietf.ipr.models import IprDetail
|
||||
from ietf.ipr.search import iprs_from_docs
|
||||
from ietf.idrfc.mails import *
|
||||
from ietf.idrfc.utils import *
|
||||
from ietf.idrfc.lastcall import request_last_call
|
||||
from ietf.doc.mails import *
|
||||
from ietf.doc.lastcall import request_last_call
|
||||
|
||||
from ietf.doc.utils import *
|
||||
from ietf.doc.models import *
|
||||
|
@ -34,9 +30,6 @@ from ietf.name.models import BallotPositionName
|
|||
from ietf.message.utils import infer_message
|
||||
from ietf.person.models import Person
|
||||
|
||||
from ietf.doc.utils import log_state_changed as docutil_log_state_changed
|
||||
from ietf.idrfc.utils import log_state_changed as idrfcutil_log_state_changed
|
||||
|
||||
BALLOT_CHOICES = (("yes", "Yes"),
|
||||
("noobj", "No Objection"),
|
||||
("discuss", "Discuss"),
|
||||
|
@ -54,20 +47,20 @@ def do_undefer_ballot(request, doc):
|
|||
logging, and the Document object.
|
||||
'''
|
||||
login = request.user.get_profile()
|
||||
telechat_date = TelechatDates.objects.all()[0].date1
|
||||
telechat_date = TelechatDate.objects.active().order_by("date")[0].date
|
||||
save_document_in_history(doc)
|
||||
|
||||
prev_state = doc.friendly_state()
|
||||
if doc.type_id == 'draft':
|
||||
doc.set_state(State.objects.get(used=True, type="draft-iesg", slug='iesg-eva'))
|
||||
prev_tag = doc.tags.filter(slug__in=('point', 'ad-f-up', 'need-rev', 'extpty'))
|
||||
prev_tag = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
|
||||
prev_tag = prev_tag[0] if prev_tag else None
|
||||
if prev_tag:
|
||||
doc.tags.remove(prev_tag)
|
||||
elif doc.type_id == 'conflrev':
|
||||
doc.set_state(State.objects.get(used=True, type='conflrev',slug='iesgeval'))
|
||||
|
||||
e = docutil_log_state_changed(request, doc, login, doc.friendly_state(), prev_state)
|
||||
e = log_state_changed(request, doc, login, doc.friendly_state(), prev_state)
|
||||
|
||||
doc.time = e.time
|
||||
doc.save()
|
||||
|
@ -96,15 +89,8 @@ def get_ballot_info(ballot, area_director):
|
|||
|
||||
return (pos, discuss, comment)
|
||||
|
||||
class EditPositionForm(forms.Form):
|
||||
pass
|
||||
|
||||
# -------------------------------------------------
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def edit_position(request, name):
|
||||
pass
|
||||
|
||||
class EditPositionFormREDESIGN(forms.Form):
|
||||
class EditPositionForm(forms.Form):
|
||||
position = forms.ModelChoiceField(queryset=BallotPositionName.objects.all(), widget=forms.RadioSelect, initial="norecord", required=True)
|
||||
discuss = forms.CharField(required=False, widget=forms.Textarea)
|
||||
comment = forms.CharField(required=False, widget=forms.Textarea)
|
||||
|
@ -123,7 +109,7 @@ class EditPositionFormREDESIGN(forms.Form):
|
|||
return entered_discuss
|
||||
|
||||
@role_required('Area Director','Secretariat')
|
||||
def edit_positionREDESIGN(request, name, ballot_id):
|
||||
def edit_position(request, name, ballot_id):
|
||||
"""Vote and edit discuss and comment on document as Area Director."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
ballot = get_object_or_404(BallotDocEvent, type="created_ballot", pk=ballot_id, doc=doc)
|
||||
|
@ -244,7 +230,7 @@ def edit_positionREDESIGN(request, name, ballot_id):
|
|||
|
||||
ballot_deferred = doc.active_defer_event()
|
||||
|
||||
return render_to_response('idrfc/edit_positionREDESIGN.html',
|
||||
return render_to_response('doc/ballot/edit_position.html',
|
||||
dict(doc=doc,
|
||||
form=form,
|
||||
ad=ad,
|
||||
|
@ -257,85 +243,9 @@ def edit_positionREDESIGN(request, name, ballot_id):
|
|||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
edit_position = edit_positionREDESIGN
|
||||
EditPositionForm = EditPositionFormREDESIGN
|
||||
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def send_ballot_comment(request, name):
|
||||
"""Email Internet Draft ballot discuss/comment for area director."""
|
||||
doc = get_object_or_404(InternetDraft, filename=name)
|
||||
if not doc.idinternal:
|
||||
raise Http404()
|
||||
|
||||
ad = login = IESGLogin.objects.get(login_name=request.user.username)
|
||||
|
||||
return_to_url = request.GET.get('return_to_url')
|
||||
if not return_to_url:
|
||||
return_to_url = doc.idinternal.get_absolute_url()
|
||||
|
||||
if 'HTTP_REFERER' in request.META:
|
||||
back_url = request.META['HTTP_REFERER']
|
||||
else:
|
||||
back_url = doc.idinternal.get_absolute_url()
|
||||
|
||||
|
||||
|
||||
# if we're in the Secretariat, we can select an AD to act as stand-in for
|
||||
if not in_group(request.user, "Area_Director"):
|
||||
ad_username = request.GET.get('ad')
|
||||
if not ad_username:
|
||||
raise Http404()
|
||||
ad = get_object_or_404(IESGLogin, login_name=ad_username)
|
||||
|
||||
pos, discuss, comment = get_ballot_info(doc.idinternal.ballot, ad)
|
||||
|
||||
subj = []
|
||||
d = ""
|
||||
if pos and pos.discuss == 1 and discuss and discuss.text:
|
||||
d = discuss.text
|
||||
subj.append("DISCUSS")
|
||||
c = ""
|
||||
if comment and comment.text:
|
||||
c = comment.text
|
||||
subj.append("COMMENT")
|
||||
|
||||
|
||||
ad_name = str(ad)
|
||||
ad_name_genitive = ad_name + "'" if ad_name.endswith('s') else ad_name + "'s"
|
||||
subject = "%s %s on %s" % (ad_name_genitive, pos.name() if pos else "No Position" , doc.filename + '-' + doc.revision_display())
|
||||
if subj:
|
||||
subject += ": (with "+" and ".join(subj)+")"
|
||||
|
||||
body = render_to_string("idrfc/ballot_comment_mail.txt",
|
||||
dict(discuss=d, comment=c, ad=ad, doc=doc, pos=pos, settings=settings))
|
||||
frm = u"%s <%s>" % ad.person.email()
|
||||
to = "The IESG <iesg@ietf.org>"
|
||||
|
||||
if request.method == 'POST':
|
||||
cc = [x.strip() for x in request.POST.get("cc", "").split(',') if x.strip()]
|
||||
if request.POST.get("cc_state_change") and doc.idinternal.state_change_notice_to:
|
||||
cc.extend(doc.idinternal.state_change_notice_to.split(','))
|
||||
|
||||
send_mail_text(request, to, frm, subject, body, cc=", ".join(cc))
|
||||
|
||||
return HttpResponseRedirect(return_to_url)
|
||||
|
||||
return render_to_response('idrfc/send_ballot_comment.html',
|
||||
dict(doc=doc,
|
||||
subject=subject,
|
||||
body=body,
|
||||
frm=frm,
|
||||
to=to,
|
||||
ad=ad,
|
||||
can_send=d or c,
|
||||
back_url=back_url,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@role_required('Area Director','Secretariat')
|
||||
def send_ballot_commentREDESIGN(request, name, ballot_id):
|
||||
def send_ballot_comment(request, name, ballot_id):
|
||||
"""Email document ballot position discuss/comment for Area Director."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
ballot = get_object_or_404(BallotDocEvent, type="created_ballot", pk=ballot_id, doc=doc)
|
||||
|
@ -379,7 +289,7 @@ def send_ballot_commentREDESIGN(request, name, ballot_id):
|
|||
if subj:
|
||||
subject += ": (with %s)" % " and ".join(subj)
|
||||
|
||||
body = render_to_string("idrfc/ballot_comment_mail.txt",
|
||||
body = render_to_string("doc/ballot/ballot_comment_mail.txt",
|
||||
dict(discuss=d,
|
||||
comment=c,
|
||||
ad=ad.plain_name(),
|
||||
|
@ -395,11 +305,11 @@ def send_ballot_commentREDESIGN(request, name, ballot_id):
|
|||
if request.POST.get("cc_state_change") and doc.notify:
|
||||
cc.extend(doc.notify.split(','))
|
||||
|
||||
send_mail_text(request, to, frm, subject, body, cc=", ".join(cc))
|
||||
send_mail_text(request, to, frm, subject, body, cc=u", ".join(cc))
|
||||
|
||||
return HttpResponseRedirect(return_to_url)
|
||||
|
||||
return render_to_response('idrfc/send_ballot_commentREDESIGN.html',
|
||||
return render_to_response('doc/ballot/send_ballot_comment.html',
|
||||
dict(doc=doc,
|
||||
subject=subject,
|
||||
body=body,
|
||||
|
@ -411,10 +321,7 @@ def send_ballot_commentREDESIGN(request, name, ballot_id):
|
|||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
send_ballot_comment = send_ballot_commentREDESIGN
|
||||
|
||||
@group_required('Secretariat')
|
||||
@role_required('Secretariat')
|
||||
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)
|
||||
|
@ -427,17 +334,13 @@ def clear_ballot(request, name):
|
|||
do_undefer_ballot(request,doc)
|
||||
return HttpResponseRedirect(urlreverse("doc_view", kwargs=dict(name=doc.name)))
|
||||
|
||||
return render_to_response('idrfc/clear_ballot.html',
|
||||
return render_to_response('doc/ballot/clear_ballot.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
@role_required('Area Director','Secretariat')
|
||||
def defer_ballot(request, name):
|
||||
pass
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def defer_ballotREDESIGN(request, name):
|
||||
"""Signal post-pone of ballot, notifying relevant parties."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
if doc.type_id not in ('draft','conflrev'):
|
||||
|
@ -446,7 +349,7 @@ def defer_ballotREDESIGN(request, name):
|
|||
raise Http404()
|
||||
|
||||
login = request.user.get_profile()
|
||||
telechat_date = TelechatDates.objects.all()[0].date2
|
||||
telechat_date = TelechatDate.objects.active().order_by("date")[1].date
|
||||
|
||||
if request.method == 'POST':
|
||||
save_document_in_history(doc)
|
||||
|
@ -461,7 +364,7 @@ def defer_ballotREDESIGN(request, name):
|
|||
elif doc.type_id == 'conflrev':
|
||||
doc.set_state(State.objects.get(used=True, type='conflrev', slug='defer'))
|
||||
|
||||
e = docutil_log_state_changed(request, doc, login, doc.friendly_state(), prev_state)
|
||||
e = log_state_changed(request, doc, login, doc.friendly_state(), prev_state)
|
||||
|
||||
doc.time = e.time
|
||||
doc.save()
|
||||
|
@ -473,21 +376,14 @@ def defer_ballotREDESIGN(request, name):
|
|||
|
||||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
|
||||
return render_to_response('idrfc/defer_ballot.html',
|
||||
return render_to_response('doc/ballot/defer_ballot.html',
|
||||
dict(doc=doc,
|
||||
telechat_date=telechat_date,
|
||||
back_url=doc.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
defer_ballot = defer_ballotREDESIGN
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
@role_required('Area Director','Secretariat')
|
||||
def undefer_ballot(request, name):
|
||||
pass
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def undefer_ballotREDESIGN(request, name):
|
||||
"""undo deferral of ballot ballot."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
if doc.type_id not in ('draft','conflrev'):
|
||||
|
@ -495,109 +391,19 @@ def undefer_ballotREDESIGN(request, name):
|
|||
if doc.type_id == 'draft' and not doc.get_state("draft-iesg"):
|
||||
raise Http404()
|
||||
|
||||
telechat_date = TelechatDates.objects.all()[0].date1
|
||||
telechat_date = TelechatDate.objects.active().order_by("date")[0].date
|
||||
|
||||
if request.method == 'POST':
|
||||
do_undefer_ballot(request,doc)
|
||||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
|
||||
return render_to_response('idrfc/undefer_ballot.html',
|
||||
return render_to_response('doc/ballot/undefer_ballot.html',
|
||||
dict(doc=doc,
|
||||
telechat_date=telechat_date,
|
||||
back_url=doc.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
undefer_ballot = undefer_ballotREDESIGN
|
||||
|
||||
class LastCallTextForm(forms.ModelForm):
|
||||
def clean_last_call_text(self):
|
||||
lines = self.cleaned_data["last_call_text"].split("\r\n")
|
||||
for l, next in zip(lines, lines[1:]):
|
||||
if l.startswith('Subject:') and next.strip():
|
||||
raise forms.ValidationError("Subject line appears to have a line break, please make sure there is no line breaks in the subject line and that it is followed by an empty line.")
|
||||
|
||||
return self.cleaned_data["last_call_text"].replace("\r", "")
|
||||
|
||||
class Meta:
|
||||
model = BallotInfo
|
||||
fields = ["last_call_text"]
|
||||
|
||||
class BallotWriteupForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = BallotInfo
|
||||
fields = ["ballot_writeup"]
|
||||
|
||||
def clean_ballot_writeup(self):
|
||||
return self.cleaned_data["ballot_writeup"].replace("\r", "")
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def lastcalltext(request, name):
|
||||
"""Editing of the last call text"""
|
||||
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)
|
||||
|
||||
last_call_form = LastCallTextForm(instance=ballot)
|
||||
|
||||
if request.method == 'POST':
|
||||
if "save_last_call_text" in request.POST or "send_last_call_request" in request.POST:
|
||||
last_call_form = LastCallTextForm(request.POST, instance=ballot)
|
||||
if last_call_form.is_valid():
|
||||
ballot.last_call_text = last_call_form.cleaned_data["last_call_text"]
|
||||
add_document_comment(request, doc, "Last Call text changed")
|
||||
ballot.save()
|
||||
|
||||
if "send_last_call_request" in request.POST:
|
||||
doc.idinternal.change_state(IDState.objects.get(document_state_id=IDState.LAST_CALL_REQUESTED), None)
|
||||
|
||||
change = idrfcutil_log_state_changed(request, doc, login)
|
||||
email_owner(request, doc, doc.idinternal.job_owner, login, change)
|
||||
request_last_call(request, doc)
|
||||
|
||||
doc.idinternal.event_date = date.today()
|
||||
doc.idinternal.save()
|
||||
|
||||
return render_to_response('idrfc/last_call_requested.html',
|
||||
dict(doc=doc),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if "regenerate_last_call_text" in request.POST:
|
||||
ballot.last_call_text = generate_last_call_announcement(request, doc)
|
||||
ballot.save()
|
||||
|
||||
# make sure form has the updated text
|
||||
last_call_form = LastCallTextForm(instance=ballot)
|
||||
|
||||
doc.idinternal.event_date = date.today()
|
||||
doc.idinternal.save()
|
||||
|
||||
can_request_last_call = doc.idinternal.cur_state_id < 27
|
||||
can_make_last_call = doc.idinternal.cur_state_id < 20
|
||||
can_announce = doc.idinternal.cur_state_id > 19
|
||||
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_lastcalltext.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.idinternal.get_absolute_url(),
|
||||
ballot=ballot,
|
||||
last_call_form=last_call_form,
|
||||
can_request_last_call=can_request_last_call,
|
||||
can_make_last_call=can_make_last_call,
|
||||
need_intended_status=need_intended_status,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
class LastCallTextFormREDESIGN(forms.Form):
|
||||
class LastCallTextForm(forms.Form):
|
||||
last_call_text = forms.CharField(widget=forms.Textarea, required=True)
|
||||
|
||||
def clean_last_call_text(self):
|
||||
|
@ -608,8 +414,9 @@ class LastCallTextFormREDESIGN(forms.Form):
|
|||
|
||||
return self.cleaned_data["last_call_text"].replace("\r", "")
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def lastcalltextREDESIGN(request, name):
|
||||
|
||||
@role_required('Area Director','Secretariat')
|
||||
def lastcalltext(request, name):
|
||||
"""Editing of the last call text"""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
if not doc.get_state("draft-iesg"):
|
||||
|
@ -639,7 +446,7 @@ def lastcalltextREDESIGN(request, name):
|
|||
if "send_last_call_request" in request.POST:
|
||||
save_document_in_history(doc)
|
||||
|
||||
prev = doc.get_state("draft-iesg")
|
||||
prev_state = doc.friendly_state()
|
||||
doc.set_state(State.objects.get(used=True, type="draft-iesg", slug='lc-req'))
|
||||
|
||||
prev_tag = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
|
||||
|
@ -647,17 +454,17 @@ def lastcalltextREDESIGN(request, name):
|
|||
if prev_tag:
|
||||
doc.tags.remove(prev_tag)
|
||||
|
||||
e = idrfcutil_log_state_changed(request, doc, login, prev, prev_tag)
|
||||
e = log_state_changed(request, doc, login, doc.friendly_state(), prev_state)
|
||||
|
||||
doc.time = e.time
|
||||
doc.save()
|
||||
|
||||
email_state_changed(request, doc, e.desc)
|
||||
email_owner(request, doc, doc.ad, login, e.desc)
|
||||
email_ad(request, doc, doc.ad, login, e.desc)
|
||||
|
||||
request_last_call(request, doc)
|
||||
|
||||
return render_to_response('idrfc/last_call_requested.html',
|
||||
return render_to_response('doc/draft/last_call_requested.html',
|
||||
dict(doc=doc),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
@ -677,7 +484,7 @@ def lastcalltextREDESIGN(request, name):
|
|||
if not doc.intended_std_level:
|
||||
need_intended_status = doc.file_tag()
|
||||
|
||||
return render_to_response('idrfc/ballot_lastcalltext.html',
|
||||
return render_to_response('doc/ballot/lastcalltext.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.get_absolute_url(),
|
||||
last_call_form=form,
|
||||
|
@ -687,95 +494,14 @@ def lastcalltextREDESIGN(request, name):
|
|||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
LastCallTextForm = LastCallTextFormREDESIGN
|
||||
lastcalltext = lastcalltextREDESIGN
|
||||
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
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, 'drafts-eval@icann.org', 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))
|
||||
|
||||
class BallotWriteupFormREDESIGN(forms.Form):
|
||||
class BallotWriteupForm(forms.Form):
|
||||
ballot_writeup = forms.CharField(widget=forms.Textarea, required=True)
|
||||
|
||||
def clean_ballot_writeup(self):
|
||||
return self.cleaned_data["ballot_writeup"].replace("\r", "")
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def ballot_writeupnotesREDESIGN(request, name):
|
||||
@role_required('Area Director','Secretariat')
|
||||
def ballot_writeupnotes(request, name):
|
||||
"""Editing of ballot write-up and notes"""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
||||
|
@ -828,7 +554,7 @@ def ballot_writeupnotesREDESIGN(request, name):
|
|||
e.desc = "Ballot has been issued"
|
||||
e.save()
|
||||
|
||||
return render_to_response('idrfc/ballot_issued.html',
|
||||
return render_to_response('doc/ballot/ballot_issued.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
@ -838,7 +564,7 @@ def ballot_writeupnotesREDESIGN(request, name):
|
|||
if not doc.intended_std_level:
|
||||
need_intended_status = doc.file_tag()
|
||||
|
||||
return render_to_response('idrfc/ballot_writeupnotesREDESIGN.html',
|
||||
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")),
|
||||
|
@ -847,19 +573,13 @@ def ballot_writeupnotesREDESIGN(request, name):
|
|||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
BallotWriteupForm = BallotWriteupFormREDESIGN
|
||||
ballot_writeupnotes = ballot_writeupnotesREDESIGN
|
||||
|
||||
|
||||
|
||||
class ApprovalTextForm(forms.Form):
|
||||
approval_text = forms.CharField(widget=forms.Textarea, required=True)
|
||||
|
||||
def clean_approval_text(self):
|
||||
return self.cleaned_data["approval_text"].replace("\r", "")
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
@role_required('Area Director','Secretariat')
|
||||
def ballot_approvaltext(request, name):
|
||||
"""Editing of approval text"""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
@ -898,7 +618,7 @@ def ballot_approvaltext(request, name):
|
|||
if not doc.intended_std_level:
|
||||
need_intended_status = doc.file_tag()
|
||||
|
||||
return render_to_response('idrfc/ballot_approvaltext.html',
|
||||
return render_to_response('doc/ballot/approvaltext.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.get_absolute_url(),
|
||||
approval_text_form=form,
|
||||
|
@ -907,80 +627,8 @@ def ballot_approvaltext(request, name):
|
|||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
@group_required('Secretariat')
|
||||
@role_required('Secretariat')
|
||||
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, "drafts-approval@icann.org", 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))
|
||||
|
||||
@group_required('Secretariat')
|
||||
def approve_ballotREDESIGN(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"):
|
||||
|
@ -1017,13 +665,14 @@ def approve_ballotREDESIGN(request, name):
|
|||
else:
|
||||
new_state = State.objects.get(used=True, type="draft-iesg", slug="ann")
|
||||
|
||||
prev_friendly_state = doc.friendly_state()
|
||||
prev_state = doc.get_state("draft-iesg")
|
||||
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/rfceditor_post_approved_draft_failed.html',
|
||||
return render_to_response('doc/draft/rfceditor_post_approved_draft_failed.html',
|
||||
dict(name=doc.name,
|
||||
response=response,
|
||||
error=error),
|
||||
|
@ -1053,13 +702,13 @@ def approve_ballotREDESIGN(request, name):
|
|||
|
||||
change_description = e.desc + " and state has been changed to %s" % doc.get_state("draft-iesg").name
|
||||
|
||||
e = idrfcutil_log_state_changed(request, doc, login, prev_state, prev_tag)
|
||||
e = log_state_changed(request, doc, login, doc.friendly_state(), prev_friendly_state)
|
||||
|
||||
doc.time = e.time
|
||||
doc.save()
|
||||
|
||||
email_state_changed(request, doc, change_description)
|
||||
email_owner(request, doc, doc.ad, login, change_description)
|
||||
email_ad(request, doc, doc.ad, login, change_description)
|
||||
|
||||
# send announcement
|
||||
|
||||
|
@ -1076,21 +725,18 @@ def approve_ballotREDESIGN(request, name):
|
|||
|
||||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
|
||||
return render_to_response('idrfc/approve_ballot.html',
|
||||
return render_to_response('doc/ballot/approve_ballot.html',
|
||||
dict(doc=doc,
|
||||
action=action,
|
||||
announcement=announcement),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
approve_ballot = approve_ballotREDESIGN
|
||||
|
||||
|
||||
class MakeLastCallForm(forms.Form):
|
||||
last_call_sent_date = forms.DateField(required=True)
|
||||
last_call_expiration_date = forms.DateField(required=True)
|
||||
|
||||
@group_required('Secretariat')
|
||||
@role_required('Secretariat')
|
||||
def make_last_call(request, name):
|
||||
"""Make last call for Internet Draft, sending out announcement."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
@ -1121,31 +767,28 @@ def make_last_call(request, name):
|
|||
|
||||
save_document_in_history(doc)
|
||||
|
||||
prev_state = doc.get_state("draft-iesg")
|
||||
if doc.type.slug == 'draft':
|
||||
|
||||
prev = doc.get_state("draft-iesg")
|
||||
doc.set_state(State.objects.get(used=True, type="draft-iesg", slug='lc'))
|
||||
|
||||
prev_tag = doc.tags.filter(slug__in=('point', 'ad-f-up', 'need-rev', 'extpty'))
|
||||
prev_tag = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
|
||||
prev_tag = prev_tag[0] if prev_tag else None
|
||||
if prev_tag:
|
||||
doc.tags.remove(prev_tag)
|
||||
|
||||
e = idrfcutil_log_state_changed(request, doc, login, prev, prev_tag)
|
||||
e = log_state_changed(request, doc, login, doc.friendly_state(), prev_state)
|
||||
change_description = "Last call has been made for %s and state has been changed to %s" % (doc.name, doc.get_state("draft-iesg").name)
|
||||
|
||||
elif doc.type.slug == 'statchg':
|
||||
|
||||
prev = doc.friendly_state()
|
||||
doc.set_state(State.objects.get(used=True, type="statchg", slug='in-lc'))
|
||||
e = docutil_log_state_changed(request, doc, login, doc.friendly_state(), prev)
|
||||
e = log_state_changed(request, doc, login, doc.friendly_state(), prev_state)
|
||||
change_description = "Last call has been made for %s and state has been changed to %s" % (doc.name, doc.friendly_state())
|
||||
|
||||
doc.time = e.time
|
||||
doc.save()
|
||||
|
||||
email_state_changed(request, doc, change_description)
|
||||
email_owner(request, doc, doc.ad, login, change_description)
|
||||
email_ad(request, doc, doc.ad, login, change_description)
|
||||
|
||||
e = LastCallDocEvent(doc=doc, by=login)
|
||||
e.type = "sent_last_call"
|
||||
|
@ -1168,18 +811,18 @@ def make_last_call(request, name):
|
|||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
else:
|
||||
initial = {}
|
||||
initial["last_call_sent_date"] = date.today()
|
||||
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 = 'idrfc/make_last_callREDESIGN.html'
|
||||
templ = 'doc/draft/make_last_call.html'
|
||||
else:
|
||||
expire_days=28
|
||||
templ = 'doc/status_change/make_last_call.html'
|
||||
|
||||
initial["last_call_expiration_date"] = date.today() + timedelta(days=expire_days)
|
||||
initial["last_call_expiration_date"] = datetime.date.today() + datetime.timedelta(days=expire_days)
|
||||
|
||||
form = MakeLastCallForm(initial=initial)
|
||||
|
|
@ -8,16 +8,14 @@ from django.template import RequestContext
|
|||
from django.template.loader import render_to_string
|
||||
from django.conf import settings
|
||||
|
||||
from ietf.idrfc.utils import update_telechat
|
||||
|
||||
from ietf.doc.utils import log_state_changed
|
||||
from ietf.doc.utils import log_state_changed, update_telechat
|
||||
|
||||
from ietf.doc.models import save_document_in_history
|
||||
from ietf.doc.utils import create_ballot_if_not_open, close_open_ballots, get_document_content
|
||||
from ietf.ietfauth.decorators import has_role, role_required
|
||||
from ietf.utils.textupload import get_cleaned_text_file_content
|
||||
from ietf.utils.mail import send_mail_preformatted
|
||||
from ietf.idrfc.mails import email_iana
|
||||
from ietf.doc.mails import email_iana
|
||||
|
||||
from ietf.doc.models import State, Document, DocHistory, DocAlias
|
||||
from ietf.doc.models import DocEvent, NewRevisionDocEvent, WriteupDocEvent, TelechatDocEvent, BallotDocEvent, BallotPositionDocEvent
|
||||
|
@ -89,7 +87,7 @@ def change_state(request, name, option=None):
|
|||
dict(form=form,
|
||||
doc=review,
|
||||
login=login,
|
||||
help_url=reverse('help_conflict_review_states'),
|
||||
help_url=reverse('state_help', kwargs=dict(type="conflict-review")),
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ from django.utils.decorators import decorator_from_middleware
|
|||
from django.middleware.gzip import GZipMiddleware
|
||||
from django.core.urlresolvers import reverse as urlreverse, NoReverseMatch
|
||||
from django.conf import settings
|
||||
from django import forms
|
||||
|
||||
from ietf.doc.models import *
|
||||
from ietf.doc.utils import *
|
||||
|
@ -50,6 +51,7 @@ from ietf.ietfauth.utils import *
|
|||
from ietf.doc.views_status_change import RELATION_SLUGS as status_change_relationships
|
||||
from ietf.wgcharter.utils import historic_milestones_for_charter
|
||||
from ietf.ipr.models import IprDocAlias
|
||||
from ietf.doc.mails import email_ad
|
||||
|
||||
def render_document_top(request, doc, tab, name):
|
||||
tabs = []
|
||||
|
@ -455,7 +457,7 @@ def document_main(request, name, rev=None):
|
|||
else:
|
||||
sorted_relations=None
|
||||
|
||||
return render_to_response("idrfc/document_status_change.html",
|
||||
return render_to_response("doc/document_status_change.html",
|
||||
dict(doc=doc,
|
||||
top=top,
|
||||
content=content,
|
||||
|
@ -773,3 +775,35 @@ def ballot_json(request, name):
|
|||
response.write(json.dumps(ballot.dict(), indent=2))
|
||||
return response
|
||||
|
||||
class AddCommentForm(forms.Form):
|
||||
comment = forms.CharField(required=True, widget=forms.Textarea)
|
||||
|
||||
@role_required('Area Director', 'Secretariat', 'IANA', 'RFC Editor')
|
||||
def add_comment(request, name):
|
||||
"""Add comment to history of document."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
||||
login = request.user.get_profile()
|
||||
|
||||
if request.method == 'POST':
|
||||
form = AddCommentForm(request.POST)
|
||||
if form.is_valid():
|
||||
c = form.cleaned_data['comment']
|
||||
|
||||
e = DocEvent(doc=doc, by=login)
|
||||
e.type = "added_comment"
|
||||
e.desc = c
|
||||
e.save()
|
||||
|
||||
if doc.type_id == "draft":
|
||||
email_ad(request, doc, doc.ad, login,
|
||||
"A new comment added by %s" % login.name)
|
||||
return HttpResponseRedirect(urlreverse("doc_history", kwargs=dict(name=doc.name)))
|
||||
else:
|
||||
form = AddCommentForm()
|
||||
|
||||
return render_to_response('doc/add_comment.html',
|
||||
dict(doc=doc,
|
||||
form=form),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
# changing state and metadata and commenting on Internet Drafts for
|
||||
# Area Directors and Secretariat
|
||||
# changing state and metadata on Internet Drafts
|
||||
|
||||
import re, os, datetime
|
||||
|
||||
import re, os
|
||||
from datetime import datetime, date, time, timedelta
|
||||
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
|
@ -16,14 +15,11 @@ from django.forms.util import ErrorList
|
|||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from ietf.utils.mail import send_mail_text, send_mail_message
|
||||
from ietf.ietfauth.decorators import group_required, has_role, role_required
|
||||
from ietf.ietfauth.utils import user_is_person
|
||||
from ietf.idtracker.templatetags.ietf_filters import in_group
|
||||
from ietf.idtracker.models import *
|
||||
from ietf.iesg.models import *
|
||||
from ietf.idrfc.mails import *
|
||||
from ietf.idrfc.utils import *
|
||||
from ietf.idrfc.lastcall import request_last_call
|
||||
from ietf.ietfauth.decorators import role_required
|
||||
from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream, user_is_person
|
||||
from ietf.iesg.models import TelechatDate
|
||||
from ietf.doc.mails import *
|
||||
from ietf.doc.lastcall import request_last_call
|
||||
from ietf.utils.textupload import get_cleaned_text_file_content
|
||||
from ietf.person.forms import EmailsField
|
||||
from ietf.group.models import Group
|
||||
|
@ -38,16 +34,8 @@ from ietf.doc.utils import *
|
|||
from ietf.name.models import IntendedStdLevelName, DocTagName, StreamName
|
||||
from ietf.person.models import Person, Email
|
||||
from ietf.message.models import Message
|
||||
from ietf.idrfc.utils import log_state_changed
|
||||
|
||||
class ChangeStateForm(forms.Form):
|
||||
pass
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def change_state(request, name):
|
||||
pass
|
||||
|
||||
class ChangeStateFormREDESIGN(forms.Form):
|
||||
state = forms.ModelChoiceField(State.objects.filter(used=True, type="draft-iesg"), empty_label=None, required=True)
|
||||
substate = forms.ModelChoiceField(DocTagName.objects.filter(slug__in=IESG_SUBSTATE_TAGS), required=False)
|
||||
comment = forms.CharField(widget=forms.Textarea, required=False)
|
||||
|
@ -62,15 +50,15 @@ class ChangeStateFormREDESIGN(forms.Form):
|
|||
|
||||
# tag handling is a bit awkward since the UI still works
|
||||
# as if IESG tags are a substate
|
||||
prev_tag = doc.tags.filter(slug__in=('point', 'ad-f-up', 'need-rev', 'extpty'))
|
||||
prev_tag = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
|
||||
prev_tag = prev_tag[0] if prev_tag else None
|
||||
|
||||
if state == prev and tag == prev_tag:
|
||||
self._errors['comment'] = ErrorList([u'State not changed. Comments entered will be lost with no state change. Please go back and use the Add Comment feature on the history tab to add comments without changing state.'])
|
||||
return retclean
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def change_stateREDESIGN(request, name):
|
||||
@role_required('Area Director','Secretariat')
|
||||
def change_state(request, name):
|
||||
"""Change state of Internet Draft, notifying parties as necessary
|
||||
and logging the change as a comment."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
@ -85,6 +73,7 @@ def change_stateREDESIGN(request, name):
|
|||
if form.is_valid():
|
||||
next_state = form.cleaned_data['state']
|
||||
prev_state = doc.get_state("draft-iesg")
|
||||
prev_friendly_state = doc.friendly_state()
|
||||
|
||||
tag = form.cleaned_data['substate']
|
||||
comment = form.cleaned_data['comment'].strip()
|
||||
|
@ -105,7 +94,7 @@ def change_stateREDESIGN(request, name):
|
|||
if tag:
|
||||
doc.tags.add(tag)
|
||||
|
||||
e = log_state_changed(request, doc, login, prev_state, prev_tag)
|
||||
e = log_state_changed(request, doc, login, doc.friendly_state(), prev_friendly_state)
|
||||
|
||||
if comment:
|
||||
c = DocEvent(type="added_comment")
|
||||
|
@ -120,7 +109,7 @@ def change_stateREDESIGN(request, name):
|
|||
doc.save()
|
||||
|
||||
email_state_changed(request, doc, e.desc)
|
||||
email_owner(request, doc, doc.ad, login, e.desc)
|
||||
email_ad(request, doc, doc.ad, login, e.desc)
|
||||
|
||||
|
||||
if prev_state and prev_state.slug in ("ann", "rfcqueue") and next_state.slug not in ("rfcqueue", "pub"):
|
||||
|
@ -133,7 +122,7 @@ def change_stateREDESIGN(request, name):
|
|||
if next_state.slug == "lc-req":
|
||||
request_last_call(request, doc)
|
||||
|
||||
return render_to_response('idrfc/last_call_requested.html',
|
||||
return render_to_response('doc/draft/last_call_requested.html',
|
||||
dict(doc=doc,
|
||||
url=doc.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
@ -161,7 +150,7 @@ def change_stateREDESIGN(request, name):
|
|||
to_iesg_eval = State.objects.get(used=True, type="draft-iesg", slug="iesg-eva")
|
||||
next_states = next_states.exclude(slug="iesg-eva")
|
||||
|
||||
return render_to_response('idrfc/change_stateREDESIGN.html',
|
||||
return render_to_response('doc/draft/change_state.html',
|
||||
dict(form=form,
|
||||
doc=doc,
|
||||
state=state,
|
||||
|
@ -170,10 +159,6 @@ def change_stateREDESIGN(request, name):
|
|||
to_iesg_eval=to_iesg_eval),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
change_state = change_stateREDESIGN
|
||||
ChangeStateForm = ChangeStateFormREDESIGN
|
||||
|
||||
class ChangeIanaStateForm(forms.Form):
|
||||
state = forms.ModelChoiceField(State.objects.all(), required=False)
|
||||
|
||||
|
@ -213,7 +198,7 @@ def change_iana_state(request, name, state_type):
|
|||
else:
|
||||
form = ChangeIanaStateForm(state_type, initial=dict(state=prev_state.pk if prev_state else None))
|
||||
|
||||
return render_to_response('idrfc/change_iana_state.html',
|
||||
return render_to_response('doc/draft/change_iana_state.html',
|
||||
dict(form=form,
|
||||
doc=doc),
|
||||
context_instance=RequestContext(request))
|
||||
|
@ -277,7 +262,7 @@ def change_stream(request, name):
|
|||
stream = doc.stream
|
||||
form = ChangeStreamForm(initial=dict(stream=stream))
|
||||
|
||||
return render_to_response('idrfc/change_stream.html',
|
||||
return render_to_response('doc/draft/change_stream.html',
|
||||
dict(form=form,
|
||||
doc=doc,
|
||||
),
|
||||
|
@ -327,7 +312,7 @@ def change_intention(request, name):
|
|||
doc.time = e.time
|
||||
doc.save()
|
||||
|
||||
email_owner(request, doc, doc.ad, login, email_desc)
|
||||
email_ad(request, doc, doc.ad, login, email_desc)
|
||||
|
||||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
|
||||
|
@ -335,45 +320,13 @@ def change_intention(request, name):
|
|||
intended_std_level = doc.intended_std_level
|
||||
form = ChangeIntentionForm(initial=dict(intended_std_level=intended_std_level))
|
||||
|
||||
return render_to_response('idrfc/change_intended_status.html',
|
||||
return render_to_response('doc/draft/change_intended_status.html',
|
||||
dict(form=form,
|
||||
doc=doc,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
def dehtmlify_textarea_text(s):
|
||||
return s.replace("<br>", "\n").replace("<b>", "").replace("</b>", "").replace(" ", " ")
|
||||
|
||||
class EditInfoForm(forms.Form):
|
||||
pass
|
||||
|
||||
def get_initial_state_change_notice(doc):
|
||||
# set change state notice to something sensible
|
||||
receivers = []
|
||||
if doc.group_id == Acronym.INDIVIDUAL_SUBMITTER:
|
||||
for a in doc.authors.all():
|
||||
# maybe it would be more appropriate to use a.email() ?
|
||||
e = a.person.email()[1]
|
||||
if e:
|
||||
receivers.append(e)
|
||||
else:
|
||||
receivers.append("%s-chairs@%s" % (doc.group.acronym, settings.TOOLS_SERVER))
|
||||
for editor in doc.group.ietfwg.wgeditor_set.all():
|
||||
e = editor.person.email()[1]
|
||||
if e:
|
||||
receivers.append(e)
|
||||
|
||||
receivers.append("%s@%s" % (doc.filename, settings.TOOLS_SERVER))
|
||||
return ", ".join(receivers)
|
||||
|
||||
def get_new_ballot_id():
|
||||
return IDInternal.objects.aggregate(Max('ballot'))['ballot__max'] + 1
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def edit_info(request, name):
|
||||
pass
|
||||
|
||||
class EditInfoFormREDESIGN(forms.Form):
|
||||
intended_std_level = forms.ModelChoiceField(IntendedStdLevelName.objects.filter(used=True), empty_label="(None)", required=True, label="Intended RFC status")
|
||||
area = forms.ModelChoiceField(Group.objects.filter(type="area", state="active"), empty_label="(None - individual submission)", required=False, label="Assigned to area")
|
||||
ad = forms.ModelChoiceField(Person.objects.filter(role__name="ad", role__group__state="active").order_by('name'), label="Responsible AD", empty_label="(None)", required=True)
|
||||
|
@ -421,8 +374,8 @@ def get_initial_notify(doc):
|
|||
receivers.append("%s@%s" % (doc.name, settings.TOOLS_SERVER))
|
||||
return ", ".join(receivers)
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def edit_infoREDESIGN(request, name):
|
||||
@role_required('Area Director','Secretariat')
|
||||
def edit_info(request, name):
|
||||
"""Edit various Internet Draft attributes, notifying parties as
|
||||
necessary and logging changes as document events."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
@ -530,7 +483,7 @@ def edit_infoREDESIGN(request, name):
|
|||
doc.time = datetime.datetime.now()
|
||||
|
||||
if changes and not new_document:
|
||||
email_owner(request, doc, orig_ad, login, "\n".join(changes))
|
||||
email_ad(request, doc, orig_ad, login, "\n".join(changes))
|
||||
|
||||
doc.save()
|
||||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
|
@ -552,7 +505,7 @@ def edit_infoREDESIGN(request, name):
|
|||
if doc.group.type_id not in ("individ", "area"):
|
||||
form.standard_fields = [x for x in form.standard_fields if x.name != "area"]
|
||||
|
||||
return render_to_response('idrfc/edit_infoREDESIGN.html',
|
||||
return render_to_response('doc/draft/edit_info.html',
|
||||
dict(doc=doc,
|
||||
form=form,
|
||||
user=request.user,
|
||||
|
@ -560,37 +513,8 @@ def edit_infoREDESIGN(request, name):
|
|||
ballot_issued=doc.latest_event(type="sent_ballot_announcement")),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
EditInfoForm = EditInfoFormREDESIGN
|
||||
edit_info = edit_infoREDESIGN
|
||||
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
@role_required('Area Director','Secretariat')
|
||||
def request_resurrect(request, name):
|
||||
"""Request resurrect of expired Internet Draft."""
|
||||
doc = get_object_or_404(InternetDraft, filename=name)
|
||||
if doc.status.status != "Expired":
|
||||
raise Http404()
|
||||
|
||||
if not doc.idinternal:
|
||||
doc.idinternal = IDInternal(draft=doc, rfc_flag=type(doc) == Rfc)
|
||||
|
||||
login = IESGLogin.objects.get(login_name=request.user.username)
|
||||
|
||||
if request.method == 'POST':
|
||||
email_resurrect_requested(request, doc, login)
|
||||
add_document_comment(request, doc, "Resurrection was requested")
|
||||
doc.idinternal.resurrect_requested_by = login
|
||||
doc.idinternal.save()
|
||||
return HttpResponseRedirect(doc.idinternal.get_absolute_url())
|
||||
|
||||
return render_to_response('idrfc/request_resurrect.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.idinternal.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
def request_resurrectREDESIGN(request, name):
|
||||
"""Request resurrect of expired Internet Draft."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
if doc.get_state_slug() != "expired":
|
||||
|
@ -608,44 +532,13 @@ def request_resurrectREDESIGN(request, name):
|
|||
|
||||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
|
||||
return render_to_response('idrfc/request_resurrect.html',
|
||||
return render_to_response('doc/draft/request_resurrect.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
request_resurrect = request_resurrectREDESIGN
|
||||
|
||||
@group_required('Secretariat')
|
||||
@role_required('Secretariat')
|
||||
def resurrect(request, name):
|
||||
"""Resurrect expired Internet Draft."""
|
||||
doc = get_object_or_404(InternetDraft, filename=name)
|
||||
if doc.status.status != "Expired":
|
||||
raise Http404()
|
||||
|
||||
if not doc.idinternal:
|
||||
doc.idinternal = IDInternal(draft=doc, rfc_flag=type(doc) == Rfc)
|
||||
|
||||
login = IESGLogin.objects.get(login_name=request.user.username)
|
||||
|
||||
if request.method == 'POST':
|
||||
if doc.idinternal.resurrect_requested_by:
|
||||
email_resurrection_completed(request, doc)
|
||||
add_document_comment(request, doc, "Resurrection was completed")
|
||||
doc.idinternal.resurrect_requested_by = None
|
||||
doc.idinternal.event_date = date.today()
|
||||
doc.idinternal.save()
|
||||
doc.status = IDStatus.objects.get(status="Active")
|
||||
doc.save()
|
||||
return HttpResponseRedirect(doc.idinternal.get_absolute_url())
|
||||
|
||||
return render_to_response('idrfc/resurrect.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.idinternal.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@group_required('Secretariat')
|
||||
def resurrectREDESIGN(request, name):
|
||||
"""Resurrect expired Internet Draft."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
if doc.get_state_slug() != "expired":
|
||||
|
@ -671,81 +564,16 @@ def resurrectREDESIGN(request, name):
|
|||
doc.save()
|
||||
return HttpResponseRedirect(doc.get_absolute_url())
|
||||
|
||||
return render_to_response('idrfc/resurrect.html',
|
||||
return render_to_response('doc/draft/resurrect.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
resurrect = resurrectREDESIGN
|
||||
|
||||
|
||||
class AddCommentForm(forms.Form):
|
||||
comment = forms.CharField(required=True, widget=forms.Textarea)
|
||||
|
||||
@group_required('Area_Director','Secretariat', 'IANA')
|
||||
def add_comment(request, name):
|
||||
"""Add comment to Internet Draft."""
|
||||
doc = get_object_or_404(InternetDraft, filename=name)
|
||||
if not doc.idinternal:
|
||||
raise Http404()
|
||||
|
||||
login = IESGLogin.objects.get(login_name=request.user.username)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = AddCommentForm(request.POST)
|
||||
if form.is_valid():
|
||||
c = form.cleaned_data['comment']
|
||||
add_document_comment(request, doc, c)
|
||||
email_owner(request, doc, doc.idinternal.job_owner, login,
|
||||
"A new comment added by %s" % login)
|
||||
return HttpResponseRedirect(doc.idinternal.get_absolute_url())
|
||||
else:
|
||||
form = AddCommentForm()
|
||||
|
||||
return render_to_response('idrfc/add_comment.html',
|
||||
dict(doc=doc,
|
||||
form=form,
|
||||
back_url=doc.idinternal.get_absolute_url()),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@group_required('Area_Director', 'Secretariat', 'IANA', 'RFC Editor')
|
||||
def add_commentREDESIGN(request, name):
|
||||
"""Add comment to history of document."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
||||
login = request.user.get_profile()
|
||||
|
||||
if request.method == 'POST':
|
||||
form = AddCommentForm(request.POST)
|
||||
if form.is_valid():
|
||||
c = form.cleaned_data['comment']
|
||||
|
||||
e = DocEvent(doc=doc, by=login)
|
||||
e.type = "added_comment"
|
||||
e.desc = c
|
||||
e.save()
|
||||
|
||||
if doc.type_id == "draft":
|
||||
email_owner(request, doc, doc.ad, login,
|
||||
"A new comment added by %s" % login.name)
|
||||
return HttpResponseRedirect(urlreverse("doc_history", kwargs=dict(name=doc.name)))
|
||||
else:
|
||||
form = AddCommentForm()
|
||||
|
||||
return render_to_response('idrfc/add_comment.html',
|
||||
dict(doc=doc,
|
||||
form=form),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
add_comment = add_commentREDESIGN
|
||||
|
||||
class NotifyForm(forms.Form):
|
||||
notify = forms.CharField(max_length=255, label="Notice emails", help_text="Separate email addresses with commas", required=False)
|
||||
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
@role_required('Area Director', 'Secretariat')
|
||||
def edit_notices(request, name):
|
||||
"""Change the set of email addresses document change notificaitions go to."""
|
||||
|
||||
|
@ -781,7 +609,7 @@ def edit_notices(request, name):
|
|||
init = { "notify" : doc.notify }
|
||||
form = NotifyForm(initial=init)
|
||||
|
||||
return render_to_response('idrfc/change_notify.html',
|
||||
return render_to_response('doc/draft/change_notify.html',
|
||||
{'form': form,
|
||||
'doc': doc,
|
||||
},
|
||||
|
@ -802,7 +630,7 @@ class TelechatForm(forms.Form):
|
|||
self.fields['telechat_date'].choices = [("", "(not on agenda)")] + [(d, d.strftime("%Y-%m-%d")) for d in dates]
|
||||
|
||||
|
||||
@group_required("Area Director", "Secretariat")
|
||||
@role_required("Area Director", "Secretariat")
|
||||
def telechat_date(request, name):
|
||||
doc = get_object_or_404(Document, type="draft", name=name)
|
||||
login = request.user.get_profile()
|
||||
|
@ -822,7 +650,7 @@ def telechat_date(request, name):
|
|||
else:
|
||||
form = TelechatForm(initial=initial)
|
||||
|
||||
return render_to_response('idrfc/edit_telechat_date.html',
|
||||
return render_to_response('doc/edit_telechat_date.html',
|
||||
dict(doc=doc,
|
||||
form=form,
|
||||
user=request.user,
|
||||
|
@ -838,7 +666,7 @@ class IESGNoteForm(forms.Form):
|
|||
# that has caused a lot of pain in the past.
|
||||
return self.cleaned_data['note'].replace('\r', '').strip()
|
||||
|
||||
@group_required("Area Director", "Secretariat")
|
||||
@role_required("Area Director", "Secretariat")
|
||||
def edit_iesg_note(request, name):
|
||||
doc = get_object_or_404(Document, type="draft", name=name)
|
||||
login = request.user.get_profile()
|
||||
|
@ -871,7 +699,7 @@ def edit_iesg_note(request, name):
|
|||
else:
|
||||
form = IESGNoteForm(initial=initial)
|
||||
|
||||
return render_to_response('idrfc/edit_iesg_note.html',
|
||||
return render_to_response('doc/draft/edit_iesg_note.html',
|
||||
dict(doc=doc,
|
||||
form=form,
|
||||
),
|
||||
|
@ -941,7 +769,7 @@ def edit_shepherd_writeup(request, name):
|
|||
)
|
||||
form = ShepherdWriteupUploadForm(initial=init)
|
||||
|
||||
return render_to_response('idrfc/change_shepherd_writeup.html',
|
||||
return render_to_response('doc/draft/change_shepherd_writeup.html',
|
||||
{'form': form,
|
||||
'doc' : doc,
|
||||
},
|
||||
|
@ -992,7 +820,7 @@ def edit_shepherd(request, name):
|
|||
init = { "shepherd": current_shepherd}
|
||||
form = ShepherdForm(initial=init)
|
||||
|
||||
return render_to_response('idrfc/change_shepherd.html',
|
||||
return render_to_response('doc/change_shepherd.html',
|
||||
{'form': form,
|
||||
'doc': doc,
|
||||
},
|
||||
|
@ -1011,7 +839,7 @@ class AdForm(forms.Form):
|
|||
if ad_pk and ad_pk not in [pk for pk, name in choices]:
|
||||
self.fields['ad'].choices = list(choices) + [("", "-------"), (ad_pk, Person.objects.get(pk=ad_pk).plain_name())]
|
||||
|
||||
@group_required("Area Director", "Secretariat")
|
||||
@role_required("Area Director", "Secretariat")
|
||||
def edit_ad(request, name):
|
||||
"""Change the shepherding Area Director for this draft."""
|
||||
|
||||
|
@ -1035,7 +863,7 @@ def edit_ad(request, name):
|
|||
init = { "ad" : doc.ad_id }
|
||||
form = AdForm(initial=init)
|
||||
|
||||
return render_to_response('idrfc/change_ad.html',
|
||||
return render_to_response('doc/draft/change_ad.html',
|
||||
{'form': form,
|
||||
'doc': doc,
|
||||
},
|
||||
|
@ -1073,7 +901,7 @@ def edit_consensus(request, name):
|
|||
else:
|
||||
form = ConsensusForm(initial=dict(consensus=nice_consensus(prev_consensus).replace("Unknown", "")))
|
||||
|
||||
return render_to_response('idrfc/change_consensus.html',
|
||||
return render_to_response('doc/draft/change_consensus.html',
|
||||
{'form': form,
|
||||
'doc': doc,
|
||||
},
|
||||
|
@ -1107,7 +935,7 @@ def request_publication(request, name):
|
|||
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/rfceditor_post_approved_draft_failed.html',
|
||||
return render_to_response('doc/draft/rfceditor_post_approved_draft_failed.html',
|
||||
dict(name=doc.name,
|
||||
response=response,
|
||||
error=error),
|
||||
|
@ -1147,7 +975,7 @@ def request_publication(request, name):
|
|||
else:
|
||||
action = "Document Action"
|
||||
|
||||
from ietf.idrfc.templatetags.mail_filters import std_level_prompt
|
||||
from ietf.doc.templatetags.mail_filters import std_level_prompt
|
||||
|
||||
subject = "%s: '%s' to %s (%s-%s.txt)" % (action, doc.title, std_level_prompt(doc), doc.name, doc.rev)
|
||||
|
||||
|
@ -1156,7 +984,7 @@ def request_publication(request, name):
|
|||
form = PublicationForm(initial=dict(subject=subject,
|
||||
body=body))
|
||||
|
||||
return render_to_response('idrfc/request_publication.html',
|
||||
return render_to_response('doc/draft/request_publication.html',
|
||||
dict(form=form,
|
||||
doc=doc,
|
||||
message=m,
|
|
@ -10,7 +10,8 @@ def state_help(request, type):
|
|||
"draft-rfceditor": ("draft-rfceditor", "RFC Editor States For Internet-Drafts"),
|
||||
"draft-iana-action": ("draft-iana-action", "IANA Action States For Internet-Drafts"),
|
||||
"charter": ("charter", "Charter States"),
|
||||
"conflict-review": ("conflrev", "Conflict Review States")
|
||||
"conflict-review": ("conflrev", "Conflict Review States"),
|
||||
"status-change": ("statchg", "RFC Status Change States"),
|
||||
}.get(type, (None, None))
|
||||
state_type = get_object_or_404(StateType, slug=slug)
|
||||
|
||||
|
|
|
@ -38,13 +38,12 @@ from django.db.models import Q
|
|||
from django.template import RequestContext
|
||||
from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect
|
||||
|
||||
from ietf.idrfc.expire import expirable_draft
|
||||
from ietf.doc.expire import expirable_draft
|
||||
from ietf.utils import normalize_draftname
|
||||
from ietf.doc.models import *
|
||||
from ietf.person.models import *
|
||||
from ietf.group.models import *
|
||||
from ietf.ipr.models import IprDocAlias
|
||||
from ietf.ipr.search import related_docs
|
||||
from ietf.idindex.index import active_drafts_index_by_group
|
||||
|
||||
class SearchForm(forms.Form):
|
||||
|
@ -152,7 +151,7 @@ def fill_in_search_attributes(docs):
|
|||
ipr_docaliases = IprDocAlias.objects.filter(doc_alias__document__in=doc_ids).select_related('doc_alias')
|
||||
for a in ipr_docaliases:
|
||||
docs_dict[a.doc_alias.document_id].iprs.append(a)
|
||||
|
||||
|
||||
rel_docs_dict = dict((d.pk, d) for d in rel_docs)
|
||||
rel_doc_ids = rel_docs_dict.keys()
|
||||
|
||||
|
@ -389,10 +388,14 @@ def search(request):
|
|||
results = []
|
||||
meta = { 'by': None, 'advanced': False, 'searching': False }
|
||||
|
||||
return render_to_response('doc/search.html',
|
||||
return render_to_response('doc/search/search.html',
|
||||
{'form':form, 'docs':results, 'meta':meta, 'show_add_to_list': True },
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
def frontpage(request):
|
||||
form = SearchForm()
|
||||
return render_to_response('doc/frontpage.html', {'form':form}, context_instance=RequestContext(request))
|
||||
|
||||
def ad_dashboard_group(doc):
|
||||
|
||||
if doc.type.slug=='draft':
|
|
@ -8,8 +8,7 @@ from django.template import RequestContext
|
|||
from django.template.loader import render_to_string
|
||||
from django.conf import settings
|
||||
|
||||
from ietf.idrfc.utils import update_telechat
|
||||
from ietf.doc.utils import log_state_changed
|
||||
from ietf.doc.utils import log_state_changed, update_telechat
|
||||
from ietf.doc.models import save_document_in_history
|
||||
|
||||
from ietf.doc.utils import create_ballot_if_not_open, close_open_ballots, get_document_content
|
||||
|
@ -24,9 +23,8 @@ from ietf.group.models import Group
|
|||
from ietf.name.models import DocRelationshipName, StdLevelName
|
||||
|
||||
from ietf.doc.forms import TelechatForm, AdForm, NotifyForm
|
||||
|
||||
from ietf.idrfc.views_ballot import LastCallTextForm
|
||||
from ietf.idrfc.lastcall import request_last_call
|
||||
from ietf.doc.views_ballot import LastCallTextForm
|
||||
from ietf.doc.lastcall import request_last_call
|
||||
|
||||
class ChangeStateForm(forms.Form):
|
||||
new_state = forms.ModelChoiceField(State.objects.filter(type="statchg", used=True), label="Status Change Evaluation State", empty_label=None, required=True)
|
||||
|
@ -95,7 +93,7 @@ def change_state(request, name, option=None):
|
|||
dict(form=form,
|
||||
doc=status_change,
|
||||
login=login,
|
||||
help_url=reverse('help_status_change_states')
|
||||
help_url=reverse('state_help', kwargs=dict(type="status-change")),
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
@ -702,7 +700,7 @@ def last_call(request, name):
|
|||
|
||||
request_last_call(request, status_change)
|
||||
|
||||
return render_to_response('idrfc/last_call_requested.html',
|
||||
return render_to_response('doc/draft/last_call_requested.html',
|
||||
dict(doc=status_change,
|
||||
url = status_change.get_absolute_url(),
|
||||
),
|
||||
|
|
|
@ -8,7 +8,7 @@ import pytz
|
|||
from django.conf import settings
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from ietf.idtracker.templatetags.ietf_filters import clean_whitespace
|
||||
from ietf.doc.templatetags.ietf_filters import clean_whitespace
|
||||
from ietf.doc.models import *
|
||||
|
||||
def all_id_txt():
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<django-objects version="1.0">
|
||||
<object pk="3175" model="idtracker.ballotinfo">
|
||||
<field type="BooleanField" name="active">1</field>
|
||||
<field type="BooleanField" name="an_sent">0</field>
|
||||
<field type="DateField" name="an_sent_date"><None></None></field>
|
||||
<field to="idtracker.iesglogin" name="an_sent_by" rel="ManyToOneRel"><None></None></field>
|
||||
<field type="BooleanField" name="defer">0</field>
|
||||
<field to="idtracker.iesglogin" name="defer_by" rel="ManyToOneRel">111</field>
|
||||
<field type="DateField" name="defer_date">2009-10-06</field>
|
||||
<field type="TextField" name="approval_text">From: The IESG <iesg-secretary@ietf.org>
|
||||
To: IETF-Announce <ietf-announce@ietf.org>
|
||||
Cc: Internet Architecture Board <iab@iab.org>,
|
||||
RFC Editor <rfc-editor@rfc-editor.org>,
|
||||
mipshop mailing list <mipshop@ietf.org>,
|
||||
mipshop chair <mipshop-chairs@tools.ietf.org>
|
||||
Subject: Protocol Action: 'Fast Handovers for Proxy Mobile IPv6' to
|
||||
Proposed Standard
|
||||
|
||||
The IESG has approved the following document:
|
||||
|
||||
- 'Fast Handovers for Proxy Mobile IPv6 '
|
||||
<draft-ietf-mipshop-pfmipv6-09.txt> as a Proposed Standard
|
||||
|
||||
|
||||
This document is the product of the Mobility for IP: Performance,
|
||||
Signaling and Handoff Optimization Working Group.
|
||||
|
||||
The IESG contact persons are Jari Arkko and Ralph Droms.
|
||||
|
||||
A URL of this Internet-Draft is:
|
||||
http://www.ietf.org/internet-drafts/draft-ietf-mipshop-pfmipv6-09.txt</field>
|
||||
<field type="TextField" name="last_call_text">To: IETF-Announce <ietf-announce@ietf.org>
|
||||
From: The IESG <iesg-secretary@ietf.org>
|
||||
Reply-to: ietf@ietf.org
|
||||
CC: <mipshop@ietf.org>
|
||||
Subject: Last Call: draft-ietf-mipshop-pfmipv6 (Fast Handovers for Proxy Mobile IPv6) to Proposed Standard
|
||||
|
||||
The IESG has received a request from the Mobility for IP: Performance,
|
||||
Signaling and Handoff Optimization WG (mipshop) to consider the following document:
|
||||
|
||||
- 'Fast Handovers for Proxy Mobile IPv6 '
|
||||
<draft-ietf-mipshop-pfmipv6-09.txt> as a Proposed Standard
|
||||
|
||||
The IESG plans to make a decision in the next few weeks, and solicits
|
||||
final comments on this action. Please send substantive comments to the
|
||||
ietf@ietf.org mailing lists by 2009-09-22. Exceptionally,
|
||||
comments may be sent to iesg@ietf.org instead. In either case, please
|
||||
retain the beginning of the Subject line to allow automated sorting.
|
||||
|
||||
The file can be obtained via
|
||||
http://www.ietf.org/internet-drafts/draft-ietf-mipshop-pfmipv6-09.txt
|
||||
|
||||
|
||||
IESG discussion can be tracked via
|
||||
https://datatracker.ietf.org/public/pidtracker.cgi?command=view_id&dTag=17914&rfc_flag=0</field>
|
||||
<field type="TextField" name="ballot_writeup">Technical Summary
|
||||
|
||||
The document describes a mechanism to provide fast handovers when
|
||||
Proxy Mobile IPv6 is used as the mobility management protocol. It
|
||||
also describes a mechanism to transfer context between two MAGs
|
||||
to assist in the handover. The mobile node is not involved in any
|
||||
Signaling for the fast handovers to work.
|
||||
|
||||
Working Group Summary
|
||||
|
||||
This is a product of the MIPSHOP WG.
|
||||
|
||||
Document Quality
|
||||
|
||||
There are no known implementations of the specification. It is likely
|
||||
to be implemented by some vendors, since this document is required
|
||||
for fast handovers in 3GPP2 eHPRD network.
|
||||
|
||||
Personnel
|
||||
|
||||
Document shepherd: Vijay Devarapalli
|
||||
Responsible AD: Jari Arkko
|
||||
|
||||
RFC Editor Note
|
||||
|
||||
(Insert RFC Editor Note here or remove section)
|
||||
|
||||
IRTF Note
|
||||
|
||||
(Insert IRTF Note here or remove section)
|
||||
|
||||
IESG Note
|
||||
|
||||
(Insert IESG Note here or remove section)
|
||||
|
||||
IANA Note
|
||||
|
||||
(Insert IANA Note here or remove section)</field>
|
||||
<field type="IntegerField" name="ballot_issued">1</field>
|
||||
</object>
|
||||
</django-objects>
|
File diff suppressed because it is too large
Load diff
|
@ -1,264 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<django-objects version="1.0">
|
||||
<object pk="17914" model="idtracker.internetdraft">
|
||||
<field type="CharField" name="title">Fast Handovers for Proxy Mobile IPv6</field>
|
||||
<field type="CharField" name="id_document_key">FAST HANDOVERS FOR PROXY MOBILE IPV6</field>
|
||||
<field to="idtracker.acronym" name="group" rel="ManyToOneRel">1598</field>
|
||||
<field type="CharField" name="filename">draft-ietf-mipshop-pfmipv6</field>
|
||||
<field type="CharField" name="revision">13</field>
|
||||
<field type="DateField" name="revision_date">2010-04-11</field>
|
||||
<field type="CharField" name="file_type">.txt</field>
|
||||
<field type="IntegerField" name="txt_page_count">41</field>
|
||||
<field type="CharField" name="local_path"><None></None></field>
|
||||
<field type="DateField" name="start_date">2008-10-27</field>
|
||||
<field type="DateField" name="expiration_date"><None></None></field>
|
||||
<field type="TextField" name="abstract">Mobile IPv6 (MIPv6) [RFC3775] provides a mobile node with IP mobility
|
||||
when it performs a handover from one MAG to another and fast
|
||||
handovers for Mobile IPv6 (FMIPv6) [RFC5568] are specified to enhance
|
||||
the handover performance in terms of latency and packet loss. While
|
||||
MIPv6 (and FMIPv6 as well) requires the participation of the mobile
|
||||
node in the mobility-related signaling, Proxy Mobile IPv6 (PMIPv6)
|
||||
[RFC5213] provides IP mobility to mobile nodes that either have or do
|
||||
not have MIPv6 functionality without such involvement. Nevertheless,
|
||||
the basic performance of PMIPv6 in terms of handover latency and
|
||||
packet loss is considered not any different from that of MIPv6.
|
||||
|
||||
When the fast handover is considered in such an environment, several
|
||||
modifications are needed to FMIPv6 to adapt to the network-based
|
||||
mobility management. This document specifies the usage of Fast
|
||||
Mobile IPv6 (FMIPv6) when Proxy Mobile IPv6 is used as the mobility
|
||||
management protocol. Necessary extensions are specified for FMIPv6
|
||||
to support the scenario when the mobile node does not have IP
|
||||
mobility functionality and hence is not involved with either MIPv6 or
|
||||
FMIPv6 operations.</field>
|
||||
<field type="DateField" name="dunn_sent_date"><None></None></field>
|
||||
<field type="DateField" name="extension_date"><None></None></field>
|
||||
<field to="idtracker.idstatus" name="status" rel="ManyToOneRel">1</field>
|
||||
<field to="idtracker.idintendedstatus" name="intended_status" rel="ManyToOneRel">6</field>
|
||||
<field type="DateField" name="lc_sent_date">2009-09-08</field>
|
||||
<field type="CharField" name="lc_changes"><None></None></field>
|
||||
<field type="DateField" name="lc_expiration_date">2009-09-22</field>
|
||||
<field type="DateField" name="b_sent_date"><None></None></field>
|
||||
<field type="DateField" name="b_discussion_date"><None></None></field>
|
||||
<field type="DateField" name="b_approve_date"><None></None></field>
|
||||
<field type="DateField" name="wgreturn_date"><None></None></field>
|
||||
<field type="IntegerField" name="rfc_number"><None></None></field>
|
||||
<field type="TextField" name="comments"><None></None></field>
|
||||
<field type="DateField" name="last_modified_date">2010-04-11</field>
|
||||
<field to="idtracker.internetdraft" name="replaced_by" rel="ManyToOneRel"><None></None></field>
|
||||
<field type="BooleanField" name="review_by_rfc_editor">0</field>
|
||||
<field type="BooleanField" name="expired_tombstone">0</field>
|
||||
</object>
|
||||
<object pk="17914" model="idtracker.idinternal">
|
||||
<field type="IntegerField" name="rfc_flag">0</field>
|
||||
<field to="idtracker.ballotinfo" name="ballot" rel="ManyToOneRel">3175</field>
|
||||
<field type="IntegerField" name="primary_flag">1</field>
|
||||
<field type="IntegerField" name="group_flag">0</field>
|
||||
<field type="CharField" name="token_name">Jari Arkko</field>
|
||||
<field type="CharField" name="token_email">jari.arkko@piuha.net</field>
|
||||
<field type="TextField" name="note">On the May 6th agenda to solicit one additional vote (Discusses cleared)<br>Vijay Devarapalli (vijay@wichorus.com) is the document shepherd.</field>
|
||||
<field type="DateField" name="status_date"><None></None></field>
|
||||
<field type="CharField" name="email_display">Jari Arkko</field>
|
||||
<field type="IntegerField" name="agenda">1</field>
|
||||
<field to="idtracker.idstate" name="cur_state" rel="ManyToOneRel">11</field>
|
||||
<field to="idtracker.idstate" name="prev_state" rel="ManyToOneRel">10</field>
|
||||
<field type="CharField" name="assigned_to"></field>
|
||||
<field to="idtracker.iesglogin" name="mark_by" rel="ManyToOneRel">100</field>
|
||||
<field to="idtracker.iesglogin" name="job_owner" rel="ManyToOneRel">49</field>
|
||||
<field type="DateField" name="event_date">2010-05-17</field>
|
||||
<field to="idtracker.area" name="area_acronym" rel="ManyToOneRel">1052</field>
|
||||
<field to="idtracker.idsubstate" name="cur_sub_state" rel="ManyToOneRel"><None></None></field>
|
||||
<field to="idtracker.idsubstate" name="prev_sub_state" rel="ManyToOneRel"><None></None></field>
|
||||
<field type="IntegerField" name="returning_item">0</field>
|
||||
<field type="DateField" name="telechat_date">2010-05-20</field>
|
||||
<field type="IntegerField" name="via_rfc_editor">0</field>
|
||||
<field type="CharField" name="state_change_notice_to">mipshop-chairs@tools.ietf.org, draft-ietf-mipshop-pfmipv6@tools.ietf.org</field>
|
||||
<field type="IntegerField" name="dnp">0</field>
|
||||
<field type="DateField" name="dnp_date"><None></None></field>
|
||||
<field type="IntegerField" name="noproblem">0</field>
|
||||
<field to="idtracker.iesglogin" name="resurrect_requested_by" rel="ManyToOneRel"><None></None></field>
|
||||
<field type="IntegerField" name="approved_in_minute">1</field>
|
||||
</object>
|
||||
<object pk="1598" model="idtracker.acronym">
|
||||
<field type="CharField" name="acronym">mipshop</field>
|
||||
<field type="CharField" name="name">Mobility for IP: Performance, Signaling and Handoff Optimization</field>
|
||||
<field type="CharField" name="name_key">MOBILITY FOR</field>
|
||||
</object>
|
||||
<object pk="1598" model="idtracker.ietfwg">
|
||||
<field to="idtracker.wgtype" name="group_type" rel="ManyToOneRel">1</field>
|
||||
<field type="DateField" name="proposed_date">2003-06-10</field>
|
||||
<field type="DateField" name="start_date">2003-10-20</field>
|
||||
<field type="DateField" name="dormant_date"><None></None></field>
|
||||
<field type="DateField" name="concluded_date"><None></None></field>
|
||||
<field to="idtracker.wgstatus" name="status" rel="ManyToOneRel">1</field>
|
||||
<field to="idtracker.areadirector" name="area_director" rel="ManyToOneRel">126</field>
|
||||
<field type="CharField" name="meeting_scheduled">NO</field>
|
||||
<field type="CharField" name="email_address">mipshop@ietf.org</field>
|
||||
<field type="CharField" name="email_subscribe">mipshop-request@ietf.org</field>
|
||||
<field type="CharField" name="email_keyword">subscribe</field>
|
||||
<field type="CharField" name="email_archive">http://www.ietf.org/mail-archive/web/mipshop/index.html</field>
|
||||
<field type="TextField" name="comments">1st meeting at the 57th IETF in Vienna, Austria</field>
|
||||
<field type="DateField" name="last_modified_date">2009-05-22</field>
|
||||
<field type="CharField" name="meeting_scheduled_old">NO</field>
|
||||
</object>
|
||||
<object pk="10910" model="idtracker.areagroup">
|
||||
<field to="idtracker.area" name="area" rel="ManyToOneRel">1052</field>
|
||||
<field to="idtracker.ietfwg" name="group" rel="ManyToOneRel">1598</field>
|
||||
</object>
|
||||
<object pk="1052" model="idtracker.area">
|
||||
<field type="DateField" name="start_date">1983-09-06</field>
|
||||
<field type="DateField" name="concluded_date"><None></None></field>
|
||||
<field to="idtracker.areastatus" name="status" rel="ManyToOneRel">1</field>
|
||||
<field type="TextField" name="comments"></field>
|
||||
<field type="DateField" name="last_modified_date">2003-09-26</field>
|
||||
<field type="TextField" name="extra_email_addresses"><None></None></field>
|
||||
</object>
|
||||
<object pk="1052" model="idtracker.acronym">
|
||||
<field type="CharField" name="acronym">int</field>
|
||||
<field type="CharField" name="name">Internet Area</field>
|
||||
<field type="CharField" name="name_key">INTERNET AREA</field>
|
||||
</object>
|
||||
<object pk="12676" model="idtracker.internetdraft">
|
||||
<field type="CharField" name="title">Using IPsec between Mobile and Correspondent IPv6 Nodes</field>
|
||||
<field type="CharField" name="id_document_key">USING IPSEC BETWEEN MOBILE AND CORRESPONDENT IPV6 NODES</field>
|
||||
<field to="idtracker.acronym" name="group" rel="ManyToOneRel">1597</field>
|
||||
<field type="CharField" name="filename">draft-ietf-mip6-cn-ipsec</field>
|
||||
<field type="CharField" name="revision">09</field>
|
||||
<field type="DateField" name="revision_date">2008-08-25</field>
|
||||
<field type="CharField" name="file_type">.txt</field>
|
||||
<field type="IntegerField" name="txt_page_count">11</field>
|
||||
<field type="CharField" name="local_path"></field>
|
||||
<field type="DateField" name="start_date">2005-01-11</field>
|
||||
<field type="DateField" name="expiration_date">2010-04-27</field>
|
||||
<field type="TextField" name="abstract">Mobile IPv6 uses IPsec to protect signaling between the Mobile Node
|
||||
and the Home Agent. This document defines how IPsec can be used
|
||||
between the Mobile Node and Correspondent Nodes for Home Address
|
||||
Option validation and protection of mobility signaling for Route
|
||||
Optimization. The configuration details for IPsec and IKE are also
|
||||
provided.</field>
|
||||
<field type="DateField" name="dunn_sent_date">2010-04-26</field>
|
||||
<field type="DateField" name="extension_date"><None></None></field>
|
||||
<field to="idtracker.idstatus" name="status" rel="ManyToOneRel">2</field>
|
||||
<field to="idtracker.idintendedstatus" name="intended_status" rel="ManyToOneRel">6</field>
|
||||
<field type="DateField" name="lc_sent_date">2007-08-17</field>
|
||||
<field type="CharField" name="lc_changes">NO</field>
|
||||
<field type="DateField" name="lc_expiration_date">2007-08-31</field>
|
||||
<field type="DateField" name="b_sent_date"><None></None></field>
|
||||
<field type="DateField" name="b_discussion_date"><None></None></field>
|
||||
<field type="DateField" name="b_approve_date"><None></None></field>
|
||||
<field type="DateField" name="wgreturn_date"><None></None></field>
|
||||
<field type="IntegerField" name="rfc_number">0</field>
|
||||
<field type="TextField" name="comments"></field>
|
||||
<field type="DateField" name="last_modified_date">2010-04-27</field>
|
||||
<field to="idtracker.internetdraft" name="replaced_by" rel="ManyToOneRel"><None></None></field>
|
||||
<field type="BooleanField" name="review_by_rfc_editor">0</field>
|
||||
<field type="BooleanField" name="expired_tombstone">0</field>
|
||||
</object>
|
||||
<object pk="12676" model="idtracker.idinternal">
|
||||
<field type="IntegerField" name="rfc_flag">0</field>
|
||||
<field to="idtracker.ballotinfo" name="ballot" rel="ManyToOneRel">2157</field>
|
||||
<field type="IntegerField" name="primary_flag">1</field>
|
||||
<field type="IntegerField" name="group_flag">0</field>
|
||||
<field type="CharField" name="token_name">Jari Arkko</field>
|
||||
<field type="CharField" name="token_email">jari.arkko@piuha.net</field>
|
||||
<field type="TextField" name="note">AD Sponsored submission. There is no Document Shepherd.</field>
|
||||
<field type="DateField" name="status_date"><None></None></field>
|
||||
<field type="CharField" name="email_display">Jari Arkko</field>
|
||||
<field type="IntegerField" name="agenda">0</field>
|
||||
<field to="idtracker.idstate" name="cur_state" rel="ManyToOneRel">99</field>
|
||||
<field to="idtracker.idstate" name="prev_state" rel="ManyToOneRel">20</field>
|
||||
<field type="CharField" name="assigned_to"></field>
|
||||
<field to="idtracker.iesglogin" name="mark_by" rel="ManyToOneRel">49</field>
|
||||
<field to="idtracker.iesglogin" name="job_owner" rel="ManyToOneRel">49</field>
|
||||
<field type="DateField" name="event_date">2010-04-26</field>
|
||||
<field to="idtracker.area" name="area_acronym" rel="ManyToOneRel">1052</field>
|
||||
<field to="idtracker.idsubstate" name="cur_sub_state" rel="ManyToOneRel"><None></None></field>
|
||||
<field to="idtracker.idsubstate" name="prev_sub_state" rel="ManyToOneRel">5</field>
|
||||
<field type="IntegerField" name="returning_item">0</field>
|
||||
<field type="DateField" name="telechat_date">2007-09-06</field>
|
||||
<field type="IntegerField" name="via_rfc_editor">0</field>
|
||||
<field type="CharField" name="state_change_notice_to">mext-chairs@tools.ietf.org,Francis.Dupont@fdupont.fr,jeanmichel.combes@orange-ftgroup.com</field>
|
||||
<field type="IntegerField" name="dnp">0</field>
|
||||
<field type="DateField" name="dnp_date"><None></None></field>
|
||||
<field type="IntegerField" name="noproblem">0</field>
|
||||
<field to="idtracker.iesglogin" name="resurrect_requested_by" rel="ManyToOneRel"><None></None></field>
|
||||
<field type="IntegerField" name="approved_in_minute">1</field>
|
||||
</object>
|
||||
<object pk="19892" model="idtracker.internetdraft">
|
||||
<field type="CharField" name="title">Uniform Resource Name (URN) Syntax</field>
|
||||
<field type="CharField" name="id_document_key">UNIFORM RESOURCE NAME (URN) SYNTAX</field>
|
||||
<field to="idtracker.acronym" name="group" rel="ManyToOneRel">1027</field>
|
||||
<field type="CharField" name="filename">draft-ah-rfc2141bis-urn</field>
|
||||
<field type="CharField" name="revision">00</field>
|
||||
<field type="DateField" name="revision_date">2010-03-25</field>
|
||||
<field type="CharField" name="file_type">.txt</field>
|
||||
<field type="IntegerField" name="txt_page_count">18</field>
|
||||
<field type="CharField" name="local_path"><None></None></field>
|
||||
<field type="DateField" name="start_date">2010-03-25</field>
|
||||
<field type="DateField" name="expiration_date"><None></None></field>
|
||||
<field type="TextField" name="abstract">Uniform Resource Names (URNs) are intended to serve as persistent,
|
||||
location-independent, resource identifiers. This document serves as
|
||||
the foundation of the 'urn' URI Scheme according to RFC 3986 and sets
|
||||
forward the canonical syntax for URNs, which subdivides URNs into
|
||||
"namespaces". A discussion of both existing legacy and new
|
||||
namespaces and requirements for URN presentation and transmission are
|
||||
presented. Finally, there is a discussion of URN equivalence and how
|
||||
to determine it. This document supersedes RFC 2141.
|
||||
|
||||
The requirements and procedures for URN Namespace registration
|
||||
documents are currently set forth in RFC 3406, which is also expected
|
||||
to be updated by an independent, revised specification soon.
|
||||
|
||||
Discussion
|
||||
|
||||
This draft version has been obtained by importing the text from RFC
|
||||
2141 into modern tools and making a first round of updating steps.
|
||||
It is intended to serve as one of the starting points for an effort
|
||||
to bring URN RFCs in alignment with STD 63, STD 68, BCP 26, and the
|
||||
requirements from emerging distributed national and international URN
|
||||
resolution systems, and advance them on the IETF Standards Track.
|
||||
|
||||
Until a more specific mailing list is established, comments are
|
||||
welcome on the uri-review@ietf.org mailing list (or sent to the
|
||||
document editor).</field>
|
||||
<field type="DateField" name="dunn_sent_date"><None></None></field>
|
||||
<field type="DateField" name="extension_date"><None></None></field>
|
||||
<field to="idtracker.idstatus" name="status" rel="ManyToOneRel">1</field>
|
||||
<field to="idtracker.idintendedstatus" name="intended_status" rel="ManyToOneRel">8</field>
|
||||
<field type="DateField" name="lc_sent_date"><None></None></field>
|
||||
<field type="CharField" name="lc_changes"><None></None></field>
|
||||
<field type="DateField" name="lc_expiration_date"><None></None></field>
|
||||
<field type="DateField" name="b_sent_date"><None></None></field>
|
||||
<field type="DateField" name="b_discussion_date"><None></None></field>
|
||||
<field type="DateField" name="b_approve_date"><None></None></field>
|
||||
<field type="DateField" name="wgreturn_date"><None></None></field>
|
||||
<field type="IntegerField" name="rfc_number"><None></None></field>
|
||||
<field type="TextField" name="comments"><None></None></field>
|
||||
<field type="DateField" name="last_modified_date">2010-03-25</field>
|
||||
<field to="idtracker.internetdraft" name="replaced_by" rel="ManyToOneRel"><None></None></field>
|
||||
<field type="BooleanField" name="review_by_rfc_editor">0</field>
|
||||
<field type="BooleanField" name="expired_tombstone">0</field>
|
||||
</object>
|
||||
<object pk="1027" model="idtracker.acronym">
|
||||
<field type="CharField" name="acronym">none</field>
|
||||
<field type="CharField" name="name">Individual Submissions</field>
|
||||
<field type="CharField" name="name_key">INDIVIDUAL SUBMISSIONS</field>
|
||||
</object>
|
||||
<object pk="1027" model="idtracker.ietfwg">
|
||||
<field to="idtracker.wgtype" name="group_type" rel="ManyToOneRel">4</field>
|
||||
<field type="DateField" name="proposed_date"><None></None></field>
|
||||
<field type="DateField" name="start_date"><None></None></field>
|
||||
<field type="DateField" name="dormant_date"><None></None></field>
|
||||
<field type="DateField" name="concluded_date"><None></None></field>
|
||||
<field to="idtracker.wgstatus" name="status" rel="ManyToOneRel">1</field>
|
||||
<field to="idtracker.areadirector" name="area_director" rel="ManyToOneRel">112</field>
|
||||
<field type="CharField" name="meeting_scheduled">NO</field>
|
||||
<field type="CharField" name="email_address"></field>
|
||||
<field type="CharField" name="email_subscribe"></field>
|
||||
<field type="CharField" name="email_keyword"></field>
|
||||
<field type="CharField" name="email_archive"></field>
|
||||
<field type="TextField" name="comments">This is here so that 'none' can be entered in, for example, idform.</field>
|
||||
<field type="DateField" name="last_modified_date">2002-06-24</field>
|
||||
<field type="CharField" name="meeting_scheduled_old">NO</field>
|
||||
</object>
|
||||
</django-objects>
|
|
@ -1,47 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<django-objects version="1.0">
|
||||
<object pk="1791" model="iesg.wgaction">
|
||||
<field type="TextField" name="note"></field>
|
||||
<field type="DateField" name="status_date">2010-04-22</field>
|
||||
<field type="BooleanField" name="agenda">1</field>
|
||||
<field type="CharField" name="token_name">Robert</field>
|
||||
<field type="IntegerField" name="category">13</field>
|
||||
<field type="DateField" name="telechat_date">2010-05-06</field>
|
||||
</object>
|
||||
<object pk="1784" model="iesg.wgaction">
|
||||
<field type="TextField" name="note"></field>
|
||||
<field type="DateField" name="status_date">2010-04-23</field>
|
||||
<field type="BooleanField" name="agenda">1</field>
|
||||
<field type="CharField" name="token_name">Peter</field>
|
||||
<field type="IntegerField" name="category">12</field>
|
||||
<field type="DateField" name="telechat_date">2010-05-06</field>
|
||||
</object>
|
||||
<object pk="1775" model="iesg.wgaction">
|
||||
<field type="TextField" name="note"></field>
|
||||
<field type="DateField" name="status_date">2010-01-19</field>
|
||||
<field type="BooleanField" name="agenda">1</field>
|
||||
<field type="CharField" name="token_name">Lars</field>
|
||||
<field type="IntegerField" name="category">13</field>
|
||||
<field type="DateField" name="telechat_date">2010-05-06</field>
|
||||
</object>
|
||||
<object pk="1775" model="idtracker.acronym">
|
||||
<field type="CharField" name="acronym">conex</field>
|
||||
<field type="CharField" name="name">Congestion Exposure</field>
|
||||
<field type="CharField" name="name_key">CONGESTION E</field>
|
||||
</object>
|
||||
<object pk="1784" model="idtracker.acronym">
|
||||
<field type="CharField" name="acronym">newprep</field>
|
||||
<field type="CharField" name="name">Stringprep after IDNA2008</field>
|
||||
<field type="CharField" name="name_key">STRINGPREP A</field>
|
||||
</object>
|
||||
<object pk="1791" model="idtracker.acronym">
|
||||
<field type="CharField" name="acronym">soc</field>
|
||||
<field type="CharField" name="name">SIP Overload Control</field>
|
||||
<field type="CharField" name="name_key">SIP OVERLOAD CONTROL</field>
|
||||
</object>
|
||||
<object pk="1389" model="idtracker.acronym">
|
||||
<field type="CharField" name="acronym">sieve</field>
|
||||
<field type="CharField" name="name">Sieve Mail Filtering Language</field>
|
||||
<field type="CharField" name="name_key">SIEVE MAIL F</field>
|
||||
</object>
|
||||
</django-objects>
|
|
@ -1,74 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# boiler plate
|
||||
import os, sys
|
||||
|
||||
one_dir_up = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../'))
|
||||
|
||||
sys.path.insert(0, one_dir_up)
|
||||
|
||||
from django.core.management import setup_environ
|
||||
import settings
|
||||
setup_environ(settings)
|
||||
|
||||
# script
|
||||
from django.core.serializers import serialize
|
||||
from django.db.models import Q
|
||||
from ietf.idtracker.models import *
|
||||
from ietf.iesg.models import *
|
||||
|
||||
def output(name, qs):
|
||||
try:
|
||||
f = open(os.path.join(settings.BASE_DIR, "idrfc/fixtures/%s.xml" % name), 'w')
|
||||
f.write(serialize("xml", qs, indent=4))
|
||||
f.close()
|
||||
except:
|
||||
from django.db import connection
|
||||
from pprint import pprint
|
||||
pprint(connection.queries)
|
||||
raise
|
||||
|
||||
# base data
|
||||
base = []
|
||||
|
||||
area_directors = AreaDirector.objects.all()
|
||||
broken_logins = ('bthorson', 'members', 'iab')
|
||||
|
||||
base.extend(area_directors)
|
||||
base.extend(PersonOrOrgInfo.objects.filter(areadirector__in=area_directors))
|
||||
base.extend(IESGLogin.objects.filter(Q(login_name="klm") | Q(person__in=[a.person for a in area_directors])).exclude(login_name__in=broken_logins))
|
||||
base.extend(EmailAddress.objects.filter(person_or_org__areadirector__in=area_directors, priority=1))
|
||||
base.extend(IDStatus.objects.all())
|
||||
base.extend(IDIntendedStatus.objects.all())
|
||||
base.extend(IDSubState.objects.all())
|
||||
base.extend(IDState.objects.all())
|
||||
base.extend(WGType.objects.all())
|
||||
base.extend(TelechatDates.objects.all())
|
||||
base.extend(Acronym.objects.filter(acronym_id=Acronym.INDIVIDUAL_SUBMITTER))
|
||||
base.extend(IDDates.objects.all())
|
||||
|
||||
output("base", base)
|
||||
|
||||
|
||||
# specific drafts
|
||||
draftdata = []
|
||||
d = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
|
||||
draftdata.extend([d, d.idinternal, d.group, d.group.ietfwg])
|
||||
ags = AreaGroup.objects.filter(group__exact=d.group.ietfwg.group_acronym)
|
||||
draftdata.extend(ags)
|
||||
draftdata.extend([a.area for a in ags])
|
||||
draftdata.extend([a.area.area_acronym for a in ags])
|
||||
d = InternetDraft.objects.get(filename="draft-ietf-mip6-cn-ipsec")
|
||||
draftdata.extend([d, d.idinternal])
|
||||
d = InternetDraft.objects.get(filename="draft-ah-rfc2141bis-urn")
|
||||
draftdata.extend([d, d.group, d.group.ietfwg])
|
||||
output("draft", draftdata)
|
||||
|
||||
# specific ballot info
|
||||
d = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
|
||||
output("ballot", [d.idinternal.ballot])
|
||||
|
||||
|
||||
# specific WG actions
|
||||
wgas = WGAction.objects.all()
|
||||
output("wgactions", list(wgas) + list(Acronym.objects.filter(wgaction__in=wgas)) + [Acronym.objects.get(acronym="sieve")])
|
1
ietf/idrfc/templatetags/.gitignore
vendored
1
ietf/idrfc/templatetags/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
/*.pyc
|
|
@ -1 +0,0 @@
|
|||
#
|
|
@ -1,191 +0,0 @@
|
|||
# Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
# All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# * Neither the name of the Nokia Corporation and/or its
|
||||
# subsidiary(-ies) nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from django import template
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
from django.conf import settings
|
||||
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.models import BallotDocEvent
|
||||
|
||||
register = template.Library()
|
||||
|
||||
def get_user_name(context):
|
||||
if 'user' in context and context['user'].is_authenticated():
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
from ietf.person.models import Person
|
||||
try:
|
||||
return context['user'].get_profile().plain_name()
|
||||
except Person.DoesNotExist:
|
||||
return None
|
||||
|
||||
person = context['user'].get_profile().person()
|
||||
if person:
|
||||
return str(person)
|
||||
return None
|
||||
|
||||
def render_ballot_icon(user, doc):
|
||||
if not doc:
|
||||
return ""
|
||||
|
||||
if doc.type_id == "draft":
|
||||
s = doc.get_state("draft-iesg")
|
||||
if s and s.name not in BALLOT_ACTIVE_STATES:
|
||||
return ""
|
||||
elif doc.type_id == "charter":
|
||||
if doc.get_state_slug() not in ("intrev", "iesgrev"):
|
||||
return ""
|
||||
|
||||
ballot = doc.latest_event(BallotDocEvent, type="created_ballot")
|
||||
if not ballot:
|
||||
return ""
|
||||
|
||||
edit_position_url = urlreverse('ietf.idrfc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk))
|
||||
|
||||
def sort_key(t):
|
||||
_, pos = t
|
||||
if not pos:
|
||||
return (2, 0)
|
||||
elif pos.pos.blocking:
|
||||
return (0, pos.pos.order)
|
||||
else:
|
||||
return (1, pos.pos.order)
|
||||
|
||||
positions = list(doc.active_ballot().active_ad_positions().items())
|
||||
positions.sort(key=sort_key)
|
||||
|
||||
cm = ""
|
||||
if has_role(user, "Area Director"):
|
||||
cm = ' oncontextmenu="editBallot(\''+str(edit_position_url)+'\');return false;"'
|
||||
|
||||
res = ['<table class="ballot_icon" title="IESG Evaluation Record (click to show more, right-click to edit position)" onclick="showBallot(\'' + doc.name + '\',\'' + str(edit_position_url) + '\')"' + cm + '>']
|
||||
|
||||
res.append("<tr>")
|
||||
|
||||
for i, (ad, pos) in enumerate(positions):
|
||||
if i > 0 and i % 5 == 0:
|
||||
res.append("</tr>")
|
||||
res.append("<tr>")
|
||||
|
||||
c = "position-%s" % (pos.pos.slug if pos else "norecord")
|
||||
|
||||
if ad.user_id == user.id:
|
||||
c += " my"
|
||||
|
||||
res.append('<td class="%s" />' % c)
|
||||
|
||||
res.append("</tr>")
|
||||
res.append("</table>")
|
||||
|
||||
return "".join(res)
|
||||
|
||||
class BallotIconNode(template.Node):
|
||||
def __init__(self, doc_var):
|
||||
self.doc_var = doc_var
|
||||
def render(self, context):
|
||||
doc = template.resolve_variable(self.doc_var, context)
|
||||
if hasattr(doc, "_idinternal"):
|
||||
# hack for old schema
|
||||
doc = doc._idinternal
|
||||
return render_ballot_icon(context.get("user"), doc)
|
||||
|
||||
def do_ballot_icon(parser, token):
|
||||
try:
|
||||
tagName, docName = token.split_contents()
|
||||
except ValueError:
|
||||
raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
|
||||
return BallotIconNode(docName)
|
||||
|
||||
register.tag('ballot_icon', do_ballot_icon)
|
||||
|
||||
@register.filter
|
||||
def my_position(doc, user):
|
||||
user_name = get_user_name({'user':user})
|
||||
if not user_name:
|
||||
return None
|
||||
if not in_group(user, "Area_Director"):
|
||||
return None
|
||||
if not doc.in_ietf_process():
|
||||
return None
|
||||
if not doc.ietf_process.has_iesg_ballot():
|
||||
return None
|
||||
ballot = doc.ietf_process.iesg_ballot()
|
||||
return ballot.position_for_ad(user_name)
|
||||
|
||||
@register.filter
|
||||
def state_age_colored(doc):
|
||||
if not doc.in_ietf_process():
|
||||
return ""
|
||||
if doc.is_id_wrapper and not doc.draft_status in ["Active", "RFC"]:
|
||||
# Don't show anything for expired/withdrawn/replaced drafts
|
||||
return ""
|
||||
main_state = doc.ietf_process.main_state
|
||||
sub_state = doc.ietf_process.sub_state
|
||||
if main_state in ["Dead","AD is watching","RFC Published"]:
|
||||
return ""
|
||||
days = timesince_days(doc.ietf_process.state_date())
|
||||
# loosely based on
|
||||
# http://trac.tools.ietf.org/group/iesg/trac/wiki/PublishPath
|
||||
if main_state == "In Last Call":
|
||||
goal1 = 30
|
||||
goal2 = 30
|
||||
elif main_state == "RFC Ed Queue":
|
||||
goal1 = 60
|
||||
goal2 = 120
|
||||
elif main_state in ["Last Call Requested", "Approved-announcement to be sent"]:
|
||||
goal1 = 4
|
||||
goal2 = 7
|
||||
elif sub_state == "Revised ID Needed":
|
||||
goal1 = 14
|
||||
goal2 = 28
|
||||
elif main_state == "Publication Requested":
|
||||
goal1 = 7
|
||||
goal2 = 14
|
||||
elif main_state == "AD Evaluation":
|
||||
goal1 = 14
|
||||
goal2 = 28
|
||||
else:
|
||||
goal1 = 14
|
||||
goal2 = 28
|
||||
if days > goal2:
|
||||
class_name = "ietf-small ietf-highlight-r"
|
||||
elif days > goal1:
|
||||
class_name = "ietf-small ietf-highlight-y"
|
||||
else:
|
||||
class_name = "ietf-small"
|
||||
if days > goal1:
|
||||
title = ' title="Goal is <%d days"' % (goal1,)
|
||||
else:
|
||||
title = ''
|
||||
return '<span class="%s"%s>(for %d day%s)</span>' % (class_name,title,days,('','s')[days != 1])
|
|
@ -1,29 +0,0 @@
|
|||
200 /
|
||||
200 /doc/
|
||||
200,heavy /doc/all/
|
||||
200,heavy /doc/active/
|
||||
|
||||
# current AD -- needs to be updated at some point
|
||||
200 /doc/ad/robert.sparks/
|
||||
# former AD
|
||||
200 /doc/ad/sam.hartman/
|
||||
404 /doc/ad/no.body/
|
||||
|
||||
200 /doc/search/
|
||||
200 /doc/search/?rfcs=on&name=snmp
|
||||
200 /doc/search/?rfcs=on&name=nfs&by=ad&ad=112773
|
||||
200 /doc/search/?activeDrafts=on&name=sipping
|
||||
200 /doc/search/?oldDrafts=on&name=tls
|
||||
200 /doc/search/?activeDrafts=on&oldDrafts=on&ad=112773&by=ad
|
||||
200 /doc/search/?activeDrafts=on&state=12&by=state
|
||||
200 /doc/search/?activeDrafts=on&oldDrafts=on&subState=need-rev&by=state
|
||||
200 /doc/search/?activeDrafts=on&oldDrafts=on&rfcs=on&ad=112773&name=nfs&by=ad
|
||||
200 /doc/search/?rfcs=on&group=tls&by=group
|
||||
200 /doc/search/?activeDrafts=on&group=tls&by=group
|
||||
200 /doc/search/?activeDrafts=on&oldDrafts=on&rfcs=on&author=eronen&by=author
|
||||
200 /doc/search/?activeDrafts=on&oldDrafts=on&rfcs=on&area=934&name=ldap&by=area
|
||||
200 /doc/search/?activeDrafts=on&name=asdfsadfsdfasdf
|
||||
200 /doc/search/?activeDrafts=on&name=%EF%BD%8C #non-ASCII
|
||||
|
||||
# Test case for missing publication date
|
||||
200 /doc/search/?oldDrafts=on&name=ppvpn
|
|
@ -1,179 +0,0 @@
|
|||
from django.conf import settings
|
||||
|
||||
from ietf.idtracker.models import InternetDraft, DocumentComment, BallotInfo, IESGLogin
|
||||
from ietf.idrfc.mails import *
|
||||
from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream
|
||||
|
||||
def add_document_comment(request, doc, text, ballot=None):
|
||||
if request:
|
||||
login = IESGLogin.objects.get(login_name=request.user.username)
|
||||
else:
|
||||
login = None
|
||||
|
||||
c = DocumentComment()
|
||||
c.document = doc.idinternal
|
||||
c.public_flag = True
|
||||
c.version = doc.revision_display()
|
||||
c.comment_text = text
|
||||
c.created_by = login
|
||||
if ballot:
|
||||
c.ballot = ballot
|
||||
c.rfc_flag = doc.idinternal.rfc_flag
|
||||
c.save()
|
||||
|
||||
def generate_ballot(request, doc):
|
||||
ballot = BallotInfo()
|
||||
ballot.ballot = doc.idinternal.ballot_id
|
||||
ballot.active = False
|
||||
ballot.last_call_text = generate_last_call_announcement(request, doc)
|
||||
ballot.approval_text = generate_approval_mail(request, doc)
|
||||
ballot.ballot_writeup = render_to_string("idrfc/ballot_writeup.txt")
|
||||
ballot.save()
|
||||
doc.idinternal.ballot = ballot
|
||||
return ballot
|
||||
|
||||
def log_state_changed(request, doc, by, email_watch_list=True, note=''):
|
||||
change = u"State changed to <b>%s</b> from %s." % (
|
||||
doc.idinternal.docstate(),
|
||||
format_document_state(doc.idinternal.prev_state,
|
||||
doc.idinternal.prev_sub_state))
|
||||
if note:
|
||||
change += "<br>%s" % note
|
||||
|
||||
c = DocumentComment()
|
||||
c.document = doc.idinternal
|
||||
c.public_flag = True
|
||||
c.version = doc.revision_display()
|
||||
c.comment_text = change
|
||||
|
||||
if doc.idinternal.docstate()=="In Last Call":
|
||||
c.comment_text += "\n\n<b>The following Last Call Announcement was sent out:</b>\n\n"
|
||||
c.comment_text += doc.idinternal.ballot.last_call_text
|
||||
|
||||
|
||||
if isinstance(by, IESGLogin):
|
||||
c.created_by = by
|
||||
c.result_state = doc.idinternal.cur_state
|
||||
c.origin_state = doc.idinternal.prev_state
|
||||
c.rfc_flag = doc.idinternal.rfc_flag
|
||||
c.save()
|
||||
|
||||
if email_watch_list:
|
||||
email_state_changed(request, doc, strip_tags(change))
|
||||
|
||||
return change
|
||||
|
||||
def log_state_changedREDESIGN(request, doc, by, prev_iesg_state, prev_iesg_tag):
|
||||
from ietf.doc.models import DocEvent, IESG_SUBSTATE_TAGS
|
||||
|
||||
state = doc.get_state("draft-iesg")
|
||||
|
||||
state_name = state.name
|
||||
tags = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
|
||||
if tags:
|
||||
state_name += "::" + tags[0].name
|
||||
|
||||
prev_state_name = prev_iesg_state.name if prev_iesg_state else "I-D Exists"
|
||||
if prev_iesg_tag:
|
||||
prev_state_name += "::" + prev_iesg_tag.name
|
||||
|
||||
e = DocEvent(doc=doc, by=by)
|
||||
e.type = "changed_document"
|
||||
e.desc = u"State changed to <b>%s</b> from %s" % (state_name, prev_state_name)
|
||||
e.save()
|
||||
return e
|
||||
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
log_state_changed = log_state_changedREDESIGN
|
||||
|
||||
|
||||
def update_telechat(request, idinternal, new_telechat_date, new_returning_item=None):
|
||||
on_agenda = bool(new_telechat_date)
|
||||
|
||||
if new_returning_item == None:
|
||||
new_returning_item = idinternal.returning_item
|
||||
|
||||
returning_item_changed = False
|
||||
if idinternal.returning_item != bool(new_returning_item):
|
||||
idinternal.returning_item = bool(new_returning_item)
|
||||
returning_item_changed = True
|
||||
|
||||
# auto-update returning item
|
||||
if (not returning_item_changed and
|
||||
on_agenda and idinternal.agenda
|
||||
and new_telechat_date != idinternal.telechat_date):
|
||||
idinternal.returning_item = True
|
||||
|
||||
# update agenda
|
||||
doc = idinternal.document()
|
||||
if bool(idinternal.agenda) != on_agenda:
|
||||
if on_agenda:
|
||||
add_document_comment(request, doc,
|
||||
"Placed on agenda for telechat - %s" % new_telechat_date)
|
||||
idinternal.telechat_date = new_telechat_date
|
||||
else:
|
||||
add_document_comment(request, doc,
|
||||
"Removed from agenda for telechat")
|
||||
idinternal.agenda = on_agenda
|
||||
elif on_agenda and new_telechat_date != idinternal.telechat_date:
|
||||
add_document_comment(request, doc,
|
||||
"Telechat date has been changed to <b>%s</b> from <b>%s</b>" %
|
||||
(new_telechat_date,
|
||||
idinternal.telechat_date))
|
||||
idinternal.telechat_date = new_telechat_date
|
||||
|
||||
def update_telechatREDESIGN(request, doc, by, new_telechat_date, new_returning_item=None):
|
||||
from ietf.doc.models import TelechatDocEvent
|
||||
|
||||
on_agenda = bool(new_telechat_date)
|
||||
|
||||
prev = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
|
||||
prev_returning = bool(prev and prev.returning_item)
|
||||
prev_telechat = prev.telechat_date if prev else None
|
||||
prev_agenda = bool(prev_telechat)
|
||||
|
||||
returning_item_changed = bool(new_returning_item != None and new_returning_item != prev_returning)
|
||||
|
||||
if new_returning_item == None:
|
||||
returning = prev_returning
|
||||
else:
|
||||
returning = new_returning_item
|
||||
|
||||
if returning == prev_returning and new_telechat_date == prev_telechat:
|
||||
# fully updated, nothing to do
|
||||
return
|
||||
|
||||
# auto-update returning item
|
||||
if (not returning_item_changed and on_agenda and prev_agenda
|
||||
and new_telechat_date != prev_telechat):
|
||||
returning = True
|
||||
|
||||
e = TelechatDocEvent()
|
||||
e.type = "scheduled_for_telechat"
|
||||
e.by = by
|
||||
e.doc = doc
|
||||
e.returning_item = returning
|
||||
e.telechat_date = new_telechat_date
|
||||
|
||||
if on_agenda != prev_agenda:
|
||||
if on_agenda:
|
||||
e.desc = "Placed on agenda for telechat - %s" % (new_telechat_date)
|
||||
else:
|
||||
e.desc = "Removed from agenda for telechat"
|
||||
elif on_agenda and new_telechat_date != prev_telechat:
|
||||
e.desc = "Telechat date has been changed to <b>%s</b> from <b>%s</b>" % (
|
||||
new_telechat_date, prev_telechat)
|
||||
else:
|
||||
# we didn't reschedule but flipped returning item bit - let's
|
||||
# just explain that
|
||||
if returning:
|
||||
e.desc = "Set telechat returning item indication"
|
||||
else:
|
||||
e.desc = "Removed telechat returning item indication"
|
||||
|
||||
e.save()
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
update_telechat = update_telechatREDESIGN
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
# All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# * Neither the name of the Nokia Corporation and/or its
|
||||
# subsidiary(-ies) nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from ietf.idrfc.views_search import SearchForm
|
||||
|
||||
def main(request):
|
||||
form = SearchForm()
|
||||
return render_to_response('idrfc/main.html', {'form':form}, context_instance=RequestContext(request))
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
# Copyright The IETF Trust 2007, All Rights Reserved
|
||||
#
|
||||
import doctest, unittest
|
||||
|
||||
from ietf.idtracker.templatetags import ietf_filters
|
||||
|
||||
class TemplateTagTest(unittest.TestCase):
|
||||
def test_template_tags(self):
|
||||
failures, tests = doctest.testmod(ietf_filters)
|
||||
self.assertEqual(failures, 0)
|
|
@ -7,7 +7,6 @@ from django.conf import settings
|
|||
|
||||
from pyquery import PyQuery
|
||||
|
||||
from ietf.idrfc.models import RfcIndex
|
||||
from ietf.idtracker.models import *
|
||||
from ietf.iesg.models import *
|
||||
from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest, canonicalize_feed, login_testing_unauthorized
|
||||
|
|
|
@ -49,11 +49,10 @@ from django.utils import simplejson as json
|
|||
from django import forms
|
||||
from ietf.iesg.models import TelechatDates, TelechatAgendaItem, WGAction
|
||||
from ietf.idrfc.idrfc_wrapper import IdWrapper, RfcWrapper
|
||||
from ietf.idrfc.models import RfcIndex
|
||||
from ietf.idrfc.utils import update_telechat
|
||||
from ietf.doc.utils import update_telechat
|
||||
from ietf.ietfauth.decorators import group_required, role_required
|
||||
from ietf.idtracker.templatetags.ietf_filters import in_group
|
||||
from ietf.ipr.models import IprDocAlias
|
||||
from ietf.ietfauth.utils import has_role
|
||||
from ietf.ipr.models import IprDocAlias
|
||||
from ietf.doc.models import Document, TelechatDocEvent, LastCallDocEvent, ConsensusDocEvent
|
||||
from ietf.group.models import Group, GroupMilestone
|
||||
|
||||
|
@ -603,61 +602,27 @@ def telechat_docs_tarfile(request,year,month,day):
|
|||
return response
|
||||
|
||||
def discusses(request):
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
res = []
|
||||
|
||||
for d in IDInternal.objects.filter(states__type="draft-iesg", states__slug__in=("pub-req", "ad-eval", "review-e", "lc-req", "lc", "writeupw", "goaheadw", "iesg-eva", "defer", "watching"), docevent__ballotpositiondocevent__pos="discuss").distinct():
|
||||
found = False
|
||||
for p in d.positions.all():
|
||||
if p.discuss:
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
continue
|
||||
|
||||
if d.rfc_flag:
|
||||
doc = RfcWrapper(d)
|
||||
else:
|
||||
doc = IdWrapper(draft=d)
|
||||
|
||||
if doc.in_ietf_process() and doc.ietf_process.has_active_iesg_ballot():
|
||||
res.append(doc)
|
||||
|
||||
return direct_to_template(request, 'iesg/discusses.html', {'docs':res})
|
||||
|
||||
positions = Position.objects.filter(discuss=1)
|
||||
res = []
|
||||
try:
|
||||
ids = set()
|
||||
except NameError:
|
||||
# for Python 2.3
|
||||
from sets import Set as set
|
||||
ids = set()
|
||||
|
||||
for p in positions:
|
||||
try:
|
||||
draft = p.ballot.drafts.filter(primary_flag=1)
|
||||
if len(draft) > 0 and draft[0].rfc_flag:
|
||||
if not -draft[0].draft_id in ids:
|
||||
ids.add(-draft[0].draft_id)
|
||||
try:
|
||||
ri = RfcIndex.objects.get(rfc_number=draft[0].draft_id)
|
||||
doc = RfcWrapper(ri)
|
||||
if doc.in_ietf_process() and doc.ietf_process.has_active_iesg_ballot():
|
||||
res.append(doc)
|
||||
except RfcIndex.DoesNotExist:
|
||||
# NOT QUITE RIGHT, although this should never happen
|
||||
pass
|
||||
if len(draft) > 0 and not draft[0].rfc_flag and draft[0].draft.id_document_tag not in ids:
|
||||
ids.add(draft[0].draft.id_document_tag)
|
||||
doc = IdWrapper(draft=draft[0])
|
||||
if doc.in_ietf_process() and doc.ietf_process.has_active_iesg_ballot():
|
||||
res.append(doc)
|
||||
except IDInternal.DoesNotExist:
|
||||
pass
|
||||
return direct_to_template(request, 'iesg/discusses.html', {'docs':res})
|
||||
|
||||
for d in IDInternal.objects.filter(states__type="draft-iesg", states__slug__in=("pub-req", "ad-eval", "review-e", "lc-req", "lc", "writeupw", "goaheadw", "iesg-eva", "defer", "watching"), docevent__ballotpositiondocevent__pos="discuss").distinct():
|
||||
found = False
|
||||
for p in d.positions.all():
|
||||
if p.discuss:
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
continue
|
||||
|
||||
if d.rfc_flag:
|
||||
doc = RfcWrapper(d)
|
||||
else:
|
||||
doc = IdWrapper(draft=d)
|
||||
|
||||
if doc.in_ietf_process() and doc.ietf_process.has_active_iesg_ballot():
|
||||
res.append(doc)
|
||||
|
||||
return direct_to_template(request, 'iesg/discusses.html', {'docs':res})
|
||||
|
||||
@role_required('Area Director', 'Secretariat')
|
||||
def milestones_needing_review(request):
|
||||
|
@ -747,7 +712,7 @@ def get_possible_wg_actions():
|
|||
def working_group_actions(request):
|
||||
current_items = WGAction.objects.order_by('status_date').select_related()
|
||||
|
||||
if request.method == 'POST' and in_group(request.user, 'Secretariat'):
|
||||
if request.method == 'POST' and has_role(request.user, 'Secretariat'):
|
||||
filename = request.POST.get('filename')
|
||||
if filename and filename in os.listdir(settings.IESG_WG_EVALUATION_DIR):
|
||||
if 'delete' in request.POST:
|
||||
|
|
|
@ -260,7 +260,7 @@ def session_agenda(request, num, session):
|
|||
|
||||
if d:
|
||||
agenda = d[0]
|
||||
content = read_agenda_file(num, agenda)
|
||||
content = read_agenda_file(num, agenda) or "Could not read agenda file"
|
||||
_, ext = os.path.splitext(agenda.external_url)
|
||||
ext = ext.lstrip(".").lower()
|
||||
|
||||
|
@ -331,33 +331,34 @@ def read_agenda_file(num, doc):
|
|||
return None
|
||||
|
||||
def session_draft_list(num, session):
|
||||
#extensions = ["html", "htm", "txt", "HTML", "HTM", "TXT", ]
|
||||
result = []
|
||||
found = False
|
||||
try:
|
||||
agenda = Document.objects.filter(type="agenda",
|
||||
session__meeting__number=num,
|
||||
session__group__acronym=session,
|
||||
states=State.objects.get(type="agenda", slug="active")).distinct().get()
|
||||
except Document.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
drafts = set()
|
||||
content = read_agenda_file(num, agenda)
|
||||
if content:
|
||||
drafts.update(re.findall('(draft-[-a-z0-9]*)', content))
|
||||
|
||||
for agenda in Document.objects.filter(type="agenda", session__meeting__number=num, session__group__acronym=session):
|
||||
content = read_agenda_file(num, agenda)
|
||||
if content != None:
|
||||
found = True
|
||||
drafts.update(re.findall('(draft-[-a-z0-9]*)', content))
|
||||
|
||||
if not found:
|
||||
raise Http404("No agenda for the %s group of IETF %s is available" % (session, num))
|
||||
|
||||
result = []
|
||||
for draft in drafts:
|
||||
try:
|
||||
if (re.search('-[0-9]{2}$',draft)):
|
||||
if re.search('-[0-9]{2}$', draft):
|
||||
doc_name = draft
|
||||
else:
|
||||
id = InternetDraft.objects.get(filename=draft)
|
||||
#doc = IdWrapper(id)
|
||||
doc_name = draft + "-" + id.revision
|
||||
result.append(doc_name)
|
||||
except InternetDraft.DoesNotExist:
|
||||
doc = Document.objects.get(filename=draft)
|
||||
doc_name = draft + "-" + doc.rev
|
||||
|
||||
if doc_name not in result:
|
||||
result.append(doc_name)
|
||||
except Document.DoesNotExist:
|
||||
pass
|
||||
return sorted(list(set(result)))
|
||||
|
||||
return sorted(result)
|
||||
|
||||
|
||||
def session_draft_tarfile(request, num, session):
|
||||
|
|
|
@ -7,7 +7,7 @@ from django.template.defaultfilters import linebreaksbr, force_escape
|
|||
|
||||
from ietf.utils.pipe import pipe
|
||||
from ietf.ietfauth.decorators import has_role
|
||||
from ietf.idtracker.templatetags.ietf_filters import wrap_text
|
||||
from ietf.doc.templatetags.ietf_filters import wrap_text
|
||||
|
||||
from ietf.person.models import Person
|
||||
from ietf.nomcom.models import Feedback
|
||||
|
|
|
@ -13,9 +13,8 @@ from ietf.doc.utils import get_document_content, log_state_changed
|
|||
from ietf.group.models import Group
|
||||
from ietf.name.models import BallotPositionName
|
||||
from ietf.person.models import Person
|
||||
from ietf.idrfc.lastcall import request_last_call
|
||||
from ietf.idrfc.mails import email_owner, email_state_changed
|
||||
from ietf.idrfc.utils import add_document_comment
|
||||
from ietf.doc.lastcall import request_last_call
|
||||
from ietf.doc.mails import email_ad, email_state_changed
|
||||
from ietf.iesg.models import TelechatDate, TelechatAgendaItem, WGAction
|
||||
from ietf.iesg.views import _agenda_data
|
||||
|
||||
|
@ -230,7 +229,7 @@ def doc_detail(request, date, name):
|
|||
if request.method == 'POST':
|
||||
button_text = request.POST.get('submit', '')
|
||||
|
||||
# logic from idrfc/views_ballot.py EditPositionRedesign
|
||||
# logic from doc/views_ballot.py EditPositionRedesign
|
||||
if button_text == 'update_ballot':
|
||||
formset = BallotFormset(request.POST, initial=initial_ballot)
|
||||
state_form = ChangeStateForm(initial=initial_state)
|
||||
|
@ -257,7 +256,7 @@ def doc_detail(request, date, name):
|
|||
url = reverse('telechat_doc_detail', kwargs={'date':date,'name':name})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
# logic from idrfc/views_edit.py change_stateREDESIGN
|
||||
# logic from doc/views_draft.py change_state
|
||||
elif button_text == 'update_state':
|
||||
formset = BallotFormset(initial=initial_ballot)
|
||||
state_form = ChangeStateForm(request.POST, initial=initial_state)
|
||||
|
@ -291,7 +290,7 @@ def doc_detail(request, date, name):
|
|||
doc.save()
|
||||
|
||||
email_state_changed(request, doc, e.desc)
|
||||
email_owner(request, doc, doc.ad, login, e.desc)
|
||||
email_ad(request, doc, doc.ad, login, e.desc)
|
||||
|
||||
if state.slug == "lc-req":
|
||||
request_last_call(request, doc)
|
||||
|
@ -436,4 +435,4 @@ def roll_call(request, date):
|
|||
'people':sorted_ads},
|
||||
RequestContext(request, {}),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Standard settings except we use SQLite, this is useful for speeding
|
||||
# up tests that depend on the test database, try for instance:
|
||||
#
|
||||
# ./manage.py test --settings=settings_sqlitetest idrfc.ChangeStateTestCase
|
||||
# ./manage.py test --settings=settings_sqlitetest doc.ChangeStateTestCase
|
||||
#
|
||||
|
||||
from settings import *
|
||||
|
|
|
@ -47,53 +47,6 @@ def request_full_url(request, submission):
|
|||
|
||||
|
||||
def perform_post(request, submission):
|
||||
group_id = submission.group_acronym and submission.group_acronym.pk or NONE_WG
|
||||
state_change_msg = ''
|
||||
try:
|
||||
draft = InternetDraft.objects.get(filename=submission.filename)
|
||||
draft.title = submission.id_document_name
|
||||
draft.group_id = group_id
|
||||
draft.filename = submission.filename
|
||||
draft.revision = submission.revision
|
||||
draft.revision_date = submission.submission_date
|
||||
draft.file_type = submission.file_type
|
||||
draft.txt_page_count = submission.txt_page_count
|
||||
draft.last_modified_date = datetime.date.today()
|
||||
draft.abstract = submission.abstract
|
||||
draft.status_id = 1 # Active
|
||||
draft.expired_tombstone = 0
|
||||
draft.save()
|
||||
except InternetDraft.DoesNotExist:
|
||||
draft = InternetDraft.objects.create(
|
||||
title=submission.id_document_name,
|
||||
group_id=group_id,
|
||||
filename=submission.filename,
|
||||
revision=submission.revision,
|
||||
revision_date=submission.submission_date,
|
||||
file_type=submission.file_type,
|
||||
txt_page_count=submission.txt_page_count,
|
||||
start_date=datetime.date.today(),
|
||||
last_modified_date=datetime.date.today(),
|
||||
abstract=submission.abstract,
|
||||
status_id=1, # Active
|
||||
intended_status_id=8, # None
|
||||
)
|
||||
update_authors(draft, submission)
|
||||
if draft.idinternal:
|
||||
from ietf.idrfc.utils import add_document_comment
|
||||
add_document_comment(None, draft, "New version available")
|
||||
if draft.idinternal.cur_sub_state_id == 5 and draft.idinternal.rfc_flag == 0: # Substate 5 Revised ID Needed
|
||||
draft.idinternal.prev_sub_state_id = draft.idinternal.cur_sub_state_id
|
||||
draft.idinternal.cur_sub_state_id = 2 # Substate 2 AD Followup
|
||||
draft.idinternal.save()
|
||||
state_change_msg = "Sub state has been changed to AD Follow up from New Id Needed"
|
||||
add_document_comment(None, draft, state_change_msg)
|
||||
move_docs(submission)
|
||||
submission.status_id = POSTED
|
||||
send_announcements(submission, draft, state_change_msg)
|
||||
submission.save()
|
||||
|
||||
def perform_postREDESIGN(request, submission):
|
||||
system = Person.objects.get(name="(System)")
|
||||
|
||||
group_id = submission.group_acronym_id or NONE_WG
|
||||
|
@ -163,7 +116,7 @@ def perform_postREDESIGN(request, submission):
|
|||
|
||||
# clean up old files
|
||||
if prev_rev != draft.rev:
|
||||
from ietf.idrfc.expire import move_draft_files_to_archive
|
||||
from ietf.doc.expire import move_draft_files_to_archive
|
||||
move_draft_files_to_archive(draft, prev_rev)
|
||||
|
||||
# automatic state changes
|
||||
|
@ -189,9 +142,6 @@ def perform_postREDESIGN(request, submission):
|
|||
|
||||
submission.save()
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
perform_post = perform_postREDESIGN
|
||||
|
||||
def send_announcements(submission, draft, state_change_msg):
|
||||
announce_to_lists(request, submission)
|
||||
if draft.idinternal and not draft.idinternal.rfc_flag:
|
||||
|
|
|
@ -5,8 +5,8 @@ from django.conf import settings
|
|||
|
||||
from ietf.doc.models import *
|
||||
from ietf.doc.utils import add_state_change_event
|
||||
from ietf.doc.mails import email_ad, email_state_changed, email_authors
|
||||
from ietf.person.models import *
|
||||
from ietf.idrfc.mails import email_owner, email_state_changed, email_authors
|
||||
from ietf.utils.timezone import *
|
||||
|
||||
#PROTOCOLS_URL = "http://www.iana.org/protocols/"
|
||||
|
@ -200,7 +200,7 @@ def update_history_with_changes(changes, send_email=True):
|
|||
|
||||
if send_email and (state != prev_state):
|
||||
email_state_changed(None, doc, "IANA %s state changed to %s" % (kind, state.name))
|
||||
email_owner(None, doc, doc.ad, system, "IANA %s state changed to %s" % (kind, state.name))
|
||||
email_ad(None, doc, doc.ad, system, "IANA %s state changed to %s" % (kind, state.name))
|
||||
|
||||
if doc.time < timestamp:
|
||||
doc.time = timestamp
|
||||
|
|
|
@ -32,9 +32,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{% endcomment %}
|
||||
{% for area in areas %}
|
||||
{% if area.area.active_wgs %}
|
||||
<li class="yuimenuitem"><a class="yuimenuitemlabel">{{area.short_name }}</a><div id="wgs-{{area.area.area_acronym}}" class="yuimenu"><div class="bd"><ul>{% for wg in area.area.active_wgs %}
|
||||
<li class="yuimenuitem"><a class="yuimenuitemlabel" href="/wg/{{wg.group_acronym}}/">{{wg.group_acronym}} — {{wg.group_acronym.name}}</a></li>{% endfor %}
|
||||
<li class="yuimenuitem"><a class="yuimenuitemlabel">{{ area.short_area_name }}</a><div id="wgs-{{ area.acronym }}" class="yuimenu"><div class="bd"><ul>{% for g in area.active_groups %}
|
||||
<li class="yuimenuitem"><a class="yuimenuitemlabel" href="/wg/{{ g.acronym }}/">{{ g.acronym }} — {{ g.name}}</a></li>{% endfor %}
|
||||
</ul></div></div></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="actions">
|
||||
|
||||
{% if request.user|has_role:"Area Director" %}
|
||||
<a href="{% url ietf.idrfc.views_ballot.edit_position name=doc.name ballot_id=ballot_id %}" class="button" style="margin-right: 1em;">Edit Position</a>
|
||||
<a href="{% url ietf.doc.views_ballot.edit_position name=doc.name ballot_id=ballot_id %}" class="button" style="margin-right: 1em;">Edit Position</a>
|
||||
{% endif %}
|
||||
|
||||
<a href="" class="button close">Close</a>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{% if editable and user|has_role:"Area Director,Secretariat" %}
|
||||
<div class="ballot-actions">
|
||||
{% if user|has_role:"Area Director" %}
|
||||
<div class="action"><a href="{% url idrfc.views_ballot.edit_position name=doc.name,ballot_id=ballot.pk %}">Edit position</a></div>
|
||||
<div class="action"><a href="{% url ietf.doc.views_ballot.edit_position name=doc.name,ballot_id=ballot.pk %}">Edit position</a></div>
|
||||
{% endif %}
|
||||
|
||||
{% if doc.type_id == "draft" or doc.type_id == "conflrev" %}
|
||||
|
@ -28,7 +28,7 @@
|
|||
<div class="position-group">
|
||||
<div class="heading"><span class="square position-{{ n.slug }}"></span> {{ n.name }}</div>
|
||||
{% for p in positions %}
|
||||
<div>{% if p.old_ad %}[{% endif %}<a{% if user|has_role:"Secretariat" %} href="{% url idrfc.views_ballot.edit_position name=doc.name,ballot_id=ballot.pk %}?ad={{ p.ad.pk }}" title="Click to edit the position of {{ p.ad.plain_name }}"{% endif %}>{{ p.ad.plain_name }}</a>{% if p.old_ad %}]{% endif %}{% if p.comment or p.discuss %} <a href="#{{ p.ad.plain_name|slugify }}"><img src="/images/comment.png" width="14" height="12" alt="*" border="0"/></a>{% endif %}</div>
|
||||
<div>{% if p.old_ad %}[{% endif %}<a{% if user|has_role:"Secretariat" %} href="{% url ietf.doc.views_ballot.edit_position name=doc.name,ballot_id=ballot.pk %}?ad={{ p.ad.pk }}" title="Click to edit the position of {{ p.ad.plain_name }}"{% endif %}>{{ p.ad.plain_name }}</a>{% if p.old_ad %}]{% endif %}{% if p.comment or p.discuss %} <a href="#{{ p.ad.plain_name|slugify }}"><img src="/images/comment.png" width="14" height="12" alt="*" border="0"/></a>{% endif %}</div>
|
||||
{% if p.old_positions %}<div class="was">(was {{ p.old_positions|join:", " }})</div>{% endif %}
|
||||
{% empty %}
|
||||
<i>none</i>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
{% if snapshot %}Snapshot of{% endif %}
|
||||
{% if doc.get_state_slug != "approved" %}Proposed{% endif %}
|
||||
Charter for "{{ group.name }}"
|
||||
(<a href="{% url ietf.wginfo.views.wg_charter acronym=group.acronym %}">{{ group.acronym }}</a>) {{ group.type.name }}
|
||||
(<a {% if group.type.slug == "wg" %}href="{% url ietf.wginfo.views.wg_charter acronym=group.acronym %}"{% endif %}>{{ group.acronym }}</a>) {{ group.type.name }}
|
||||
</div>
|
||||
|
||||
<table id="metatable" width="100%">
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
</tr>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td><a href="/doc/help/state/status-change/">Review State</a>:</td>
|
||||
<td><a href="{% url state_help type="status-change" %}">Review State</a>:</td>
|
||||
<td>
|
||||
<div>
|
||||
<a title="{{ doc.get_state.desc }}"{% if not snapshot and user|has_role:"Area Director,Secretariat" %} class="editlink" href="{% url status_change_change_state name=doc.name %}"{% endif %}>{{ doc.get_state.name }}</a>
|
|
@ -5,7 +5,7 @@
|
|||
{% block content %}
|
||||
<h1>Documents for {{ ad_name }}</h1>
|
||||
|
||||
{% include "idrfc/search_results.html" %}
|
||||
{% include "doc/search/search_results.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{% block content %}
|
||||
<h1>Internet-Drafts in IETF Last Call</h1>
|
||||
|
||||
{% include "idrfc/search_results.html" %}
|
||||
{% include "doc/search/search_results.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ td.ietf-main-intro { width:200px; background:#fff5df; padding:8px; border:1px so
|
|||
|
||||
<tr valign="top"><td class="ietf-box ietf-main-search">
|
||||
<h1>Search Internet-Drafts and RFCs</h1>
|
||||
{% include "idrfc/search_form.html" %}
|
||||
{% include "doc/search/search_form.html" %}
|
||||
</td>
|
||||
<td style="width:8px;"> </td>
|
||||
<td class="ietf-main-intro">
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue