add setRawHeader to Rquest API
[pykit.git] / PythonPublisher.cc
1 // $Id$
2 //
3 // Copyright (C) 2010
4 //     Stefan Bund <info@j32.de>
5
6 /** \file
7     \brief PythonPublisher non-inline non-template implementation */
8
9 #include "PythonPublisher.hh"
10 //#include "PythonPublisher.ih"
11
12 // Custom includes
13 #include <iostream>
14 #include <boost/python.hpp>
15 #include "Publisher.hh"
16
17 //#include "PythonPublisher.mpp"
18 #define prefix_
19 ///////////////////////////////cc.p////////////////////////////////////////
20
21 namespace py = boost::python;
22
23 struct pykit::PythonPublisher::Impl
24 {
25     boost::python::dict mainNamespace;
26     Publisher * pythonPublisher;
27 };
28
29 #define PYTHON_PREPARE_IMPORT(module) \
30     PyImport_AppendInittab(const_cast<char*>(#module), init ## module)
31
32 namespace {
33
34     struct PublisherPyWrapper
35         : public pykit::Publisher, py::wrapper<pykit::Publisher>
36     {
37         virtual void publish(pykit::Request & request)
38             { get_override("publish")(request); }
39     };
40
41     namespace pyconvert {
42
43         struct QString_PyUnicode
44         {
45             static PyObject * convert(QString const & s)
46                 {
47                     std::wstring ws (s.toStdWString());
48                     return PyUnicode_FromWideChar(ws.data(), ws.length());
49                 }
50         };
51
52         struct PyUnicode_QString
53         {
54             static void * convertible(PyObject * o)
55                 {
56                     return PyUnicode_Check(o) ? o : 0;
57                 }
58
59             static void construct(PyObject * o,
60                                   py::converter::rvalue_from_python_stage1_data * data)
61                 {
62                     unsigned length (PyUnicode_GetSize(o));
63                     std::wstring ws (length, 0);
64                     // Hmm ... I don't want to copy the stupid data TWICE but this
65                     // breaks the standard ... who cares ?
66                     PyUnicode_AsWideChar(reinterpret_cast<PyUnicodeObject *>(o),
67                                          const_cast<wchar_t*>(ws.data()),
68                                          length);
69                     void * storage (((py::converter::rvalue_from_python_storage<QString>*)
70                                      data)->storage.bytes);
71                     *(new (storage) QString()) = QString::fromStdWString(ws);
72                     data->convertible = storage;
73                 }
74
75             PyUnicode_QString()
76                 {
77                     py::converter::registry::push_back(
78                         &convertible,
79                         &construct,
80                         py::type_id<QString>());
81                 }
82         };
83
84         struct QByteArray_PyString
85         {
86             static PyObject * convert(QByteArray const & s)
87                 {
88                     return boost::python::incref(boost::python::object(s.constData()).ptr());
89                 }
90         };
91
92         struct PyString_QByteArray
93         {
94             static void * convertible(PyObject * o)
95                 {
96                     return PyString_Check(o) ? o : 0;
97                 }
98
99             static void construct(PyObject * o,
100                                   py::converter::rvalue_from_python_stage1_data * data)
101                 {
102                     unsigned length (PyString_Size(o));
103                     const char * value (PyString_AsString(o));
104                     void * storage (((py::converter::rvalue_from_python_storage<QByteArray>*)
105                                      data)->storage.bytes);
106                     new (storage) QByteArray(value,length);
107                     data->convertible = storage;
108                 }
109
110             PyString_QByteArray()
111                 {
112                     py::converter::registry::push_back(
113                         &convertible,
114                         &construct,
115                         py::type_id<QByteArray>());
116                 }
117         };
118
119     }
120
121     QString QUrl_toString_noargs(QUrl const & url)
122     { return url.toString(); }
123
124 }
125
126 #define MEMFNP(ret, cls, nam, arg) static_cast<ret (cls::*)arg>(&cls::nam)
127
128 BOOST_PYTHON_MODULE(_qt)
129 {
130     py::to_python_converter<QString, pyconvert::QString_PyUnicode>();
131     pyconvert::PyUnicode_QString register_PyUnicode_QString;
132
133     py::to_python_converter<QByteArray, pyconvert::QByteArray_PyString>();
134     pyconvert::PyString_QByteArray register_PyString_QByteArray;
135
136     // Missing converters:
137     //    QPair <-> tuple
138     //    QList <-> vector
139
140         // QUrl ()
141     py::class_<QUrl>("QUrl", py::init<>())
142         // QUrl ( const QString & url )
143         .def(py::init<QString const &>())
144         // QUrl ( const QUrl & other )
145         .def(py::init<QUrl const &>())
146         // QUrl ( const QString & url, ParsingMode parsingMode )
147         // .def(init<QString const &, ParsingMode>())
148         // ~QUrl ()
149         // void   addEncodedQueryItem ( const QByteArray & key, const QByteArray & value )
150         .def("addEncodedQueryItem",
151              MEMFNP(void, QUrl, addEncodedQueryItem,
152                     ( const QByteArray & key, const QByteArray & value )))
153         // void   addQueryItem ( const QString & key, const QString & value )
154         .def("addQueryItem",
155              MEMFNP(void, QUrl, addQueryItem,
156                     ( const QString & key, const QString & value )))
157         // QList<QByteArray>   allEncodedQueryItemValues ( const QByteArray & key ) const
158         // .def("allEncodedQueryItemValues",
159         //      MEMFNP(QList<QByteArray>, QUrl, allEncodedQueryItemValues,
160         //             ( const QByteArray & key ) const))
161         // QStringList   allQueryItemValues ( const QString & key ) const
162         // .def("allQueryItemValues",
163         //      MEMFNP(QStringList, QUrl, allQueryItemValues,
164         //             ( const QString & key ) const))
165         // QString   authority () const
166         .def("authority",
167              MEMFNP(QString, QUrl, authority,
168                     () const))
169         // void   clear ()
170         .def("clear",
171              MEMFNP(void, QUrl, clear,
172                     ()))
173         // QByteArray   encodedFragment () const
174         .def("encodedFragment",
175              MEMFNP(QByteArray, QUrl, encodedFragment,
176                     () const))
177         // QByteArray   encodedHost () const
178         .def("encodedHost",
179              MEMFNP(QByteArray, QUrl, encodedHost,
180                     () const))
181         // QByteArray   encodedPassword () const
182         .def("encodedPassword",
183              MEMFNP(QByteArray, QUrl, encodedPassword,
184                     () const))
185         // QByteArray   encodedPath () const
186         .def("encodedPath",
187              MEMFNP(QByteArray, QUrl, encodedPath,
188                     () const))
189         // QByteArray   encodedQuery () const
190         .def("encodedQuery",
191              MEMFNP(QByteArray, QUrl, encodedQuery,
192                     () const))
193         // QByteArray   encodedQueryItemValue ( const QByteArray & key ) const
194         .def("encodedQueryItemValue",
195              MEMFNP(QByteArray, QUrl, encodedQueryItemValue,
196                     ( const QByteArray & key ) const))
197         // QList<QPair<QByteArray, QByteArray> >   encodedQueryItems () const
198         // .def("encodedQueryItems",
199         //      MEMFNP(QList<QPair<QByteArray, QByteArray> >, QUrl, encodedQueryItems,
200         //             () const))
201         // QByteArray   encodedUserName () const
202         .def("encodedUserName",
203              MEMFNP(QByteArray, QUrl, encodedUserName,
204                     () const))
205         // QString   errorString () const
206         .def("errorString",
207              MEMFNP(QString, QUrl, errorString,
208                     () const))
209         // QString   fragment () const
210         .def("fragment",
211              MEMFNP(QString, QUrl, fragment,
212                     () const))
213         // bool   hasEncodedQueryItem ( const QByteArray & key ) const
214         .def("hasEncodedQueryItem",
215              MEMFNP(bool, QUrl, hasEncodedQueryItem,
216                     ( const QByteArray & key ) const))
217         // bool   hasFragment () const
218         .def("hasFragment",
219              MEMFNP(bool, QUrl, hasFragment,
220                     () const))
221         // bool   hasQuery () const
222         .def("hasQuery",
223              MEMFNP(bool, QUrl, hasQuery,
224                     () const))
225         // bool   hasQueryItem ( const QString & key ) const
226         .def("hasQueryItem",
227              MEMFNP(bool, QUrl, hasQueryItem,
228                     ( const QString & key ) const))
229         // QString   host () const
230         .def("host",
231              MEMFNP(QString, QUrl, host,
232                     () const))
233         // bool   isEmpty () const
234         .def("isEmpty",
235              MEMFNP(bool, QUrl, isEmpty,
236                     () const))
237         // bool   isParentOf ( const QUrl & childUrl ) const
238         .def("isParentOf",
239              MEMFNP(bool, QUrl, isParentOf,
240                     ( const QUrl & childUrl ) const))
241         // bool   isRelative () const
242         .def("isRelative",
243              MEMFNP(bool, QUrl, isRelative,
244                     () const))
245         // bool   isValid () const
246         .def("isValid",
247              MEMFNP(bool, QUrl, isValid,
248                     () const))
249         // QString   password () const
250         .def("password",
251              MEMFNP(QString, QUrl, password,
252                     () const))
253         // QString   path () const
254         .def("path",
255              MEMFNP(QString, QUrl, path,
256                     () const))
257         // int   port () const
258         .def("port",
259              MEMFNP(int, QUrl, port,
260                     () const))
261         // int   port ( int defaultPort ) const
262         .def("port",
263              MEMFNP(int, QUrl, port,
264                     ( int defaultPort ) const))
265         // QString   queryItemValue ( const QString & key ) const
266         .def("queryItemValue",
267              MEMFNP(QString, QUrl, queryItemValue,
268                     ( const QString & key ) const))
269         // QList<QPair<QString, QString> >   queryItems () const
270         // .def("queryItems",
271         //      MEMFNP(QList<QPair<QString, QString> >, QUrl, queryItems,
272         //             () const))
273         // char   queryPairDelimiter () const
274         .def("queryPairDelimiter",
275              MEMFNP(char, QUrl, queryPairDelimiter,
276                     () const))
277         // char   queryValueDelimiter () const
278         .def("queryValueDelimiter",
279              MEMFNP(char, QUrl, queryValueDelimiter,
280                     () const))
281         // void   removeAllEncodedQueryItems ( const QByteArray & key )
282         .def("removeAllEncodedQueryItems",
283              MEMFNP(void, QUrl, removeAllEncodedQueryItems,
284                     ( const QByteArray & key )))
285         // void   removeAllQueryItems ( const QString & key )
286         .def("removeAllQueryItems",
287              MEMFNP(void, QUrl, removeAllQueryItems,
288                     ( const QString & key )))
289         // void   removeEncodedQueryItem ( const QByteArray & key )
290         .def("removeEncodedQueryItem",
291              MEMFNP(void, QUrl, removeEncodedQueryItem,
292                     ( const QByteArray & key )))
293         // void   removeQueryItem ( const QString & key )
294         .def("removeQueryItem",
295              MEMFNP(void, QUrl, removeQueryItem,
296                     ( const QString & key )))
297         // QUrl   resolved ( const QUrl & relative ) const
298         .def("resolved",
299              MEMFNP(QUrl, QUrl, resolved,
300                     ( const QUrl & relative ) const))
301         // QString   scheme () const
302         .def("scheme",
303              MEMFNP(QString, QUrl, scheme,
304                     () const))
305         // void   setAuthority ( const QString & authority )
306         .def("setAuthority",
307              MEMFNP(void, QUrl, setAuthority,
308                     ( const QString & authority )))
309         // void   setEncodedFragment ( const QByteArray & fragment )
310         .def("setEncodedFragment",
311              MEMFNP(void, QUrl, setEncodedFragment,
312                     ( const QByteArray & fragment )))
313         // void   setEncodedHost ( const QByteArray & host )
314         .def("setEncodedHost",
315              MEMFNP(void, QUrl, setEncodedHost,
316                     ( const QByteArray & host )))
317         // void   setEncodedPassword ( const QByteArray & password )
318         .def("setEncodedPassword",
319              MEMFNP(void, QUrl, setEncodedPassword,
320                     ( const QByteArray & password )))
321         // void   setEncodedPath ( const QByteArray & path )
322         .def("setEncodedPath",
323              MEMFNP(void, QUrl, setEncodedPath,
324                     ( const QByteArray & path )))
325         // void   setEncodedQuery ( const QByteArray & query )
326         .def("setEncodedQuery",
327              MEMFNP(void, QUrl, setEncodedQuery,
328                     ( const QByteArray & query )))
329         // void   setEncodedQueryItems ( const QList<QPair<QByteArray, QByteArray> > & query )
330         // .def("setEncodedQueryItems",
331         //      MEMFNP(void, QUrl, setEncodedQueryItems,
332         //             ( const QList<QPair<QByteArray, QByteArray> > & query )))
333         // void   setEncodedUrl ( const QByteArray & encodedUrl )
334         .def("setEncodedUrl",
335              MEMFNP(void, QUrl, setEncodedUrl,
336                     ( const QByteArray & encodedUrl )))
337         // void   setEncodedUrl ( const QByteArray & encodedUrl, ParsingMode parsingMode )
338         // .def("setEncodedUrl",
339         //      MEMFNP(void, QUrl, setEncodedUrl,
340         //             ( const QByteArray & encodedUrl, ParsingMode parsingMode )))
341         // void   setEncodedUserName ( const QByteArray & userName )
342         .def("setEncodedUserName",
343              MEMFNP(void, QUrl, setEncodedUserName,
344                     ( const QByteArray & userName )))
345         // void   setFragment ( const QString & fragment )
346         .def("setFragment",
347              MEMFNP(void, QUrl, setFragment,
348                     ( const QString & fragment )))
349         // void   setHost ( const QString & host )
350         .def("setHost",
351              MEMFNP(void, QUrl, setHost,
352                     ( const QString & host )))
353         // void   setPassword ( const QString & password )
354         .def("setPassword",
355              MEMFNP(void, QUrl, setPassword,
356                     ( const QString & password )))
357         // void   setPath ( const QString & path )
358         .def("setPath",
359              MEMFNP(void, QUrl, setPath,
360                     ( const QString & path )))
361         // void   setPort ( int port )
362         .def("setPort",
363              MEMFNP(void, QUrl, setPort,
364                     ( int port )))
365         // void   setQueryDelimiters ( char valueDelimiter, char pairDelimiter )
366         .def("setQueryDelimiters",
367              MEMFNP(void, QUrl, setQueryDelimiters,
368                     ( char valueDelimiter, char pairDelimiter )))
369         // void   setQueryItems ( const QList<QPair<QString, QString> > & query )
370         // .def("setQueryItems",
371         //      MEMFNP(void, QUrl, setQueryItems,
372         //             ( const QList<QPair<QString, QString> > & query )))
373         // void   setScheme ( const QString & scheme )
374         .def("setScheme",
375              MEMFNP(void, QUrl, setScheme,
376                     ( const QString & scheme )))
377         // void   setUrl ( const QString & url )
378         .def("setUrl",
379              MEMFNP(void, QUrl, setUrl,
380                     ( const QString & url )))
381         // void   setUrl ( const QString & url, ParsingMode parsingMode )
382         // .def("setUrl",
383         //      MEMFNP(void, QUrl, setUrl,
384         //             ( const QString & url, ParsingMode parsingMode )))
385         // void   setUserInfo ( const QString & userInfo )
386         .def("setUserInfo",
387              MEMFNP(void, QUrl, setUserInfo,
388                     ( const QString & userInfo )))
389         // void   setUserName ( const QString & userName )
390         .def("setUserName",
391              MEMFNP(void, QUrl, setUserName,
392                     ( const QString & userName )))
393         // QByteArray   toEncoded ( FormattingOptions options = None ) const
394         // .def("toEncoded",
395         //      MEMFNP(QByteArray, QUrl, toEncoded,
396         //             ( FormattingOptions options = None ) const))
397         // QString   toLocalFile () const
398         .def("toLocalFile",
399              MEMFNP(QString, QUrl, toLocalFile,
400                     () const))
401         // QString   toString ( FormattingOptions options = None ) const
402         .def("__unicode__", &QUrl_toString_noargs)
403         // QString   userInfo () const
404         .def("userInfo",
405              MEMFNP(QString, QUrl, userInfo,
406                     () const))
407         // QString   userName () const
408         .def("userName",
409              MEMFNP(QString, QUrl, userName,
410                     () const))
411
412         // bool   operator!= ( const QUrl & url ) const
413         // QUrl &   operator= ( const QUrl & url )
414         // QUrl &   operator= ( const QString & url )
415         // bool   operator== ( const QUrl & url ) const
416         ;
417 }
418
419 BOOST_PYTHON_MODULE(_pykit)
420 {
421     py::class_<pykit::Request>("Request", py::no_init)
422         .def("write", &pykit::Request::write)
423         .def("reset", &pykit::Request::reset)
424         .def("setContentType", &pykit::Request::setContentType)
425         .def("setLocation", &pykit::Request::setLocation)
426         .def("setRawHeader", &pykit::Request::setHeader)
427         .def("url", &pykit::Request::url)
428         .def("postData", &pykit::Request::postData)
429         .def("operation", &pykit::Request::operation)
430         .def("postContentType", &pykit::Request::postContentType)
431         ;
432
433     py::class_<PublisherPyWrapper, boost::noncopyable>("Publisher")
434         .def("publish", py::pure_virtual(&pykit::Publisher::publish))
435         ;
436 }
437
438 prefix_ pykit::PythonPublisher::PythonPublisher()
439     : impl_ (new Impl)
440 {
441     try {
442         PYTHON_PREPARE_IMPORT(_pykit);
443         PYTHON_PREPARE_IMPORT(_qt);
444         Py_Initialize();
445         py::object initModule = py::import("init");
446         impl_->mainNamespace = py::extract<py::dict>(initModule.attr("__dict__"));
447         impl_->pythonPublisher = py::extract<Publisher*>(impl_->mainNamespace["initialize"]());
448     }
449     catch (boost::python::error_already_set & ex) {
450         PyErr_Print();
451         throw;
452     }
453 }
454
455 prefix_ pykit::PythonPublisher::~PythonPublisher()
456 {}
457
458 prefix_ void pykit::PythonPublisher::publish(Request & request)
459 {
460     try {
461         impl_->pythonPublisher->publish(request);
462     }
463     catch (py::error_already_set & ex) {
464         PyErr_Print();
465     }
466 }
467
468 ///////////////////////////////cc.e////////////////////////////////////////
469 #undef prefix_
470 //#include "PythonPublisher.mpp"
471
472 \f
473 // Local Variables:
474 // mode: c++
475 // fill-column: 100
476 // comment-column: 40
477 // c-file-style: "j32"
478 // indent-tabs-mode: nil
479 // ispell-local-dictionary: "american"
480 // compile-command: "scons -U"
481 // End: