1313from django .conf import settings
1414from django .forms .util import ErrorList
1515from django .contrib .auth .decorators import login_required
16+ from django .template .defaultfilters import pluralize
1617
1718from ietf .utils .mail import send_mail_text , send_mail_message
1819from ietf .ietfauth .decorators import role_required
@@ -1123,7 +1124,7 @@ def adopt_draft(request, name):
11231124 doc = get_object_or_404 (Document , type = "draft" , name = name )
11241125
11251126 if not can_adopt_draft (request .user , doc ):
1126- return HttpResponseForbidden ("You don't have permission to access this view " )
1127+ return HttpResponseForbidden ("You don't have permission to access this page " )
11271128
11281129 if request .method == 'POST' :
11291130 form = AdoptDraftForm (request .POST , user = request .user )
@@ -1137,15 +1138,14 @@ def adopt_draft(request, name):
11371138 doc .time = datetime .datetime .now ()
11381139
11391140 group = form .cleaned_data ["group" ]
1140- comment = form .cleaned_data ["comment" ].strip ()
1141-
11421141 if group .type .slug == "rg" :
11431142 new_stream = StreamName .objects .get (slug = "irtf" )
11441143 adopt_state_slug = "active"
11451144 else :
11461145 new_stream = StreamName .objects .get (slug = "ietf" )
11471146 adopt_state_slug = "c-adopt"
11481147
1148+ # stream
11491149 if doc .stream != new_stream :
11501150 e = DocEvent (type = "changed_stream" , time = doc .time , by = by , doc = doc )
11511151 e .desc = u"Changed stream to <b>%s</b>" % new_stream .name
@@ -1154,6 +1154,7 @@ def adopt_draft(request, name):
11541154 e .save ()
11551155 doc .stream = new_stream
11561156
1157+ # group
11571158 if group != doc .group :
11581159 e = DocEvent (type = "changed_group" , time = doc .time , by = by , doc = doc )
11591160 e .desc = u"Changed group to <b>%s (%s)</b>" % (group .name , group .acronym .upper ())
@@ -1164,9 +1165,9 @@ def adopt_draft(request, name):
11641165
11651166 doc .save ()
11661167
1168+ # state
11671169 prev_state = doc .get_state ("draft-stream-%s" % doc .stream_id )
11681170 new_state = State .objects .get (slug = adopt_state_slug , type = "draft-stream-%s" % doc .stream_id , used = True )
1169-
11701171 if new_state != prev_state :
11711172 doc .set_state (new_state )
11721173 e = add_state_change_event (doc , by , prev_state , new_state , doc .time )
@@ -1177,6 +1178,8 @@ def adopt_draft(request, name):
11771178
11781179 update_reminder (doc , "stream-s" , e , due_date )
11791180
1181+ # comment
1182+ comment = form .cleaned_data ["comment" ].strip ()
11801183 if comment :
11811184 e = DocEvent (type = "added_comment" , time = doc .time , by = by , doc = doc )
11821185 e .desc = comment
@@ -1194,5 +1197,128 @@ def adopt_draft(request, name):
11941197 },
11951198 context_instance = RequestContext (request ))
11961199
1197- def change_stream_state (request ):
1198- pass
1200+ class ChangeStreamStateForm (forms .Form ):
1201+ new_state = forms .ModelChoiceField (queryset = State .objects .filter (used = True ), label = 'State' )
1202+ weeks = forms .IntegerField (label = 'Expected weeks in state' ,required = False )
1203+ comment = forms .CharField (widget = forms .Textarea , required = False , help_text = "Optional comment for the document history" )
1204+ tags = forms .ModelMultipleChoiceField (queryset = DocTagName .objects .filter (used = True ), widget = forms .CheckboxSelectMultiple , required = False )
1205+
1206+ def __init__ (self , * args , ** kwargs ):
1207+ doc = kwargs .pop ("doc" )
1208+ state_type = kwargs .pop ("state_type" )
1209+ super (ChangeStreamStateForm , self ).__init__ (* args , ** kwargs )
1210+
1211+ f = self .fields ["new_state" ]
1212+ f .queryset = f .queryset .filter (type = state_type )
1213+ if doc .group :
1214+ unused_states = doc .group .unused_states .values_list ("pk" , flat = True )
1215+ f .queryset = f .queryset .exclude (pk__in = unused_states )
1216+ f .label = state_type .label
1217+
1218+ f = self .fields ['tags' ]
1219+ f .queryset = f .queryset .filter (slug__in = get_tags_for_stream_id (doc .stream_id ))
1220+ if doc .group :
1221+ unused_tags = doc .group .unused_tags .values_list ("pk" , flat = True )
1222+ f .queryset = f .queryset .exclude (pk__in = unused_tags )
1223+
1224+ def next_states_for_stream_state (doc , state_type , current_state ):
1225+ # find next states
1226+ next_states = []
1227+ if current_state :
1228+ next_states = current_state .next_states .all ()
1229+
1230+ if doc .stream_id == "ietf" and doc .group :
1231+ transitions = doc .group .groupstatetransitions_set .filter (state = current_state )
1232+ if transitions :
1233+ next_states = transitions [0 ].next_states .all ()
1234+ else :
1235+ # return the initial state
1236+ states = State .objects .filter (used = True , type = state_type ).order_by ('order' )
1237+ if states :
1238+ next_states = states [:1 ]
1239+
1240+ if doc .group :
1241+ unused_states = doc .group .unused_states .values_list ("pk" , flat = True )
1242+ next_states = [n for n in next_states if n .pk not in unused_states ]
1243+
1244+ return next_states
1245+
1246+ @login_required
1247+ def change_stream_state (request , name ):
1248+ doc = get_object_or_404 (Document , type = "draft" , name = name )
1249+ if not doc .stream :
1250+ raise Http404
1251+
1252+ if not is_authorized_in_doc_stream (request .user , doc ):
1253+ return HttpResponseForbidden ("You don't have permission to access this page" )
1254+
1255+ state_type = StateType .objects .get (slug = "draft-stream-%s" % doc .stream_id )
1256+ prev_state = doc .get_state (state_type .slug )
1257+ next_states = next_states_for_stream_state (doc , state_type , prev_state )
1258+
1259+ if request .method == 'POST' :
1260+ form = ChangeStreamStateForm (request .POST , doc = doc , state_type = state_type )
1261+ if form .is_valid ():
1262+ by = request .user .get_profile ()
1263+
1264+ save_document_in_history (doc )
1265+
1266+ doc .time = datetime .datetime .now ()
1267+ comment = form .cleaned_data ["comment" ].strip ()
1268+
1269+ # state
1270+ new_state = form .cleaned_data ["new_state" ]
1271+ if new_state != prev_state :
1272+ doc .set_state (new_state )
1273+ e = add_state_change_event (doc , by , prev_state , new_state , doc .time )
1274+
1275+ due_date = None
1276+ if form .cleaned_data ["weeks" ] != None :
1277+ due_date = datetime .date .today () + datetime .timedelta (weeks = form .cleaned_data ["weeks" ])
1278+
1279+ update_reminder (doc , "stream-s" , e , due_date )
1280+
1281+ email_stream_state_changed (request , doc , prev_state , new_state , by , comment )
1282+
1283+ # tags
1284+ existing_tags = set (doc .tags .all ())
1285+ new_tags = set (form .cleaned_data ["tags" ])
1286+
1287+ if existing_tags != new_tags :
1288+ doc .tags = new_tags
1289+
1290+ e = DocEvent (type = "changed_document" , time = doc .time , by = by , doc = doc )
1291+ added_tags = new_tags - existing_tags
1292+ removed_tags = existing_tags - new_tags
1293+ l = []
1294+ if added_tags :
1295+ l .append (u"Tag%s %s set." % (pluralize (added_tags ), ", " .join (t .name for t in added_tags )))
1296+ if removed_tags :
1297+ l .append (u"Tag%s %s cleared." % (pluralize (removed_tags ), ", " .join (t .name for t in removed_tags )))
1298+ e .desc = " " .join (l )
1299+ e .save ()
1300+
1301+ email_stream_tags_changed (request , doc , added_tags , removed_tags , by , comment )
1302+
1303+ # comment
1304+ if comment :
1305+ e = DocEvent (type = "added_comment" , time = doc .time , by = by , doc = doc )
1306+ e .desc = comment
1307+ e .save ()
1308+
1309+ return HttpResponseRedirect (doc .get_absolute_url ())
1310+ else :
1311+ form = ChangeStreamStateForm (initial = dict (new_state = prev_state .pk ),
1312+ doc = doc , state_type = state_type )
1313+
1314+ milestones = doc .groupmilestone_set .all ()
1315+
1316+
1317+ return render_to_response ("doc/draft/change_stream_state.html" ,
1318+ {"doc" : doc ,
1319+ "form" : form ,
1320+ "milestones" : milestones ,
1321+ "state_type" : state_type ,
1322+ "next_states" : next_states ,
1323+ },
1324+ context_instance = RequestContext (request ))
0 commit comments