]> jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/nick.py
[extractor] Common function `_match_valid_url`
[yt-dlp.git] / yt_dlp / extractor / nick.py
1 # coding: utf-8
2 from __future__ import unicode_literals
3
4
5 from .mtv import MTVServicesInfoExtractor
6 from ..utils import update_url_query
7
8
9 class NickIE(MTVServicesInfoExtractor):
10 IE_NAME = 'nick.com'
11 _VALID_URL = r'https?://(?P<domain>(?:www\.)?nick(?:jr)?\.com)/(?:[^/]+/)?(?P<type>videos/clip|[^/]+/videos|episodes/[^/]+)/(?P<id>[^/?#.]+)'
12 _FEED_URL = 'http://udat.mtvnservices.com/service1/dispatch.htm'
13 _GEO_COUNTRIES = ['US']
14 _TESTS = [{
15 'url': 'https://www.nick.com/episodes/sq47rw/spongebob-squarepants-a-place-for-pets-lockdown-for-love-season-13-ep-1',
16 'info_dict': {
17 'description': 'md5:0650a9eb88955609d5c1d1c79292e234',
18 'title': 'A Place for Pets/Lockdown for Love',
19 },
20 'playlist': [
21 {
22 'md5': 'cb8a2afeafb7ae154aca5a64815ec9d6',
23 'info_dict': {
24 'id': '85ee8177-d6ce-48f8-9eee-a65364f8a6df',
25 'ext': 'mp4',
26 'title': 'SpongeBob SquarePants: "A Place for Pets/Lockdown for Love" S1',
27 'description': 'A Place for Pets/Lockdown for Love: When customers bring pets into the Krusty Krab, Mr. Krabs realizes pets are more profitable than owners. Plankton ruins another date with Karen, so she puts the Chum Bucket on lockdown until he proves his affection.',
28
29 }
30 },
31 {
32 'md5': '839a04f49900a1fcbf517020d94e0737',
33 'info_dict': {
34 'id': '2e2a9960-8fd4-411d-868b-28eb1beb7fae',
35 'ext': 'mp4',
36 'title': 'SpongeBob SquarePants: "A Place for Pets/Lockdown for Love" S2',
37 'description': 'A Place for Pets/Lockdown for Love: When customers bring pets into the Krusty Krab, Mr. Krabs realizes pets are more profitable than owners. Plankton ruins another date with Karen, so she puts the Chum Bucket on lockdown until he proves his affection.',
38
39 }
40 },
41 {
42 'md5': 'f1145699f199770e2919ee8646955d46',
43 'info_dict': {
44 'id': 'dc91c304-6876-40f7-84a6-7aece7baa9d0',
45 'ext': 'mp4',
46 'title': 'SpongeBob SquarePants: "A Place for Pets/Lockdown for Love" S3',
47 'description': 'A Place for Pets/Lockdown for Love: When customers bring pets into the Krusty Krab, Mr. Krabs realizes pets are more profitable than owners. Plankton ruins another date with Karen, so she puts the Chum Bucket on lockdown until he proves his affection.',
48
49 }
50 },
51 {
52 'md5': 'd463116875aee2585ee58de3b12caebd',
53 'info_dict': {
54 'id': '5d929486-cf4c-42a1-889a-6e0d183a101a',
55 'ext': 'mp4',
56 'title': 'SpongeBob SquarePants: "A Place for Pets/Lockdown for Love" S4',
57 'description': 'A Place for Pets/Lockdown for Love: When customers bring pets into the Krusty Krab, Mr. Krabs realizes pets are more profitable than owners. Plankton ruins another date with Karen, so she puts the Chum Bucket on lockdown until he proves his affection.',
58
59 }
60 },
61 ],
62 }, {
63 'url': 'http://www.nickjr.com/blues-clues-and-you/videos/blues-clues-and-you-original-209-imagination-station/',
64 'info_dict': {
65 'id': '31631529-2fc5-430b-b2ef-6a74b4609abd',
66 'ext': 'mp4',
67 'description': 'md5:9d65a66df38e02254852794b2809d1cf',
68 'title': 'Blue\'s Imagination Station',
69 },
70 }]
71
72 def _get_feed_query(self, uri):
73 return {
74 'feed': 'nick_arc_player_prime',
75 'mgid': uri,
76 }
77
78 def _extract_mgid(self, webpage):
79 mgid = self._search_regex(r'"media":{"video":{"config":{"uri":"(mgid:.*?)"', webpage, 'mgid', default=None)
80 return mgid
81
82 def _real_extract(self, url):
83 domain, video_type, display_id = self._match_valid_url(url).groups()
84 if video_type.startswith("episodes"):
85 return super()._real_extract(url)
86 video_data = self._download_json(
87 'http://%s/data/video.endLevel.json' % domain,
88 display_id, query={
89 'urlKey': display_id,
90 })
91 return self._get_videos_info(video_data['player'] + video_data['id'])
92
93
94 class NickBrIE(MTVServicesInfoExtractor):
95 IE_NAME = 'nickelodeon:br'
96 _VALID_URL = r'''(?x)
97 https?://
98 (?:
99 (?P<domain>(?:www\.)?nickjr|mundonick\.uol)\.com\.br|
100 (?:www\.)?nickjr\.[a-z]{2}|
101 (?:www\.)?nickelodeonjunior\.fr
102 )
103 /(?:programas/)?[^/]+/videos/(?:episodios/)?(?P<id>[^/?\#.]+)
104 '''
105 _TESTS = [{
106 'url': 'http://www.nickjr.com.br/patrulha-canina/videos/210-labirinto-de-pipoca/',
107 'only_matching': True,
108 }, {
109 'url': 'http://mundonick.uol.com.br/programas/the-loud-house/videos/muitas-irmas/7ljo9j',
110 'only_matching': True,
111 }, {
112 'url': 'http://www.nickjr.nl/paw-patrol/videos/311-ge-wol-dig-om-terug-te-zijn/',
113 'only_matching': True,
114 }, {
115 'url': 'http://www.nickjr.de/blaze-und-die-monster-maschinen/videos/f6caaf8f-e4e8-4cc1-b489-9380d6dcd059/',
116 'only_matching': True,
117 }, {
118 'url': 'http://www.nickelodeonjunior.fr/paw-patrol-la-pat-patrouille/videos/episode-401-entier-paw-patrol/',
119 'only_matching': True,
120 }]
121
122 def _real_extract(self, url):
123 domain, display_id = self._match_valid_url(url).groups()
124 webpage = self._download_webpage(url, display_id)
125 uri = self._search_regex(
126 r'data-(?:contenturi|mgid)="([^"]+)', webpage, 'mgid')
127 video_id = self._id_from_uri(uri)
128 config = self._download_json(
129 'http://media.mtvnservices.com/pmt/e1/access/index.html',
130 video_id, query={
131 'uri': uri,
132 'configtype': 'edge',
133 }, headers={
134 'Referer': url,
135 })
136 info_url = self._remove_template_parameter(config['feedWithQueryParams'])
137 if info_url == 'None':
138 if domain.startswith('www.'):
139 domain = domain[4:]
140 content_domain = {
141 'mundonick.uol': 'mundonick.com.br',
142 'nickjr': 'br.nickelodeonjunior.tv',
143 }[domain]
144 query = {
145 'mgid': uri,
146 'imageEp': content_domain,
147 'arcEp': content_domain,
148 }
149 if domain == 'nickjr.com.br':
150 query['ep'] = 'c4b16088'
151 info_url = update_url_query(
152 'http://feeds.mtvnservices.com/od/feed/intl-mrss-player-feed', query)
153 return self._get_videos_info_from_url(info_url, video_id)
154
155
156 class NickDeIE(MTVServicesInfoExtractor):
157 IE_NAME = 'nick.de'
158 _VALID_URL = r'https?://(?:www\.)?(?P<host>nick\.(?:de|com\.pl|ch)|nickelodeon\.(?:nl|be|at|dk|no|se))/[^/]+/(?:[^/]+/)*(?P<id>[^/?#&]+)'
159 _TESTS = [{
160 'url': 'http://www.nick.de/playlist/3773-top-videos/videos/episode/17306-zu-wasser-und-zu-land-rauchende-erdnusse',
161 'only_matching': True,
162 }, {
163 'url': 'http://www.nick.de/shows/342-icarly',
164 'only_matching': True,
165 }, {
166 'url': 'http://www.nickelodeon.nl/shows/474-spongebob/videos/17403-een-kijkje-in-de-keuken-met-sandy-van-binnenuit',
167 'only_matching': True,
168 }, {
169 'url': 'http://www.nickelodeon.at/playlist/3773-top-videos/videos/episode/77993-das-letzte-gefecht',
170 'only_matching': True,
171 }, {
172 'url': 'http://www.nick.com.pl/seriale/474-spongebob-kanciastoporty/wideo/17412-teatr-to-jest-to-rodeo-oszolom',
173 'only_matching': True,
174 }, {
175 'url': 'http://www.nickelodeon.no/program/2626-bulderhuset/videoer/90947-femteklasse-veronica-vs-vanzilla',
176 'only_matching': True,
177 }, {
178 'url': 'http://www.nickelodeon.dk/serier/2626-hojs-hus/videoer/761-tissepause',
179 'only_matching': True,
180 }, {
181 'url': 'http://www.nickelodeon.se/serier/2626-lugn-i-stormen/videos/998-',
182 'only_matching': True,
183 }, {
184 'url': 'http://www.nick.ch/shows/2304-adventure-time-abenteuerzeit-mit-finn-und-jake',
185 'only_matching': True,
186 }, {
187 'url': 'http://www.nickelodeon.be/afspeellijst/4530-top-videos/videos/episode/73917-inval-broodschapper-lariekoek-arie',
188 'only_matching': True,
189 }]
190
191 def _get_feed_url(self, uri, url=None):
192 video_id = self._id_from_uri(uri)
193 config = self._download_json(
194 'http://media.mtvnservices.com/pmt/e1/access/index.html?uri=%s&configtype=edge&ref=%s' % (uri, url), video_id)
195 return self._remove_template_parameter(config['feedWithQueryParams'])
196
197
198 class NickNightIE(NickDeIE):
199 IE_NAME = 'nicknight'
200 _VALID_URL = r'https?://(?:www\.)(?P<host>nicknight\.(?:de|at|tv))/(?:playlist|shows)/(?:[^/]+/)*(?P<id>[^/?#&]+)'
201 _TESTS = [{
202 'url': 'http://www.nicknight.at/shows/977-awkward/videos/85987-nimmer-beste-freunde',
203 'only_matching': True,
204 }, {
205 'url': 'http://www.nicknight.at/shows/977-awkward',
206 'only_matching': True,
207 }, {
208 'url': 'http://www.nicknight.at/shows/1900-faking-it',
209 'only_matching': True,
210 }]
211
212 def _extract_mrss_url(self, webpage, *args):
213 return self._search_regex(
214 r'mrss\s*:\s*(["\'])(?P<url>http.+?)\1', webpage,
215 'mrss url', group='url')
216
217
218 class NickRuIE(MTVServicesInfoExtractor):
219 IE_NAME = 'nickelodeonru'
220 _VALID_URL = r'https?://(?:www\.)nickelodeon\.(?:ru|fr|es|pt|ro|hu|com\.tr)/[^/]+/(?:[^/]+/)*(?P<id>[^/?#&]+)'
221 _TESTS = [{
222 'url': 'http://www.nickelodeon.ru/shows/henrydanger/videos/episodes/3-sezon-15-seriya-licenziya-na-polyot/pmomfb#playlist/7airc6',
223 'only_matching': True,
224 }, {
225 'url': 'http://www.nickelodeon.ru/videos/smotri-na-nickelodeon-v-iyule/g9hvh7',
226 'only_matching': True,
227 }, {
228 'url': 'http://www.nickelodeon.fr/programmes/bob-l-eponge/videos/le-marathon-de-booh-kini-bottom-mardi-31-octobre/nfn7z0',
229 'only_matching': True,
230 }, {
231 'url': 'http://www.nickelodeon.es/videos/nickelodeon-consejos-tortitas/f7w7xy',
232 'only_matching': True,
233 }, {
234 'url': 'http://www.nickelodeon.pt/series/spongebob-squarepants/videos/a-bolha-de-tinta-gigante/xutq1b',
235 'only_matching': True,
236 }, {
237 'url': 'http://www.nickelodeon.ro/emisiuni/shimmer-si-shine/video/nahal-din-bomboane/uw5u2k',
238 'only_matching': True,
239 }, {
240 'url': 'http://www.nickelodeon.hu/musorok/spongyabob-kockanadrag/videok/episodes/buborekfujas-az-elszakadt-nadrag/q57iob#playlist/k6te4y',
241 'only_matching': True,
242 }, {
243 'url': 'http://www.nickelodeon.com.tr/programlar/sunger-bob/videolar/kayip-yatak/mgqbjy',
244 'only_matching': True,
245 }]
246
247 def _real_extract(self, url):
248 video_id = self._match_id(url)
249 webpage = self._download_webpage(url, video_id)
250 mgid = self._extract_mgid(webpage, url)
251 return self.url_result('http://media.mtvnservices.com/embed/%s' % mgid)