예제 #1
0
    def get_vedio_module_conent(self):
        """
        Provide the content data for Video component.
        :return: dict 
        """
        content = {
            'category': self._component.category,
            'start': self._component.start,
            'display_name': self._component.display_name,
            'youtube_is_available': self._component.youtube_is_available,
            'youtube_id_0_75': self._component.youtube_id_0_75,
            'youtube_id_1_0': self._component.youtube_id_1_0,
            'youtube_id_1_25': self._component.youtube_id_1_25,
            'youtube_id_1_5': self._component.youtube_id_1_5,
            'start_time': self._component.start_time,
            'end_time': self._component.end_time,
            'download_video': self._component.download_video,
        }

        if self._component.html5_sources is not None:
            temp_source = []
            for key in self._component.html5_sources:
                temp_source.append({'url': key})
            content['html5_sources'] = temp_source

        transcript_info = self._component.get_transcripts_info()
        if len(transcript_info['sub']) is not 0:
            transcript = Transcript()
            transcript_content = transcript.asset(self._component.location,
                                                  transcript_info['sub'])
            content['transcript'] = json.loads(transcript_content.data)

        return content
예제 #2
0
    def get(self, request, course, *args, **kwargs):
        block_id = kwargs['block_id']
        lang = kwargs['lang']

        usage_key = BlockUsageLocator(course.id, block_type='video', block_id=block_id)
        video_descriptor = modulestore().get_item(usage_key)
        feature_enabled = is_val_transcript_feature_enabled_for_course(usage_key.course_key)
        try:
            transcripts = video_descriptor.get_transcripts_info(include_val_transcripts=feature_enabled)
            content, filename, mimetype = video_descriptor.get_transcript(transcripts, lang=lang)
        except (ValueError, NotFoundError):
            # Fallback mechanism for edx-val transcripts
            transcript = None
            if feature_enabled:
                transcript = get_video_transcript_content(
                    language_code=lang,
                    edx_video_id=video_descriptor.edx_video_id,
                    youtube_id_1_0=video_descriptor.youtube_id_1_0,
                    html5_sources=video_descriptor.html5_sources,
                )

            if not transcript:
                raise Http404(u'Transcript not found for {}, lang: {}'.format(block_id, lang))

            base_name, __ = os.path.splitext(os.path.basename(transcript['file_name']))
            filename = '{base_name}.srt'.format(base_name=base_name)
            content = Transcript.convert(transcript['content'], 'sjson', 'srt')
            mimetype = Transcript.mime_types['srt']
        except KeyError:
            raise Http404(u"Transcript not found for {}, lang: {}".format(block_id, lang))

        response = HttpResponse(content, content_type=mimetype)
        response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename.encode('utf-8'))

        return response
예제 #3
0
def save_video_transcript(edx_video_id, input_format, transcript_content,
                          language_code):
    """
    Saves a video transcript to the VAL and its content to the configured django storage(DS).

    Arguments:
        edx_video_id: A Video ID to associate the transcript.
        input_format: Input transcript format for content being passed.
        transcript_content: Content of the transcript file
        language_code: transcript language code

    Returns:
        A boolean indicating whether the transcript was saved or not.
    """
    try:
        # Convert the transcript into the 'sjson' and upload it to
        # configured transcript storage. For example, S3.
        sjson_subs = Transcript.convert(content=transcript_content,
                                        input_format=input_format,
                                        output_format=Transcript.SJSON)
        create_or_update_video_transcript(
            video_id=edx_video_id,
            language_code=language_code,
            metadata={
                'provider': TranscriptProvider.CUSTOM,
                'file_format': Transcript.SJSON,
                'language_code': language_code
            },
            file_data=ContentFile(sjson_subs),
        )
        result = True
    except (TranscriptsGenerationException, UnicodeDecodeError):
        result = False

    return result
