Exemple #1
0
    def emit(self, record):
        if self._plugin is None and Plugins.get_instance() is not None:
            self._plugin = Plugins.get_instance().return_plugin(
                self._xmpp_plugin)

        if self._plugin is not None and self._plugin.is_connected():
            self._plugin.send(self._xmpp_receiver, self.format(record),
                              self._xmpp_receiver_type)
Exemple #2
0
    def emit(self, record):
        if self._plugin is None and Plugins.get_instance() is not None:
            self._plugin = Plugins.get_instance().return_plugin(self._xmpp_plugin)
            if self._plugin is None:
                if self._xmpp_plugin not in self._errors:
                    self._errors.append(self._xmpp_plugin)
                    logging.getLogger(__name__).error('Can not get XMPP plugin \'{}\' used to log messages via XMPP - trying later!'.format(self._xmpp_plugin))
            else:
                logging.getLogger(__name__).info('Configured XMPP logging using pluing {}'.format(self._xmpp_plugin))

        if self._plugin is not None:
            self._plugin.send(self._xmpp_receiver, self.format(record), self._xmpp_receiver_type)
Exemple #3
0
    def __init__(self, module, shng_url_root):
        self._sh = module._sh
        self.module = module
        self.shng_url_root = shng_url_root

        self.base_dir = self._sh.get_basedir()
        self.plugins_dir = os.path.join(self.base_dir, 'plugins')
        self.logger = logging.getLogger(__name__)

        self.plugins = Plugins.get_instance()

        self.plugin_data = {}

        self.blog_urls = {}
        self._update_bloglinks_active = True

        # Start scheduler
        self._blog_task_name = 'modules.admin.update_blog_links'
        self._sh.scheduler.add(self._blog_task_name,
                               self._test_for_blog_articles_task,
                               cycle=60,
                               offset=0)
        try:
            module.add_stop_method(self.stop, self.__class__.__name__)
        except Exception as e:
            self.logger.exception("__init__: Exception {}".format(e))
        return
Exemple #4
0
    def logics_initialize(self):
        """
        Initialize access to logics API and test if Blockly plugin is loaded

        This can't be done during __init__, since not all components are loaded/initialized
        at that time.
        """
        if self.logics is not None:
            return

        self.logics = Logics.get_instance()
        if self.logics is None:
            # SmartHomeNG has not yet initialized the logics module (still starting up)
            return

        if self.plugins == None:
            self.plugins = Plugins.get_instance()
        self.yaml_updates = (self.logics.return_config_type() == '.yaml')

        # find out if blockly plugin is loaded
        if self.blockly_plugin_loaded == None:
            self.blockly_plugin_loaded = False
            for x in self.plugins.return_plugins():
                try:
                    if x.get_shortname() == 'blockly':
                        self.blockly_plugin_loaded = True
                except:
                    pass
        return
Exemple #5
0
    def read(self, id=None):
        """
        return an object with data about all configured plugins
        """
        if self.plugins is None:
            self.plugins = Plugins.get_instance()

        config_filename = self.plugins._get_plugin_conf_filename()
        _etc_dir = os.path.dirname(config_filename)

        info = {}
        # make it 'readonly', if plugin.conf is used
        info['readonly'] = not(os.path.splitext(config_filename)[1].lower() == '.yaml')

        if not info['readonly']:
            # for beta-testing: create a backup of ../etc/plugin.yaml
            if not os.path.isfile(os.path.join(_etc_dir, 'plugin_before_admin_config.yaml')):
                shutil.copy2(config_filename, os.path.join(_etc_dir, 'plugin_before_admin_config.yaml'))
                self.logger.warning('Created a backup copy of plugin.yaml ({})'.format(os.path.join(_etc_dir, 'plugin_before_admin_config.yaml')))

        # get path to plugin configuration file, withou extension
        _conf = lib.config.parse_basename(os.path.splitext(config_filename)[0], configtype='plugin')


        for confplg in _conf:
            plg = _conf[confplg].get('plugin_name', '?')
            if plg == '?':
                plg = _conf[confplg].get('class_path', '?')
            plginstance = self.plugins.return_plugin(confplg)
            typ = '?'
            if plginstance != None:
                # self.logger.warning("confplg {}: type(plginstance) = {}".format(confplg, type(plginstance)))
                # self.logger.warning("confplg {}: type(plginstance.metadata) = {}".format(confplg, type(plginstance.metadata)))
                try:
                    typ = plginstance.metadata.get_string('type')
                    _conf[confplg]['_meta'] = plginstance.metadata.meta
                    _conf[confplg]['_description'] = plginstance.metadata.meta['plugin']['description']
                except:
                    self.logger.warning('confplg {}: Passed for plginstance = {}'.format(confplg, plginstance))
            else:
                # nicht geladene Plugins
                # self.logger.warning("confplg {}: type(plginstance) = None".format(confplg))
                plugin_name, metadata = self._get_pluginname_and_metadata(confplg, _conf[confplg])
                # self.logger.warning("plugin_name = {}, meta = {}".format(plugin_name, metadata.meta))

                typ = metadata.get_string('type')
                _conf[confplg]['_meta'] = metadata.meta
                try:
                    _conf[confplg]['_description'] = metadata.meta['plugin']['description']
                except:
                    _conf[confplg]['_description'] = {}
                    _conf[confplg]['_description']['de'] = ''
                    _conf[confplg]['_description']['en'] = ''


        info['plugin_config'] = _conf

        return json.dumps(info)
    def __init__(self):

        # !! Cannot initialze self.logics here, because at startup logics are initialized after plugins !!
        self.logics = Logics.get_instance()
        self.logger.info("BackendLogics __init__ self.logics = {}".format(self.logics))
        self.plugins = Plugins.get_instance()
        self.logger.info("BackendLogics __init__ self.plugins = {}".format(str(self.plugins)))
        self.scheduler = Scheduler.get_instance()
        self.logger.info("BackendLogics __init__ self.scheduler = {}".format(self.scheduler))
Exemple #7
0
    def __init__(self, module):
        self._sh = module._sh
        self.base_dir = self._sh.get_basedir()
        self.plugins_dir = os.path.join(self.base_dir, 'plugins')
        self.logger = logging.getLogger(__name__)

        self.plugins = Plugins.get_instance()

        self.plugin_data = {}
        return
Exemple #8
0
    def __init__(self, module, jwt_secret=False):
        self._sh = module._sh
        self.base_dir = self._sh.get_basedir()
        self.plugins_dir = os.path.join(self.base_dir, 'plugins')
        self.logger = logging.getLogger(__name__)
        self.logger.info("PluginController(): __init__")
        self.plugins = Plugins.get_instance()

        self.plugin_data = {}
        self.jwt_secret = jwt_secret
        return
