Get rid of lepl deprecation warning by removing rfc6266 dependency (#24059)
The LEPL dependency was triggering a lot of deprecation warnings of the
form:
venv/lib/python3.5/site-packages/lepl/matchers/support.py:497:
DeprecationWarning: inspect.getargspec() is deprecated, use
inspect.signature() instead
argspec = getargspec(func)
It turns out that LEPL was only used by the rfc6266_parser package, which
itself was only used in one place to generate utf8-compliant
Content-Disposition headers.
This issue was noticed here:
https://github.com/SWW13/python-rfc6266-parser/issues/2
Unfortunately it is quite difficult to extract LEPL from the
rfc6266-parser package.
The rfc6266-parser package (https://pypi.org/project/rfc6266-parser/) is
itself a fork of the now-unmaintained rfc6266 package
(https://pypi.org/project/rfc6266/). Thus, it became high time to get
rid of this package. The FileResponse object can appropriately set the
Content-Disposition header, and thus replace the rfc6266 functionality,
since Django 2.0: https://code.djangoproject.com/ticket/16470
In our testing, the FileResponse object correctly set the
`filename*=utf-8''` value, following the RFC. The only difference is
that it does not provide "filename" fallback value, as expressed in the
RFC: https://tools.ietf.org/html/rfc6266#appendix-D
With rfc6266_parser:
>> import rfc6266_parser
>> rfc6266_parser.build_header("my_file_é.csv", filename_compat="video_urls.csv")
b"attachment; filename=video_urls.csv; filename*=utf-8''my_file_%C3%A9.csv"
With FileResponse we have:
>> from django.http import FileResponse
>> import io
>> response = FileResponse(io.StringIO(), as_attachment=True, filename="my_file_é.csv", content_type="text/csv")
>> response.get("Content-Disposition")
"attachment; filename*=utf-8''my_file_%C3%A9.csv"
We consider that this is a sufficiently minor difference, that will
impact very few browsers.
This commit is contained in:
@@ -1541,9 +1541,10 @@ class VideoUrlsCsvTestCase(VideoUploadTestMixin, CourseTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
response["Content-Disposition"],
|
||||
u"attachment; filename={course}_video_urls.csv".format(course=self.course.id.course)
|
||||
u"attachment; filename=\"{course}_video_urls.csv\"".format(course=self.course.id.course)
|
||||
)
|
||||
response_reader = StringIO(response.content.decode('utf-8') if six.PY3 else response.content)
|
||||
response_content = b"".join(response.streaming_content)
|
||||
response_reader = StringIO(response_content.decode('utf-8') if six.PY3 else response_content)
|
||||
reader = csv.DictReader(response_reader, dialect=csv.excel)
|
||||
self.assertEqual(
|
||||
reader.fieldnames,
|
||||
@@ -1605,5 +1606,5 @@ class VideoUrlsCsvTestCase(VideoUploadTestMixin, CourseTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
response["Content-Disposition"],
|
||||
u"attachment; filename=video_urls.csv; filename*=utf-8''n%C3%B3n-%C3%A4scii_video_urls.csv"
|
||||
u"attachment; filename*=utf-8''n%C3%B3n-%C3%A4scii_video_urls.csv"
|
||||
)
|
||||
|
||||
@@ -3,21 +3,22 @@ Views related to the video upload feature
|
||||
"""
|
||||
|
||||
|
||||
import codecs
|
||||
import csv
|
||||
import json
|
||||
import logging
|
||||
from contextlib import closing
|
||||
from datetime import datetime, timedelta
|
||||
import io
|
||||
from uuid import uuid4
|
||||
|
||||
import rfc6266_parser
|
||||
import six
|
||||
from boto import s3
|
||||
from boto.sts import STSConnection
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.staticfiles.storage import staticfiles_storage
|
||||
from django.http import HttpResponse, HttpResponseNotFound
|
||||
from django.http import FileResponse, HttpResponseNotFound
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext_noop
|
||||
@@ -461,17 +462,12 @@ def video_encodings_download(request, course_key_string):
|
||||
for key, value in ret.items()
|
||||
}
|
||||
|
||||
response = HttpResponse(content_type="text/csv")
|
||||
# Translators: This is the suggested filename when downloading the URL
|
||||
# listing for videos uploaded through Studio
|
||||
filename = _("{course}_video_urls").format(course=course.id.course)
|
||||
# See https://tools.ietf.org/html/rfc6266#appendix-D
|
||||
response["Content-Disposition"] = rfc6266_parser.build_header(
|
||||
filename + ".csv",
|
||||
filename_compat="video_urls.csv"
|
||||
)
|
||||
# Write csv to bytes-like object. We need a separate writer and buffer as the csv
|
||||
# writer writes str and the FileResponse expects a bytes files.
|
||||
buffer = io.BytesIO()
|
||||
buffer_writer = codecs.getwriter("utf-8")(buffer)
|
||||
writer = csv.DictWriter(
|
||||
response,
|
||||
buffer_writer,
|
||||
[
|
||||
col_name.encode("utf-8") if six.PY2 else col_name
|
||||
for col_name
|
||||
@@ -482,7 +478,12 @@ def video_encodings_download(request, course_key_string):
|
||||
writer.writeheader()
|
||||
for video in videos:
|
||||
writer.writerow(make_csv_dict(video))
|
||||
return response
|
||||
buffer.seek(0)
|
||||
|
||||
# Translators: This is the suggested filename when downloading the URL
|
||||
# listing for videos uploaded through Studio
|
||||
filename = _("{course}_video_urls").format(course=course.id.course) + ".csv"
|
||||
return FileResponse(buffer, as_attachment=True, filename=filename, content_type="text/csv")
|
||||
|
||||
|
||||
def _get_and_validate_course(course_key_string, user):
|
||||
|
||||
@@ -136,7 +136,6 @@ python3-saml
|
||||
pyuca # For more accurate sorting of translated country names in django-countries
|
||||
recommender-xblock # https://github.com/edx/RecommenderXBlock
|
||||
rest-condition # DRF's recommendation for supporting complex permissions
|
||||
rfc6266-parser # Used to generate Content-Disposition headers.
|
||||
social-auth-core
|
||||
pysrt # Support for SubRip subtitle files, used in the video XModule
|
||||
pytz # Time zone information database
|
||||
|
||||
@@ -142,7 +142,6 @@ jsonfield2==3.0.3 # via -c requirements/edx/../constraints.txt, -r requi
|
||||
kombu==3.0.37 # via celery
|
||||
laboratory==1.0.2 # via -r requirements/edx/base.in
|
||||
lazy==1.4 # via -r requirements/edx/paver.txt, acid-xblock, lti-consumer-xblock, ora2
|
||||
lepl==5.1.3 # via rfc6266-parser
|
||||
libsass==0.10.0 # via -r requirements/edx/paver.txt, ora2
|
||||
loremipsum==1.0.5 # via ora2
|
||||
lti-consumer-xblock==2.3 # via -r requirements/edx/base.in
|
||||
@@ -206,7 +205,6 @@ regex==2020.7.14 # via -r requirements/edx/../edx-sandbox/shared.txt, n
|
||||
requests-oauthlib==1.3.0 # via -r requirements/edx/base.in, social-auth-core
|
||||
requests==2.24.0 # via -r requirements/edx/paver.txt, analytics-python, coreapi, django-oauth-toolkit, edx-analytics-data-api-client, edx-bulk-grades, edx-drf-extensions, edx-enterprise, edx-rest-api-client, geoip2, mailsnake, pyjwkest, python-swiftclient, requests-oauthlib, sailthru-client, slumber, social-auth-core
|
||||
rest-condition==1.0.3 # via -r requirements/edx/base.in, edx-drf-extensions
|
||||
rfc6266-parser==0.0.6 # via -r requirements/edx/base.in
|
||||
ruamel.yaml.clib==0.2.0 # via ruamel.yaml
|
||||
ruamel.yaml==0.16.10 # via drf-yasg
|
||||
rules==2.2 # via -r requirements/edx/base.in, edx-enterprise, edx-proctoring
|
||||
|
||||
@@ -171,7 +171,6 @@ kombu==3.0.37 # via -r requirements/edx/testing.txt, celery
|
||||
laboratory==1.0.2 # via -r requirements/edx/testing.txt
|
||||
lazy-object-proxy==1.4.3 # via -r requirements/edx/testing.txt, astroid
|
||||
lazy==1.4 # via -r requirements/edx/testing.txt, acid-xblock, bok-choy, lti-consumer-xblock, ora2
|
||||
lepl==5.1.3 # via -r requirements/edx/testing.txt, rfc6266-parser
|
||||
libsass==0.10.0 # via -r requirements/edx/testing.txt, ora2
|
||||
loremipsum==1.0.5 # via -r requirements/edx/testing.txt, ora2
|
||||
lti-consumer-xblock==2.3 # via -r requirements/edx/testing.txt
|
||||
@@ -259,7 +258,6 @@ regex==2020.7.14 # via -r requirements/edx/testing.txt, nltk
|
||||
requests-oauthlib==1.3.0 # via -r requirements/edx/testing.txt, social-auth-core
|
||||
requests==2.24.0 # via -r requirements/edx/testing.txt, analytics-python, coreapi, django-oauth-toolkit, edx-analytics-data-api-client, edx-bulk-grades, edx-drf-extensions, edx-enterprise, edx-rest-api-client, geoip2, mailsnake, pyjwkest, python-swiftclient, requests-oauthlib, sailthru-client, slumber, social-auth-core, sphinx, transifex-client
|
||||
rest-condition==1.0.3 # via -r requirements/edx/testing.txt, edx-drf-extensions
|
||||
rfc6266-parser==0.0.6 # via -r requirements/edx/testing.txt
|
||||
ruamel.yaml.clib==0.2.0 # via -r requirements/edx/testing.txt, ruamel.yaml
|
||||
ruamel.yaml==0.16.10 # via -r requirements/edx/testing.txt, drf-yasg
|
||||
rules==2.2 # via -r requirements/edx/testing.txt, edx-enterprise, edx-proctoring
|
||||
|
||||
@@ -165,7 +165,6 @@ kombu==3.0.37 # via -r requirements/edx/base.txt, celery
|
||||
laboratory==1.0.2 # via -r requirements/edx/base.txt
|
||||
lazy-object-proxy==1.4.3 # via astroid
|
||||
lazy==1.4 # via -r requirements/edx/base.txt, acid-xblock, bok-choy, lti-consumer-xblock, ora2
|
||||
lepl==5.1.3 # via -r requirements/edx/base.txt, rfc6266-parser
|
||||
libsass==0.10.0 # via -r requirements/edx/base.txt, ora2
|
||||
loremipsum==1.0.5 # via -r requirements/edx/base.txt, ora2
|
||||
lti-consumer-xblock==2.3 # via -r requirements/edx/base.txt
|
||||
@@ -248,7 +247,6 @@ regex==2020.7.14 # via -r requirements/edx/base.txt, nltk
|
||||
requests-oauthlib==1.3.0 # via -r requirements/edx/base.txt, social-auth-core
|
||||
requests==2.24.0 # via -r requirements/edx/base.txt, analytics-python, coreapi, django-oauth-toolkit, edx-analytics-data-api-client, edx-bulk-grades, edx-drf-extensions, edx-enterprise, edx-rest-api-client, geoip2, mailsnake, pyjwkest, python-swiftclient, requests-oauthlib, sailthru-client, slumber, social-auth-core, transifex-client
|
||||
rest-condition==1.0.3 # via -r requirements/edx/base.txt, edx-drf-extensions
|
||||
rfc6266-parser==0.0.6 # via -r requirements/edx/base.txt
|
||||
ruamel.yaml.clib==0.2.0 # via -r requirements/edx/base.txt, ruamel.yaml
|
||||
ruamel.yaml==0.16.10 # via -r requirements/edx/base.txt, drf-yasg
|
||||
rules==2.2 # via -r requirements/edx/base.txt, edx-enterprise, edx-proctoring
|
||||
|
||||
Reference in New Issue
Block a user