mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	[cleanup] Remove unused code paths (#2173)
Notes: * `_windows_write_string`: Fixed in 3.6 * https://bugs.python.org/issue1602 * PEP: https://www.python.org/dev/peps/pep-0528 * Windows UTF-8 fix: Fixed in 3.3 * https://bugs.python.org/issue13216 * `__loader__`: is always present in 3.3+ * https://bugs.python.org/issue14646 * `workaround_optparse_bug9161`: Fixed in 2.7 * https://bugs.python.org/issue9161 Authored by: fstirlitz
This commit is contained in:
		@@ -1008,12 +1008,6 @@ class YoutubeDL(object):
 | 
			
		||||
            expand_path(paths.get('home', '').strip()),
 | 
			
		||||
            expand_path(paths.get(dir_type, '').strip()) if dir_type else '',
 | 
			
		||||
            filename or '')
 | 
			
		||||
 | 
			
		||||
        # Temporary fix for #4787
 | 
			
		||||
        # 'Treat' all problem characters by passing filename through preferredencoding
 | 
			
		||||
        # to workaround encoding issues with subprocess on python2 @ Windows
 | 
			
		||||
        if sys.version_info < (3, 0) and sys.platform == 'win32':
 | 
			
		||||
            path = encodeFilename(path, True).decode(preferredencoding())
 | 
			
		||||
        return sanitize_path(path, force=self.params.get('windowsfilenames'))
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@ f'You are using an unsupported version of Python. Only Python versions 3.6 and a
 | 
			
		||||
 | 
			
		||||
__license__ = 'Public Domain'
 | 
			
		||||
 | 
			
		||||
import codecs
 | 
			
		||||
import io
 | 
			
		||||
import itertools
 | 
			
		||||
import os
 | 
			
		||||
@@ -18,7 +17,6 @@ from .compat import (
 | 
			
		||||
    compat_getpass,
 | 
			
		||||
    compat_os_name,
 | 
			
		||||
    compat_shlex_quote,
 | 
			
		||||
    workaround_optparse_bug9161,
 | 
			
		||||
)
 | 
			
		||||
from .cookies import SUPPORTED_BROWSERS, SUPPORTED_KEYRINGS
 | 
			
		||||
from .utils import (
 | 
			
		||||
@@ -807,13 +805,6 @@ 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)
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,7 @@
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
# Execute with
 | 
			
		||||
# $ python yt_dlp/__main__.py (2.6+)
 | 
			
		||||
# $ python -m yt_dlp          (2.7+)
 | 
			
		||||
# $ python -m yt_dlp
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,6 @@ import http.cookiejar
 | 
			
		||||
import http.cookies
 | 
			
		||||
import http.server
 | 
			
		||||
import itertools
 | 
			
		||||
import optparse
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
import shlex
 | 
			
		||||
@@ -86,28 +85,6 @@ def compat_print(s):
 | 
			
		||||
    assert isinstance(s, compat_str)
 | 
			
		||||
    print(s)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Fix https://github.com/ytdl-org/youtube-dl/issues/4223
 | 
			
		||||
# See http://bugs.python.org/issue9161 for what is broken
 | 
			
		||||
def workaround_optparse_bug9161():
 | 
			
		||||
    op = optparse.OptionParser()
 | 
			
		||||
    og = optparse.OptionGroup(op, 'foo')
 | 
			
		||||
    try:
 | 
			
		||||
        og.add_option('-t')
 | 
			
		||||
    except TypeError:
 | 
			
		||||
        real_add_option = optparse.OptionGroup.add_option
 | 
			
		||||
 | 
			
		||||
        def _compat_add_option(self, *args, **kwargs):
 | 
			
		||||
            enc = lambda v: (
 | 
			
		||||
                v.encode('ascii', 'replace') if isinstance(v, compat_str)
 | 
			
		||||
                else v)
 | 
			
		||||
            bargs = [enc(a) for a in args]
 | 
			
		||||
            bkwargs = dict(
 | 
			
		||||
                (k, enc(v)) for k, v in kwargs.items())
 | 
			
		||||
            return real_add_option(self, *bargs, **bkwargs)
 | 
			
		||||
        optparse.OptionGroup.add_option = _compat_add_option
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
    compat_Pattern = re.Pattern
 | 
			
		||||
except AttributeError:
 | 
			
		||||