Exemple #9
0
    def _test_for_blog_articles_task(self):
        """
        Scheduler task to test if blog articles for the loaded plugins exist
        :return:
        """

        if self.plugins == None:
            self.plugins = Plugins.get_instance()
        if self.plugins != None and self._sh.shng_status.get('code', 0) == 20:   # Running
            self._sh.scheduler._scheduler[self._blog_task_name]['cycle'] = {120 * 60 + randrange(60) : None}  # set scheduler cycle to test every 2 hours
            start = time.time()
            temp_blog_urls = {}

            try:
                for plugin in self.plugins.return_plugins():
                    if not self._update_bloglinks_active:
                        break
                    if isinstance(plugin, SmartPlugin):
                        plugin_name = plugin.get_shortname()
                        if temp_blog_urls.get(plugin_name, None) is None:
                            # add link to blog, if articles exist, that have the pluginname as a tag
                            #   example: Blog articles with tag 'backend'
                            #   - https://www.smarthomeng.de/tag/backend
                            #   alternative example: Blog articles with category 'plugins' and tag 'backend'
                            #   - https://www.smarthomeng.de/category/plugins?tag=backend
                            temp_blog_urls[plugin_name] = 'https://www.smarthomeng.de/tag/' + plugin_name
                            r = requests.get(temp_blog_urls[plugin_name])
                            if r.status_code == 404:
                                temp_blog_urls[plugin_name] = ''
                            elif r.status_code != 200:
                                if r.status_code in [500, 503]:
                                    self.logger.info("www.smarthomeng.de sent status_code {} for get-request to {}".format(r.status_code, temp_blog_urls[plugin_name]))
                                else:
                                    self.logger.notice("www.smarthomeng.de sent status_code {} for get-request to {}".format(r.status_code, temp_blog_urls[plugin_name]))
                                temp_blog_urls[plugin_name] = ''
                        else:
                            pass
                        time.sleep(1)
            except OSError as e:
                if str(e).find('[Errno 101]') > -1:     # [Errno 101] Das Netzwerk ist nicht erreichbar
                    pass
                else:
                    self.logger.error("_test_for_blog_articles: OSError {}".format(e))
            except Exception as e:
                self.logger.error("_test_for_blog_articles: Exception {}".format(e))
            self.blog_urls = temp_blog_urls
            end = time.time()
            self.logger.info("_test_for_blog_articles_task: Used time: {} - blog_urls = {}".format(end - start, self.blog_urls))
        else:
            self.logger.debug("_test_for_blog_articles: Plugin initialization not finished")
        return
Exemple #10
0
    def _test_for_blog_articles(self):
        while self._update_bloglinks_active:
            self.logger.info("_test_for_blog_articles: Testing for blog articles for every configured plugin")
            start = time.time()
            temp_blog_urls = {}
            if self.plugins == None:
                self.plugins = Plugins.get_instance()
            if self.plugins != None:
                try:
                    for plugin in self.plugins.return_plugins():
                        if not self._update_bloglinks_active:
                            break
                        if isinstance(plugin, SmartPlugin):
                            plugin_name = plugin.get_shortname()
                            if temp_blog_urls.get(plugin_name, None) is None:
                                # add link to blog, if articles exist, that have the pluginname as a tag
                                #   example: Blog articles with tag 'backend'
                                #   - https://www.smarthomeng.de/tag/backend
                                #   alternative example: Blog articles with category 'plugins' and tag 'backend'
                                #   - https://www.smarthomeng.de/category/plugins?tag=backend
                                temp_blog_urls[plugin_name] = 'https://www.smarthomeng.de/tag/' + plugin_name
                                r = requests.get(temp_blog_urls[plugin_name])
                                if r.status_code == 404:
                                    temp_blog_urls[plugin_name] = ''
                                elif r.status_code != 200:
                                    self.logger.error("Received status_code {} for get-request to {}".format(r.status_code, temp_blog_urls[plugin_name]))
                                    temp_blog_urls[plugin_name] = ''
                            else:
                                pass
                except Exception as e:
                    self.logger.exception("_test_for_blog_articles: Exception {}".format(e))
                sleeptime = 120 * 60   # test every 2 hours
            else:
                sleeptime = 30
                self.logger.debug("_test_for_blog_articles: Plugin initialization not finished")
            self.blog_urls = temp_blog_urls
            end = time.time()
            self.logger.info("_test_for_blog_articles: Used time: {} - blog_urls = {}".format(end-start, self.blog_urls))

            max_sleepcount = sleeptime / 5

            sleepcount = 0
            while self._update_bloglinks_active and sleepcount < max_sleepcount:
                sleepcount += 1
                time.sleep(5)

        self.logger.info("Thread '_test_for_blog_articles' exited because '_update_bloglinks_active' is False")
        return
Exemple #11
0
    def read(self, id=None):
        """
        return a list of all configured plugin instances
        """
        self.logger.info("PluginsAPIController (index)")

        if self.plugins == None:
            self.plugins = Plugins.get_instance()
        self.plugin_list = []
        for x in self.plugins.return_plugins():
            if isinstance(x, SmartPlugin):
                plugin_config_name = x.get_configname()
                if x.metadata is not None:
                    api = x.metadata.get_plugin_function_defstrings(with_type=True, with_default=True)
                    if api is not None:
                        for function in api:
                            self.plugin_list.append(plugin_config_name + "." + function)

        return json.dumps(self.plugin_list)
