[plugins] Fix zip search paths

Closes #6011
This commit is contained in:
pukkandan 2023-01-20 23:34:16 +05:30
parent 176a068cde
commit 88d8928bf7
No known key found for this signature in database
GPG Key ID: 7EEE9E1E817D0A39

View File

@ -34,9 +34,15 @@ def exec_module(self, module):
@functools.cache @functools.cache
def dirs_in_zip(archive): def dirs_in_zip(archive):
with ZipFile(archive) as zip: try:
return set(itertools.chain.from_iterable( with ZipFile(archive) as zip_:
Path(file).parents for file in zip.namelist())) return set(itertools.chain.from_iterable(
Path(file).parents for file in zip_.namelist()))
except FileNotFoundError:
pass
except Exception as e:
write_string(f'WARNING: Could not read zip file {archive}: {e}\n')
return set()
class PluginFinder(importlib.abc.MetaPathFinder): class PluginFinder(importlib.abc.MetaPathFinder):
@ -57,10 +63,8 @@ def search_locations(self, fullname):
def _get_package_paths(*root_paths, containing_folder='plugins'): def _get_package_paths(*root_paths, containing_folder='plugins'):
for config_dir in orderedSet(map(Path, root_paths), lazy=True): for config_dir in orderedSet(map(Path, root_paths), lazy=True):
plugin_dir = config_dir / containing_folder with contextlib.suppress(OSError):
if not plugin_dir.is_dir(): yield from (config_dir / containing_folder).iterdir()
continue
yield from plugin_dir.iterdir()
# Load from yt-dlp config folders # Load from yt-dlp config folders
candidate_locations.extend(_get_package_paths( candidate_locations.extend(_get_package_paths(
@ -76,24 +80,23 @@ def _get_package_paths(*root_paths, containing_folder='plugins'):
containing_folder='yt-dlp-plugins')) containing_folder='yt-dlp-plugins'))
candidate_locations.extend(map(Path, sys.path)) # PYTHONPATH candidate_locations.extend(map(Path, sys.path)) # PYTHONPATH
with contextlib.suppress(ValueError): # Added when running __main__.py directly
candidate_locations.remove(Path(__file__).parent)
parts = Path(*fullname.split('.')) parts = Path(*fullname.split('.'))
locations = set() for path in orderedSet(candidate_locations, lazy=True):
for path in dict.fromkeys(candidate_locations):
candidate = path / parts candidate = path / parts
if candidate.is_dir(): if candidate.is_dir():
locations.add(str(candidate)) yield candidate
elif path.name and any(path.with_suffix(suffix).is_file() for suffix in {'.zip', '.egg', '.whl'}): elif path.suffix in ('.zip', '.egg', '.whl'):
with contextlib.suppress(FileNotFoundError): if parts in dirs_in_zip(path):
if parts in dirs_in_zip(path): yield candidate
locations.add(str(candidate))
return locations
def find_spec(self, fullname, path=None, target=None): def find_spec(self, fullname, path=None, target=None):
if fullname not in self.packages: if fullname not in self.packages:
return None return None
search_locations = self.search_locations(fullname) search_locations = list(map(str, self.search_locations(fullname)))
if not search_locations: if not search_locations:
return None return None