예제 #1
0
 def test_youtube_empty_text(self, mock_get):
     mock_get.return_value = Mock(status_code=200, text='')
     youtube_id = 'bad_youtube_id'
     with self.assertRaises(
             transcripts_utils.GetTranscriptsFromYouTubeException):
         transcripts_utils.get_transcripts_from_youtube(
             youtube_id, settings, translation)
예제 #2
0
 def test_youtube_good_result(self):
     response = textwrap.dedent("""<?xml version="1.0" encoding="utf-8" ?>
             <transcript>
                 <text start="0" dur="0.27"></text>
                 <text start="0.27" dur="2.45">Test text 1.</text>
                 <text start="2.72">Test text 2.</text>
                 <text start="5.43" dur="1.73">Test text 3.</text>
             </transcript>
     """)
     expected_transcripts = {
         'start': [270, 2720, 5430],
         'end': [2720, 2720, 7160],
         'text': ['Test text 1.', 'Test text 2.', 'Test text 3.']
     }
     youtube_id = 'good_youtube_id'
     with patch('xmodule.video_module.transcripts_utils.requests.get'
                ) as mock_get:
         mock_get.return_value = Mock(status_code=200,
                                      text=response,
                                      content=response)
         transcripts = transcripts_utils.get_transcripts_from_youtube(
             youtube_id, settings, translation)
     self.assertEqual(transcripts, expected_transcripts)
     mock_get.assert_called_with('http://video.google.com/timedtext',
                                 params={
                                     'lang': 'en',
                                     'v': 'good_youtube_id'
                                 })
예제 #3
0
    def __init__(self, course_key, youtube_id, lang):
        self.course_key = course_key
        self.youtube_id = youtube_id

        # Download transcripts from YouTube
        # Note: cribbed from common/lib/xmodule/xmodule/video_module/transcripts_utils.py download_youtube_subs()
        self.settings = copy.deepcopy(settings)
        self.settings.YOUTUBE['TEXT_API']['params']['lang'] = lang
        try:
            self.subs = transcripts_utils.get_transcripts_from_youtube(self.youtube_id, self.settings, ModuleI18nService())
            self.lang = lang
        except GetTranscriptsFromYouTubeException:
            raise Exception("Can't receive transcripts from Youtube for %s." % self.youtube_id)
 def test_youtube_good_result(self):
     response = textwrap.dedent("""<?xml version="1.0" encoding="utf-8" ?>
             <transcript>
                 <text start="0" dur="0.27"></text>
                 <text start="0.27" dur="2.45">Test text 1.</text>
                 <text start="2.72">Test text 2.</text>
                 <text start="5.43" dur="1.73">Test text 3.</text>
             </transcript>
     """)
     expected_transcripts = {
         'start': [270, 2720, 5430],
         'end': [2720, 2720, 7160],
         'text': ['Test text 1.', 'Test text 2.', 'Test text 3.']
     }
     youtube_id = 'good_youtube_id'
     with patch('xmodule.video_module.transcripts_utils.requests.get') as mock_get:
         mock_get.return_value = Mock(status_code=200, text=response, content=response)
         transcripts = transcripts_utils.get_transcripts_from_youtube(youtube_id, settings, translation)
     self.assertEqual(transcripts, expected_transcripts)
     mock_get.assert_called_with('http://video.google.com/timedtext', params={'lang': 'en', 'v': 'good_youtube_id'})
 def test_youtube_good_result(self):
     response = textwrap.dedent(
         """<?xml version="1.0" encoding="utf-8" ?>
             <transcript>
                 <text start="0" dur="0.27"></text>
                 <text start="0.27" dur="2.45">Test text 1.</text>
                 <text start="2.72">Test text 2.</text>
                 <text start="5.43" dur="1.73">Test text 3.</text>
             </transcript>
     """
     )
     expected_transcripts = {
         "start": [270, 2720, 5430],
         "end": [2720, 2720, 7160],
         "text": ["Test text 1.", "Test text 2.", "Test text 3."],
     }
     youtube_id = "good_youtube_id"
     with patch("xmodule.video_module.transcripts_utils.requests.get") as mock_get:
         mock_get.return_value = Mock(status_code=200, text=response, content=response)
         transcripts = transcripts_utils.get_transcripts_from_youtube(youtube_id, settings, translation)
     self.assertEqual(transcripts, expected_transcripts)
     mock_get.assert_called_with("http://video.google.com/timedtext", params={"lang": "en", "v": "good_youtube_id"})
