1 """No longer used and new code should not use. Exists only for API compat."""
10 from ._utils
import Popen
, decode_base_n
, preferredencoding
11 from .networking
import escape_rfc3986
# noqa: F401
12 from .networking
import normalize_url
as escape_url
# noqa: F401
13 from .traversal
import traverse_obj
14 from ..dependencies
import certifi
, websockets
15 from ..networking
._helper
import make_ssl_context
16 from ..networking
._urllib
import HTTPHandler
19 from .networking
import random_user_agent
, std_headers
# noqa: F401
20 from ..cookies
import YoutubeDLCookieJar
# noqa: F401
21 from ..networking
._urllib
import PUTRequest
# noqa: F401
22 from ..networking
._urllib
import SUPPORTED_ENCODINGS
, HEADRequest
# noqa: F401
23 from ..networking
._urllib
import ProxyHandler
as PerRequestProxyHandler
# noqa: F401
24 from ..networking
._urllib
import RedirectHandler
as YoutubeDLRedirectHandler
# noqa: F401
25 from ..networking
._urllib
import ( # noqa: F401
26 make_socks_conn_class
,
29 from ..networking
.exceptions
import HTTPError
, network_exceptions
# noqa: F401
31 has_certifi
= bool(certifi
)
32 has_websockets
= bool(websockets
)
35 def load_plugins(name
, suffix
, namespace
):
36 from ..plugins
import load_plugins
37 ret
= load_plugins(name
, suffix
)
42 def traverse_dict(dictn
, keys
, casesense
=True):
43 return traverse_obj(dictn
, keys
, casesense
=casesense
, is_user_input
=True, traverse_string
=True)
46 def decode_base(value
, digits
):
47 return decode_base_n(value
, table
=digits
)
51 """ Returns the platform name as a str """
52 return platform
.platform()
55 def get_subprocess_encoding():
56 if sys
.platform
== 'win32' and sys
.getwindowsversion()[0] >= 5:
57 # For subprocess calls, encode with locale encoding
58 # Refer to http://stackoverflow.com/a/9951851/35070
59 encoding
= preferredencoding()
61 encoding
= sys
.getfilesystemencoding()
68 # Based on png2str() written by @gdkchan and improved by @yokrysty
69 # Originally posted at https://github.com/ytdl-org/youtube-dl/issues/9706
70 def decode_png(png_data
):
71 # Reference: https://www.w3.org/TR/PNG/
74 if png_data
[:8] != b
'\x89PNG\x0d\x0a\x1a\x0a' or header
[4:8] != b
'IHDR':
75 raise OSError('Not a valid PNG file.')
77 int_map
= {1: '>B', 2: '>H', 4: '>I'}
78 unpack_integer
= lambda x
: struct
.unpack(int_map
[len(x
)], x
)[0]
83 length
= unpack_integer(header
[:4])
86 chunk_type
= header
[:4]
89 chunk_data
= header
[:length
]
90 header
= header
[length
:]
92 header
= header
[4:] # Skip CRC
100 ihdr
= chunks
[0]['data']
102 width
= unpack_integer(ihdr
[:4])
103 height
= unpack_integer(ihdr
[4:8])
108 if chunk
['type'] == b
'IDAT':
109 idat
+= chunk
['data']
112 raise OSError('Unable to read PNG data.')
114 decompressed_data
= bytearray(zlib
.decompress(idat
))
124 for y
in range(height
):
125 basePos
= y
* (1 + stride
)
126 filter_type
= decompressed_data
[basePos
]
130 pixels
.append(current_row
)
132 for x
in range(stride
):
133 color
= decompressed_data
[1 + basePos
+ x
]
134 basex
= y
* stride
+ x
139 left
= _get_pixel(basex
- 3)
141 up
= _get_pixel(basex
- stride
)
143 if filter_type
== 1: # Sub
144 color
= (color
+ left
) & 0xff
145 elif filter_type
== 2: # Up
146 color
= (color
+ up
) & 0xff
147 elif filter_type
== 3: # Average
148 color
= (color
+ ((left
+ up
) >> 1)) & 0xff
149 elif filter_type
== 4: # Paeth
155 c
= _get_pixel(basex
- stride
- 3)
163 if pa
<= pb
and pa
<= pc
:
164 color
= (color
+ a
) & 0xff
166 color
= (color
+ b
) & 0xff
168 color
= (color
+ c
) & 0xff
170 current_row
.append(color
)
172 return width
, height
, pixels
175 def register_socks_protocols():
176 # "Register" SOCKS protocols
177 # In Python < 2.6.5, urlsplit() suffers from bug https://bugs.python.org/issue7904
178 # URLs with protocols not in urlparse.uses_netloc are not handled correctly
179 for scheme
in ('socks', 'socks4', 'socks4a', 'socks5'):
180 if scheme
not in urllib
.parse
.uses_netloc
:
181 urllib
.parse
.uses_netloc
.append(scheme
)
184 def handle_youtubedl_headers(headers
):
185 filtered_headers
= headers
187 if 'Youtubedl-no-compression' in filtered_headers
:
188 filtered_headers
= {k: v for k, v in filtered_headers.items() if k.lower() != 'accept-encoding'}
189 del filtered_headers
['Youtubedl-no-compression']
191 return filtered_headers
194 def request_to_url(req
):
195 if isinstance(req
, urllib
.request
.Request
):
196 return req
.get_full_url()
201 def sanitized_Request(url
, *args
, **kwargs
):
202 from ..utils
import extract_basic_auth
, sanitize_url
203 url
, auth_header
= extract_basic_auth(escape_url(sanitize_url(url
)))
204 if auth_header
is not None:
205 headers
= args
[1] if len(args
) >= 2 else kwargs
.setdefault('headers', {})
206 headers
['Authorization'] = auth_header
207 return urllib
.request
.Request(url
, *args
, **kwargs
)
210 class YoutubeDLHandler(HTTPHandler
):
211 def __init__(self
, params
, *args
, **kwargs
):
212 self
._params
= params
213 super().__init
__(*args
, **kwargs
)
216 YoutubeDLHTTPSHandler
= YoutubeDLHandler
219 class YoutubeDLCookieProcessor(urllib
.request
.HTTPCookieProcessor
):
220 def __init__(self
, cookiejar
=None):
221 urllib
.request
.HTTPCookieProcessor
.__init
__(self
, cookiejar
)
223 def http_response(self
, request
, response
):
224 return urllib
.request
.HTTPCookieProcessor
.http_response(self
, request
, response
)
226 https_request
= urllib
.request
.HTTPCookieProcessor
.http_request
227 https_response
= http_response
230 def make_HTTPS_handler(params
, **kwargs
):
231 return YoutubeDLHTTPSHandler(params
, context
=make_ssl_context(
232 verify
=not params
.get('nocheckcertificate'),
233 client_certificate
=params
.get('client_certificate'),
234 client_certificate_key
=params
.get('client_certificate_key'),
235 client_certificate_password
=params
.get('client_certificate_password'),
236 legacy_support
=params
.get('legacyserverconnect'),
237 use_certifi
='no-certifi' not in params
.get('compat_opts', []),
241 def process_communicate_or_kill(p
, *args
, **kwargs
):
242 return Popen
.communicate_or_kill(p
, *args
, **kwargs
)