From 9d2b2f9b1e48db58a2293b8b9a55a19b4d293ed4 Mon Sep 17 00:00:00 2001 From: tabjy Date: Sat, 29 Oct 2022 02:35:12 -0400 Subject: [PATCH] [VXXX] Refactor and apply further code review suggestions --- youtube_dl/extractor/bdsmxtube.py | 44 ------- youtube_dl/extractor/blackporntube.py | 44 ------- youtube_dl/extractor/extractors.py | 5 - youtube_dl/extractor/inporn.py | 43 ------- youtube_dl/extractor/mrgay.py | 43 ------- youtube_dl/extractor/vxxx.py | 173 +++++++++++++++++++++----- youtube_dl/extractor/xmilf.py | 43 ------- 7 files changed, 144 insertions(+), 251 deletions(-) delete mode 100644 youtube_dl/extractor/bdsmxtube.py delete mode 100644 youtube_dl/extractor/blackporntube.py delete mode 100644 youtube_dl/extractor/inporn.py delete mode 100644 youtube_dl/extractor/mrgay.py delete mode 100644 youtube_dl/extractor/xmilf.py diff --git a/youtube_dl/extractor/bdsmxtube.py b/youtube_dl/extractor/bdsmxtube.py deleted file mode 100644 index ef0769c03..000000000 --- a/youtube_dl/extractor/bdsmxtube.py +++ /dev/null @@ -1,44 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .vxxx import VXXXIE - - -class BdsmxTubeIE(VXXXIE): - _VALID_URL = r'https?://bdsmx\.tube/video/(?P\d+)' - _TESTS = [{ - 'url': 'https://bdsmx.tube/video/127583/latex-puppy-leashed/', - 'md5': '79751d4ed75668afe07a660c4bcb2f1b', - 'info_dict': { - 'id': '127583', - 'ext': 'mp4', - 'title': 'Latex Puppy Leashed', - 'display_id': 'latex-puppy-leashed', - 'thumbnail': 'https://tn.bdsmx-porn.com/contents/videos_screenshots/127000/127583/480x270/1.jpg', - 'description': '', - 'timestamp': 1651003323, - 'upload_date': '20220426', - 'duration': 68.0, - 'categories': ['Asian', 'Brunette', 'Cosplay', 'Fetish', - 'Fuck Machine', 'Gagging', 'Japanese', - 'JAV Uncensored', 'Latex', 'Leather', 'POV'], - 'age_limit': 18, - } - }] - - def _download_info_object(self, video_id): - return self._download_json( - 'https://bdsmx.tube/api/json/video/86400/0/{0}/{1}.json'.format( - int(video_id) // 1000 * 1000, - video_id, - ), video_id, headers={'Referer': 'https://bdsmx.tube'})['video'] - - def _download_format_object(self, video_id): - return self._download_json( - 'https://bdsmx.tube/api/videofile.php?video_id={0}'.format(video_id), - video_id, - headers={'Referer': 'https://bdsmx.tube'} - ) - - def _get_video_host(self): - return 'bdsmx.tube' diff --git a/youtube_dl/extractor/blackporntube.py b/youtube_dl/extractor/blackporntube.py deleted file mode 100644 index 12168fcb9..000000000 --- a/youtube_dl/extractor/blackporntube.py +++ /dev/null @@ -1,44 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .vxxx import VXXXIE - - -class BlackPornTubeIE(VXXXIE): - _VALID_URL = r'https?://blackporn\.tube/video/(?P\d+)' - _TESTS = [{ - 'url': 'https://blackporn.tube/video/10043813/young-ebony-babe-gets-super-wet/', - 'md5': '4a4c126970f2f1453b8b2050947fc870', - 'info_dict': { - 'id': '10043813', - 'ext': 'mp4', - 'title': 'Young Ebony Babe Gets Super Wet', - 'display_id': 'young-ebony-babe-gets-super-wet', - 'thumbnail': 'https://tn.blackporn.tube/contents/videos_screenshots/10043000/10043813/480x270/1.jpg', - 'description': '', - 'timestamp': 1654806141, - 'upload_date': '20220609', - 'duration': 193.0, - 'categories': ['BDSM', 'Bondage', 'Celebrity', 'Ebony', 'Fetish', - 'Shibari Bondage', 'Solo Female', - 'Tattoo'], - 'age_limit': 18, - } - }] - - def _download_info_object(self, video_id): - return self._download_json( - 'https://blackporn.tube/api/json/video/86400/0/{}/{}.json'.format( - int(video_id) // 1000 * 1000, - video_id, - ), video_id, headers={'Referer': 'https://blackporn.tube'})['video'] - - def _download_format_object(self, video_id): - return self._download_json( - 'https://blackporn.tube/api/videofile.php?video_id={}'.format(video_id), - video_id, - headers={'Referer': 'https://blackporn.tube'} - ) - - def _get_video_host(self): - return 'blackporn.tube' diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index df68e2f62..d74169aad 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -106,7 +106,6 @@ from .bbc import ( BBCCoUkPlaylistIE, BBCIE, ) -from .bdsmxtube import BdsmxTubeIE from .beeg import BeegIE from .behindkink import BehindKinkIE from .bellmedia import BellMediaIE @@ -139,7 +138,6 @@ from .bleacherreport import ( BleacherReportIE, BleacherReportCMSIE, ) -from .blackporntube import BlackPornTubeIE from .bloomberg import BloombergIE from .bokecc import BokeCCIE from .bongacams import BongaCamsIE @@ -522,7 +520,6 @@ from .instagram import ( ) from .internazionale import InternazionaleIE from .internetvideoarchive import InternetVideoArchiveIE -from .inporn import InPornIE from .iprima import IPrimaIE from .iqiyi import IqiyiIE from .ir90tv import Ir90TvIE @@ -675,7 +672,6 @@ from .metacritic import MetacriticIE from .mgoon import MgoonIE from .mgtv import MGTVIE from .miaopai import MiaoPaiIE -from .mrgay import MrGayIE from .microsoftvirtualacademy import ( MicrosoftVirtualAcademyIE, MicrosoftVirtualAcademyCourseIE, @@ -1589,7 +1585,6 @@ from .ximalaya import ( XimalayaAlbumIE ) from .xminus import XMinusIE -from .xmilf import XMilfIE from .xnxx import XNXXIE from .xstream import XstreamIE from .xtube import XTubeUserIE, XTubeIE diff --git a/youtube_dl/extractor/inporn.py b/youtube_dl/extractor/inporn.py deleted file mode 100644 index ab68c9f02..000000000 --- a/youtube_dl/extractor/inporn.py +++ /dev/null @@ -1,43 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .vxxx import VXXXIE - - -class InPornIE(VXXXIE): - _VALID_URL = r'https?://(?:www\.)?inporn\.com/video/(?P\d+)' - _TESTS = [{ - 'url': 'https://inporn.com/video/533613/2k-t-2nd-season-parm-151/', - 'md5': 'c358d1da6b451ebe7cfb00dd89741607', - 'info_dict': { - 'id': '533613', - 'ext': 'mp4', - 'title': '2k 美月まい - ガーリー系アパレルモt゙ルの挑発パンチラ 2nd Season [parm-151]', - 'display_id': '2k-t-2nd-season-parm-151', - 'thumbnail': 'https://tn.inporn.com/media/tn/533613_1.jpg', - 'description': '', - 'timestamp': 1664571262, - 'upload_date': '20220930', - 'duration': 480.0, - 'categories': ['Asian', 'Brunette', 'Casting', 'HD', 'Japanese', - 'JAV Uncensored'], - 'age_limit': 18, - }, - }] - - def _download_info_object(self, video_id): - return self._download_json( - 'https://inporn.com/api/json/video/86400/0/{}/{}.json'.format( - int(video_id) // 1000 * 1000, - video_id, - ), video_id, headers={'Referer': 'https://inporn.com'})['video'] - - def _download_format_object(self, video_id): - return self._download_json( - 'https://inporn.com/api/videofile.php?video_id={}'.format(video_id), - video_id, - headers={'Referer': 'https://inporn.com'} - ) - - def _get_video_host(self): - return 'inporn.com' diff --git a/youtube_dl/extractor/mrgay.py b/youtube_dl/extractor/mrgay.py deleted file mode 100644 index ad827f422..000000000 --- a/youtube_dl/extractor/mrgay.py +++ /dev/null @@ -1,43 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .vxxx import VXXXIE - - -class MrGayIE(VXXXIE): - _VALID_URL = r'https?://mrgay\.com/video/(?P\d+)' - _TESTS = [{ - 'url': 'https://mrgay.com/video/10169199/jpn-crossdresser-6/', - 'md5': 'b5780a9437c205b4bc87eb939b23e8ef', - 'info_dict': { - 'id': '10169199', - 'ext': 'mp4', - 'title': 'Jpn Crossdresser 6', - 'display_id': 'jpn-crossdresser-6', - 'thumbnail': 'https://tn.mrgay.com/media/tn/10169199_1.jpg', - 'description': '', - 'timestamp': 1651066888, - 'upload_date': '20220427', - 'duration': 834.0, - 'categories': ['Amateur', 'Asian', 'Brunette', 'Crossdressing', - 'Japanese', 'Webcam'], - 'age_limit': 18, - } - }] - - def _download_info_object(self, video_id): - return self._download_json( - 'https://mrgay.com/api/json/video/86400/0/{}/{}.json'.format( - int(video_id) // 1000 * 1000, - video_id, - ), video_id, headers={'Referer': 'https://mrgay.com'})['video'] - - def _download_format_object(self, video_id): - return self._download_json( - 'https://mrgay.com/api/videofile.php?video_id={}'.format(video_id), - video_id, - headers={'Referer': 'https://mrgay.com'} - ) - - def _get_video_host(self): - return 'mrgay.com' diff --git a/youtube_dl/extractor/vxxx.py b/youtube_dl/extractor/vxxx.py index 014ae808e..6b37c8128 100644 --- a/youtube_dl/extractor/vxxx.py +++ b/youtube_dl/extractor/vxxx.py @@ -2,12 +2,15 @@ from __future__ import unicode_literals import base64 -import re from .common import InfoExtractor from ..utils import ( + float_or_none, + int_or_none, parse_duration, + strip_or_none, unified_timestamp, + url_or_none, ) @@ -22,7 +25,7 @@ class VXXXIE(InfoExtractor): 'title': 'Monica Aka Selina', 'display_id': 'monica-aka-selina', 'thumbnail': 'https://tn.vxxx.com/contents/videos_screenshots/80000/80747/420x236/1.jpg', - 'description': '', + 'description': None, 'timestamp': 1607167706, 'upload_date': '20201205', 'duration': 2373.0, @@ -32,6 +35,10 @@ class VXXXIE(InfoExtractor): } }] + _BASE_URL = 'https://vxxx.com' + _INFO_OBJECT_URL_TMPL = '{0}/api/json/video/86400/0/{1}/{2}.json' + _FORMAT_OBJECT_URL_TMPL = '{0}/api/videofile.php?video_id={1}' + def _download_info_object(self, video_id): return self._download_json( self._INFO_OBJECT_URL_TMPL.format( @@ -47,11 +54,6 @@ class VXXXIE(InfoExtractor): headers={'Referer': self._BASE_URL} ) - @classmethod - def _get_video_host(cls): - # or use the proper Python URL parsing functions - return cls._BASE_URL.split('//')[-1] - def _decode_base164(self, e): """ Some non-standard encoding called "base164" in the JavaScript code. It's @@ -61,21 +63,19 @@ class VXXXIE(InfoExtractor): - "~" is used for padding instead of "=" """ - # using the kwarg to memoise the result - def get_trans_tbl(from_, to, tbl={}): - k = (from_, to) - if not tbl.get(k): - tbl[k] = string.maketrans(from_, to) - return tbl[k] + # using the kwarg to memoise the result + def get_trans_tbl(from_, to, tbl={}): + k = (from_, to) + if not tbl.get(k): + tbl[k] = str.maketrans(from_, to) + return tbl[k] - # maybe for the 2nd arg: - # import unicodedata and - # ''.join((unicodedata.lookup('CYRILLIC CAPITAL LETTER ' + x) for x in ('A', 'BE', 'ES', 'IE', 'EM'))) + '+/=' - trans_tbl = get_trans_tbl('АBCEM.,~', 'ABCEM+/=') - return base64.b64decode(e.translate(trans_tbl) - ).decode() + trans_tbl = get_trans_tbl( + '\u0410\u0412\u0421\u0415\u041c.,~', + 'ABCEM+/=') + return base64.b64decode(e.translate(trans_tbl)).decode() - def _extract_info(self, url): + def _real_extract(self, url): video_id = self._match_id(url) info_object = self._download_info_object(video_id) @@ -87,21 +87,22 @@ class VXXXIE(InfoExtractor): 'title': title, 'display_id': info_object.get('dir'), 'thumbnail': url_or_none(info_object.get('thumb')), - 'description': strip_or_none(info_object('description')) or None, + 'description': strip_or_none(info_object.get('description')) or None, 'timestamp': unified_timestamp(info_object.get('post_date')), 'duration': parse_duration(info_object.get('duration')), 'view_count': int_or_none(stats.get('viewed')), 'like_count': int_or_none(stats.get('likes')), 'dislike_count': int_or_none(stats.get('dislikes')), 'average_rating': float_or_none(stats.get('rating')), - 'categories': [category['title'] for category in (info_object.get('categories') or {}).values() if category.get('title')], + 'categories': [category['title'] for category in (info_object.get('categories') or {}).values() + if category.get('title')], 'age_limit': 18, } format_object = self._download_format_object(video_id) m3u8_formats = self._extract_m3u8_formats( - 'https://{0}{1}&f=video.m3u8'.format( - self._get_video_host(), + '{0}/{1}&f=video.m3u8'.format( + self._BASE_URL, self._decode_base164(format_object[0]['video_url']) ), video_id, 'mp4') @@ -110,10 +111,124 @@ class VXXXIE(InfoExtractor): return info - def _real_extract(self, url): - info = self._extract_info(url) - if not info['formats']: - return self.url_result(url, 'Generic') +class BdsmxTubeIE(VXXXIE): + _VALID_URL = r'https?://bdsmx\.tube/video/(?P\d+)' + _TESTS = [{ + 'url': 'https://bdsmx.tube/video/127583/latex-puppy-leashed/', + 'md5': '79751d4ed75668afe07a660c4bcb2f1b', + 'info_dict': { + 'id': '127583', + 'ext': 'mp4', + 'title': 'Latex Puppy Leashed', + 'display_id': 'latex-puppy-leashed', + 'thumbnail': 'https://tn.bdsmx-porn.com/contents/videos_screenshots/127000/127583/480x270/1.jpg', + 'description': None, + 'timestamp': 1651003323, + 'upload_date': '20220426', + 'duration': 68.0, + 'categories': ['Asian', 'Brunette', 'Cosplay', 'Fetish', + 'Fuck Machine', 'Gagging', 'Japanese', + 'JAV Uncensored', 'Latex', 'Leather', 'POV'], + 'age_limit': 18, + } + }] - return info + _BASE_URL = 'https://bdsmx.tube' + + +class BlackPornTubeIE(VXXXIE): + _VALID_URL = r'https?://blackporn\.tube/video/(?P\d+)' + _TESTS = [{ + 'url': 'https://blackporn.tube/video/10043813/young-ebony-babe-gets-super-wet/', + 'md5': '4a4c126970f2f1453b8b2050947fc870', + 'info_dict': { + 'id': '10043813', + 'ext': 'mp4', + 'title': 'Young Ebony Babe Gets Super Wet', + 'display_id': 'young-ebony-babe-gets-super-wet', + 'thumbnail': 'https://tn.blackporn.tube/contents/videos_screenshots/10043000/10043813/480x270/1.jpg', + 'description': None, + 'timestamp': 1654806141, + 'upload_date': '20220609', + 'duration': 193.0, + 'categories': ['BDSM', 'Bondage', 'Celebrity', 'Ebony', 'Fetish', + 'Shibari Bondage', 'Solo Female', + 'Tattoo'], + 'age_limit': 18, + } + }] + + _BASE_URL = 'https://blackporn.tube' + + +class InPornIE(VXXXIE): + _VALID_URL = r'https?://(?:www\.)?inporn\.com/video/(?P\d+)' + _TESTS = [{ + 'url': 'https://inporn.com/video/533613/2k-t-2nd-season-parm-151/', + 'md5': 'c358d1da6b451ebe7cfb00dd89741607', + 'info_dict': { + 'id': '533613', + 'ext': 'mp4', + 'title': '2k 美月まい - ガーリー系アパレルモt゙ルの挑発パンチラ 2nd Season [parm-151]', + 'display_id': '2k-t-2nd-season-parm-151', + 'thumbnail': 'https://tn.inporn.com/media/tn/533613_1.jpg', + 'description': None, + 'timestamp': 1664571262, + 'upload_date': '20220930', + 'duration': 480.0, + 'categories': ['Asian', 'Brunette', 'Casting', 'HD', 'Japanese', + 'JAV Uncensored'], + 'age_limit': 18, + }, + }] + + _BASE_URL = 'https://inporn.com' + + +class MrGayIE(VXXXIE): + _VALID_URL = r'https?://mrgay\.com/video/(?P\d+)' + _TESTS = [{ + 'url': 'https://mrgay.com/video/10169199/jpn-crossdresser-6/', + 'md5': 'b5780a9437c205b4bc87eb939b23e8ef', + 'info_dict': { + 'id': '10169199', + 'ext': 'mp4', + 'title': 'Jpn Crossdresser 6', + 'display_id': 'jpn-crossdresser-6', + 'thumbnail': 'https://tn.mrgay.com/media/tn/10169199_1.jpg', + 'description': None, + 'timestamp': 1651066888, + 'upload_date': '20220427', + 'duration': 834.0, + 'categories': ['Amateur', 'Asian', 'Brunette', 'Crossdressing', + 'Japanese', 'Webcam'], + 'age_limit': 18, + } + }] + + _BASE_URL = 'https://mrgay.com' + + +class XMilfIE(VXXXIE): + _VALID_URL = r'https?://xmilf\.com/video/(?P\d+)' + _TESTS = [{ + 'url': 'https://xmilf.com/video/143777/big-boob-brunette-masturbates3/', + 'md5': 'a196fe8daebe194a758754c81e9232ad', + 'info_dict': { + 'id': '143777', + 'ext': 'mp4', + 'title': 'Big Boob Brunette Masturbates', + 'display_id': 'big-boob-brunette-masturbates3', + 'thumbnail': 'https://tn.xmilf.com/contents/videos_screenshots/143000/143777/480x270/1.jpg', + 'description': None, + 'timestamp': 1662465481, + 'upload_date': '20220906', + 'duration': 480.0, + 'categories': ['Amateur', 'Big Tits', 'Brunette', 'Fetish', 'HD', + 'Lingerie', 'MILF', 'Webcam'], + 'age_limit': 18, + } + }] + + _BASE_URL = 'https://xmilf.com' diff --git a/youtube_dl/extractor/xmilf.py b/youtube_dl/extractor/xmilf.py deleted file mode 100644 index d3a749402..000000000 --- a/youtube_dl/extractor/xmilf.py +++ /dev/null @@ -1,43 +0,0 @@ -# coding: utf-8 -from __future__ import unicode_literals - -from .vxxx import VXXXIE - - -class XMilfIE(VXXXIE): - _VALID_URL = r'https?://xmilf\.com/video/(?P\d+)' - _TESTS = [{ - 'url': 'https://xmilf.com/video/143777/big-boob-brunette-masturbates3/', - 'md5': 'a196fe8daebe194a758754c81e9232ad', - 'info_dict': { - 'id': '143777', - 'ext': 'mp4', - 'title': 'Big Boob Brunette Masturbates', - 'display_id': 'big-boob-brunette-masturbates3', - 'thumbnail': 'https://tn.xmilf.com/contents/videos_screenshots/143000/143777/480x270/1.jpg', - 'description': '', - 'timestamp': 1662465481, - 'upload_date': '20220906', - 'duration': 480.0, - 'categories': ['Amateur', 'Big Tits', 'Brunette', 'Fetish', 'HD', - 'Lingerie', 'MILF', 'Webcam'], - 'age_limit': 18, - } - }] - - def _download_info_object(self, video_id): - return self._download_json( - 'https://xmilf.com/api/json/video/86400/0/{}/{}.json'.format( - int(video_id) // 1000 * 1000, - video_id, - ), video_id, headers={'Referer': 'https://xmilf.com'})['video'] - - def _download_format_object(self, video_id): - return self._download_json( - 'https://xmilf.com/api/videofile.php?video_id={}'.format(video_id), - video_id, - headers={'Referer': 'https://xmilf.com'} - ) - - def _get_video_host(self): - return 'xmilf.com'