]>
Commit | Line | Data |
---|---|---|
e25ca9b0 AG |
1 | import re |
2 | ||
3 | from .common import InfoExtractor | |
4 | from ..utils import js_to_json | |
5 | ||
6 | ||
7 | class RTNewsIE(InfoExtractor): | |
8 | _VALID_URL = r'https?://(?:www\.)?rt\.com/[^/]+/(?:[^/]+/)?(?P<id>\d+)' | |
9 | ||
10 | _TESTS = [{ | |
11 | 'url': 'https://www.rt.com/sport/546301-djokovic-arrives-belgrade-crowds/', | |
12 | 'playlist_mincount': 2, | |
13 | 'info_dict': { | |
14 | 'id': '546301', | |
15 | 'title': 'Crowds gather to greet deported Djokovic as he returns to Serbia (VIDEO)', | |
16 | 'description': 'md5:1d5bfe1a988d81fd74227cfdf93d314d', | |
17 | 'thumbnail': 'https://cdni.rt.com/files/2022.01/article/61e587a085f540102c3386c1.png' | |
18 | }, | |
19 | }, { | |
20 | 'url': 'https://www.rt.com/shows/in-question/535980-plot-to-assassinate-julian-assange/', | |
21 | 'playlist_mincount': 1, | |
22 | 'info_dict': { | |
23 | 'id': '535980', | |
24 | 'title': 'The plot to assassinate Julian Assange', | |
25 | 'description': 'md5:55279ce5e4441dc1d16e2e4a730152cd', | |
26 | 'thumbnail': 'https://cdni.rt.com/files/2021.09/article/615226f42030274e8879b53d.png' | |
27 | }, | |
28 | 'playlist': [{ | |
29 | 'info_dict': { | |
30 | 'id': '6152271d85f5400464496162', | |
31 | 'ext': 'mp4', | |
32 | 'title': '6152271d85f5400464496162', | |
33 | }, | |
34 | }] | |
35 | }] | |
36 | ||
37 | def _entries(self, webpage): | |
38 | video_urls = set(re.findall(r'https://cdnv\.rt\.com/.*[a-f0-9]+\.mp4', webpage)) | |
39 | for v_url in video_urls: | |
40 | v_id = re.search(r'([a-f0-9]+)\.mp4', v_url).group(1) | |
41 | if v_id: | |
42 | yield { | |
43 | 'id': v_id, | |
44 | 'title': v_id, | |
45 | 'url': v_url, | |
46 | } | |
47 | ||
48 | def _real_extract(self, url): | |
49 | id = self._match_id(url) | |
50 | webpage = self._download_webpage(url, id) | |
51 | ||
52 | return { | |
53 | '_type': 'playlist', | |
54 | 'id': id, | |
55 | 'entries': self._entries(webpage), | |
56 | 'title': self._og_search_title(webpage), | |
57 | 'description': self._og_search_description(webpage), | |
58 | 'thumbnail': self._og_search_thumbnail(webpage), | |
59 | } | |
60 | ||
61 | ||
62 | class RTDocumentryIE(InfoExtractor): | |
63 | _VALID_URL = r'https?://rtd\.rt\.com/(?:(?:series|shows)/[^/]+|films)/(?P<id>[^/?$&#]+)' | |
64 | ||
65 | _TESTS = [{ | |
66 | 'url': 'https://rtd.rt.com/films/escobars-hitman/', | |
67 | 'info_dict': { | |
68 | 'id': 'escobars-hitman', | |
69 | 'ext': 'mp4', | |
70 | 'title': "Escobar's Hitman. Former drug-gang killer, now loved and loathed in Colombia", | |
71 | 'description': 'md5:647c76984b7cb9a8b52a567e87448d88', | |
72 | 'thumbnail': 'https://cdni.rt.com/rtd-files/films/escobars-hitman/escobars-hitman_11.jpg', | |
73 | 'average_rating': 8.53, | |
74 | 'duration': 3134.0 | |
75 | }, | |
76 | 'params': {'skip_download': True} | |
77 | }, { | |
78 | 'url': 'https://rtd.rt.com/shows/the-kalashnikova-show-military-secrets-anna-knishenko/iskander-tactical-system-natos-headache/', | |
79 | 'info_dict': { | |
80 | 'id': 'iskander-tactical-system-natos-headache', | |
81 | 'ext': 'mp4', | |
82 | 'title': "Iskander tactical system. NATO's headache | The Kalashnikova Show. Episode 10", | |
83 | 'description': 'md5:da7c24a0aa67bc2bb88c86658508ca87', | |
84 | 'thumbnail': 'md5:89de8ce38c710b7c501ff02d47e2aa89', | |
85 | 'average_rating': 9.27, | |
86 | 'duration': 274.0, | |
87 | 'timestamp': 1605726000, | |
88 | 'view_count': int, | |
89 | 'upload_date': '20201118' | |
90 | }, | |
91 | 'params': {'skip_download': True} | |
92 | }, { | |
93 | 'url': 'https://rtd.rt.com/series/i-am-hacked-trailer/introduction-to-safe-digital-life-ep2/', | |
94 | 'info_dict': { | |
95 | 'id': 'introduction-to-safe-digital-life-ep2', | |
96 | 'ext': 'mp4', | |
97 | 'title': 'How to Keep your Money away from Hackers | I am Hacked. Episode 2', | |
98 | 'description': 'md5:c46fa9a5af86c0008c45a3940a8cce87', | |
99 | 'thumbnail': 'md5:a5e81b9bf5aed8f5e23d9c053601b825', | |
100 | 'average_rating': 10.0, | |
101 | 'duration': 1524.0, | |
102 | 'timestamp': 1636977600, | |
103 | 'view_count': int, | |
104 | 'upload_date': '20211115' | |
105 | }, | |
106 | 'params': {'skip_download': True} | |
107 | }] | |
108 | ||
109 | def _real_extract(self, url): | |
110 | id = self._match_id(url) | |
111 | webpage = self._download_webpage(url, id) | |
112 | ld_json = self._search_json_ld(webpage, None, fatal=False) | |
113 | if not ld_json: | |
114 | self.raise_no_formats('No video/audio found at the provided url.', expected=True) | |
115 | media_json = self._parse_json( | |
116 | self._search_regex(r'(?s)\'Med\'\s*:\s*\[\s*({.+})\s*\]\s*};', webpage, 'media info'), | |
117 | id, transform_source=js_to_json) | |
118 | if 'title' not in ld_json and 'title' in media_json: | |
119 | ld_json['title'] = media_json['title'] | |
120 | formats = [{'url': src['file']} for src in media_json.get('sources') or [] if src.get('file')] | |
121 | ||
122 | return { | |
123 | 'id': id, | |
124 | 'thumbnail': media_json.get('image'), | |
125 | 'formats': formats, | |
126 | **ld_json | |
127 | } | |
128 | ||
129 | ||
130 | class RTDocumentryPlaylistIE(InfoExtractor): | |
131 | _VALID_URL = r'https?://rtd\.rt\.com/(?:series|shows)/(?P<id>[^/]+)/$' | |
132 | ||
133 | _TESTS = [{ | |
134 | 'url': 'https://rtd.rt.com/series/i-am-hacked-trailer/', | |
135 | 'playlist_mincount': 6, | |
136 | 'info_dict': { | |
137 | 'id': 'i-am-hacked-trailer', | |
138 | }, | |
139 | }, { | |
140 | 'url': 'https://rtd.rt.com/shows/the-kalashnikova-show-military-secrets-anna-knishenko/', | |
141 | 'playlist_mincount': 34, | |
142 | 'info_dict': { | |
143 | 'id': 'the-kalashnikova-show-military-secrets-anna-knishenko', | |
144 | }, | |
145 | }] | |
146 | ||
147 | def _entries(self, webpage, id): | |
148 | video_urls = set(re.findall(r'list-2__link\s*"\s*href="([^"]+)"', webpage)) | |
149 | for v_url in video_urls: | |
150 | if id not in v_url: | |
151 | continue | |
152 | yield self.url_result( | |
153 | 'https://rtd.rt.com%s' % v_url, | |
154 | ie=RTDocumentryIE.ie_key()) | |
155 | ||
156 | def _real_extract(self, url): | |
157 | id = self._match_id(url) | |
158 | webpage = self._download_webpage(url, id) | |
159 | ||
160 | return { | |
161 | '_type': 'playlist', | |
162 | 'id': id, | |
163 | 'entries': self._entries(webpage, id), | |
164 | } | |
165 | ||
166 | ||
167 | class RuptlyIE(InfoExtractor): | |
168 | _VALID_URL = r'https?://(?:www\.)?ruptly\.tv/[a-z]{2}/videos/(?P<id>\d+-\d+)' | |
169 | ||
170 | _TESTS = [{ | |
171 | 'url': 'https://www.ruptly.tv/en/videos/20220112-020-Japan-Double-trouble-Tokyo-zoo-presents-adorable-panda-twins', | |
172 | 'info_dict': { | |
173 | 'id': '20220112-020', | |
174 | 'ext': 'mp4', | |
175 | 'title': 'Japan: Double trouble! Tokyo zoo presents adorable panda twins | Video Ruptly', | |
176 | 'description': 'md5:85a8da5fdb31486f0562daf4360ce75a', | |
177 | 'thumbnail': 'https://storage.ruptly.tv/thumbnails/20220112-020/i6JQKnTNpYuqaXsR/i6JQKnTNpYuqaXsR.jpg' | |
178 | }, | |
179 | 'params': {'skip_download': True} | |
180 | }] | |
181 | ||
182 | def _real_extract(self, url): | |
183 | id = self._match_id(url) | |
184 | webpage = self._download_webpage(url, id) | |
185 | m3u8_url = self._search_regex(r'preview_url"\s?:\s?"(https?://storage\.ruptly\.tv/video_projects/.+\.m3u8)"', webpage, 'm3u8 url', fatal=False) | |
186 | if not m3u8_url: | |
187 | self.raise_no_formats('No video/audio found at the provided url.', expected=True) | |
188 | formats, subs = self._extract_m3u8_formats_and_subtitles(m3u8_url, id, ext='mp4') | |
189 | return { | |
190 | 'id': id, | |
191 | 'formats': formats, | |
192 | 'subtitles': subs, | |
193 | 'title': self._og_search_title(webpage), | |
194 | 'description': self._og_search_description(webpage), | |
195 | 'thumbnail': self._og_search_thumbnail(webpage), | |
196 | } |