[youtube:tab] Raise error on tab redirect (#2318)

Closes #2306
Authored by: krichbanana, coletdjnz
This commit is contained in:
krichbanana 2022-01-19 16:31:57 -05:00 committed by GitHub
parent 0ff1e0fba3
commit 64f36541c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 20 deletions

View file

@ -138,7 +138,7 @@ ### Differences in default behavior
* The output of `-F` is listed in a new format. Use `--compat-options list-formats` to revert this * The output of `-F` is listed in a new format. Use `--compat-options list-formats` to revert this
* All *experiences* of a funimation episode are considered as a single video. This behavior breaks existing archives. Use `--compat-options seperate-video-versions` to extract information from only the default player * All *experiences* of a funimation episode are considered as a single video. This behavior breaks existing archives. Use `--compat-options seperate-video-versions` to extract information from only the default player
* Youtube live chat (if available) is considered as a subtitle. Use `--sub-langs all,-live_chat` to download all subtitles except live chat. You can also use `--compat-options no-live-chat` to prevent live chat from downloading * Youtube live chat (if available) is considered as a subtitle. Use `--sub-langs all,-live_chat` to download all subtitles except live chat. You can also use `--compat-options no-live-chat` to prevent live chat from downloading
* Youtube channel URLs are automatically redirected to `/video`. Append a `/featured` to the URL to download only the videos in the home page. If the channel does not have a videos tab, we try to download the equivalent `UU` playlist instead. Also, `/live` URLs raise an error if there are no live videos instead of silently downloading the entire channel. You may use `--compat-options no-youtube-channel-redirect` to revert all these redirections * Youtube channel URLs are automatically redirected to `/video`. Append a `/featured` to the URL to download only the videos in the home page. If the channel does not have a videos tab, we try to download the equivalent `UU` playlist instead. For all other tabs, if the channel does not show the requested tab, an error will be raised. Also, `/live` URLs raise an error if there are no live videos instead of silently downloading the entire channel. You may use `--compat-options no-youtube-channel-redirect` to revert all these redirections
* Unavailable videos are also listed for youtube playlists. Use `--compat-options no-youtube-unavailable-videos` to remove this * Unavailable videos are also listed for youtube playlists. Use `--compat-options no-youtube-unavailable-videos` to remove this
* If `ffmpeg` is used as the downloader, the downloading and merging of formats happen in a single step when possible. Use `--compat-options no-direct-merge` to revert this * If `ffmpeg` is used as the downloader, the downloading and merging of formats happen in a single step when possible. Use `--compat-options no-direct-merge` to revert this
* Thumbnail embedding in `mp4` is done with mutagen if possible. Use `--compat-options embed-thumbnail-atomicparsley` to force the use of AtomicParsley instead * Thumbnail embedding in `mp4` is done with mutagen if possible. Use `--compat-options embed-thumbnail-atomicparsley` to force the use of AtomicParsley instead

View file

@ -4864,7 +4864,7 @@ def _real_extract(self, url):
info_dict['entries'] = self._smuggle_data(info_dict['entries'], smuggled_data) info_dict['entries'] = self._smuggle_data(info_dict['entries'], smuggled_data)
return info_dict return info_dict
_URL_RE = re.compile(rf'(?P<pre>{_VALID_URL})(?(channel_type)(?P<tab>/\w+))?(?P<post>.*)$') _URL_RE = re.compile(rf'(?P<pre>{_VALID_URL})(?(not_channel)|(?P<tab>/\w+))?(?P<post>.*)$')
def __real_extract(self, url, smuggled_data): def __real_extract(self, url, smuggled_data):
item_id = self._match_id(url) item_id = self._match_id(url)
@ -4896,6 +4896,7 @@ def get_mobj(url):
elif mobj['channel_type'] == 'browse': # Youtube music /browse/ should be changed to /channel/ elif mobj['channel_type'] == 'browse': # Youtube music /browse/ should be changed to /channel/
pre = f'https://www.youtube.com/channel/{item_id}' pre = f'https://www.youtube.com/channel/{item_id}'
original_tab_name = tab
if is_channel and not tab and 'no-youtube-channel-redirect' not in compat_opts: if is_channel and not tab and 'no-youtube-channel-redirect' not in compat_opts:
# Home URLs should redirect to /videos/ # Home URLs should redirect to /videos/
redirect_warning = ('A channel/user page was given. All the channel\'s videos will be downloaded. ' redirect_warning = ('A channel/user page was given. All the channel\'s videos will be downloaded. '
@ -4930,29 +4931,35 @@ def get_mobj(url):
tabs = traverse_obj(data, ('contents', 'twoColumnBrowseResultsRenderer', 'tabs'), expected_type=list) tabs = traverse_obj(data, ('contents', 'twoColumnBrowseResultsRenderer', 'tabs'), expected_type=list)
if tabs: if tabs:
selected_tab = self._extract_selected_tab(tabs) selected_tab = self._extract_selected_tab(tabs)
tab_name = selected_tab.get('title', '') selected_tab_name = selected_tab.get('title', '').lower()
if selected_tab_name == 'home':
selected_tab_name = 'featured'
requested_tab_name = mobj['tab'][1:]
if 'no-youtube-channel-redirect' not in compat_opts: if 'no-youtube-channel-redirect' not in compat_opts:
if mobj['tab'] == '/live': if requested_tab_name == 'live':
# Live tab should have redirected to the video # Live tab should have redirected to the video
raise ExtractorError('The channel is not currently live', expected=True) raise ExtractorError('The channel is not currently live', expected=True)
if mobj['tab'] == '/videos' and tab_name.lower() != mobj['tab'][1:]: if requested_tab_name not in ('', selected_tab_name):
redirect_warning = f'The URL does not have a {mobj["tab"][1:]} tab' redirect_warning = f'The channel does not have a {requested_tab_name} tab'
if not mobj['not_channel'] and item_id[:2] == 'UC': if not original_tab_name:
# Topic channels don't have /videos. Use the equivalent playlist instead if item_id[:2] == 'UC':
pl_id = f'UU{item_id[2:]}' # Topic channels don't have /videos. Use the equivalent playlist instead
pl_url = f'https://www.youtube.com/playlist?list={pl_id}' pl_id = f'UU{item_id[2:]}'
try: pl_url = f'https://www.youtube.com/playlist?list={pl_id}'
data, ytcfg = self._extract_data(pl_url, pl_id, ytcfg=ytcfg, fatal=True) try:
except ExtractorError: data, ytcfg = self._extract_data(pl_url, pl_id, ytcfg=ytcfg, fatal=True, webpage_fatal=True)
redirect_warning += ' and the playlist redirect gave error' except ExtractorError:
else: redirect_warning += ' and the playlist redirect gave error'
item_id, url, tab_name = pl_id, pl_url, mobj['tab'][1:] else:
redirect_warning += f'. Redirecting to playlist {pl_id} instead' item_id, url, selected_tab_name = pl_id, pl_url, requested_tab_name
if tab_name.lower() != mobj['tab'][1:]: redirect_warning += f'. Redirecting to playlist {pl_id} instead'
redirect_warning += f'. {tab_name} tab is being downloaded instead' if selected_tab_name and selected_tab_name != requested_tab_name:
redirect_warning += f'. {selected_tab_name} tab is being downloaded instead'
else:
raise ExtractorError(redirect_warning, expected=True)
if redirect_warning: if redirect_warning:
self.report_warning(redirect_warning) self.to_screen(redirect_warning)
self.write_debug(f'Final URL: {url}') self.write_debug(f'Final URL: {url}')
# YouTube sometimes provides a button to reload playlist with unavailable videos. # YouTube sometimes provides a button to reload playlist with unavailable videos.