예제 #6
0
def check_transcripts(request):
    """
    Check state of transcripts availability.

    request.GET['data'] has key `videos`, which can contain any of the following::

        [
            {u'type': u'youtube', u'video': u'OEoXaMPEzfM', u'mode': u'youtube'},
            {u'type': u'html5',    u'video': u'video1',             u'mode': u'mp4'}
            {u'type': u'html5',    u'video': u'video2',             u'mode': u'webm'}
        ]
        `type` is youtube or html5
        `video` is html5 or youtube video_id
        `mode` is youtube, ,p4 or webm

    Returns transcripts_presence dict::

        html5_local: list of html5 ids, if subtitles exist locally for them;
        is_youtube_mode: bool, if we have youtube_id, and as youtube mode is of higher priority, reflect this with flag;
        youtube_local: bool, if youtube transcripts exist locally;
        youtube_server: bool, if youtube transcripts exist on server;
        youtube_diff: bool, if youtube transcripts exist on youtube server, and are different from local youtube ones;
        current_item_subs: string, value of item.sub field;
        status: string, 'Error' or 'Success';
        subs: string, new value of item.sub field, that should be set in module;
        command: string, action to front-end what to do and what to show to user.
    """
    transcripts_presence = {
        'html5_local': [],
        'html5_equal': False,
        'is_youtube_mode': False,
        'youtube_local': False,
        'youtube_server': False,
        'youtube_diff': True,
        'current_item_subs': None,
        'status': 'Error',
    }
    try:
        __, videos, item = _validate_transcripts_data(request)
    except TranscriptsRequestValidationException as e:
        return error_response(transcripts_presence, e.message)

    transcripts_presence['status'] = 'Success'

    filename = 'subs_{0}.srt.sjson'.format(item.sub)
    content_location = StaticContent.compute_location(
        item.location.org, item.location.course, filename
    )
    try:
        local_transcripts = contentstore().find(content_location).data
        transcripts_presence['current_item_subs'] = item.sub
    except NotFoundError:
        pass

    # Check for youtube transcripts presence
    youtube_id = videos.get('youtube', None)
    if youtube_id:
        transcripts_presence['is_youtube_mode'] = True

        # youtube local
        filename = 'subs_{0}.srt.sjson'.format(youtube_id)
        content_location = StaticContent.compute_location(
            item.location.org, item.location.course, filename
        )
        try:
            local_transcripts = contentstore().find(content_location).data
            transcripts_presence['youtube_local'] = True
        except NotFoundError:
            log.debug("Can't find transcripts in storage for youtube id: %s", youtube_id)

        # youtube server
        youtube_api = copy.deepcopy(settings.YOUTUBE_API)
        youtube_api['params']['v'] = youtube_id
        youtube_response = requests.get(youtube_api['url'], params=youtube_api['params'])

        if youtube_response.status_code == 200 and youtube_response.text:
            transcripts_presence['youtube_server'] = True
        #check youtube local and server transcripts for equality
        if transcripts_presence['youtube_server'] and transcripts_presence['youtube_local']:
            try:
                youtube_server_subs = get_transcripts_from_youtube(
                    youtube_id,
                    settings,
                    item.runtime.service(item, "i18n")
                )
                if json.loads(local_transcripts) == youtube_server_subs:  # check transcripts for equality
                    transcripts_presence['youtube_diff'] = False
            except GetTranscriptsFromYouTubeException:
                pass

    # Check for html5 local transcripts presence
    html5_subs = []
    for html5_id in videos['html5']:
        filename = 'subs_{0}.srt.sjson'.format(html5_id)
        content_location = StaticContent.compute_location(
            item.location.org, item.location.course, filename
        )
        try:
            html5_subs.append(contentstore().find(content_location).data)
            transcripts_presence['html5_local'].append(html5_id)
        except NotFoundError:
            log.debug("Can't find transcripts in storage for non-youtube video_id: %s", html5_id)
        if len(html5_subs) == 2:  # check html5 transcripts for equality
            transcripts_presence['html5_equal'] = json.loads(html5_subs[0]) == json.loads(html5_subs[1])

    command, subs_to_use = _transcripts_logic(transcripts_presence, videos)
    transcripts_presence.update({
        'command': command,
        'subs': subs_to_use,
    })
    return JsonResponse(transcripts_presence)