@@ -207,6 +184,7 @@ compat_numeric_types = (int, float, complex)
 | 
			
		||||
compat_str = str
 | 
			
		||||
compat_xpath = lambda xpath: xpath
 | 
			
		||||
compat_zip = zip
 | 
			
		||||
workaround_optparse_bug9161 = lambda: None
 | 
			
		||||
 | 
			
		||||
compat_collections_abc = collections.abc
 | 
			
		||||
compat_HTMLParser = html.parser.HTMLParser
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,6 @@ class BpbIE(InfoExtractor):
 | 
			
		||||
 | 
			
		||||
    _TEST = {
 | 
			
		||||
        'url': 'http://www.bpb.de/mediathek/297/joachim-gauck-zu-1989-und-die-erinnerung-an-die-ddr',
 | 
			
		||||
        # md5 fails in Python 2.6 due to buggy server response and wrong handling of urllib2
 | 
			
		||||
        'md5': 'c4f84c8a8044ca9ff68bb8441d300b3f',
 | 
			
		||||
        'info_dict': {
 | 
			
		||||
            'id': '297',
 | 
			
		||||
 
 | 
			
		||||
@@ -3606,9 +3606,7 @@ class InfoExtractor(object):
 | 
			
		||||
        for header, cookies in url_handle.headers.items():
 | 
			
		||||
            if header.lower() != 'set-cookie':
 | 
			
		||||
                continue
 | 
			
		||||
            if sys.version_info[0] >= 3:
 | 
			
		||||
                cookies = cookies.encode('iso-8859-1')
 | 
			
		||||
            cookies = cookies.decode('utf-8')
 | 
			
		||||
            cookies = cookies.encode('iso-8859-1').decode('utf-8')
 | 
			
		||||
            cookie_value = re.search(
 | 
			
		||||
                r'%s=(.+?);.*?\b[Dd]omain=(.+?)(?:[,;]|$)' % cookie, cookies)
 | 
			
		||||
            if cookie_value:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
from .common import InfoExtractor
 | 
			
		||||
from ..utils import ExtractorError
 | 
			
		||||
 | 
			
		||||
@@ -35,9 +33,7 @@ class UnicodeBOMIE(InfoExtractor):
 | 
			
		||||
    IE_DESC = False
 | 
			
		||||
    _VALID_URL = r'(?P<bom>\ufeff)(?P<id>.*)$'
 | 
			
		||||
 | 
			
		||||
    # Disable test for python 3.2 since BOM is broken in re in this version
 | 
			
		||||
    # (see https://github.com/ytdl-org/youtube-dl/issues/9751)
 | 
			
		||||
    _TESTS = [] if (3, 0) < sys.version_info <= (3, 3) else [{
 | 
			
		||||
    _TESTS = [{
 | 
			
		||||
        'url': '\ufeffhttp://www.youtube.com/watch?v=BaW_jenozKc',
 | 
			
		||||
        'only_matching': True,
 | 
			
		||||
    }]
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
from .common import InfoExtractor
 | 
			
		||||
from .youtube import YoutubeIE
 | 
			
		||||
@@ -4011,9 +4010,6 @@ class GenericIE(InfoExtractor):
 | 
			
		||||
                # Look also in Refresh HTTP header
 | 
			
		||||
                refresh_header = head_response.headers.get('Refresh')
 | 
			
		||||
                if refresh_header:
 | 
			
		||||
                    # In python 2 response HTTP headers are bytestrings
 | 
			
		||||
                    if sys.version_info < (3, 0) and isinstance(refresh_header, str):
 | 
			
		||||
                        refresh_header = refresh_header.decode('iso-8859-1')
 | 
			
		||||
                    found = re.search(REDIRECT_REGEX, refresh_header)
 | 
			
		||||
            if found:
 | 
			
		||||
                new_url = compat_urlparse.urljoin(url, unescapeHTML(found.group(1)))
 | 
			
		||||
 
 | 
			
		||||
@@ -15,22 +15,6 @@ from .utils import encode_compat_str, Popen, write_string
 | 
			
		||||
from .version import __version__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
'''  # Not signed
 | 
			
		||||
def rsa_verify(message, signature, key):
 | 
			
		||||
    from hashlib import sha256
 | 
			
		||||
    assert isinstance(message, bytes)
 | 
			
		||||
    byte_size = (len(bin(key[0])) - 2 + 8 - 1) // 8
 | 
			
		||||
    signature = ('%x' % pow(int(signature, 16), key[1], key[0])).encode()
 | 
			
		||||
    signature = (byte_size * 2 - len(signature)) * b'0' + signature
 | 
			
		||||
    asn1 = b'3031300d060960864801650304020105000420'
 | 
			
		||||
    asn1 += sha256(message).hexdigest().encode()
 | 
			
		||||
    if byte_size < len(asn1) // 2 + 11:
 | 
			
		||||
        return False
 | 
			
		||||
    expected = b'0001' + (byte_size - len(asn1) // 2 - 3) * b'ff' + b'00' + asn1
 | 
			
		||||
    return expected == signature
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def detect_variant():
 | 
			
		||||
    if hasattr(sys, 'frozen'):
 | 
			
		||||
        prefix = 'mac' if sys.platform == 'darwin' else 'win'
 | 
			
		||||
@@ -39,7 +23,7 @@ def detect_variant():
 | 
			
		||||
                return f'{prefix}_dir'
 | 
			
		||||
            return f'{prefix}_exe'
 | 
			
		||||
        return 'py2exe'
 | 
			
		||||
    elif isinstance(globals().get('__loader__'), zipimporter):
 | 
			
		||||
    elif isinstance(__loader__, zipimporter):
 | 
			
		||||
        return 'zip'
 | 
			
		||||
    elif os.path.basename(sys.argv[0]) == '__main__.py':
 | 
			
		||||
        return 'source'
 | 
			
		||||
@@ -232,24 +216,6 @@ def run_update(ydl):
 | 
			
		||||
    assert False, f'Unhandled variant: {variant}'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
'''  # UNUSED
 | 
			
		||||
def get_notes(versions, fromVersion):
 | 
			
		||||
    notes = []
 | 
			
		||||
    for v, vdata in sorted(versions.items()):
 | 
			
		||||
        if v > fromVersion:
 | 
			
		||||
            notes.extend(vdata.get('notes', []))
 | 
			
		||||
    return notes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def print_notes(to_screen, versions, fromVersion=__version__):
 | 
			
		||||
    notes = get_notes(versions, fromVersion)
 | 
			
		||||
    if notes:
 | 
			
		||||
        to_screen('PLEASE NOTE:')
 | 
			
		||||
        for note in notes:
 | 
			
		||||
            to_screen(note)
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Deprecated
 | 
			
		||||
def update_self(to_screen, verbose, opener):
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										247
									
								
								yt_dlp/utils.py
									
									
									
									
									
								
							
							
						
						
									
										247
									
								
								yt_dlp/utils.py
									
									
									
									
									
								
							@@ -50,7 +50,6 @@ from .compat import (
 | 
			
		||||
    compat_brotli,
 | 
			
		||||
    compat_chr,
 | 
			
		||||
    compat_cookiejar,
 | 
			
		||||
    compat_ctypes_WINFUNCTYPE,
 | 
			
		||||
    compat_etree_fromstring,
 | 
			
		||||
    compat_expanduser,
 | 
			
		||||
    compat_html_entities,
 | 
			
		||||
@@ -288,37 +287,9 @@ def preferredencoding():
 | 
			
		||||
def write_json_file(obj, fn):
 | 
			
		||||
    """ Encode obj as JSON and write it to fn, atomically if possible """
 | 
			
		||||
 | 
			
		||||
    fn = encodeFilename(fn)
 | 
			
		||||
    if sys.version_info < (3, 0) and sys.platform != 'win32':
 | 
			
		||||
        encoding = get_filesystem_encoding()
 | 
			
		||||
        # os.path.basename returns a bytes object, but NamedTemporaryFile
 | 
			
		||||
        # will fail if the filename contains non ascii characters unless we
 | 
			
		||||
        # use a unicode object
 | 
			
		||||
        path_basename = lambda f: os.path.basename(fn).decode(encoding)
 | 
			
		||||
        # the same for os.path.dirname
 | 
			
		||||
        path_dirname = lambda f: os.path.dirname(fn).decode(encoding)
 | 
			
		||||
    else:
 | 
			
		||||
        path_basename = os.path.basename
 | 
			
		||||
        path_dirname = os.path.dirname
 | 
			
		||||
 | 
			
		||||
    args = {
 | 
			
		||||
        'suffix': '.tmp',
 | 
			
		||||
        'prefix': path_basename(fn) + '.',
 | 
			
		||||
        'dir': path_dirname(fn),
 | 
			
		||||
        'delete': False,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # In Python 2.x, json.dump expects a bytestream.
 | 
			
		||||
    # In Python 3.x, it writes to a character stream
 | 
			
		||||
    if sys.version_info < (3, 0):
 | 
			
		||||
        args['mode'] = 'wb'
 | 
			
		||||
    else:
 | 
			
		||||
        args.update({
 | 
			
		||||
            'mode': 'w',
 | 
			
		||||
            'encoding': 'utf-8',
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
    tf = tempfile.NamedTemporaryFile(**compat_kwargs(args))
 | 
			
		||||
    tf = tempfile.NamedTemporaryFile(
 | 
			
		||||
        prefix=f'{os.path.basename(fn)}.', dir=os.path.dirname(fn),
 | 
			
		||||
        suffix='.tmp', delete=False, mode='w', encoding='utf-8')
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        with tf:
 | 
			
		||||
@@ -345,20 +316,11 @@ def write_json_file(obj, fn):
 | 
			
		||||
        raise
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if sys.version_info >= (2, 7):
 | 
			
		||||
    def find_xpath_attr(node, xpath, key, val=None):
 | 
			
		||||
        """ Find the xpath xpath[@key=val] """
 | 
			
		||||
        assert re.match(r'^[a-zA-Z_-]+$', key)
 | 
			
		||||
        expr = xpath + ('[@%s]' % key if val is None else "[@%s='%s']" % (key, val))
 | 
			
		||||
        return node.find(expr)
 | 
			
		||||
else:
 | 
			
		||||
    def find_xpath_attr(node, xpath, key, val=None):
 | 
			
		||||
        for f in node.findall(compat_xpath(xpath)):
 | 
			
		||||
            if key not in f.attrib:
 | 
			
		||||
                continue
 | 
			
		||||
            if val is None or f.attrib.get(key) == val:
 | 
			
		||||
                return f
 | 
			
		||||
        return None
 | 
			
		||||
def find_xpath_attr(node, xpath, key, val=None):
 | 
			
		||||
    """ Find the xpath xpath[@key=val] """
 | 
			
		||||
    assert re.match(r'^[a-zA-Z_-]+$', key)
 | 
			
		||||
    expr = xpath + ('[@%s]' % key if val is None else "[@%s='%s']" % (key, val))
 | 
			
		||||
    return node.find(expr)
 | 
			
		||||
 | 
			
		||||
# On python2.6 the xml.etree.ElementTree.Element methods don't support
 | 
			
		||||
# the namespace parameter
 | 
			
		||||
@@ -626,8 +588,6 @@ def extract_attributes(html_element):
 | 
			
		||||
        'empty': '', 'noval': None, 'entity': '&',
 | 
			
		||||
        'sq': '"', 'dq': '\''
 | 
			
		||||
    }.
 | 
			
		||||
    NB HTMLParser is stricter in Python 2.6 & 3.2 than in later versions,
 | 
			
		||||
    but the cases in the unit test will work for all of 2.6, 2.7, 3.2-3.5.
 | 
			
		||||
    """
 | 
			
		||||
    parser = HTMLAttributeParser()
 | 
			
		||||
    try:
 | 
			
		||||
@@ -763,8 +723,6 @@ def sanitize_path(s, force=False):
 | 
			
		||||
    if sys.platform == 'win32':
 | 
			
		||||
        force = False
 | 
			
		||||
        drive_or_unc, _ = os.path.splitdrive(s)
 | 
			
		||||
        if sys.version_info < (2, 7) and not drive_or_unc:
 | 
			
		||||
            drive_or_unc, _ = os.path.splitunc(s)
 | 
			
		||||
    elif force:
 | 
			
		||||
        drive_or_unc = ''
 | 
			
		||||
    else:
 | 
			
		||||
@@ -922,51 +880,23 @@ def get_subprocess_encoding():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def encodeFilename(s, for_subprocess=False):
 | 
			
		||||
    """
 | 
			
		||||
    @param s The name of the file
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    assert type(s) == compat_str
 | 
			
		||||
 | 
			
		||||
    # Python 3 has a Unicode API
 | 
			
		||||
    if sys.version_info >= (3, 0):
 | 
			
		||||
        return s
 | 
			
		||||
 | 
			
		||||
    # Pass '' directly to use Unicode APIs on Windows 2000 and up
 | 
			
		||||
    # (Detecting Windows NT 4 is tricky because 'major >= 4' would
 | 
			
		||||
    # match Windows 9x series as well. Besides, NT 4 is obsolete.)
 | 
			
		||||
    if not for_subprocess and sys.platform == 'win32' and sys.getwindowsversion()[0] >= 5:
 | 
			
		||||
        return s
 | 
			
		||||
 | 
			
		||||
    # Jython assumes filenames are Unicode strings though reported as Python 2.x compatible
 | 
			
		||||
    if sys.platform.startswith('java'):
 | 
			
		||||
        return s
 | 
			
		||||
 | 
			
		||||
    return s.encode(get_subprocess_encoding(), 'ignore')
 | 
			
		||||
    assert type(s) == str
 | 
			
		||||
    return s
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def decodeFilename(b, for_subprocess=False):
 | 
			
		||||
 | 
			
		||||
    if sys.version_info >= (3, 0):
 | 
			
		||||
        return b
 | 
			
		||||
 | 
			
		||||
    if not isinstance(b, bytes):
 | 
			
		||||
        return b
 | 
			
		||||
 | 
			
		||||
    return b.decode(get_subprocess_encoding(), 'ignore')
 | 
			
		||||
    return b
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def encodeArgument(s):
 | 
			
		||||
    if not isinstance(s, compat_str):
 | 
			
		||||
        # Legacy code that uses byte strings
 | 
			
		||||
        # Uncomment the following line after fixing all post processors
 | 
			
		||||
        # assert False, 'Internal error: %r should be of type %r, is %r' % (s, compat_str, type(s))
 | 
			
		||||
        s = s.decode('ascii')
 | 
			
		||||
    return encodeFilename(s, True)
 | 
			
		||||
    # Legacy code that uses byte strings
 | 
			
		||||
    # Uncomment the following line after fixing all post processors
 | 
			
		||||
    # assert isinstance(s, str), 'Internal error: %r should be of type %r, is %r' % (s, compat_str, type(s))
 | 
			
		||||
    return s if isinstance(s, str) else s.decode('ascii')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def decodeArgument(b):
 | 
			
		||||
    return decodeFilename(b, True)
 | 
			
		||||
    return b
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def decodeOption(optval):
 | 
			
		||||
@@ -1263,11 +1193,6 @@ class XAttrUnavailableError(YoutubeDLError):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _create_http_connection(ydl_handler, http_class, is_https, *args, **kwargs):
 | 
			
		||||
    # Working around python 2 bug (see http://bugs.python.org/issue17849) by limiting
 | 
			
		||||
    # expected HTTP responses to meet HTTP/1.0 or later (see also
 | 
			
		||||
    # https://github.com/ytdl-org/youtube-dl/issues/6727)
 | 
			
		||||
    if sys.version_info < (3, 0):
 | 
			
		||||
        kwargs['strict'] = True
 | 
			
		||||
    hc = http_class(*args, **compat_kwargs(kwargs))
 | 
			
		||||
    source_address = ydl_handler._params.get('source_address')
 | 
			
		||||
 | 
			
		||||
@@ -1309,20 +1234,7 @@ def _create_http_connection(ydl_handler, http_class, is_https, *args, **kwargs):
 | 
			
		||||
                raise socket.error('getaddrinfo returns an empty list')
 | 
			
		||||
        if hasattr(hc, '_create_connection'):
 | 
			
		||||
            hc._create_connection = _create_connection
 | 
			
		||||
        sa = (source_address, 0)
 | 
			
		||||
        if hasattr(hc, 'source_address'):  # Python 2.7+
 | 
			
		||||
            hc.source_address = sa
 | 
			
		||||
        else:  # Python 2.6
 | 
			
		||||
            def _hc_connect(self, *args, **kwargs):
 | 
			
		||||
                sock = _create_connection(
 | 
			
		||||
                    (self.host, self.port), self.timeout, sa)
 | 
			
		||||
                if is_https:
 | 
			
		||||
                    self.sock = ssl.wrap_socket(
 | 
			
		||||
                        sock, self.key_file, self.cert_file,
 | 
			
		||||
                        ssl_version=ssl.PROTOCOL_TLSv1)
 | 
			
		||||
                else:
 | 
			
		||||
                    self.sock = sock
 | 
			
		||||
            hc.connect = functools.partial(_hc_connect, hc)
 | 
			
		||||
        hc.source_address = (source_address, 0)
 | 
			
		||||
 | 
			
		||||
    return hc
 | 
			
		||||
 | 
			
		||||
@@ -1413,11 +1325,6 @@ class YoutubeDLHandler(compat_urllib_request.HTTPHandler):
 | 
			
		||||
 | 
			
		||||
        req.headers = handle_youtubedl_headers(req.headers)
 | 
			
		||||
 | 
			
		||||
        if sys.version_info < (2, 7) and '#' in req.get_full_url():
 | 
			
		||||
            # Python 2.6 is brain-dead when it comes to fragments
 | 
			
		||||
            req._Request__original = req._Request__original.partition('#')[0]
 | 
			
		||||
            req._Request__r_type = req._Request__r_type.partition('#')[0]
 | 
			
		||||
 | 
			
		||||
        return req
 | 
			
		||||
 | 
			
		||||
    def http_response(self, req, resp):
 | 
			
		||||
@@ -1461,15 +1368,10 @@ class YoutubeDLHandler(compat_urllib_request.HTTPHandler):
 | 
			
		||||
            location = resp.headers.get('Location')
 | 
			
		||||
            if location:
 | 
			
		||||
                # As of RFC 2616 default charset is iso-8859-1 that is respected by python 3
 | 
			
		||||
                if sys.version_info >= (3, 0):
 | 
			
		||||
                    location = location.encode('iso-8859-1').decode('utf-8')
 | 
			
		||||
                else:
 | 
			
		||||
                    location = location.decode('utf-8')
 | 
			
		||||
                location = location.encode('iso-8859-1').decode('utf-8')
 | 
			
		||||
                location_escaped = escape_url(location)
 | 
			
		||||
                if location != location_escaped:
 | 
			
		||||
                    del resp.headers['Location']
 | 
			
		||||
                    if sys.version_info < (3, 0):
 | 
			
		||||
                        location_escaped = location_escaped.encode('utf-8')
 | 
			
		||||
                    resp.headers['Location'] = location_escaped
 | 
			
		||||
        return resp
 | 
			
		||||
 | 
			
		||||
@@ -1668,19 +1570,6 @@ class YoutubeDLCookieProcessor(compat_urllib_request.HTTPCookieProcessor):
 | 
			
		||||
        compat_urllib_request.HTTPCookieProcessor.__init__(self, cookiejar)
 | 
			
		||||
 | 
			
		||||
    def http_response(self, request, response):
 | 
			
		||||
        # Python 2 will choke on next HTTP request in row if there are non-ASCII
 | 
			
		||||
        # characters in Set-Cookie HTTP header of last response (see
 | 
			
		||||
        # https://github.com/ytdl-org/youtube-dl/issues/6769).
 | 
			
		||||
        # In order to at least prevent crashing we will percent encode Set-Cookie
 | 
			
		||||
        # header before HTTPCookieProcessor starts processing it.
 | 
			
		||||
        # if sys.version_info < (3, 0) and response.headers:
 | 
			
		||||
        #     for set_cookie_header in ('Set-Cookie', 'Set-Cookie2'):
 | 
			
		||||
        #         set_cookie = response.headers.get(set_cookie_header)
 | 
			
		||||
        #         if set_cookie:
 | 
			
		||||
        #             set_cookie_escaped = compat_urllib_parse.quote(set_cookie, b"%/;:@&=+$,!~*'()?#[] ")
 | 
			
		||||
        #             if set_cookie != set_cookie_escaped:
 | 
			
		||||
        #                 del response.headers[set_cookie_header]
 | 
			
		||||
        #                 response.headers[set_cookie_header] = set_cookie_escaped
 | 
			
		||||
        return compat_urllib_request.HTTPCookieProcessor.http_response(self, request, response)
 | 
			
		||||
 | 
			
		||||
    https_request = compat_urllib_request.HTTPCookieProcessor.http_request
 | 
			
		||||
@@ -1724,12 +1613,6 @@ class YoutubeDLRedirectHandler(compat_urllib_request.HTTPRedirectHandler):
 | 
			
		||||
        # essentially all clients do redirect in this case, so we do
 | 
			
		||||
        # the same.
 | 
			
		||||
 | 
			
		||||
        # On python 2 urlh.geturl() may sometimes return redirect URL
 | 
			
		||||
        # as byte string instead of unicode. This workaround allows
 | 
			
		||||
        # to force it always return unicode.
 | 
			
		||||
        if sys.version_info[0] < 3:
 | 
			
		||||
            newurl = compat_str(newurl)
 | 
			
		||||
 | 
			
		||||
        # Be conciliant with URIs containing a space.  This is mainly
 | 
			
		||||
        # redundant with the more complete encoding done in http_error_302(),
 | 
			
		||||
        # but it is kept for compatibility with other callers.
 | 
			
		||||
@@ -2013,91 +1896,12 @@ def get_windows_version():
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _windows_write_string(s, out):
 | 
			
		||||
    """ Returns True if the string was written using special methods,
 | 
			
		||||
    False if it has yet to be written out."""
 | 
			
		||||
    # Adapted from http://stackoverflow.com/a/3259271/35070
 | 
			
		||||
 | 
			
		||||
    import ctypes.wintypes
 | 
			
		||||
 | 
			
		||||
    WIN_OUTPUT_IDS = {
 | 
			
		||||
        1: -11,
 | 
			
		||||
        2: -12,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        fileno = out.fileno()
 | 
			
		||||
    except AttributeError:
 | 
			
		||||
        # If the output stream doesn't have a fileno, it's virtual
 | 
			
		||||
        return False
 | 
			
		||||
    except io.UnsupportedOperation:
 | 
			
		||||
        # Some strange Windows pseudo files?
 | 
			
		||||
        return False
 | 
			
		||||
    if fileno not in WIN_OUTPUT_IDS:
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    GetStdHandle = compat_ctypes_WINFUNCTYPE(
 | 
			
		||||
        ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD)(
 | 
			
		||||
        ('GetStdHandle', ctypes.windll.kernel32))
 | 
			
		||||
    h = GetStdHandle(WIN_OUTPUT_IDS[fileno])
 | 
			
		||||
 | 
			
		||||
    WriteConsoleW = compat_ctypes_WINFUNCTYPE(
 | 
			
		||||
        ctypes.wintypes.BOOL, ctypes.wintypes.HANDLE, ctypes.wintypes.LPWSTR,
 | 
			
		||||
        ctypes.wintypes.DWORD, ctypes.POINTER(ctypes.wintypes.DWORD),
 | 
			
		||||
        ctypes.wintypes.LPVOID)(('WriteConsoleW', ctypes.windll.kernel32))
 | 
			
		||||
    written = ctypes.wintypes.DWORD(0)
 | 
			
		||||
 | 
			
		||||
    GetFileType = compat_ctypes_WINFUNCTYPE(ctypes.wintypes.DWORD, ctypes.wintypes.DWORD)(('GetFileType', ctypes.windll.kernel32))
 | 
			
		||||
    FILE_TYPE_CHAR = 0x0002
 | 
			
		||||
    FILE_TYPE_REMOTE = 0x8000
 | 
			
		||||
    GetConsoleMode = compat_ctypes_WINFUNCTYPE(
 | 
			
		||||
        ctypes.wintypes.BOOL, ctypes.wintypes.HANDLE,
 | 
			
		||||
        ctypes.POINTER(ctypes.wintypes.DWORD))(
 | 
			
		||||
        ('GetConsoleMode', ctypes.windll.kernel32))
 | 
			
		||||
    INVALID_HANDLE_VALUE = ctypes.wintypes.DWORD(-1).value
 | 
			
		||||
 | 
			
		||||
    def not_a_console(handle):
 | 
			
		||||
        if handle == INVALID_HANDLE_VALUE or handle is None:
 | 
			
		||||
            return True
 | 
			
		||||
        return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR
 | 
			
		||||
                or GetConsoleMode(handle, ctypes.byref(ctypes.wintypes.DWORD())) == 0)
 | 
			
		||||
 | 
			
		||||
    if not_a_console(h):
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    def next_nonbmp_pos(s):
 | 
			
		||||
        try:
 | 
			
		||||
            return next(i for i, c in enumerate(s) if ord(c) > 0xffff)
 | 
			
		||||
        except StopIteration:
 | 
			
		||||
            return len(s)
 | 
			
		||||
 | 
			
		||||
    while s:
 | 
			
		||||
        count = min(next_nonbmp_pos(s), 1024)
 | 
			
		||||
 | 
			
		||||
        ret = WriteConsoleW(
 | 
			
		||||
            h, s, count if count else 2, ctypes.byref(written), None)
 | 
			
		||||
        if ret == 0:
 | 
			
		||||
            raise OSError('Failed to write string')
 | 
			
		||||
        if not count:  # We just wrote a non-BMP character
 | 
			
		||||
            assert written.value == 2
 | 
			
		||||
            s = s[1:]
 | 
			
		||||
        else:
 | 
			
		||||
            assert written.value > 0
 | 
			
		||||
            s = s[written.value:]
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def write_string(s, out=None, encoding=None):
 | 
			
		||||
    if out is None:
 | 
			
		||||
        out = sys.stderr
 | 
			
		||||
    assert type(s) == compat_str
 | 
			
		||||
 | 
			
		||||
    if sys.platform == 'win32' and encoding is None and hasattr(out, 'fileno'):
 | 
			
		||||
        if _windows_write_string(s, out):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
    if ('b' in getattr(out, 'mode', '')
 | 
			
		||||
            or sys.version_info[0] < 3):  # Python 2 lies about mode of sys.stderr
 | 
			
		||||
    if 'b' in getattr(out, 'mode', ''):
 | 
			
		||||
        byt = s.encode(encoding or preferredencoding(), 'ignore')
 | 
			
		||||
        out.write(byt)
 | 
			
		||||
    elif hasattr(out, 'buffer'):
 | 
			
		||||
@@ -2985,8 +2789,6 @@ def lowercase_escape(s):
 | 
			
		||||
 | 
			
		||||
def escape_rfc3986(s):
 | 
			
		||||
    """Escape non-ASCII characters as suggested by RFC 3986"""
 | 
			
		||||
    if sys.version_info < (3, 0) and isinstance(s, compat_str):
 | 
			
		||||
        s = s.encode('utf-8')
 | 
			
		||||
    return compat_urllib_parse.quote(s, b"%/;:@&=+$,!~*'()?#[]")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -3335,12 +3137,7 @@ def args_to_str(args):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def error_to_compat_str(err):
 | 
			
		||||
    err_str = str(err)
 | 
			
		||||
    # On python 2 error byte string must be decoded with proper
 | 
			
		||||
    # encoding rather than ascii
 | 
			
		||||
    if sys.version_info[0] < 3:
 | 
			
		||||
        err_str = err_str.decode(preferredencoding())
 | 
			
		||||
    return err_str
 | 
			
		||||
    return str(err)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def error_to_str(err):
 | 
			
		||||
@@ -5144,7 +4941,7 @@ def get_executable_path():
 | 
			
		||||
    from zipimport import zipimporter
 | 
			
		||||
    if hasattr(sys, 'frozen'):  # Running from PyInstaller
 | 
			
		||||
        path = os.path.dirname(sys.executable)
 | 
			
		||||
    elif isinstance(globals().get('__loader__'), zipimporter):  # Running from ZIP
 | 
			
		||||
    elif isinstance(__loader__, zipimporter):  # Running from ZIP
 | 
			
		||||
        path = os.path.join(os.path.dirname(__file__), '../..')
 | 
			
		||||
    else:
 | 
			
		||||
        path = os.path.join(os.path.dirname(__file__), '..')
 | 
			
		||||
@@ -5436,8 +5233,6 @@ class Config:
 | 
			
		||||
        try:
 | 
			
		||||
            # FIXME: https://github.com/ytdl-org/youtube-dl/commit/dfe5fa49aed02cf36ba9f743b11b0903554b5e56
 | 
			
		||||
            contents = optionf.read()
 | 
			
		||||
            if sys.version_info < (3,):
 | 
			
		||||
                contents = contents.decode(preferredencoding())
 | 
			
		||||
            res = compat_shlex_split(contents, comments=True)
 | 
			
		||||
        finally:
 | 
			
		||||
            optionf.close()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user