ellentube.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. from .common import InfoExtractor
  2. from ..utils import (
  3. clean_html,
  4. extract_attributes,
  5. float_or_none,
  6. int_or_none,
  7. try_get,
  8. )
  9. class EllenTubeBaseIE(InfoExtractor):
  10. def _extract_data_config(self, webpage, video_id):
  11. details = self._search_regex(
  12. r'(<[^>]+\bdata-component=(["\'])[Dd]etails.+?></div>)', webpage,
  13. 'details')
  14. return self._parse_json(
  15. extract_attributes(details)['data-config'], video_id)
  16. def _extract_video(self, data, video_id):
  17. title = data['title']
  18. formats = []
  19. duration = None
  20. for entry in data.get('media'):
  21. if entry.get('id') == 'm3u8':
  22. formats, subtitles = self._extract_m3u8_formats_and_subtitles(
  23. entry['url'], video_id, 'mp4',
  24. entry_protocol='m3u8_native', m3u8_id='hls')
  25. duration = int_or_none(entry.get('duration'))
  26. break
  27. def get_insight(kind):
  28. return int_or_none(try_get(
  29. data, lambda x: x['insight']['%ss' % kind]))
  30. return {
  31. 'extractor_key': EllenTubeIE.ie_key(),
  32. 'id': video_id,
  33. 'title': title,
  34. 'description': data.get('description'),
  35. 'duration': duration,
  36. 'thumbnail': data.get('thumbnail'),
  37. 'timestamp': float_or_none(data.get('publishTime'), scale=1000),
  38. 'view_count': get_insight('view'),
  39. 'like_count': get_insight('like'),
  40. 'formats': formats,
  41. 'subtitles': subtitles,
  42. }
  43. class EllenTubeIE(EllenTubeBaseIE):
  44. _VALID_URL = r'''(?x)
  45. (?:
  46. ellentube:|
  47. https://api-prod\.ellentube\.com/ellenapi/api/item/
  48. )
  49. (?P<id>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})
  50. '''
  51. _TESTS = [{
  52. 'url': 'https://api-prod.ellentube.com/ellenapi/api/item/0822171c-3829-43bf-b99f-d77358ae75e3',
  53. 'md5': '2fabc277131bddafdd120e0fc0f974c9',
  54. 'info_dict': {
  55. 'id': '0822171c-3829-43bf-b99f-d77358ae75e3',
  56. 'ext': 'mp4',
  57. 'title': 'Ellen Meets Las Vegas Survivors Jesus Campos and Stephen Schuck',
  58. 'description': 'md5:76e3355e2242a78ad9e3858e5616923f',
  59. 'thumbnail': r're:^https?://.+?',
  60. 'duration': 514,
  61. 'timestamp': 1508505120,
  62. 'upload_date': '20171020',
  63. 'view_count': int,
  64. 'like_count': int,
  65. }
  66. }, {
  67. 'url': 'ellentube:734a3353-f697-4e79-9ca9-bfc3002dc1e0',
  68. 'only_matching': True,
  69. }]
  70. def _real_extract(self, url):
  71. video_id = self._match_id(url)
  72. data = self._download_json(
  73. 'https://api-prod.ellentube.com/ellenapi/api/item/%s' % video_id,
  74. video_id)
  75. return self._extract_video(data, video_id)
  76. class EllenTubeVideoIE(EllenTubeBaseIE):
  77. _VALID_URL = r'https?://(?:www\.)?ellentube\.com/video/(?P<id>.+?)\.html'
  78. _TEST = {
  79. 'url': 'https://www.ellentube.com/video/ellen-meets-las-vegas-survivors-jesus-campos-and-stephen-schuck.html',
  80. 'only_matching': True,
  81. }
  82. def _real_extract(self, url):
  83. display_id = self._match_id(url)
  84. webpage = self._download_webpage(url, display_id)
  85. video_id = self._extract_data_config(webpage, display_id)['id']
  86. return self.url_result(
  87. 'ellentube:%s' % video_id, ie=EllenTubeIE.ie_key(),
  88. video_id=video_id)
  89. class EllenTubePlaylistIE(EllenTubeBaseIE):
  90. _VALID_URL = r'https?://(?:www\.)?ellentube\.com/(?:episode|studios)/(?P<id>.+?)\.html'
  91. _TESTS = [{
  92. 'url': 'https://www.ellentube.com/episode/dax-shepard-jordan-fisher-haim.html',
  93. 'info_dict': {
  94. 'id': 'dax-shepard-jordan-fisher-haim',
  95. 'title': "Dax Shepard, 'DWTS' Team Jordan Fisher & Lindsay Arnold, HAIM",
  96. 'description': 'md5:bfc982194dabb3f4e325e43aa6b2e21c',
  97. },
  98. 'playlist_count': 6,
  99. }, {
  100. 'url': 'https://www.ellentube.com/studios/macey-goes-rving0.html',
  101. 'only_matching': True,
  102. }]
  103. def _real_extract(self, url):
  104. display_id = self._match_id(url)
  105. webpage = self._download_webpage(url, display_id)
  106. data = self._extract_data_config(webpage, display_id)['data']
  107. feed = self._download_json(
  108. 'https://api-prod.ellentube.com/ellenapi/api/feed/?%s'
  109. % data['filter'], display_id)
  110. entries = [
  111. self._extract_video(elem, elem['id'])
  112. for elem in feed if elem.get('type') == 'VIDEO' and elem.get('id')]
  113. return self.playlist_result(
  114. entries, display_id, data.get('title'),
  115. clean_html(data.get('description')))