summaryrefslogtreecommitdiffstats
path: root/yt_dlp/dependencies
diff options
context:
space:
mode:
Diffstat (limited to 'yt_dlp/dependencies')
-rw-r--r--yt_dlp/dependencies/Cryptodome.py38
-rw-r--r--yt_dlp/dependencies/__init__.py92
2 files changed, 130 insertions, 0 deletions
diff --git a/yt_dlp/dependencies/Cryptodome.py b/yt_dlp/dependencies/Cryptodome.py
new file mode 100644
index 0000000..2cfa4c9
--- /dev/null
+++ b/yt_dlp/dependencies/Cryptodome.py
@@ -0,0 +1,38 @@
+from ..compat.compat_utils import passthrough_module
+
+try:
+ import Cryptodome as _parent
+except ImportError:
+ try:
+ import Crypto as _parent
+ except (ImportError, SyntaxError): # Old Crypto gives SyntaxError in newer Python
+ _parent = passthrough_module(__name__, 'no_Cryptodome')
+ __bool__ = lambda: False
+
+del passthrough_module
+
+__version__ = ''
+AES = PKCS1_v1_5 = Blowfish = PKCS1_OAEP = SHA1 = CMAC = RSA = None
+try:
+ if _parent.__name__ == 'Cryptodome':
+ from Cryptodome import __version__
+ from Cryptodome.Cipher import AES, PKCS1_OAEP, Blowfish, PKCS1_v1_5
+ from Cryptodome.Hash import CMAC, SHA1
+ from Cryptodome.PublicKey import RSA
+ elif _parent.__name__ == 'Crypto':
+ from Crypto import __version__
+ from Crypto.Cipher import AES, PKCS1_OAEP, Blowfish, PKCS1_v1_5 # noqa: F401
+ from Crypto.Hash import CMAC, SHA1 # noqa: F401
+ from Crypto.PublicKey import RSA # noqa: F401
+except ImportError:
+ __version__ = f'broken {__version__}'.strip()
+
+
+_yt_dlp__identifier = _parent.__name__
+if AES and _yt_dlp__identifier == 'Crypto':
+ try:
+ # In pycrypto, mode defaults to ECB. See:
+ # https://www.pycryptodome.org/en/latest/src/vs_pycrypto.html#:~:text=not%20have%20ECB%20as%20default%20mode
+ AES.new(b'abcdefghijklmnop')
+ except TypeError:
+ _yt_dlp__identifier = 'pycrypto'
diff --git a/yt_dlp/dependencies/__init__.py b/yt_dlp/dependencies/__init__.py
new file mode 100644
index 0000000..9e3f907
--- /dev/null
+++ b/yt_dlp/dependencies/__init__.py
@@ -0,0 +1,92 @@
+# flake8: noqa: F401
+"""Imports all optional dependencies for the project.
+An attribute "_yt_dlp__identifier" may be inserted into the module if it uses an ambiguous namespace"""
+
+try:
+ import brotlicffi as brotli
+except ImportError:
+ try:
+ import brotli
+ except ImportError:
+ brotli = None
+
+
+try:
+ import certifi
+except ImportError:
+ certifi = None
+else:
+ from os.path import exists as _path_exists
+
+ # The certificate may not be bundled in executable
+ if not _path_exists(certifi.where()):
+ certifi = None
+
+
+try:
+ import mutagen
+except ImportError:
+ mutagen = None
+
+
+secretstorage = None
+try:
+ import secretstorage
+ _SECRETSTORAGE_UNAVAILABLE_REASON = None
+except ImportError:
+ _SECRETSTORAGE_UNAVAILABLE_REASON = (
+ 'as the `secretstorage` module is not installed. '
+ 'Please install by running `python3 -m pip install secretstorage`')
+except Exception as _err:
+ _SECRETSTORAGE_UNAVAILABLE_REASON = f'as the `secretstorage` module could not be initialized. {_err}'
+
+
+try:
+ import sqlite3
+ # We need to get the underlying `sqlite` version, see https://github.com/yt-dlp/yt-dlp/issues/8152
+ sqlite3._yt_dlp__version = sqlite3.sqlite_version
+except ImportError:
+ # although sqlite3 is part of the standard library, it is possible to compile Python without
+ # sqlite support. See: https://github.com/yt-dlp/yt-dlp/issues/544
+ sqlite3 = None
+
+
+try:
+ import websockets
+except ImportError:
+ websockets = None
+
+try:
+ import urllib3
+except ImportError:
+ urllib3 = None
+
+try:
+ import requests
+except ImportError:
+ requests = None
+
+try:
+ import xattr # xattr or pyxattr
+except ImportError:
+ xattr = None
+else:
+ if hasattr(xattr, 'set'): # pyxattr
+ xattr._yt_dlp__identifier = 'pyxattr'
+
+
+from . import Cryptodome
+
+all_dependencies = {k: v for k, v in globals().items() if not k.startswith('_')}
+available_dependencies = {k: v for k, v in all_dependencies.items() if v}
+
+
+# Deprecated
+Cryptodome_AES = Cryptodome.AES
+
+
+__all__ = [
+ 'all_dependencies',
+ 'available_dependencies',
+ *all_dependencies.keys(),
+]