예제 #4
0
 def convert_contentstore_subs_to_xblock(self):
     sjson_subs = Transcript.asset(
         self.location,
         self.default_subtitles_id,
         self.default_subtitles_langs[0]
         )
     return sjson_subs
예제 #5
0
def download_transcripts(request):
    """
    Passes to user requested transcripts file.

    Raises Http404 if unsuccessful.
    """
    locator = request.GET.get('locator')
    subs_id = request.GET.get('subs_id')
    if not locator:
        log.debug('GET data without "locator" property.')
        raise Http404

    try:
        item = _get_item(request, request.GET)
    except (InvalidKeyError, ItemNotFoundError):
        log.debug("Can't find item by locator.")
        raise Http404

    if item.category != 'video':
        log.debug('transcripts are supported only for video" modules.')
        raise Http404

    try:
        if not subs_id:
            raise NotFoundError

        filename = subs_id
        content_location = StaticContent.compute_location(
            item.location.course_key,
            'subs_{filename}.srt.sjson'.format(filename=filename),
        )
        sjson_transcript = contentstore().find(content_location).data
    except NotFoundError:
        # Try searching in VAL for the transcript as a last resort
        transcript = None
        if is_val_transcript_feature_enabled_for_course(item.location.course_key):
            transcript = get_video_transcript_content(
                language_code=u'en',
                edx_video_id=item.edx_video_id,
                youtube_id_1_0=item.youtube_id_1_0,
                html5_sources=item.html5_sources,
            )

        if not transcript:
            raise Http404

        filename = os.path.splitext(os.path.basename(transcript['file_name']))[0].encode('utf8')
        sjson_transcript = transcript['content']

    # convert sjson content into srt format.
    transcript_content = Transcript.convert(sjson_transcript, input_format='sjson', output_format='srt')
    if not transcript_content:
        raise Http404

    # Construct an HTTP response
    response = HttpResponse(transcript_content, content_type='application/x-subrip; charset=utf-8')
    response['Content-Disposition'] = 'attachment; filename="{filename}.srt"'.format(filename=filename)
    return response
예제 #6
0
def transcript_upload_handler(request, course_key_string):
    """
    View to upload a transcript file.

    Arguments:
        request: A WSGI request object
        course_key_string: Course key identifying a course

    Transcript file, edx video id and transcript language are required.
    Transcript file should be in SRT(SubRip) format.

    Returns
        - A 400 if any of the validation fails
        - A 404 if the corresponding feature flag is disabled
        - A 200 if transcript has been uploaded successfully
    """
    # Check whether the feature is available for this course.
    course_key = CourseKey.from_string(course_key_string)
    if not VideoTranscriptEnabledFlag.feature_enabled(course_key):
        return HttpResponseNotFound()

    error = validate_transcript_upload_data(data=request.POST, files=request.FILES)
    if error:
        response = JsonResponse({'error': error}, status=400)
    else:
        edx_video_id = request.POST['edx_video_id']
        language_code = request.POST['language_code']
        new_language_code = request.POST['new_language_code']
        transcript_file = request.FILES['file']
        try:
            # Convert SRT transcript into an SJSON format
            # and upload it to S3.
            sjson_subs = Transcript.convert(
                content=transcript_file.read(),
                input_format=Transcript.SRT,
                output_format=Transcript.SJSON
            )
            create_or_update_video_transcript(
                video_id=edx_video_id,
                language_code=language_code,
                metadata={
                    'provider': TranscriptProvider.CUSTOM,
                    'file_format': Transcript.SJSON,
                    'language_code': new_language_code
                },
                file_data=ContentFile(sjson_subs),
            )
            response = JsonResponse(status=201)
        except (TranscriptsGenerationException, UnicodeDecodeError):
            response = JsonResponse(
                {'error': _(u'There is a problem with this transcript file. Try to upload a different file.')},
                status=400
            )

    return response
