示例#1
0
    def add_plugin(self, plugin, activate=False):
        plugin_class = plugin.load_module()
        if plugin_class is None:
            return None

        if plugin in self.plugins:
            log.info('Not loading plugin %s v %s. Plugin already loaded.',
                     plugin.short_name, plugin.version)
            return None

        try:
            plugin_obj = plugin_class()
        except Exception:
            log.exception('Error while loading a plugin')
            return None

        if plugin.short_name not in app.settings.get_plugins():
            app.settings.set_plugin_setting(plugin.short_name, 'active',
                                            plugin.shipped)

        self.plugins.append(plugin_obj)
        plugin_obj.active = False

        if activate:
            self.activate_plugin(plugin_obj)

        app.nec.push_incoming_event(
            NetworkEvent('plugin-added', plugin=plugin_obj))

        return plugin_obj
示例#2
0
    def add_plugin(self, plugin_class):
        '''
        :todo: what about adding plug-ins that are already added? Module reload
        and adding class from reloaded module or ignoring adding plug-in?
        '''
        try:
            plugin = plugin_class()
        except Exception:
            log.exception('Error while loading a plugin')
            return

        if plugin not in self.plugins:
            if not self._plugin_has_entry_in_global_config(plugin):
                self._create_plugin_entry_in_global_config(plugin)

            self.plugins.append(plugin)
            plugin.active = False
            app.nec.push_incoming_event(
                NetworkEvent('plugin-added', plugin=plugin))
        else:
            log.info(
                'Not loading plugin %s v%s from module %s '
                '(identified by short name: %s). Plugin already loaded.',
                plugin.name, plugin.version, plugin.__module__,
                plugin.short_name)
示例#3
0
def try_run(argv, directory):
    try:
        p = popen_nt_friendly(argv, directory)
        out = p.communicate()[0]
        log.info(out)
        return p.wait()
    except Exception as e:
        return _('Error executing "%(command)s": %(error)s') % {
            'command': " ".join(argv),
            'error': str(e)
        }
示例#4
0
    def _nec_subscribe_presence_received(self, obj):
        if self.config['block_subscription_requests'] and \
        not app.contacts.get_contacts(obj.conn.name, obj.jid):
            log.info('discarding subscription request from %s', obj.jid)
            return True

        if obj.jid.split("@", 1)[1] in self.block_domains:
            log.info(
                'discarding subscription request from %s, domain is blocked',
                obj.jid)
            return True
示例#5
0
    def _nec_message_received_received(self, obj):
        if self.config['disable_xhtml_muc'] and obj.mtype == 'groupchat':
            self.remove_xhtml(obj)
        if self.config['disable_xhtml_pm'] and obj.gc_control and \
        obj.resource and obj.mtype == 'chat':
            self.remove_xhtml(obj)

        if obj.jid.split("@", 1)[1] in self.block_domains:
            log.info('discarding message from %s, domain is blocked', obj.jid)
            return True

        return False
示例#6
0
    def _nec_decrypted_message_received_received(self, obj):
        if not obj.msgtxt:
            return False

        if obj.jid.split("@", 1)[1] in self.block_domains:
            log.info('discarding message from %s, domain is blocked', obj.jid)
            return True

        if self._nec_decrypted_message_received_question(obj):
            return True
        limit = self.config['msgtxt_limit']
        if limit > -1 and len(obj.msgtxt) > limit:
            return True
        return False
示例#7
0
    def add_plugin(self, plugin_class):
        '''
        :todo: what about adding plug-ins that are already added? Module reload
        and adding class from reloaded module or ignoring adding plug-in?
        '''
        plugin = plugin_class()

        if plugin not in self.plugins:
            if not self._plugin_has_entry_in_global_config(plugin):
                self._create_plugin_entry_in_global_config(plugin)

            self.plugins.append(plugin)
            plugin.active = False
        else:
            log.info('Not loading plugin %s v%s from module %s (identified by'
                ' short name: %s). Plugin already loaded.' % (plugin.name,
                plugin.version, plugin.__module__, plugin.short_name))
示例#8
0
    def send_question(self, obj, jid):
        if obj.mtype != 'chat' and obj.mtype != 'normal':
            log.info('Anti_spam wrong message type: %s', obj.mtype)
            return

        question = self.config['msgtxt_question']
        log.info('Anti_spam enabled for %s, question: %s', jid, question)
        message = _('Antispam enabled. Please answer the question. The message must only ' + \
                    'contain the answer. (Messages sent before the correct answer, will be lost): ') \
                    + question

        if obj.mtype == 'chat':
            stanza = nbxmpp.Message(to=jid, body=message, typ=obj.mtype)
        else:  # for 'normal' type
            stanza = nbxmpp.Message(to=jid,
                                    body=message,
                                    subject='Antispam enabled',
                                    typ=obj.mtype)

        app.connections[obj.conn.name].connection.send(stanza)
示例#9
0
    def _load_plugins(self):
        plugins = {}
        for plugin_dir in configpaths.get_plugin_dirs():
            if not plugin_dir.is_dir():
                continue

            for plugin_path in plugin_dir.iterdir():
                plugin = self._load_plugin(plugin_path)
                if plugin is None:
                    continue

                same_plugin = plugins.get(plugin.short_name)
                if same_plugin is not None:
                    if same_plugin.version > plugin.version:
                        continue

                log.info('Found plugin %s %s', plugin.short_name,
                         plugin.version)
                plugins[plugin.short_name] = plugin

        for plugin in plugins.values():
            self.add_plugin(plugin)
示例#10
0
    def scan_dir_for_plugins(path, scan_dirs=True, package=False):
        r'''
        Scans given directory for plugin classes.

        :param path: directory to scan for plugins
        :type path: str

        :param scan_dirs: folders inside path are processed as modules
        :type scan_dirs: boolean

        :param package: if path points to a single package folder
        :type package: boolean

        :return: list of found plugin classes (subclasses of `GajimPlugin`
        :rtype: [] of class objects

        :note: currently it only searches for plugin classes in '\*.py' files
                present in given directory `path` (no recursion here)

        :todo: add scanning zipped modules
        '''
        from gajim.plugins.plugins_i18n import _
        plugins_found = []
        conf = configparser.ConfigParser()
        fields = ('name', 'short_name', 'version', 'description', 'authors',
                  'homepage')
        if not os.path.isdir(path):
            return plugins_found

        if package:
            path, package_name = os.path.split(path)
            dir_list = [package_name]
        else:
            dir_list = os.listdir(path)

        sys.path.insert(0, path)

        for elem_name in dir_list:
            file_path = os.path.join(path, elem_name)

            if os.path.isfile(file_path) and fnmatch.fnmatch(
                    file_path, '*.py'):
                module_name = os.path.splitext(elem_name)[0]
            elif os.path.isdir(file_path) and scan_dirs:
                module_name = elem_name
                file_path += os.path.sep
            else:
                continue

            manifest_path = os.path.join(os.path.dirname(file_path),
                                         'manifest.ini')
            if scan_dirs and (not os.path.isfile(manifest_path)):
                continue

            # read metadata from manifest.ini
            conf.remove_section('info')
            with open(manifest_path, encoding='utf-8') as conf_file:
                try:
                    conf.read_file(conf_file)
                except configparser.Error:
                    log.warning(("Plugin {plugin} not loaded, error loading"
                                 " manifest").format(plugin=elem_name),
                                exc_info=True)
                    continue

            min_v = conf.get('info', 'min_gajim_version', fallback=None)
            max_v = conf.get('info', 'max_gajim_version', fallback=None)

            gajim_v = gajim.__version__.split('+', 1)[0]
            gajim_v_cmp = parse_version(gajim_v)

            if min_v and gajim_v_cmp < parse_version(min_v):
                log.warning(('Plugin {plugin} not loaded, newer version of'
                             'gajim required: {gajim_v} < {min_v}').format(
                                 plugin=elem_name,
                                 gajim_v=gajim_v,
                                 min_v=min_v))
                continue
            if max_v and gajim_v_cmp > parse_version(max_v):
                log.warning(('Plugin {plugin} not loaded, plugin incompatible '
                             'with current version of gajim: '
                             '{gajim_v} > {max_v}').format(plugin=elem_name,
                                                           gajim_v=gajim_v,
                                                           max_v=max_v))
                continue

            module = None
            try:
                log.info('Loading %s', module_name)
                module = __import__(module_name)
            except Exception as error:
                log.warning(
                    "While trying to load {plugin}, exception occurred".format(
                        plugin=elem_name),
                    exc_info=sys.exc_info())
                continue

            if module is None:
                continue

            log.debug('Attributes processing started')
            for module_attr_name in [
                    attr_name for attr_name in dir(module) if not (
                        attr_name.startswith('__') or attr_name.endswith('__'))
            ]:
                module_attr = getattr(module, module_attr_name)
                log.debug('%s : %s' % (module_attr_name, module_attr))

                try:
                    if not issubclass(module_attr, GajimPlugin) or \
                    module_attr is GajimPlugin:
                        continue
                    log.debug('is subclass of GajimPlugin')
                    module_attr.__path__ = os.path.abspath(
                        os.path.dirname(file_path))

                    for option in fields:
                        if conf.get('info', option) is '':
                            raise configparser.NoOptionError(option, 'info')
                        if option == 'description':
                            setattr(module_attr, option,
                                    _(conf.get('info', option)))
                            continue
                        setattr(module_attr, option, conf.get('info', option))

                    plugins_found.append(module_attr)
                except TypeError:
                    # set plugin localization
                    try:
                        module_attr._ = _
                    except AttributeError:
                        pass
                except configparser.NoOptionError:
                    # all fields are required
                    log.debug(
                        '%s : %s' %
                        (module_attr_name,
                         'wrong manifest file. all fields are required!'))
                except configparser.NoSectionError:
                    # info section are required
                    log.debug(
                        '%s : %s' %
                        (module_attr_name,
                         'wrong manifest file. info section are required!'))
                except configparser.MissingSectionHeaderError:
                    # info section are required
                    log.debug('%s : %s' %
                              (module_attr_name,
                               'wrong manifest file. section are required!'))

        sys.path.remove(path)
        return plugins_found
示例#11
0
 def _nec_atom_entry_received(self, obj):
     if self.config['block_pubsub_messages']:
         log.info('discarding pubdubd message')
         return True