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>
18 //#include "PythonPublisher.mpp"
20 ///////////////////////////////cc.p////////////////////////////////////////
22 namespace py = boost::python;
24 struct pykit::PythonPublisher::Impl
26 boost::python::dict mainNamespace;
27 Publisher * pythonPublisher;
30 #define PYTHON_EXTERN_MODULE(module) \
31 extern "C" { void init ## module (); }
32 #define PYTHON_PREPARE_IMPORT(module) \
33 PyImport_AppendInittab(const_cast<char*>(#module), init ## module)
37 struct PublisherPyWrapper
38 : public pykit::Publisher, py::wrapper<pykit::Publisher>
40 virtual void publish(pykit::Request & request)
41 { get_override("publish")(request); }
46 struct QString_PyUnicode
48 static PyObject * convert(QString const & s)
50 std::wstring ws (s.toStdWString());
51 return PyUnicode_FromWideChar(ws.data(), ws.length());
55 struct PyUnicode_QString
57 static void * convertible(PyObject * o)
59 return PyUnicode_Check(o) ? o : 0;
62 static void construct(PyObject * o,
63 py::converter::rvalue_from_python_stage1_data * data)
65 unsigned length (PyUnicode_GetSize(o));
66 std::wstring ws (length, 0);
67 // Hmm ... I don't want to copy the stupid data TWICE but this
68 // breaks the standard ... who cares ?
69 PyUnicode_AsWideChar(reinterpret_cast<PyUnicodeObject *>(o),
70 const_cast<wchar_t*>(ws.data()),
72 void * storage (((py::converter::rvalue_from_python_storage<QString>*)
73 data)->storage.bytes);
74 *(new (storage) QString()) = QString::fromStdWString(ws);
75 data->convertible = storage;
80 py::converter::registry::push_back(
83 py::type_id<QString>());
87 struct QByteArray_PyString
89 static PyObject * convert(QByteArray const & s)
91 return boost::python::incref(boost::python::object(s.constData()).ptr());
95 struct PyString_QByteArray
97 static void * convertible(PyObject * o)
99 return PyString_Check(o) ? o : 0;
102 static void construct(PyObject * o,
103 py::converter::rvalue_from_python_stage1_data * data)
105 unsigned length (PyString_Size(o));
106 const char * value (PyString_AsString(o));
107 void * storage (((py::converter::rvalue_from_python_storage<QByteArray>*)
108 data)->storage.bytes);
109 new (storage) QByteArray(value,length);
110 data->convertible = storage;
113 PyString_QByteArray()
115 py::converter::registry::push_back(
118 py::type_id<QByteArray>());
124 QString QUrl_toString_noargs(QUrl const & url)
125 { return url.toString(); }
129 #define MEMFNP(ret, cls, nam, arg) static_cast<ret (cls::*)arg>(&cls::nam)
131 BOOST_PYTHON_MODULE(_qt)
133 py::to_python_converter<QString, pyconvert::QString_PyUnicode>();
134 pyconvert::PyUnicode_QString register_PyUnicode_QString;
136 py::to_python_converter<QByteArray, pyconvert::QByteArray_PyString>();
137 pyconvert::PyString_QByteArray register_PyString_QByteArray;
139 // Missing converters:
144 py::class_<QUrl>("QUrl", py::init<>())
145 // QUrl ( const QString & url )
146 .def(py::init<QString const &>())
147 // QUrl ( const QUrl & other )
148 .def(py::init<QUrl const &>())
149 // QUrl ( const QString & url, ParsingMode parsingMode )
150 // .def(init<QString const &, ParsingMode>())
152 // void addEncodedQueryItem ( const QByteArray & key, const QByteArray & value )
153 .def("addEncodedQueryItem",
154 MEMFNP(void, QUrl, addEncodedQueryItem,
155 ( const QByteArray & key, const QByteArray & value )))
156 // void addQueryItem ( const QString & key, const QString & value )
158 MEMFNP(void, QUrl, addQueryItem,
159 ( const QString & key, const QString & value )))
160 // QList<QByteArray> allEncodedQueryItemValues ( const QByteArray & key ) const
161 // .def("allEncodedQueryItemValues",
162 // MEMFNP(QList<QByteArray>, QUrl, allEncodedQueryItemValues,
163 // ( const QByteArray & key ) const))
164 // QStringList allQueryItemValues ( const QString & key ) const
165 // .def("allQueryItemValues",
166 // MEMFNP(QStringList, QUrl, allQueryItemValues,
167 // ( const QString & key ) const))
168 // QString authority () const
170 MEMFNP(QString, QUrl, authority,
174 MEMFNP(void, QUrl, clear,
176 // QByteArray encodedFragment () const
177 .def("encodedFragment",
178 MEMFNP(QByteArray, QUrl, encodedFragment,
180 // QByteArray encodedHost () const
182 MEMFNP(QByteArray, QUrl, encodedHost,
184 // QByteArray encodedPassword () const
185 .def("encodedPassword",
186 MEMFNP(QByteArray, QUrl, encodedPassword,
188 // QByteArray encodedPath () const
190 MEMFNP(QByteArray, QUrl, encodedPath,
192 // QByteArray encodedQuery () const
194 MEMFNP(QByteArray, QUrl, encodedQuery,
196 // QByteArray encodedQueryItemValue ( const QByteArray & key ) const
197 .def("encodedQueryItemValue",
198 MEMFNP(QByteArray, QUrl, encodedQueryItemValue,
199 ( const QByteArray & key ) const))
200 // QList<QPair<QByteArray, QByteArray> > encodedQueryItems () const
201 // .def("encodedQueryItems",
202 // MEMFNP(QList<QPair<QByteArray, QByteArray> >, QUrl, encodedQueryItems,
204 // QByteArray encodedUserName () const
205 .def("encodedUserName",
206 MEMFNP(QByteArray, QUrl, encodedUserName,
208 // QString errorString () const
210 MEMFNP(QString, QUrl, errorString,
212 // QString fragment () const
214 MEMFNP(QString, QUrl, fragment,
216 // bool hasEncodedQueryItem ( const QByteArray & key ) const
217 .def("hasEncodedQueryItem",
218 MEMFNP(bool, QUrl, hasEncodedQueryItem,
219 ( const QByteArray & key ) const))
220 // bool hasFragment () const
222 MEMFNP(bool, QUrl, hasFragment,
224 // bool hasQuery () const
226 MEMFNP(bool, QUrl, hasQuery,
228 // bool hasQueryItem ( const QString & key ) const
230 MEMFNP(bool, QUrl, hasQueryItem,
231 ( const QString & key ) const))
232 // QString host () const
234 MEMFNP(QString, QUrl, host,
236 // bool isEmpty () const
238 MEMFNP(bool, QUrl, isEmpty,
240 // bool isParentOf ( const QUrl & childUrl ) const
242 MEMFNP(bool, QUrl, isParentOf,
243 ( const QUrl & childUrl ) const))
244 // bool isRelative () const
246 MEMFNP(bool, QUrl, isRelative,
248 // bool isValid () const
250 MEMFNP(bool, QUrl, isValid,
252 // QString password () const
254 MEMFNP(QString, QUrl, password,
256 // QString path () const
258 MEMFNP(QString, QUrl, path,
262 MEMFNP(int, QUrl, port,
264 // int port ( int defaultPort ) const
266 MEMFNP(int, QUrl, port,
267 ( int defaultPort ) const))
268 // QString queryItemValue ( const QString & key ) const
269 .def("queryItemValue",
270 MEMFNP(QString, QUrl, queryItemValue,
271 ( const QString & key ) const))
272 // QList<QPair<QString, QString> > queryItems () const
273 // .def("queryItems",
274 // MEMFNP(QList<QPair<QString, QString> >, QUrl, queryItems,
276 // char queryPairDelimiter () const
277 .def("queryPairDelimiter",
278 MEMFNP(char, QUrl, queryPairDelimiter,
280 // char queryValueDelimiter () const
281 .def("queryValueDelimiter",
282 MEMFNP(char, QUrl, queryValueDelimiter,
284 // void removeAllEncodedQueryItems ( const QByteArray & key )
285 .def("removeAllEncodedQueryItems",
286 MEMFNP(void, QUrl, removeAllEncodedQueryItems,
287 ( const QByteArray & key )))
288 // void removeAllQueryItems ( const QString & key )
289 .def("removeAllQueryItems",
290 MEMFNP(void, QUrl, removeAllQueryItems,
291 ( const QString & key )))
292 // void removeEncodedQueryItem ( const QByteArray & key )
293 .def("removeEncodedQueryItem",
294 MEMFNP(void, QUrl, removeEncodedQueryItem,
295 ( const QByteArray & key )))
296 // void removeQueryItem ( const QString & key )
297 .def("removeQueryItem",
298 MEMFNP(void, QUrl, removeQueryItem,
299 ( const QString & key )))
300 // QUrl resolved ( const QUrl & relative ) const
302 MEMFNP(QUrl, QUrl, resolved,
303 ( const QUrl & relative ) const))
304 // QString scheme () const
306 MEMFNP(QString, QUrl, scheme,
308 // void setAuthority ( const QString & authority )
310 MEMFNP(void, QUrl, setAuthority,
311 ( const QString & authority )))
312 // void setEncodedFragment ( const QByteArray & fragment )
313 .def("setEncodedFragment",
314 MEMFNP(void, QUrl, setEncodedFragment,
315 ( const QByteArray & fragment )))
316 // void setEncodedHost ( const QByteArray & host )
317 .def("setEncodedHost",
318 MEMFNP(void, QUrl, setEncodedHost,
319 ( const QByteArray & host )))
320 // void setEncodedPassword ( const QByteArray & password )
321 .def("setEncodedPassword",
322 MEMFNP(void, QUrl, setEncodedPassword,
323 ( const QByteArray & password )))
324 // void setEncodedPath ( const QByteArray & path )
325 .def("setEncodedPath",
326 MEMFNP(void, QUrl, setEncodedPath,
327 ( const QByteArray & path )))
328 // void setEncodedQuery ( const QByteArray & query )
329 .def("setEncodedQuery",
330 MEMFNP(void, QUrl, setEncodedQuery,
331 ( const QByteArray & query )))
332 // void setEncodedQueryItems ( const QList<QPair<QByteArray, QByteArray> > & query )
333 // .def("setEncodedQueryItems",
334 // MEMFNP(void, QUrl, setEncodedQueryItems,
335 // ( const QList<QPair<QByteArray, QByteArray> > & query )))
336 // void setEncodedUrl ( const QByteArray & encodedUrl )
337 .def("setEncodedUrl",
338 MEMFNP(void, QUrl, setEncodedUrl,
339 ( const QByteArray & encodedUrl )))
340 // void setEncodedUrl ( const QByteArray & encodedUrl, ParsingMode parsingMode )
341 // .def("setEncodedUrl",
342 // MEMFNP(void, QUrl, setEncodedUrl,
343 // ( const QByteArray & encodedUrl, ParsingMode parsingMode )))
344 // void setEncodedUserName ( const QByteArray & userName )
345 .def("setEncodedUserName",
346 MEMFNP(void, QUrl, setEncodedUserName,
347 ( const QByteArray & userName )))
348 // void setFragment ( const QString & fragment )
350 MEMFNP(void, QUrl, setFragment,
351 ( const QString & fragment )))
352 // void setHost ( const QString & host )
354 MEMFNP(void, QUrl, setHost,
355 ( const QString & host )))
356 // void setPassword ( const QString & password )
358 MEMFNP(void, QUrl, setPassword,
359 ( const QString & password )))
360 // void setPath ( const QString & path )
362 MEMFNP(void, QUrl, setPath,
363 ( const QString & path )))
364 // void setPort ( int port )
366 MEMFNP(void, QUrl, setPort,
368 // void setQueryDelimiters ( char valueDelimiter, char pairDelimiter )
369 .def("setQueryDelimiters",
370 MEMFNP(void, QUrl, setQueryDelimiters,
371 ( char valueDelimiter, char pairDelimiter )))
372 // void setQueryItems ( const QList<QPair<QString, QString> > & query )
373 // .def("setQueryItems",
374 // MEMFNP(void, QUrl, setQueryItems,
375 // ( const QList<QPair<QString, QString> > & query )))
376 // void setScheme ( const QString & scheme )
378 MEMFNP(void, QUrl, setScheme,
379 ( const QString & scheme )))
380 // void setUrl ( const QString & url )
382 MEMFNP(void, QUrl, setUrl,
383 ( const QString & url )))
384 // void setUrl ( const QString & url, ParsingMode parsingMode )
386 // MEMFNP(void, QUrl, setUrl,
387 // ( const QString & url, ParsingMode parsingMode )))
388 // void setUserInfo ( const QString & userInfo )
390 MEMFNP(void, QUrl, setUserInfo,
391 ( const QString & userInfo )))
392 // void setUserName ( const QString & userName )
394 MEMFNP(void, QUrl, setUserName,
395 ( const QString & userName )))
396 // QByteArray toEncoded ( FormattingOptions options = None ) const
398 // MEMFNP(QByteArray, QUrl, toEncoded,
399 // ( FormattingOptions options = None ) const))
400 // QString toLocalFile () const
402 MEMFNP(QString, QUrl, toLocalFile,
404 // QString toString ( FormattingOptions options = None ) const
405 .def("__unicode__", &QUrl_toString_noargs)
406 // QString userInfo () const
408 MEMFNP(QString, QUrl, userInfo,
410 // QString userName () const
412 MEMFNP(QString, QUrl, userName,
415 // bool operator!= ( const QUrl & url ) const
416 // QUrl & operator= ( const QUrl & url )
417 // QUrl & operator= ( const QString & url )
418 // bool operator== ( const QUrl & url ) const
422 BOOST_PYTHON_MODULE(_pykit)
424 py::class_<pykit::Request>("Request", py::no_init)
425 .def("write", &pykit::Request::write)
426 .def("reset", &pykit::Request::reset)
427 .def("setContentType", &pykit::Request::setContentType)
428 .def("setLocation", &pykit::Request::setLocation)
429 .def("setRawHeader", &pykit::Request::setHeader)
430 .def("setStatusCode", &pykit::Request::setStatusCode)
431 .def("url", &pykit::Request::url)
432 .def("postData", &pykit::Request::postData)
433 .def("operation", &pykit::Request::operation)
434 .def("postContentType", &pykit::Request::postContentType)
437 py::class_<PublisherPyWrapper, boost::noncopyable>("Publisher")
438 .def("publish", py::pure_virtual(&pykit::Publisher::publish))
441 py::def("openUrl", &QDesktopServices::openUrl);
444 PYTHON_EXTERN_MODULE(_httpapi);
446 prefix_ pykit::PythonPublisher::PythonPublisher()
450 PYTHON_PREPARE_IMPORT(_pykit);
451 PYTHON_PREPARE_IMPORT(_qt);
452 PYTHON_PREPARE_IMPORT(_httpapi);
454 py::object initModule = py::import("init");
455 impl_->mainNamespace = py::extract<py::dict>(initModule.attr("__dict__"));
456 impl_->pythonPublisher = py::extract<Publisher*>(impl_->mainNamespace["initialize"]());
458 catch (boost::python::error_already_set & ex) {
464 prefix_ pykit::PythonPublisher::~PythonPublisher()
467 impl_->mainNamespace["shutdown"]();
472 prefix_ void pykit::PythonPublisher::publish(Request & request)
475 impl_->pythonPublisher->publish(request);
477 catch (py::error_already_set & ex) {
482 ///////////////////////////////cc.e////////////////////////////////////////
484 //#include "PythonPublisher.mpp"
490 // comment-column: 40
491 // c-file-style: "j32"
492 // indent-tabs-mode: nil
493 // ispell-local-dictionary: "american"
494 // compile-command: "scons -U"