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
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
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 convert_contentstore_subs_to_xblock(self): sjson_subs = Transcript.asset( self.location, self.default_subtitles_id, self.default_subtitles_langs[0] ) return sjson_subs
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
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
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
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 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)] })
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 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)] })
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)] })
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)] })
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
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)
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
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_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)
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)
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)