[pitivi] pluginmanager: Write and read activated plugins from the configuration file
- From: Alexandru Băluț <alexbalut src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] pluginmanager: Write and read activated plugins from the configuration file
- Date: Mon, 28 Aug 2017 22:07:41 +0000 (UTC)
commit ca40c6bb5fc24829c132ab4c15325f7453811ffe
Author: Fabian Orccon <cfoch fabian gmail com>
Date: Wed May 31 15:39:09 2017 -0500
pluginmanager: Write and read activated plugins from the configuration file
Differential Revision: https://phabricator.freedesktop.org/D1812
pitivi/pluginmanager.py | 36 +++++++++++++++++++-
pitivi/settings.py | 42 +++++++++++++++--------
tests/test_plugin_manager.py | 76 ++++++++++++++++++++++++++++++++++++++++++
tests/test_settings.py | 25 +++++++++++++-
4 files changed, 163 insertions(+), 16 deletions(-)
---
diff --git a/pitivi/pluginmanager.py b/pitivi/pluginmanager.py
index ef953d6..e748488 100644
--- a/pitivi/pluginmanager.py
+++ b/pitivi/pluginmanager.py
@@ -23,6 +23,14 @@ from gi.repository import Peas
from pitivi.configure import get_plugins_dir
from pitivi.configure import get_user_plugins_dir
+from pitivi.settings import GlobalSettings
+from pitivi.utils.loggable import Loggable
+
+
+GlobalSettings.addConfigSection("plugins")
+GlobalSettings.addConfigOption("ActivePlugins",
+ section="plugins", key="active-plugins",
+ default=[])
class API(GObject.GObject):
@@ -33,7 +41,7 @@ class API(GObject.GObject):
self.app = app
-class PluginManager:
+class PluginManager(Loggable):
"""Pitivi Plugin Manager to handle a set of plugins.
Attributes:
@@ -45,8 +53,14 @@ class PluginManager:
DEFAULT_LOADERS = ("python3", )
def __init__(self, app):
+ Loggable.__init__(self)
self.app = app
self.engine = Peas.Engine.get_default()
+ # Many plugins need access to the main window. However, by the time a
+ # plugin is loaded from settings (as soon Pitivi application starts),
+ # the main window doesn't exist yet. So we load plugins from settings
+ # after the main window is added.
+ self.app.connect("window-added", self.__window_added_cb)
for loader in self.DEFAULT_LOADERS:
self.engine.enable_loader(loader)
@@ -59,6 +73,16 @@ class PluginManager:
"""Gets the engine's plugin list."""
return self.engine.get_plugin_list()
+ def _load_plugins(self):
+ """Loads plugins from settings."""
+ plugin_names = self.app.settings.ActivePlugins
+ for plugin_name in plugin_names:
+ plugin_info = self.engine.get_plugin_info(plugin_name)
+ if plugin_info not in self.plugins:
+ self.warning("Plugin missing: %s", plugin_name)
+ continue
+ self.engine.load_plugin(plugin_info)
+
def _setup_extension_set(self):
plugin_iface = API(self.app)
self.extension_set =\
@@ -86,3 +110,13 @@ class PluginManager:
@staticmethod
def __extension_added_cb(unused_set, unused_plugin_info, extension):
extension.activate()
+
+ def __window_added_cb(self, unused_app, unused_window):
+ """Handles the addition of a window to the application."""
+ self._load_plugins()
+ self.engine.connect("notify::loaded-plugins", self.__loaded_plugins_cb)
+ self.app.disconnect_by_func(self.__window_added_cb)
+
+ def __loaded_plugins_cb(self, engine, unused_pspec):
+ """Handles the changing of the loaded plugin list."""
+ self.app.settings.ActivePlugins = engine.get_property("loaded-plugins")
diff --git a/pitivi/settings.py b/pitivi/settings.py
index 55110e1..4bf75cc 100644
--- a/pitivi/settings.py
+++ b/pitivi/settings.py
@@ -137,6 +137,32 @@ class GlobalSettings(GObject.Object, Loggable):
self._readSettingsFromConfigurationFile()
self._readSettingsFromEnvironmentVariables()
+ def _read_value(self, section, key, type_):
+ if type_ == int:
+ try:
+ value = self._config.getint(section, key)
+ except ValueError:
+ # In previous configurations we incorrectly stored
+ # ints using float values.
+ value = int(self._config.getfloat(section, key))
+ elif type_ == float:
+ value = self._config.getfloat(section, key)
+ elif type_ == bool:
+ value = self._config.getboolean(section, key)
+ elif type_ == list:
+ tmp_value = self._config.get(section, key)
+ value = [token.strip() for token in tmp_value.split("\n") if token]
+ else:
+ value = self._config.get(section, key)
+ return value
+
+ def _write_value(self, section, key, value):
+ if type(value) == list:
+ value = "\n" + "\n".join(value)
+ self._config.set(section, key, value)
+ else:
+ self._config.set(section, key, str(value))
+
def _readSettingsFromConfigurationFile(self):
"""Reads the settings from the user configuration file."""
try:
@@ -153,19 +179,7 @@ class GlobalSettings(GObject.Object, Loggable):
if not self._config.has_section(section):
continue
if key and self._config.has_option(section, key):
- if typ == int or typ == int:
- try:
- value = self._config.getint(section, key)
- except ValueError:
- # In previous configurations we incorrectly stored
- # ints using float values.
- value = int(self._config.getfloat(section, key))
- elif typ == float:
- value = self._config.getfloat(section, key)
- elif typ == bool:
- value = self._config.getboolean(section, key)
- else:
- value = self._config.get(section, key)
+ value = self._read_value(section, key, typ)
setattr(self, attrname, value)
@classmethod
@@ -210,7 +224,7 @@ class GlobalSettings(GObject.Object, Loggable):
self._config.add_section(section)
if key:
if value is not None:
- self._config.set(section, key, str(value))
+ self._write_value(section, key, value)
else:
self._config.remove_option(section, key)
try:
diff --git a/tests/test_plugin_manager.py b/tests/test_plugin_manager.py
new file mode 100644
index 0000000..0958091
--- /dev/null
+++ b/tests/test_plugin_manager.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+# Pitivi video editor
+# Copyright (c) 2017, Fabian Orccon <cfoch fabian gmail com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+"""Test the Plugin Manager"""
+import os
+import tempfile
+import unittest
+from unittest import mock
+
+from gi.repository import GObject
+
+from pitivi.pluginmanager import PluginManager
+from pitivi.settings import GlobalSettings
+
+
+class TestPluginManager(unittest.TestCase):
+ """Test the behavior of the Plugin Manager"""
+
+ def test_load_plugins_from_settings(self):
+ """Checks if the plugin manager loads plugins from GlobalSettings."""
+
+ class App(GObject.Object):
+ """A representation of the Pitivi Application for test purposes"""
+ __gsignals__ = {
+ "window-added": (GObject.SIGNAL_RUN_LAST, None, (object, ))
+ }
+
+ def __init__(self):
+ GObject.Object.__init__(self)
+ self.settings = GlobalSettings()
+
+ with mock.patch("pitivi.pluginmanager.get_plugins_dir") as get_plugins_dir,\
+ mock.patch("pitivi.pluginmanager.get_user_plugins_dir") as get_user_plugins_dir,\
+ tempfile.TemporaryDirectory() as temp_dir:
+
+ plugin_content = ("[Plugin]\n"
+ "Module=pluginA\n"
+ "Name=PluginA\n"
+ "Loader=Python3")
+
+ py_content = ("from gi.repository import GObject\n"
+ "class PluginA(GObject.GObject):\n"
+ " def __init__(self):\n"
+ " GObject.Object.__init__(self)")
+
+ with open(os.path.join(temp_dir, "pluginA.plugin"), "w") as plugin_file:
+ plugin_file.write(plugin_content)
+ with open(os.path.join(temp_dir, "pluginA.py"), "w") as py_file:
+ py_file.write(py_content)
+
+ get_plugins_dir.return_value = temp_dir
+ get_user_plugins_dir.return_value = temp_dir
+
+ app = App()
+ app.settings.ActivePlugins = ["pluginA"]
+
+ plugin_manager = PluginManager(app)
+ app.emit("window-added", None)
+
+ loaded_plugins = plugin_manager.engine.get_loaded_plugins()
+ self.assertCountEqual(loaded_plugins, app.settings.ActivePlugins)
diff --git a/tests/test_settings.py b/tests/test_settings.py
index a948cb2..a0e51c4 100644
--- a/tests/test_settings.py
+++ b/tests/test_settings.py
@@ -91,15 +91,26 @@ class TestGlobalSettings(unittest.TestCase):
key="option-b", default=False)
GlobalSettings.addConfigOption("section1OptionC", section="section-1",
key="option-c", default="")
+ GlobalSettings.addConfigOption("section1OptionD", section="section-1",
+ key="option-d", default=[])
+ GlobalSettings.addConfigOption("section1OptionE", section="section-1",
+ key="option-e", default=["foo"])
self.assertEqual(GlobalSettings.section1OptionA, 50)
self.assertEqual(GlobalSettings.section1OptionB, False)
self.assertEqual(GlobalSettings.section1OptionC, "")
+ self.assertEqual(GlobalSettings.section1OptionD, [])
+ self.assertEqual(GlobalSettings.section1OptionE, ["foo"])
conf_file_content = ("[section-1]\n"
"option-a = 10\n"
"option-b = True\n"
- "option-c = Pigs fly\n")
+ "option-c = Pigs fly\n"
+ "option-d=\n"
+ "option-e=\n"
+ " elmo\n"
+ " knows\n"
+ " where you live\n")
with mock.patch("pitivi.settings.xdg_config_home") as xdg_config_home,\
tempfile.TemporaryDirectory() as temp_dir:
@@ -111,12 +122,22 @@ class TestGlobalSettings(unittest.TestCase):
self.assertEqual(settings.section1OptionA, 10)
self.assertEqual(settings.section1OptionB, True)
self.assertEqual(settings.section1OptionC, "Pigs fly")
+ self.assertEqual(settings.section1OptionD, [])
+ expected_e_value = [
+ "elmo",
+ "knows",
+ "where you live"
+ ]
+ self.assertEqual(settings.section1OptionE, expected_e_value)
def test_write_config_file(self):
GlobalSettings.addConfigSection("section-new")
GlobalSettings.addConfigOption("sectionNewOptionA",
section="section-new", key="option-a",
default="elmo")
+ GlobalSettings.addConfigOption("sectionNewOptionB",
+ section="section-new", key="option-b",
+ default=["foo"])
with mock.patch("pitivi.settings.xdg_config_home") as xdg_config_home,\
tempfile.TemporaryDirectory() as temp_dir:
@@ -124,7 +145,9 @@ class TestGlobalSettings(unittest.TestCase):
settings1 = GlobalSettings()
settings1.sectionNewOptionA = "kermit"
+ settings1.sectionNewOptionB = []
settings1.storeSettings()
settings2 = GlobalSettings()
self.assertEqual(settings2.sectionNewOptionA, "kermit")
+ self.assertEqual(settings2.sectionNewOptionB, [])
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]