diff options
author | pukkandan <pukkandan.ytdlp@gmail.com> | 2022-05-09 10:02:17 +0530 |
---|---|---|
committer | pukkandan <pukkandan.ytdlp@gmail.com> | 2022-05-11 22:10:15 +0530 |
commit | 8dcce6a89ca0dcb875fa1ba5f8a83cc244ceabcb (patch) | |
tree | dee8c422585730446ca4b502325ea9eed6c2f722 /yt_dlp | |
parent | 494f52308b313110b481711d3d1cb8f3630a5bbe (diff) | |
download | hypervideo-pre-8dcce6a89ca0dcb875fa1ba5f8a83cc244ceabcb.tar.lz hypervideo-pre-8dcce6a89ca0dcb875fa1ba5f8a83cc244ceabcb.tar.xz hypervideo-pre-8dcce6a89ca0dcb875fa1ba5f8a83cc244ceabcb.zip |
[extractor] Document netrc machines
Closes #3169
Diffstat (limited to 'yt_dlp')
-rw-r--r-- | yt_dlp/__init__.py | 32 | ||||
-rw-r--r-- | yt_dlp/extractor/__init__.py | 12 | ||||
-rw-r--r-- | yt_dlp/extractor/common.py | 51 | ||||
-rw-r--r-- | yt_dlp/extractor/fujitv.py | 2 | ||||
-rw-r--r-- | yt_dlp/extractor/vimeo.py | 2 |
5 files changed, 56 insertions, 43 deletions
diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index 2e9da4c98..924604631 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -5,14 +5,13 @@ __license__ = 'Public Domain' import itertools import os -import random import re import sys from .compat import compat_getpass, compat_os_name, compat_shlex_quote from .cookies import SUPPORTED_BROWSERS, SUPPORTED_KEYRINGS from .downloader import FileDownloader -from .extractor import gen_extractors, list_extractors +from .extractor import list_extractors from .extractor.adobepass import MSO_INFO from .extractor.common import InfoExtractor from .options import parseOpts @@ -75,29 +74,23 @@ def get_urls(urls, batchfile, verbose): def print_extractor_information(opts, urls): + out = '' if opts.list_extractors: for ie in list_extractors(opts.age_limit): - write_string(ie.IE_NAME + (' (CURRENTLY BROKEN)' if not ie.working() else '') + '\n', out=sys.stdout) - matchedUrls = [url for url in urls if ie.suitable(url)] - for mu in matchedUrls: - write_string(' ' + mu + '\n', out=sys.stdout) + out += ie.IE_NAME + (' (CURRENTLY BROKEN)' if not ie.working() else '') + '\n' + out += ''.join(f' {url}\n' for url in filter(ie.suitable, urls)) elif opts.list_extractor_descriptions: - for ie in list_extractors(opts.age_limit): - if not ie.working(): - continue - if ie.IE_DESC is False: - continue - desc = ie.IE_DESC or ie.IE_NAME - if getattr(ie, 'SEARCH_KEY', None) is not None: - _SEARCHES = ('cute kittens', 'slithering pythons', 'falling cat', 'angry poodle', 'purple fish', 'running tortoise', 'sleeping bunny', 'burping cow') - _COUNTS = ('', '5', '10', 'all') - desc += f'; "{ie.SEARCH_KEY}:" prefix (Example: "{ie.SEARCH_KEY}{random.choice(_COUNTS)}:{random.choice(_SEARCHES)}")' - write_string(desc + '\n', out=sys.stdout) + _SEARCHES = ('cute kittens', 'slithering pythons', 'falling cat', 'angry poodle', 'purple fish', 'running tortoise', 'sleeping bunny', 'burping cow') + out = '\n'.join( + ie.description(markdown=False, search_examples=_SEARCHES) + for ie in list_extractors(opts.age_limit) if ie.working() and ie.IE_DESC is not False) + '\n' elif opts.ap_list_mso: - table = [[mso_id, mso_info['name']] for mso_id, mso_info in MSO_INFO.items()] - write_string('Supported TV Providers:\n' + render_table(['mso', 'mso name'], table) + '\n', out=sys.stdout) + out = 'Supported TV Providers:\n%s\n' % render_table( + ['mso', 'mso name'], + [[mso_id, mso_info['name']] for mso_id, mso_info in MSO_INFO.items()]) else: return False + write_string(out, out=sys.stdout) return True @@ -869,6 +862,7 @@ def main(argv=None): sys.exit(f'\nERROR: {e}') +from .extractor import gen_extractors __all__ = [ 'main', 'YoutubeDL', diff --git a/yt_dlp/extractor/__init__.py b/yt_dlp/extractor/__init__.py index 6288c5c6b..506ffe87c 100644 --- a/yt_dlp/extractor/__init__.py +++ b/yt_dlp/extractor/__init__.py @@ -38,14 +38,10 @@ def gen_extractors(): def list_extractors(age_limit): - """ - Return a list of extractors that are suitable for the given age, - sorted by extractor ID. - """ - - return sorted( - filter(lambda ie: ie.is_suitable(age_limit), gen_extractors()), - key=lambda ie: ie.IE_NAME.lower()) + """Return a list of extractors that are suitable for the given age, sorted by extractor name""" + return sorted(filter( + lambda ie: ie.is_suitable(age_limit), + gen_extractors()), key=lambda ie: ie.IE_NAME.lower()) def get_info_extractor(ie_name): diff --git a/yt_dlp/extractor/common.py b/yt_dlp/extractor/common.py index e5a44e296..23d57ddaf 100644 --- a/yt_dlp/extractor/common.py +++ b/yt_dlp/extractor/common.py @@ -469,14 +469,18 @@ class InfoExtractor: _WORKING = True _NETRC_MACHINE = None IE_DESC = None + SEARCH_KEY = None - _LOGIN_HINTS = { - 'any': 'Use --cookies, --cookies-from-browser, --username and --password, or --netrc to provide account credentials', - 'cookies': ( - 'Use --cookies-from-browser or --cookies for the authentication. ' - 'See https://github.com/ytdl-org/youtube-dl#how-do-i-pass-cookies-to-youtube-dl for how to manually pass cookies'), - 'password': 'Use --username and --password, or --netrc to provide account credentials', - } + def _login_hint(self, method=NO_DEFAULT, netrc=None): + password_hint = f'--username and --password, or --netrc ({netrc or self._NETRC_MACHINE}) to provide account credentials' + return { + None: '', + 'any': f'Use --cookies, --cookies-from-browser, {password_hint}', + 'password': f'Use {password_hint}', + 'cookies': ( + 'Use --cookies-from-browser or --cookies for the authentication. ' + 'See https://github.com/ytdl-org/youtube-dl#how-do-i-pass-cookies-to-youtube-dl for how to manually pass cookies'), + }[method if method is not NO_DEFAULT else 'any' if self.supports_login() else 'cookies'] def __init__(self, downloader=None): """Constructor. Receives an optional downloader (a YoutubeDL instance). @@ -539,7 +543,7 @@ class InfoExtractor: if username: self._perform_login(username, password) elif self.get_param('username') and False not in (self.IE_DESC, self._NETRC_MACHINE): - self.report_warning(f'Login with password is not supported for this website. {self._LOGIN_HINTS["cookies"]}') + self.report_warning(f'Login with password is not supported for this website. {self._login_hint("cookies")}') self._real_initialize() self._ready = True @@ -708,7 +712,7 @@ class InfoExtractor: @property def IE_NAME(self): - return compat_str(type(self).__name__[:-2]) + return type(self).__name__[:-2] @staticmethod def __can_accept_status_code(err, expected_status): @@ -1131,11 +1135,7 @@ class InfoExtractor: self.get_param('ignore_no_formats_error') or self.get_param('wait_for_video')): self.report_warning(msg) return - if method is NO_DEFAULT: - method = 'any' if self.supports_login() else 'cookies' - if method is not None: - assert method in self._LOGIN_HINTS, 'Invalid login method' - msg = f'{msg}. {self._LOGIN_HINTS[method]}' + msg += format_field(self._login_hint(method), template='. %s') raise ExtractorError(msg, expected=True) def raise_geo_restricted( @@ -3653,6 +3653,29 @@ class InfoExtractor: any_restricted = any_restricted or is_restricted return not any_restricted + def description(self, *, markdown=True, search_examples=None): + """Description of the extractor""" + desc = '' + if self._NETRC_MACHINE: + if markdown: + desc += f' [<abbr title="netrc machine"><em>{self._NETRC_MACHINE}</em></abbr>]' + else: + desc += f' [{self._NETRC_MACHINE}]' + if self.IE_DESC is False: + desc += ' [HIDDEN]' + elif self.IE_DESC: + desc += f' {self.IE_DESC}' + if self.SEARCH_KEY: + desc += f'; "{self.SEARCH_KEY}:" prefix' + if search_examples: + _COUNTS = ('', '5', '10', 'all') + desc += f' (Example: "{self.SEARCH_KEY}{random.choice(_COUNTS)}:{random.choice(search_examples)}")' + if not self.working(): + desc += ' (**Currently broken**)' if markdown else ' (Currently broken)' + + name = f' - **{self.IE_NAME}**' if markdown else self.IE_NAME + return f'{name}:{desc}' if desc else name + def extract_subtitles(self, *args, **kwargs): if (self.get_param('writesubtitles', False) or self.get_param('listsubtitles')): diff --git a/yt_dlp/extractor/fujitv.py b/yt_dlp/extractor/fujitv.py index f66149d2c..d7f49accd 100644 --- a/yt_dlp/extractor/fujitv.py +++ b/yt_dlp/extractor/fujitv.py @@ -45,7 +45,7 @@ class FujiTVFODPlus7IE(InfoExtractor): if token: json_info = self._download_json('https://fod-sp.fujitv.co.jp/apps/api/episode/detail/?ep_id=%s&is_premium=false' % video_id, video_id, headers={'x-authorization': f'Bearer {token.value}'}, fatal=False) else: - self.report_warning(f'The token cookie is needed to extract video metadata. {self._LOGIN_HINTS["cookies"]}') + self.report_warning(f'The token cookie is needed to extract video metadata. {self._login_hint("cookies")}') formats, subtitles = [], {} src_json = self._download_json(f'{self._BASE_URL}abrjson_v2/tv_android/{video_id}', video_id) for src in src_json['video_selector']: diff --git a/yt_dlp/extractor/vimeo.py b/yt_dlp/extractor/vimeo.py index b2c929373..de4fc61cc 100644 --- a/yt_dlp/extractor/vimeo.py +++ b/yt_dlp/extractor/vimeo.py @@ -1333,7 +1333,7 @@ class VimeoReviewIE(VimeoBaseInfoExtractor): class VimeoWatchLaterIE(VimeoChannelIE): IE_NAME = 'vimeo:watchlater' - IE_DESC = 'Vimeo watch later list, "vimeowatchlater" keyword (requires authentication)' + IE_DESC = 'Vimeo watch later list, ":vimeowatchlater" keyword (requires authentication)' _VALID_URL = r'https://vimeo\.com/(?:home/)?watchlater|:vimeowatchlater' _TITLE = 'Watch Later' _LOGIN_REQUIRED = True |