Source code for ipypublish.scripts.export_plugins

import glob
import imp
import inspect
import logging
import os
import uuid
import warnings

# py 2/3 compatibility
try:
    import pathlib
except ImportError:
    import pathlib2 as pathlib
try:
    from importlib.machinery import SourceFileLoader
    from types import ModuleType


[docs] def load_source(modname, fname): loader = SourceFileLoader(modname, fname) mod = ModuleType(loader.name) loader.exec_module(mod) return mod
except ImportError as err: load_source = lambda modname, fname: imp.load_source(modname, fname) from ipypublish import export_plugins def _get_module_path(module): """return a directory path to a module""" return pathlib.Path(os.path.dirname(os.path.abspath(inspect.getfile(module)))) def _get_modules(path): """ get modules from a directory Properties ---------- path : str or path-like Returns ------- modules : list of modules load_errors: list of str Examples -------- >>> from jsonextended.utils import MockPath >>> mod1 = MockPath('mod1.py', is_file=True, ... content="name='modname1'") >>> dir = MockPath(structure=[mod1]) >>> modules, errors = _get_modules(dir) >>> errors [] >>> list(modules.keys()) ['mod1'] >>> modules['mod1'].name 'modname1' """ # get potential plugin python files if hasattr(path, 'glob'): pypaths = path.glob('*.py') else: pypaths = glob.glob(os.path.join(path, '*.py')) modules = {} load_errors = [] for pypath in pypaths: # use uuid to ensure no conflicts in name space mod_name = str(uuid.uuid4()) try: if hasattr(pypath, 'resolve'): # Make the path absolute, resolving any symlinks pypath = pypath.resolve() with warnings.catch_warnings(record=True) as w: warnings.filterwarnings("ignore", category=ImportWarning) # for MockPaths if hasattr(pypath, 'maketemp'): with pypath.maketemp() as fpath: module = load_source(mod_name, str(fpath)) pypath = pypath.name else: module = load_source(mod_name, str(pypath)) modules[os.path.splitext(os.path.basename(str(pypath)))[0]] = module except Exception as err: load_errors.append((str(pypath), 'Load Error: {}'.format(err))) continue return modules, load_errors _plugins_dict = {}
[docs]def add_directory(path): """ add a directory of export plugin modules to the existing dict plugins must have: oformat, template and config attributes and a doc string Properties ---------- path : str or path-like """ modules, load_errors = _get_modules(path) for mod_name, mod in modules.items(): try: descript = getattr(mod, '__doc__') oformat = getattr(mod, 'oformat') template = getattr(mod, 'template') config = getattr(mod, 'config') except AttributeError: continue _plugins_dict[mod_name] = {'descript': descript, 'oformat': oformat, 'template': template, 'config': config} return load_errors
logging.debug('loading builtin plugins') load_errors = add_directory(_get_module_path(export_plugins)) if load_errors: raise IOError( 'errors in builtin plugins loading: {}'.format('\n'.join(['{0}: {1}'.format(a, b) for a, b in load_errors])))
[docs]def get(): """ return export plugins """ return _plugins_dict.copy()