1616import debug # pyflakes:ignore
1717
1818from ietf .doc .models import Document
19+ from ietf .doc .utils import get_document_content
1920from ietf .group .models import Group
2021from ietf .ietfauth .utils import has_role , user_is_person
2122from ietf .liaisons .utils import get_person_for_user
@@ -290,67 +291,31 @@ def session_constraint_expire(request,session):
290291# -------------------------------------------------
291292# Interim Meeting Helpers
292293# -------------------------------------------------
293- def get_announcement_initial (meeting ):
294- '''Returns a dictionary suitable to initialize an InterimAnnouncementForm (Message ModelForm)'''
295- group = meeting .session_set .first ().group
296- in_person = bool (meeting .city )
297- initial = {}
298- initial ['to' ] = settings .INTERIM_ANNOUNCE_TO_EMAIL
299- initial ['cc' ] = group .list_email
300- initial ['frm' ] = settings .INTERIM_ANNOUNCE_FROM_EMAIL
301- if in_person :
302- desc = 'Interim'
303- else :
304- desc = 'Virtual'
305- initial ['subject' ] = '%s (%s) WG %s Meeting: %s' % (group .name ,group .acronym ,desc ,meeting .date )
306- body = render_to_string ('meeting/interim_announcement.txt' , locals ())
307- initial ['body' ] = body
308- return initial
309294
310- def get_earliest_session (session_formset ):
311- '''Return earliest InterimSessionForm from formset'''
312- earliest = session_formset [0 ]
313- if len (session_formset ) == 1 :
314- return earliest
315- for form in session_formset [1 :]:
316- date = form .cleaned_data .get ('date' )
317- if date and date < earliest .cleaned_data .get ('date' ):
318- earliest = form
319- return earliest
320-
321- def get_next_interim_number (group ,date ):
322- sequence = Meeting .objects .filter (number__startswith = 'interim-%s-%s' % (date .year ,group .acronym )).count () + 1
323- return 'interim-%s-%s-%s' % (date .year ,group .acronym ,sequence )
324-
325- def create_interim_meeting (group ,date ,city = '' ,country = '' ,timezone = 'UTC' ,person = None ):
326- '''Helper function to create interim meeting and associated schedule'''
327- if not person :
328- person = Person .objects .get (name = "(System)" )
329- number = get_next_interim_number (group ,date )
330- meeting = Meeting .objects .create (number = number ,type_id = 'interim' ,date = date ,city = city ,
331- country = country ,time_zone = timezone )
332- schedule = Schedule .objects .create (meeting = meeting , owner = person , visible = True , public = True )
333- meeting .agenda = schedule
334- meeting .save ()
335- return meeting
336295
337- def create_interim_meeting_from_forms (request_form ,session_form ):
338- '''Create an Interim meeting, given an InterimRequestForm and InterimSessionForm'''
339- group = request_form .cleaned_data .get ('group' )
340- date = session_form .cleaned_data .get ('date' )
341- city = session_form .cleaned_data .get ('city' )
342- country = session_form .cleaned_data .get ('country' )
343- timezone = session_form .cleaned_data .get ('timezone' )
344- person = request_form .person
345- return create_interim_meeting (group = group ,date = date ,city = city ,country = country ,timezone = timezone ,person = person )
346-
347- def assign_interim_session (session ,time ):
348- '''Helper function to create a timeslot and assign the interim session'''
349- slot = TimeSlot .objects .create (meeting = session .meeting , type_id = "session" ,
350- duration = session .requested_duration , time = time )
351- SchedTimeSessAssignment .objects .create (timeslot = slot , session = session , schedule = session .meeting .agenda )
352-
353- def can_approve_interim_request (meeting ,user ):
296+ def assign_interim_session (form ):
297+ """Helper function to create a timeslot and assign the interim session"""
298+ time = datetime .datetime .combine (
299+ form .cleaned_data ['date' ],
300+ form .cleaned_data ['time' ])
301+ session = form .instance
302+ if session .official_timeslotassignment ():
303+ slot = session .official_timeslotassignment ().timeslot
304+ slot .time = time
305+ slot .save ()
306+ else :
307+ slot = TimeSlot .objects .create (
308+ meeting = session .meeting ,
309+ type_id = "session" ,
310+ duration = session .requested_duration ,
311+ time = time )
312+ SchedTimeSessAssignment .objects .create (
313+ timeslot = slot ,
314+ session = session ,
315+ schedule = session .meeting .agenda )
316+
317+
318+ def can_approve_interim_request (meeting , user ):
354319 '''Returns True if the user has permissions to approve an interim meeting request'''
355320 if meeting .type .slug != 'interim' :
356321 return False
@@ -361,26 +326,29 @@ def can_approve_interim_request(meeting,user):
361326 if not session :
362327 return False
363328 group = session .group
364- if group .type .slug == 'wg' and group .parent .role_set .filter (name = 'ad' ,person = person ):
329+ if group .type .slug == 'wg' and group .parent .role_set .filter (name = 'ad' , person = person ):
365330 return True
366- if group .type .slug == 'rg' and group .parent .role_set .filter (name = 'chair' ,person = person ):
331+ if group .type .slug == 'rg' and group .parent .role_set .filter (name = 'chair' , person = person ):
367332 return True
368333 return False
369334
370- def can_edit_interim_request (meeting ,user ):
335+
336+ def can_edit_interim_request (meeting , user ):
371337 '''Returns True if the user can edit the interim meeting request'''
372-
373- if can_approve_interim_request (meeting ,user ):
338+
339+ if can_approve_interim_request (meeting , user ):
374340 return True
375-
341+
376342 return False
377343
344+
378345def can_request_interim_meeting (user ):
379- if has_role (user , ('Secretariat' ,'Area Director' ,'WG Chair' ,'IRTF Chair' , 'RG Chair' )):
346+ if has_role (user , ('Secretariat' , 'Area Director' , 'WG Chair' , 'IRTF Chair' , 'RG Chair' )):
380347 return True
381348 return False
382349
383- def can_view_interim_request (meeting ,user ):
350+
351+ def can_view_interim_request (meeting , user ):
384352 '''Returns True if the user can see the pending interim request in the pending interim view'''
385353 if meeting .type .slug != 'interim' :
386354 return False
@@ -395,6 +363,129 @@ def can_view_interim_request(meeting,user):
395363 return True
396364 if has_role (user , 'IRTF Chair' ) and group .type .slug == 'rg' :
397365 return True
398- if group .role_set .filter (name = 'chair' ,person = person ):
366+ if group .role_set .filter (name = 'chair' , person = person ):
399367 return True
400368 return False
369+
370+
371+ def create_interim_meeting (group , date , city = '' , country = '' , timezone = 'UTC' ,
372+ person = None ):
373+ """Helper function to create interim meeting and associated schedule"""
374+ if not person :
375+ person = Person .objects .get (name = '(System)' )
376+ number = get_next_interim_number (group , date )
377+ meeting = Meeting .objects .create (
378+ number = number ,
379+ type_id = 'interim' ,
380+ date = date ,
381+ city = city ,
382+ country = country ,
383+ time_zone = timezone )
384+ schedule = Schedule .objects .create (
385+ meeting = meeting ,
386+ owner = person ,
387+ visible = True ,
388+ public = True )
389+ meeting .agenda = schedule
390+ meeting .save ()
391+ return meeting
392+
393+
394+ def get_announcement_initial (meeting ):
395+ '''Returns a dictionary suitable to initialize an InterimAnnouncementForm (Message ModelForm)'''
396+ group = meeting .session_set .first ().group
397+ in_person = bool (meeting .city )
398+ initial = {}
399+ initial ['to' ] = settings .INTERIM_ANNOUNCE_TO_EMAIL
400+ initial ['cc' ] = group .list_email
401+ initial ['frm' ] = settings .INTERIM_ANNOUNCE_FROM_EMAIL
402+ if in_person :
403+ desc = 'Interim'
404+ else :
405+ desc = 'Virtual'
406+ initial ['subject' ] = '%s (%s) WG %s Meeting: %s' % (group .name , group .acronym , desc , meeting .date )
407+ body = render_to_string ('meeting/interim_announcement.txt' , locals ())
408+ initial ['body' ] = body
409+ return initial
410+
411+
412+ def get_earliest_session_date (formset ):
413+ '''Return earliest date from InterimSession Formset'''
414+ return sorted ([f .cleaned_data ['date' ] for f in formset .forms if f .cleaned_data .get ('date' )])[0 ]
415+
416+
417+ def get_interim_initial (meeting ):
418+ '''Returns a dictionary suitable to initialize a InterimRequestForm'''
419+ initial = {}
420+ initial ['group' ] = meeting .session_set .first ().group
421+ if meeting .city :
422+ initial ['in_person' ] = True
423+ else :
424+ initial ['in_person' ] = False
425+ if meeting .session_set .count () > 1 :
426+ initial ['meeting_type' ] = 'multi-day'
427+ else :
428+ initial ['meeting_type' ] = 'single'
429+ if meeting .session_set .first ().status .slug == 'apprw' :
430+ initial ['approved' ] = False
431+ else :
432+ initial ['approved' ] = True
433+ return initial
434+
435+
436+ def get_interim_session_initial (meeting ):
437+ '''Returns a list of dictionaries suitable to initialize a InterimSessionForm'''
438+ initials = []
439+ for session in meeting .session_set .all ():
440+ initial = {}
441+ initial ['date' ] = session .official_timeslotassignment ().timeslot .time
442+ initial ['time' ] = session .official_timeslotassignment ().timeslot .time
443+ initial ['duration' ] = session .requested_duration
444+ initial ['remote_instructions' ] = session .remote_instructions
445+ initial ['agenda_note' ] = session .agenda_note
446+ doc = session .agenda ()
447+ if doc :
448+ path = os .path .join (doc .get_file_path (), doc .filename_with_rev ())
449+ initial ['agenda' ] = get_document_content (os .path .basename (path ), path , markup = False )
450+ initials .append (initial )
451+
452+ return initials
453+
454+
455+ def is_meeting_approved (meeting ):
456+ """Returns True if the meeting is approved"""
457+ if meeting .session_set .first ().status .slug == 'apprw' :
458+ return False
459+ else :
460+ return True
461+
462+
463+ def get_next_interim_number (group , date ):
464+ """Returns a unique number to use for the next interim meeting for
465+ *group*"""
466+ meetings = Meeting .objects .filter (
467+ number__startswith = 'interim-{year}-{group}' .format (
468+ year = date .year ,
469+ group = group .acronym ))
470+ if meetings :
471+ sequences = [int (m .number .split ('-' )[- 1 ]) for m in meetings ]
472+ last_sequence = sorted (sequences )[- 1 ]
473+ else :
474+ last_sequence = 0
475+ return 'interim-{year}-{group}-{sequence}' .format (
476+ year = date .year ,
477+ group = group .acronym ,
478+ sequence = last_sequence + 1 )
479+
480+
481+ def sessions_post_save (forms ):
482+ """Helper function to perform various post save operations on each form of a
483+ InterimSessionModelForm formset"""
484+
485+ for form in forms :
486+ if not form .has_changed ():
487+ continue
488+ if ('date' in form .changed_data ) or ('time' in form .changed_data ):
489+ assign_interim_session (form )
490+ if 'agenda' in form .changed_data :
491+ form .save_agenda ()
0 commit comments