diff --git a/pyinst.py b/pyinst.py index 17c950563..22df672c9 100644 --- a/pyinst.py +++ b/pyinst.py @@ -37,7 +37,7 @@ def main(): '--icon=devscripts/logo.ico', '--upx-exclude=vcruntime140.dll', '--noconfirm', - *dependency_options(), + '--additional-hooks-dir=yt_dlp/__pyinstaller', *opts, 'yt_dlp/__main__.py', ] @@ -77,30 +77,6 @@ def version_to_list(version): return list(map(int, version_list)) + [0] * (4 - len(version_list)) -def dependency_options(): - # Due to the current implementation, these are auto-detected, but explicitly add them just in case - dependencies = [pycryptodome_module(), 'mutagen', 'brotli', 'certifi', 'websockets'] - excluded_modules = ('youtube_dl', 'youtube_dlc', 'test', 'ytdlp_plugins', 'devscripts') - - yield from (f'--hidden-import={module}' for module in dependencies) - yield '--collect-submodules=websockets' - yield from (f'--exclude-module={module}' for module in excluded_modules) - - -def pycryptodome_module(): - try: - import Cryptodome # noqa: F401 - except ImportError: - try: - import Crypto # noqa: F401 - print('WARNING: Using Crypto since Cryptodome is not available. ' - 'Install with: pip install pycryptodomex', file=sys.stderr) - return 'Crypto' - except ImportError: - pass - return 'Cryptodome' - - def set_version_info(exe, version): if OS_NAME == 'win32': windows_set_version(exe, version) diff --git a/setup.py b/setup.py index e2520ff6f..ccfcf4252 100644 --- a/setup.py +++ b/setup.py @@ -92,7 +92,10 @@ def build_params(): params = {'data_files': data_files} if setuptools_available: - params['entry_points'] = {'console_scripts': ['yt-dlp = yt_dlp:main']} + params['entry_points'] = { + 'console_scripts': ['yt-dlp = yt_dlp:main'], + 'pyinstaller40': ['hook-dirs = yt_dlp.__pyinstaller:get_hook_dirs'], + } else: params['scripts'] = ['yt-dlp'] return params diff --git a/yt_dlp/__pyinstaller/__init__.py b/yt_dlp/__pyinstaller/__init__.py new file mode 100644 index 000000000..1c52aadf4 --- /dev/null +++ b/yt_dlp/__pyinstaller/__init__.py @@ -0,0 +1,5 @@ +import os + + +def get_hook_dirs(): + return [os.path.dirname(__file__)] diff --git a/yt_dlp/__pyinstaller/hook-yt_dlp.py b/yt_dlp/__pyinstaller/hook-yt_dlp.py new file mode 100644 index 000000000..66d1b6369 --- /dev/null +++ b/yt_dlp/__pyinstaller/hook-yt_dlp.py @@ -0,0 +1,29 @@ +import sys + +from PyInstaller.utils.hooks import collect_submodules + + +def _pycryptodome_module(): + try: + import Cryptodome # noqa: F401 + except ImportError: + try: + import Crypto # noqa: F401 + print('WARNING: Using Crypto since Cryptodome is not available. ' + 'Install with: pip install pycryptodomex', file=sys.stderr) + return 'Crypto' + except ImportError: + pass + return 'Cryptodome' + + +def _hidden_imports(): + yield 'yt_dlp.compat._legacy' + for m in [_pycryptodome_module(), 'websockets']: + yield from collect_submodules(m) + # These are auto-detected, but explicitly add them just in case + yield from ('mutagen', 'brotli', 'certifi') + + +hiddenimports = list(_hidden_imports()) +excludedimports = ['youtube_dl', 'youtube_dlc', 'test', 'ytdlp_plugins', 'devscripts'] diff --git a/yt_dlp/compat/__init__.py b/yt_dlp/compat/__init__.py index 5cc78ebc2..c6c02541c 100644 --- a/yt_dlp/compat/__init__.py +++ b/yt_dlp/compat/__init__.py @@ -70,9 +70,3 @@ if compat_os_name in ('nt', 'ce'): return userhome + path[i:] else: compat_expanduser = os.path.expanduser - - -# NB: Add modules that are imported dynamically here so that PyInstaller can find them -# See https://github.com/pyinstaller/pyinstaller-hooks-contrib/issues/438 -if False: - from . import _legacy # noqa: F401