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