2016-07-07 03:37:29 -06:00
|
|
|
# coding: utf-8
|
2014-11-02 03:36:29 -07:00
|
|
|
|
2021-07-19 14:51:55 -06:00
|
|
|
import asyncio
|
2018-01-23 07:53:01 -07:00
|
|
|
import base64
|
2014-12-11 20:01:08 -07:00
|
|
|
import ctypes
|
2014-11-02 03:23:40 -07:00
|
|
|
import getpass
|
2021-07-19 14:51:55 -06:00
|
|
|
import html
|
|
|
|
import html.parser
|
|
|
|
import http
|
|
|
|
import http.client
|
|
|
|
import http.cookiejar
|
|
|
|
import http.cookies
|
|
|
|
import http.server
|
2017-09-05 20:24:34 -06:00
|
|
|
import itertools
|
2014-11-19 10:21:58 -07:00
|
|
|
import optparse
|
2014-11-02 03:23:40 -07:00
|
|
|
import os
|
2014-11-23 02:49:19 -07:00
|
|
|
import re
|
2015-09-05 09:40:44 -06:00
|
|
|
import shlex
|
2015-02-28 13:42:16 -07:00
|
|
|
import shutil
|
2015-01-10 11:55:36 -07:00
|
|
|
import socket
|
2016-04-23 04:28:49 -06:00
|
|
|
import struct
|
2014-11-02 03:23:40 -07:00
|
|
|
import sys
|
2021-07-19 14:51:55 -06:00
|
|
|
import tokenize
|
|
|
|
import urllib
|
|
|
|
import xml.etree.ElementTree as etree
|
|
|
|
from subprocess import DEVNULL
|
2017-06-11 12:50:32 -06:00
|
|
|
|
|
|
|
|
2021-07-19 14:51:55 -06:00
|
|
|
# HTMLParseError has been deprecated in Python 3.3 and removed in
|
|
|
|
# Python 3.5. Introducing dummy exception for Python >3.5 for compatible
|
|
|
|
# and uniform cross-version exception handling
|
|
|
|
class compat_HTMLParseError(Exception):
|
|
|
|
pass
|
2016-03-25 13:46:57 -06:00
|
|
|
|
|
|
|
|
2021-07-19 14:51:55 -06:00
|
|
|
def compat_ctypes_WINFUNCTYPE(*args, **kwargs):
|
|
|
|
return ctypes.WINFUNCTYPE(*args, **kwargs)
|
2016-05-22 11:34:08 -06:00
|
|
|
|
|
|
|
|
|
|
|
class _TreeBuilder(etree.TreeBuilder):
|
|
|
|
def doctype(self, name, pubid, system):
|
|
|
|
pass
|
|
|
|
|
2016-11-17 04:42:56 -07:00
|
|
|
|
2021-07-19 14:51:55 -06:00
|
|
|
def compat_etree_fromstring(text):
|
|
|
|
return etree.XML(text, parser=etree.XMLParser(target=_TreeBuilder()))
|
2014-11-02 03:23:40 -07:00
|
|
|
|
2017-06-17 10:14:24 -06:00
|
|
|
|
|
|
|
compat_os_name = os._name if os.name == 'java' else os.name
|
|
|
|
|
|
|
|
|
|
|
|
if compat_os_name == 'nt':
|
2016-05-10 01:58:25 -06:00
|
|
|
def compat_shlex_quote(s):
|
2017-06-17 10:14:24 -06:00
|
|
|
return s if re.match(r'^[-_\w./]+$', s) else '"%s"' % s.replace('"', '\\"')
|
|
|
|
else:
|
2021-07-19 14:51:55 -06:00
|
|
|
from shlex import quote as compat_shlex_quote
|
2015-09-05 09:40:44 -06:00
|
|
|
|
|
|
|
|
2014-11-02 03:23:40 -07:00
|
|
|
def compat_ord(c):
|
2014-11-23 12:41:03 -07:00
|
|
|
if type(c) is int:
|
|
|
|
return c
|
|
|
|
else:
|
|
|
|
return ord(c)
|
2014-11-02 03:23:40 -07:00
|
|
|
|
|
|
|
|
2021-07-19 14:51:55 -06:00
|
|
|
def compat_setenv(key, value, env=os.environ):
|
|
|
|
env[key] = value
|
2014-11-02 03:23:40 -07:00
|
|
|
|
|
|
|
|
2020-02-08 05:36:55 -07:00
|
|
|
if compat_os_name == 'nt' and sys.version_info < (3, 8):
|
|
|
|
# os.path.realpath on Windows does not follow symbolic links
|
|
|
|
# prior to Python 3.8 (see https://bugs.python.org/issue9949)
|
|
|
|
def compat_realpath(path):
|
|
|
|
while os.path.islink(path):
|
|
|
|
path = os.path.abspath(os.readlink(path))
|
|
|
|
return path
|
|
|
|
else:
|
|
|
|
compat_realpath = os.path.realpath
|
|
|
|
|
|
|
|
|
2021-07-19 14:51:55 -06:00
|
|
|
def compat_print(s):
|
|
|
|
assert isinstance(s, compat_str)
|
|
|
|
print(s)
|
2015-01-10 11:55:36 -07:00
|
|
|
|
|
|
|
|
2019-03-09 05:14:41 -07:00
|
|
|
# Fix https://github.com/ytdl-org/youtube-dl/issues/4223
|
2014-11-19 10:21:58 -07:00
|
|
|
# See http://bugs.python.org/issue9161 for what is broken
|
|
|
|
def workaround_optparse_bug9161():
|
2014-11-19 23:21:12 -07:00
|
|
|
op = optparse.OptionParser()
|
|
|
|
og = optparse.OptionGroup(op, 'foo')
|
2014-11-19 10:21:58 -07:00
|
|
|
try:
|
2014-11-19 23:21:12 -07:00
|
|
|
og.add_option('-t')
|
2014-11-20 08:35:55 -07:00
|
|
|
except TypeError:
|
2014-11-19 10:21:58 -07:00
|
|
|
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
|
|
|
|
|
2016-11-17 04:42:56 -07:00
|
|
|
|
2021-04-28 04:47:30 -06:00
|
|
|
try:
|
|
|
|
compat_Pattern = re.Pattern
|
|
|
|
except AttributeError:
|
|
|
|
compat_Pattern = type(re.compile(''))
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
compat_Match = re.Match
|
|
|
|
except AttributeError:
|
|
|
|
compat_Match = type(re.compile('').match(''))
|
|
|
|
|
|
|
|
|
2021-06-21 11:23:17 -06:00
|
|
|
try:
|
2021-07-19 14:51:55 -06:00
|
|
|
compat_asyncio_run = asyncio.run # >= 3.7
|
2021-06-21 11:23:17 -06:00
|
|
|
except AttributeError:
|
|
|
|
def compat_asyncio_run(coro):
|
|
|
|
try:
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
except RuntimeError:
|
|
|
|
loop = asyncio.new_event_loop()
|
|
|
|
asyncio.set_event_loop(loop)
|
|
|
|
loop.run_until_complete(coro)
|
|
|
|
|
|
|
|
asyncio.run = compat_asyncio_run
|
|
|
|
|
|
|
|
|
2021-09-15 13:04:18 -06:00
|
|
|
# Python 3.8+ does not honor %HOME% on windows, but this breaks compatibility with youtube-dl
|
|
|
|
# See https://github.com/yt-dlp/yt-dlp/issues/792
|
|
|
|
# https://docs.python.org/3/library/os.path.html#os.path.expanduser
|
|
|
|
if compat_os_name in ('nt', 'ce') and 'HOME' in os.environ:
|
|
|
|
_userhome = os.environ['HOME']
|
|
|
|
|
|
|
|
def compat_expanduser(path):
|
|
|
|
if not path.startswith('~'):
|
|
|
|
return path
|
|
|
|
i = path.replace('\\', '/', 1).find('/') # ~user
|
|
|
|
if i < 0:
|
|
|
|
i = len(path)
|
|
|
|
userhome = os.path.join(os.path.dirname(_userhome), path[1:i]) if i > 1 else _userhome
|
|
|
|
return userhome + path[i:]
|
|
|
|
else:
|
|
|
|
compat_expanduser = os.path.expanduser
|
|
|
|
|
|
|
|
|
2021-09-17 13:21:27 -06:00
|
|
|
try:
|
|
|
|
from Cryptodome.Cipher import AES as compat_pycrypto_AES
|
|
|
|
except ImportError:
|
|
|
|
try:
|
|
|
|
from Crypto.Cipher import AES as compat_pycrypto_AES
|
|
|
|
except ImportError:
|
|
|
|
compat_pycrypto_AES = None
|
|
|
|
|
|
|
|
|
2021-07-19 14:51:55 -06:00
|
|
|
# Deprecated
|
|
|
|
|
|
|
|
compat_basestring = str
|
|
|
|
compat_chr = chr
|
|
|
|
compat_input = input
|
|
|
|
compat_integer_types = (int, )
|
|
|
|
compat_kwargs = lambda kwargs: kwargs
|
|
|
|
compat_numeric_types = (int, float, complex)
|
|
|
|
compat_str = str
|
|
|
|
compat_xpath = lambda xpath: xpath
|
|
|
|
compat_zip = zip
|
|
|
|
|
|
|
|
compat_HTMLParser = html.parser.HTMLParser
|
|
|
|
compat_HTTPError = urllib.error.HTTPError
|
|
|
|
compat_Struct = struct.Struct
|
|
|
|
compat_b64decode = base64.b64decode
|
|
|
|
compat_cookiejar = http.cookiejar
|
|
|
|
compat_cookiejar_Cookie = compat_cookiejar.Cookie
|
|
|
|
compat_cookies = http.cookies
|
|
|
|
compat_cookies_SimpleCookie = compat_cookies.SimpleCookie
|
|
|
|
compat_etree_Element = etree.Element
|
|
|
|
compat_etree_register_namespace = etree.register_namespace
|
|
|
|
compat_get_terminal_size = shutil.get_terminal_size
|
|
|
|
compat_getenv = os.getenv
|
|
|
|
compat_getpass = getpass.getpass
|
|
|
|
compat_html_entities = html.entities
|
|
|
|
compat_html_entities_html5 = compat_html_entities.html5
|
|
|
|
compat_http_client = http.client
|
|
|
|
compat_http_server = http.server
|
|
|
|
compat_itertools_count = itertools.count
|
|
|
|
compat_parse_qs = urllib.parse.parse_qs
|
|
|
|
compat_shlex_split = shlex.split
|
|
|
|
compat_socket_create_connection = socket.create_connection
|
|
|
|
compat_struct_pack = struct.pack
|
|
|
|
compat_struct_unpack = struct.unpack
|
|
|
|
compat_subprocess_get_DEVNULL = lambda: DEVNULL
|
|
|
|
compat_tokenize_tokenize = tokenize.tokenize
|
|
|
|
compat_urllib_error = urllib.error
|
|
|
|
compat_urllib_parse = urllib.parse
|
|
|
|
compat_urllib_parse_quote = urllib.parse.quote
|
|
|
|
compat_urllib_parse_quote_plus = urllib.parse.quote_plus
|
|
|
|
compat_urllib_parse_unquote = urllib.parse.unquote
|
|
|
|
compat_urllib_parse_unquote_plus = urllib.parse.unquote_plus
|
|
|
|
compat_urllib_parse_unquote_to_bytes = urllib.parse.unquote_to_bytes
|
|
|
|
compat_urllib_parse_urlencode = urllib.parse.urlencode
|
|
|
|
compat_urllib_parse_urlparse = urllib.parse.urlparse
|
|
|
|
compat_urllib_parse_urlunparse = urllib.parse.urlunparse
|
|
|
|
compat_urllib_request = urllib.request
|
|
|
|
compat_urllib_request_DataHandler = urllib.request.DataHandler
|
|
|
|
compat_urllib_response = urllib.response
|
|
|
|
compat_urlparse = urllib.parse
|
|
|
|
compat_urlretrieve = urllib.request.urlretrieve
|
|
|
|
compat_xml_parse_error = etree.ParseError
|
|
|
|
|
|
|
|
|
|
|
|
# Set public objects
|
|
|
|
|
2014-11-02 03:23:40 -07:00
|
|
|
__all__ = [
|
2017-06-11 13:35:57 -06:00
|
|
|
'compat_HTMLParseError',
|
2016-01-02 12:49:59 -07:00
|
|
|
'compat_HTMLParser',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_HTTPError',
|
2021-04-28 04:47:30 -06:00
|
|
|
'compat_Match',
|
|
|
|
'compat_Pattern',
|
2018-01-27 13:04:39 -07:00
|
|
|
'compat_Struct',
|
2021-06-21 11:23:17 -06:00
|
|
|
'compat_asyncio_run',
|
2018-01-23 07:53:01 -07:00
|
|
|
'compat_b64decode',
|
2015-02-01 03:36:59 -07:00
|
|
|
'compat_basestring',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_chr',
|
|
|
|
'compat_cookiejar',
|
2020-05-04 16:54:10 -06:00
|
|
|
'compat_cookiejar_Cookie',
|
2015-07-29 16:20:37 -06:00
|
|
|
'compat_cookies',
|
2021-04-10 10:47:11 -06:00
|
|
|
'compat_cookies_SimpleCookie',
|
2014-12-11 20:01:08 -07:00
|
|
|
'compat_ctypes_WINFUNCTYPE',
|
2019-03-05 11:18:52 -07:00
|
|
|
'compat_etree_Element',
|
2015-10-25 13:04:55 -06:00
|
|
|
'compat_etree_fromstring',
|
2017-02-01 12:15:25 -07:00
|
|
|
'compat_etree_register_namespace',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_expanduser',
|
2015-02-28 13:42:16 -07:00
|
|
|
'compat_get_terminal_size',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_getenv',
|
|
|
|
'compat_getpass',
|
|
|
|
'compat_html_entities',
|
2016-06-10 01:05:24 -06:00
|
|
|
'compat_html_entities_html5',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_http_client',
|
2015-01-29 18:57:37 -07:00
|
|
|
'compat_http_server',
|
2016-06-05 15:16:08 -06:00
|
|
|
'compat_input',
|
2018-06-17 14:22:08 -06:00
|
|
|
'compat_integer_types',
|
2015-07-10 04:58:12 -06:00
|
|
|
'compat_itertools_count',
|
2014-11-15 07:17:19 -07:00
|
|
|
'compat_kwargs',
|
2016-03-05 10:07:25 -07:00
|
|
|
'compat_numeric_types',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_ord',
|
2016-03-03 04:24:24 -07:00
|
|
|
'compat_os_name',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_parse_qs',
|
|
|
|
'compat_print',
|
2021-09-17 13:21:27 -06:00
|
|
|
'compat_pycrypto_AES',
|
2020-02-08 05:38:36 -07:00
|
|
|
'compat_realpath',
|
2016-05-09 09:55:03 -06:00
|
|
|
'compat_setenv',
|
2016-05-10 01:58:25 -06:00
|
|
|
'compat_shlex_quote',
|
2015-09-05 09:40:44 -06:00
|
|
|
'compat_shlex_split',
|
2015-01-10 11:55:36 -07:00
|
|
|
'compat_socket_create_connection',
|
2015-01-11 02:13:03 -07:00
|
|
|
'compat_str',
|
2016-05-03 02:50:16 -06:00
|
|
|
'compat_struct_pack',
|
|
|
|
'compat_struct_unpack',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_subprocess_get_DEVNULL',
|
2015-06-28 14:08:29 -06:00
|
|
|
'compat_tokenize_tokenize',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_urllib_error',
|
|
|
|
'compat_urllib_parse',
|
2020-10-27 04:37:21 -06:00
|
|
|
'compat_urllib_parse_quote',
|
|
|
|
'compat_urllib_parse_quote_plus',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_urllib_parse_unquote',
|
2015-07-17 11:28:34 -06:00
|
|
|
'compat_urllib_parse_unquote_plus',
|
2015-07-17 06:24:07 -06:00
|
|
|
'compat_urllib_parse_unquote_to_bytes',
|
2016-03-25 13:46:57 -06:00
|
|
|
'compat_urllib_parse_urlencode',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_urllib_parse_urlparse',
|
2020-10-27 04:37:21 -06:00
|
|
|
'compat_urllib_parse_urlunparse',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_urllib_request',
|
2015-10-17 09:15:01 -06:00
|
|
|
'compat_urllib_request_DataHandler',
|
|
|
|
'compat_urllib_response',
|
2014-11-02 03:23:40 -07:00
|
|
|
'compat_urlparse',
|
|
|
|
'compat_urlretrieve',
|
|
|
|
'compat_xml_parse_error',
|
2016-03-17 14:51:38 -06:00
|
|
|
'compat_xpath',
|
2017-09-05 20:24:34 -06:00
|
|
|
'compat_zip',
|
2014-11-19 10:21:58 -07:00
|
|
|
'workaround_optparse_bug9161',
|
2014-11-02 03:23:40 -07:00
|
|
|
]
|