Add configuration and mechanisms to allow meeting materials to be served via a CDN. Fixes #2935. Commit ready for merge.

- Legacy-Id: 18131
This commit is contained in:
Robert Sparks 2020-07-02 21:53:30 +00:00
parent c6f55a3306
commit 49c2fa8be2
3 changed files with 57 additions and 22 deletions

View file

@ -293,6 +293,18 @@ class MeetingTests(TestCase):
self.assertEqual(r.status_code,200)
self.assertTrue(all([x in unicontent(r) for x in ['var all_items', 'maximize', 'draw_calendar', ]]))
@override_settings(SERVE_MEETING_MATERIALS_LOCALLY=False)
def test_materials_through_cdn(self):
meeting = make_meeting_test_data()
session = Session.objects.filter(meeting=meeting, group__acronym="mars").first()
self.write_materials_files(meeting, session)
for document in (session.agenda(),session.minutes(),session.slides()[0]):
url = urlreverse("ietf.meeting.views.materials_document",
kwargs=dict(num=meeting.number, document=document))
r = self.client.get(url)
self.assertEqual(r.status_code,302)
self.assertEqual(r['Location'],document.get_href())
def test_materials(self):
meeting = make_meeting_test_data()
session = Session.objects.filter(meeting=meeting, group__acronym="mars").first()
@ -307,6 +319,7 @@ class MeetingTests(TestCase):
self.do_test_materials(meeting, session)
@override_settings(SERVE_MEETING_MATERIALS_LOCALLY=True)
def do_test_materials(self, meeting, session):
self.write_materials_files(meeting, session)
@ -2523,6 +2536,7 @@ class MaterialsTests(TestCase):
r = self.client.post(url,dict(file=test_file,apply_to_all=False))
self.assertEqual(r.status_code, 410)
@override_settings(SERVE_MEETING_MATERIALS_LOCALLY=True)
def test_upload_minutes_agenda_interim(self):
session=SessionFactory(meeting__type_id='interim')
for doctype in ('minutes','agenda'):

View file

@ -220,29 +220,33 @@ def materials_document(request, document, num=None, ext=None):
_, basename = os.path.split(filename)
if not os.path.exists(filename):
raise Http404("File not found: %s" % filename)
with io.open(filename, 'rb') as file:
bytes = file.read()
mtype, chset = get_mime_type(bytes)
content_type = "%s; charset=%s" % (mtype, chset)
file_ext = os.path.splitext(filename)
if len(file_ext) == 2 and file_ext[1] == '.md' and mtype == 'text/plain':
sorted_accept = sort_accept_tuple(request.META.get('HTTP_ACCEPT'))
for atype in sorted_accept:
if atype[0] == 'text/markdown':
content_type = content_type.replace('plain', 'markdown', 1)
break;
elif atype[0] == 'text/html':
bytes = "<html>\n<head></head>\n<body>\n%s\n</body>\n</html>\n" % markdown2.markdown(bytes)
content_type = content_type.replace('plain', 'html', 1)
break;
elif atype[0] == 'text/plain':
break;
if settings.SERVE_MEETING_MATERIALS_LOCALLY :
with io.open(filename, 'rb') as file:
bytes = file.read()
mtype, chset = get_mime_type(bytes)
content_type = "%s; charset=%s" % (mtype, chset)
response = HttpResponse(bytes, content_type=content_type)
response['Content-Disposition'] = 'inline; filename="%s"' % basename
return response
file_ext = os.path.splitext(filename)
if len(file_ext) == 2 and file_ext[1] == '.md' and mtype == 'text/plain':
sorted_accept = sort_accept_tuple(request.META.get('HTTP_ACCEPT'))
for atype in sorted_accept:
if atype[0] == 'text/markdown':
content_type = content_type.replace('plain', 'markdown', 1)
break;
elif atype[0] == 'text/html':
bytes = "<html>\n<head></head>\n<body>\n%s\n</body>\n</html>\n" % markdown2.markdown(bytes)
content_type = content_type.replace('plain', 'html', 1)
break;
elif atype[0] == 'text/plain':
break;
response = HttpResponse(bytes, content_type=content_type)
response['Content-Disposition'] = 'inline; filename="%s"' % basename
return response
else:
return HttpResponseRedirect(redirect_to=doc.get_href())
@login_required
def materials_editable_groups(request, num=None):

View file

@ -687,7 +687,13 @@ DOC_HREFS = {
"liai-att": "%s{doc.uploaded_filename}" % LIAISON_ATTACH_URL,
}
MEETING_DOC_HREFS = {
SERVE_MEETING_MATERIALS_LOCALLY = False
# If you override SERVE_MEETING_MATERIALS_LOCALLY in your settings_local.conf, you will need to
# set the right value for MEETING_DOC_HREFS there as well. LOCAL_MEETING_DOC_HREFS and
# CDN_MEETING_DOC_HREFS are defined here to make that simpler.
LOCAL_MEETING_DOC_HREFS = {
"agenda": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}",
"minutes": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}",
"slides": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}",
@ -695,6 +701,16 @@ MEETING_DOC_HREFS = {
"bluesheets": "https://www.ietf.org/proceedings/{meeting.number}/bluesheets/{doc.uploaded_filename}",
}
CDN_MEETING_DOC_HREFS = {
"agenda": "https://www.ietf.org/proceedings/{meeting.number}/agenda/{doc.name}-{doc.rev}",
"minutes": "https://www.ietf.org/proceedings/{meeting.number}/minutes/{doc.name}-{doc.rev}",
"slides": "https://www.ietf.org/proceedings/{meeting.number}/slides/{doc.name}-{doc.rev}",
"recording": "{doc.external_url}",
"bluesheets": "https://www.ietf.org/proceedings/{meeting.number}/bluesheets/{doc.uploaded_filename}",
}
MEETING_DOC_HREFS = LOCAL_MEETING_DOC_HREFS if SERVE_MEETING_MATERIALS_LOCALLY else CDN_MEETING_DOC_HREFS
MEETING_DOC_OLD_HREFS = {
"agenda": "/meeting/{meeting.number}/materials/{doc.name}",
"minutes": "/meeting/{meeting.number}/materials/{doc.name}",
@ -712,6 +728,7 @@ MEETING_DOC_GREFS = {
"bluesheets": "https://www.ietf.org/proceedings/{meeting.number}/bluesheets/{doc.uploaded_filename}",
}
# Valid MIME types for cases where text is uploaded and immediately extracted,
# e.g. a charter or a review. Must be a tuple, not a list.
DOC_TEXT_FILE_VALID_UPLOAD_MIME_TYPES = ('text/plain', 'text/markdown', 'text/x-rst')