Falkon Develop
Cross-platform Qt-based web browser
pythonplugin.cpp
Go to the documentation of this file.
1/* ============================================================
2* Falkon - Qt web browser
3* Copyright (C) 2018 David Rosca <nowrep@gmail.com>
4*
5* This program is free software: you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation, either version 3 of the License, or
8* (at your option) any later version.
9*
10* This program is distributed in the hope that it will be useful,
11* but WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17* ============================================================ */
18#include "pythonplugin.h"
19
20#include "datapaths.h"
21#include "desktopfile.h"
22
23#include <QDir>
24#include <QCoreApplication>
25
26#include <PyFalkon/pyfalkon_python.h>
27
28extern "C" PyObject *PyInit_PyFalkon();
29
31{
35};
36
38
40QHash<PyObject*, PluginInterface*> pluginInstances;
41
42static void cleanup()
43{
45 Py_Finalize();
47 }
48}
49
50static void set_path(const QStringList &scriptPaths)
51{
52 const QString originalPath = QString::fromLocal8Bit(qgetenv("PYTHONPATH"));
53
54 QStringList paths = scriptPaths;
55 paths.append(originalPath);
56
57 qputenv("PYTHONPATH", paths.join(QL1C(':')).toLocal8Bit());
58}
59
60static State init()
61{
63 return state;
64 }
65
67
68 if (PyImport_AppendInittab("Falkon", PyInit_PyFalkon) != 0) {
69 PyErr_Print();
70 qWarning() << "Failed to initialize Falkon module!";
71 return state = PythonError;
72 }
73
74 Py_Initialize();
75 qAddPostRoutine(cleanup);
76 return state = PythonInitialized;
77}
78
80{
81 pluginInterface = plugin;
82}
83
84void *pyfalkon_load_plugin(const QString &name)
85{
86 QString fullPath;
87 if (QFileInfo(name).isAbsolute()) {
88 fullPath = name;
89 } else {
90 fullPath = DataPaths::locate(DataPaths::Plugins, name);
91 if (fullPath.isEmpty()) {
92 qWarning() << "Python plugin" << name << "not found";
93 return nullptr;
94 }
95 }
96
97 Plugins::Plugin *plugin = new Plugins::Plugin;
99 plugin->pluginId = QSL("python:%1").arg(QFileInfo(name).fileName());
100 plugin->pluginPath = fullPath;
101 plugin->pluginSpec = Plugins::createSpec(DesktopFile(fullPath + QSL("/metadata.desktop")));
102 return plugin;
103}
104
106{
107 if (init() != PythonInitialized) {
108 return;
109 }
110
111 PyObject *module = static_cast<PyObject*>(plugin->data.value<void*>());
112 if (module) {
113 plugin->instance = pluginInstances.value(module);
114 return;
115 }
116
117 const QString moduleName = plugin->pluginId.mid(7);
118
119 pluginInterface = nullptr;
120
121 module = PyImport_ImportModule(qPrintable(moduleName));
122 if (!module) {
123 PyErr_Print();
124 qWarning() << "Failed to import module" << moduleName;
125 return;
126 }
127 if (!pluginInterface) {
128 qWarning() << "No plugin registered! Falkon.registerPlugin() must be called from script.";
129 return;
130 }
131
133 plugin->instance = pluginInterface;
134 plugin->data = QVariant::fromValue(static_cast<void*>(module));
135}
static QStringList allPaths(Path type)
Definition: datapaths.cpp:74
static QString locate(Path type, const QString &file)
Definition: datapaths.cpp:82
static PluginSpec createSpec(const QJsonObject &metaData)
Definition: plugins.cpp:172
void * pyfalkon_load_plugin(const QString &name)
PluginInterface * pluginInterface
State
@ PythonError
@ PythonInitialized
@ PythonUninitialized
State state
PyObject * PyInit_PyFalkon()
QHash< PyObject *, PluginInterface * > pluginInstances
void pyfalkon_register_plugin(PluginInterface *plugin)
void pyfalkon_init_plugin(Plugins::Plugin *plugin)
#define QL1C(x)
Definition: qzcommon.h:48
#define QSL(x)
Definition: qzcommon.h:40
QVariant data
Definition: plugins.h:75
QString pluginId
Definition: plugins.h:63
PluginSpec pluginSpec
Definition: plugins.h:65
QString pluginPath
Definition: plugins.h:64
PluginInterface * instance
Definition: plugins.h:66