def _import_plugin(self, plugin_info): module = __import__(plugin_info['_id'], globals(), locals()) plugin = None module_views = list() for name, obj in self.get_classes(module, prism.api.plugin.BasePlugin): plugin = obj() plugin._module = module plugin._info = plugin_info plugin._endpoint = plugin.plugin_id self.plugins[plugin.plugin_id] = plugin # Break. Just in case they imported another plugin's base class break for name, obj in self.get_classes(module, api.view.BaseView): module_views.append(obj) if plugin is None: logging.error( 'Error: Invalid plugin in plugins folder. Offender: %s' % plugin_id) return False plugin._module_views = module_views return plugin
def _verify_dependencies(self): # These will always be initialized. logging.up('Verifying dependencies') installed_packages_list = sorted( [i.key for i in pip.get_installed_distributions()]) for plugin_id, plugin_info in self.available_plugins.items(): if not plugin_info['_is_core']: if 'dependencies' not in plugin_info: continue if 'os' in plugin_info['dependencies']: if get_general_os() in plugin_info['dependencies']['os']: plugin_info['dependencies'] = data_merge( plugin_info['dependencies'], plugin_info['dependencies']['os'][ get_general_os()]) if 'plugin' in plugin_info['dependencies']: for depend_name in plugin_info['dependencies']['plugin']: installed = 'prism_' + depend_name in self.available_plugins if not installed: plugin_info['_is_satisfied'] = False plugin_info['_dependencies'].append( ('plugin', depend_name, installed)) if 'binary' in plugin_info['dependencies']: for depend_name in plugin_info['dependencies']['binary']: installed = is_package_installed(depend_name) if not installed: plugin_info['_is_satisfied'] = False plugin_info['_dependencies'].append( ('binary', depend_name, installed)) if 'module' in plugin_info['dependencies']: for depend_name in plugin_info['dependencies']['module']: installed = (depend_name in installed_packages_list) if not installed: plugin_info['_is_satisfied'] = False plugin_info['_dependencies'].append( ('module', depend_name, installed)) if not plugin_info['_is_satisfied']: # Create a dummy plugin container self._insert_dummy_plugin(plugin_info) logging.error('Dependency unsatisfied. Offender: %s' % plugin_id) logging.down()
def _search_plugins(self, path, is_core): """ Searches for plugins in a specified folder """ if is_core: logging.info('Finding core plugins') else: logging.info('Finding additional plugins') sys.path.append(path) for plugin_id in os.listdir(path): if not plugin_id.startswith('prism_'): continue base_folder = os.path.join(path, plugin_id) if not os.path.isfile(base_folder): if not os.path.exists(os.path.join(base_folder, 'plugin.json')): logging.error( 'Plugin does not have a plugin.json file. Offender: %s' % plugin_id) continue plugin_info = JSONConfig(base_folder, 'plugin.json', auto_save=False) plugin_info['_id'] = plugin_id plugin_info['id'] = plugin_info['_id'].split('_', 1)[1] plugin_info['_is_core'] = is_core plugin_info['_is_satisfied'] = True plugin_info['_is_enabled'] = False # Make the version readable version = None for i in plugin_info['version']: if isinstance(i, int): if version is None: version = str(i) else: version += '.' + str(i) else: version += '-' + i plugin_info['_version'] = plugin_info['version'] plugin_info['version'] = version plugin_info['_dependencies'] = list() self.available_plugins[plugin_id] = plugin_info
def start_http(self): logging.output('Verifying SSL') has_ssl = False try: from OpenSSL import SSL has_ssl = True except ImportError: pass if has_ssl: ssl_crt = os.path.join(prism.settings.CONFIG_FOLDER, 'prism-ssl.crt') ssl_key = os.path.join(prism.settings.CONFIG_FOLDER, 'prism-ssl.key') ssl_files_exist = os.path.exists(ssl_crt) if ssl_files_exist: ssl_files_exist = os.path.exists(ssl_key) # Generate certificate if not ssl_files_exist: logging.up() logging.up('Generating SSL certificate') prism.settings.generate_certificate() logging.down() logging.down() if self.should_bind: # Finally, start Prism under a self-signed SSL connection self.flask_app.run(host='::', port=9000, threaded=True, debug=prism.settings.is_dev(), ssl_context=(ssl_crt, ssl_key)) else: if self.should_bind: logging.error( 'Warning: Prism is starting under an insecure connection!') self.flask_app.run(host='::', port=9000, threaded=True, debug=prism.settings.is_dev())
def ping_version(output=False): global PRISM_VERSIONING should_check = True if 'last_check' in PRISM_VERSIONING: should_check = ((datetime.now() - datetime.strptime(PRISM_VERSIONING['last_check'], "%Y-%m-%d %H:%M:%S")).seconds >= 60 * 60 * 2) if output or should_check: logging.up('Collecting version info...') if should_check: rate_limited, dev_changes, recent_releases, num_releases = get_new_versions(prism.__version__) if rate_limited: logging.error('Rate limited. Version info not checked.') # If no values made yet, apply some defaults if 'dev_changes' not in PRISM_VERSIONING: PRISM_VERSIONING['dev_changes'] = [] if 'recent_releases' not in PRISM_VERSIONING: PRISM_VERSIONING['recent_releases'] = [] if 'num_releases' not in PRISM_VERSIONING: PRISM_VERSIONING['num_releases'] = 0 else: # Reset and reapply cached versioning info PRISM_VERSIONING['dev_changes'] = [] PRISM_VERSIONING['recent_releases'] = [] PRISM_VERSIONING['num_releases'] = 0 if 'dev_changes' is not None: PRISM_VERSIONING['dev_changes'] = dev_changes if 'recent_releases' is not None: PRISM_VERSIONING['recent_releases'] = recent_releases if 'num_releases' is not None: PRISM_VERSIONING['num_releases'] = num_releases if 'dev_changes' is not None or 'recent_releases' is not None or 'num_releases' is not None: PRISM_VERSIONING['last_check'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") if output or should_check: if PRISM_VERSIONING['dev_changes'] is None: logging.error('Failed to check development version.') elif len(PRISM_VERSIONING['dev_changes']) > 0: logging.info('%s development commit(s) since the latest version.' % len(PRISM_VERSIONING['dev_changes'])) if PRISM_VERSIONING['recent_releases'] is None: logging.error('Failed to check for latest version.') elif len(PRISM_VERSIONING['recent_releases']) != 0: logging.info('Current version: %s' % prism.__version__) if prism.__version__ != PRISM_VERSIONING['recent_releases'][0]['name']: logging.error('Your version is out of date. Latest version is %s' % PRISM_VERSIONING['recent_releases'][0]['name']) logging.down() logging.down()
def _load_plugins(self): """ Attempts to load every enabled plugin """ plugins_loaded = list() core_plugins = list() plugins_additional = list() for plugin_id, plugin_info in self.available_plugins.items(): if plugin_info['_is_core']: core_plugins.append(plugin_info) elif plugin_info['_is_satisfied']: plugins_additional.append(plugin_info) # These will always be initialized. logging.info('Loading %s core plugin(s)' % len(core_plugins)) for plugin_info in core_plugins: plugin = self._import_plugin(plugin_info) if not plugin: logging.error( 'Error: Failed to load core plugin. Offender: %s' % plugin_info['id']) continue else: logging.good('Loaded %s' % plugin_info['id']) plugins_loaded.append(plugin) logging.down() logging.info('Sorting dependencies') sorted_plugins = [] while plugins_additional: added_any = False for plugin in plugins_additional: ready_add = True if 'dependencies' in plugin and 'plugin' in plugin[ 'dependencies']: for dependency in plugin['dependencies']['plugin']: found = False for ready_plugin in sorted_plugins: if ready_plugin['id'] == dependency: found = True break if not found: ready_add = False if ready_add: added_any = True sorted_plugins.append(plugin) plugins_additional.remove(plugin) if not added_any: break plugins_additional = sorted_plugins logging.up('Loading %s additional plugin(s)' % len(plugins_additional)) # Start plugins if they're set to be enabled. for plugin_info in plugins_additional: if not self.is_enabled(plugin_info['id']): self._insert_dummy_plugin(plugin_info) continue plugin = self._import_plugin(plugin_info) if not plugin: logging.error( 'Error: Failed to load additional plugin. Offender: %s' % plugin_id) continue else: logging.good('Loaded %s' % plugin_info['id']) plugins_loaded.append(plugin) logging.down() logging.up('Initializing %s plugin(s)' % len(plugins_loaded)) for plugin in plugins_loaded: plugin._info['_is_enabled'] = True self._init_plugin(plugin) logging.down()