diff --git a/apprise/manager.py b/apprise/manager.py index d649afab..c2b715d4 100644 --- a/apprise/manager.py +++ b/apprise/manager.py @@ -365,67 +365,66 @@ class PluginManager(metaclass=Singleton): # end of _import_module() return - with self._lock: - for _path in paths: - path = os.path.abspath(os.path.expanduser(_path)) - if (cache and path in self._paths_previously_scanned) \ - or not os.path.exists(path): - # We're done as we've already scanned this - continue + for _path in paths: + path = os.path.abspath(os.path.expanduser(_path)) + if (cache and path in self._paths_previously_scanned) \ + or not os.path.exists(path): + # We're done as we've already scanned this + continue - # Store our path as a way of hashing it has been handled - self._paths_previously_scanned.add(path) + # Store our path as a way of hashing it has been handled + self._paths_previously_scanned.add(path) - if os.path.isdir(path) and not \ - os.path.isfile(os.path.join(path, '__init__.py')): + if os.path.isdir(path) and not \ + os.path.isfile(os.path.join(path, '__init__.py')): - logger.debug('Scanning for custom plugins in: %s', path) - for entry in os.listdir(path): - re_match = module_re.match(entry) - if not re_match: - # keep going - logger.trace('Plugin Scan: Ignoring %s', entry) - continue + logger.debug('Scanning for custom plugins in: %s', path) + for entry in os.listdir(path): + re_match = module_re.match(entry) + if not re_match: + # keep going + logger.trace('Plugin Scan: Ignoring %s', entry) + continue - new_path = os.path.join(path, entry) - if os.path.isdir(new_path): - # Update our path - new_path = os.path.join(path, entry, '__init__.py') - if not os.path.isfile(new_path): - logger.trace( - 'Plugin Scan: Ignoring %s', - os.path.join(path, entry)) - continue - - if not cache or \ - (cache and new_path not in - self._paths_previously_scanned): - # Load our module - _import_module(new_path) - - # Add our subdir path - self._paths_previously_scanned.add(new_path) - else: - if os.path.isdir(path): - # This logic is safe to apply because we already - # validated the directories state above; update our - # path - path = os.path.join(path, '__init__.py') - if cache and path in self._paths_previously_scanned: + new_path = os.path.join(path, entry) + if os.path.isdir(new_path): + # Update our path + new_path = os.path.join(path, entry, '__init__.py') + if not os.path.isfile(new_path): + logger.trace( + 'Plugin Scan: Ignoring %s', + os.path.join(path, entry)) continue - self._paths_previously_scanned.add(path) + if not cache or \ + (cache and new_path not in + self._paths_previously_scanned): + # Load our module + _import_module(new_path) - # directly load as is - re_match = module_re.match(os.path.basename(path)) - # must be a match and must have a .py extension - if not re_match or not re_match.group(1): - # keep going - logger.trace('Plugin Scan: Ignoring %s', path) + # Add our subdir path + self._paths_previously_scanned.add(new_path) + else: + if os.path.isdir(path): + # This logic is safe to apply because we already + # validated the directories state above; update our + # path + path = os.path.join(path, '__init__.py') + if cache and path in self._paths_previously_scanned: continue - # Load our module - _import_module(path) + self._paths_previously_scanned.add(path) + + # directly load as is + re_match = module_re.match(os.path.basename(path)) + # must be a match and must have a .py extension + if not re_match or not re_match.group(1): + # keep going + logger.trace('Plugin Scan: Ignoring %s', path) + continue + + # Load our module + _import_module(path) return None diff --git a/test/test_apprise_cli.py b/test/test_apprise_cli.py index f1981a38..bcc44b6d 100644 --- a/test/test_apprise_cli.py +++ b/test/test_apprise_cli.py @@ -615,6 +615,68 @@ def test_apprise_cli_nux_env(tmpdir): assert result.exit_code == 0 +def test_apprise_cli_modules(tmpdir): + """ + CLI: --plugin (-P) + + """ + + runner = CliRunner() + + # + # Loading of modules works correctly + # + notify_cmod_base = tmpdir.mkdir('cli_modules') + notify_cmod = notify_cmod_base.join('hook.py') + notify_cmod.write(cleandoc(""" + from apprise.decorators import notify + + @notify(on="climod") + def mywrapper(body, title, notify_type, *args, **kwargs): + pass + """)) + + result = runner.invoke(cli.main, [ + '--plugin-path', str(notify_cmod), + '-t', 'title', + '-b', 'body', + 'climod://', + ]) + + assert result.exit_code == 0 + + # Test -P + result = runner.invoke(cli.main, [ + '-P', str(notify_cmod), + '-t', 'title', + '-b', 'body', + 'climod://', + ]) + + assert result.exit_code == 0 + + # Test double hooks + notify_cmod2 = notify_cmod_base.join('hook2.py') + notify_cmod2.write(cleandoc(""" + from apprise.decorators import notify + + @notify(on="climod2") + def mywrapper(body, title, notify_type, *args, **kwargs): + pass + """)) + + result = runner.invoke(cli.main, [ + '--plugin-path', str(notify_cmod), + '--plugin-path', str(notify_cmod2), + '-t', 'title', + '-b', 'body', + 'climod://', + 'climod2://', + ]) + + assert result.exit_code == 0 + + def test_apprise_cli_details(tmpdir): """ CLI: --details (-l)