From ad4e3d50a5fec76da29a9dd3fc1b594b0601bcff Mon Sep 17 00:00:00 2001 From: Omar Al-Ithawi Date: Mon, 3 Apr 2017 14:06:57 +0300 Subject: [PATCH] Allow uploading subtitles with unicode filenames --- .../tests/test_transcripts_utils.py | 37 ++++++++++++++----- .../xmodule/video_module/transcripts_utils.py | 2 +- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/cms/djangoapps/contentstore/tests/test_transcripts_utils.py b/cms/djangoapps/contentstore/tests/test_transcripts_utils.py index 3cdf01e543..61ae89702d 100644 --- a/cms/djangoapps/contentstore/tests/test_transcripts_utils.py +++ b/cms/djangoapps/contentstore/tests/test_transcripts_utils.py @@ -86,11 +86,19 @@ class TestSaveSubsToStore(SharedModuleStoreTestCase): def clear_subs_content(self): """Remove, if subtitles content exists.""" - try: - content = contentstore().find(self.content_location) - contentstore().delete(content.location) - except NotFoundError: - pass + for content_location in [self.content_location, self.content_copied_location]: + try: + content = contentstore().find(content_location) + contentstore().delete(content.location) + except NotFoundError: + pass + + @classmethod + def sub_id_to_location(cls, sub_id): + """ + A helper to compute a static file location from a subtitle id. + """ + return StaticContent.compute_location(cls.course.id, u'subs_{0}.srt.sjson'.format(sub_id)) @classmethod def setUpClass(cls): @@ -110,22 +118,31 @@ class TestSaveSubsToStore(SharedModuleStoreTestCase): ] } - cls.subs_id = str(uuid4()) - filename = 'subs_{0}.srt.sjson'.format(cls.subs_id) - cls.content_location = StaticContent.compute_location(cls.course.id, filename) + # Prefix it to ensure that unicode filenames are allowed + cls.subs_id = u'uniçøde_{}'.format(uuid4()) + cls.subs_copied_id = u'cøpy_{}'.format(uuid4()) + + cls.content_location = cls.sub_id_to_location(cls.subs_id) + cls.content_copied_location = cls.sub_id_to_location(cls.subs_copied_id) # incorrect subs cls.unjsonable_subs = {1} # set can't be serialized cls.unjsonable_subs_id = str(uuid4()) - filename_unjsonable = 'subs_{0}.srt.sjson'.format(cls.unjsonable_subs_id) - cls.content_location_unjsonable = StaticContent.compute_location(cls.course.id, filename_unjsonable) + cls.content_location_unjsonable = cls.sub_id_to_location(cls.unjsonable_subs_id) def setUp(self): super(TestSaveSubsToStore, self).setUp() self.addCleanup(self.clear_subs_content) self.clear_subs_content() + def test_save_unicode_filename(self): + # Mock a video item + item = Mock(location=Mock(course_key=self.course.id)) + transcripts_utils.save_subs_to_store(self.subs, self.subs_id, self.course) + transcripts_utils.copy_or_rename_transcript(self.subs_copied_id, self.subs_id, item) + self.assertTrue(contentstore().find(self.content_copied_location)) + def test_save_subs_to_store(self): with self.assertRaises(NotFoundError): contentstore().find(self.content_location) diff --git a/common/lib/xmodule/xmodule/video_module/transcripts_utils.py b/common/lib/xmodule/xmodule/video_module/transcripts_utils.py index 2eeb3ff888..af4f1e22fb 100644 --- a/common/lib/xmodule/xmodule/video_module/transcripts_utils.py +++ b/common/lib/xmodule/xmodule/video_module/transcripts_utils.py @@ -283,7 +283,7 @@ def copy_or_rename_transcript(new_name, old_name, item, delete_old=False, user=N If `old_name` is not found in storage, raises `NotFoundError`. If `delete_old` is True, removes `old_name` files from storage. """ - filename = 'subs_{0}.srt.sjson'.format(old_name) + filename = u'subs_{0}.srt.sjson'.format(old_name) content_location = StaticContent.compute_location(item.location.course_key, filename) transcripts = contentstore().find(content_location).data save_subs_to_store(json.loads(transcripts), new_name, item)