예제 #7
0
def get_transcripts_presence(videos, item):
    """ fills in the transcripts_presence dictionary after for a given component
    with its list of videos.

    Returns transcripts_presence dict:

        html5_local: list of html5 ids, if subtitles exist locally for them;
        is_youtube_mode: bool, if we have youtube_id, and as youtube mode is of higher priority, reflect this with flag;
        youtube_local: bool, if youtube transcripts exist locally;
        youtube_server: bool, if youtube transcripts exist on server;
        youtube_diff: bool, if youtube transcripts exist on youtube server, and are different from local youtube ones;
        current_item_subs: string, value of item.sub field;
        status: string, 'Error' or 'Success';
        subs: string, new value of item.sub field, that should be set in module;
        command: string, action to front-end what to do and what to show to user.
    """
    transcripts_presence = {
        'html5_local': [],
        'html5_equal': False,
        'is_youtube_mode': False,
        'youtube_local': False,
        'youtube_server': False,
        'youtube_diff': True,
        'current_item_subs': None,
        'status': 'Success',
    }

    filename = 'subs_{0}.srt.sjson'.format(item.sub)
    content_location = StaticContent.compute_location(item.location.course_key,
                                                      filename)
    try:
        local_transcripts = contentstore().find(content_location).data
        transcripts_presence['current_item_subs'] = item.sub
    except NotFoundError:
        pass

    # Check for youtube transcripts presence
    youtube_id = videos.get('youtube', None)
    if youtube_id:
        transcripts_presence['is_youtube_mode'] = True

        # youtube local
        filename = 'subs_{0}.srt.sjson'.format(youtube_id)
        content_location = StaticContent.compute_location(
            item.location.course_key, filename)
        try:
            local_transcripts = contentstore().find(content_location).data
            transcripts_presence['youtube_local'] = True
        except NotFoundError:
            log.debug("Can't find transcripts in storage for youtube id: %s",
                      youtube_id)

        # youtube server
        youtube_text_api = copy.deepcopy(settings.YOUTUBE['TEXT_API'])
        youtube_text_api['params']['v'] = youtube_id
        youtube_transcript_name = youtube_video_transcript_name(
            youtube_text_api)
        if youtube_transcript_name:
            youtube_text_api['params']['name'] = youtube_transcript_name
        youtube_response = requests.get('http://' + youtube_text_api['url'],
                                        params=youtube_text_api['params'])

        if youtube_response.status_code == 200 and youtube_response.text:
            transcripts_presence['youtube_server'] = True
        #check youtube local and server transcripts for equality
        if transcripts_presence['youtube_server'] and transcripts_presence[
                'youtube_local']:
            try:
                youtube_server_subs = get_transcripts_from_youtube(
                    youtube_id, settings, item.runtime.service(item, "i18n"))
                if json.loads(
                        local_transcripts
                ) == youtube_server_subs:  # check transcripts for equality
                    transcripts_presence['youtube_diff'] = False
            except GetTranscriptsFromYouTubeException:
                pass

    # Check for html5 local transcripts presence
    html5_subs = []
    for html5_id in videos['html5']:
        filename = 'subs_{0}.srt.sjson'.format(html5_id)
        content_location = StaticContent.compute_location(
            item.location.course_key, filename)
        try:
            html5_subs.append(contentstore().find(content_location).data)
            transcripts_presence['html5_local'].append(html5_id)
        except NotFoundError:
            log.debug(
                "Can't find transcripts in storage for non-youtube video_id: %s",
                html5_id)
        if len(html5_subs) == 2:  # check html5 transcripts for equality
            transcripts_presence['html5_equal'] = json.loads(
                html5_subs[0]) == json.loads(html5_subs[1])

    command, subs_to_use = _transcripts_logic(transcripts_presence, videos)
    transcripts_presence.update({
        'command': command,
        'subs': subs_to_use,
    })
    return transcripts_presence
 def test_youtube_empty_text(self, mock_get):
     mock_get.return_value = Mock(status_code=200, text='')
     youtube_id = 'bad_youtube_id'
     with self.assertRaises(transcripts_utils.GetTranscriptsFromYouTubeException):
         transcripts_utils.get_transcripts_from_youtube(youtube_id, settings, translation)
