diff --git a/free_bandcamp_downloader/__main__.py b/free_bandcamp_downloader/__main__.py index b28d47c..678eded 100644 --- a/free_bandcamp_downloader/__main__.py +++ b/free_bandcamp_downloader/__main__.py @@ -65,6 +65,7 @@ from docopt import docopt from tqdm import tqdm from free_bandcamp_downloader import __version__, logger +from free_bandcamp_downloader.bandcamp_http_adapter import BandcampHTTPAdapter @dataclass @@ -138,6 +139,7 @@ class BCFreeDownloader: def _init_session(self, cookies_file: Optional[str], identity: Optional[str]): self.session = requests.Session() + self.session.mount("https://", BandcampHTTPAdapter()) if cookies_file: cj = MozillaCookieJar(cookies_file) cj.load() @@ -319,7 +321,7 @@ class BCFreeDownloader: # the one that corresponds to the track release (t) or album release (a) # physical releases are p, and discography offers are b, so this should be fine head_data = next(obj for obj in head_data if obj["@id"] == url) - if not "offers" in head_data: + if "offers" not in head_data: raise BCFreeDownloadError(f"{url} has no digital download. Skipping...") album_data.title = head_data["name"] diff --git a/free_bandcamp_downloader/bandcamp_http_adapter.py b/free_bandcamp_downloader/bandcamp_http_adapter.py new file mode 100644 index 0000000..5916b7d --- /dev/null +++ b/free_bandcamp_downloader/bandcamp_http_adapter.py @@ -0,0 +1,32 @@ +from requests.adapters import HTTPAdapter +from urllib3.util.ssl_ import create_urllib3_context + + +# https://github.com/urllib3/urllib3/issues/3439#issuecomment-2306400349 +class BandcampHTTPAdapter(HTTPAdapter): + def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs): + ctx = create_urllib3_context() + ctx.load_default_certs() + DEFAULT_CIPHERS = ":".join( + [ + "ECDHE+AESGCM", + "ECDHE+CHACHA20", + "DHE+AESGCM", + "DHE+CHACHA20", + "ECDH+AESGCM", + "DH+AESGCM", + "ECDH+AES", + "DH+AES", + "RSA+AESGCM", + "RSA+AES", + "!aNULL", + "!eNULL", + "!MD5", + "!DSS", + "!AESCCM", + ] + ) + ctx.set_ciphers(DEFAULT_CIPHERS) + return super().init_poolmanager( + connections, maxsize, block, **pool_kwargs, ssl_context=ctx + ) diff --git a/poetry.lock b/poetry.lock index 7d8154d..9d8ab34 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. [[package]] name = "1secmail" @@ -261,13 +261,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -385,21 +385,22 @@ files = [ [[package]] name = "urllib3" -version = "1.26.19" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +python-versions = ">=3.8" files = [ - {file = "urllib3-1.26.19-py2.py3-none-any.whl", hash = "sha256:37a0344459b199fce0e80b0d3569837ec6b6937435c5244e7fd73fa6006830f3"}, - {file = "urllib3-1.26.19.tar.gz", hash = "sha256:3e3d753a8618b86d7de333b4223005f68720bcd6a7d2bcb9fbd2229ec7c1e429"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] -brotli = ["brotli (==1.0.9)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "11c64bcfbd3c88d4b144cc9f75d62d20a459abae169c7d56ec02d5fb4691e439" +content-hash = "b167eea04fb32fb22688a58b4a4cab72d2ad7bd468f82b19fb06bb5c20271dd9" diff --git a/pyproject.toml b/pyproject.toml index 058f274..267675a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "free-bandcamp-downloader" -version = "0.3.4" +version = "0.3.5" description = "Download free and name-your-price albums from Bandcamp in lossless quality" authors = ["7x11x13 "] license = "MIT" @@ -18,7 +18,6 @@ pyrfc6266 = "^1.0.2" mutagen = "^1.47.0" 1secmail = "^1.1.0" docopt-ng = "^0.9.0" -urllib3 = "<2.0.0" [build-system]