1 /*
2  * plugins_engine.c: Liferea Plugins using libpeas
3  * (derived from gtranslator code)
4  *
5  * Copyright (C) 2002-2005 Paolo Maggi
6  * Copyright (C) 2010 Steve Frécinaux
7  * Copyright (C) 2012-2015 Lars Windolf <lars.windolf@gmx.de>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 
29 #include <string.h>
30 
31 #include <glib/gi18n.h>
32 #include <glib.h>
33 #include <gio/gio.h>
34 #include <girepository.h>
35 
36 #include "plugins_engine.h"
37 
38 G_DEFINE_TYPE (LifereaPluginsEngine, liferea_plugins_engine, PEAS_TYPE_ENGINE)
39 
40 struct _LifereaPluginsEnginePrivate
41 {
42   GSettings *plugin_settings;
43 };
44 
45 LifereaPluginsEngine *default_engine = NULL;
46 
47 static void
liferea_plugins_engine_init(LifereaPluginsEngine * engine)48 liferea_plugins_engine_init (LifereaPluginsEngine * engine)
49 {
50   gchar *typelib_dir;
51   GError *error = NULL;
52   PeasPluginInfo *plugin_installer_plugin_info = NULL;
53 
54   engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine,
55                                               LIFEREA_TYPE_PLUGINS_ENGINE,
56                                               LifereaPluginsEnginePrivate);
57 
58   peas_engine_enable_loader (PEAS_ENGINE (engine), "python3");
59 
60   engine->priv->plugin_settings = g_settings_new ("net.sf.liferea.plugins");
61 
62   /* Require Lifereas's typelib. */
63   typelib_dir = g_build_filename (PACKAGE_LIB_DIR,
64                                   "girepository-1.0", NULL);
65 
66   if (!g_irepository_require_private (g_irepository_get_default (),
67 	  typelib_dir, "Liferea", "3.0", 0, &error))
68     {
69       g_warning ("Could not load Liferea repository: %s", error->message);
70       g_error_free (error);
71       error = NULL;
72     }
73 
74   g_free (typelib_dir);
75 
76   /* This should be moved to libpeas */
77   if (!g_irepository_require (g_irepository_get_default (),
78                               "Peas", "1.0", 0, &error))
79     {
80       g_warning ("Could not load Peas repository: %s", error->message);
81       g_error_free (error);
82       error = NULL;
83     }
84 
85   if (!g_irepository_require (g_irepository_get_default (),
86                               "PeasGtk", "1.0", 0, &error))
87     {
88       g_warning ("Could not load PeasGtk repository: %s", error->message);
89       g_error_free (error);
90       error = NULL;
91     }
92 
93   peas_engine_add_search_path (PEAS_ENGINE (engine),
94                                g_build_filename (g_get_user_data_dir (), "liferea", "plugins", NULL),
95                                g_build_filename (g_get_user_data_dir (), "liferea", "plugins", NULL));
96 
97   peas_engine_add_search_path (PEAS_ENGINE (engine),
98                                g_build_filename (PACKAGE_LIB_DIR,  "plugins", NULL),
99                                g_build_filename (PACKAGE_DATA_DIR, "plugins", NULL));
100 
101   g_settings_bind (engine->priv->plugin_settings,
102                    "active-plugins",
103                    engine, "loaded-plugins", G_SETTINGS_BIND_DEFAULT);
104 
105   plugin_installer_plugin_info = peas_engine_get_plugin_info (PEAS_ENGINE (engine), "plugin-installer");
106   if (plugin_installer_plugin_info)
107 	peas_engine_load_plugin (PEAS_ENGINE (engine), plugin_installer_plugin_info);
108   else
109 	g_warning ("The plugin-installer plugin was not found.");
110 }
111 
112 /* Provide default signal handlers */
113 
114 static void
on_extension_added(PeasExtensionSet * extensions,PeasPluginInfo * info,PeasExtension * exten,gpointer user_data)115 on_extension_added (PeasExtensionSet *extensions,
116                     PeasPluginInfo   *info,
117                     PeasExtension    *exten,
118                     gpointer         user_data)
119 {
120 	peas_extension_call (exten, "activate");
121 }
122 
123 static void
on_extension_removed(PeasExtensionSet * extensions,PeasPluginInfo * info,PeasExtension * exten,gpointer user_data)124 on_extension_removed (PeasExtensionSet *extensions,
125                       PeasPluginInfo   *info,
126                       PeasExtension    *exten,
127                       gpointer         user_data)
128 {
129 	peas_extension_call (exten, "deactivate");
130 }
131 
132 void
liferea_plugins_engine_set_default_signals(PeasExtensionSet * extensions,gpointer user_data)133 liferea_plugins_engine_set_default_signals (PeasExtensionSet *extensions,
134                                             gpointer user_data)
135 {
136 	g_signal_connect (extensions, "extension-added", G_CALLBACK (on_extension_added), user_data);
137 	g_signal_connect (extensions, "extension-removed", G_CALLBACK (on_extension_removed), user_data);
138 
139 	peas_extension_set_call (extensions, "activate");
140 }
141 
142 static void
liferea_plugins_engine_dispose(GObject * object)143 liferea_plugins_engine_dispose (GObject * object)
144 {
145 	LifereaPluginsEngine *engine = LIFEREA_PLUGINS_ENGINE (object);
146 
147 	if (engine->priv->plugin_settings) {
148 		g_object_unref (engine->priv->plugin_settings);
149 		engine->priv->plugin_settings = NULL;
150 	}
151 
152 	G_OBJECT_CLASS (liferea_plugins_engine_parent_class)->dispose (object);
153 }
154 
155 static void
liferea_plugins_engine_class_init(LifereaPluginsEngineClass * klass)156 liferea_plugins_engine_class_init (LifereaPluginsEngineClass * klass)
157 {
158 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
159 
160 	object_class->dispose = liferea_plugins_engine_dispose;
161 
162 	g_type_class_add_private (klass, sizeof (LifereaPluginsEnginePrivate));
163 }
164 
165 LifereaPluginsEngine *
liferea_plugins_engine_get_default(void)166 liferea_plugins_engine_get_default (void)
167 {
168 	if (!default_engine) {
169 		default_engine = LIFEREA_PLUGINS_ENGINE (g_object_new (LIFEREA_TYPE_PLUGINS_ENGINE, NULL));
170 		g_object_add_weak_pointer (G_OBJECT (default_engine), (gpointer) &default_engine);
171 	}
172 
173 	return default_engine;
174 }
175