typo fix
[pykit.git] / PythonPublisher.cc
index d71cdee..f1699d4 100644 (file)
@@ -13,6 +13,9 @@
 #include <iostream>
 #include <boost/python.hpp>
 #include "Publisher.hh"
+#include <QDesktopServices>
+#include <QWebHistory>
+#include "Viewer.hh"
 
 //#include "PythonPublisher.mpp"
 #define prefix_
@@ -26,6 +29,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)
 
@@ -416,6 +421,30 @@ BOOST_PYTHON_MODULE(_qt)
         ;
 }
 
+namespace {
+
+    bool canGoBack()
+    {
+        return pykit::Viewer::instance()->page()->history()->canGoBack();
+    }
+
+    bool canGoForward()
+    {
+        return pykit::Viewer::instance()->page()->history()->canGoForward();
+    }
+
+    class ErrorCatcher
+    {
+    public:
+        explicit ErrorCatcher(std::string & out) : out_ (out) {}
+        void write(std::string const & msg)
+            { std::cerr << "append: " << msg; out_ += msg; }
+    private:
+        std::string & out_;
+    };
+
+}
+
 BOOST_PYTHON_MODULE(_pykit)
 {
     py::class_<pykit::Request>("Request", py::no_init)
@@ -423,33 +452,65 @@ BOOST_PYTHON_MODULE(_pykit)
         .def("reset", &pykit::Request::reset)
         .def("setContentType", &pykit::Request::setContentType)
         .def("setLocation", &pykit::Request::setLocation)
+        .def("setRawHeader", &pykit::Request::setHeader)
+        .def("setStatusCode", &pykit::Request::setStatusCode)
         .def("url", &pykit::Request::url)
+        .def("postData", &pykit::Request::postData)
+        .def("operation", &pykit::Request::operation)
+        .def("postContentType", &pykit::Request::postContentType)
         ;
 
     py::class_<PublisherPyWrapper, boost::noncopyable>("Publisher")
         .def("publish", py::pure_virtual(&pykit::Publisher::publish))
         ;
+
+    py::class_<ErrorCatcher>("ErrorCatcher", py::no_init)
+        .def("write", &ErrorCatcher::write)
+        ;
+
+    py::def("openUrl", &QDesktopServices::openUrl);
+
+    py::def("canGoBack", &canGoBack);
+    py::def("canGoForward", &canGoForward);
 }
 
+PYTHON_EXTERN_MODULE(_httpapi);
+
 prefix_ pykit::PythonPublisher::PythonPublisher()
     : impl_ (new Impl)
 {
+    std::string pyError;
     try {
         PYTHON_PREPARE_IMPORT(_pykit);
         PYTHON_PREPARE_IMPORT(_qt);
+        PYTHON_PREPARE_IMPORT(_httpapi);
         Py_Initialize();
-        py::object initModule = py::import("init");
+
+        py::import("_pykit");
+        py::object sysModule (py::import("sys"));
+        py::object origStderr (sysModule.attr("stderr"));
+        ErrorCatcher catcher (pyError);
+        sysModule.attr("stderr") = catcher;
+
+        py::object initModule (py::import("init"));
         impl_->mainNamespace = py::extract<py::dict>(initModule.attr("__dict__"));
         impl_->pythonPublisher = py::extract<Publisher*>(impl_->mainNamespace["initialize"]());
+
+        sysModule.attr("stderr") = origStderr;
     }
     catch (boost::python::error_already_set & ex) {
         PyErr_Print();
-        throw;
+        throw PythonError(pyError);
     }
 }
 
 prefix_ pykit::PythonPublisher::~PythonPublisher()
-{}
+{
+    try {
+        impl_->mainNamespace["shutdown"]();
+    }
+    catch (...) {;}
+}
 
 prefix_ void pykit::PythonPublisher::publish(Request & request)
 {
@@ -458,6 +519,7 @@ prefix_ void pykit::PythonPublisher::publish(Request & request)
     }
     catch (py::error_already_set & ex) {
         PyErr_Print();
+        PyErr_Clear();
     }
 }