Exemple #12
0
    def read(self, logicname=None):
        """
        return an object with type info about all logics
        """
        # create a list of dicts, where each dict contains the information for one logic
        self.logger.info("LogicsController.read()")

        if self.plugins is None:
            self.plugins = Plugins.get_instance()
        if self.scheduler is None:
            self.scheduler = Scheduler.get_instance()

        self.logics_initialize()
        if self.logics is None:
            # SmartHomeNG has not yet initialized the logics module (still starting up)
            raise cherrypy.NotFound

        if logicname is None:
            return self.get_logics_info()
        else:
            return self.get_logic_info(logicname)
Exemple #13
0
    def handle_plugin_action(self, id, action):

        if self.plugins is None:
            self.plugins = Plugins.get_instance()
        plugin = self.plugins.return_plugin(id)
        if plugin is None:
            response = {'result': 'error', 'description': "No running plugin instance found for '{}'".format(id)}
            return response

        response = {}
        if action == 'start':
            self.logger.info("PluginController.handle_plugin_action(): Starting plugin '{}'".format(id))
            plugin.run()
            response = {'result': 'ok'}

        elif action == 'stop':
            self.logger.info("PluginController.handle_plugin_action(): Stopping plugin '{}'".format(id))
            plugin.stop()
            response = {'result': 'ok'}

        return response
Exemple #14
0
    def __init__(self, smarthome, userlogicconf, envlogicconf):
        logger.info('Start Logics')
        self.shtime = Shtime.get_instance()
        self.items = Items.get_instance()
        self.plugins = Plugins.get_instance()
        self.scheduler = Scheduler.get_instance()

        self._sh = smarthome
        self._userlogicconf = userlogicconf
        self._env_dir = smarthome._env_dir
        self._envlogicconf = envlogicconf
        self._etc_dir = smarthome._etc_dir
        self._logic_dir = smarthome._logic_dir
        self._workers = []
        self._logics = {}
        self._bytecode = {}
        self.alive = True

        global _logics_instance
        if _logics_instance is not None:
            import inspect
            curframe = inspect.currentframe()
            calframe = inspect.getouterframes(curframe, 4)
            logger.critical(
                "A second 'logics' object has been created. There should only be ONE instance of class 'Logics'!!! Called from: {} ({})"
                .format(calframe[1][1], calframe[1][3]))

        _logics_instance = self

        self.scheduler = Scheduler.get_instance()

        _config = {}
        self._systemlogics = self._read_logics(envlogicconf, self._env_dir)
        _config.update(self._systemlogics)
        self._userlogics = self._read_logics(userlogicconf, self._logic_dir)
        _config.update(self._userlogics)

        for name in _config:
            self._load_logic(name, _config)
Exemple #15
0
    def __init__(self, module):
        self._sh = module._sh
        self.module = module
        self.base_dir = self._sh.get_basedir()
        self.logger = logging.getLogger(__name__)

        self.etc_dir = self._sh._etc_dir

        self.logics_dir = os.path.join(self.base_dir, 'logics')
        self.logics = Logics.get_instance()
        self.logger.info("__init__ self.logics = {}".format(self.logics))
        self.plugins = Plugins.get_instance()
        self.logger.info("__init__ self.plugins = {}".format(str(
            self.plugins)))
        self.scheduler = Scheduler.get_instance()
        self.logger.info("__init__ self.scheduler = {}".format(self.scheduler))

        self.blockly_plugin_loaded = None
        self.logics_data = {}

        self.logics = Logics.get_instance()
        return
Exemple #16
0
    def update(self, logicname='', action='', filename=''):
        """
        Handle PUT requests for logics API
        """
        self.logger.info(
            "LogicsController.update(logicname='{}', action='{}')".format(
                logicname, action))

        if self.plugins is None:
            self.plugins = Plugins.get_instance()
        if self.scheduler is None:
            self.scheduler = Scheduler.get_instance()

        self.logics_initialize()
        if self.logics is None:
            return json.dumps({
                'result':
                'Error',
                'description':
                "SmartHomeNG is still initializing"
            })

        if (action == 'saveparameters') and (logicname != ''):
            return self.save_logic_parameters(logicname)
        elif not action in ['create', 'load', 'delete']:
            mylogic = self.logics.return_logic(logicname)
            if mylogic is None:
                return json.dumps({
                    'result':
                    'Error',
                    'description':
                    "No logic with name '" + logicname + "' found"
                })

        if logicname != '':
            return self.set_logic_state(logicname, action, filename)

        return None
Exemple #17
0
    def __init__(self, module, shng_url_root):
        self._sh = module._sh
        self.module = module
        self.shng_url_root = shng_url_root

        self.base_dir = self._sh.get_basedir()
        self.plugins_dir = os.path.join(self.base_dir, 'plugins')
        self.logger = logging.getLogger(__name__)

        self.plugins = Plugins.get_instance()

        self.plugin_data = {}

        self.blog_urls = {}
        self._update_bloglinks_active = True
        self._update_bloglinks_thread = threading.Thread(target=self._test_for_blog_articles,
                                                         name="Admin: Update blog links").start()

        try:
            module.add_stop_method(self.stop, self.__class__.__name__)
        except Exception as e:
            self.logger.exception("__init__: Exception {}".format(e))
        return
Exemple #18
0
    def __init__(self, smarthome, userlogicconf, envlogicconf):
        logger.info('Start Logics')
        self.shtime = Shtime.get_instance()
        self.items = Items.get_instance()
        self.plugins = Plugins.get_instance()
        self.scheduler = Scheduler.get_instance()

        self._sh = smarthome
        self._userlogicconf = userlogicconf
        self._env_dir = smarthome._env_dir
        self._envlogicconf = envlogicconf
        self._etc_dir = smarthome._etc_dir
        self._logic_dir = smarthome._logic_dir
        self._workers = []
        self._logics = {}
        self._bytecode = {}
        self.alive = True

        global _logics_instance
        if _logics_instance is not None:
            import inspect
            curframe = inspect.currentframe()
            calframe = inspect.getouterframes(curframe, 4)
            logger.critical("A second 'logics' object has been created. There should only be ONE instance of class 'Logics'!!! Called from: {} ({})".format(calframe[1][1], calframe[1][3]))

        _logics_instance = self

        self.scheduler = Scheduler.get_instance()
        
        _config = {}
        self._systemlogics = self._read_logics(envlogicconf, self._env_dir)
        _config.update(self._systemlogics)
        self._userlogics = self._read_logics(userlogicconf, self._logic_dir)
        _config.update(self._userlogics)

        for name in _config:
            self._load_logic(name, _config)
Exemple #19
0
    def get_config_filename(self):

        if self.plugins is None:
            self.plugins = Plugins.get_instance()

        return self.plugins._get_plugin_conf_filename()
Exemple #20
0
    def __init__(self):

        self.plugins = Plugins.get_instance()
        self.logger.info("BackendPlugins __init__ self.plugins = {}".format(
            str(self.plugins)))
Exemple #21
0
 def read(self, id=None):
     """
     return an object with data about the logic parameters of all configured plugins
     """
     self.plugins = Plugins.get_instance()
     return json.dumps(self.plugins.get_logic_parameters())
Exemple #22
0
    def read(self, id=None):
        """
        return a list of all configured plugin instances
        """
        self.logger.info("PluginsInfoController (index)")
        if self.plugins == None:
            self.plugins = Plugins.get_instance()

        # get data for display of page
        conf_plugins = {}
        _conf = lib.config.parse(self.plugins._get_plugin_conf_filename())

        for plugin in _conf:
            conf_plugins[plugin] = {}
            conf_plugins[plugin] = _conf[plugin]

        #self._test_for_blog_articles()
        plugin_list = []
        for x in self.plugins.return_plugins():
            plugin = dict()
            plugin['metadata'] = {}

            plugin['stopped'] = False
            # Update(s) triggered by < strong > {{p.instance._itemlist | length}} < / strong > items
            plugin['triggers'] = str(x._itemlist)

            if isinstance(x, SmartPlugin):
                plugin['pluginname'] = x.get_shortname()
                plugin['configname'] = x.get_configname()
                plugin['version'] = x.get_version()
                plugin['smartplugin'] = True
                plugin['multiinstance'] = x.is_multi_instance_capable()
                plugin['instancename'] = x.get_instance_name()

                plugin['webif_url'] = ''
                if self.module.mod_http.get_webifs_for_plugin(
                        x.get_shortname()) != []:
                    for webif in self.module.mod_http.get_webifs_for_plugin(
                            x.get_shortname()):
                        if webif['Instance'] == plugin['instancename']:
                            # plugin['webif_url'] = self.shng_url_root + webif['Mount']  # don't specify full path (for docker installations reletive path is needed)
                            plugin['webif_url'] = webif['Mount']

                plugin['blog_url'] = self.blog_urls.get(
                    plugin['pluginname'], '')

                plugin['parameters'] = []
                if bool(x._parameters):
                    #                    for p in x._parameters:
                    for p in x._metadata.get_parameterlist():
                        p_dict = {}
                        p_dict['name'] = str(p)
                        p_dict[
                            'type'] = x._metadata.get_parameter_type_with_subtype(
                                p)
                        p_dict['value'] = str(x._parameters[p])
                        p_dict[
                            'default'] = x._metadata.get_parameter_defaultvalue(
                                p)
                        plugin['parameters'].append(p_dict)

                plugin['attributes'] = []
                for a in x._metadata.get_itemdefinitionlist():
                    a_dict = {}
                    a_dict['name'] = str(a)
                    a_dict[
                        'type'] = x._metadata.get_itemdefinition_type_with_subtype(
                            a)
                    plugin['attributes'].append(a_dict)

                plugin['metadata']['classpath'] = x._classpath  # str
                plugin['metadata']['classname'] = x.get_classname()
            else:
                plugin['pluginname'] = x._shortname
                plugin['configname'] = x._configname
                plugin['version'] = ''
                plugin['smartplugin'] = False
                plugin['multiinstance'] = False
                plugin['instancename'] = ''
                plugin['webif_url'] = ''
                plugin['parameters'] = []
                plugin['attributes'] = []

                plugin['metadata']['classpath'] = str(x._classpath)  # str
                plugin['metadata']['classname'] = str(x._classname)  # str
                plugin['stopped'] = False

            plugin['metadata']['type'] = x._metadata.get_string('type')
            plugin['metadata']['state'] = x._metadata.get_string('state')
            plugin['metadata']['description'] = x._metadata.get_mlstring(
                'description')
            plugin['metadata']['description_long'] = x._metadata.get_mlstring(
                'description_long')
            plugin['metadata']['keywords'] = x._metadata.get_string('keywords')
            plugin['metadata']['documentation'] = x._metadata.get_string(
                'documentation')
            plugin['metadata']['support'] = x._metadata.get_string('support')
            plugin['metadata']['maintainer'] = x._metadata.get_string(
                'maintainer')
            plugin['metadata']['tester'] = x._metadata.get_string('tester')

            try:
                plugin['stopped'] = not x.alive
                plugin['stoppable'] = True
            except:
                plugin['stopped'] = False
                plugin['stoppable'] = False
            if plugin['pluginname'] == 'backend':
                plugin['stoppable'] = False

            plugin_list.append(plugin)
        #        plugins_sorted = sorted(plugin_list, key=lambda k: k['classpath'])
        plugins_sorted = sorted(
            plugin_list, key=lambda k: k['pluginname'] + k['instancename'])

        return json.dumps(plugins_sorted)
Exemple #23
0
    def __init__(self):

        self.plugins = Plugins.get_instance()

        return