Skip to content

Commit 1a92efb

Browse files
committed
Merged in ^/branch/proceedings/6.33.1.dev0@12141 from rcross@amsl.com:
Added meeting proceedings introduction pages: Progress Report and Attendees. Added a data migration to provide proceedings introduction information for IETF 95 and 96. - Legacy-Id: 12150
2 parents dbfea90 + 68e11fc commit 1a92efb

16 files changed

Lines changed: 301 additions & 135 deletions

hold-for-merge

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- conf-mode -*-
22

3-
/branch/proceedings/6.33.1.dev0@12111 # Missing data migration to add dbtemplates ?
3+
44
/branch/proceedings/6.29.1.dev0@11850 # Merged into /branch/proceedings/6.30.1.dev0, will be merged from there
55
/branch/proceedings/6.29.1.dev0@11856 # Merged into /branch/proceedings/6.30.1.dev0, will be merged from there
66
/personal/rcross/6.29.1.dev0@11765 # Merged into ^/personal/rjs/6.29.1.dev0@11770, will be merged from there
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations
5+
6+
from ietf.meeting.utils import create_proceedings_templates
7+
8+
def create_attendee_templates(apps, schema_editor):
9+
"""Create attendee templates for supported meetings"""
10+
Meeting = apps.get_model("meeting", "Meeting")
11+
create_proceedings_templates(Meeting.objects.get(number=95))
12+
create_proceedings_templates(Meeting.objects.get(number=96))
13+
14+
class Migration(migrations.Migration):
15+
16+
dependencies = [
17+
('meeting', '0037_change_meta_options_on_sessionpresentation'),
18+
]
19+
20+
operations = [
21+
migrations.RunPython(create_attendee_templates),
22+
]

ietf/meeting/tests_views.py

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from django.conf import settings
1212
from django.contrib.auth.models import User
1313

14+
from mock import patch
1415
from pyquery import PyQuery
1516
from StringIO import StringIO
1617

@@ -22,6 +23,7 @@
2223
from ietf.meeting.helpers import send_interim_minutes_reminder
2324
from ietf.meeting.models import Session, TimeSlot, Meeting
2425
from ietf.meeting.test_data import make_meeting_test_data, make_interim_meeting
26+
from ietf.meeting.utils import finalize
2527
from ietf.name.models import SessionStatusName
2628
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
2729
from ietf.utils.mail import outbox
@@ -33,6 +35,7 @@
3335
MeetingFactory, FloorPlanFactory )
3436
from ietf.doc.factories import DocumentFactory
3537

38+
3639
class MeetingTests(TestCase):
3740
def setUp(self):
3841
self.materials_dir = os.path.abspath(settings.TEST_MATERIALS_DIR)
@@ -272,41 +275,50 @@ def test_proceedings(self):
272275
self.assertEqual(r.status_code, 200)
273276

274277
def test_proceedings_acknowledgements(self):
275-
meeting = make_meeting_test_data()
278+
make_meeting_test_data()
279+
meeting = MeetingFactory(type_id='ietf', date=datetime.date(2016,7,14), number="96")
280+
meeting.acknowledgements = 'test acknowledgements'
281+
meeting.save()
276282
url = urlreverse('ietf.meeting.views.proceedings_acknowledgements',kwargs={'num':meeting.number})
277-
login_testing_unauthorized(self,"secretary",url)
278-
r = self.client.get(url)
279-
self.assertEqual(r.status_code, 200)
283+
response = self.client.get(url)
284+
self.assertEqual(response.status_code, 200)
285+
self.assertTrue('test acknowledgements' in response.content)
286+
287+
@patch('urllib2.urlopen')
288+
def test_proceedings_attendees(self, mock_urlopen):
289+
mock_urlopen.return_value = StringIO('[{"LastName":"Smith","FirstName":"John","Company":"ABC","Country":"US"}]')
290+
make_meeting_test_data()
291+
meeting = MeetingFactory(type_id='ietf', date=datetime.date(2016,7,14), number="96")
292+
finalize(meeting)
293+
url = urlreverse('ietf.meeting.views.proceedings_attendees',kwargs={'num':96})
294+
response = self.client.get(url)
295+
self.assertEqual(response.status_code, 200)
296+
self.assertTrue('Attendee List' in response.content)
297+
q = PyQuery(response.content)
298+
self.assertEqual(1,len(q("#id_attendees tbody tr")))
280299

