--- /dev/null
+// $Id$
+//
+// Copyright (C) 2010
+
+/** \file
+ \brief InternalNetworkAccessManager non-inline non-template implementation */
+
+#include "Publisher.hh"
+//#include "Publisher.ih"
+
+// Custom includes
+#include <iostream>
+#include <QNetworkProxy>
+#include <QVariant>
+#include "Publisher.hh"
+#include <boost/python.hpp>
+
+//#include "Publisher.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// pykit::detail::InternalServerReply
+
+namespace pykit {
+namespace detail {
+
+ class InternalServerReply
+ : public QNetworkReply
+ {
+ Q_OBJECT;
+ public:
+ InternalServerReply(QNetworkAccessManager::Operation operation,
+ QNetworkRequest const & networkRequest,
+ Publisher * publisher);
+
+ // Forwarded to buffer
+ virtual bool atEnd() const;
+ virtual qint64 bytesAvailable() const;
+ virtual qint64 bytesToWrite() const;
+ virtual bool canReadLine() const;
+ virtual bool isSequential() const;
+ virtual qint64 pos() const;
+ virtual bool reset();
+ virtual bool seek(qint64 pos);
+ virtual qint64 size() const;
+ virtual bool waitForBytesWritten(int msecs);
+ virtual bool waitForReadyRead(int msecs);
+
+ virtual void abort();
+
+ using QNetworkReply::setHeader;
+
+ void clearResponse();
+
+ protected:
+ qint64 readData(char * data, qint64 maxSize);
+ qint64 writeData(char const * data, qint64 maxSize);
+
+ signals:
+ void initSignal();
+
+ private slots:
+ void initSlot();
+
+ private:
+ QBuffer buffer_;
+ };
+
+}}
+
+prefix_ pykit::detail::InternalServerReply::
+InternalServerReply(QNetworkAccessManager::Operation operation,
+ QNetworkRequest const & networkRequest, Publisher * publisher)
+{
+ setRequest(networkRequest);
+ setOperation(operation);
+ setUrl(networkRequest.url());
+ open(ReadWrite | Unbuffered);
+ buffer_.open(ReadWrite | Unbuffered);
+
+ Request request (*this);
+ publisher->publish(request);
+
+ seek(0);
+ setHeader(QNetworkRequest::ContentLengthHeader, QVariant(size()));
+ setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/html; charset=UTF-8"));
+
+ // The following rigamole is needed to delay emitting readyRead() / finished() after until the
+ // connections to those signals have been set up.
+ //
+ // We use a queued signal here. This will call initSlot after processing has returned to the
+ // event loop.
+ connect(this, SIGNAL(initSignal()), this, SLOT(initSlot()), Qt::QueuedConnection);
+ emit initSignal();
+}
+
+prefix_ void pykit::detail::InternalServerReply::initSlot()
+{
+ emit readyRead();
+ emit finished();
+}
+
+prefix_ bool pykit::detail::InternalServerReply::atEnd()
+ const
+{ return buffer_.atEnd(); }
+
+prefix_ qint64 pykit::detail::InternalServerReply::bytesAvailable()
+ const
+{ return buffer_.bytesAvailable(); }
+
+prefix_ qint64 pykit::detail::InternalServerReply::bytesToWrite()
+ const
+{ return buffer_.bytesToWrite(); }
+
+prefix_ bool pykit::detail::InternalServerReply::canReadLine()
+ const
+{ return buffer_.canReadLine(); }
+
+prefix_ bool pykit::detail::InternalServerReply::isSequential()
+ const
+{ return buffer_.isSequential(); }
+
+prefix_ qint64 pykit::detail::InternalServerReply::pos()
+ const
+{ return buffer_.pos(); }
+
+prefix_ bool pykit::detail::InternalServerReply::reset()
+{ return buffer_.reset(); }
+
+prefix_ bool pykit::detail::InternalServerReply::seek(qint64 pos)
+{ return buffer_.seek(pos); }
+
+prefix_ qint64 pykit::detail::InternalServerReply::size()
+ const
+{ return buffer_.size(); }
+
+prefix_ bool pykit::detail::InternalServerReply::waitForBytesWritten(int msecs)
+{ return buffer_.waitForBytesWritten(msecs); }
+
+prefix_ bool pykit::detail::InternalServerReply::waitForReadyRead(int msecs)
+{ return buffer_.waitForReadyRead(msecs); }
+
+prefix_ qint64 pykit::detail::InternalServerReply::readData(char * data, qint64 maxSize)
+{ return buffer_.read(data,maxSize); }
+
+prefix_ qint64 pykit::detail::InternalServerReply::writeData(char const * data, qint64 maxSize)
+{ return buffer_.write(data,maxSize); }
+
+prefix_ void pykit::detail::InternalServerReply::abort()
+{}
+
+prefix_ void pykit::detail::InternalServerReply::clearResponse()
+{
+ buffer_.buffer().clear();
+}
+
+///////////////////////////////////////////////////////////////////////////
+// pykit::Request
+
+prefix_ void pykit::Request::write(std::string const & data)
+{
+ reply_.write(data.c_str());
+}
+
+prefix_ void pykit::Request::reset()
+{
+ reply_.clearResponse();
+}
+
+prefix_ void pykit::Request::setContentType(std::string const & contentType)
+{
+ reply_.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(contentType.c_str()));
+}
+
+prefix_ void pykit::Request::setLocation(std::string const & location)
+{
+ reply_.setHeader(QNetworkRequest::LocationHeader, QVariant(location.c_str()));
+}
+
+prefix_ QUrl pykit::Request::url()
+ const
+{
+ return reply_.url();
+}
+
+prefix_ pykit::Request::Request(detail::InternalServerReply & reply)
+ : reply_ (reply)
+{}
+
+///////////////////////////////////////////////////////////////////////////
+// pykit::InternalNetworkAccessManager
+
+prefix_ pykit::InternalNetworkAccessManager::
+InternalNetworkAccessManager(QNetworkAccessManager * manager, QObject * parent,
+ Publisher * publisher)
+ : QNetworkAccessManager(parent), publisher_ (publisher)
+{
+ setCache(manager->cache());
+ setCookieJar(manager->cookieJar());
+ setProxy(manager->proxy());
+ setProxyFactory(manager->proxyFactory());
+}
+
+prefix_ QNetworkReply *
+pykit::InternalNetworkAccessManager::createRequest(Operation operation,
+ QNetworkRequest const & request,
+ QIODevice * device)
+{
+ if (request.url().scheme() != "srv")
+ return QNetworkAccessManager::createRequest(operation, request, device);
+
+ return new detail::InternalServerReply(operation, request, publisher_);
+}
+
+#include "Publisher.moc"
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "Publisher.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "j32"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -U"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2010
+// Stefan Bund <info@j32.de>
+
+/** \file
+ \brief PythonPublisher non-inline non-template implementation */
+
+#include "PythonPublisher.hh"
+//#include "PythonPublisher.ih"
+
+// Custom includes
+#include "Publisher.hh"
+
+//#include "PythonPublisher.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace py = boost::python;
+
+namespace {
+
+ struct PublisherPyWrapper
+ : public pykit::Publisher, py::wrapper<pykit::Publisher>
+ {
+ virtual void publish(pykit::Request & request)
+ { get_override("publish")(request); }
+ };
+
+ namespace pyconvert {
+
+ struct QString_PyUnicode
+ {
+ static PyObject * convert(QString const & s)
+ {
+ std::wstring ws (s.toStdWString());
+ return PyUnicode_FromWideChar(ws.c_str(), ws.length());
+ }
+ };
+
+ struct PyUnicode_QString
+ {
+ static void * convertible(PyObject * o)
+ {
+ return PyUnicode_Check(o) ? o : 0;
+ }
+
+ static void construct(PyObject * o,
+ py::converter::rvalue_from_python_stage1_data * data)
+ {
+ unsigned length (PyUnicode_GetSize(o));
+ std::wstring ws (length, 0);
+ // Hmm ... I don't want to copy the stupid data TWICE but this
+ // breaks the standard ... who cares ?
+ PyUnicode_AsWideChar(reinterpret_cast<PyUnicodeObject *>(o),
+ const_cast<wchar_t*>(ws.data()),
+ length);
+ void * storage (((py::converter::rvalue_from_python_storage<QString>*)
+ data)->storage.bytes);
+ *(new (storage) QString()) = QString::fromStdWString(ws);
+ data->convertible = storage;
+ }
+
+ PyUnicode_QString()
+ {
+ py::converter::registry::push_back(
+ &convertible,
+ &construct,
+ py::type_id<QString>());
+ }
+ };
+
+ struct QByteArray_PyString
+ {
+ static PyObject * convert(QByteArray const & s)
+ {
+ return boost::python::incref(boost::python::object(s.constData()).ptr());
+ }
+ };
+
+ struct PyString_QByteArray
+ {
+ static void * convertible(PyObject * o)
+ {
+ return PyString_Check(o) ? o : 0;
+ }
+
+ static void construct(PyObject * o,
+ py::converter::rvalue_from_python_stage1_data * data)
+ {
+ const char * value (PyString_AsString(o));
+ void * storage (((py::converter::rvalue_from_python_storage<QByteArray>*)
+ data)->storage.bytes);
+ new (storage) QByteArray(value);
+ data->convertible = storage;
+ }
+
+ PyString_QByteArray()
+ {
+ py::converter::registry::push_back(
+ &convertible,
+ &construct,
+ py::type_id<QByteArray>());
+ }
+ };
+
+ }
+
+ QString QUrl_toString_noargs(QUrl const & url)
+ { return url.toString(); }
+
+}
+
+#define MEMFNP(ret, cls, nam, arg) static_cast<ret (cls::*)arg>(&cls::nam)
+
+BOOST_PYTHON_MODULE(_qt)
+{
+ py::to_python_converter<QString, pyconvert::QString_PyUnicode>();
+ pyconvert::PyUnicode_QString register_PyUnicode_QString;
+
+ py::to_python_converter<QByteArray, pyconvert::QByteArray_PyString>();
+ pyconvert::PyString_QByteArray register_PyString_QByteArray;
+
+ // Missing converters:
+ // QPair <-> tuple
+ // QList <-> vector
+
+ // QUrl ()
+ py::class_<QUrl>("QUrl", py::init<>())
+ // QUrl ( const QString & url )
+ .def(py::init<QString const &>())
+ // QUrl ( const QUrl & other )
+ .def(py::init<QUrl const &>())
+ // QUrl ( const QString & url, ParsingMode parsingMode )
+ // .def(init<QString const &, ParsingMode>())
+ // ~QUrl ()
+ // void addEncodedQueryItem ( const QByteArray & key, const QByteArray & value )
+ .def("addEncodedQueryItem",
+ MEMFNP(void, QUrl, addEncodedQueryItem,
+ ( const QByteArray & key, const QByteArray & value )))
+ // void addQueryItem ( const QString & key, const QString & value )
+ .def("addQueryItem",
+ MEMFNP(void, QUrl, addQueryItem,
+ ( const QString & key, const QString & value )))
+ // QList<QByteArray> allEncodedQueryItemValues ( const QByteArray & key ) const
+ // .def("allEncodedQueryItemValues",
+ // MEMFNP(QList<QByteArray>, QUrl, allEncodedQueryItemValues,
+ // ( const QByteArray & key ) const))
+ // QStringList allQueryItemValues ( const QString & key ) const
+ // .def("allQueryItemValues",
+ // MEMFNP(QStringList, QUrl, allQueryItemValues,
+ // ( const QString & key ) const))
+ // QString authority () const
+ .def("authority",
+ MEMFNP(QString, QUrl, authority,
+ () const))
+ // void clear ()
+ .def("clear",
+ MEMFNP(void, QUrl, clear,
+ ()))
+ // QByteArray encodedFragment () const
+ .def("encodedFragment",
+ MEMFNP(QByteArray, QUrl, encodedFragment,
+ () const))
+ // QByteArray encodedHost () const
+ .def("encodedHost",
+ MEMFNP(QByteArray, QUrl, encodedHost,
+ () const))
+ // QByteArray encodedPassword () const
+ .def("encodedPassword",
+ MEMFNP(QByteArray, QUrl, encodedPassword,
+ () const))
+ // QByteArray encodedPath () const
+ .def("encodedPath",
+ MEMFNP(QByteArray, QUrl, encodedPath,
+ () const))
+ // QByteArray encodedQuery () const
+ .def("encodedQuery",
+ MEMFNP(QByteArray, QUrl, encodedQuery,
+ () const))
+ // QByteArray encodedQueryItemValue ( const QByteArray & key ) const
+ .def("encodedQueryItemValue",
+ MEMFNP(QByteArray, QUrl, encodedQueryItemValue,
+ ( const QByteArray & key ) const))
+ // QList<QPair<QByteArray, QByteArray> > encodedQueryItems () const
+ // .def("encodedQueryItems",
+ // MEMFNP(QList<QPair<QByteArray, QByteArray> >, QUrl, encodedQueryItems,
+ // () const))
+ // QByteArray encodedUserName () const
+ .def("encodedUserName",
+ MEMFNP(QByteArray, QUrl, encodedUserName,
+ () const))
+ // QString errorString () const
+ .def("errorString",
+ MEMFNP(QString, QUrl, errorString,
+ () const))
+ // QString fragment () const
+ .def("fragment",
+ MEMFNP(QString, QUrl, fragment,
+ () const))
+ // bool hasEncodedQueryItem ( const QByteArray & key ) const
+ .def("hasEncodedQueryItem",
+ MEMFNP(bool, QUrl, hasEncodedQueryItem,
+ ( const QByteArray & key ) const))
+ // bool hasFragment () const
+ .def("hasFragment",
+ MEMFNP(bool, QUrl, hasFragment,
+ () const))
+ // bool hasQuery () const
+ .def("hasQuery",
+ MEMFNP(bool, QUrl, hasQuery,
+ () const))
+ // bool hasQueryItem ( const QString & key ) const
+ .def("hasQueryItem",
+ MEMFNP(bool, QUrl, hasQueryItem,
+ ( const QString & key ) const))
+ // QString host () const
+ .def("host",
+ MEMFNP(QString, QUrl, host,
+ () const))
+ // bool isEmpty () const
+ .def("isEmpty",
+ MEMFNP(bool, QUrl, isEmpty,
+ () const))
+ // bool isParentOf ( const QUrl & childUrl ) const
+ .def("isParentOf",
+ MEMFNP(bool, QUrl, isParentOf,
+ ( const QUrl & childUrl ) const))
+ // bool isRelative () const
+ .def("isRelative",
+ MEMFNP(bool, QUrl, isRelative,
+ () const))
+ // bool isValid () const
+ .def("isValid",
+ MEMFNP(bool, QUrl, isValid,
+ () const))
+ // QString password () const
+ .def("password",
+ MEMFNP(QString, QUrl, password,
+ () const))
+ // QString path () const
+ .def("path",
+ MEMFNP(QString, QUrl, path,
+ () const))
+ // int port () const
+ .def("port",
+ MEMFNP(int, QUrl, port,
+ () const))
+ // int port ( int defaultPort ) const
+ .def("port",
+ MEMFNP(int, QUrl, port,
+ ( int defaultPort ) const))
+ // QString queryItemValue ( const QString & key ) const
+ .def("queryItemValue",
+ MEMFNP(QString, QUrl, queryItemValue,
+ ( const QString & key ) const))
+ // QList<QPair<QString, QString> > queryItems () const
+ // .def("queryItems",
+ // MEMFNP(QList<QPair<QString, QString> >, QUrl, queryItems,
+ // () const))
+ // char queryPairDelimiter () const
+ .def("queryPairDelimiter",
+ MEMFNP(char, QUrl, queryPairDelimiter,
+ () const))
+ // char queryValueDelimiter () const
+ .def("queryValueDelimiter",
+ MEMFNP(char, QUrl, queryValueDelimiter,
+ () const))
+ // void removeAllEncodedQueryItems ( const QByteArray & key )
+ .def("removeAllEncodedQueryItems",
+ MEMFNP(void, QUrl, removeAllEncodedQueryItems,
+ ( const QByteArray & key )))
+ // void removeAllQueryItems ( const QString & key )
+ .def("removeAllQueryItems",
+ MEMFNP(void, QUrl, removeAllQueryItems,
+ ( const QString & key )))
+ // void removeEncodedQueryItem ( const QByteArray & key )
+ .def("removeEncodedQueryItem",
+ MEMFNP(void, QUrl, removeEncodedQueryItem,
+ ( const QByteArray & key )))
+ // void removeQueryItem ( const QString & key )
+ .def("removeQueryItem",
+ MEMFNP(void, QUrl, removeQueryItem,
+ ( const QString & key )))
+ // QUrl resolved ( const QUrl & relative ) const
+ .def("resolved",
+ MEMFNP(QUrl, QUrl, resolved,
+ ( const QUrl & relative ) const))
+ // QString scheme () const
+ .def("scheme",
+ MEMFNP(QString, QUrl, scheme,
+ () const))
+ // void setAuthority ( const QString & authority )
+ .def("setAuthority",
+ MEMFNP(void, QUrl, setAuthority,
+ ( const QString & authority )))
+ // void setEncodedFragment ( const QByteArray & fragment )
+ .def("setEncodedFragment",
+ MEMFNP(void, QUrl, setEncodedFragment,
+ ( const QByteArray & fragment )))
+ // void setEncodedHost ( const QByteArray & host )
+ .def("setEncodedHost",
+ MEMFNP(void, QUrl, setEncodedHost,
+ ( const QByteArray & host )))
+ // void setEncodedPassword ( const QByteArray & password )
+ .def("setEncodedPassword",
+ MEMFNP(void, QUrl, setEncodedPassword,
+ ( const QByteArray & password )))
+ // void setEncodedPath ( const QByteArray & path )
+ .def("setEncodedPath",
+ MEMFNP(void, QUrl, setEncodedPath,
+ ( const QByteArray & path )))
+ // void setEncodedQuery ( const QByteArray & query )
+ .def("setEncodedQuery",
+ MEMFNP(void, QUrl, setEncodedQuery,
+ ( const QByteArray & query )))
+ // void setEncodedQueryItems ( const QList<QPair<QByteArray, QByteArray> > & query )
+ // .def("setEncodedQueryItems",
+ // MEMFNP(void, QUrl, setEncodedQueryItems,
+ // ( const QList<QPair<QByteArray, QByteArray> > & query )))
+ // void setEncodedUrl ( const QByteArray & encodedUrl )
+ .def("setEncodedUrl",
+ MEMFNP(void, QUrl, setEncodedUrl,
+ ( const QByteArray & encodedUrl )))
+ // void setEncodedUrl ( const QByteArray & encodedUrl, ParsingMode parsingMode )
+ // .def("setEncodedUrl",
+ // MEMFNP(void, QUrl, setEncodedUrl,
+ // ( const QByteArray & encodedUrl, ParsingMode parsingMode )))
+ // void setEncodedUserName ( const QByteArray & userName )
+ .def("setEncodedUserName",
+ MEMFNP(void, QUrl, setEncodedUserName,
+ ( const QByteArray & userName )))
+ // void setFragment ( const QString & fragment )
+ .def("setFragment",
+ MEMFNP(void, QUrl, setFragment,
+ ( const QString & fragment )))
+ // void setHost ( const QString & host )
+ .def("setHost",
+ MEMFNP(void, QUrl, setHost,
+ ( const QString & host )))
+ // void setPassword ( const QString & password )
+ .def("setPassword",
+ MEMFNP(void, QUrl, setPassword,
+ ( const QString & password )))
+ // void setPath ( const QString & path )
+ .def("setPath",
+ MEMFNP(void, QUrl, setPath,
+ ( const QString & path )))
+ // void setPort ( int port )
+ .def("setPort",
+ MEMFNP(void, QUrl, setPort,
+ ( int port )))
+ // void setQueryDelimiters ( char valueDelimiter, char pairDelimiter )
+ .def("setQueryDelimiters",
+ MEMFNP(void, QUrl, setQueryDelimiters,
+ ( char valueDelimiter, char pairDelimiter )))
+ // void setQueryItems ( const QList<QPair<QString, QString> > & query )
+ // .def("setQueryItems",
+ // MEMFNP(void, QUrl, setQueryItems,
+ // ( const QList<QPair<QString, QString> > & query )))
+ // void setScheme ( const QString & scheme )
+ .def("setScheme",
+ MEMFNP(void, QUrl, setScheme,
+ ( const QString & scheme )))
+ // void setUrl ( const QString & url )
+ .def("setUrl",
+ MEMFNP(void, QUrl, setUrl,
+ ( const QString & url )))
+ // void setUrl ( const QString & url, ParsingMode parsingMode )
+ // .def("setUrl",
+ // MEMFNP(void, QUrl, setUrl,
+ // ( const QString & url, ParsingMode parsingMode )))
+ // void setUserInfo ( const QString & userInfo )
+ .def("setUserInfo",
+ MEMFNP(void, QUrl, setUserInfo,
+ ( const QString & userInfo )))
+ // void setUserName ( const QString & userName )
+ .def("setUserName",
+ MEMFNP(void, QUrl, setUserName,
+ ( const QString & userName )))
+ // QByteArray toEncoded ( FormattingOptions options = None ) const
+ // .def("toEncoded",
+ // MEMFNP(QByteArray, QUrl, toEncoded,
+ // ( FormattingOptions options = None ) const))
+ // QString toLocalFile () const
+ .def("toLocalFile",
+ MEMFNP(QString, QUrl, toLocalFile,
+ () const))
+ // QString toString ( FormattingOptions options = None ) const
+ .def("__unicode__", &QUrl_toString_noargs)
+ // QString userInfo () const
+ .def("userInfo",
+ MEMFNP(QString, QUrl, userInfo,
+ () const))
+ // QString userName () const
+ .def("userName",
+ MEMFNP(QString, QUrl, userName,
+ () const))
+
+ // bool operator!= ( const QUrl & url ) const
+ // QUrl & operator= ( const QUrl & url )
+ // QUrl & operator= ( const QString & url )
+ // bool operator== ( const QUrl & url ) const
+ ;
+}
+
+BOOST_PYTHON_MODULE(_pykit)
+{
+ py::class_<pykit::Request>("Request", py::no_init)
+ .def("write", &pykit::Request::write)
+ .def("reset", &pykit::Request::reset)
+ .def("setContentType", &pykit::Request::setContentType)
+ .def("setLocation", &pykit::Request::setLocation)
+ .def("url", &pykit::Request::url)
+ ;
+
+ py::class_<PublisherPyWrapper, boost::noncopyable>("Publisher")
+ .def("publish", py::pure_virtual(&pykit::Publisher::publish))
+ ;
+}
+
+prefix_ pykit::PythonPublisher::PythonPublisher(std::string initPy)
+{
+ PYTHON_PREPARE_IMPORT(_pykit);
+ PYTHON_PREPARE_IMPORT(_qt);
+ Py_Initialize();
+ py::object mainModule_ = py::import("__main__");
+ mainNamespace_ = py::extract<py::dict>(mainModule_.attr("__dict__"));
+ mainNamespace_["__file__"] = py::str(initPy.c_str());
+ py::object ignored (
+ py::exec_file(initPy.c_str(), mainNamespace_, mainNamespace_));
+ pythonPublisher_ = py::extract<Publisher*>(mainNamespace_["publisher"]);
+}
+
+prefix_ void pykit::PythonPublisher::publish(Request & request)
+{
+ try {
+ pythonPublisher_->publish(request);
+ }
+ catch (py::error_already_set & ex) {
+ PyErr_Print();
+ }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "PythonPublisher.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "j32"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -U"
+// End: