comparison sat/core/sat_main.py @ 3370:2157880ba3b4

core: plugins can now be loaded from a directory: A plugin can now be a directory with a name starting by `plugin_`. It will then be loaded as a module. The `__init__.py` file must contain the `PLUGIN_INFO` dict with metadata.
author Goffi <goffi@goffi.org>
date Sun, 20 Sep 2020 14:05:40 +0200
parents 9bc3fca290ab
children cc288ec8ec1a
comparison
equal deleted inserted replaced
3369:96b2f84a685c 3370:2157880ba3b4
14 # GNU Affero General Public License for more details. 14 # GNU Affero General Public License for more details.
15 15
16 # You should have received a copy of the GNU Affero General Public License 16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18
19 from glob import glob
20 import sys 19 import sys
21 import os.path 20 import os.path
22 import uuid 21 import uuid
23 import hashlib 22 import hashlib
24 import copy 23 import copy
271 # TODO: make this more generic and reusable in tools.common 270 # TODO: make this more generic and reusable in tools.common
272 # FIXME: should use imp 271 # FIXME: should use imp
273 # TODO: do not import all plugins if no needed: component plugins are not needed 272 # TODO: do not import all plugins if no needed: component plugins are not needed
274 # if we just use a client, and plugin blacklisting should be possible in 273 # if we just use a client, and plugin blacklisting should be possible in
275 # sat.conf 274 # sat.conf
276 plugins_path = os.path.dirname(sat.plugins.__file__) 275 plugins_path = Path(sat.plugins.__file__).parent
277 plugin_glob = "plugin*." + C.PLUGIN_EXT
278 plug_lst = [
279 os.path.splitext(plugin)[0]
280 for plugin in map(
281 os.path.basename, glob(os.path.join(plugins_path, plugin_glob))
282 )
283 ]
284 plugins_to_import = {} # plugins we still have to import 276 plugins_to_import = {} # plugins we still have to import
285 for plug in plug_lst: 277 for plug_path in plugins_path.glob("plugin_*"):
286 plugin_path = "sat.plugins." + plug 278 if plug_path.is_dir():
279 init_path = plug_path / f"__init__.{C.PLUGIN_EXT}"
280 if not init_path.exists():
281 log.warning(
282 f"{plug_path} doesn't appear to be a package, can't load it")
283 continue
284 plug_name = plug_path.name
285 elif plug_path.is_file():
286 if plug_path.suffix != f".{C.PLUGIN_EXT}":
287 continue
288 plug_name = plug_path.stem
289 else:
290 log.warning(
291 f"{plug_path} is not a file or a dir, ignoring it")
292 continue
293 if not plug_name.isidentifier():
294 log.warning(
295 f"{plug_name!r} is not a valid name for a plugin, ignoring it")
296 continue
297 plugin_path = f"sat.plugins.{plug_name}"
287 try: 298 try:
288 __import__(plugin_path) 299 __import__(plugin_path)
289 except exceptions.MissingModule as e: 300 except exceptions.MissingModule as e:
290 self._unimport_plugin(plugin_path) 301 self._unimport_plugin(plugin_path)
291 log.warning( 302 log.warning(