1111from ietf .doc .utils import add_state_change_event , update_telechat
1212from ietf .doc .models import save_document_in_history
1313from ietf .doc .utils import create_ballot_if_not_open , close_open_ballots , get_document_content
14- from ietf .ietfauth .utils import has_role , role_required
14+ from ietf .ietfauth .utils import has_role , role_required , is_authorized_in_doc_stream
1515from ietf .utils .textupload import get_cleaned_text_file_content
1616from ietf .utils .mail import send_mail_preformatted
1717from ietf .doc .mails import email_iana
@@ -88,6 +88,22 @@ def change_state(request, name, option=None):
8888 ),
8989 context_instance = RequestContext (request ))
9090
91+ def send_conflict_review_started_email (request , review ):
92+ msg = render_to_string ("doc/conflict_review/review_started.txt" ,
93+ dict (frm = settings .DEFAULT_FROM_EMAIL ,
94+ by = request .user .person ,
95+ review = review ,
96+ reviewed_doc = review .relateddocument_set .get (relationship__slug = 'conflrev' ).target .document ,
97+ review_url = settings .IDTRACKER_BASE_URL + review .get_absolute_url (),
98+ )
99+ )
100+ if not has_role (request .user ,"Secretariat" ):
101+ send_mail_preformatted (request ,msg )
102+ email_iana (request ,
103+ review .relateddocument_set .get (relationship__slug = 'conflrev' ).target .document ,
104+ settings .IANA_EVAL_EMAIL ,
105+ msg )
106+
91107def send_conflict_eval_email (request ,review ):
92108 msg = render_to_string ("doc/eval_email.txt" ,
93109 dict (doc = review ,
@@ -345,6 +361,9 @@ def approve(request, name):
345361 ),
346362 context_instance = RequestContext (request ))
347363
364+ class SimpleStartReviewForm (forms .Form ):
365+ notify = forms .CharField (max_length = 255 , label = "Notice emails" , help_text = "Separate email addresses with commas" , required = False )
366+
348367class StartReviewForm (forms .Form ):
349368 ad = forms .ModelChoiceField (Person .objects .filter (role__name = "ad" , role__group__state = "active" ).order_by ('name' ),
350369 label = "Shepherding AD" , empty_label = "(None)" , required = True )
@@ -363,73 +382,96 @@ def __init__(self, *args, **kwargs):
363382
364383 self .fields ['telechat_date' ].choices = [("" , "(not on agenda)" )] + [(d , d .strftime ("%Y-%m-%d" )) for d in dates ]
365384
366- @role_required ("Secretariat" )
385+ @role_required ("Secretariat" , "IRTF Chair" , "ISE" )
367386def start_review (request , name ):
368- """Start the conflict review process, setting the initial shepherding AD, and possibly putting the review on a telechat."""
387+ if has_role (request .user ,"Secretariat" ):
388+ return start_review_as_secretariat (request ,name )
389+ else :
390+ return start_review_as_stream_owner (request ,name )
369391
392+ def start_review_sanity_check (request , name ):
370393 doc_to_review = get_object_or_404 (Document , type = "draft" , name = name )
371394
372- if not doc_to_review .stream_id in ('ise' ,'irtf' ):
395+ if ( not doc_to_review .stream_id in ('ise' ,'irtf' ) ) or ( not is_authorized_in_doc_stream ( request . user , doc_to_review ) ):
373396 raise Http404
374397
375398 # sanity check that there's not already a conflict review document for this document
376399 if [ rel .source for alias in doc_to_review .docalias_set .all () for rel in alias .relateddocument_set .filter (relationship = 'conflrev' ) ]:
377400 raise Http404
378401
379- login = request . user . person
402+ return doc_to_review
380403
404+ def build_notify_addresses (doc_to_review ):
405+ # Take care to do the right thing during ietf chair and stream owner transitions
406+ notify_addresses = []
407+ notify_addresses .extend ([x .person .formatted_email () for x in Role .objects .filter (group__acronym = doc_to_review .stream .slug ,name = 'chair' )])
408+ notify_addresses .append ("%s@%s" % (doc_to_review .name , settings .TOOLS_SERVER ))
409+ return notify_addresses
410+
411+ def build_conflict_review_document (login , doc_to_review , ad , notify , create_in_state ):
412+ if doc_to_review .name .startswith ('draft-' ):
413+ review_name = 'conflict-review-' + doc_to_review .name [6 :]
414+ else :
415+ # This is a failsafe - and might be treated better as an error
416+ review_name = 'conflict-review-' + doc_to_review .name
417+
418+ iesg_group = Group .objects .get (acronym = 'iesg' )
419+
420+ conflict_review = Document ( type_id = "conflrev" ,
421+ title = "IETF conflict review for %s" % doc_to_review .name ,
422+ name = review_name ,
423+ rev = "00" ,
424+ ad = ad ,
425+ notify = notify ,
426+ stream_id = 'ietf' ,
427+ group = iesg_group ,
428+ )
429+ conflict_review .save ()
430+ conflict_review .set_state (create_in_state )
431+
432+ DocAlias .objects .create ( name = review_name , document = conflict_review )
433+
434+ conflict_review .relateddocument_set .create (target = DocAlias .objects .get (name = doc_to_review .name ),relationship_id = 'conflrev' )
435+
436+ c = DocEvent (type = "added_comment" , doc = conflict_review , by = login )
437+ c .desc = "IETF conflict review requested"
438+ c .save ()
439+
440+ c = DocEvent (type = "added_comment" , doc = doc_to_review , by = login )
441+ # Is it really OK to put html tags into comment text?
442+ c .desc = 'IETF conflict review initiated - see <a href="%s">%s</a>' % (reverse ('doc_view' , kwargs = {'name' :conflict_review .name }),conflict_review .name )
443+ c .save ()
444+
445+ return conflict_review
446+
447+ def start_review_as_secretariat (request , name ):
448+ """Start the conflict review process, setting the initial shepherding AD, and possibly putting the review on a telechat."""
449+
450+ doc_to_review = start_review_sanity_check (request , name )
451+
452+ login = request .user .person
381453
382454 if request .method == 'POST' :
383455 form = StartReviewForm (request .POST )
384456 if form .is_valid ():
457+ conflict_review = build_conflict_review_document (login = login ,
458+ doc_to_review = doc_to_review ,
459+ ad = form .cleaned_data ['ad' ],
460+ notify = form .cleaned_data ['notify' ],
461+ create_in_state = form .cleaned_data ['create_in_state' ]
462+ )
385463
386- if doc_to_review .name .startswith ('draft-' ):
387- review_name = 'conflict-review-' + doc_to_review .name [6 :]
388- else :
389- # This is a failsafe - and might be treated better as an error
390- review_name = 'conflict-review-' + doc_to_review .name
391-
392- iesg_group = Group .objects .get (acronym = 'iesg' )
393-
394- conflict_review = Document ( type_id = "conflrev" ,
395- title = "IETF conflict review for %s" % doc_to_review .name ,
396- name = review_name ,
397- rev = "00" ,
398- ad = form .cleaned_data ['ad' ],
399- notify = form .cleaned_data ['notify' ],
400- stream_id = 'ietf' ,
401- group = iesg_group ,
402- )
403- conflict_review .save ()
404- conflict_review .set_state (form .cleaned_data ['create_in_state' ])
405-
406- DocAlias .objects .create ( name = review_name , document = conflict_review )
407-
408- conflict_review .relateddocument_set .create (target = DocAlias .objects .get (name = doc_to_review .name ),relationship_id = 'conflrev' )
409-
410- c = DocEvent (type = "added_comment" , doc = conflict_review , by = login )
411- c .desc = "IETF conflict review requested"
412- c .save ()
413-
414- c = DocEvent (type = "added_comment" , doc = doc_to_review , by = login )
415- # Is it really OK to put html tags into comment text?
416- c .desc = 'IETF conflict review initiated - see <a href="%s">%s</a>' % (reverse ('doc_view' , kwargs = {'name' :conflict_review .name }),conflict_review .name )
417- c .save ()
418-
419464 tc_date = form .cleaned_data ['telechat_date' ]
420465 if tc_date :
421466 update_telechat (request , conflict_review , login , tc_date )
422467
468+ send_conflict_review_started_email (request , conflict_review )
469+
423470 return HttpResponseRedirect (conflict_review .get_absolute_url ())
424471 else :
425- # Take care to do the right thing during ietf chair and stream owner transitions
426- ietf_chair_id = Role .objects .filter (group__acronym = 'ietf' ,name = 'chair' )[0 ].person .id
427- notify_addresses = []
428- notify_addresses .extend ([x .person .formatted_email () for x in Role .objects .filter (group__acronym = doc_to_review .stream .slug ,name = 'chair' )])
429- notify_addresses .append ("%s@%s" % (name , settings .TOOLS_SERVER ))
430-
472+ notify_addresses = build_notify_addresses (doc_to_review )
431473 init = {
432- "ad" : ietf_chair_id ,
474+ "ad" : Role . objects . filter ( group__acronym = 'ietf' , name = 'chair' )[ 0 ]. person . id ,
433475 "notify" : u', ' .join (notify_addresses ),
434476 }
435477 form = StartReviewForm (initial = init )
@@ -440,6 +482,39 @@ def start_review(request, name):
440482 },
441483 context_instance = RequestContext (request ))
442484
485+ def start_review_as_stream_owner (request , name ):
486+ """Start the conflict review process using defaults for everything but notify and let the secretariat know"""
487+
488+ doc_to_review = start_review_sanity_check (request , name )
489+
490+ login = request .user .person
491+
492+ if request .method == 'POST' :
493+ form = SimpleStartReviewForm (request .POST )
494+ if form .is_valid ():
495+ conflict_review = build_conflict_review_document (login = login ,
496+ doc_to_review = doc_to_review ,
497+ ad = Role .objects .filter (group__acronym = 'ietf' ,name = 'chair' )[0 ].person ,
498+ notify = form .cleaned_data ['notify' ],
499+ create_in_state = State .objects .get (used = True ,type = 'conflrev' ,slug = 'needshep' )
500+ )
501+
502+ send_conflict_review_started_email (request , conflict_review )
503+
504+ return HttpResponseRedirect (conflict_review .get_absolute_url ())
505+ else :
506+ notify_addresses = build_notify_addresses (doc_to_review )
507+
508+ init = {
509+ "notify" : u', ' .join (notify_addresses ),
510+ }
511+ form = SimpleStartReviewForm (initial = init )
512+
513+ return render_to_response ('doc/conflict_review/start.html' ,
514+ {'form' : form ,
515+ 'doc_to_review' : doc_to_review ,
516+ },
517+ context_instance = RequestContext (request ))
443518
444519@role_required ("Area Director" , "Secretariat" )
445520def telechat_date (request , name ):
0 commit comments