def download_transcripts(request):
    """
    Passes to user requested transcripts file.

    Raises Http404 if unsuccessful.
    """
    locator = request.GET.get('locator')
    subs_id = request.GET.get('subs_id')
    if not locator:
        log.debug('GET data without "locator" property.')
        raise Http404

    try:
        item = _get_item(request, request.GET)
    except (InvalidKeyError, ItemNotFoundError):
        log.debug("Can't find item by locator.")
        raise Http404

    if item.category != 'video':
        log.debug('transcripts are supported only for video" modules.')
        raise Http404

    try:
        if not subs_id:
            raise NotFoundError

        filename = subs_id
        content_location = StaticContent.compute_location(
            item.location.course_key,
            'subs_{filename}.srt.sjson'.format(filename=filename),
        )
        input_format = Transcript.SJSON
        transcript_content = contentstore().find(content_location).data
    except NotFoundError:
        # Try searching in VAL for the transcript as a last resort
        transcript = None
        if is_val_transcript_feature_enabled_for_course(item.location.course_key):
            transcript = get_video_transcript_content(edx_video_id=item.edx_video_id, language_code=u'en')

        if not transcript:
            raise Http404

        name_and_extension = os.path.splitext(transcript['file_name'])
        filename, input_format = name_and_extension[0], name_and_extension[1][1:]
        transcript_content = transcript['content']

    # convert sjson content into srt format.
    transcript_content = Transcript.convert(transcript_content, input_format=input_format, output_format=Transcript.SRT)
    if not transcript_content:
        raise Http404

    # Construct an HTTP response
    response = HttpResponse(transcript_content, content_type='application/x-subrip; charset=utf-8')
    response['Content-Disposition'] = 'attachment; filename="{filename}.srt"'.format(filename=filename)
    return response
def upload_transcripts(request):
    """
    Upload transcripts for current module.

    returns: response dict::

        status: 'Success' and HTTP 200 or 'Error' and HTTP 400.
        subs: Value of uploaded and saved html5 sub field in video item.
    """
    error, validated_data = validate_transcript_upload_data(request)
    if error:
        response = JsonResponse({'status': error}, status=400)
    else:
        video = validated_data['video']
        edx_video_id = validated_data['edx_video_id']
        transcript_file = validated_data['transcript_file']
        # check if we need to create an external VAL video to associate the transcript
        # and save its ID on the video component.
        if not edx_video_id:
            edx_video_id = create_external_video(display_name=u'external video')
            video.edx_video_id = edx_video_id
            video.save_with_metadata(request.user)

        response = JsonResponse({'edx_video_id': edx_video_id, 'status': 'Success'}, status=200)

        try:
            # Convert 'srt' transcript into the 'sjson' and upload it to
            # configured transcript storage. For example, S3.
            sjson_subs = Transcript.convert(
                content=transcript_file.read(),
                input_format=Transcript.SRT,
                output_format=Transcript.SJSON
            )
            transcript_created = create_or_update_video_transcript(
                video_id=edx_video_id,
                language_code=u'en',
                metadata={
                    'provider': TranscriptProvider.CUSTOM,
                    'file_format': Transcript.SJSON,
                    'language_code': u'en'
                },
                file_data=ContentFile(sjson_subs),
            )

            if transcript_created is None:
                response = JsonResponse({'status': 'Invalid Video ID'}, status=400)

        except (TranscriptsGenerationException, UnicodeDecodeError):

            response = JsonResponse({
                'status': _(u'There is a problem with this transcript file. Try to upload a different file.')
            }, status=400)

    return response
