fix bug where concluded BOFs showing in proceedings
- Legacy-Id: 6143
This commit is contained in:
parent
0d1c0b2db9
commit
ed745b457d
|
@ -37,7 +37,7 @@ def mycomp(timeslot):
|
|||
except AttributeError:
|
||||
key = None
|
||||
return key
|
||||
|
||||
|
||||
def get_progress_stats(sdate,edate):
|
||||
'''
|
||||
This function takes a date range and produces a dictionary of statistics / objects for use
|
||||
|
@ -46,7 +46,7 @@ def get_progress_stats(sdate,edate):
|
|||
data = {}
|
||||
data['sdate'] = sdate
|
||||
data['edate'] = edate
|
||||
|
||||
|
||||
# Activty Report Section
|
||||
new_docs = Document.objects.filter(type='draft').filter(docevent__type='new_revision',
|
||||
docevent__newrevisiondocevent__rev='00',
|
||||
|
@ -61,20 +61,20 @@ def get_progress_stats(sdate,edate):
|
|||
data['updated'] += 1
|
||||
if updates > 2:
|
||||
data['updated_more'] +=1
|
||||
|
||||
|
||||
# calculate total documents updated, not counting new, rev=00
|
||||
result = set()
|
||||
events = DocEvent.objects.filter(doc__type='draft',time__gte=sdate,time__lte=edate)
|
||||
for e in events.filter(type='new_revision').exclude(newrevisiondocevent__rev='00'):
|
||||
result.add(e.doc)
|
||||
data['total_updated'] = len(result)
|
||||
|
||||
|
||||
# calculate sent last call
|
||||
data['last_call'] = events.filter(type='sent_last_call').count()
|
||||
|
||||
|
||||
# calculate approved
|
||||
data['approved'] = events.filter(type='iesg_approved').count()
|
||||
|
||||
|
||||
# get 4 weeks
|
||||
monday = Meeting.get_ietf_monday()
|
||||
cutoff = monday + datetime.timedelta(days=3)
|
||||
|
@ -82,14 +82,14 @@ def get_progress_stats(sdate,edate):
|
|||
ff2_date = cutoff - datetime.timedelta(days=21)
|
||||
ff3_date = cutoff - datetime.timedelta(days=14)
|
||||
ff4_date = cutoff - datetime.timedelta(days=7)
|
||||
|
||||
|
||||
ff_docs = Document.objects.filter(type='draft').filter(docevent__type='new_revision',
|
||||
docevent__newrevisiondocevent__rev='00',
|
||||
docevent__time__gte=ff1_date,
|
||||
docevent__time__lte=cutoff)
|
||||
ff_new_count = ff_docs.count()
|
||||
ff_new_percent = format(ff_new_count / float(data['new']),'.0%')
|
||||
|
||||
|
||||
# calculate total documents updated in final four weeks, not counting new, rev=00
|
||||
result = set()
|
||||
events = DocEvent.objects.filter(doc__type='draft',time__gte=ff1_date,time__lte=cutoff)
|
||||
|
@ -97,48 +97,48 @@ def get_progress_stats(sdate,edate):
|
|||
result.add(e.doc)
|
||||
ff_update_count = len(result)
|
||||
ff_update_percent = format(ff_update_count / float(data['total_updated']),'.0%')
|
||||
|
||||
|
||||
data['ff_new_count'] = ff_new_count
|
||||
data['ff_new_percent'] = ff_new_percent
|
||||
data['ff_update_count'] = ff_update_count
|
||||
data['ff_update_percent'] = ff_update_percent
|
||||
|
||||
|
||||
# Progress Report Section
|
||||
data['docevents'] = DocEvent.objects.filter(doc__type='draft',time__gte=sdate,time__lte=edate)
|
||||
data['action_events'] = data['docevents'].filter(type='iesg_approved')
|
||||
data['lc_events'] = data['docevents'].filter(type='sent_last_call')
|
||||
|
||||
|
||||
data['new_groups'] = Group.objects.filter(type='wg',
|
||||
groupevent__changestategroupevent__state='active',
|
||||
groupevent__time__gte=sdate,
|
||||
groupevent__time__lte=edate)
|
||||
|
||||
|
||||
data['concluded_groups'] = Group.objects.filter(type='wg',
|
||||
groupevent__changestategroupevent__state='conclude',
|
||||
groupevent__time__gte=sdate,
|
||||
groupevent__time__lte=edate)
|
||||
|
||||
|
||||
data['new_docs'] = Document.objects.filter(type='draft').filter(docevent__type='new_revision',
|
||||
docevent__time__gte=sdate,
|
||||
docevent__time__lte=edate).distinct()
|
||||
|
||||
|
||||
data['rfcs'] = DocEvent.objects.filter(type='published_rfc',
|
||||
doc__type='draft',
|
||||
time__gte=sdate,
|
||||
time__lte=edate)
|
||||
|
||||
|
||||
# attach the ftp URL for use in the template
|
||||
for event in data['rfcs']:
|
||||
num = get_rfc_num(event.doc)
|
||||
event.ftp_url = 'ftp://ftp.ietf.org/rfc/rfc%s.txt' % num
|
||||
|
||||
|
||||
data['counts'] = {'std':data['rfcs'].filter(doc__intended_std_level__in=('ps','ds','std')).count(),
|
||||
'bcp':data['rfcs'].filter(doc__intended_std_level='bcp').count(),
|
||||
'exp':data['rfcs'].filter(doc__intended_std_level='exp').count(),
|
||||
'inf':data['rfcs'].filter(doc__intended_std_level='inf').count()}
|
||||
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def write_html(path,content):
|
||||
f = open(path,'w')
|
||||
f.write(content)
|
||||
|
@ -156,7 +156,7 @@ def create_interim_directory():
|
|||
Create static Interim Meeting directory pages that will live in a different URL space than
|
||||
the secretariat Django project
|
||||
'''
|
||||
|
||||
|
||||
# produce date sorted output
|
||||
page = 'proceedings.html'
|
||||
meetings = InterimMeeting.objects.order_by('-date')
|
||||
|
@ -165,7 +165,7 @@ def create_interim_directory():
|
|||
f = open(path,'w')
|
||||
f.write(response.content)
|
||||
f.close()
|
||||
|
||||
|
||||
# produce group sorted output
|
||||
page = 'proceedings-bygroup.html'
|
||||
qs = InterimMeeting.objects.all()
|
||||
|
@ -175,7 +175,7 @@ def create_interim_directory():
|
|||
f = open(path,'w')
|
||||
f.write(response.content)
|
||||
f.close()
|
||||
|
||||
|
||||
def create_proceedings(meeting, group, is_final=False):
|
||||
'''
|
||||
This function creates the proceedings html document. It gets called anytime there is an
|
||||
|
@ -185,7 +185,7 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
# abort, proceedings from meetings before 79 have a different format, don't overwrite
|
||||
if meeting.type_id == 'ietf' and int(meeting.number) < 79:
|
||||
return
|
||||
|
||||
|
||||
sessions = Session.objects.filter(meeting=meeting,group=group)
|
||||
if sessions:
|
||||
session = sessions[0]
|
||||
|
@ -194,7 +194,7 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
agenda = None
|
||||
minutes = None
|
||||
slides = None
|
||||
|
||||
|
||||
chairs = group.role_set.filter(name='chair')
|
||||
secretaries = group.role_set.filter(name='secr')
|
||||
if group.parent: # Certain groups like Tools Team do no have a parent
|
||||
|
@ -202,7 +202,7 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
else:
|
||||
ads = None
|
||||
tas = group.role_set.filter(name='techadv')
|
||||
|
||||
|
||||
docs = Document.objects.filter(group=group,type='draft').order_by('time')
|
||||
|
||||
meeting_root = get_upload_root(meeting)
|
||||
|
@ -213,15 +213,15 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
settings.MEDIA_URL,
|
||||
meeting.date.strftime('%Y/%m/%d'),
|
||||
group.acronym)
|
||||
|
||||
|
||||
# Only do these tasks if we are running official proceedings generation,
|
||||
# otherwise skip them for expediency. This procedure is called any time meeting
|
||||
# otherwise skip them for expediency. This procedure is called any time meeting
|
||||
# materials are uploaded/deleted, and we don't want to do all this work each time.
|
||||
|
||||
|
||||
if is_final:
|
||||
# ----------------------------------------------------------------------
|
||||
# Find active Drafts and RFCs, copy them to id and rfc directories
|
||||
|
||||
|
||||
drafts = docs.filter(states__slug='active')
|
||||
for draft in drafts:
|
||||
source = os.path.join(draft.get_file_path(),draft.filename_with_rev())
|
||||
|
@ -234,7 +234,7 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
else:
|
||||
draft.bytes = 0
|
||||
draft.url = url_root + "id/%s" % draft.filename_with_rev()
|
||||
|
||||
|
||||
rfcs = docs.filter(states__slug='rfc')
|
||||
for rfc in rfcs:
|
||||
# TODO should use get_file_path() here but is incorrect for rfcs
|
||||
|
@ -245,7 +245,7 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
target = os.path.join(meeting_root,'rfc')
|
||||
rfc.rmsg = ''
|
||||
rfc.msg = ''
|
||||
|
||||
|
||||
if not os.path.exists(target):
|
||||
os.makedirs(target)
|
||||
shutil.copy(source,target)
|
||||
|
@ -282,7 +282,7 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
# ----------------------------------------------------------------------
|
||||
else:
|
||||
drafts = rfcs = bluesheets = None
|
||||
|
||||
|
||||
# the simplest way to display the charter is to place it in a <pre> block
|
||||
# however, because this forces a fixed-width font, different than the rest of
|
||||
# the document we modify the charter by adding replacing linefeeds with <br>'s
|
||||
|
@ -292,8 +292,8 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
else:
|
||||
charter = None
|
||||
ctime = None
|
||||
|
||||
|
||||
|
||||
|
||||
# rather than return the response as in a typical view function we save it as the snapshot
|
||||
# proceedings.html
|
||||
response = render_to_response('proceedings/proceedings.html',{
|
||||
|
@ -312,10 +312,10 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
'minutes': minutes,
|
||||
'agenda': agenda}
|
||||
)
|
||||
|
||||
|
||||
# save proceedings
|
||||
proceedings_path = get_proceedings_path(meeting,group)
|
||||
|
||||
|
||||
f = open(proceedings_path,'w')
|
||||
f.write(response.content)
|
||||
f.close()
|
||||
|
@ -323,7 +323,7 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
os.chmod(proceedings_path, 0664)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
# rebuild the directory
|
||||
if meeting.type.slug == 'interim':
|
||||
create_interim_directory()
|
||||
|
@ -335,20 +335,21 @@ def create_proceedings(meeting, group, is_final=False):
|
|||
def gen_areas(context):
|
||||
meeting = context['meeting']
|
||||
gmet, gnot = groups_by_session(None,meeting)
|
||||
|
||||
|
||||
# append proceedings URL
|
||||
for group in gmet + gnot:
|
||||
group.proceedings_url = "%s/proceedings/%s/%s.html" % (settings.MEDIA_URL,meeting.number,group.acronym)
|
||||
|
||||
for (counter,area) in enumerate(context['areas'], start=1):
|
||||
groups_met = {'wg':filter(lambda a: a.parent==area and a.state.slug!='bof' and a.type_id=='wg',gmet),
|
||||
'bof':filter(lambda a: a.parent==area and a.state.slug=='bof' and a.type_id=='wg',gmet),
|
||||
|
||||
for (counter,area) in enumerate(context['areas'], start=1):
|
||||
groups_met = {'wg':filter(lambda a: a.parent==area and a.state.slug not in ('bof','bof-conc') and a.type_id=='wg',gmet),
|
||||
'bof':filter(lambda a: a.parent==area and a.state.slug in ('bof','bof-conc') and a.type_id=='wg',gmet),
|
||||
'ag':filter(lambda a: a.parent==area and a.type_id=='ag',gmet)}
|
||||
|
||||
groups_not = {'wg':filter(lambda a: a.parent==area and a.state.slug!='bof' and a.type_id=='wg',gnot),
|
||||
|
||||
groups_not = {'wg':filter(lambda a: a.parent==area and a.state.slug not in ('bof','bof-conc') and a.type_id=='wg',gnot),
|
||||
'bof':filter(lambda a: a.parent==area and a.state.slug=='bof' and a.type_id=='wg',gnot),
|
||||
'ag':filter(lambda a: a.parent==area and a.type_id=='ag',gnot)}
|
||||
|
||||
|
||||
|
||||
html = render_to_response('proceedings/area.html',{
|
||||
'area': area,
|
||||
'meeting': meeting,
|
||||
|
@ -356,63 +357,63 @@ def gen_areas(context):
|
|||
'groups_not': groups_not,
|
||||
'index': counter}
|
||||
)
|
||||
|
||||
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'%s.html' % area.acronym)
|
||||
write_html(path,html.content)
|
||||
|
||||
def gen_acknowledgement(context):
|
||||
meeting = context['meeting']
|
||||
|
||||
|
||||
html = render_to_response('proceedings/acknowledgement.html',{
|
||||
'meeting': meeting}
|
||||
)
|
||||
|
||||
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'acknowledgement.html')
|
||||
write_html(path,html.content)
|
||||
|
||||
|
||||
def gen_agenda(context):
|
||||
meeting = context['meeting']
|
||||
|
||||
|
||||
#timeslots, update, meeting, venue, ads, plenaryw_agenda, plenaryt_agenda = agenda_info(meeting.number)
|
||||
timeslots = TimeSlot.objects.filter(meeting=meeting)
|
||||
|
||||
|
||||
# sort by area:group then time
|
||||
sort1 = sorted(timeslots, key = mycomp)
|
||||
sort2 = sorted(sort1, key = lambda a: a.time)
|
||||
|
||||
|
||||
html = render_to_response('proceedings/agenda.html',{
|
||||
'meeting': meeting,
|
||||
'timeslots': sort2}
|
||||
)
|
||||
|
||||
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'agenda.html')
|
||||
write_html(path,html.content)
|
||||
|
||||
|
||||
# get the text agenda from datatracker
|
||||
url = 'https://datatracker.ietf.org/meeting/%s/agenda.txt' % meeting.number
|
||||
text = urlopen(url).read()
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'agenda.txt')
|
||||
write_html(path,text)
|
||||
|
||||
|
||||
def gen_attendees(context):
|
||||
meeting = context['meeting']
|
||||
|
||||
|
||||
attendees = Registration.objects.using('ietf' + meeting.number).all().order_by('lname')
|
||||
|
||||
|
||||
html = render_to_response('proceedings/attendee.html',{
|
||||
'meeting': meeting,
|
||||
'attendees': attendees}
|
||||
)
|
||||
|
||||
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'attendee.html')
|
||||
write_html(path,html.content)
|
||||
|
||||
|
||||
def gen_group_pages(context):
|
||||
meeting = context['meeting']
|
||||
|
||||
|
||||
for group in Group.objects.filter(type__in=('wg','ag','rg'), state__in=('bof','proposed','active')):
|
||||
create_proceedings(meeting,group,is_final=True)
|
||||
|
||||
|
||||
def gen_index(context):
|
||||
index = render_to_response('proceedings/index.html',context)
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,context['meeting'].number,'index.html')
|
||||
|
@ -421,36 +422,36 @@ def gen_index(context):
|
|||
def gen_irtf(context):
|
||||
meeting = context['meeting']
|
||||
irtf_chair = Role.objects.filter(group__acronym='irtf',name='chair')[0]
|
||||
|
||||
|
||||
html = render_to_response('proceedings/irtf.html',{
|
||||
'irtf_chair':irtf_chair}
|
||||
)
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'irtf.html')
|
||||
write_html(path,html.content)
|
||||
|
||||
|
||||
def gen_overview(context):
|
||||
meeting = context['meeting']
|
||||
|
||||
|
||||
ietf_chair = Role.objects.get(group__acronym='ietf',name='chair')
|
||||
ads = Role.objects.filter(group__type='area',group__state='active',name='ad')
|
||||
sorted_ads = sorted(ads, key = lambda a: a.person.name_parts()[3])
|
||||
|
||||
|
||||
html = render_to_response('proceedings/overview.html',{
|
||||
'meeting': meeting,
|
||||
'ietf_chair': ietf_chair,
|
||||
'ads': sorted_ads}
|
||||
)
|
||||
|
||||
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'overview.html')
|
||||
write_html(path,html.content)
|
||||
|
||||
|
||||
def gen_plenaries(context):
|
||||
'''
|
||||
This function generates pages for the Plenaries. At meeting 85 the Plenary sessions
|
||||
This function generates pages for the Plenaries. At meeting 85 the Plenary sessions
|
||||
were combined into one, so we need to handle not finding one of the sessions.
|
||||
'''
|
||||
meeting = context['meeting']
|
||||
|
||||
|
||||
# Administration Plenary
|
||||
try:
|
||||
admin_session = Session.objects.get(meeting=meeting,name__contains='Administration Plenary')
|
||||
|
@ -466,7 +467,7 @@ def gen_plenaries(context):
|
|||
write_html(path,admin.content)
|
||||
except Session.DoesNotExist:
|
||||
pass
|
||||
|
||||
|
||||
# Technical Plenary
|
||||
try:
|
||||
tech_session = Session.objects.get(meeting=meeting,name__contains='Technical Plenary')
|
||||
|
@ -482,16 +483,16 @@ def gen_plenaries(context):
|
|||
write_html(path,tech.content)
|
||||
except Session.DoesNotExist:
|
||||
pass
|
||||
|
||||
|
||||
def gen_progress(context, final=True):
|
||||
'''
|
||||
This function generates the Progress Report. This report is actually produced twice. First
|
||||
for inclusion in the Admin Plenary, then for the final proceedings. When produced the first
|
||||
time we want to exclude the headers because they are broken links until all the proceedings
|
||||
time we want to exclude the headers because they are broken links until all the proceedings
|
||||
are generated.
|
||||
'''
|
||||
meeting = context['meeting']
|
||||
|
||||
|
||||
# proceedings are run sometime after the meeting, so end date = the previous meeting
|
||||
# date and start date = the date of the meeting before that
|
||||
now = datetime.date.today()
|
||||
|
@ -501,30 +502,30 @@ def gen_progress(context, final=True):
|
|||
data = get_progress_stats(start_date,end_date)
|
||||
data['meeting'] = meeting
|
||||
data['final'] = final
|
||||
|
||||
|
||||
html = render_to_response('proceedings/progress.html',data)
|
||||
|
||||
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'progress-report.html')
|
||||
write_html(path,html.content)
|
||||
|
||||
|
||||
def gen_research(context):
|
||||
meeting = context['meeting']
|
||||
gmet, gnot = groups_by_session(None,meeting)
|
||||
|
||||
|
||||
groups = filter(lambda a: a.type_id=='rg', gmet)
|
||||
|
||||
|
||||
# append proceedings URL
|
||||
for group in groups:
|
||||
group.proceedings_url = "%s/proceedings/%s/%s.html" % (settings.MEDIA_URL,meeting.number,group.acronym)
|
||||
|
||||
|
||||
html = render_to_response('proceedings/rg_irtf.html',{
|
||||
'meeting': meeting,
|
||||
'groups': groups}
|
||||
)
|
||||
|
||||
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'rg_irtf.html')
|
||||
write_html(path,html.content)
|
||||
|
||||
|
||||
def gen_training(context):
|
||||
meeting = context['meeting']
|
||||
timeslots = context['others']
|
||||
|
@ -540,4 +541,4 @@ def gen_training(context):
|
|||
)
|
||||
path = os.path.join(settings.SECR_PROCEEDINGS_DIR,meeting.number,'train-%s.html' % counter )
|
||||
write_html(path,html.content)
|
||||
|
||||
|
||||
|
|
|
@ -20,9 +20,9 @@ def get_charter_text(group):
|
|||
f = file(path,'r')
|
||||
text = f.read()
|
||||
f.close()
|
||||
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def get_my_groups(user,conclude=False):
|
||||
'''
|
||||
Takes a Django user object (from request)
|
||||
|
@ -31,24 +31,24 @@ def get_my_groups(user,conclude=False):
|
|||
area director - has access to all groups in their area
|
||||
wg chair or secretary - has acceses to their own group
|
||||
chair of irtf has access to all irtf groups
|
||||
|
||||
|
||||
If user=None than all groups are returned.
|
||||
concluded=True means include concluded groups. Need this to upload materials for groups
|
||||
after they've been concluded. it happens.
|
||||
'''
|
||||
my_groups = set()
|
||||
states = ['bof','proposed','active']
|
||||
if conclude:
|
||||
states.append('conclude')
|
||||
if conclude:
|
||||
states.extend(['conclude','bof-conc'])
|
||||
all_groups = Group.objects.filter(type__in=('wg','rg','ag','team'),state__in=states).order_by('acronym')
|
||||
if user == None:
|
||||
return all_groups
|
||||
else:
|
||||
person = user.get_profile()
|
||||
|
||||
|
||||
if has_role(user,'Secretariat'):
|
||||
return all_groups
|
||||
|
||||
|
||||
for group in all_groups:
|
||||
if group.role_set.filter(person=person,name__in=('chair','secr')):
|
||||
my_groups.add(group)
|
||||
|
@ -56,16 +56,16 @@ def get_my_groups(user,conclude=False):
|
|||
if group.parent and group.parent.role_set.filter(person=person,name__in=('ad','chair')):
|
||||
my_groups.add(group)
|
||||
continue
|
||||
|
||||
|
||||
return list(my_groups)
|
||||
|
||||
|
||||
def groups_by_session(user, meeting):
|
||||
'''
|
||||
Takes a Django User object and a Meeting object
|
||||
Returns a tuple scheduled_groups, unscheduled groups. sorted lists of those groups that
|
||||
Returns a tuple scheduled_groups, unscheduled groups. sorted lists of those groups that
|
||||
the user has access to, secretariat defaults to all groups
|
||||
If user=None than all groups are returned.
|
||||
|
||||
|
||||
For groups with a session, we must include "concluded" groups because we still want to know
|
||||
who had a session at a particular meeting even if they are concluded after. This is not true
|
||||
for groups without a session because this function is often used to build select lists (ie.
|
||||
|
@ -80,8 +80,7 @@ def groups_by_session(user, meeting):
|
|||
if group in groups_with_sessions:
|
||||
groups_session.append(group)
|
||||
else:
|
||||
if group.state_id != 'conclude':
|
||||
if group.state_id not in ('conclude','bof-conc'):
|
||||
groups_no_session.append(group)
|
||||
|
||||
|
||||
return groups_session, groups_no_session
|
||||
|
Loading…
Reference in a new issue