| 28 | |
| 29 | |
| 30 | def load_plugins(plugin_dir=PLUGIN_DIR): |
| 31 | plugins = [] |
| 32 | if not plugin_dir.exists(): |
| 33 | return plugins |
| 34 | for p in plugin_dir.iterdir(): |
| 35 | if p.name.startswith('_') or not p.suffix == '.py': |
| 36 | continue |
| 37 | name = p.stem |
| 38 | spec = importlib.util.spec_from_file_location(f"encrypt_plugins.{name}", str(p)) |
| 39 | if spec is None: |
| 40 | continue |
| 41 | module = importlib.util.module_from_spec(spec) |
| 42 | try: |
| 43 | spec.loader.exec_module(module) |
| 44 | except Exception as e: |
| 45 | print(f"Failed loading plugin {name}: {e}") |
| 46 | continue |
| 47 | # module must expose `name` and `process(data, args)` or a `Plugin` class |
| 48 | if hasattr(module, 'Plugin'): |
| 49 | try: |
| 50 | inst = module.Plugin() |
| 51 | plugins.append(inst) |
| 52 | except Exception as e: |
| 53 | print(f"Failed instantiating Plugin in {name}: {e}") |
| 54 | elif hasattr(module, 'name') and hasattr(module, 'process'): |
| 55 | plugins.append(module) |
| 56 | return plugins |
| 57 | |
| 58 | |
| 59 | def build_base_parser(plugin_names): |