fix bug where concluded BOFs showing in proceedings

- Legacy-Id: 6143
This commit is contained in:
Ryan Cross 2013-09-11 17:35:10 +00:00
parent 0d1c0b2db9
commit ed745b457d
2 changed files with 95 additions and 95 deletions

View file

@ -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)

View file

@ -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