diff --git a/src/backends/python/CMakeLists.txt b/src/backends/python/CMakeLists.txt --- a/src/backends/python/CMakeLists.txt +++ b/src/backends/python/CMakeLists.txt @@ -6,6 +6,7 @@ pythonhighlighter.cpp pythoncompletionobject.cpp pythonextensions.cpp + pythondbussession.cpp ) qt5_add_resources(PythonBackend_RSCS python.qrc) @@ -17,7 +18,8 @@ cantorlibs KF5::KIOCore KF5::ConfigCore - KF5::ConfigGui) + KF5::ConfigGui + Qt5::DBus) install(TARGETS cantor_pythonbackend DESTINATION ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) #install(DIRECTORY . DESTINATION ${KDE_INSTALL_DATADIR}/cantor/pythonbackend FILES_MATCHING PATTERN "*.py") diff --git a/src/backends/python2/python2session.h b/src/backends/python/pythondbussession.h copy from src/backends/python2/python2session.h copy to src/backends/python/pythondbussession.h --- a/src/backends/python2/python2session.h +++ b/src/backends/python/pythondbussession.h @@ -1,4 +1,4 @@ -/* + /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 @@ -15,36 +15,37 @@ Boston, MA 02110-1301, USA. --- - Copyright (C) 2015 Minh Ngo - */ + Copyright (C) 2018 Nikita Sirgienko +*/ -#ifndef _PYTHON2SESSION_H -#define _PYTHON2SESSION_H +#ifndef _PYTHONDBUSSESSION_H +#define _PYTHONDBUSSESSION_H -#include "../python/pythonsession.h" +#include "pythonsession.h" -struct _object; -typedef _object PyObject; +class QDBusInterface; +class KProcess; -class Python2Session : public PythonSession +class CANTOR_EXPORT PythonDbusSession : public PythonSession { public: - Python2Session(Cantor::Backend* backend); + PythonDbusSession(Cantor::Backend* backend, const QString serverName, const QString DbusChannelName); + ~PythonDbusSession(); void login() Q_DECL_OVERRIDE; + void logout() Q_DECL_OVERRIDE; + void interrupt() Q_DECL_OVERRIDE; - bool integratePlots() const Q_DECL_OVERRIDE; - QStringList autorunScripts() const Q_DECL_OVERRIDE; - - private: + protected: void runPythonCommand(const QString& command) const Q_DECL_OVERRIDE; QString getOutput() const Q_DECL_OVERRIDE; QString getError() const Q_DECL_OVERRIDE; - QString pyObjectToQString(PyObject* obj) const; - - private: - PyObject *m_pModule; + protected: + QDBusInterface* m_pIface; + KProcess* m_pProcess; + QString serverName; + QString DbusChannelName; }; #endif diff --git a/src/backends/python3/python3session.cpp b/src/backends/python/pythondbussession.cpp copy from src/backends/python3/python3session.cpp copy to src/backends/python/pythondbussession.cpp --- a/src/backends/python3/python3session.cpp +++ b/src/backends/python/pythondbussession.cpp @@ -15,36 +15,43 @@ Boston, MA 02110-1301, USA. --- - Copyright (C) 2015 Minh Ngo - */ + Copyright (C) 2018 Nikita Sirgienko +*/ -#include "python3session.h" -#include "settings.h" -#include "../python/pythonexpression.h" + +#include "pythondbussession.h" +#include "pythonexpression.h" #include +#include #include #include #include #include -Python3Session::Python3Session(Cantor::Backend* backend) +PythonDbusSession::PythonDbusSession(Cantor::Backend* backend, const QString serverName, const QString DbusChannelName) : PythonSession(backend) , m_pIface(nullptr) , m_pProcess(nullptr) + , serverName(serverName) + , DbusChannelName(DbusChannelName) +{ +} + +PythonDbusSession::~PythonDbusSession() { } -void Python3Session::login() +void PythonDbusSession::login() { if (m_pProcess) m_pProcess->deleteLater(); m_pProcess = new KProcess(this); m_pProcess->setOutputChannelMode(KProcess::SeparateChannels); - (*m_pProcess) << QStandardPaths::findExecutable(QLatin1String("cantor_python3server")); + (*m_pProcess) << QStandardPaths::findExecutable(serverName); m_pProcess->start(); @@ -67,7 +74,7 @@ return; } - const QString& serviceName = QString::fromLatin1("org.kde.Cantor.Python3-%1").arg(m_pProcess->pid()); + const QString& serviceName = DbusChannelName + QString::fromLatin1("-%1").arg(m_pProcess->pid()); m_pIface = new QDBusInterface(serviceName, QString::fromLatin1("/"), QString(), QDBusConnection::sessionBus()); @@ -82,59 +89,39 @@ PythonSession::login(); } -void Python3Session::logout() +void PythonDbusSession::logout() { m_pProcess->terminate(); PythonSession::logout(); } -void Python3Session::interrupt() +void PythonDbusSession::interrupt() { if (m_pProcess->pid()) m_pProcess->kill(); PythonSession::interrupt(); } -void Python3Session::runPythonCommand(const QString& command) const +void PythonDbusSession::runPythonCommand(const QString& command) const { m_pIface->call(QString::fromLatin1("runPythonCommand"), command); } -void Python3Session::readExpressionOutput(const QString& commandProcessing) -{ - runClassOutputPython(); - runPythonCommand(commandProcessing); - m_output = getOutput(); - m_error = getError(); - - updateOutput(); -} - -QString Python3Session::getOutput() const +QString PythonDbusSession::getOutput() const { const QDBusReply& reply = m_pIface->call(QString::fromLatin1("getOutput")); if (reply.isValid()) return reply.value(); return reply.error().message(); } -QString Python3Session::getError() const +QString PythonDbusSession::getError() const { const QDBusReply& reply = m_pIface->call(QString::fromLatin1("getError")); if (reply.isValid()) return reply.value(); return reply.error().message(); } - -bool Python3Session::integratePlots() const -{ - return PythonSettings::integratePlots(); -} - -QStringList Python3Session::autorunScripts() const -{ - return PythonSettings::autorunScripts(); -} diff --git a/src/backends/python3/python3server/python3server.h b/src/backends/python/pythonserver.h rename from src/backends/python3/python3server/python3server.h rename to src/backends/python/pythonserver.h --- a/src/backends/python3/python3server/python3server.h +++ b/src/backends/python/pythonserver.h @@ -18,19 +18,19 @@ Copyright (C) 2015 Minh Ngo */ -#ifndef _PYTHON3SERVER_H -#define _PYTHON3SERVER_H +#ifndef _PYTHONSERVER_H +#define _PYTHONSERVER_H #include #include struct _object; typedef _object PyObject; -class Python3Server : public QObject +class PythonServer : public QObject { Q_OBJECT public: - Python3Server(QObject* parent = nullptr); + PythonServer(QObject* parent = nullptr); public Q_SLOTS: Q_SCRIPTABLE void login(); diff --git a/src/backends/python3/python3server/python3server.cpp b/src/backends/python/pythonserver.cpp rename from src/backends/python3/python3server/python3server.cpp rename to src/backends/python/pythonserver.cpp --- a/src/backends/python3/python3server/python3server.cpp +++ b/src/backends/python/pythonserver.cpp @@ -18,43 +18,49 @@ Copyright (C) 2015 Minh Ngo */ -#include "python3server.h" +#include "pythonserver.h" #include -Python3Server::Python3Server(QObject* parent) +PythonServer::PythonServer(QObject* parent) : QObject(parent) { } namespace { QString pyObjectToQString(PyObject* obj) { +#if PY_MAJOR_VERSION == 3 return QString::fromUtf8(PyUnicode_AsUTF8(obj)); +#elif PY_MAJOR_VERSION == 2 + return QString::fromLocal8Bit(PyString_AsString(obj)); +#else + #warning Unknown Python version +#endif } } -void Python3Server::login() +void PythonServer::login() { Py_Initialize(); m_pModule = PyImport_AddModule("__main__"); } -void Python3Server::runPythonCommand(const QString& command) const +void PythonServer::runPythonCommand(const QString& command) const { PyRun_SimpleString(command.toStdString().c_str()); } -QString Python3Server::getError() const +QString PythonServer::getError() const { PyObject *errorPython = PyObject_GetAttrString(m_pModule, "errorPythonBackend"); PyObject *error = PyObject_GetAttrString(errorPython, "value"); return pyObjectToQString(error); } -QString Python3Server::getOutput() const +QString PythonServer::getOutput() const { PyObject *outputPython = PyObject_GetAttrString(m_pModule, "outputPythonBackend"); PyObject *output = PyObject_GetAttrString(outputPython, "value"); diff --git a/src/backends/python2/CMakeLists.txt b/src/backends/python2/CMakeLists.txt --- a/src/backends/python2/CMakeLists.txt +++ b/src/backends/python2/CMakeLists.txt @@ -29,3 +29,5 @@ install(FILES cantor_python2.knsrc DESTINATION ${KDE_INSTALL_CONFDIR}) install(FILES python2backend.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) + +add_subdirectory(python2server) \ No newline at end of file diff --git a/src/backends/python2/python2server/CMakeLists.txt b/src/backends/python2/python2server/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/backends/python2/python2server/CMakeLists.txt @@ -0,0 +1,16 @@ +include_directories(${PYTHON_INCLUDE_DIR}) + +set(Python2Server_SRCS + main.cpp + ../../python/pythonserver.cpp +) + +add_executable(cantor_python2server ${Python2Server_SRCS}) + +set_target_properties(cantor_python2server PROPERTIES INSTALL_RPATH_USE_LINK_PATH false) +target_link_libraries(cantor_python2server + ${PYTHON_LIBRARIES} + Qt5::Widgets + Qt5::DBus) + +install(TARGETS cantor_python2server ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/backends/python3/python3server/main.cpp b/src/backends/python2/python2server/main.cpp copy from src/backends/python3/python3server/main.cpp copy to src/backends/python2/python2server/main.cpp --- a/src/backends/python3/python3server/main.cpp +++ b/src/backends/python2/python2server/main.cpp @@ -24,7 +24,7 @@ #include #include -#include "python3server.h" +#include "../../python/pythonserver.h" int main(int argc, char *argv[]) { @@ -37,15 +37,15 @@ return 1; } - const QString& serviceName = QString::fromLatin1("org.kde.Cantor.Python3-%1").arg(app.applicationPid()); + const QString& serviceName = QString::fromLatin1("org.kde.Cantor.Python2-%1").arg(app.applicationPid()); if (!QDBusConnection::sessionBus().registerService(serviceName)) { qDebug() << QDBusConnection::sessionBus().lastError().message(); return 2; } - Python3Server server; + PythonServer server; QDBusConnection::sessionBus().registerObject(QString::fromLatin1("/"), &server, QDBusConnection::ExportAllSlots); QTextStream(stdout) << "ready" << endl; diff --git a/src/backends/python2/python2session.h b/src/backends/python2/python2session.h --- a/src/backends/python2/python2session.h +++ b/src/backends/python2/python2session.h @@ -21,30 +21,15 @@ #ifndef _PYTHON2SESSION_H #define _PYTHON2SESSION_H -#include "../python/pythonsession.h" +#include "../python/pythondbussession.h" -struct _object; -typedef _object PyObject; - -class Python2Session : public PythonSession +class Python2Session : public PythonDbusSession { public: Python2Session(Cantor::Backend* backend); - void login() Q_DECL_OVERRIDE; - bool integratePlots() const Q_DECL_OVERRIDE; QStringList autorunScripts() const Q_DECL_OVERRIDE; - - private: - void runPythonCommand(const QString& command) const Q_DECL_OVERRIDE; - QString getOutput() const Q_DECL_OVERRIDE; - QString getError() const Q_DECL_OVERRIDE; - - QString pyObjectToQString(PyObject* obj) const; - - private: - PyObject *m_pModule; }; #endif diff --git a/src/backends/python2/python2session.cpp b/src/backends/python2/python2session.cpp --- a/src/backends/python2/python2session.cpp +++ b/src/backends/python2/python2session.cpp @@ -20,47 +20,18 @@ #include "python2session.h" #include "settings.h" +#include "../python/pythonexpression.h" -#include +#include +#include +#include +#include -Python2Session::Python2Session(Cantor::Backend* backend) - : PythonSession(backend) - , m_pModule(nullptr) -{ -} - -void Python2Session::runPythonCommand(const QString& command) const -{ - PyRun_SimpleString(command.toStdString().c_str()); -} - -void Python2Session::login() -{ - Py_Initialize(); - m_pModule = PyImport_AddModule("__main__"); - - PythonSession::login(); -} +#include -QString Python2Session::getOutput() const -{ - PyObject *outputPython = PyObject_GetAttrString(m_pModule, "outputPythonBackend"); - PyObject *output = PyObject_GetAttrString(outputPython, "value"); - - return pyObjectToQString(output); -} - -QString Python2Session::getError() const -{ - PyObject *errorPython = PyObject_GetAttrString(m_pModule, "errorPythonBackend"); - PyObject *error = PyObject_GetAttrString(errorPython, "value"); - - return pyObjectToQString(error); -} - -QString Python2Session::pyObjectToQString(PyObject* obj) const +Python2Session::Python2Session(Cantor::Backend* backend) + : PythonDbusSession(backend, QLatin1String("cantor_python2server"), QLatin1String("org.kde.Cantor.Python2")) { - return QString::fromLocal8Bit(PyString_AsString(obj)); } bool Python2Session::integratePlots() const diff --git a/src/backends/python3/python3server/CMakeLists.txt b/src/backends/python3/python3server/CMakeLists.txt --- a/src/backends/python3/python3server/CMakeLists.txt +++ b/src/backends/python3/python3server/CMakeLists.txt @@ -1,8 +1,8 @@ include_directories(${PYTHONLIBS3_INCLUDE_DIRS}) set(Python3Server_SRCS - python3server.cpp main.cpp + ../../python/pythonserver.cpp ) add_executable(cantor_python3server ${Python3Server_SRCS}) diff --git a/src/backends/python3/python3server/main.cpp b/src/backends/python3/python3server/main.cpp --- a/src/backends/python3/python3server/main.cpp +++ b/src/backends/python3/python3server/main.cpp @@ -24,7 +24,7 @@ #include #include -#include "python3server.h" +#include "../../python/pythonserver.h" int main(int argc, char *argv[]) { @@ -45,7 +45,7 @@ return 2; } - Python3Server server; + PythonServer server; QDBusConnection::sessionBus().registerObject(QString::fromLatin1("/"), &server, QDBusConnection::ExportAllSlots); QTextStream(stdout) << "ready" << endl; diff --git a/src/backends/python3/python3session.h b/src/backends/python3/python3session.h --- a/src/backends/python3/python3session.h +++ b/src/backends/python3/python3session.h @@ -21,36 +21,15 @@ #ifndef _PYTHON3SESSION_H #define _PYTHON3SESSION_H -#include "../python/pythonsession.h" +#include "../python/pythondbussession.h" -class QDBusInterface; -class KProcess; -class Python3Session : public PythonSession +class Python3Session : public PythonDbusSession { - Q_OBJECT public: Python3Session(Cantor::Backend* backend); - void login() override; - void logout() override; - void interrupt() override; - bool integratePlots() const override; QStringList autorunScripts() const override; - - private: - void runPythonCommand(const QString& command) const override; - void readExpressionOutput(const QString& commandProcessing) override; - - QString getOutput() const override; - QString getError() const override; - - private: - QDBusInterface* m_pIface; - KProcess* m_pProcess; - - Q_SIGNALS: - void updateHighlighter(); }; #endif diff --git a/src/backends/python3/python3session.cpp b/src/backends/python3/python3session.cpp --- a/src/backends/python3/python3session.cpp +++ b/src/backends/python3/python3session.cpp @@ -20,113 +20,10 @@ #include "python3session.h" #include "settings.h" -#include "../python/pythonexpression.h" - -#include -#include -#include -#include - -#include Python3Session::Python3Session(Cantor::Backend* backend) - : PythonSession(backend) - , m_pIface(nullptr) - , m_pProcess(nullptr) -{ -} - -void Python3Session::login() + : PythonDbusSession(backend, QLatin1String("cantor_python3server"), QLatin1String("org.kde.Cantor.Python3")) { - if (m_pProcess) - m_pProcess->deleteLater(); - - m_pProcess = new KProcess(this); - m_pProcess->setOutputChannelMode(KProcess::SeparateChannels); - - (*m_pProcess) << QStandardPaths::findExecutable(QLatin1String("cantor_python3server")); - - m_pProcess->start(); - - m_pProcess->waitForStarted(); - m_pProcess->waitForReadyRead(); - QTextStream stream(m_pProcess->readAllStandardOutput()); - - const QString& readyStatus = QString::fromLatin1("ready"); - while (m_pProcess->state() == QProcess::Running) - { - const QString& rl = stream.readLine(); - if (rl == readyStatus) - break; - } - - if (!QDBusConnection::sessionBus().isConnected()) - { - qWarning() << "Can't connect to the D-Bus session bus.\n" - "To start it, run: eval `dbus-launch --auto-syntax`"; - return; - } - - const QString& serviceName = QString::fromLatin1("org.kde.Cantor.Python3-%1").arg(m_pProcess->pid()); - - m_pIface = new QDBusInterface(serviceName, - QString::fromLatin1("/"), QString(), QDBusConnection::sessionBus()); - if (!m_pIface->isValid()) - { - qWarning() << QDBusConnection::sessionBus().lastError().message(); - return; - } - - m_pIface->call(QString::fromLatin1("login")); - - PythonSession::login(); -} - -void Python3Session::logout() -{ - m_pProcess->terminate(); - PythonSession::logout(); -} - -void Python3Session::interrupt() -{ - if (m_pProcess->pid()) - m_pProcess->kill(); - - PythonSession::interrupt(); -} - -void Python3Session::runPythonCommand(const QString& command) const -{ - m_pIface->call(QString::fromLatin1("runPythonCommand"), command); -} - -void Python3Session::readExpressionOutput(const QString& commandProcessing) -{ - runClassOutputPython(); - runPythonCommand(commandProcessing); - m_output = getOutput(); - m_error = getError(); - - updateOutput(); -} - -QString Python3Session::getOutput() const -{ - const QDBusReply& reply = m_pIface->call(QString::fromLatin1("getOutput")); - if (reply.isValid()) - return reply.value(); - - return reply.error().message(); -} - -QString Python3Session::getError() const -{ - const QDBusReply& reply = m_pIface->call(QString::fromLatin1("getError")); - if (reply.isValid()) - return reply.value(); - - return reply.error().message(); } bool Python3Session::integratePlots() const