txxx.py 17 KB

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