281300
def test_proceedings_overview(self):
282301
'''Test proceedings IETF Overview page.
283302
Note: old meetings aren't supported so need to add a new meeting then test.
284303
'''
285304
make_meeting_test_data()
286-
# add meeting requires a previous meeting to work
287-
date = datetime.date(2016,7,14)
288-
Meeting.objects.create(type_id='ietf',date=date,number=96)
289-
url = urlreverse('ietf.secr.meetings.views.add')
290-
post_data = dict(number='97',city='Seoul',date='2016-11-13',country='KR',
291-
time_zone='Asia/Seoul',venue_name='Conrad Seoul',
292-
venue_addr='10 Gukjegeumyung-ro',
293-
idsubmit_cutoff_day_offset_00=13,
294-
idsubmit_cutoff_day_offset_01=20,
295-
idsubmit_cutoff_time_utc =datetime.timedelta(hours=23, minutes=59, seconds=59),
296-
idsubmit_cutoff_warning_days =datetime.timedelta(days=21),
297-
submission_start_day_offset=90,
298-
submission_cutoff_day_offset=26,
299-
submission_correction_day_offset=50,
300-
)
301-
self.client.login(username='secretary', password='secretary+password')
302-
303-
response = self.client.post(url, post_data)
304-
self.assertRedirects(response,urlreverse('ietf.secr.meetings.views.main'))
305-
url = urlreverse('ietf.meeting.views.proceedings_overview',kwargs={'num':97})
305+
meeting = MeetingFactory(type_id='ietf', date=datetime.date(2016,7,14), number="96")
306+
finalize(meeting)
307+
url = urlreverse('ietf.meeting.views.proceedings_overview',kwargs={'num':96})
306308
response = self.client.get(url)
307309
self.assertEqual(response.status_code, 200)
308310
self.assertTrue('The Internet Engineering Task Force' in response.content)
309311

312+
def test_proceedings_progress_report(self):
313+
make_meeting_test_data()
314+
MeetingFactory(type_id='ietf', date=datetime.date(2016,4,3), number="95")
315+
MeetingFactory(type_id='ietf', date=datetime.date(2016,7,14), number="96")
316+
317+
url = urlreverse('ietf.meeting.views.proceedings_progress_report',kwargs={'num':96})
318+
response = self.client.get(url)
319+
self.assertEqual(response.status_code, 200)
320+
self.assertTrue('Progress Report' in response.content)
321+
310322
def test_feed(self):
311323
meeting = make_meeting_test_data()
312324
session = Session.objects.filter(meeting=meeting, group__acronym="mars").first()
@@ -1279,7 +1291,9 @@ def test_iphone_app_json(self):
12791291
self.assertEqual(r.status_code,200)
12801292

12811293
class FinalizeProceedingsTests(TestCase):
1282-
def test_finalize_proceedings(self):
1294+
@patch('urllib2.urlopen')
1295+
def test_finalize_proceedings(self, mock_urlopen):
1296+
mock_urlopen.return_value = StringIO('[{"LastName":"Smith","FirstName":"John","Company":"ABC","Country":"US"}]')
12831297
make_meeting_test_data()
12841298
meeting = Meeting.objects.filter(type_id='ietf').order_by('id').last()
12851299
meeting.session_set.filter(group__acronym='mars').first().sessionpresentation_set.create(document=Document.objects.filter(type='draft').first(),rev=None)

ietf/meeting/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@
7878
url(r'^proceedings(?:.html)?/?$', views.proceedings),
7979
url(r'^proceedings(?:.html)?/finalize/?$', views.finalize_proceedings),
8080
url(r'^proceedings/acknowledgements/$', views.proceedings_acknowledgements),
81+
url(r'^proceedings/attendees/$', views.proceedings_attendees),
8182
url(r'^proceedings/overview/$', views.proceedings_overview),
83+
url(r'^proceedings/progress-report/$', views.proceedings_progress_report),
8284
]
8385

