4 // Stefan Bund <info@j32.de>
7 \brief PythonPublisher non-inline non-template implementation */
9 #include "PythonPublisher.hh"
10 //#include "PythonPublisher.ih"
14 #include <boost/python.hpp>
15 #include "Publisher.hh"
16 #include <QDesktopServices>
17 #include <QWebHistory>
20 //#include "PythonPublisher.mpp"
22 ///////////////////////////////cc.p////////////////////////////////////////
24 namespace py = boost::python;
26 struct pykit::PythonPublisher::Impl
28 boost::python::dict mainNamespace;
29 Publisher * pythonPublisher;
32 #define PYTHON_EXTERN_MODULE(module) \
33 extern "C" { void init ## module (); }
34 #define PYTHON_PREPARE_IMPORT(module) \
35 PyImport_AppendInittab(const_cast<char*>(#module), init ## module)
39 struct PublisherPyWrapper
40 : public pykit::Publisher, py::wrapper<pykit::Publisher>
42 virtual void publish(pykit::Request & request)
43 { get_override("publish")(request); }
48 struct QString_PyUnicode
50 static PyObject * convert(QString const & s)
52 std::wstring ws (s.toStdWString());
53 return PyUnicode_FromWideChar(ws.data(), ws.length());
57 struct PyUnicode_QString
59 static void * convertible(PyObject * o)
61 return PyUnicode_Check(o) ? o : 0;
64 static void construct(PyObject * o,
65 py::converter::rvalue_from_python_stage1_data * data)
67 unsigned length (PyUnicode_GetSize(o));
68 std::wstring ws (length, 0);
69 // Hmm ... I don't want to copy the stupid data TWICE but this
70 // breaks the standard ... who cares ?
71 PyUnicode_AsWideChar(reinterpret_cast<PyUnicodeObject *>(o),
72 const_cast<wchar_t*>(ws.data()),
74 void * storage (((py::converter::rvalue_from_python_storage<QString>*)
75 data)->storage.bytes);
76 *(new (storage) QString()) = QString::fromStdWString(ws);
77 data->convertible = storage;
82 py::converter::registry::push_back(
85 py::type_id<QString>());
89 struct QByteArray_PyString
91 static PyObject * convert(QByteArray const & s)
93 return boost::python::incref(boost::python::object(s.constData()).ptr());
97 struct PyString_QByteArray
99 static void * convertible(PyObject * o)
101 return PyString_Check(o) ? o : 0;
104 static void construct(PyObject * o,
105 py::converter::rvalue_from_python_stage1_data * data)
107 unsigned length (PyString_Size(o));
108 const char * value (PyString_AsString(o));
109 void * storage (((py::converter::rvalue_from_python_storage<QByteArray>*)
110 data)->storage.bytes);
111 new (storage) QByteArray(value,length);
112 data->convertible = storage;
115 PyString_QByteArray()
117 py::converter::registry::push_back(
120 py::type_id<QByteArray>());
126 QString QUrl_toString_noargs(QUrl const & url)
127 { return url.toString(); }
131 #define MEMFNP(ret, cls, nam, arg) static_cast<ret (cls::*)arg>(&cls::nam)
133 BOOST_PYTHON_MODULE(_qt)
135 py::to_python_converter<QString, pyconvert::QString_PyUnicode>();
136 pyconvert::PyUnicode_QString register_PyUnicode_QString;
138 py::to_python_converter<QByteArray, pyconvert::QByteArray_PyString>();
139 pyconvert::PyString_QByteArray register_PyString_QByteArray;
141 // Missing converters:
146 py::class_<QUrl>("QUrl", py::init<>())
147 // QUrl ( const QString & url )
148 .def(py::init<QString const &>())
149 // QUrl ( const QUrl & other )
150 .def(py::init<QUrl const &>())
151 // QUrl ( const QString & url, ParsingMode parsingMode )
152 // .def(init<QString const &, ParsingMode>())
154 // void addEncodedQueryItem ( const QByteArray & key, const QByteArray & value )
155 .def("addEncodedQueryItem",
156 MEMFNP(void, QUrl, addEncodedQueryItem,
157 ( const QByteArray & key, const QByteArray & value )))
158 // void addQueryItem ( const QString & key, const QString & value )
160 MEMFNP(void, QUrl, addQueryItem,
161 ( const QString & key, const QString & value )))
162 // QList<QByteArray> allEncodedQueryItemValues ( const QByteArray & key ) const
163 // .def("allEncodedQueryItemValues",
164 // MEMFNP(QList<QByteArray>, QUrl, allEncodedQueryItemValues,
165 // ( const QByteArray & key ) const))
166 // QStringList allQueryItemValues ( const QString & key ) const
167 // .def("allQueryItemValues",
168 // MEMFNP(QStringList, QUrl, allQueryItemValues,
169 // ( const QString & key ) const))
170 // QString authority () const
172 MEMFNP(QString, QUrl, authority,
176 MEMFNP(void, QUrl, clear,
178 // QByteArray encodedFragment () const
179 .def("encodedFragment",
180 MEMFNP(QByteArray, QUrl, encodedFragment,
182 // QByteArray encodedHost () const
184 MEMFNP(QByteArray, QUrl, encodedHost,
186 // QByteArray encodedPassword () const
187 .def("encodedPassword",
188 MEMFNP(QByteArray, QUrl, encodedPassword,
190 // QByteArray encodedPath () const
192 MEMFNP(QByteArray, QUrl, encodedPath,
194 // QByteArray encodedQuery () const
196 MEMFNP(QByteArray, QUrl, encodedQuery,
198 // QByteArray encodedQueryItemValue ( const QByteArray & key ) const
199 .def("encodedQueryItemValue",
200 MEMFNP(QByteArray, QUrl, encodedQueryItemValue,
201 ( const QByteArray & key ) const))
202 // QList<QPair<QByteArray, QByteArray> > encodedQueryItems () const
203 // .def("encodedQueryItems",
204 // MEMFNP(QList<QPair<QByteArray, QByteArray> >, QUrl, encodedQueryItems,
206 // QByteArray encodedUserName () const
207 .def("encodedUserName",
208 MEMFNP(QByteArray, QUrl, encodedUserName,
210 // QString errorString () const
212 MEMFNP(QString, QUrl, errorString,
214 // QString fragment () const
216 MEMFNP(QString, QUrl, fragment,
218 // bool hasEncodedQueryItem ( const QByteArray & key ) const
219 .def("hasEncodedQueryItem",
220 MEMFNP(bool, QUrl, hasEncodedQueryItem,
221 ( const QByteArray & key ) const))
222 // bool hasFragment () const
224 MEMFNP(bool, QUrl, hasFragment,
226 // bool hasQuery () const
228 MEMFNP(bool, QUrl, hasQuery,
230 // bool hasQueryItem ( const QString & key ) const
232 MEMFNP(bool, QUrl, hasQueryItem,
233 ( const QString & key ) const))
234 // QString host () const
236 MEMFNP(QString, QUrl, host,
238 // bool isEmpty () const
240 MEMFNP(bool, QUrl, isEmpty,
242 // bool isParentOf ( const QUrl & childUrl ) const
244 MEMFNP(bool, QUrl, isParentOf,
245 ( const QUrl & childUrl ) const))
246 // bool isRelative () const
248 MEMFNP(bool, QUrl, isRelative,
250 // bool isValid () const
252 MEMFNP(bool, QUrl, isValid,
254 // QString password () const
256 MEMFNP(QString, QUrl, password,
258 // QString path () const
260 MEMFNP(QString, QUrl, path,
264 MEMFNP(int, QUrl, port,
266 // int port ( int defaultPort ) const
268 MEMFNP(int, QUrl, port,
269 ( int defaultPort ) const))
270 // QString queryItemValue ( const QString & key ) const
271 .def("queryItemValue",
272 MEMFNP(QString, QUrl, queryItemValue,
273 ( const QString & key ) const))
274 // QList<QPair<QString, QString> > queryItems () const
275 // .def("queryItems",
276 // MEMFNP(QList<QPair<QString, QString> >, QUrl, queryItems,
278 // char queryPairDelimiter () const
279 .def("queryPairDelimiter",
280 MEMFNP(char, QUrl, queryPairDelimiter,
282 // char queryValueDelimiter () const
283 .def("queryValueDelimiter",
284 MEMFNP(char, QUrl, queryValueDelimiter,
286 // void removeAllEncodedQueryItems ( const QByteArray & key )
287 .def("removeAllEncodedQueryItems",
288 MEMFNP(void, QUrl, removeAllEncodedQueryItems,
289 ( const QByteArray & key )))
290 // void removeAllQueryItems ( const QString & key )
291 .def("removeAllQueryItems",
292 MEMFNP(void, QUrl, removeAllQueryItems,
293 ( const QString & key )))
294 // void removeEncodedQueryItem ( const QByteArray & key )
295 .def("removeEncodedQueryItem",
296 MEMFNP(void, QUrl, removeEncodedQueryItem,
297 ( const QByteArray & key )))
298 // void removeQueryItem ( const QString & key )
299 .def("removeQueryItem",
300 MEMFNP(void, QUrl, removeQueryItem,
301 ( const QString & key )))
302 // QUrl resolved ( const QUrl & relative ) const
304 MEMFNP(QUrl, QUrl, resolved,
305 ( const QUrl & relative ) const))
306 // QString scheme () const
308 MEMFNP(QString, QUrl, scheme,
310 // void setAuthority ( const QString & authority )
312 MEMFNP(void, QUrl, setAuthority,
313 ( const QString & authority )))
314 // void setEncodedFragment ( const QByteArray & fragment )
315 .def("setEncodedFragment",
316 MEMFNP(void, QUrl, setEncodedFragment,
317 ( const QByteArray & fragment )))
318 // void setEncodedHost ( const QByteArray & host )
319 .def("setEncodedHost",
320 MEMFNP(void, QUrl, setEncodedHost,
321 ( const QByteArray & host )))
322 // void setEncodedPassword ( const QByteArray & password )
323 .def("setEncodedPassword",
324 MEMFNP(void, QUrl, setEncodedPassword,
325 ( const QByteArray & password )))
326 // void setEncodedPath ( const QByteArray & path )
327 .def("setEncodedPath",
328 MEMFNP(void, QUrl, setEncodedPath,
329 ( const QByteArray & path )))
330 // void setEncodedQuery ( const QByteArray & query )
331 .def("setEncodedQuery",
332 MEMFNP(void, QUrl, setEncodedQuery,
333 ( const QByteArray & query )))
334 // void setEncodedQueryItems ( const QList<QPair<QByteArray, QByteArray> > & query )
335 // .def("setEncodedQueryItems",
336 // MEMFNP(void, QUrl, setEncodedQueryItems,
337 // ( const QList<QPair<QByteArray, QByteArray> > & query )))
338 // void setEncodedUrl ( const QByteArray & encodedUrl )
339 .def("setEncodedUrl",
340 MEMFNP(void, QUrl, setEncodedUrl,
341 ( const QByteArray & encodedUrl )))
342 // void setEncodedUrl ( const QByteArray & encodedUrl, ParsingMode parsingMode )
343 // .def("setEncodedUrl",
344 // MEMFNP(void, QUrl, setEncodedUrl,
345 // ( const QByteArray & encodedUrl, ParsingMode parsingMode )))
346 // void setEncodedUserName ( const QByteArray & userName )
347 .def("setEncodedUserName",
348 MEMFNP(void, QUrl, setEncodedUserName,
349 ( const QByteArray & userName )))
350 // void setFragment ( const QString & fragment )
352 MEMFNP(void, QUrl, setFragment,
353 ( const QString & fragment )))
354 // void setHost ( const QString & host )
356 MEMFNP(void, QUrl, setHost,
357 ( const QString & host )))
358 // void setPassword ( const QString & password )
360 MEMFNP(void, QUrl, setPassword,
361 ( const QString & password )))
362 // void setPath ( const QString & path )
364 MEMFNP(void, QUrl, setPath,
365 ( const QString & path )))
366 // void setPort ( int port )
368 MEMFNP(void, QUrl, setPort,
370 // void setQueryDelimiters ( char valueDelimiter, char pairDelimiter )
371 .def("setQueryDelimiters",
372 MEMFNP(void, QUrl, setQueryDelimiters,
373 ( char valueDelimiter, char pairDelimiter )))
374 // void setQueryItems ( const QList<QPair<QString, QString> > & query )
375 // .def("setQueryItems",
376 // MEMFNP(void, QUrl, setQueryItems,
377 // ( const QList<QPair<QString, QString> > & query )))
378 // void setScheme ( const QString & scheme )
380 MEMFNP(void, QUrl, setScheme,
381 ( const QString & scheme )))
382 // void setUrl ( const QString & url )
384 MEMFNP(void, QUrl, setUrl,
385 ( const QString & url )))
386 // void setUrl ( const QString & url, ParsingMode parsingMode )
388 // MEMFNP(void, QUrl, setUrl,
389 // ( const QString & url, ParsingMode parsingMode )))
390 // void setUserInfo ( const QString & userInfo )
392 MEMFNP(void, QUrl, setUserInfo,
393 ( const QString & userInfo )))
394 // void setUserName ( const QString & userName )
396 MEMFNP(void, QUrl, setUserName,
397 ( const QString & userName )))
398 // QByteArray toEncoded ( FormattingOptions options = None ) const
400 // MEMFNP(QByteArray, QUrl, toEncoded,
401 // ( FormattingOptions options = None ) const))
402 // QString toLocalFile () const
404 MEMFNP(QString, QUrl, toLocalFile,
406 // QString toString ( FormattingOptions options = None ) const
407 .def("__unicode__", &QUrl_toString_noargs)
408 // QString userInfo () const
410 MEMFNP(QString, QUrl, userInfo,
412 // QString userName () const
414 MEMFNP(QString, QUrl, userName,
417 // bool operator!= ( const QUrl & url ) const
418 // QUrl & operator= ( const QUrl & url )
419 // QUrl & operator= ( const QString & url )
420 // bool operator== ( const QUrl & url ) const
428 return pykit::Viewer::instance()->page()->history()->canGoBack();
433 return pykit::Viewer::instance()->page()->history()->canGoForward();
439 explicit ErrorCatcher(std::string & out) : out_ (out) {}
440 void write(std::string const & msg)
441 { std::cerr << "append: " << msg; out_ += msg; }
448 BOOST_PYTHON_MODULE(_pykit)
450 py::class_<pykit::Request>("Request", py::no_init)
451 .def("write", &pykit::Request::write)
452 .def("reset", &pykit::Request::reset)
453 .def("setContentType", &pykit::Request::setContentType)
454 .def("setLocation", &pykit::Request::setLocation)
455 .def("setRawHeader", &pykit::Request::setHeader)
456 .def("setStatusCode", &pykit::Request::setStatusCode)
457 .def("url", &pykit::Request::url)
458 .def("postData", &pykit::Request::postData)
459 .def("operation", &pykit::Request::operation)
460 .def("postContentType", &pykit::Request::postContentType)
463 py::class_<PublisherPyWrapper, boost::noncopyable>("Publisher")
464 .def("publish", py::pure_virtual(&pykit::Publisher::publish))
467 py::class_<ErrorCatcher>("ErrorCatcher", py::no_init)
468 .def("write", &ErrorCatcher::write)
471 py::def("openUrl", &QDesktopServices::openUrl);
473 py::def("canGoBack", &canGoBack);
474 py::def("canGoForward", &canGoForward);
477 PYTHON_EXTERN_MODULE(_httpapi);
479 prefix_ pykit::PythonPublisher::PythonPublisher()
484 PYTHON_PREPARE_IMPORT(_pykit);
485 PYTHON_PREPARE_IMPORT(_qt);
486 PYTHON_PREPARE_IMPORT(_httpapi);
489 py::import("_pykit");
490 py::object sysModule (py::import("sys"));
491 py::object origStderr (sysModule.attr("stderr"));
492 ErrorCatcher catcher (pyError);
493 sysModule.attr("stderr") = catcher;
495 py::object initModule (py::import("init"));
496 impl_->mainNamespace = py::extract<py::dict>(initModule.attr("__dict__"));
497 impl_->pythonPublisher = py::extract<Publisher*>(impl_->mainNamespace["initialize"]());
499 sysModule.attr("stderr") = origStderr;
501 catch (boost::python::error_already_set & ex) {
503 throw PythonError(pyError);
507 prefix_ pykit::PythonPublisher::~PythonPublisher()
510 impl_->mainNamespace["shutdown"]();
515 prefix_ void pykit::PythonPublisher::publish(Request & request)
518 impl_->pythonPublisher->publish(request);
520 catch (py::error_already_set & ex) {
526 ///////////////////////////////cc.e////////////////////////////////////////
528 //#include "PythonPublisher.mpp"
534 // comment-column: 40
535 // c-file-style: "j32"
536 // indent-tabs-mode: nil
537 // ispell-local-dictionary: "american"
538 // compile-command: "scons -U"