2
* Copyright Ā© 2003 Marco Pesenti Gritti
3
* Copyright Ā© 2003 Christian Persch
4
* Copyright Ā© 2004, 2005 Adam Hooper
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2, or (at your option)
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27
#include "ephy-python-extension.h"
28
#include "ephy-python.h"
30
#define NO_IMPORT_PYGOBJECT
31
#include <pygobject.h>
33
#include "ephy-extension.h"
34
#include "ephy-window.h"
35
#include "ephy-file-helpers.h"
36
#include "ephy-debug.h"
38
static void ephy_python_extension_iface_init (EphyExtensionIface *iface);
40
#define EPHY_PYTHON_EXTENSION_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_PYTHON_EXTENSION, EphyPythonExtensionPrivate))
42
struct _EphyPythonExtensionPrivate
55
set_python_search_path (const char *filename)
63
sys_path = PySys_GetObject ("path");
65
/* Systems extensions dir */
66
pValue = PyString_FromString (EXTENSIONS_DIR);
67
PyList_Insert (sys_path, 0, pValue);
71
dot_dir = g_strconcat (ephy_dot_dir (), "/extensions", NULL);
72
pValue = PyString_FromString (dot_dir);
73
PyList_Insert (sys_path, 0, pValue);
77
/* Absolute path specified in .xml file */
78
dirname = g_path_get_dirname (filename);
79
if (g_path_is_absolute (dirname))
81
pValue = PyString_FromString (dirname);
82
PyList_Insert (sys_path, 0, pValue);
92
unset_python_search_path (int num_dirs)
94
PyObject *sys_path = PySys_GetObject ("path");
96
PySequence_DelSlice (sys_path, 0, num_dirs);
100
ephy_python_extension_init (EphyPythonExtension *extension)
102
LOG ("EphyPythonExtension initialising");
104
extension->priv = EPHY_PYTHON_EXTENSION_GET_PRIVATE (extension);
108
call_python_func (EphyExtension *extension,
109
const char *func_name,
111
EphyEmbed *embed) /* HACK: tab may be NULL */
113
PyObject *pDict, *pFunc;
114
PyObject *pArgs, *pValue, *pEmbed = NULL, *pWindow;
115
EphyPythonExtension *py_ext;
117
py_ext = EPHY_PYTHON_EXTENSION (extension);
119
/* Happens if the module load fails, e.g. python couldn't
120
* parse it, so be quiet about it, we will have already warned */
121
if (py_ext->priv->module == NULL)
126
pDict = PyModule_GetDict (py_ext->priv->module);
127
pFunc = PyDict_GetItemString (pDict, func_name);
129
if (pFunc && PyCallable_Check (pFunc))
131
pArgs = PyTuple_New (embed == NULL ? 1 : 2);
133
pWindow = pygobject_new (G_OBJECT (window));
134
PyTuple_SetItem (pArgs, 0, pWindow);
138
pEmbed = pygobject_new (G_OBJECT (embed));
139
PyTuple_SetItem (pArgs, 1, pEmbed);
142
pValue = PyObject_CallObject (pFunc, pArgs);
147
g_warning ("Python code for '%s' failed to execute",
155
if (PyErr_Occurred ())
164
impl_attach_tab (EphyExtension *extension,
168
call_python_func (extension, "attach_tab", window, embed);
172
impl_detach_tab (EphyExtension *extension,
176
call_python_func (extension, "detach_tab", window, embed);
178
ephy_python_schedule_gc ();
182
impl_attach_window (EphyExtension *extension,
185
call_python_func (extension, "attach_window", window, NULL);
189
impl_detach_window (EphyExtension *extension,
192
call_python_func (extension, "detach_window", window, NULL);
194
ephy_python_schedule_gc ();
198
ephy_python_extension_iface_init (EphyExtensionIface *iface)
200
iface->attach_tab = impl_attach_tab;
201
iface->detach_tab = impl_detach_tab;
202
iface->attach_window = impl_attach_window;
203
iface->detach_window = impl_detach_window;
206
G_DEFINE_TYPE_WITH_CODE (EphyPythonExtension, ephy_python_extension, G_TYPE_OBJECT,
207
G_IMPLEMENT_INTERFACE (EPHY_TYPE_EXTENSION,
208
ephy_python_extension_iface_init))
211
ephy_python_extension_constructor (GType type,
212
guint n_construct_properties,
213
GObjectConstructParam *construct_params)
216
EphyPythonExtension *ext;
217
char *module_name; /* filename minus optional ".py" */
218
/* Note: could equally be a directory */
219
PyObject *pModules, *pModule, *pReload;
223
object = G_OBJECT_CLASS (ephy_python_extension_parent_class)->constructor (type,
224
n_construct_properties,
227
ext = EPHY_PYTHON_EXTENSION (object);
229
module_name = g_path_get_basename (ext->priv->filename);
231
num_temp_paths = set_python_search_path (ext->priv->filename);
233
pModules = PySys_GetObject ("modules");
234
g_assert (pModules != NULL);
236
pModule = PyDict_GetItemString (pModules, module_name);
240
pModule = PyImport_ImportModule (module_name);
246
g_warning ("Could not initialize Python module '%s'",
252
pReload = PyImport_ReloadModule (pModule);
258
g_warning ("Could not reload Python module '%s'\n"
259
"Falling back to previous version",
268
unset_python_search_path (num_temp_paths);
270
ext->priv->module = pModule;
272
g_free (module_name);
278
ephy_python_extension_finalize (GObject *object)
280
EphyPythonExtension *extension =
281
EPHY_PYTHON_EXTENSION (object);
283
LOG ("EphyPythonExtension finalizing");
285
g_free (extension->priv->filename);
286
Py_XDECREF (extension->priv->module);
288
G_OBJECT_CLASS (ephy_python_extension_parent_class)->finalize (object);
292
ephy_python_extension_get_property (GObject *object,
297
/* no readable properties */
298
g_return_if_reached ();
302
ephy_python_extension_set_property (GObject *object,
307
EphyPythonExtension *ext = EPHY_PYTHON_EXTENSION (object);
312
ext->priv->filename = g_value_dup_string (value);
315
g_return_if_reached ();
320
ephy_python_extension_class_init (EphyPythonExtensionClass *klass)
322
GObjectClass *object_class = G_OBJECT_CLASS (klass);
324
object_class->finalize = ephy_python_extension_finalize;
325
object_class->constructor = ephy_python_extension_constructor;
326
object_class->get_property = ephy_python_extension_get_property;
327
object_class->set_property = ephy_python_extension_set_property;
329
g_object_class_install_property
332
g_param_spec_string ("filename",
336
G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_CONSTRUCT_ONLY));
338
g_type_class_add_private (object_class, sizeof (EphyPythonExtensionPrivate));