implement _httpapi python module
Stefan Bund [Fri, 14 Jan 2011 10:07:26 +0000 (11:07 +0100)]
.gitignore
PythonHTTP.cc [new file with mode: 0644]
PythonPublisher.cc
init.py
pykit.pro

index 3a846b5..96fcbbc 100644 (file)
@@ -9,3 +9,4 @@ moc_*
 /build-*/
 /Info.plist
 /object_script.*
+*.pyc
\ No newline at end of file
diff --git a/PythonHTTP.cc b/PythonHTTP.cc
new file mode 100644 (file)
index 0000000..04667d6
--- /dev/null
@@ -0,0 +1,128 @@
+// $Id$
+//
+// Copyright (C) 2011
+
+/** \file
+    \brief PythonHTTP non-inline non-template implementation */
+
+//#include "PythonHTTP.hh"
+//#include "PythonHTTP.ih"
+
+// Custom includes
+#include <boost/python.hpp>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+#include <QTimer>
+
+//#include "PythonHTTP.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace py = boost::python;
+
+namespace {
+
+    class Manager
+    {
+    public:
+        void post(QString const & url, QByteArray const & data, boost::python::object callback);
+
+    private:
+        QNetworkAccessManager mgr_;
+    };
+
+    class ReplyHandler : public QObject
+    {
+        Q_OBJECT;
+    public:
+        explicit ReplyHandler(boost::python::object callback, QNetworkReply * reply);
+        virtual ~ReplyHandler();
+
+    public slots:
+        void finished();
+
+    private:
+        boost::python::object callback_;
+        QNetworkReply * reply_;
+    };
+
+    class TimeoutHandler : public QObject
+    {
+        Q_OBJECT;
+    public:
+        explicit TimeoutHandler(boost::python::object callback, unsigned msecs);
+
+    public slots:
+        void timeout();
+
+    private:
+        boost::python::object callback_;
+        QTimer timer_;
+    };
+
+    void timeout(boost::python::object callback, unsigned msecs)
+    {
+        new TimeoutHandler(callback, msecs);
+    }
+}
+
+prefix_ void Manager::post(QString const & url, QByteArray const & data,
+                           boost::python::object callback)
+{
+    QNetworkRequest req;
+    req.setUrl(QUrl(url));
+    QNetworkReply * reply (mgr_.post(req, data));
+    new ReplyHandler(callback, reply);
+}
+
+prefix_ ReplyHandler::ReplyHandler(boost::python::object callback, QNetworkReply * reply)
+    : callback_ (callback), reply_ (reply)
+{
+    connect(reply_,SIGNAL(finished()),this,SLOT(finished()));
+}
+
+prefix_ ReplyHandler::~ReplyHandler()
+{}
+
+prefix_ void ReplyHandler::finished()
+{
+    callback_(reply_->error() == QNetworkReply::NoError, reply_->readAll());
+    reply_->deleteLater();
+    deleteLater();
+}
+
+prefix_ TimeoutHandler::TimeoutHandler(boost::python::object callback, unsigned msecs)
+    : callback_ (callback)
+{
+    timer_.setSingleShot(true);
+    timer_.start(msecs);
+    connect(&timer_, SIGNAL(timeout()), this, SLOT(timeout()));
+}
+
+prefix_ void TimeoutHandler::timeout()
+{
+    callback_();
+    deleteLater();
+}
+
+BOOST_PYTHON_MODULE(_httpapi)
+{
+    py::class_<Manager, boost::noncopyable>("Manager")
+        .def("post", &Manager::post)
+        ;
+
+    py::def("timeout", &timeout);
+}
+
+#include "PythonHTTP.moc"
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "PythonHTTP.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// indent-tabs-mode: nil
+// End:
index fc29b6f..410f707 100644 (file)
@@ -26,6 +26,8 @@ struct pykit::PythonPublisher::Impl
     Publisher * pythonPublisher;
 };
 
+#define PYTHON_EXTERN_MODULE(module) \
+    extern "C" { void init ## module (); }
 #define PYTHON_PREPARE_IMPORT(module) \
     PyImport_AppendInittab(const_cast<char*>(#module), init ## module)
 
@@ -436,12 +438,15 @@ BOOST_PYTHON_MODULE(_pykit)
         ;
 }
 
+PYTHON_EXTERN_MODULE(_httpapi);
+
 prefix_ pykit::PythonPublisher::PythonPublisher()
     : impl_ (new Impl)
 {
     try {
         PYTHON_PREPARE_IMPORT(_pykit);
         PYTHON_PREPARE_IMPORT(_qt);
+        PYTHON_PREPARE_IMPORT(_httpapi);
         Py_Initialize();
         py::object initModule = py::import("init");
         impl_->mainNamespace = py::extract<py::dict>(initModule.attr("__dict__"));
diff --git a/init.py b/init.py
index b0981f9..80d9e00 100644 (file)
--- a/init.py
+++ b/init.py
@@ -1,8 +1,17 @@
-import _pykit, _qt
+import _pykit, _qt, _httpapi
+
+mgr = _httpapi.Manager()
+
+def ready(success, data):
+    print ">> response complete:", success, repr(data)
 
 class Publisher(_pykit.Publisher):
     def publish(self, request):
         request.setContentType('text/html')
         request.write("<html><body><h1>PyKit up and running</h1></body></html>")
+        mgr.post(u"http://home.j32.de/", "data",ready)
 
 publisher = Publisher()
+
+def initialize():
+    return publisher
index d36f6c5..e204b7c 100644 (file)
--- a/pykit.pro
+++ b/pykit.pro
@@ -54,11 +54,13 @@ win32 {
 HEADERS += MainWindow.hh \
            Publisher.hh \
            PythonPublisher.hh \
+           PythonHTTP.hh \
            Viewer.hh
 SOURCES += main.cc \
            MainWindow.cc \
            Publisher.cc \
            PythonPublisher.cc \
+           PythonHTTP.cc \
            Viewer.cc
 
 # poppler