예제 #9
0
def upload_transcripts(request):
    """
    Upload transcripts for current module.

    returns: response dict::

        status: 'Success' and HTTP 200 or 'Error' and HTTP 400.
        subs: Value of uploaded and saved html5 sub field in video item.
    """
    error, validated_data = validate_transcript_upload_data(request)
    if error:
        response = JsonResponse({'status': error}, status=400)
    else:
        video = validated_data['video']
        edx_video_id = validated_data['edx_video_id']
        transcript_file = validated_data['transcript_file']
        # check if we need to create an external VAL video to associate the transcript
        # and save its ID on the video component.
        if not edx_video_id:
            edx_video_id = create_external_video(display_name=u'external video')
            video.edx_video_id = edx_video_id
            video.save_with_metadata(request.user)

        response = JsonResponse({'edx_video_id': edx_video_id, 'status': 'Success'}, status=200)

        try:
            # Convert 'srt' transcript into the 'sjson' and upload it to
            # configured transcript storage. For example, S3.
            sjson_subs = Transcript.convert(
                content=transcript_file.read(),
                input_format=Transcript.SRT,
                output_format=Transcript.SJSON
            )
            transcript_created = create_or_update_video_transcript(
                video_id=edx_video_id,
                language_code=u'en',
                metadata={
                    'provider': TranscriptProvider.CUSTOM,
                    'file_format': Transcript.SJSON,
                    'language_code': u'en'
                },
                file_data=ContentFile(sjson_subs),
            )

            if transcript_created is None:
                response = JsonResponse({'status': 'Invalid Video ID'}, status=400)

        except (TranscriptsGenerationException, UnicodeDecodeError):

            response = JsonResponse({
                'status': _(u'There is a problem with this transcript file. Try to upload a different file.')
            }, status=400)

    return response
def transcript_upload_handler(request):
    """
    View to upload a transcript file.

    Arguments:
        request: A WSGI request object

    Transcript file, edx video id and transcript language are required.
    Transcript file should be in SRT(SubRip) format.

    Returns
        - A 400 if any of the validation fails
        - A 200 if transcript has been uploaded successfully
    """
    error = validate_transcript_upload_data(data=request.POST,
                                            files=request.FILES)
    if error:
        response = JsonResponse({'error': error}, status=400)
    else:
        edx_video_id = request.POST['edx_video_id']
        language_code = request.POST['language_code']
        new_language_code = request.POST['new_language_code']
        transcript_file = request.FILES['file']
        try:
            # Convert SRT transcript into an SJSON format
            # and upload it to S3.
            sjson_subs = Transcript.convert(
                content=transcript_file.read().decode('utf-8'),
                input_format=Transcript.SRT,
                output_format=Transcript.SJSON)
            create_or_update_video_transcript(
                video_id=edx_video_id,
                language_code=language_code,
                metadata={
                    'provider': TranscriptProvider.CUSTOM,
                    'file_format': Transcript.SJSON,
                    'language_code': new_language_code
                },
                file_data=ContentFile(sjson_subs),
            )
            response = JsonResponse(status=201)
        except (TranscriptsGenerationException, UnicodeDecodeError):
            response = JsonResponse(
                {
                    'error':
                    _(u'There is a problem with this transcript file. Try to upload a different file.'
                      )
                },
                status=400)

    return response
def transcript_download_handler(request):
    """
    JSON view handler to download a transcript.

    Arguments:
        request: WSGI request object

    Returns:
        - A 200 response with SRT transcript file attached.
        - A 400 if there is a validation error.
        - A 404 if there is no such transcript.
    """
    missing = [
        attr for attr in ['edx_video_id', 'language_code']
        if attr not in request.GET
    ]
    if missing:
        return JsonResponse(
            {
                'error':
                _(u'The following parameters are required: {missing}.').format(
                    missing=', '.join(missing))
            },
            status=400)

    edx_video_id = request.GET['edx_video_id']
    language_code = request.GET['language_code']
    transcript = get_video_transcript_data(video_id=edx_video_id,
                                           language_code=language_code)
    if transcript:
        name_and_extension = os.path.splitext(transcript['file_name'])
        basename, file_format = name_and_extension[0], name_and_extension[1][
            1:]
        transcript_filename = '{base_name}.{ext}'.format(base_name=basename,
                                                         ext=Transcript.SRT)
        transcript_content = Transcript.convert(content=transcript['content'],
                                                input_format=file_format,
                                                output_format=Transcript.SRT)
        # Construct an HTTP response
        response = HttpResponse(
            transcript_content,
            content_type=Transcript.mime_types[Transcript.SRT])
        response[
            'Content-Disposition'] = u'attachment; filename="{filename}"'.format(
                filename=transcript_filename)
    else:
        response = HttpResponseNotFound()

    return response
