def save_transcript_to_storage(command_run, edx_video_id, language_code, transcript_content, file_format, force_update): """ Pushes a given transcript's data to django storage. Arguments: command_run: A positive integer indicating the current run edx_video_id: video ID language_code: language code transcript_content: content of the transcript file_format: format of the transcript file force_update: tells whether it needs to perform force update in case of an existing transcript for the given video. """ transcript_present = is_transcript_available(video_id=edx_video_id, language_code=language_code) if transcript_present and force_update: create_or_update_video_transcript(edx_video_id, language_code, dict({'file_format': file_format}), ContentFile(transcript_content)) elif not transcript_present: create_video_transcript(edx_video_id, language_code, file_format, ContentFile(transcript_content)) else: LOGGER.info( "[%s] [run=%s] [do-not-override-existing-transcript] [edx_video_id=%s] [language_code=%s]", MIGRATION_LOGS_PREFIX, command_run, edx_video_id, language_code)
def save_transcript_to_storage(command_run, edx_video_id, language_code, transcript_content, file_format, force_update): """ Pushes a given transcript's data to django storage. Arguments: command_run: A positive integer indicating the current run edx_video_id: video ID language_code: language code transcript_content: content of the transcript file_format: format of the transcript file force_update: tells whether it needs to perform force update in case of an existing transcript for the given video. """ transcript_present = is_transcript_available(video_id=edx_video_id, language_code=language_code) if transcript_present and force_update: create_or_update_video_transcript( edx_video_id, language_code, dict({'file_format': file_format}), ContentFile(transcript_content) ) elif not transcript_present: create_video_transcript( edx_video_id, language_code, file_format, ContentFile(transcript_content) ) else: LOGGER.info( "[%s] [run=%s] [do-not-override-existing-transcript] [edx_video_id=%s] [language_code=%s]", MIGRATION_LOGS_PREFIX, command_run, edx_video_id, language_code )
def test_transcript_delete_handler(self, is_staff, is_course_staff): """ Tests that transcript delete handler works as expected with combinations of staff and course's staff. """ # Setup user's roles self.user.is_staff = is_staff self.user.save() course_staff_role = CourseStaffRole(self.course.id) if is_course_staff: course_staff_role.add_users(self.user) else: course_staff_role.remove_users(self.user) # Assert the user role self.assertEqual(self.user.is_staff, is_staff) self.assertEqual(CourseStaffRole(self.course.id).has_user(self.user), is_course_staff) video_id, language_code = u'1234', u'en' # Create a real transcript in VAL. api.create_or_update_video_transcript( video_id=video_id, language_code=language_code, metadata={'file_format': 'srt'} ) # Make request to transcript deletion handler response = self.client.delete(self.get_url_for_course_key( self.course.id, edx_video_id=video_id, language_code=language_code )) self.assertEqual(response.status_code, 200) self.assertFalse(api.get_video_transcript_data(video_id=video_id, language_code=language_code))
def save_transcript_to_storage(edx_video_id, language_code, transcript_content, file_format, force_update): """ Pushes a given transcript's data to django storage. Arguments: edx_video_id: video ID language_code: language code transcript_content: content of the transcript file_format: format of the transcript file force_update: tells whether it needs to perform force update in case of an existing transcript for the given video. """ transcript_present = is_transcript_available(video_id=edx_video_id, language_code=language_code) if transcript_present and force_update: create_or_update_video_transcript( edx_video_id, language_code, dict({'file_format': file_format}), ContentFile(transcript_content) ) elif not transcript_present: create_video_transcript( edx_video_id, language_code, file_format, ContentFile(transcript_content) )
def post(self, request): """ Creates a video transcript instance with the given information. Arguments: request: A WSGI request. """ attrs = ('video_id', 'name', 'language_code', 'provider', 'file_format') missing = [attr for attr in attrs if attr not in request.data] if missing: LOGGER.warn('[VAL] Required transcript params are missing. %s', ' and '.join(missing)) return Response( status=status.HTTP_400_BAD_REQUEST, data=dict(message=u'{missing} must be specified.'.format( missing=' and '.join(missing)))) video_id = request.data['video_id'] language_code = request.data['language_code'] transcript_name = request.data['name'] provider = request.data['provider'] file_format = request.data['file_format'] supported_formats = sorted(dict(TranscriptFormat.CHOICES).keys()) if file_format not in supported_formats: message = ( u'"{format}" transcript file type is not supported. Supported formats are "{supported_formats}"' ).format(format=file_format, supported_formats=supported_formats) return Response(status=status.HTTP_400_BAD_REQUEST, data={'message': message}) supported_providers = sorted( dict(TranscriptProviderType.CHOICES).keys()) if provider not in supported_providers: message = ( u'"{provider}" provider is not supported. Supported transcription providers are "{supported_providers}"' ).format(provider=provider, supported_providers=supported_providers) return Response(status=status.HTTP_400_BAD_REQUEST, data={'message': message}) transcript = VideoTranscript.get_or_none(video_id, language_code) if transcript is None: create_or_update_video_transcript(video_id, language_code, metadata={ 'provider': provider, 'file_name': transcript_name, 'file_format': file_format }) response = Response(status=status.HTTP_200_OK) else: message = ( u'Can not override existing transcript for video "{video_id}" and language code "{language}".' ).format(video_id=video_id, language=language_code) response = Response(status=status.HTTP_400_BAD_REQUEST, data={'message': message}) return response
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
def test_transcript_delete_handler(self, is_staff, is_course_staff): """ Tests that transcript delete handler works as expected with combinations of staff and course's staff. """ # Setup user's roles self.user.is_staff = is_staff self.user.save() course_staff_role = CourseStaffRole(self.course.id) if is_course_staff: course_staff_role.add_users(self.user) else: course_staff_role.remove_users(self.user) # Assert the user role self.assertEqual(self.user.is_staff, is_staff) self.assertEqual( CourseStaffRole(self.course.id).has_user(self.user), is_course_staff) video_id, language_code = u'1234', u'en' # Create a real transcript in VAL. api.create_or_update_video_transcript(video_id=video_id, language_code=language_code, metadata={'file_format': 'srt'}) # Make request to transcript deletion handler response = self.client.delete( self.get_url_for_course_key(self.course.id, edx_video_id=video_id, language_code=language_code)) self.assertEqual(response.status_code, 200) self.assertFalse( api.get_video_transcript_data(video_id=video_id, language_code=language_code))
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 post(self, request): """ Creates a video transcript instance with the given information. Arguments: request: A WSGI request. """ attrs = ('video_id', 'name', 'language_code', 'provider', 'file_format') missing = [attr for attr in attrs if attr not in request.data] if missing: LOGGER.warn( '[VAL] Required transcript params are missing. %s', ' and '.join(missing) ) return Response( status=status.HTTP_400_BAD_REQUEST, data=dict(message=u'{missing} must be specified.'.format(missing=' and '.join(missing))) ) video_id = request.data['video_id'] language_code = request.data['language_code'] transcript_name = request.data['name'] provider = request.data['provider'] file_format = request.data['file_format'] supported_formats = sorted(dict(TranscriptFormat.CHOICES).keys()) if file_format not in supported_formats: message = ( u'"{format}" transcript file type is not supported. Supported formats are "{supported_formats}"' ).format(format=file_format, supported_formats=supported_formats) return Response(status=status.HTTP_400_BAD_REQUEST, data={'message': message}) supported_providers = sorted(dict(TranscriptProviderType.CHOICES).keys()) if provider not in supported_providers: message = ( u'"{provider}" provider is not supported. Supported transcription providers are "{supported_providers}"' ).format(provider=provider, supported_providers=supported_providers) return Response(status=status.HTTP_400_BAD_REQUEST, data={'message': message}) transcript = VideoTranscript.get_or_none(video_id, language_code) if transcript is None: create_or_update_video_transcript(video_id, language_code, metadata={ 'provider': provider, 'file_name': transcript_name, 'file_format': file_format }) response = Response(status=status.HTTP_200_OK) else: message = ( u'Can not override existing transcript for video "{video_id}" and language code "{language}".' ).format(video_id=video_id, language=language_code) response = Response(status=status.HTTP_400_BAD_REQUEST, data={'message': message}) 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_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
def save_transcript_to_storage(edx_video_id, language_code, transcript_content, file_format=Transcript.SJSON, force_update=False): """ Pushes a given transcript's data to django storage. """ try: result = None edx_video_id = clean_video_id(edx_video_id) if force_update: result = create_or_update_video_transcript( edx_video_id, language_code, dict({'file_format': file_format}), ContentFile(transcript_content)) LOGGER.info( "[Transcript migration] save_transcript_to_storage %s for %s with create_or_update method", True if result else False, edx_video_id) else: result = create_video_transcript(edx_video_id, language_code, file_format, ContentFile(transcript_content)) LOGGER.info( "[Transcript migration] save_transcript_to_storage %s for %s with create method", result, edx_video_id) return result except ValCannotCreateError as err: LOGGER.exception( "[Transcript migration] save_transcript_to_storage_failed: %s", err) raise
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
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 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 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
def save_transcript_to_storage( edx_video_id, language_code, transcript_content, file_format=Transcript.SJSON, force_update=False ): """ Pushes a given transcript's data to django storage. """ try: result = None edx_video_id = clean_video_id(edx_video_id) if force_update: result = create_or_update_video_transcript( edx_video_id, language_code, dict({'file_format': file_format}), ContentFile(transcript_content) ) LOGGER.info("[Transcript migration] save_transcript_to_storage %s for %s with create_or_update method", True if result else False, edx_video_id) else: result = create_video_transcript( edx_video_id, language_code, file_format, ContentFile(transcript_content) ) LOGGER.info( "[Transcript migration] save_transcript_to_storage %s for %s with create method", result, edx_video_id ) return result except ValCannotCreateError as err: LOGGER.exception("[Transcript migration] save_transcript_to_storage_failed: %s", err) raise
def studio_transcript(self, request, dispatch): """ Entry point for Studio transcript handlers. Dispatches: /translation/[language_id] - language_id sould be in url. `translation` dispatch support following HTTP methods: `POST`: Upload srt file. Check possibility of generation of proper sjson files. For now, it works only for self.transcripts, not for `en`. Do not update self.transcripts, as fields are updated on save in Studio. `GET: Return filename from storage. SRT format is sent back on success. Filename should be in GET dict. We raise all exceptions right in Studio: NotFoundError: Video or asset was deleted from module/contentstore, but request came later. Seems impossible to be raised. module_render.py catches NotFoundErrors from here. /translation POST: TypeError: Unjsonable filename or content. TranscriptsGenerationException, TranscriptException: no SRT extension or not parse-able by PySRT UnicodeDecodeError: non-UTF8 uploaded file content encoding. """ _ = self.runtime.service(self, "i18n").ugettext if dispatch.startswith('translation'): if request.method == 'POST': error = self.validate_transcript_upload_data(data=request.POST) if error: response = Response(json={'error': error}, status=400) else: edx_video_id = clean_video_id(request.POST['edx_video_id']) language_code = request.POST['language_code'] new_language_code = request.POST['new_language_code'] transcript_file = request.POST['file'].file if not edx_video_id: # Back-populate the video ID for an external video. # pylint: disable=attribute-defined-outside-init self.edx_video_id = edx_video_id = create_external_video(display_name=u'external video') 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={ 'file_format': Transcript.SJSON, 'language_code': new_language_code }, file_data=ContentFile(sjson_subs), ) payload = { 'edx_video_id': edx_video_id, 'language_code': new_language_code } response = Response(json.dumps(payload), status=201) except (TranscriptsGenerationException, UnicodeDecodeError): response = Response( json={ 'error': _( u'There is a problem with this transcript file. Try to upload a different file.' ) }, status=400 ) elif request.method == 'DELETE': request_data = request.json if 'lang' not in request_data or 'edx_video_id' not in request_data: return Response(status=400) language = request_data['lang'] edx_video_id = clean_video_id(request_data['edx_video_id']) if edx_video_id: delete_video_transcript(video_id=edx_video_id, language_code=language) if language == u'en': # remove any transcript file from content store for the video ids possible_sub_ids = [ self.sub, # pylint: disable=access-member-before-definition self.youtube_id_1_0 ] + get_html5_ids(self.html5_sources) for sub_id in possible_sub_ids: remove_subs_from_store(sub_id, self, language) # update metadata as `en` can also be present in `transcripts` field remove_subs_from_store(self.transcripts.pop(language, None), self, language) # also empty `sub` field self.sub = '' # pylint: disable=attribute-defined-outside-init else: remove_subs_from_store(self.transcripts.pop(language, None), self, language) return Response(status=200) elif request.method == 'GET': language = request.GET.get('language_code') if not language: return Response(json={'error': _(u'Language is required.')}, status=400) try: transcript_content, transcript_name, mime_type = get_transcript( video=self, lang=language, output_format=Transcript.SRT ) response = Response(transcript_content, headerlist=[ ( 'Content-Disposition', 'attachment; filename="{}"'.format( transcript_name.encode('utf8') if six.PY2 else transcript_name ) ), ('Content-Language', language), ('Content-Type', mime_type) ]) except (UnicodeDecodeError, TranscriptsGenerationException, NotFoundError): response = Response(status=404) else: # Any other HTTP method is not allowed. response = Response(status=404) else: # unknown dispatch log.debug("Dispatch is not allowed") response = Response(status=404) return response
def studio_transcript(self, request, dispatch): """ Entry point for Studio transcript handlers. Dispatches: /translation/[language_id] - language_id sould be in url. `translation` dispatch support following HTTP methods: `POST`: Upload srt file. Check possibility of generation of proper sjson files. For now, it works only for self.transcripts, not for `en`. Do not update self.transcripts, as fields are updated on save in Studio. `GET: Return filename from storage. SRT format is sent back on success. Filename should be in GET dict. We raise all exceptions right in Studio: NotFoundError: Video or asset was deleted from module/contentstore, but request came later. Seems impossible to be raised. module_render.py catches NotFoundErrors from here. /translation POST: TypeError: Unjsonable filename or content. TranscriptsGenerationException, TranscriptException: no SRT extension or not parse-able by PySRT UnicodeDecodeError: non-UTF8 uploaded file content encoding. """ _ = self.runtime.service(self, "i18n").ugettext if dispatch.startswith('translation'): if request.method == 'POST': error = self.validate_transcript_upload_data(data=request.POST) if error: response = Response(json={'error': error}, status=400) else: edx_video_id = clean_video_id(request.POST['edx_video_id']) language_code = request.POST['language_code'] new_language_code = request.POST['new_language_code'] transcript_file = request.POST['file'].file if not edx_video_id: # Back-populate the video ID for an external video. # pylint: disable=attribute-defined-outside-init self.edx_video_id = edx_video_id = create_external_video(display_name=u'external video') 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={ 'file_format': Transcript.SJSON, 'language_code': new_language_code }, file_data=ContentFile(sjson_subs), ) payload = { 'edx_video_id': edx_video_id, 'language_code': new_language_code } response = Response(json.dumps(payload), status=201) except (TranscriptsGenerationException, UnicodeDecodeError): response = Response( json={ 'error': _( u'There is a problem with this transcript file. Try to upload a different file.' ) }, status=400 ) elif request.method == 'DELETE': request_data = request.json if 'lang' not in request_data or 'edx_video_id' not in request_data: return Response(status=400) language = request_data['lang'] edx_video_id = clean_video_id(request_data['edx_video_id']) if edx_video_id: delete_video_transcript(video_id=edx_video_id, language_code=language) if language == u'en': # remove any transcript file from content store for the video ids possible_sub_ids = [ self.sub, # pylint: disable=access-member-before-definition self.youtube_id_1_0 ] + get_html5_ids(self.html5_sources) for sub_id in possible_sub_ids: remove_subs_from_store(sub_id, self, language) # update metadata as `en` can also be present in `transcripts` field remove_subs_from_store(self.transcripts.pop(language, None), self, language) # also empty `sub` field self.sub = '' # pylint: disable=attribute-defined-outside-init else: remove_subs_from_store(self.transcripts.pop(language, None), self, language) return Response(status=200) elif request.method == 'GET': language = request.GET.get('language_code') if not language: return Response(json={'error': _(u'Language is required.')}, status=400) try: transcript_content, transcript_name, mime_type = get_transcript( video=self, lang=language, output_format=Transcript.SRT ) response = Response(transcript_content, headerlist=[ ('Content-Disposition', 'attachment; filename="{}"'.format(transcript_name.encode('utf8'))), ('Content-Language', language), ('Content-Type', mime_type) ]) except (UnicodeDecodeError, TranscriptsGenerationException, NotFoundError): response = Response(status=404) else: # Any other HTTP method is not allowed. response = Response(status=404) else: # unknown dispatch log.debug("Dispatch is not allowed") response = Response(status=404) return response