8486
urlpatterns = [

ietf/meeting/utils.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import datetime
2+
import json
3+
import urllib2
4+
import urlparse
25

6+
from django.conf import settings
7+
from django.template.loader import render_to_string
8+
9+
from ietf.dbtemplate.models import DBTemplate
310
from ietf.meeting.models import Session
411
from ietf.group.utils import can_manage_materials
512

@@ -72,6 +79,35 @@ def time_sort_key(session):
7279

7380
return meeting_sorted
7481

82+
def create_proceedings_templates(meeting):
83+
'''Create DBTemplates for meeting proceedings'''
84+
# Get meeting attendees from registration system
85+
url = urlparse.urljoin(settings.REGISTRATION_ATTENDEES_BASE_URL,meeting.number)
86+
try:
87+
attendees = json.load(urllib2.urlopen(url))
88+
except (ValueError, urllib2.HTTPError):
89+
attendees = []
90+
91+
if attendees:
92+
attendees = sorted(attendees, key = lambda a: a['LastName'])
93+
content = render_to_string('meeting/proceedings_attendees_table.html', {
94+
'attendees':attendees})
95+
DBTemplate.objects.create(
96+
path='/meeting/proceedings/%s/attendees.html' % meeting.number,
97+
title='IETF %s Attendee List' % meeting.number,
98+
type_id='django',
99+
content=content)
100+
101+
# Make copy of default IETF Overview template
102+
if not meeting.overview:
103+
template = DBTemplate.objects.get(path='/meeting/proceedings/defaults/overview.rst')
104+
template.id = None
105+
template.path = '/meeting/proceedings/%s/overview.rst' % (meeting.number)
106+
template.title = 'IETF %s Proceedings Overview' % (meeting.number)
107+
template.save()
108+
meeting.overview = template
109+
meeting.save()
110+
75111
def finalize(meeting):
76112
end_date = meeting.end_date()
77113
end_time = datetime.datetime.combine(end_date, datetime.datetime.min.time())+datetime.timedelta(days=1)
@@ -81,8 +117,10 @@ def finalize(meeting):
81117
if rev_before_end:
82118
sp.rev = rev_before_end[-1].newrevisiondocevent.rev
83119
else:
84-
sp.rev = '00'
120+
sp.rev = '00'
85121
sp.save()
122+
123+
create_proceedings_templates(meeting)
86124
meeting.proceedings_final = True
87125
meeting.save()
88126
return

ietf/meeting/views.py

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from django.conf import settings
2626
from django.forms.models import modelform_factory, inlineformset_factory
2727
from django.forms import ModelForm
28+
from django.template import TemplateDoesNotExist
2829
from django.template.loader import render_to_string
2930
from django.utils.functional import curry
3031
from django.views.decorators.cache import cache_page
@@ -56,6 +57,7 @@
5657
from ietf.meeting.helpers import send_interim_announcement_request
5758
from ietf.meeting.utils import finalize
5859
from ietf.secr.proceedings.utils import handle_upload_file
60+
from ietf.secr.proceedings.proc_utils import get_progress_stats
5961
from ietf.utils.mail import send_mail_message
6062
from ietf.utils.pipe import pipe
6163
from ietf.utils.pdf import pdf_pages
@@ -2009,30 +2011,65 @@ def finalize_proceedings(request, num=None):
20092011

20102012
return render(request, "meeting/finalize.html", {'meeting':meeting,})
20112013

2012-
@role_required('Secretariat')
20132014
def proceedings_acknowledgements(request, num=None):
2014-
2015+
'''Display Acknowledgements for meeting'''
20152016
meeting = get_meeting(num)
2016-
if meeting.number < 95:
2017+
if not num.isdigit():
2018+
raise Http404
2019+
if int(meeting.number) < settings.NEW_PROCEEDINGS_START:
20172020
return HttpResponseRedirect( 'https://www.ietf.org/proceedings/%s/acknowledgement.html' % num )
20182021
return render(request, "meeting/proceedings_acknowledgements.html", {
20192022
'meeting': meeting,
20202023
})
20212024

2022-
@role_required('Secretariat')
2025+
def proceedings_attendees(request, num=None):
2026+
'''Display list of meeting attendees'''
2027+
meeting = get_meeting(num)
2028+
if not num.isdigit():
2029+
raise Http404
2030+
if int(meeting.number) < settings.NEW_PROCEEDINGS_START:
2031+
return HttpResponseRedirect( 'https://www.ietf.org/proceedings/%s/attendees.html' % num )
2032+
overview_template = '/meeting/proceedings/%s/attendees.html' % meeting.number
2033+
try:
2034+
template = render_to_string(overview_template, {})
2035+
except TemplateDoesNotExist:
2036+
raise Http404
2037+
return render(request, "meeting/proceedings_attendees.html", {
2038+
'meeting': meeting,
2039+
'template': template,
2040+
})
2041+
20232042
def proceedings_overview(request, num=None):
20242043
'''Display Overview for given meeting'''
20252044
meeting = get_meeting(num)
2026-
if meeting.number < 95:
2045+
if not num.isdigit():
2046+
raise Http404
2047+
if int(meeting.number) < settings.NEW_PROCEEDINGS_START:
20272048
return HttpResponseRedirect( 'https://www.ietf.org/proceedings/%s/overview.html' % num )
20282049
overview_template = '/meeting/proceedings/%s/overview.rst' % meeting.number
2029-
template = render_to_string(overview_template, {})
2030-
2050+
try:
2051+
template = render_to_string(overview_template, {})
2052+
except TemplateDoesNotExist:
2053+
raise Http404
20312054
return render(request, "meeting/proceedings_overview.html", {
20322055
'meeting': meeting,
20332056
'template': template,
20342057
})
20352058

2059+
@cache_page( 60 * 60 )
2060+
def proceedings_progress_report(request, num=None):
2061+
'''Display Progress Report (stats since last meeting)'''
2062+
meeting = get_meeting(num)
2063+
if not num.isdigit():
2064+
raise Http404
2065+
if int(meeting.number) < settings.NEW_PROCEEDINGS_START:
2066+
return HttpResponseRedirect( 'https://www.ietf.org/proceedings/%s/progress-report.html' % num )
2067+
sdate = meeting.previous_meeting().date
2068+
edate = meeting.date
2069+
context = get_progress_stats(sdate,edate)
2070+
context['meeting'] = meeting
2071+
return render(request, "meeting/proceedings_progress_report.html", context)
2072+
20362073
class OldUploadRedirect(RedirectView):
20372074
def get_redirect_url(self, **kwargs):
20382075
return reverse_lazy('ietf.meeting.views.session_details',kwargs=self.kwargs)

ietf/secr/meetings/tests.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ def test_add_meeting(self):
8585
response = self.client.post(url, post_data, follow=True)
8686
self.assertEqual(response.status_code, 200)
8787
self.assertEqual(Meeting.objects.count(),count + 1)
88-
meeting = Meeting.objects.order_by('id').last()
89-
self.assertEqual(meeting.overview.path,'/meeting/proceedings/%s/overview.rst' % meeting.number)
9088

9189
def test_edit_meeting(self):
9290
"Edit Meeting"

ietf/secr/meetings/views.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from django.template import RequestContext
1515
from django.utils.functional import curry
1616

17-
from ietf.dbtemplate.models import DBTemplate
1817
from ietf.ietfauth.utils import role_required
1918
from ietf.utils.mail import send_mail
2019
from ietf.meeting.helpers import get_meeting, make_materials_directories
@@ -317,16 +316,7 @@ def add(request):
317316

318317
# Create Physical new meeting directory and subdirectories
319318
make_materials_directories(meeting)
320-
321-
# Make copy of IETF Overview template
322-
template = DBTemplate.objects.get(path='/meeting/proceedings/defaults/overview.rst')
323-
template.id = None
324-
template.path = '/meeting/proceedings/%s/overview.rst' % (meeting.number)
325-
template.title = 'IETF %s Proceedings Overview' % (meeting.number)
326-
template.save()
327-
meeting.overview = template
328-
meeting.save()
329-
319+
330320
messages.success(request, 'The Meeting was created successfully!')
331321
return redirect('meetings')
332322
else:

0 commit comments

Comments
 (0)