[dailymotion] Added support for subtitles + new InfoExtractor for
[youtube-dl] / youtube_dl / extractor / subtitles.py
1 import socket
2
3 from .common import InfoExtractor
4
5 from ..utils import (
6     compat_http_client,
7     compat_urllib_error,
8     compat_urllib_request,
9     compat_str,
10 )
11
12
13 class SubtitlesIE(InfoExtractor):
14
15     def report_video_subtitles_available(self, video_id, sub_lang_list):
16         """Report available subtitles."""
17         sub_lang = ",".join(list(sub_lang_list.keys()))
18         self.to_screen(u'%s: Available subtitles for video: %s' % (video_id, sub_lang))
19
20     def _list_available_subtitles(self, video_id):
21         sub_lang_list = self._get_available_subtitles(video_id)
22         self.report_video_subtitles_available(video_id, sub_lang_list)
23
24     def _extract_subtitles(self, video_id):
25         """
26         Return a dictionary: {language: subtitles} or {} if the subtitles
27         couldn't be found
28         """
29         sub_lang_list = self._get_available_subtitles(video_id)
30         sub_format = self._downloader.params.get('subtitlesformat')
31         if  not sub_lang_list: #There was some error, it didn't get the available subtitles
32             return {}
33         if self._downloader.params.get('writesubtitles', False):
34             if self._downloader.params.get('subtitleslang', False):
35                 sub_lang = self._downloader.params.get('subtitleslang')
36             elif 'en' in sub_lang_list:
37                 sub_lang = 'en'
38             else:
39                 sub_lang = list(sub_lang_list.keys())[0]
40             if not sub_lang in sub_lang_list:
41                 self._downloader.report_warning(u'no closed captions found in the specified language "%s"' % sub_lang)
42                 return {}
43             sub_lang_list = {sub_lang: sub_lang_list[sub_lang]}
44         subtitles = {}
45         for sub_lang in sub_lang_list:
46             subtitle = self._request_subtitle(sub_lang, sub_lang_list[sub_lang].encode('utf-8'), video_id, sub_format)
47             if subtitle:
48                 subtitles[sub_lang] = subtitle
49         return subtitles
50
51     def _request_subtitle(self, sub_lang, sub_name, video_id, format):
52         """ Return the subtitle as a string or None if they are not found """
53         # return (u'Did not fetch video subtitles for %s' % sub_lang, None, None)
54         self.to_screen(u'%s: Downloading video subtitles for %s.%s' % (video_id, sub_lang, format))
55         url = self._get_subtitle_url(sub_lang, sub_name, video_id, format)
56         try:
57             sub = compat_urllib_request.urlopen(url).read().decode('utf-8')
58         except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err:
59             self._downloader.report_warning(u'unable to download video subtitles for %s: %s' % (sub_lang, compat_str(err)))
60             return
61         if not sub:
62             self._downloader.report_warning(u'Did not fetch video subtitles')
63             return
64         return sub
65
66     def _get_available_subtitles(self, video_id):
67         """Get available subtitles. Redefine in subclasses."""
68         """returns {(lang, url)} """
69         # return {}
70         pass
71
72     def _get_subtitle_url(self, sub_lang, sub_name, video_id, format):
73         """returns the url for the given subtitle. Redefine in subclasses."""
74         pass
75
76     def _request_automatic_caption(self, video_id, webpage):
77         """Request automatic caption. Redefine in subclasses."""
78         """returns a tuple of ... """
79         # return [(err_msg, None, None)]
80         pass