Commit ab6c8234 by Carson Gee

Add last resort method to download and showing of video transcript

parent 6963d24e
...@@ -11,6 +11,7 @@ from webob import Response ...@@ -11,6 +11,7 @@ from webob import Response
from xblock.core import XBlock from xblock.core import XBlock
from xmodule.course_module import CourseDescriptor
from xmodule.exceptions import NotFoundError from xmodule.exceptions import NotFoundError
from xmodule.fields import RelativeTime from xmodule.fields import RelativeTime
...@@ -22,6 +23,7 @@ from .transcripts_utils import ( ...@@ -22,6 +23,7 @@ from .transcripts_utils import (
youtube_speed_dict, youtube_speed_dict,
Transcript, Transcript,
save_to_store, save_to_store,
subs_filename
) )
...@@ -171,6 +173,33 @@ class VideoStudentViewHandlers(object): ...@@ -171,6 +173,33 @@ class VideoStudentViewHandlers(object):
return content, filename, Transcript.mime_types[transcript_format] return content, filename, Transcript.mime_types[transcript_format]
def get_static_transcript(self, request):
"""
Return URL for static transcript if it isn't available in the content store
"""
# Try to return static redirect to the transcript as a last
# resort, but return 404 if we don't
response = Response(status=404)
vid_id = request.GET.get('videoId', None)
if vid_id:
transcript_name = vid_id
else:
transcript_name = self.sub
if transcript_name:
course_location = CourseDescriptor.id_to_location(self.course_id)
course = self.descriptor.runtime.modulestore.get_item(course_location)
if course.static_asset_path:
response = Response(
status=307,
location='/static/{0}/{1}'.format(
course.static_asset_path,
subs_filename(transcript_name, self.transcript_language)
)
)
return response
@XBlock.handler @XBlock.handler
def transcript(self, request, dispatch): def transcript(self, request, dispatch):
""" """
...@@ -206,6 +235,7 @@ class VideoStudentViewHandlers(object): ...@@ -206,6 +235,7 @@ class VideoStudentViewHandlers(object):
if language != self.transcript_language: if language != self.transcript_language:
self.transcript_language = language self.transcript_language = language
try: try:
transcript = self.translation(request.GET.get('videoId', None)) transcript = self.translation(request.GET.get('videoId', None))
except ( except (
...@@ -216,7 +246,8 @@ class VideoStudentViewHandlers(object): ...@@ -216,7 +246,8 @@ class VideoStudentViewHandlers(object):
TranscriptsGenerationException TranscriptsGenerationException
) as ex: ) as ex:
log.info(ex.message) log.info(ex.message)
response = Response(status=404) # Try to return static URL redirection as last resort
return self.get_static_transcript(request)
else: else:
response = Response(transcript, headerlist=[('Content-Language', language)]) response = Response(transcript, headerlist=[('Content-Language', language)])
response.content_type = Transcript.mime_types['sjson'] response.content_type = Transcript.mime_types['sjson']
...@@ -226,7 +257,8 @@ class VideoStudentViewHandlers(object): ...@@ -226,7 +257,8 @@ class VideoStudentViewHandlers(object):
transcript_content, transcript_filename, transcript_mime_type = self.get_transcript(self.transcript_download_format) transcript_content, transcript_filename, transcript_mime_type = self.get_transcript(self.transcript_download_format)
except (NotFoundError, ValueError, KeyError, UnicodeDecodeError): except (NotFoundError, ValueError, KeyError, UnicodeDecodeError):
log.debug("Video@download exception") log.debug("Video@download exception")
return Response(status=404) # Return static URL or 404
return self.get_static_transcript(request)
else: else:
response = Response( response = Response(
transcript_content, transcript_content,
......
...@@ -10,8 +10,9 @@ from datetime import timedelta ...@@ -10,8 +10,9 @@ from datetime import timedelta
from webob import Request from webob import Request
from xmodule.contentstore.content import StaticContent from xmodule.contentstore.content import StaticContent
from xmodule.modulestore import Location
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
from xmodule.modulestore import Location
from xmodule.modulestore.django import editable_modulestore
from . import BaseTestXmodule from . import BaseTestXmodule
from .test_video_xml import SOURCE_XML from .test_video_xml import SOURCE_XML
from cache_toolbox.core import del_cached_content from cache_toolbox.core import del_cached_content
...@@ -225,6 +226,7 @@ class TestTranscriptDownloadDispatch(TestVideo): ...@@ -225,6 +226,7 @@ class TestTranscriptDownloadDispatch(TestVideo):
DATA = """ DATA = """
<video show_captions="true" <video show_captions="true"
display_name="A Name" display_name="A Name"
sub='blahblah'
> >
<source src="example.mp4"/> <source src="example.mp4"/>
<source src="example.webm"/> <source src="example.webm"/>
...@@ -277,6 +279,23 @@ class TestTranscriptDownloadDispatch(TestVideo): ...@@ -277,6 +279,23 @@ class TestTranscriptDownloadDispatch(TestVideo):
self.assertEqual(response.headers['Content-Type'], 'application/x-subrip; charset=utf-8') self.assertEqual(response.headers['Content-Type'], 'application/x-subrip; charset=utf-8')
self.assertEqual(response.headers['Content-Disposition'], 'attachment; filename="塞.srt"') self.assertEqual(response.headers['Content-Disposition'], 'attachment; filename="塞.srt"')
def test_download_static_transcript(self):
"""
Set course static_asset_path and ensure we get redirected to that path
if it isn't found in the contentstore
"""
self.course.static_asset_path = 'dummy/static'
self.course.save()
store = editable_modulestore()
store.update_item(self.course, 'blahblah')
request = Request.blank('/download')
response = self.item.transcript(request=request, dispatch='download')
self.assertEqual(response.status, '307 Temporary Redirect')
self.assertIn(
('Location', '/static/dummy/static/subs_blahblah.srt.sjson'),
response.headerlist
)
class TestTranscriptTranslationGetDispatch(TestVideo): class TestTranscriptTranslationGetDispatch(TestVideo):
""" """
...@@ -402,6 +421,44 @@ class TestTranscriptTranslationGetDispatch(TestVideo): ...@@ -402,6 +421,44 @@ class TestTranscriptTranslationGetDispatch(TestVideo):
response = self.item.transcript(request=request, dispatch='translation/uk') response = self.item.transcript(request=request, dispatch='translation/uk')
self.assertDictEqual(json.loads(response.body), subs) self.assertDictEqual(json.loads(response.body), subs)
def test_translation_static_transcript(self):
"""
Set course static_asset_path and ensure we get redirected to that path
if it isn't found in the contentstore
"""
self.course.static_asset_path = 'dummy/static'
self.course.save()
store = editable_modulestore()
store.update_item(self.course, 'blahblah')
# Test youtube style en
request = Request.blank('/translation/en?videoId=12345')
response = self.item.transcript(request=request, dispatch='translation/en')
self.assertEqual(response.status, '307 Temporary Redirect')
self.assertIn(
('Location', '/static/dummy/static/subs_12345.srt.sjson'),
response.headerlist
)
# Test HTML5 video style
self.item.sub = 'blahblah'
request = Request.blank('/translation/en')
response = self.item.transcript(request=request, dispatch='translation/en')
self.assertEqual(response.status, '307 Temporary Redirect')
self.assertIn(
('Location', '/static/dummy/static/subs_blahblah.srt.sjson'),
response.headerlist
)
# Test different language
request = Request.blank('/translation/uk')
response = self.item.transcript(request=request, dispatch='translation/uk')
self.assertEqual(response.status, '307 Temporary Redirect')
self.assertIn(
('Location', '/static/dummy/static/uk_subs_blahblah.srt.sjson'),
response.headerlist
)
class TestStudioTranscriptTranslationGetDispatch(TestVideo): class TestStudioTranscriptTranslationGetDispatch(TestVideo):
""" """
......
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