예제 #9
0
def get_transcripts_presence(videos, item):
    """ fills in the transcripts_presence dictionary after for a given component
    with its list of videos.

    Returns transcripts_presence dict:

        html5_local: list of html5 ids, if subtitles exist locally for them;
        is_youtube_mode: bool, if we have youtube_id, and as youtube mode is of higher priority, reflect this with flag;
        youtube_local: bool, if youtube transcripts exist locally;
        youtube_server: bool, if youtube transcripts exist on server;
        youtube_diff: bool, if youtube transcripts exist on youtube server, and are different from local youtube ones;
        current_item_subs: string, value of item.sub field;
        status: string, 'Error' or 'Success';
        subs: string, new value of item.sub field, that should be set in module;
        command: string, action to front-end what to do and what to show to user.
    """
    transcripts_presence = {
        'html5_local': [],
        'html5_equal': False,
        'is_youtube_mode': False,
        'youtube_local': False,
        'youtube_server': False,
        'youtube_diff': True,
        'current_item_subs': None,
        'status': 'Success',
    }

    filename = 'subs_{0}.srt.sjson'.format(item.sub)
    content_location = StaticContent.compute_location(item.location.course_key, filename)
    try:
        local_transcripts = contentstore().find(content_location).data
        transcripts_presence['current_item_subs'] = item.sub
    except NotFoundError:
        pass

    # Check for youtube transcripts presence
    youtube_id = videos.get('youtube', None)
    if youtube_id:
        transcripts_presence['is_youtube_mode'] = True

        # youtube local
        filename = 'subs_{0}.srt.sjson'.format(youtube_id)
        content_location = StaticContent.compute_location(item.location.course_key, filename)
        try:
            local_transcripts = contentstore().find(content_location).data
            transcripts_presence['youtube_local'] = True
        except NotFoundError:
            log.debug("Can't find transcripts in storage for youtube id: %s", youtube_id)

        # youtube server
        youtube_text_api = copy.deepcopy(settings.YOUTUBE['TEXT_API'])
        youtube_text_api['params']['v'] = youtube_id
        youtube_response = requests.get('http://' + youtube_text_api['url'], params=youtube_text_api['params'])

        if youtube_response.status_code == 200 and youtube_response.text:
            transcripts_presence['youtube_server'] = True
        #check youtube local and server transcripts for equality
        if transcripts_presence['youtube_server'] and transcripts_presence['youtube_local']:
            try:
                youtube_server_subs = get_transcripts_from_youtube(
                    youtube_id,
                    settings,
                    item.runtime.service(item, "i18n")
                )
                if json.loads(local_transcripts) == youtube_server_subs:  # check transcripts for equality
                    transcripts_presence['youtube_diff'] = False
            except GetTranscriptsFromYouTubeException:
                pass

    # Check for html5 local transcripts presence
    html5_subs = []
    for html5_id in videos['html5']:
        filename = 'subs_{0}.srt.sjson'.format(html5_id)
        content_location = StaticContent.compute_location(item.location.course_key, filename)
        try:
            html5_subs.append(contentstore().find(content_location).data)
            transcripts_presence['html5_local'].append(html5_id)
        except NotFoundError:
            log.debug("Can't find transcripts in storage for non-youtube video_id: %s", html5_id)
        if len(html5_subs) == 2:  # check html5 transcripts for equality
            transcripts_presence['html5_equal'] = json.loads(html5_subs[0]) == json.loads(html5_subs[1])

    command, subs_to_use = _transcripts_logic(transcripts_presence, videos)
    transcripts_presence.update({
        'command': command,
        'subs': subs_to_use,
    })
    return transcripts_presence
예제 #10
0
 def test_youtube_bad_status_code(self, mock_get):
     mock_get.return_value = Mock(status_code=404, text="test")
     youtube_id = "bad_youtube_id"
     with self.assertRaises(transcripts_utils.GetTranscriptsFromYouTubeException):
         transcripts_utils.get_transcripts_from_youtube(youtube_id, settings, translation)