예제 #12
0
def transcript_upload_handler(request):
    """
    View to upload a transcript file.

    Arguments:
        request: A WSGI request object

    Transcript file, edx video id and transcript language are required.
    Transcript file should be in SRT(SubRip) format.

    Returns
        - A 400 if any of the validation fails
        - A 200 if transcript has been uploaded successfully
    """
    error = validate_transcript_upload_data(data=request.POST, files=request.FILES)
    if error:
        response = JsonResponse({'error': error}, status=400)
    else:
        edx_video_id = request.POST['edx_video_id']
        language_code = request.POST['language_code']
        new_language_code = request.POST['new_language_code']
        transcript_file = request.FILES['file']
        try:
            # Convert SRT transcript into an SJSON format
            # and upload it to S3.
            sjson_subs = Transcript.convert(
                content=transcript_file.read(),
                input_format=Transcript.SRT,
                output_format=Transcript.SJSON
            )
            create_or_update_video_transcript(
                video_id=edx_video_id,
                language_code=language_code,
                metadata={
                    'provider': TranscriptProvider.CUSTOM,
                    'file_format': Transcript.SJSON,
                    'language_code': new_language_code
                },
                file_data=ContentFile(sjson_subs),
            )
            response = JsonResponse(status=201)
        except (TranscriptsGenerationException, UnicodeDecodeError):
            response = JsonResponse(
                {'error': _(u'There is a problem with this transcript file. Try to upload a different file.')},
                status=400
            )

    return response
예제 #13
0
    def setUp(self):
        super(TestChooseTranscripts, self).setUp()

        # Create test transcript in contentstore
        self.chosen_html5_id = 'test_html5_subs'
        self.sjson_subs = Transcript.convert(SRT_TRANSCRIPT_CONTENT, Transcript.SRT, Transcript.SJSON)
        self.save_subs_to_store(json.loads(self.sjson_subs), self.chosen_html5_id)

        # Setup a VEDA produced video and persist `edx_video_id` in VAL.
        create_video({
            'edx_video_id': u'123-456-789',
            'status': 'upload',
            'client_video_id': u'Test Video',
            'duration': 0,
            'encoded_videos': [],
            'courses': [unicode(self.course.id)]
        })
예제 #14
0
def upload_transcript(request):
    """
    Upload a transcript file

    Arguments:
        request: A WSGI request object

        Transcript file in SRT format
    """
    edx_video_id = request.POST['edx_video_id']
    language_code = request.POST['language_code']
    new_language_code = request.POST['new_language_code']
    transcript_file = request.FILES['file']
    try:
        # Convert SRT transcript into an SJSON format
        # and upload it to S3.
        sjson_subs = Transcript.convert(
            content=transcript_file.read().decode('utf-8'),
            input_format=Transcript.SRT,
            output_format=Transcript.SJSON).encode()
        create_or_update_video_transcript(
            video_id=edx_video_id,
            language_code=language_code,
            metadata={
                'provider': TranscriptProvider.CUSTOM,
                'file_format': Transcript.SJSON,
                'language_code': new_language_code
            },
            file_data=ContentFile(sjson_subs),
        )
        response = JsonResponse(status=201)
    except (TranscriptsGenerationException, UnicodeDecodeError):
        LOGGER.error(
            "Unable to update transcript on edX video %s for language %s",
            edx_video_id, new_language_code)
        response = JsonResponse(
            {
                'error':
                _('There is a problem with this transcript file. Try to upload a different file.'
                  )
            },
            status=400)
    finally:
        LOGGER.info("Updated transcript on edX video %s for language %s",
                    edx_video_id, new_language_code)
    return response
