コード例 #1
0
 def load(self):
     if not self.FILE_PATH.is_file():
         self.data = {}
         self.save()
         return
     with open(self.FILE_PATH, 'rb') as fd:
         try:
             self.data = pickle.load(fd)
         except Exception:
             try:
                 import shelve
                 s = shelve.open(self.FILE_PATH)
                 for (k, v) in s.items():
                     self.data[k] = v
                 if not isinstance(self.data, dict):
                     raise GajimPluginException
                 s.close()
                 self.save()
             except Exception:
                 enc = locale.getpreferredencoding()
                 filename = self.FILE_PATH.decode(enc) + '.bak'
                 log.warning(
                     '%s plugin config file not readable. Saving it as '
                     '%s and creating a new one',
                     self.plugin.short_name, filename)
                 if os.path.exists(self.FILE_PATH + '.bak'):
                     os.remove(self.FILE_PATH + '.bak')
                 os.rename(self.FILE_PATH, self.FILE_PATH + '.bak')
                 self.data = {}
                 self.save()
コード例 #2
0
    def deactivate_plugin(self, plugin):
        # remove GUI extension points handlers (provided by plug-in) from
        # handlers list
        for gui_extpoint_name, gui_extpoint_handlers in \
        plugin.gui_extension_points.items():
            self.gui_extension_points_handlers[gui_extpoint_name].remove(
                gui_extpoint_handlers)

        # detaching plug-in from handler GUI extension points (calling
        # cleaning up method that must be provided by plug-in developer
        # for each handled GUI extension point)
        for gui_extpoint_name, gui_extpoint_handlers in \
        plugin.gui_extension_points.items():
            if gui_extpoint_name in self.gui_extension_points:
                for gui_extension_point_args in self.gui_extension_points[
                        gui_extpoint_name]:
                    handler = gui_extpoint_handlers[1]
                    if handler:
                        try:
                            handler(*gui_extension_point_args)
                        except Exception as e:
                            log.warning('Error executing %s',
                                        handler,
                                        exc_info=True)

        self._remove_events_handler_from_ged(plugin)
        self._remove_network_events_from_nec(plugin)
        self._remove_name_from_encryption_plugins(plugin)

        # removing plug-in from active plug-ins list
        plugin.deactivate()
        self.active_plugins.remove(plugin)
        self._set_plugin_active_in_global_config(plugin, False)
        plugin.active = False
コード例 #3
0
ファイル: pluginmanager.py プロジェクト: slokhorst/gajim
    def load_module(self):
        module_path = self.path / '__init__.py'
        if not module_path.exists():
            # On Windows we only ship compiled files
            module_path = self.path / '__init__.pyc'

        module_name = self.path.stem

        try:
            spec = spec_from_file_location(module_name, module_path)
            if spec is None:
                return None
            module = module_from_spec(spec)
            sys.modules[spec.name] = module
            spec.loader.exec_module(module)
        except Exception as error:
            log.warning('Error while loading module: %s', error)
            return None

        for module_attr_name in dir(module):
            module_attr = getattr(module, module_attr_name)
            if issubclass(module_attr, GajimPlugin):
                for field in FIELDS:
                    setattr(module_attr, field, str(getattr(self, field)))
                setattr(module_attr, '__path__', str(self.path))
                return module_attr
        return None
コード例 #4
0
 def load(self):
     if os.path.isfile(self.FILE_PATH):
         fd = open(self.FILE_PATH, 'rb')
         try:
             self.data = pickle.load(fd)
             fd.close()
         except:
             fd.close()
             try:
                 import shelve
                 s = shelve.open(self.FILE_PATH)
                 for (k, v) in s.items():
                     self.data[k] = v
                 if not isinstance(self.data, dict):
                     raise GajimPluginException
                 s.close()
                 self.save()
             except:
                 log.warning(
                     '%s plugin config file not readable. Saving it as '
                     '%s and creating a new one' %
                     (self.plugin.short_name,
                      self.FILE_PATH.decode(locale.getpreferredencoding()) +
                      '.bak'))
                 if os.path.exists(self.FILE_PATH + '.bak'):
                     os.remove(self.FILE_PATH + '.bak')
                 os.rename(self.FILE_PATH, self.FILE_PATH + '.bak')
                 self.data = {}
                 self.save()
     else:
         self.data = {}
         self.save()
