mirror of
https://github.com/ytdl-org/youtube-dl.git
synced 2024-01-07 17:16:08 +00:00
Provide guidance when called with a YouTube ID starting with a dash.
Reported at https://news.ycombinator.com/item?id=8648121
This commit is contained in:
parent
d37cab2a9d
commit
7d4111ed14
|
@ -47,6 +47,7 @@ from youtube_dl.utils import (
|
||||||
js_to_json,
|
js_to_json,
|
||||||
get_filesystem_encoding,
|
get_filesystem_encoding,
|
||||||
intlist_to_bytes,
|
intlist_to_bytes,
|
||||||
|
args_to_str,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -361,5 +362,11 @@ class TestUtil(unittest.TestCase):
|
||||||
intlist_to_bytes([0, 1, 127, 128, 255]),
|
intlist_to_bytes([0, 1, 127, 128, 255]),
|
||||||
b'\x00\x01\x7f\x80\xff')
|
b'\x00\x01\x7f\x80\xff')
|
||||||
|
|
||||||
|
def test_args_to_str(self):
|
||||||
|
self.assertEqual(
|
||||||
|
args_to_str(['foo', 'ba/r', '-baz', '2 be', '']),
|
||||||
|
'foo ba/r -baz \'2 be\' \'\''
|
||||||
|
)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -29,6 +29,7 @@ from .compat import (
|
||||||
compat_str,
|
compat_str,
|
||||||
compat_urllib_error,
|
compat_urllib_error,
|
||||||
compat_urllib_request,
|
compat_urllib_request,
|
||||||
|
shlex_quote,
|
||||||
)
|
)
|
||||||
from .utils import (
|
from .utils import (
|
||||||
escape_url,
|
escape_url,
|
||||||
|
@ -60,6 +61,7 @@ from .utils import (
|
||||||
write_string,
|
write_string,
|
||||||
YoutubeDLHandler,
|
YoutubeDLHandler,
|
||||||
prepend_extension,
|
prepend_extension,
|
||||||
|
args_to_str,
|
||||||
)
|
)
|
||||||
from .cache import Cache
|
from .cache import Cache
|
||||||
from .extractor import get_info_extractor, gen_extractors
|
from .extractor import get_info_extractor, gen_extractors
|
||||||
|
@ -253,6 +255,22 @@ class YoutubeDL(object):
|
||||||
self.print_debug_header()
|
self.print_debug_header()
|
||||||
self.add_default_info_extractors()
|
self.add_default_info_extractors()
|
||||||
|
|
||||||
|
def warn_if_short_id(self, argv):
|
||||||
|
# short YouTube ID starting with dash?
|
||||||
|
idxs = [
|
||||||
|
i for i, a in enumerate(argv)
|
||||||
|
if re.match(r'^-[0-9A-Za-z_-]{10}$', a)]
|
||||||
|
if idxs:
|
||||||
|
correct_argv = (
|
||||||
|
['youtube-dl'] +
|
||||||
|
[a for i, a in enumerate(argv) if i not in idxs] +
|
||||||
|
['--'] + [argv[i] for i in idxs]
|
||||||
|
)
|
||||||
|
self.report_warning(
|
||||||
|
'Long argument string detected. '
|
||||||
|
'Use -- to separate parameters and URLs, like this:\n%s\n' %
|
||||||
|
args_to_str(correct_argv))
|
||||||
|
|
||||||
def add_info_extractor(self, ie):
|
def add_info_extractor(self, ie):
|
||||||
"""Add an InfoExtractor object to the end of the list."""
|
"""Add an InfoExtractor object to the end of the list."""
|
||||||
self._ies.append(ie)
|
self._ies.append(ie)
|
||||||
|
@ -1410,3 +1428,4 @@ class YoutubeDL(object):
|
||||||
if encoding is None:
|
if encoding is None:
|
||||||
encoding = preferredencoding()
|
encoding = preferredencoding()
|
||||||
return encoding
|
return encoding
|
||||||
|
|
||||||
|
|
|
@ -334,11 +334,12 @@ def _real_main(argv=None):
|
||||||
|
|
||||||
# Maybe do nothing
|
# Maybe do nothing
|
||||||
if (len(all_urls) < 1) and (opts.load_info_filename is None):
|
if (len(all_urls) < 1) and (opts.load_info_filename is None):
|
||||||
if not (opts.update_self or opts.rm_cachedir):
|
if opts.update_self or opts.rm_cachedir:
|
||||||
parser.error('you must provide at least one URL')
|
|
||||||
else:
|
|
||||||
sys.exit()
|
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')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if opts.load_info_filename is not None:
|
if opts.load_info_filename is not None:
|
||||||
retcode = ydl.download_with_info_file(opts.load_info_filename)
|
retcode = ydl.download_with_info_file(opts.load_info_filename)
|
||||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||||
import getpass
|
import getpass
|
||||||
import optparse
|
import optparse
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -174,7 +175,10 @@ try:
|
||||||
from shlex import quote as shlex_quote
|
from shlex import quote as shlex_quote
|
||||||
except ImportError: # Python < 3.3
|
except ImportError: # Python < 3.3
|
||||||
def shlex_quote(s):
|
def shlex_quote(s):
|
||||||
return "'" + s.replace("'", "'\"'\"'") + "'"
|
if re.match(r'^[-_\w./]+$', s):
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return "'" + s.replace("'", "'\"'\"'") + "'"
|
||||||
|
|
||||||
|
|
||||||
def compat_ord(c):
|
def compat_ord(c):
|
||||||
|
|
|
@ -41,6 +41,7 @@ from .compat import (
|
||||||
compat_urllib_parse_urlparse,
|
compat_urllib_parse_urlparse,
|
||||||
compat_urllib_request,
|
compat_urllib_request,
|
||||||
compat_urlparse,
|
compat_urlparse,
|
||||||
|
shlex_quote,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1433,3 +1434,8 @@ def ytdl_is_updateable():
|
||||||
from zipimport import zipimporter
|
from zipimport import zipimporter
|
||||||
|
|
||||||
return isinstance(globals().get('__loader__'), zipimporter) or hasattr(sys, 'frozen')
|
return isinstance(globals().get('__loader__'), zipimporter) or hasattr(sys, 'frozen')
|
||||||
|
|
||||||
|
|
||||||
|
def args_to_str(args):
|
||||||
|
# Get a short string representation for a subprocess command
|
||||||
|
return ' '.join(shlex_quote(a) for a in args)
|
||||||
|
|
Loading…
Reference in a new issue