]> jfr.im git - yt-dlp.git/blame - yt_dlp/extractor/txxx.py
[ie/matchtv] Fix extractor (#10190)
[yt-dlp.git] / yt_dlp / extractor / txxx.py
CommitLineData
389896df 1import base64
2import re
3
4from .common import InfoExtractor
5from ..utils import (
6 ExtractorError,
7 int_or_none,
8 js_to_json,
9 merge_dicts,
10 parse_duration,
11 traverse_obj,
12 try_call,
d79c7e99 13 url_or_none,
389896df 14 urljoin,
15 variadic,
16)
17
18
19def decode_base64(text):
20 return base64.b64decode(text.translate(text.maketrans({
21 '\u0405': 'S',
22 '\u0406': 'I',
23 '\u0408': 'J',
24 '\u0410': 'A',
25 '\u0412': 'B',
26 '\u0415': 'E',
27 '\u041a': 'K',
28 '\u041c': 'M',
29 '\u041d': 'H',
30 '\u041e': 'O',
31 '\u0420': 'P',
32 '\u0421': 'C',
33 '\u0425': 'X',
34 ',': '/',
35 '.': '+',
36 '~': '=',
37 }))).decode()
38
39
40def get_formats(host, video_file):
41 return [{
42 'url': urljoin(f'https://{host}', decode_base64(video['video_url'])),
43 'format_id': try_call(lambda: variadic(video['format'])[0].lstrip('_')),
44 'quality': index,
45 } for index, video in enumerate(video_file) if video.get('video_url')]
46
47
48class TxxxIE(InfoExtractor):
49 _DOMAINS = (
50 'hclips.com',
51 'hdzog.com',
52 'hdzog.tube',
53 'hotmovs.com',
54 'hotmovs.tube',
55 'inporn.com',
56 'privatehomeclips.com',
57 'tubepornclassic.com',
58 'txxx.com',
59 'txxx.tube',
60 'upornia.com',
61 'upornia.tube',
62 'vjav.com',
63 'vjav.tube',
64 'vxxx.com',
65 'voyeurhit.com',
66 'voyeurhit.tube',
67 )
68 _VALID_URL = rf'''(?x)
69 https?://(?:www\.)?(?P<host>{"|".join(map(re.escape, _DOMAINS))})/
70 (?:videos?[/-]|embed/)(?P<id>\d+)(?:/(?P<display_id>[^/?#]+))?
71 '''
72 _EMBED_REGEX = [rf'<iframe[^>]+?src=(["\'])(?P<url>(?:https?:)?//(?:www\.)?(?:{"|".join(map(re.escape, _DOMAINS))})/embed/[^"\']*)\1']
73 _TESTS = [{
74 'url': 'https://txxx.com/videos/16574965/digital-desire-malena-morgan/',
75 'md5': 'c54e4ace54320aaf8e2a72df87859391',
76 'info_dict': {
77 'id': '16574965',
78 'display_id': 'digital-desire-malena-morgan',
79 'ext': 'mp4',
80 'title': 'Digital Desire - Malena Morgan',
81 'uploader': 'Lois Argentum',
82 'duration': 694,
83 'view_count': int,
84 'like_count': int,
85 'dislike_count': int,
86 'age_limit': 18,
d79c7e99 87 'thumbnail': 'https://tn.txxx.tube/contents/videos_sources/16574000/16574965/screenshots/1.jpg',
add96eb9 88 },
389896df 89 }, {
90 'url': 'https://txxx.tube/videos/16574965/digital-desire-malena-morgan/',
91 'md5': 'c54e4ace54320aaf8e2a72df87859391',
92 'info_dict': {
93 'id': '16574965',
94 'display_id': 'digital-desire-malena-morgan',
95 'ext': 'mp4',
96 'title': 'Digital Desire - Malena Morgan',
97 'uploader': 'Lois Argentum',
98 'duration': 694,
99 'view_count': int,
100 'like_count': int,
101 'dislike_count': int,
102 'age_limit': 18,
d79c7e99 103 'thumbnail': 'https://tn.txxx.tube/contents/videos_sources/16574000/16574965/screenshots/1.jpg',
add96eb9 104 },
389896df 105 }, {
106 'url': 'https://vxxx.com/video-68925/',
107 'md5': '1fcff3748b0c5b41fe41d0afa22409e1',
108 'info_dict': {
109 'id': '68925',
110 'display_id': '68925',
111 'ext': 'mp4',
112 'title': 'Malena Morgan',
113 'uploader': 'Huge Hughes',
114 'duration': 694,
115 'view_count': int,
116 'like_count': int,
117 'dislike_count': int,
118 'age_limit': 18,
d79c7e99 119 'thumbnail': 'https://tn.vxxx.com/contents/videos_sources/68000/68925/screenshots/1.jpg',
add96eb9 120 },
389896df 121 }, {
122 'url': 'https://hclips.com/videos/6291073/malena-morgan-masturbates-her-sweet/',
123 'md5': 'a5dd4f83363972ee043313cff85e7e26',
124 'info_dict': {
125 'id': '6291073',
126 'display_id': 'malena-morgan-masturbates-her-sweet',
127 'ext': 'mp4',
128 'title': 'Malena Morgan masturbates her sweet',
129 'uploader': 'John Salt',
130 'duration': 426,
131 'view_count': int,
132 'like_count': int,
133 'dislike_count': int,
134 'age_limit': 18,
d79c7e99 135 'thumbnail': 'https://hctn.nv7s.com/contents/videos_sources/6291000/6291073/screenshots/1.jpg',
add96eb9 136 },
389896df 137 }, {
138 'url': 'https://hdzog.com/videos/67063/gorgeous-malena-morgan-will-seduce-you-at-the-first-glance/',
139 'md5': 'f8bdedafd45d1ec2875c43fe33a846d3',
140 'info_dict': {
141 'id': '67063',
142 'display_id': 'gorgeous-malena-morgan-will-seduce-you-at-the-first-glance',
143 'ext': 'mp4',
144 'title': 'Gorgeous Malena Morgan will seduce you at the first glance',
145 'uploader': 'momlesson',
146 'duration': 601,
147 'view_count': int,
148 'like_count': int,
149 'dislike_count': int,
150 'age_limit': 18,
d79c7e99 151 'thumbnail': 'https://tn.hdzog.com/contents/videos_sources/67000/67063/screenshots/1.jpg',
add96eb9 152 },
389896df 153 }, {
154 'url': 'https://hdzog.tube/videos/67063/gorgeous-malena-morgan-will-seduce-you-at-the-first-glance/',
155 'md5': 'f8bdedafd45d1ec2875c43fe33a846d3',
156 'info_dict': {
157 'id': '67063',
158 'display_id': 'gorgeous-malena-morgan-will-seduce-you-at-the-first-glance',
159 'ext': 'mp4',
160 'title': 'Gorgeous Malena Morgan will seduce you at the first glance',
161 'uploader': 'momlesson',
162 'duration': 601,
163 'view_count': int,
164 'like_count': int,
165 'dislike_count': int,
166 'age_limit': 18,
d79c7e99 167 'thumbnail': 'https://tn.hdzog.com/contents/videos_sources/67000/67063/screenshots/1.jpg',
add96eb9 168 },
389896df 169 }, {
170 'url': 'https://hotmovs.com/videos/8789287/unbelievable-malena-morgan-performing-in-incredible-masturantion/',
171 'md5': '71d32c51584876472db87e561171a386',
172 'info_dict': {
173 'id': '8789287',
174 'display_id': 'unbelievable-malena-morgan-performing-in-incredible-masturantion',
175 'ext': 'mp4',
176 'title': 'Unbelievable Malena Morgan performing in incredible masturantion',
177 'uploader': 'Davit Sanchez',
178 'duration': 940,
179 'view_count': int,
180 'like_count': int,
181 'dislike_count': int,
182 'age_limit': 18,
d79c7e99 183 'thumbnail': 'https://tn.hotmovs.com/contents/videos_sources/8789000/8789287/screenshots/10.jpg',
add96eb9 184 },
389896df 185 }, {
186 'url': 'https://hotmovs.tube/videos/8789287/unbelievable-malena-morgan-performing-in-incredible-masturantion/',
187 'md5': '71d32c51584876472db87e561171a386',
188 'info_dict': {
189 'id': '8789287',
190 'display_id': 'unbelievable-malena-morgan-performing-in-incredible-masturantion',
191 'ext': 'mp4',
192 'title': 'Unbelievable Malena Morgan performing in incredible masturantion',
193 'uploader': 'Davit Sanchez',
194 'duration': 940,
195 'view_count': int,
196 'like_count': int,
197 'dislike_count': int,
198 'age_limit': 18,
d79c7e99 199 'thumbnail': 'https://tn.hotmovs.com/contents/videos_sources/8789000/8789287/screenshots/10.jpg',
add96eb9 200 },
389896df 201 }, {
202 'url': 'https://inporn.com/video/517897/malena-morgan-solo/',
203 'md5': '344db467481edf78f193cdf5820a7cfb',
204 'info_dict': {
205 'id': '517897',
206 'display_id': 'malena-morgan-solo',
207 'ext': 'mp4',
208 'title': 'Malena Morgan - Solo',
209 'uploader': 'Ashley Oxy',
210 'duration': 480,
211 'view_count': int,
212 'like_count': int,
213 'dislike_count': int,
214 'age_limit': 18,
d79c7e99 215 'thumbnail': 'https://iptn.m3pd.com/media/tn/sources/517897_1.jpg',
add96eb9 216 },
389896df 217 }, {
218 'url': 'https://privatehomeclips.com/videos/3630599/malena-morgan-cam-show/',
219 'md5': 'ea657273e352493c5fb6357fbfa4f126',
220 'info_dict': {
221 'id': '3630599',
222 'display_id': 'malena-morgan-cam-show',
223 'ext': 'mp4',
224 'title': 'malena morgan cam show',
225 'uploader': 'Member9915',
226 'duration': 290,
227 'view_count': int,
228 'like_count': int,
229 'dislike_count': int,
230 'age_limit': 18,
d79c7e99 231 'thumbnail': 'https://hctn.nv7s.com/contents/videos_sources/3630000/3630599/screenshots/15.jpg',
add96eb9 232 },
389896df 233 }, {
234 'url': 'https://tubepornclassic.com/videos/1015455/mimi-rogers-full-body-massage-nude-compilation/',
235 'md5': '2e9a6cf610c9862e86e0ce24f08f4427',
236 'info_dict': {
237 'id': '1015455',
238 'display_id': 'mimi-rogers-full-body-massage-nude-compilation',
239 'ext': 'mp4',
240 'title': 'Mimi Rogers - Full Body Massage (Nude) compilation',
241 'uploader': '88bhuto',
242 'duration': 286,
243 'view_count': int,
244 'like_count': int,
245 'dislike_count': int,
246 'age_limit': 18,
d79c7e99 247 'thumbnail': 'https://tn.tubepornclassic.com/contents/videos_sources/1015000/1015455/screenshots/6.jpg',
add96eb9 248 },
389896df 249 }, {
250 'url': 'https://upornia.com/videos/1498858/twistys-malena-morgan-starring-at-dr-morgan-baller/',
251 'md5': '7ff7033340bc88a173198b7c22600e4f',
252 'info_dict': {
253 'id': '1498858',
254 'display_id': 'twistys-malena-morgan-starring-at-dr-morgan-baller',
255 'ext': 'mp4',
256 'title': 'Twistys - Malena Morgan starring at Dr. Morgan-Baller',
257 'uploader': 'mindgeek',
258 'duration': 480,
259 'view_count': int,
260 'like_count': int,
261 'dislike_count': int,
262 'age_limit': 18,
d79c7e99 263 'thumbnail': 'https://tn.upornia.com/contents/videos_sources/1498000/1498858/screenshots/1.jpg',
add96eb9 264 },
389896df 265 }, {
266 'url': 'https://upornia.tube/videos/1498858/twistys-malena-morgan-starring-at-dr-morgan-baller/',
267 'md5': '7ff7033340bc88a173198b7c22600e4f',
268 'info_dict': {
269 'id': '1498858',
270 'display_id': 'twistys-malena-morgan-starring-at-dr-morgan-baller',
271 'ext': 'mp4',
272 'title': 'Twistys - Malena Morgan starring at Dr. Morgan-Baller',
273 'uploader': 'mindgeek',
274 'duration': 480,
275 'view_count': int,
276 'like_count': int,
277 'dislike_count': int,
278 'age_limit': 18,
d79c7e99 279 'thumbnail': 'https://tn.upornia.com/contents/videos_sources/1498000/1498858/screenshots/1.jpg',
add96eb9 280 },
389896df 281 }, {
282 'url': 'https://vjav.com/videos/11761/yui-hatano-in-if-yui-was-my-girlfriend2/',
283 'md5': '6de5bc1f13bdfc3491a77f23edb1676f',
284 'info_dict': {
285 'id': '11761',
286 'display_id': 'yui-hatano-in-if-yui-was-my-girlfriend2',
287 'ext': 'mp4',
288 'title': 'Yui Hatano in If Yui Was My Girlfriend',
289 'uploader': 'Matheus69',
290 'duration': 3310,
291 'view_count': int,
292 'like_count': int,
293 'dislike_count': int,
294 'age_limit': 18,
d79c7e99 295 'thumbnail': 'https://tn.vjav.com/contents/videos_sources/11000/11761/screenshots/23.jpg',
add96eb9 296 },
389896df 297 }, {
298 'url': 'https://vjav.tube/videos/11761/yui-hatano-in-if-yui-was-my-girlfriend2/',
299 'md5': '6de5bc1f13bdfc3491a77f23edb1676f',
300 'info_dict': {
301 'id': '11761',
302 'display_id': 'yui-hatano-in-if-yui-was-my-girlfriend2',
303 'ext': 'mp4',
304 'title': 'Yui Hatano in If Yui Was My Girlfriend',
305 'uploader': 'Matheus69',
306 'duration': 3310,
307 'view_count': int,
308 'like_count': int,
309 'dislike_count': int,
310 'age_limit': 18,
d79c7e99 311 'thumbnail': 'https://tn.vjav.com/contents/videos_sources/11000/11761/screenshots/23.jpg',
add96eb9 312 },
389896df 313 }, {
314 'url': 'https://voyeurhit.com/videos/332875/charlotte-stokely-elle-alexandra-malena-morgan-lingerie/',
315 'md5': '12b4666e9c3e60dafe9182e5d12aae33',
316 'info_dict': {
317 'id': '332875',
318 'display_id': 'charlotte-stokely-elle-alexandra-malena-morgan-lingerie',
319 'ext': 'mp4',
320 'title': 'Charlotte Stokely, Elle Alexandra, Malena Morgan-Lingerie',
321 'uploader': 'Kyle Roberts',
322 'duration': 655,
323 'view_count': int,
324 'like_count': int,
325 'dislike_count': int,
326 'age_limit': 18,
d79c7e99 327 'thumbnail': 'https://tn.voyeurhit.com/contents/videos_sources/332000/332875/screenshots/1.jpg',
add96eb9 328 },
389896df 329 }, {
330 'url': 'https://voyeurhit.tube/videos/332875/charlotte-stokely-elle-alexandra-malena-morgan-lingerie/',
331 'md5': '12b4666e9c3e60dafe9182e5d12aae33',
332 'info_dict': {
333 'id': '332875',
334 'display_id': 'charlotte-stokely-elle-alexandra-malena-morgan-lingerie',
335 'ext': 'mp4',
336 'title': 'Charlotte Stokely, Elle Alexandra, Malena Morgan-Lingerie',
337 'uploader': 'Kyle Roberts',
338 'duration': 655,
339 'view_count': int,
340 'like_count': int,
341 'dislike_count': int,
342 'age_limit': 18,
d79c7e99 343 'thumbnail': 'https://tn.voyeurhit.com/contents/videos_sources/332000/332875/screenshots/1.jpg',
add96eb9 344 },
389896df 345 }]
346 _WEBPAGE_TESTS = [{
347 'url': 'https://pornzog.com/video/9125519/michelle-malone-dreamgirls-wild-wet-3/',
348 'info_dict': {
349 'id': '5119660',
350 'display_id': '5119660',
351 'ext': 'mp4',
352 'title': 'Michelle Malone - Dreamgirls - Wild Wet 3',
353 'uploader': 'FallenAngel12',
354 'duration': 402,
355 'view_count': int,
356 'like_count': int,
357 'dislike_count': int,
358 'age_limit': 18,
d79c7e99 359 'thumbnail': 'https://hctn.nv7s.com/contents/videos_sources/5119000/5119660/screenshots/1.jpg',
add96eb9 360 },
389896df 361 }]
362
363 def _call_api(self, url, video_id, fatal=False, **kwargs):
364 content = self._download_json(url, video_id, fatal=fatal, **kwargs)
365 if traverse_obj(content, 'error'):
366 raise self._error_or_warning(ExtractorError(
367 f'Txxx said: {content["error"]}', expected=True), fatal=fatal)
368 return content or {}
369
370 def _real_extract(self, url):
371 video_id, host, display_id = self._match_valid_url(url).group('id', 'host', 'display_id')
372 headers = {'Referer': url, 'X-Requested-With': 'XMLHttpRequest'}
373
374 video_file = self._call_api(
375 f'https://{host}/api/videofile.php?video_id={video_id}&lifetime=8640000',
376 video_id, fatal=True, note='Downloading video file info', headers=headers)
377
378 slug = f'{int(1E6 * (int(video_id) // 1E6))}/{1000 * (int(video_id) // 1000)}'
379 video_info = self._call_api(
380 f'https://{host}/api/json/video/86400/{slug}/{video_id}.json',
381 video_id, note='Downloading video info', headers=headers)
382
383 return {
384 'id': video_id,
385 'display_id': display_id,
386 'title': traverse_obj(video_info, ('video', 'title')),
387 'uploader': traverse_obj(video_info, ('video', 'user', 'username')),
388 'duration': parse_duration(traverse_obj(video_info, ('video', 'duration'))),
389 'view_count': int_or_none(traverse_obj(video_info, ('video', 'statistics', 'viewed'))),
390 'like_count': int_or_none(traverse_obj(video_info, ('video', 'statistics', 'likes'))),
391 'dislike_count': int_or_none(traverse_obj(video_info, ('video', 'statistics', 'dislikes'))),
392 'age_limit': 18,
d79c7e99 393 'thumbnail': traverse_obj(video_info, ('video', 'thumbsrc', {url_or_none})),
389896df 394 'formats': get_formats(host, video_file),
395 }
396
397
398class PornTopIE(InfoExtractor):
399 _VALID_URL = r'https?://(?P<host>(?:www\.)?porntop\.com)/video/(?P<id>\d+)(?:/(?P<display_id>[^/?]+))?'
400 _TESTS = [{
401 'url': 'https://porntop.com/video/101569/triple-threat-with-lia-lor-malena-morgan-and-dani-daniels/',
402 'md5': '612ba7b3cb99455b382972948e200b08',
403 'info_dict': {
404 'id': '101569',
405 'display_id': 'triple-threat-with-lia-lor-malena-morgan-and-dani-daniels',
406 'ext': 'mp4',
407 'title': 'Triple Threat With Lia Lor, Malena Morgan And Dani Daniels',
408 'description': 'md5:285357d9d3a00ce5acb29f39f826dbf6',
409 'uploader': 'PatrickBush',
410 'duration': 480,
411 'view_count': int,
412 'like_count': int,
413 'dislike_count': int,
414 'age_limit': 18,
415 'timestamp': 1609455029,
416 'upload_date': '20201231',
417 'thumbnail': 'https://tn.porntop.com/media/tn/sources/101569_1.jpg',
add96eb9 418 },
389896df 419 }]
420
421 def _real_extract(self, url):
422 video_id, host, display_id = self._match_valid_url(url).group('id', 'host', 'display_id')
423 webpage = self._download_webpage(url, video_id)
424
425 json_ld = self._json_ld(self._search_json(
426 r'\bschemaJson\s*=', webpage, 'JSON-LD', video_id, transform_source=js_to_json,
427 contains_pattern='{[^<]+?VideoObject[^<]+};'), video_id, fatal=True)
428
429 video_file = self._parse_json(decode_base64(self._search_regex(
430 r"window\.initPlayer\(.*}}},\s*'(?P<json_b64c>[^']+)'",
431 webpage, 'json_urls', group='json_b64c')), video_id)
432
433 return merge_dicts({
434 'id': video_id,
435 'display_id': display_id,
436 'age_limit': 18,
437 'formats': get_formats(host, video_file),
438 }, json_ld)