コード例 #5
0
ファイル: pluginmanager.py プロジェクト: mdellweg/gajim
 def _execute_all_handlers_of_gui_extension_point(self, gui_extpoint_name,
 *args):
     if gui_extpoint_name in self.gui_extension_points_handlers:
         for handlers in self.gui_extension_points_handlers[
         gui_extpoint_name]:
             try:
                 handlers[0](*args)
             except Exception as e:
                 log.warning('Error executing %s', handlers[0],
                     exc_info=True)
コード例 #6
0
ファイル: pluginmanager.py プロジェクト: slokhorst/gajim
    def install_from_zip(self, zip_filename, overwrite=None):
        '''
        Install plugin from zip and return plugin
        '''
        try:
            zip_file = zipfile.ZipFile(zip_filename)
        except zipfile.BadZipfile:
            # it is not zip file
            raise PluginsystemError(_('Archive corrupted'))
        except IOError:
            raise PluginsystemError(_('Archive empty'))

        if zip_file.testzip():
            # CRC error
            raise PluginsystemError(_('Archive corrupted'))

        dirs = []
        manifest = None
        for filename in zip_file.namelist():
            if filename.startswith('.') or filename.startswith('/') or \
            ('/' not in filename):
                # members not safe
                raise PluginsystemError(_('Archive is malformed'))
            if filename.endswith('/') and filename.find('/', 0, -1) < 0:
                dirs.append(filename.strip('/'))
            if 'manifest.ini' in filename.split('/')[1]:
                manifest = True
        if not manifest:
            return None
        if len(dirs) > 1:
            raise PluginsystemError(_('Archive is malformed'))

        plugin_name = dirs[0]
        user_dir = configpaths.get('PLUGINS_USER')
        plugin_path = user_dir / plugin_name

        if plugin_path.exists():
            # Plugin dir already exists
            if not overwrite:
                raise PluginsystemError(_('Plugin already exists'))
            self.uninstall_plugin(self.get_plugin_by_path(str(plugin_path)))

        zip_file.extractall(user_dir)
        zip_file.close()

        plugin = self._load_plugin(plugin_path)
        if plugin is None:
            log.warning('Error while installing from zip')
            rmtree(plugin_path)
            raise PluginsystemError(_('Installation failed'))

        return self.add_plugin(plugin)
コード例 #7
0
ファイル: pluginmanager.py プロジェクト: mdellweg/gajim
 def _handle_all_gui_extension_points_with_plugin(self, plugin):
     for gui_extpoint_name, gui_extpoint_handlers in \
     plugin.gui_extension_points.items():
         if gui_extpoint_name in self.gui_extension_points:
             for gui_extension_point_args in self.gui_extension_points[
             gui_extpoint_name]:
                 handler = gui_extpoint_handlers[0]
                 if handler:
                     try:
                         handler(*gui_extension_point_args)
                     except Exception as e:
                         log.warning('Error executing %s', handler,
                             exc_info=True)
コード例 #8
0
ファイル: pluginmanager.py プロジェクト: slokhorst/gajim
    def update_plugins(self, replace=True, activate=False, plugin_name=None):
        '''
        Move plugins from the downloaded folder to the user plugin folder

        :param replace: replace plugin files if they already exist.
        :type replace: boolean
        :param activate: load and activate the plugin
        :type activate: boolean
        :param plugin_name: if provided, update only this plugin
        :type plugin_name: str
        :return: list of updated plugins (files have been installed)
        :rtype: [] of str
        '''
        updated_plugins = []
        user_dir = configpaths.get('PLUGINS_USER')
        dl_dir = configpaths.get('PLUGINS_DOWNLOAD')
        to_update = [plugin_name] if plugin_name else next(os.walk(dl_dir))[1]
        for directory in to_update:
            src_dir = dl_dir / directory
            dst_dir = user_dir / directory
            try:
                if dst_dir.exists():
                    if not replace:
                        continue
                    self.delete_plugin_files(dst_dir)
                move(src_dir, dst_dir)
            except Exception:
                log.exception(
                    'Upgrade of plugin %s failed. '
                    'Impossible to move files from "%s" to "%s"', directory,
                    src_dir, dst_dir)
                continue
            updated_plugins.append(directory)
            if activate:
                plugin = self._load_plugin(Path(dst_dir))
                if plugin is None:
                    log.warning('Error while updating plugin')
                    continue

                self.add_plugin(plugin, activate=True)
        return updated_plugins
コード例 #9
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
コード例 #10
0
ファイル: pluginmanager.py プロジェクト: slokhorst/gajim
 def _load_plugin(plugin_path):
     try:
         return Plugin.from_manifest(plugin_path)
     except Exception as error:
         log.warning(error)