예제 #15
0
    def setUp(self):
        super(TestChooseTranscripts, self).setUp()

        # Create test transcript in contentstore
        self.chosen_html5_id = 'test_html5_subs'
        self.sjson_subs = Transcript.convert(SRT_TRANSCRIPT_CONTENT, Transcript.SRT, Transcript.SJSON)
        self.save_subs_to_store(json.loads(self.sjson_subs), self.chosen_html5_id)

        # Setup a VEDA produced video and persist `edx_video_id` in VAL.
        create_video({
            'edx_video_id': u'123-456-789',
            'status': 'upload',
            'client_video_id': u'Test Video',
            'duration': 0,
            'encoded_videos': [],
            'courses': [six.text_type(self.course.id)]
        })
예제 #16
0
    def setUp(self):
        super(TestRenameTranscripts, self).setUp()

        # Create test transcript in contentstore and update item's sub.
        self.item.sub = 'test_video_subs'
        self.sjson_subs = Transcript.convert(SRT_TRANSCRIPT_CONTENT, Transcript.SRT, Transcript.SJSON)
        self.save_subs_to_store(json.loads(self.sjson_subs), self.item.sub)
        modulestore().update_item(self.item, self.user.id)

        # Setup a VEDA produced video and persist `edx_video_id` in VAL.
        create_video({
            'edx_video_id': u'123-456-789',
            'status': 'upload',
            'client_video_id': u'Test Video',
            'duration': 0,
            'encoded_videos': [],
            'courses': [unicode(self.course.id)]
        })
예제 #17
0
    def setUp(self):
        super().setUp()

        # Create test transcript in contentstore and update item's sub.
        self.item.sub = 'test_video_subs'
        self.sjson_subs = Transcript.convert(SRT_TRANSCRIPT_CONTENT, Transcript.SRT, Transcript.SJSON)
        self.save_subs_to_store(json.loads(self.sjson_subs), self.item.sub)
        modulestore().update_item(self.item, self.user.id)

        # Setup a VEDA produced video and persist `edx_video_id` in VAL.
        create_video({
            'edx_video_id': '123-456-789',
            'status': 'upload',
            'client_video_id': 'Test Video',
            'duration': 0,
            'encoded_videos': [],
            'courses': [str(self.course.id)]
        })
예제 #18
0
    def get(self, request, course, *args, **kwargs):
        block_id = kwargs['block_id']
        lang = kwargs['lang']

        usage_key = BlockUsageLocator(course.id,
                                      block_type='video',
                                      block_id=block_id)
        video_descriptor = modulestore().get_item(usage_key)
        feature_enabled = is_val_transcript_feature_enabled_for_course(
            usage_key.course_key)
        try:
            transcripts = video_descriptor.get_transcripts_info(
                include_val_transcripts=feature_enabled)
            content, filename, mimetype = video_descriptor.get_transcript(
                transcripts, lang=lang)
        except (ValueError, NotFoundError):
            # Fallback mechanism for edx-val transcripts
            transcript = None
            if feature_enabled:
                transcript = get_video_transcript_content(
                    language_code=lang,
                    edx_video_id=video_descriptor.edx_video_id,
                    youtube_id_1_0=video_descriptor.youtube_id_1_0,
                    html5_sources=video_descriptor.html5_sources,
                )

            if not transcript:
                raise Http404(u'Transcript not found for {}, lang: {}'.format(
                    block_id, lang))

            base_name, __ = os.path.splitext(
                os.path.basename(transcript['file_name']))
            filename = '{base_name}.srt'.format(base_name=base_name)
            content = Transcript.convert(transcript['content'], 'sjson', 'srt')
            mimetype = Transcript.mime_types['srt']
        except KeyError:
            raise Http404(u"Transcript not found for {}, lang: {}".format(
                block_id, lang))

        response = HttpResponse(content, content_type=mimetype)
        response['Content-Disposition'] = 'attachment; filename="{}"'.format(
            filename.encode('utf-8'))

        return response
