def test_success_generating_subs(self): youtube_subs = { 0.5: 'JMD_ifUUfsU', 1.0: 'hI10vDNYz4M', 2.0: 'AKqURZnYqpk' } srt_filedata = textwrap.dedent(""" 1 00:00:10,500 --> 00:00:13,000 Elephant's Dream 2 00:00:15,000 --> 00:00:18,000 At the left we can see... """) self.clear_subs_content(youtube_subs) # Check transcripts_utils.TranscriptsGenerationException not thrown. # Also checks that uppercase file extensions are supported. transcripts_utils.generate_subs_from_source(youtube_subs, 'SRT', srt_filedata, self.course) # Check assets status after importing subtitles. for subs_id in youtube_subs.values(): filename = 'subs_{0}.srt.sjson'.format(subs_id) content_location = StaticContent.compute_location( self.course.id, filename ) self.assertTrue(contentstore().find(content_location)) self.clear_subs_content(youtube_subs)
def test_success_generating_subs(self): youtube_subs = { 0.5: 'JMD_ifUUfsU', 1.0: 'hI10vDNYz4M', 2.0: 'AKqURZnYqpk' } srt_filedata = textwrap.dedent(""" 1 00:00:10,500 --> 00:00:13,000 Elephant's Dream 2 00:00:15,000 --> 00:00:18,000 At the left we can see... """) self.clear_subs_content(youtube_subs) # Check transcripts_utils.TranscriptsGenerationException not thrown. # Also checks that uppercase file extensions are supported. transcripts_utils.generate_subs_from_source(youtube_subs, 'SRT', srt_filedata, self.course) # Check assets status after importing subtitles. for subs_id in youtube_subs.values(): filename = 'subs_{0}.srt.sjson'.format(subs_id) content_location = StaticContent.compute_location( self.course.id, filename) self.assertTrue(contentstore().find(content_location)) self.clear_subs_content(youtube_subs)
def test_fail_bad_subs_filedata(self): youtube_subs = {0.5: "JMD_ifUUfsU", 1.0: "hI10vDNYz4M", 2.0: "AKqURZnYqpk"} srt_filedata = """BAD_DATA""" with self.assertRaises(transcripts_utils.TranscriptsGenerationException) as cm: transcripts_utils.generate_subs_from_source(youtube_subs, "srt", srt_filedata, self.course) exception_message = cm.exception.message self.assertEqual(exception_message, "Something wrong with SubRip transcripts file during parsing.")
def test_fail_bad_subs_filedata(self): youtube_subs = { 0.5: 'JMD_ifUUfsU', 1.0: 'hI10vDNYz4M', 2.0: 'AKqURZnYqpk' } srt_filedata = """BAD_DATA""" with self.assertRaises(transcripts_utils.TranscriptsGenerationException) as cm: transcripts_utils.generate_subs_from_source(youtube_subs, 'srt', srt_filedata, self.course) exception_message = text_type(cm.exception) self.assertEqual(exception_message, "Something wrong with SubRip transcripts file during parsing.")
def test_fail_bad_subs_type(self): youtube_subs = {0.5: "JMD_ifUUfsU", 1.0: "hI10vDNYz4M", 2.0: "AKqURZnYqpk"} srt_filedata = textwrap.dedent( """ 1 00:00:10,500 --> 00:00:13,000 Elephant's Dream 2 00:00:15,000 --> 00:00:18,000 At the left we can see... """ ) with self.assertRaises(transcripts_utils.TranscriptsGenerationException) as cm: transcripts_utils.generate_subs_from_source(youtube_subs, "BAD_FORMAT", srt_filedata, self.course) exception_message = cm.exception.message self.assertEqual(exception_message, "We support only SubRip (*.srt) transcripts format.")
def test_fail_bad_subs_type(self): youtube_subs = { 0.5: 'JMD_ifUUfsU', 1.0: 'hI10vDNYz4M', 2.0: 'AKqURZnYqpk' } srt_filedata = textwrap.dedent(""" 1 00:00:10,500 --> 00:00:13,000 Elephant's Dream 2 00:00:15,000 --> 00:00:18,000 At the left we can see... """) with self.assertRaises(transcripts_utils.TranscriptsGenerationException) as cm: transcripts_utils.generate_subs_from_source(youtube_subs, 'BAD_FORMAT', srt_filedata, self.course) exception_message = text_type(cm.exception) self.assertEqual(exception_message, "We support only SubRip (*.srt) transcripts format.")
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. """ response = { 'status': 'Unknown server error', 'subs': '', } locator = request.POST.get('locator') if not locator: return error_response(response, 'POST data without "locator" form data.') try: item = _get_item(request, request.POST) except (ItemNotFoundError, InvalidLocationError, InsufficientSpecificationError): return error_response(response, "Can't find item by locator.") if 'file' not in request.FILES: return error_response(response, 'POST data without "file" form data.') video_list = request.POST.get('video_list') if not video_list: return error_response(response, 'POST data without video names.') try: video_list = json.loads(video_list) except ValueError: return error_response(response, 'Invalid video_list JSON.') source_subs_filedata = request.FILES['file'].read().decode('utf8') source_subs_filename = request.FILES['file'].name if '.' not in source_subs_filename: return error_response(response, "Undefined file extension.") basename = os.path.basename(source_subs_filename) source_subs_name = os.path.splitext(basename)[0] source_subs_ext = os.path.splitext(basename)[1][1:] if item.category != 'video': return error_response(response, 'Transcripts are supported only for "video" modules.') # Allow upload only if any video link is presented if video_list: sub_attr = source_subs_name try: # Generate and save for 1.0 speed, will create subs_sub_attr.srt.sjson subtitles file in storage. generate_subs_from_source({1: sub_attr}, source_subs_ext, source_subs_filedata, item) except TranscriptsGenerationException as e: return error_response(response, e.message) statuses = {} for video_dict in video_list: video_name = video_dict['video'] # We are creating transcripts for every video source, # for the case that in future, some of video sources can be deleted. statuses[video_name] = copy_or_rename_transcript(video_name, sub_attr, item, user=request.user) try: # updates item.sub with `video_name` if it is successful. copy_or_rename_transcript(video_name, sub_attr, item, user=request.user) selected_name = video_name # name to write to item.sub field, chosen at random. except NotFoundError: # subtitles file `sub_attr` is not presented in the system. Nothing to copy or rename. return error_response(response, "Can't find transcripts in storage for {}".format(sub_attr)) item.sub = selected_name # write one of new subtitles names to item.sub attribute. item.save_with_metadata(request.user) response['subs'] = item.sub response['status'] = 'Success' else: return error_response(response, 'Empty video sources.') return JsonResponse(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. """ response = { 'status': 'Unknown server error', 'subs': '', } locator = request.POST.get('locator') if not locator: return error_response(response, 'POST data without "locator" form data.') try: item = _get_item(request, request.POST) except (InvalidKeyError, ItemNotFoundError): return error_response(response, "Can't find item by locator.") if 'transcript-file' not in request.FILES: return error_response(response, 'POST data without "file" form data.') video_list = request.POST.get('video_list') if not video_list: return error_response(response, 'POST data without video names.') try: video_list = json.loads(video_list) except ValueError: return error_response(response, 'Invalid video_list JSON.') source_subs_filedata = request.FILES['transcript-file'].read().decode( 'utf8') source_subs_filename = request.FILES['transcript-file'].name if '.' not in source_subs_filename: return error_response(response, "Undefined file extension.") basename = os.path.basename(source_subs_filename) source_subs_name = os.path.splitext(basename)[0] source_subs_ext = os.path.splitext(basename)[1][1:] if item.category != 'video': return error_response( response, 'Transcripts are supported only for "video" modules.') # Allow upload only if any video link is presented if video_list: sub_attr = source_subs_name try: # Generate and save for 1.0 speed, will create subs_sub_attr.srt.sjson subtitles file in storage. generate_subs_from_source({1: sub_attr}, source_subs_ext, source_subs_filedata, item) for video_dict in video_list: video_name = video_dict['video'] # We are creating transcripts for every video source, if in future some of video sources would be deleted. # Updates item.sub with `video_name` on success. copy_or_rename_transcript(video_name, sub_attr, item, user=request.user) response['subs'] = item.sub response['status'] = 'Success' except Exception as ex: return error_response(response, ex.message) else: return error_response(response, 'Empty video sources.') return JsonResponse(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. """ response = { 'status': 'Unknown server error', 'subs': '', } locator = request.POST.get('locator') if not locator: return error_response(response, 'POST data without "locator" form data.') try: item = _get_item(request, request.POST) except (ItemNotFoundError, InvalidLocationError, InsufficientSpecificationError): return error_response(response, "Can't find item by locator.") if 'file' not in request.FILES: return error_response(response, 'POST data without "file" form data.') video_list = request.POST.get('video_list') if not video_list: return error_response(response, 'POST data without video names.') try: video_list = json.loads(video_list) except ValueError: return error_response(response, 'Invalid video_list JSON.') source_subs_filedata = request.FILES['file'].read().decode('utf8') source_subs_filename = request.FILES['file'].name if '.' not in source_subs_filename: return error_response(response, "Undefined file extension.") basename = os.path.basename(source_subs_filename) source_subs_name = os.path.splitext(basename)[0] source_subs_ext = os.path.splitext(basename)[1][1:] if item.category != 'video': return error_response(response, 'Transcripts are supported only for "video" modules.') # Allow upload only if any video link is presented if video_list: sub_attr = source_subs_name try: # Generate and save for 1.0 speed, will create subs_sub_attr.srt.sjson subtitles file in storage. generate_subs_from_source({1: sub_attr}, source_subs_ext, source_subs_filedata, item) for video_dict in video_list: video_name = video_dict['video'] # We are creating transcripts for every video source, if in future some of video sources would be deleted. # Updates item.sub with `video_name` on success. copy_or_rename_transcript(video_name, sub_attr, item, user=request.user) response['subs'] = item.sub response['status'] = 'Success' except Exception as ex: return error_response(response, ex.message) else: return error_response(response, 'Empty video sources.') return JsonResponse(response)