Commit d32a434d by muhammad-ammar

video component basic tab upload transcript to S3

EDUCATOR-1758
parent dd2f90fb
...@@ -21,6 +21,7 @@ from xmodule.contentstore.django import contentstore ...@@ -21,6 +21,7 @@ from xmodule.contentstore.django import contentstore
from xmodule.exceptions import NotFoundError from xmodule.exceptions import NotFoundError
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.video_module import transcripts_utils from xmodule.video_module import transcripts_utils
from edxval import api as edxval_api
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE) TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex
...@@ -106,11 +107,11 @@ class TestUploadTranscripts(BaseTranscripts): ...@@ -106,11 +107,11 @@ class TestUploadTranscripts(BaseTranscripts):
self.good_srt_file = tempfile.NamedTemporaryFile(suffix='.srt') self.good_srt_file = tempfile.NamedTemporaryFile(suffix='.srt')
self.good_srt_file.write(textwrap.dedent(""" self.good_srt_file.write(textwrap.dedent("""
1 0
00:00:10,500 --> 00:00:13,000 00:00:10,500 --> 00:00:13,000
Elephant's Dream Elephant's Dream
2 1
00:00:15,000 --> 00:00:18,000 00:00:15,000 --> 00:00:18,000
At the left we can see... At the left we can see...
""")) """))
...@@ -134,6 +135,25 @@ class TestUploadTranscripts(BaseTranscripts): ...@@ -134,6 +135,25 @@ class TestUploadTranscripts(BaseTranscripts):
self.ufeff_srt_file = tempfile.NamedTemporaryFile(suffix='.srt') self.ufeff_srt_file = tempfile.NamedTemporaryFile(suffix='.srt')
def assert_transcript_upload(self, filename, expected_transcript_content):
"""
Verify that transcript is uploaded as expected
"""
# verify that transcript should not be in contentstore
content_location = StaticContent.compute_location(self.course.id, 'subs_{0}.srt.sjson'.format(filename))
with self.assertRaises(NotFoundError) as item_not_found:
contentstore().find(content_location)
# verify uploaded transcript content
transcript_data = edxval_api.get_video_transcript_data([filename], 'en')
sjson_transcript = transcript_data['content']
uploaded_transcript_content = transcripts_utils.Transcript.convert(
sjson_transcript,
input_format='sjson',
output_format='srt'
)
self.assertIn(expected_transcript_content.strip(), uploaded_transcript_content.strip())
def test_success_video_module_source_subs_uploading(self): def test_success_video_module_source_subs_uploading(self):
self.item.data = textwrap.dedent(""" self.item.data = textwrap.dedent("""
<video youtube=""> <video youtube="">
...@@ -161,9 +181,9 @@ class TestUploadTranscripts(BaseTranscripts): ...@@ -161,9 +181,9 @@ class TestUploadTranscripts(BaseTranscripts):
item = modulestore().get_item(self.video_usage_key) item = modulestore().get_item(self.video_usage_key)
self.assertEqual(item.sub, filename) self.assertEqual(item.sub, filename)
content_location = StaticContent.compute_location( # move the file pointer to start of the file
self.course.id, 'subs_{0}.srt.sjson'.format(filename)) self.good_srt_file.seek(0)
self.assertTrue(contentstore().find(content_location)) self.assert_transcript_upload(filename, self.good_srt_file.read())
def test_fail_data_without_id(self): def test_fail_data_without_id(self):
link = reverse('upload_transcripts') link = reverse('upload_transcripts')
...@@ -346,12 +366,7 @@ class TestUploadTranscripts(BaseTranscripts): ...@@ -346,12 +366,7 @@ class TestUploadTranscripts(BaseTranscripts):
}) })
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
content_location = StaticContent.compute_location( self.assert_transcript_upload(filename, 'Test ufeff characters')
self.course.id, 'subs_{0}.srt.sjson'.format(filename))
self.assertTrue(contentstore().find(content_location))
subs_text = json.loads(contentstore().find(content_location).data).get('text')
self.assertIn("Test ufeff characters", subs_text)
def tearDown(self): def tearDown(self):
super(TestUploadTranscripts, self).tearDown() super(TestUploadTranscripts, self).tearDown()
......
...@@ -14,6 +14,7 @@ import requests ...@@ -14,6 +14,7 @@ import requests
from django.conf import settings from django.conf import settings
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.core.files.base import ContentFile
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
...@@ -40,6 +41,7 @@ from xmodule.video_module.transcripts_utils import ( ...@@ -40,6 +41,7 @@ from xmodule.video_module.transcripts_utils import (
TranscriptsRequestValidationException, TranscriptsRequestValidationException,
youtube_video_transcript_name, youtube_video_transcript_name,
) )
from edxval import api as edxval_api
__all__ = [ __all__ = [
'upload_transcripts', 'upload_transcripts',
...@@ -119,16 +121,24 @@ def upload_transcripts(request): ...@@ -119,16 +121,24 @@ def upload_transcripts(request):
if video_list: if video_list:
sub_attr = source_subs_name sub_attr = source_subs_name
try: try:
# Generate and save for 1.0 speed, will create subs_sub_attr.srt.sjson subtitles file in storage. # Generate sjson subtitles from srt substitles
generate_subs_from_source({1: sub_attr}, source_subs_ext, source_subs_filedata, item) sjson_subs = generate_subs_from_source({}, source_subs_ext, source_subs_filedata, item)
for video_dict in video_list: for video_dict in video_list:
video_name = video_dict['video'] video_name = video_dict['video']
# We are creating transcripts for every video source, if in future some of video sources would be deleted. # We are creating transcripts for every video source in case a video source is deleted in future.
# Updates item.sub with `video_name` on success. edxval_api.create_or_update_video_transcript(
copy_or_rename_transcript(video_name, sub_attr, item, user=request.user) video_id=video_name,
language_code='en',
file_name='subs.sjson', # S3 filename will be `uuid.sjson` like 5d30d3e44cebacf6163976388cae.sjson
file_format='sjson',
provider='Custom',
file_data=ContentFile(json.dumps(sjson_subs)),
)
response['subs'] = item.sub item.sub = video_name
item.save_with_metadata(request.user)
response['subs'] = video_name
response['status'] = 'Success' response['status'] = 'Success'
except Exception as ex: except Exception as ex:
return error_response(response, ex.message) return error_response(response, ex.message)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment