+ simplify porting of Web module to Python3

This commit is contained in:
wmayer 2016-01-17 19:17:34 +01:00
parent 5aea3220c8
commit a467612b9f
6 changed files with 173 additions and 247 deletions

View File

@ -24,27 +24,118 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Python.h>
# include <climits>
# include <sstream>
#endif
#include <Base/Console.h>
#include <CXX/Extensions.hxx>
#include <CXX/Objects.hxx>
#include "Server.h"
/* registration table */
extern struct PyMethodDef Web_methods[];
// See http://docs.python.org/2/library/socketserver.html
/*
import socket
import threading
import SocketServer
PyDoc_STRVAR(module_Web_doc,
"This module is the Web module.");
ip = "127.0.0.1"
port=54880
def client(ip, port, message):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
try:
sock.sendall(message)
response = sock.recv(1024)
print "Received: {}".format(response)
finally:
sock.close()
client(ip, port, "print 'Hello World 1'")
client(ip, port, "import FreeCAD\nFreeCAD.newDocument()")
client(ip, port, "Hello World 3\n")
*/
namespace Web {
class Module : public Py::ExtensionModule<Module>
{
public:
Module() : Py::ExtensionModule<Module>("Web")
{
add_varargs_method("startServer",&Module::startServer,
"startServer(address=127.0.0.1,port=0) -- Start a server."
);
add_varargs_method("registerServerFirewall",&Module::registerServerFirewall,
"registerServerFirewall(callable(string)) -- Register a firewall."
);
initialize("This module is the Web module."); // register with Python
}
virtual ~Module() {}
private:
Py::Object startServer(const Py::Tuple& args)
{
const char* addr = "127.0.0.1";
int port=0;
if (!PyArg_ParseTuple(args.ptr(), "|si",&addr,&port))
throw Py::Exception();
if (port > USHRT_MAX) {
throw Py::OverflowError("port number is greater than maximum");
}
else if (port < 0) {
throw Py::OverflowError("port number is lower than 0");
}
AppServer* server = new AppServer();
if (server->listen(QHostAddress(QString::fromLatin1(addr)), port)) {
QString a = server->serverAddress().toString();
quint16 p = server->serverPort();
Py::Tuple t(2);
t.setItem(0, Py::String((const char*)a.toLatin1()));
t.setItem(1, Py::Int(p));
return t;
}
else {
server->deleteLater();
std::stringstream out;
out << "Server failed to listen at address " << addr << " and port " << port;
throw Py::RuntimeError(out.str());
}
return Py::None();
}
Py::Object registerServerFirewall(const Py::Tuple& args)
{
PyObject* obj;
if (!PyArg_ParseTuple(args.ptr(), "O",&obj))
throw Py::Exception();
Py::Object pyobj(obj);
if (pyobj.isNone())
Web::Firewall::setInstance(0);
else
Web::Firewall::setInstance(new Web::FirewallPython(pyobj));
return Py::None();
}
};
} // namespace Web
/* Python entry */
extern "C" {
void WebAppExport initWeb() {
PyMODINIT_FUNC initWeb() {
// ADD YOUR CODE HERE
//
//
(void) Py_InitModule3("Web", Web_methods, module_Web_doc); /* mod name, table ptr */
new Web::Module();
Base::Console().Log("Loading Web module... done\n");
}
} // extern "C"

View File

@ -1,129 +0,0 @@
/***************************************************************************
* Copyright (c) 2014 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include <Python.h>
#include <climits>
#include <Base/Console.h>
#include <Base/PyObjectBase.h>
#include <Base/Exception.h>
#include <CXX/Objects.hxx>
#include "Server.h"
using namespace Web;
// See http://docs.python.org/2/library/socketserver.html
/*
import socket
import threading
import SocketServer
ip = "127.0.0.1"
port=54880
def client(ip, port, message):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
try:
sock.sendall(message)
response = sock.recv(1024)
print "Received: {}".format(response)
finally:
sock.close()
client(ip, port, "print 'Hello World 1'")
client(ip, port, "import FreeCAD\nFreeCAD.newDocument()")
client(ip, port, "Hello World 3\n")
*/
/* module functions */
static PyObject * startServer(PyObject *self, PyObject *args)
{
const char* addr = "127.0.0.1";
int port=0;
if (!PyArg_ParseTuple(args, "|si",&addr,&port))
return NULL;
if (port > USHRT_MAX) {
PyErr_SetString(PyExc_OverflowError, "port number is greater than maximum");
return 0;
}
else if (port < 0) {
PyErr_SetString(PyExc_OverflowError, "port number is lower than 0");
return 0;
}
PY_TRY {
AppServer* server = new AppServer();
if (server->listen(QHostAddress(QString::fromLatin1(addr)), port)) {
QString a = server->serverAddress().toString();
quint16 p = server->serverPort();
Py::Tuple t(2);
t.setItem(0, Py::String((const char*)a.toLatin1()));
t.setItem(1, Py::Int(p));
return Py::new_reference_to(t);
}
else {
server->deleteLater();
PyErr_Format(PyExc_RuntimeError, "Server failed to listen at address %s and port %d", addr, port);
return 0;
}
} PY_CATCH;
Py_Return;
}
static PyObject * registerServerFirewall(PyObject *self, PyObject *args)
{
PyObject* obj;
if (!PyArg_ParseTuple(args, "O",&obj))
return NULL;
PY_TRY {
Py::Object pyobj(obj);
if (pyobj.isNone())
Web::Firewall::setInstance(0);
else
Web::Firewall::setInstance(new Web::FirewallPython(pyobj));
} PY_CATCH;
Py_Return;
}
/* registration table */
struct PyMethodDef Web_methods[] = {
{"startServer",startServer ,METH_VARARGS,
"startServer(address=127.0.0.1,port=0) -- Start a server."},
{"registerServerFirewall",registerServerFirewall ,METH_VARARGS,
"registerServerFirewall(callable(string)) -- Register a firewall."},
{NULL, NULL} /* end of table marker */
};

View File

@ -22,7 +22,6 @@ SOURCE_GROUP("Moc" FILES ${Web_MOC_SRCS})
SET(Web_SRCS
AppWeb.cpp
AppWebPy.cpp
PreCompiled.cpp
PreCompiled.h
Server.cpp

View File

@ -24,13 +24,18 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Python.h>
# include <QMdiArea>
# include <QMdiSubWindow>
# include <QUrl>
#endif
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <Gui/Application.h>
#include <Gui/MainWindow.h>
#include <Gui/WorkbenchManager.h>
#include <Gui/Language/Translator.h>
#include "BrowserView.h"
#include "Workbench.h"
@ -45,21 +50,83 @@ void loadWebResource()
Gui::Translator::instance()->refresh();
}
/* registration table */
extern struct PyMethodDef WebGui_Import_methods[];
namespace WebGui {
class Module : public Py::ExtensionModule<Module>
{
public:
Module() : Py::ExtensionModule<Module>("WebGui")
{
add_varargs_method("openBrowser",&Module::openBrowser
);
add_varargs_method("openBrowserHTML",&Module::openBrowserHTML
);
initialize("This module is the Web module."); // register with Python
}
virtual ~Module() {}
private:
Py::Object openBrowser(const Py::Tuple& args)
{
const char* url;
if (!PyArg_ParseTuple(args.ptr(), "s",&url))
throw Py::Exception();
WebGui::BrowserView* pcBrowserView;
pcBrowserView = new WebGui::BrowserView(Gui::getMainWindow());
pcBrowserView->setWindowTitle(QObject::tr("Browser"));
pcBrowserView->resize(400, 300);
pcBrowserView->load(url);
Gui::getMainWindow()->addWindow(pcBrowserView);
return Py::None();
}
Py::Object openBrowserHTML(const Py::Tuple& args)
{
const char* HtmlCode;
const char* BaseUrl;
const char* TabName = "Browser";
if (! PyArg_ParseTuple(args.ptr(), "ss|s",&HtmlCode,&BaseUrl,&TabName))
throw Py::Exception();
QMdiSubWindow* browserView = 0;
QMdiArea* mdiArea = Gui::getMainWindow()->findChild<QMdiArea*>();
QList<QMdiSubWindow *> mdiViews = mdiArea->subWindowList();
for (QList<QMdiSubWindow *>::iterator it = mdiViews.begin(); it != mdiViews.end(); ++it) {
if (qobject_cast<WebGui::BrowserView*>((*it)->widget())) {
browserView = *it;
break;
}
}
if (!browserView) {
WebGui::BrowserView* pcBrowserView = 0;
pcBrowserView = new WebGui::BrowserView(Gui::getMainWindow());
pcBrowserView->resize(400, 300);
pcBrowserView->setHtml(QString::fromUtf8(HtmlCode),QUrl(QString::fromLatin1(BaseUrl)),QString::fromUtf8(TabName));
Gui::getMainWindow()->addWindow(pcBrowserView);
}
else {
mdiArea->setActiveSubWindow(browserView);
}
return Py::None();
}
};
} // namespace WebGui
/* Python entry */
extern "C" {
void WebGuiExport initWebGui()
PyMODINIT_FUNC initWebGui()
{
if (!Gui::Application::Instance) {
PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application.");
return;
}
(void) Py_InitModule("WebGui", WebGui_Import_methods); /* mod name, table ptr */
new WebGui::Module();
Base::Console().Log("Loading GUI of Web module... done\n");
// instantiating the commands
@ -69,5 +136,3 @@ void WebGuiExport initWebGui()
// add resources and reloads the translators
loadWebResource();
}
} // extern "C" {

View File

@ -1,99 +0,0 @@
/***************************************************************************
* Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Python.h>
# include <QMdiArea>
# include <QMdiSubWindow>
# include <QUrl>
#endif
#include "BrowserView.h"
#include <Gui/Application.h>
#include <Gui/MainWindow.h>
/* module functions */
static PyObject *
openBrowser(PyObject *self, PyObject *args)
{
const char* Url;
if (! PyArg_ParseTuple(args, "s",&Url))
return NULL;
PY_TRY {
WebGui::BrowserView* pcBrowserView;
pcBrowserView = new WebGui::BrowserView(Gui::getMainWindow());
pcBrowserView->setWindowTitle(QObject::tr("Browser"));
pcBrowserView->resize(400, 300);
pcBrowserView->load(Url);
Gui::getMainWindow()->addWindow(pcBrowserView);
} PY_CATCH;
Py_Return;
}
static PyObject *
openBrowserHTML(PyObject *self, PyObject *args)
{
const char* HtmlCode;
const char* BaseUrl;
const char* TabName = "Browser";
if (! PyArg_ParseTuple(args, "ss|s",&HtmlCode,&BaseUrl,&TabName))
return NULL;
PY_TRY {
QMdiSubWindow* browserView = 0;
QMdiArea* mdiArea = Gui::getMainWindow()->findChild<QMdiArea*>();
QList<QMdiSubWindow *> mdiViews = mdiArea->subWindowList();
for (QList<QMdiSubWindow *>::iterator it = mdiViews.begin(); it != mdiViews.end(); ++it) {
if (qobject_cast<WebGui::BrowserView*>((*it)->widget())) {
browserView = *it;
break;
}
}
if (!browserView) {
WebGui::BrowserView* pcBrowserView = 0;
pcBrowserView = new WebGui::BrowserView(Gui::getMainWindow());
pcBrowserView->resize(400, 300);
pcBrowserView->setHtml(QString::fromUtf8(HtmlCode),QUrl(QString::fromLatin1(BaseUrl)),QString::fromUtf8(TabName));
Gui::getMainWindow()->addWindow(pcBrowserView);
}
else {
mdiArea->setActiveSubWindow(browserView);
}
} PY_CATCH;
Py_Return;
}
/* registration table */
struct PyMethodDef WebGui_Import_methods[] = {
{"openBrowser" ,openBrowser , 1}, /* method name, C func ptr, always-tuple */
{"openBrowserHTML" ,openBrowserHTML , 1}, /* method name, C func ptr, always-tuple */
{NULL, NULL} /* end of table marker */
};

View File

@ -17,7 +17,6 @@ qt4_add_resources(Web_QRC_SRCS Resources/Web.qrc)
SET(WebGui_SRCS
${Web_QRC_SRCS}
AppWebGui.cpp
AppWebGuiPy.cpp
Command.cpp
PreCompiled.cpp
PreCompiled.h