aboutsummaryrefslogtreecommitdiffstats
path: root/yt_dlp/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'yt_dlp/__init__.py')
-rw-r--r--yt_dlp/__init__.py91
1 files changed, 41 insertions, 50 deletions
diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py
index 0a8bf37b6..386996e16 100644
--- a/yt_dlp/__init__.py
+++ b/yt_dlp/__init__.py
@@ -1,7 +1,7 @@
-#!/usr/bin/env python3
+#!/usr/bin/python
f'You are using an unsupported version of Python. Only Python versions 3.6 and above are supported by yt-dlp' # noqa: F541
-__license__ = 'Public Domain'
+__license__ = 'CC0-1.0'
import itertools
import os
@@ -60,12 +60,13 @@ def get_urls(urls, batchfile, verbose):
'Ctrl+Z' if compat_os_name == 'nt' else 'Ctrl+D'))
batchfd = sys.stdin
else:
- batchfd = open(
- expand_path(batchfile), encoding='utf-8', errors='ignore')
+ batchfd = io.open(
+ expand_path(batchfile),
+ 'r', encoding='utf-8', errors='ignore')
batch_urls = read_batch_urls(batchfd)
if verbose:
write_string('[debug] Batch file urls: ' + repr(batch_urls) + '\n')
- except OSError:
+ except IOError:
sys.exit('ERROR: batch file %s could not be read' % batchfile)
_enc = preferredencoding()
return [
@@ -74,29 +75,29 @@ def get_urls(urls, batchfile, verbose):
def print_extractor_information(opts, urls):
- out = ''
if opts.list_extractors:
- urls = dict.fromkeys(urls, False)
- for ie in list_extractor_classes(opts.age_limit):
- out += ie.IE_NAME + (' (CURRENTLY BROKEN)' if not ie.working() else '') + '\n'
- if ie == GenericIE:
- matched_urls = [url for url, matched in urls.items() if not matched]
- else:
- matched_urls = tuple(filter(ie.suitable, urls.keys()))
- urls.update(dict.fromkeys(matched_urls, True))
- out += ''.join(f' {url}\n' for url in matched_urls)
+ 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)
elif opts.list_extractor_descriptions:
- _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_extractor_classes(opts.age_limit) if ie.working() and ie.IE_DESC is not False)
+ 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)
elif opts.ap_list_mso:
- 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()])
+ 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)
else:
return False
- write_string(out, out=sys.stdout)
return True
@@ -397,15 +398,13 @@ def validate_options(opts):
# Conflicting options
report_conflict('--dateafter', 'dateafter', '--date', 'date', default=None)
report_conflict('--datebefore', 'datebefore', '--date', 'date', default=None)
- report_conflict('--exec-before-download', 'exec_before_dl_cmd',
- '"--exec before_dl:"', 'exec_cmd', val2=opts.exec_cmd.get('before_dl'))
+ report_conflict('--exec-before-download', 'exec_before_dl_cmd', '"--exec before_dl:"', 'exec_cmd', opts.exec_cmd.get('before_dl'))
report_conflict('--id', 'useid', '--output', 'outtmpl', val2=opts.outtmpl.get('default'))
report_conflict('--remux-video', 'remuxvideo', '--recode-video', 'recodevideo')
report_conflict('--sponskrub', 'sponskrub', '--remove-chapters', 'remove_chapters')
report_conflict('--sponskrub', 'sponskrub', '--sponsorblock-mark', 'sponsorblock_mark')
report_conflict('--sponskrub', 'sponskrub', '--sponsorblock-remove', 'sponsorblock_remove')
- report_conflict('--sponskrub-cut', 'sponskrub_cut', '--split-chapter', 'split_chapters',
- val1=opts.sponskrub and opts.sponskrub_cut)
+ report_conflict('--sponskrub-cut', 'sponskrub_cut', '--split-chapter', 'split_chapters', val1=opts.sponskrub and opts.sponskrub_cut)
# Conflicts with --allow-unplayable-formats
report_conflict('--add-metadata', 'addmetadata')
@@ -414,7 +413,7 @@ def validate_options(opts):
report_conflict('--embed-subs', 'embedsubtitles')
report_conflict('--embed-thumbnail', 'embedthumbnail')
report_conflict('--extract-audio', 'extractaudio')
- report_conflict('--fixup', 'fixup', val1=opts.fixup not in (None, 'never', 'ignore'), default='never')
+ report_conflict('--fixup', 'fixup', val1=(opts.fixup or '').lower() in ('', 'never', 'ignore'), default='never')
report_conflict('--recode-video', 'recodevideo')
report_conflict('--remove-chapters', 'remove_chapters', default=[])
report_conflict('--remux-video', 'remuxvideo')
@@ -618,11 +617,11 @@ def parse_options(argv=None):
postprocessors = list(get_postprocessors(opts))
- print_only = bool(opts.forceprint) and all(k not in opts.forceprint for k in POSTPROCESS_WHEN[2:])
- any_getting = any(getattr(opts, k) for k in (
- 'dumpjson', 'dump_single_json', 'getdescription', 'getduration', 'getfilename',
- 'getformat', 'getid', 'getthumbnail', 'gettitle', 'geturl'
- ))
+ any_getting = (any(opts.forceprint.values()) or opts.dumpjson or opts.dump_single_json
+ or opts.geturl or opts.gettitle or opts.getid or opts.getthumbnail
+ or opts.getdescription or opts.getfilename or opts.getformat or opts.getduration)
+
+ any_printing = opts.print_json
final_ext = (
opts.recodevideo if opts.recodevideo in FFmpegVideoConvertorPP.SUPPORTED_EXTS
@@ -640,10 +639,7 @@ def parse_options(argv=None):
'ap_mso': opts.ap_mso,
'ap_username': opts.ap_username,
'ap_password': opts.ap_password,
- 'client_certificate': opts.client_certificate,
- 'client_certificate_key': opts.client_certificate_key,
- 'client_certificate_password': opts.client_certificate_password,
- 'quiet': opts.quiet or any_getting or opts.print_json or bool(opts.forceprint),
+ 'quiet': (opts.quiet or any_getting or any_printing),
'no_warnings': opts.no_warnings,
'forceurl': opts.geturl,
'forcetitle': opts.gettitle,
@@ -658,7 +654,7 @@ def parse_options(argv=None):
'forcejson': opts.dumpjson or opts.print_json,
'dump_single_json': opts.dump_single_json,
'force_write_download_archive': opts.force_write_download_archive,
- 'simulate': (print_only or any_getting or None) if opts.simulate is None else opts.simulate,
+ 'simulate': (any_getting or None) if opts.simulate is None else opts.simulate,
'skip_download': opts.skip_download,
'format': opts.format,
'allow_unplayable_formats': opts.allow_unplayable_formats,
@@ -802,6 +798,13 @@ def parse_options(argv=None):
def _real_main(argv=None):
+ # Compatibility fixes for Windows
+ if sys.platform == 'win32':
+ # https://github.com/ytdl-org/youtube-dl/issues/820
+ codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
+
+ workaround_optparse_bug9161()
+
setproctitle('yt-dlp')
parser, opts, all_urls, ydl_opts = parse_options(argv)
@@ -822,19 +825,8 @@ def _real_main(argv=None):
if opts.rm_cachedir:
ydl.cache.remove()
- # Update version
- if opts.update_self:
- # If updater returns True, exit. Required for windows
- if run_update(ydl):
- if actual_use:
- sys.exit('ERROR: The program must exit for the update to complete')
- sys.exit()
-
# Maybe do nothing
if not actual_use:
- if opts.update_self or opts.rm_cachedir:
- sys.exit()
-
ydl.warn_if_short_id(sys.argv[1:] if argv is None else argv)
parser.error(
'You must provide at least one URL.\n'
@@ -868,7 +860,6 @@ def main(argv=None):
sys.exit(f'\nERROR: {e}')
-from .extractor import gen_extractors, list_extractors
__all__ = [
'main',
'YoutubeDL',