예제 #19
0
    def test_transcript_upload_success(self, edx_video_id, include_bom):
        """
        Tests transcript file upload to video component works as
        expected in case of following:

         1. External video component
         2. VEDA produced video component
         3. Transcript content containing BOM character
        """
        # In case of an external video component, the `edx_video_id` must be empty
        # and VEDA produced video component will have `edx_video_id` set to VAL video ID.
        self.item.edx_video_id = edx_video_id
        modulestore().update_item(self.item, self.user.id)

        # Upload a transcript
        transcript_file = self.bom_srt_file if include_bom else self.good_srt_file
        response = self.upload_transcript(self.video_usage_key,
                                          transcript_file, '')

        # Verify the response
        self.assert_response(response,
                             expected_status_code=200,
                             expected_message='Success')

        # Verify the `edx_video_id` on the video component
        json_response = json.loads(response.content.decode('utf-8'))
        expected_edx_video_id = edx_video_id if edx_video_id else json_response[
            'edx_video_id']
        video = modulestore().get_item(self.video_usage_key)
        self.assertEqual(video.edx_video_id, expected_edx_video_id)

        # Verify transcript content
        actual_transcript = get_video_transcript_content(video.edx_video_id,
                                                         language_code=u'en')
        actual_sjson_content = json.loads(
            actual_transcript['content'].decode('utf-8'))
        expected_sjson_content = json.loads(
            Transcript.convert(self.contents['good'],
                               input_format=Transcript.SRT,
                               output_format=Transcript.SJSON))
        self.assertDictEqual(actual_sjson_content, expected_sjson_content)
예제 #20
0
def transcript_download_handler(request):
    """
    JSON view handler to download a transcript.

    Arguments:
        request: WSGI request object

    Returns:
        - A 200 response with SRT transcript file attached.
        - A 400 if there is a validation error.
        - A 404 if there is no such transcript.
    """
    missing = [attr for attr in ['edx_video_id', 'language_code'] if attr not in request.GET]
    if missing:
        return JsonResponse(
            {'error': _(u'The following parameters are required: {missing}.').format(missing=', '.join(missing))},
            status=400
        )

    edx_video_id = request.GET['edx_video_id']
    language_code = request.GET['language_code']
    transcript = get_video_transcript_data(video_id=edx_video_id, language_code=language_code)
    if transcript:
        name_and_extension = os.path.splitext(transcript['file_name'])
        basename, file_format = name_and_extension[0], name_and_extension[1][1:]
        transcript_filename = '{base_name}.{ext}'.format(base_name=basename.encode('utf8'), ext=Transcript.SRT)
        transcript_content = Transcript.convert(
            content=transcript['content'],
            input_format=file_format,
            output_format=Transcript.SRT
        )
        # Construct an HTTP response
        response = HttpResponse(transcript_content, content_type=Transcript.mime_types[Transcript.SRT])
        response['Content-Disposition'] = 'attachment; filename="{filename}"'.format(filename=transcript_filename)
    else:
        response = HttpResponseNotFound()

    return response
예제 #21
0
def save_video_transcript(edx_video_id, input_format, transcript_content, language_code):
    """
    Saves a video transcript to the VAL and its content to the configured django storage(DS).

    Arguments:
        edx_video_id: A Video ID to associate the transcript.
        input_format: Input transcript format for content being passed.
        transcript_content: Content of the transcript file
        language_code: transcript language code

    Returns:
        A boolean indicating whether the transcript was saved or not.
    """
    try:
        # Convert the transcript into the 'sjson' and upload it to
        # configured transcript storage. For example, S3.
        sjson_subs = Transcript.convert(
            content=transcript_content,
            input_format=input_format,
            output_format=Transcript.SJSON
        )
        create_or_update_video_transcript(
            video_id=edx_video_id,
            language_code=language_code,
            metadata={
                'provider': TranscriptProvider.CUSTOM,
                'file_format': Transcript.SJSON,
                'language_code': language_code
            },
            file_data=ContentFile(sjson_subs),
        )
        result = True
    except (TranscriptsGenerationException, UnicodeDecodeError):
        result = False

    return result
