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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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.")
Ejemplo n.º 5
0
    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.")
Ejemplo n.º 6
0
    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.")
Ejemplo n.º 7
0
    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.")
Ejemplo n.º 8
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.
    """
    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)
Ejemplo n.º 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.
    """
    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)
Ejemplo n.º 10
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.
    """
    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)