1717from ietf .doc .utils import add_state_change_event , check_common_doc_name_rules
1818from ietf .group .models import Group
1919from ietf .group .utils import can_manage_materials
20+ from ietf .meeting .models import Session
2021
2122@login_required
2223def choose_material_type (request , acronym ):
@@ -32,8 +33,9 @@ def choose_material_type(request, acronym):
3233class UploadMaterialForm (forms .Form ):
3334 title = forms .CharField (max_length = Document ._meta .get_field ("title" ).max_length )
3435 name = forms .CharField (max_length = Document ._meta .get_field ("name" ).max_length )
36+ abstract = forms .CharField (max_length = Document ._meta .get_field ("abstract" ).max_length ,widget = forms .Textarea )
3537 state = forms .ModelChoiceField (State .objects .all (), empty_label = None )
36- material = forms .FileField (label = 'File' , help_text = "PDF or text file (ASCII/UTF-8)" )
38+ material = forms .FileField (label = 'File' )
3739
3840 def __init__ (self , doc_type , action , group , doc , * args , ** kwargs ):
3941 super (UploadMaterialForm , self ).__init__ (* args , ** kwargs )
@@ -53,16 +55,15 @@ def __init__(self, doc_type, action, group, doc, *args, **kwargs):
5355 del self .fields ["name" ]
5456
5557 self .fields ["title" ].initial = doc .title
58+ self .fields ["abstract" ].initial = doc .abstract
5659 self .fields ["state" ].initial = doc .get_state ().pk if doc .get_state () else None
5760 if doc .get_state_slug () == "deleted" :
5861 self .fields ["state" ].help_text = "Note: If you wish to revise this document, you may wish to change the state so it's not deleted."
5962
60- if action == "title" :
61- del self .fields ["state" ]
62- del self .fields ["material" ]
63- elif action == "state" :
64- del self .fields ["title" ]
65- del self .fields ["material" ]
63+ if action in ["title" ,"state" ,"abstract" ]:
64+ for fieldname in ["title" ,"state" ,"material" ,"abstract" ]:
65+ if fieldname != action :
66+ del self .fields [fieldname ]
6667
6768 def clean_name (self ):
6869 name = self .cleaned_data ["name" ].strip ().rstrip ("-" )
@@ -120,6 +121,9 @@ def edit_material(request, name=None, acronym=None, action=None, doc_type=None):
120121 if "title" in form .cleaned_data :
121122 doc .title = form .cleaned_data ["title" ]
122123
124+ if "abstract" in form .cleaned_data :
125+ doc .abstract = form .cleaned_data ["abstract" ]
126+
123127 doc .time = datetime .datetime .now ()
124128
125129 if "material" in form .fields :
@@ -168,3 +172,151 @@ def edit_material(request, name=None, acronym=None, action=None, doc_type=None):
168172 'document_type' : document_type ,
169173 'doc_name' : doc .name if doc else "" ,
170174 })
175+
176+ class MaterialVersionForm (forms .Form ):
177+
178+ version = forms .ChoiceField (required = False ,
179+ label = 'Which version of this document will be presented at this session' )
180+
181+ def __init__ (self , * args , ** kwargs ):
182+ choices = kwargs .pop ('choices' )
183+ super (MaterialVersionForm ,self ).__init__ (* args ,** kwargs )
184+ self .fields ['version' ].choices = choices
185+
186+ def get_upcoming_manageable_sessions (user , doc , acronym = None , date = None , seq = None , week_day = None ):
187+
188+ # Find all the sessions for meetings that haven't ended that the user could affect
189+ # This motif is also in Document.future_presentations - it would be nice to consolodate it somehow
190+
191+ candidate_sessions = Session .objects .exclude (status__in = ['canceled' ,'disappr' ,'notmeet' ,'deleted' ]).filter (meeting__date__gte = datetime .date .today ()- datetime .timedelta (days = 15 ))
192+ refined_candidates = [ sess for sess in candidate_sessions if sess .meeting .end_date ()>= datetime .date .today ()]
193+
194+ if acronym :
195+ refined_candidates = [ sess for sess in refined_candidates if sess .group .acronym == acronym ]
196+
197+ if date :
198+ if len (date )== 15 :
199+ start = datetime .datetime .strptime (date ,"%Y-%m-%d-%H%M" )
200+ refined_candidates = [ sess for sess in refined_candidates if sess .scheduledsession_set .filter (schedule = sess .meeting .agenda ,timeslot__time = start ) ]
201+ else :
202+ start = datetime .datetime .strptime (date ,"%Y-%m-%d" ).date ()
203+ end = start + datetime .timedelta (days = 1 )
204+ refined_candidates = [ sess for sess in refined_candidates if sess .scheduledsession_set .filter (schedule = sess .meeting .agenda ,timeslot__time__range = (start ,end )) ]
205+
206+ if week_day :
207+ try :
208+ dow = ['sun' ,'mon' ,'tue' ,'wed' ,'thu' ,'fri' ,'sat' ].index (week_day .lower ()[:3 ]) + 1
209+ except ValueError :
210+ raise Http404
211+ refined_candidates = [ sess for sess in refined_candidates if sess .scheduledsession_set .filter (schedule = sess .meeting .agenda ,timeslot__time__week_day = dow ) ]
212+
213+ changeable_sessions = [ sess for sess in refined_candidates if can_manage_materials (user , sess .group ) ]
214+
215+ if not changeable_sessions :
216+ raise Http404
217+
218+ for sess in changeable_sessions :
219+ sess .has_presentation = bool (sess .sessionpresentation_set .filter (document = doc ))
220+ if sess .has_presentation :
221+ sess .version = sess .sessionpresentation_set .get (document = doc ).rev
222+
223+ # Since Python 2.2 sorts are stable, so this series results in a list sorted first by whether
224+ # the session has any presentations, then by the meeting 'number', then by session's group
225+ # acronym, then by scheduled time (or the time of the session request if the session isn't
226+ # scheduled).
227+
228+ def time_sort_key (session ):
229+ official_sessions = session .scheduledsession_set .filter (schedule = session .meeting .agenda )
230+ if official_sessions :
231+ return official_sessions .first ().timeslot .time
232+ else :
233+ return session .requested
234+
235+ time_sorted = sorted (changeable_sessions ,key = time_sort_key )
236+ acronym_sorted = sorted (time_sorted ,key = lambda x : x .group .acronym )
237+ meeting_sorted = sorted (acronym_sorted ,key = lambda x : x .meeting .number )
238+ sorted_sessions = sorted (meeting_sorted ,key = lambda x : '0' if x .has_presentation else '1' )
239+
240+ if seq :
241+ iseq = int (seq ) - 1
242+ if not iseq in range (0 ,len (sorted_sessions )):
243+ raise Http404
244+ else :
245+ sorted_sessions = [sorted_sessions [iseq ]]
246+
247+ return sorted_sessions
248+
249+ @login_required
250+ def edit_material_presentations (request , name , acronym = None , date = None , seq = None , week_day = None ):
251+
252+ doc = get_object_or_404 (Document , name = name )
253+ if not (doc .type_id == 'slides' and doc .get_state ('slides' ).slug == 'active' ):
254+ raise Http404
255+
256+ group = doc .group
257+ if not (group .features .has_materials and can_manage_materials (request .user ,group )):
258+ raise Http404
259+
260+ sorted_sessions = get_upcoming_manageable_sessions (request .user , doc , acronym , date , seq , week_day )
261+
262+ if len (sorted_sessions )!= 1 :
263+ raise Http404
264+
265+ session = sorted_sessions [0 ]
266+ choices = [('notpresented' ,'Not Presented' )]
267+ choices .extend ([(x ,x ) for x in doc .docevent_set .filter (type = 'new_revision' ).values_list ('newrevisiondocevent__rev' ,flat = True )])
268+ initial = {'version' : session .version if hasattr (session ,'version' ) else 'notpresented' }
269+
270+ if request .method == 'POST' :
271+ form = MaterialVersionForm (request .POST ,choices = choices )
272+ if form .is_valid ():
273+ if request .POST .get ("action" , "" ) == "Save" :
274+ new_selection = form .cleaned_data ['version' ]
275+ if initial ['version' ] != new_selection :
276+ if initial ['version' ] == 'notpresented' :
277+ doc .sessionpresentation_set .create (session = session ,rev = new_selection )
278+ c = DocEvent (type = "added_comment" , doc = doc , by = request .user .person )
279+ c .desc = "Added version %s to session: %s" % (new_selection ,session )
280+ c .save ()
281+ elif new_selection == 'notpresented' :
282+ doc .sessionpresentation_set .filter (session = session ).delete ()
283+ c = DocEvent (type = "added_comment" , doc = doc , by = request .user .person )
284+ c .desc = "Removed from session: %s" % (session )
285+ c .save ()
286+ else :
287+ doc .sessionpresentation_set .filter (session = session ).update (rev = new_selection )
288+ c = DocEvent (type = "added_comment" , doc = doc , by = request .user .person )
289+ c .desc = "Revision for session %s changed to %s" % (session ,new_selection )
290+ c .save ()
291+ return redirect ('doc_view' ,name = doc .name )
292+ else :
293+ form = MaterialVersionForm (choices = choices ,initial = initial )
294+
295+ return render (request , 'doc/material/edit_material_presentations.html' , {
296+ 'session' : session ,
297+ 'doc' : doc ,
298+ 'form' : form ,
299+ })
300+
301+ @login_required
302+ def material_presentations (request , name , acronym = None , date = None , seq = None , week_day = None ):
303+
304+ doc = get_object_or_404 (Document , name = name )
305+ if not (doc .type_id == 'slides' and doc .get_state ('slides' ).slug == 'active' ):
306+ raise Http404
307+
308+ group = doc .group
309+ if not (group .features .has_materials and can_manage_materials (request .user ,group )):
310+ raise Http404
311+
312+ sorted_sessions = get_upcoming_manageable_sessions (request .user , doc , acronym , date , seq , week_day )
313+
314+ #for index,session in enumerate(sorted_sessions):
315+ # session.sequence = index+1
316+
317+ return render (request , 'doc/material/material_presentations.html' , {
318+ 'sessions' : sorted_sessions ,
319+ 'doc' : doc ,
320+ 'date' : date ,
321+ 'week_day' : week_day ,
322+ })
0 commit comments