예제 #22
0
    def test_transcript_upload_success(self, edx_video_id, include_bom):
        """
        Tests transcript file upload to video component works as
        expected in case of following:

         1. External video component
         2. VEDA produced video component
         3. Transcript content containing BOM character
        """
        # In case of an external video component, the `edx_video_id` must be empty
        # and VEDA produced video component will have `edx_video_id` set to VAL video ID.
        self.item.edx_video_id = edx_video_id
        modulestore().update_item(self.item, self.user.id)

        # Upload a transcript
        transcript_file = self.bom_srt_file if include_bom else self.good_srt_file
        response = self.upload_transcript(self.video_usage_key, transcript_file, '')

        # Verify the response
        self.assert_response(response, expected_status_code=200, expected_message='Success')

        # Verify the `edx_video_id` on the video component
        json_response = json.loads(response.content)
        expected_edx_video_id = edx_video_id if edx_video_id else json_response['edx_video_id']
        video = modulestore().get_item(self.video_usage_key)
        self.assertEqual(video.edx_video_id, expected_edx_video_id)

        # Verify transcript content
        actual_transcript = get_video_transcript_content(video.edx_video_id, language_code=u'en')
        actual_sjson_content = json.loads(actual_transcript['content'])
        expected_sjson_content = json.loads(Transcript.convert(
            self.contents['good'],
            input_format=Transcript.SRT,
            output_format=Transcript.SJSON
        ))
        self.assertDictEqual(actual_sjson_content, expected_sjson_content)
예제 #23
0
TEST_DATA_CONTENTSTORE = copy.deepcopy(settings.CONTENTSTORE)
TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4().hex

SRT_TRANSCRIPT_CONTENT = """0
00:00:10,500 --> 00:00:13,000
Elephant's Dream

1
00:00:15,000 --> 00:00:18,000
At the left we can see...

"""

SJSON_TRANSCRIPT_CONTENT = Transcript.convert(
    SRT_TRANSCRIPT_CONTENT,
    Transcript.SRT,
    Transcript.SJSON,
)


@override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE)
class BaseTranscripts(CourseTestCase):
    """Base test class for transcripts tests."""

    def clear_subs_content(self):
        """Remove, if transcripts content exists."""
        for youtube_id in self.get_youtube_ids().values():
            filename = 'subs_{0}.srt.sjson'.format(youtube_id)
            content_location = StaticContent.compute_location(self.course.id, filename)
            try:
                content = contentstore().find(content_location)
예제 #24
0
TEST_DATA_CONTENTSTORE['DOC_STORE_CONFIG']['db'] = 'test_xcontent_%s' % uuid4(
).hex

SRT_TRANSCRIPT_CONTENT = u"""0
00:00:10,500 --> 00:00:13,000
Elephant's Dream

1
00:00:15,000 --> 00:00:18,000
At the left we can see...

"""

SJSON_TRANSCRIPT_CONTENT = Transcript.convert(
    SRT_TRANSCRIPT_CONTENT,
    Transcript.SRT,
    Transcript.SJSON,
)


@override_settings(CONTENTSTORE=TEST_DATA_CONTENTSTORE)
class BaseTranscripts(CourseTestCase):
    """Base test class for transcripts tests."""
    def clear_subs_content(self):
        """Remove, if transcripts content exists."""
        for youtube_id in self.get_youtube_ids().values():
            filename = 'subs_{0}.srt.sjson'.format(youtube_id)
            content_location = StaticContent.compute_location(
                self.course.id, filename)
            try:
                content = contentstore().find(content_location)