mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-27 09:41:26 +01:00
Compare commits
No commits in common. "1791d713f82e58e86b503dc05a9905ebada3c9e9" and "c04db59adbdfe9b6bedd99d0842a5bffae883ecf" have entirely different histories.
1791d713f8
...
c04db59adb
|
@ -1782,6 +1782,7 @@ from .rumble import (
|
||||||
)
|
)
|
||||||
from .rutube import (
|
from .rutube import (
|
||||||
RutubeChannelIE,
|
RutubeChannelIE,
|
||||||
|
RutubeCustomPlaylistIE,
|
||||||
RutubeEmbedIE,
|
RutubeEmbedIE,
|
||||||
RutubeIE,
|
RutubeIE,
|
||||||
RutubeMovieIE,
|
RutubeMovieIE,
|
||||||
|
|
|
@ -5,9 +5,7 @@ from ..utils import (
|
||||||
bool_or_none,
|
bool_or_none,
|
||||||
determine_ext,
|
determine_ext,
|
||||||
int_or_none,
|
int_or_none,
|
||||||
js_to_json,
|
|
||||||
parse_qs,
|
parse_qs,
|
||||||
str_or_none,
|
|
||||||
try_get,
|
try_get,
|
||||||
unified_timestamp,
|
unified_timestamp,
|
||||||
url_or_none,
|
url_or_none,
|
||||||
|
@ -219,6 +217,10 @@ class RutubeIE(RutubeBaseIE):
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def suitable(cls, url):
|
||||||
|
return False if RutubePlaylistIE.suitable(url) else super().suitable(url)
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
video_id = self._match_id(url)
|
video_id = self._match_id(url)
|
||||||
query = parse_qs(url)
|
query = parse_qs(url)
|
||||||
|
@ -374,21 +376,43 @@ class RutubePersonIE(RutubePlaylistBaseIE):
|
||||||
class RutubePlaylistIE(RutubePlaylistBaseIE):
|
class RutubePlaylistIE(RutubePlaylistBaseIE):
|
||||||
IE_NAME = 'rutube:playlist'
|
IE_NAME = 'rutube:playlist'
|
||||||
IE_DESC = 'Rutube playlists'
|
IE_DESC = 'Rutube playlists'
|
||||||
_VALID_URL = r'https?://rutube\.ru/plst/(?P<id>\d+)'
|
_VALID_URL = r'https?://rutube\.ru/(?:video|(?:play/)?embed)/[\da-z]{32}/\?.*?\bpl_id=(?P<id>\d+)'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://rutube.ru/plst/308547/',
|
'url': 'https://rutube.ru/video/cecd58ed7d531fc0f3d795d51cee9026/?pl_id=3097&pl_type=tag',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '308547',
|
'id': '3097',
|
||||||
},
|
},
|
||||||
'playlist_mincount': 22,
|
'playlist_count': 27,
|
||||||
|
}, {
|
||||||
|
'url': 'https://rutube.ru/video/10b3a03fc01d5bbcc632a2f3514e8aab/?pl_id=4252&pl_type=source',
|
||||||
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
_PAGE_TEMPLATE = 'https://rutube.ru/api/playlist/custom/%s/videos?page=%s&format=json'
|
|
||||||
|
_PAGE_TEMPLATE = 'https://rutube.ru/api/playlist/%s/%s/?page=%s&format=json'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def suitable(cls, url):
|
||||||
|
from ..utils import int_or_none, parse_qs
|
||||||
|
|
||||||
|
if not super().suitable(url):
|
||||||
|
return False
|
||||||
|
params = parse_qs(url)
|
||||||
|
return params.get('pl_type', [None])[0] and int_or_none(params.get('pl_id', [None])[0])
|
||||||
|
|
||||||
|
def _next_page_url(self, page_num, playlist_id, item_kind):
|
||||||
|
return self._PAGE_TEMPLATE % (item_kind, playlist_id, page_num)
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
qs = parse_qs(url)
|
||||||
|
playlist_kind = qs['pl_type'][0]
|
||||||
|
playlist_id = qs['pl_id'][0]
|
||||||
|
return self._extract_playlist(playlist_id, item_kind=playlist_kind)
|
||||||
|
|
||||||
|
|
||||||
class RutubeChannelIE(RutubePlaylistBaseIE):
|
class RutubeChannelIE(RutubePlaylistBaseIE):
|
||||||
IE_NAME = 'rutube:channel'
|
IE_NAME = 'rutube:channel'
|
||||||
IE_DESC = 'Rutube channel'
|
IE_DESC = 'Rutube channel'
|
||||||
_VALID_URL = r'https?://rutube\.ru/(?:channel/(?P<id>\d+)|u/(?P<slug>\w+))(?:/(?P<section>videos|shorts))?'
|
_VALID_URL = r'https?://rutube\.ru/channel/(?P<id>\d+)/(?P<section>videos|shorts)'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://rutube.ru/channel/639184/videos/',
|
'url': 'https://rutube.ru/channel/639184/videos/',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
|
@ -401,18 +425,6 @@ class RutubeChannelIE(RutubePlaylistBaseIE):
|
||||||
'id': '25902603_shorts',
|
'id': '25902603_shorts',
|
||||||
},
|
},
|
||||||
'playlist_mincount': 277,
|
'playlist_mincount': 277,
|
||||||
}, {
|
|
||||||
'url': 'https://rutube.ru/channel/25902603/',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '25902603',
|
|
||||||
},
|
|
||||||
'playlist_mincount': 406,
|
|
||||||
}, {
|
|
||||||
'url': 'https://rutube.ru/u/rutube/videos/',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '23704195_videos',
|
|
||||||
},
|
|
||||||
'playlist_mincount': 113,
|
|
||||||
}]
|
}]
|
||||||
|
|
||||||
_PAGE_TEMPLATE = 'https://rutube.ru/api/video/person/%s/?page=%s&format=json&origin__type=%s'
|
_PAGE_TEMPLATE = 'https://rutube.ru/api/video/person/%s/?page=%s&format=json&origin__type=%s'
|
||||||
|
@ -421,20 +433,25 @@ class RutubeChannelIE(RutubePlaylistBaseIE):
|
||||||
origin_type = {
|
origin_type = {
|
||||||
'videos': 'rtb,rst,ifrm,rspa',
|
'videos': 'rtb,rst,ifrm,rspa',
|
||||||
'shorts': 'rshorts',
|
'shorts': 'rshorts',
|
||||||
None: '',
|
|
||||||
}.get(section)
|
}.get(section)
|
||||||
return self._PAGE_TEMPLATE % (playlist_id, page_num, origin_type)
|
return self._PAGE_TEMPLATE % (playlist_id, page_num, origin_type)
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
playlist_id, slug, section = self._match_valid_url(url).group('id', 'slug', 'section')
|
playlist_id, section = self._match_valid_url(url).group('id', 'section')
|
||||||
if slug:
|
|
||||||
webpage = self._download_webpage(url, slug)
|
|
||||||
redux_state = self._search_json(
|
|
||||||
r'window\.reduxState\s*=', webpage, 'redux state', slug, transform_source=js_to_json)
|
|
||||||
playlist_id = traverse_obj(redux_state, (
|
|
||||||
'api', 'queries', lambda k, _: k.startswith('channelIdBySlug'),
|
|
||||||
'data', 'channel_id', {int}, {str_or_none}, any))
|
|
||||||
playlist = self._extract_playlist(playlist_id, section=section)
|
playlist = self._extract_playlist(playlist_id, section=section)
|
||||||
if section:
|
playlist['id'] = f'{playlist_id}_{section}'
|
||||||
playlist['id'] = f'{playlist_id}_{section}'
|
|
||||||
return playlist
|
return playlist
|
||||||
|
|
||||||
|
|
||||||
|
class RutubeCustomPlaylistIE(RutubePlaylistBaseIE):
|
||||||
|
IE_NAME = 'rutube:customplaylist'
|
||||||
|
IE_DESC = 'Rutube custom playlist'
|
||||||
|
_VALID_URL = r'https?://rutube\.ru/plst/(?P<id>\d+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://rutube.ru/plst/308547/',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '308547',
|
||||||
|
},
|
||||||
|
'playlist_mincount': 22,
|
||||||
|
}]
|
||||||
|
_PAGE_TEMPLATE = 'https://rutube.ru/api/playlist/custom/%s/videos?page=%s&format=json'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user