mirror of https://github.com/yt-dlp/yt-dlp.git
Add option `--plugin-dirs` (#11277)
Closes #3260 Authored by: imranh2, coletdjnz Co-authored-by: coletdjnz <coletdjnz@protonmail.com>
This commit is contained in:
parent
8de431ec97
commit
0f593dca9f
|
@ -348,6 +348,13 @@ If you fork the project on GitHub, you can run your fork's [build workflow](.git
|
|||
containing directory ("-" for stdin). Can be
|
||||
used multiple times and inside other
|
||||
configuration files
|
||||
--plugin-dirs PATH Path to an additional directory to search
|
||||
for plugins. This option can be used
|
||||
multiple times to add multiple directories.
|
||||
Note that this currently only works for
|
||||
extractor plugins; postprocessor plugins can
|
||||
only be loaded from the default plugin
|
||||
directories
|
||||
--flat-playlist Do not extract the videos of a playlist,
|
||||
only list them
|
||||
--no-flat-playlist Fully extract the videos of a playlist
|
||||
|
|
|
@ -10,6 +10,7 @@ TEST_DATA_DIR = Path(os.path.dirname(os.path.abspath(__file__)), 'testdata')
|
|||
sys.path.append(str(TEST_DATA_DIR))
|
||||
importlib.invalidate_caches()
|
||||
|
||||
from yt_dlp.utils import Config
|
||||
from yt_dlp.plugins import PACKAGE_NAME, directories, load_plugins
|
||||
|
||||
|
||||
|
@ -68,6 +69,24 @@ class TestPlugins(unittest.TestCase):
|
|||
os.remove(zip_path)
|
||||
importlib.invalidate_caches() # reset the import caches
|
||||
|
||||
def test_plugin_dirs(self):
|
||||
# Internal plugin dirs hack for CLI --plugin-dirs
|
||||
# To be replaced with proper system later
|
||||
custom_plugin_dir = TEST_DATA_DIR / 'plugin_packages'
|
||||
Config._plugin_dirs = [str(custom_plugin_dir)]
|
||||
importlib.invalidate_caches() # reset the import caches
|
||||
|
||||
try:
|
||||
package = importlib.import_module(f'{PACKAGE_NAME}.extractor')
|
||||
self.assertIn(custom_plugin_dir / 'testpackage' / PACKAGE_NAME / 'extractor', map(Path, package.__path__))
|
||||
|
||||
plugins_ie = load_plugins('extractor', 'IE')
|
||||
self.assertIn('PackagePluginIE', plugins_ie.keys())
|
||||
|
||||
finally:
|
||||
Config._plugin_dirs = []
|
||||
importlib.invalidate_caches() # reset the import caches
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
5
test/testdata/plugin_packages/testpackage/yt_dlp_plugins/extractor/package.py
vendored
Normal file
5
test/testdata/plugin_packages/testpackage/yt_dlp_plugins/extractor/package.py
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
from yt_dlp.extractor.common import InfoExtractor
|
||||
|
||||
|
||||
class PackagePluginIE(InfoExtractor):
|
||||
pass
|
|
@ -34,6 +34,7 @@ from .postprocessor import (
|
|||
)
|
||||
from .update import Updater
|
||||
from .utils import (
|
||||
Config,
|
||||
NO_DEFAULT,
|
||||
POSTPROCESS_WHEN,
|
||||
DateRange,
|
||||
|
@ -967,6 +968,10 @@ def _real_main(argv=None):
|
|||
|
||||
parser, opts, all_urls, ydl_opts = parse_options(argv)
|
||||
|
||||
# HACK: Set the plugin dirs early on
|
||||
# TODO(coletdjnz): remove when plugin globals system is implemented
|
||||
Config._plugin_dirs = opts.plugin_dirs
|
||||
|
||||
# Dump user agent
|
||||
if opts.dump_user_agent:
|
||||
ua = traverse_obj(opts.headers, 'User-Agent', casesense=False, default=std_headers['User-Agent'])
|
||||
|
|
|
@ -408,6 +408,14 @@ def create_parser():
|
|||
help=(
|
||||
'Location of the main configuration file; either the path to the config or its containing directory '
|
||||
'("-" for stdin). Can be used multiple times and inside other configuration files'))
|
||||
general.add_option(
|
||||
'--plugin-dirs',
|
||||
dest='plugin_dirs', metavar='PATH', action='append',
|
||||
help=(
|
||||
'Path to an additional directory to search for plugins. '
|
||||
'This option can be used multiple times to add multiple directories. '
|
||||
'Note that this currently only works for extractor plugins; '
|
||||
'postprocessor plugins can only be loaded from the default plugin directories'))
|
||||
general.add_option(
|
||||
'--flat-playlist',
|
||||
action='store_const', dest='extract_flat', const='in_playlist', default=False,
|
||||
|
|
|
@ -15,6 +15,7 @@ from zipfile import ZipFile
|
|||
|
||||
from .compat import functools # isort: split
|
||||
from .utils import (
|
||||
Config,
|
||||
get_executable_path,
|
||||
get_system_config_dirs,
|
||||
get_user_config_dirs,
|
||||
|
@ -84,6 +85,12 @@ class PluginFinder(importlib.abc.MetaPathFinder):
|
|||
with contextlib.suppress(ValueError): # Added when running __main__.py directly
|
||||
candidate_locations.remove(Path(__file__).parent)
|
||||
|
||||
# TODO(coletdjnz): remove when plugin globals system is implemented
|
||||
if Config._plugin_dirs:
|
||||
candidate_locations.extend(_get_package_paths(
|
||||
*Config._plugin_dirs,
|
||||
containing_folder=''))
|
||||
|
||||
parts = Path(*fullname.split('.'))
|
||||
for path in orderedSet(candidate_locations, lazy=True):
|
||||
candidate = path / parts
|
||||
|
|
|
@ -4897,6 +4897,10 @@ class Config:
|
|||
filename = None
|
||||
__initialized = False
|
||||
|
||||
# Internal only, do not use! Hack to enable --plugin-dirs
|
||||
# TODO(coletdjnz): remove when plugin globals system is implemented
|
||||
_plugin_dirs = None
|
||||
|
||||
def __init__(self, parser, label=None):
|
||||
self.parser, self.label = parser, label
|
||||
self._loaded_paths, self.configs = set(), []
|
||||
|
|
Loading…
Reference in New Issue