summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-05-29 00:44:49 +0000
committerDavid Robillard <d@drobilla.net>2009-05-29 00:44:49 +0000
commit085f5e9c5eec12171596c47c0b70f6634dbc1402 (patch)
tree16df3f452c174bbd1f1099936dc592939a59967e
parentb3c31c94eb572063ec97f24a89e5f7f98d5eae41 (diff)
downloadingen-085f5e9c5eec12171596c47c0b70f6634dbc1402.tar.gz
ingen-085f5e9c5eec12171596c47c0b70f6634dbc1402.tar.bz2
ingen-085f5e9c5eec12171596c47c0b70f6634dbc1402.zip
Node creation via HTTP.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2045 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/client/ClientStore.cpp2
-rw-r--r--src/client/HTTPClientReceiver.cpp3
-rw-r--r--src/client/HTTPEngineSender.cpp34
-rw-r--r--src/client/HTTPEngineSender.hpp12
-rw-r--r--src/client/client.cpp5
-rw-r--r--src/client/client.hpp6
-rw-r--r--src/engine/HTTPClientSender.cpp29
-rw-r--r--src/engine/HTTPEngineReceiver.cpp15
-rw-r--r--src/engine/QueuedEngineInterface.cpp9
-rw-r--r--src/ingen/main.cpp5
-rw-r--r--src/serialisation/Parser.cpp18
11 files changed, 97 insertions, 41 deletions
diff --git a/src/client/ClientStore.cpp b/src/client/ClientStore.cpp
index bb501079..7a2a4ef5 100644
--- a/src/client/ClientStore.cpp
+++ b/src/client/ClientStore.cpp
@@ -327,7 +327,7 @@ ClientStore::put(const URI& uri, const Resource::Properties& properties)
p->set_properties(properties);
add_object(p);
} else {
- cerr << "WARNING: Illegal port " << path << endl;
+ cerr << "WARNING: Port " << path << " is malformed" << endl;
}
} else {
cerr << "WARNING: Ignoring object " << path << " with unknown type "
diff --git a/src/client/HTTPClientReceiver.cpp b/src/client/HTTPClientReceiver.cpp
index 6d0dbb1b..be1b6238 100644
--- a/src/client/HTTPClientReceiver.cpp
+++ b/src/client/HTTPClientReceiver.cpp
@@ -99,7 +99,7 @@ HTTPClientReceiver::Listener::Listener(HTTPClientReceiver* receiver, const std::
void
HTTPClientReceiver::update(const std::string& str)
{
- cout << _parser->parse_update(_world, _target.get(), str, ".");
+ cout << _parser->parse_update(_world, _target.get(), str, "");
}
void
@@ -180,6 +180,7 @@ HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, voi
} else {
cerr << "UNKNOWN MESSAGE: " << path << endl;
+ me->update(msg->response_body->data);
}
}
diff --git a/src/client/HTTPEngineSender.cpp b/src/client/HTTPEngineSender.cpp
index 692d01fc..fa3509f6 100644
--- a/src/client/HTTPEngineSender.cpp
+++ b/src/client/HTTPEngineSender.cpp
@@ -17,8 +17,12 @@
#include <iostream>
#include <libsoup/soup.h>
+#include "raul/AtomRDF.hpp"
+#include "redlandmm/Model.hpp"
+#include "module/World.hpp"
#include "HTTPEngineSender.hpp"
+
using namespace std;
using namespace Raul;
@@ -27,8 +31,9 @@ using namespace Shared;
namespace Client {
-HTTPEngineSender::HTTPEngineSender(const URI& engine_url)
- : _engine_url(engine_url)
+HTTPEngineSender::HTTPEngineSender(const World* world, const URI& engine_url)
+ : _world(*world->rdf_world)
+ , _engine_url(engine_url)
, _id(0)
, _enabled(true)
{
@@ -103,11 +108,32 @@ HTTPEngineSender::quit()
// Object commands
+void
+HTTPEngineSender::message_callback(SoupSession* session, SoupMessage* msg, void* ptr)
+{
+ cerr << "HTTP CALLBACK" << endl;
+}
+
void
-HTTPEngineSender::put(const Raul::URI& path,
- const Shared::Resource::Properties& properties)
+HTTPEngineSender::put(const URI& uri,
+ const Resource::Properties& properties)
{
+ const string path = (uri.substr(0, 6) == "path:/") ? uri.substr(6) : uri.str();
+ const string full_uri = _engine_url.str() + "/" + path;
+
+ Redland::Model model(_world);
+ for (Resource::Properties::const_iterator i = properties.begin(); i != properties.end(); ++i)
+ model.add_statement(
+ Redland::Resource(_world, path),
+ i->first.str(),
+ AtomRDF::atom_to_node(_world, i->second));
+
+ const string str = model.serialise_to_string();
+ SoupMessage* msg = soup_message_new("PUT", full_uri.c_str());
+ assert(msg);
+ soup_message_set_request(msg, "application/x-turtle", SOUP_MEMORY_COPY, str.c_str(), str.length());
+ soup_session_send_message(_session, msg);
}
diff --git a/src/client/HTTPEngineSender.hpp b/src/client/HTTPEngineSender.hpp
index 00df2d7e..b5f8cfa5 100644
--- a/src/client/HTTPEngineSender.hpp
+++ b/src/client/HTTPEngineSender.hpp
@@ -23,8 +23,12 @@
#include <libsoup/soup.h>
#include "raul/Path.hpp"
#include "interface/EngineInterface.hpp"
+#include "redlandmm/World.hpp"
namespace Ingen {
+
+namespace Shared { class World; }
+
namespace Client {
@@ -35,9 +39,10 @@ namespace Client {
*
* \ingroup IngenClient
*/
-class HTTPEngineSender : public Shared::EngineInterface {
+class HTTPEngineSender : public Shared::EngineInterface
+{
public:
- HTTPEngineSender(const Raul::URI& engine_url);
+ HTTPEngineSender(const Shared::World* world, const Raul::URI& engine_url);
~HTTPEngineSender();
Raul::URI uri() const { return _engine_url; }
@@ -115,7 +120,10 @@ public:
void request_all_objects();
protected:
+ static void message_callback(SoupSession* session, SoupMessage* msg, void* ptr);
+
SoupSession* _session;
+ Redland::World& _world;
const Raul::URI _engine_url;
int _client_port;
int32_t _id;
diff --git a/src/client/client.cpp b/src/client/client.cpp
index 3ced5f63..53d7810f 100644
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -26,6 +26,7 @@
#include "HTTPEngineSender.hpp"
#endif
+
using namespace std;
namespace Ingen {
@@ -33,7 +34,7 @@ namespace Client {
SharedPtr<Ingen::Shared::EngineInterface>
-new_remote_interface(const std::string& url)
+new_remote_interface(Ingen::Shared::World* world, const std::string& url)
{
const string scheme = url.substr(0, url.find(":"));
@@ -47,7 +48,7 @@ new_remote_interface(const std::string& url)
#ifdef HAVE_SOUP
if (scheme == "http") {
- HTTPEngineSender* hes = new HTTPEngineSender(url);
+ HTTPEngineSender* hes = new HTTPEngineSender(world, url);
hes->attach(rand(), true);
return SharedPtr<Shared::EngineInterface>(hes);
}
diff --git a/src/client/client.hpp b/src/client/client.hpp
index b2543c22..9ad1423a 100644
--- a/src/client/client.hpp
+++ b/src/client/client.hpp
@@ -24,13 +24,15 @@ namespace Ingen {
class Engine;
-namespace Shared { class EngineInterface; }
+namespace Shared { class EngineInterface; class World; }
namespace Client {
extern "C" {
- SharedPtr<Shared::EngineInterface> new_remote_interface(const std::string& url);
+ SharedPtr<Shared::EngineInterface> new_remote_interface(
+ Shared::World* world, const std::string& url);
+
SharedPtr<Shared::EngineInterface> new_queued_interface(SharedPtr<Ingen::Engine> engine);
}
diff --git a/src/engine/HTTPClientSender.cpp b/src/engine/HTTPClientSender.cpp
index 6735c164..d77f684e 100644
--- a/src/engine/HTTPClientSender.cpp
+++ b/src/engine/HTTPClientSender.cpp
@@ -16,6 +16,7 @@
*/
#include <string>
+#include <libsoup/soup.h>
#include "raul/Atom.hpp"
#include "raul/AtomRDF.hpp"
#include "serialisation/Serialiser.hpp"
@@ -28,17 +29,18 @@ using namespace Raul;
namespace Ingen {
+using namespace Shared;
+
void
HTTPClientSender::response_ok(int32_t id)
{
- cout << "HTTP OK" << endl;
}
void
HTTPClientSender::response_error(int32_t id, const std::string& msg)
{
- cout << "HTTP ERROR" << endl;
+ cout << "HTTP ERROR " << id << ": " << msg << endl;
}
@@ -50,10 +52,21 @@ HTTPClientSender::error(const std::string& msg)
void
-HTTPClientSender::put(const URI& path,
- const Shared::Resource::Properties& properties)
+HTTPClientSender::put(const URI& uri,
+ const Resource::Properties& properties)
{
- cerr << "HTTP CLIENT PUT " << path << endl;
+ const string path = (uri.substr(0, 6) == "path:/") ? uri.substr(6) : uri.str();
+ const string full_uri = _url + "/" + path;
+
+ Redland::Model model(*_engine.world()->rdf_world);
+ for (Resource::Properties::const_iterator i = properties.begin(); i != properties.end(); ++i)
+ model.add_statement(
+ Redland::Resource(*_engine.world()->rdf_world, path),
+ i->first.str(),
+ AtomRDF::atom_to_node(*_engine.world()->rdf_world, i->second));
+
+ const string str = model.serialise_to_string();
+ send_chunk(str);
}
@@ -138,16 +151,16 @@ HTTPClientSender::activity(const Path& path)
}
#if 0
-static void null_deleter(const Shared::GraphObject*) {}
+static void null_deleter(const GraphObject*) {}
bool
-HTTPClientSender::new_object(const Shared::GraphObject* object)
+HTTPClientSender::new_object(const GraphObject* object)
{
SharedPtr<Serialisation::Serialiser> serialiser = _engine.world()->serialiser;
serialiser->start_to_string("/", "");
// FIXME: kludge
// FIXME: engine boost dependency?
- boost::shared_ptr<Shared::GraphObject> obj((Shared::GraphObject*)object, null_deleter);
+ boost::shared_ptr<GraphObject> obj((GraphObject*)object, null_deleter);
serialiser->serialise(obj);
string str = serialiser->finish();
send_chunk(str);
diff --git a/src/engine/HTTPEngineReceiver.cpp b/src/engine/HTTPEngineReceiver.cpp
index 61d74ada..b2d3ca99 100644
--- a/src/engine/HTTPEngineReceiver.cpp
+++ b/src/engine/HTTPEngineReceiver.cpp
@@ -153,6 +153,7 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
soup_message_set_status(msg, SOUP_STATUS_OK);
soup_message_set_response(msg, mime_type, SOUP_MEMORY_COPY, r.c_str(), r.length());
return;
+
} else if (path.substr(0, 6) == "/patch") {
path = '/' + path.substr(6);
@@ -167,15 +168,10 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
soup_message_set_status(msg, SOUP_STATUS_OK);
soup_message_set_response(msg, mime_type, SOUP_MEMORY_COPY, buf, strlen(buf));
return;
-
- } else {
- soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND);
- soup_message_set_response(msg, "text/plain", SOUP_MEMORY_STATIC,
- "Unknown path\n\n", 14);
- return;
}
if (!Path::is_valid(path)) {
+ cerr << "HTTP BAD REQUEST" << endl;
soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
const string& err = (boost::format("Bad path: %1%") % path).str();
soup_message_set_response(msg, "text/plain", SOUP_MEMORY_COPY,
@@ -223,6 +219,7 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
// Be sure object doesn't exist
Store::const_iterator start = store->find(path);
if (start != store->end()) {
+ cerr << "HTTP CONFLICT" << endl;
soup_message_set_status(msg, SOUP_STATUS_CONFLICT);
return;
}
@@ -230,16 +227,18 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const
// Get parser
SharedPtr<Parser> parser = me->_engine.world()->parser;
if (!parser) {
+ cerr << "HTTP INTERNAL ERROR" << endl;
soup_message_set_status(msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
return;
}
- //cout << "POST: " << msg->request_body->data << endl;
+ parser->parse_string(me->_engine.world(), me, msg->request_body->data, "");
// Load object
soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
+
} else if (msg->method == SOUP_METHOD_POST) {
- //cout << "PUT: " << msg->request_body->data << endl;
+ cout << "POST" << endl;
soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
} else {
soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
diff --git a/src/engine/QueuedEngineInterface.cpp b/src/engine/QueuedEngineInterface.cpp
index cce6bb9d..4873f21b 100644
--- a/src/engine/QueuedEngineInterface.cpp
+++ b/src/engine/QueuedEngineInterface.cpp
@@ -155,17 +155,16 @@ void
QueuedEngineInterface::put(const URI& uri,
const Resource::Properties& properties)
{
- size_t hash = uri.find("#");
- bool meta = (hash != string::npos);
- Path path(meta ? (string("/") + uri.chop_start("#")) : uri.str());
+ bool meta = uri.substr(0, 6) == "meta:#";
+ URI subject(meta ? (string("path:/") + uri.substr(6)) : uri.str());
+ /*cerr << "ENGINE PUT " << subject << " {" << endl;
typedef Resource::Properties::const_iterator iterator;
- /*cerr << "ENGINE PUT " << path << " (" << path << ") {" << endl;
for (iterator i = properties.begin(); i != properties.end(); ++i)
cerr << "\t" << i->first << " = " << i->second << " :: " << i->second.type() << endl;
cerr << "}" << endl;*/
- push_queued(new SetMetadataEvent(_engine, _responder, now(), this, meta, path, properties));
+ push_queued(new SetMetadataEvent(_engine, _responder, now(), this, meta, subject, properties));
}
diff --git a/src/ingen/main.cpp b/src/ingen/main.cpp
index 647aa9dd..3ead6146 100644
--- a/src/ingen/main.cpp
+++ b/src/ingen/main.cpp
@@ -189,10 +189,11 @@ main(int argc, char** argv)
/* If we don't have a local engine interface (for GUI), use network */
if (client_module && ! engine_interface) {
- SharedPtr<Shared::EngineInterface> (*new_remote_interface)(const std::string&) = NULL;
+ SharedPtr<Shared::EngineInterface> (*new_remote_interface)
+ (Ingen::Shared::World*, const std::string&) = NULL;
if (client_module->get_symbol("new_remote_interface", (void*&)new_remote_interface)) {
- engine_interface = new_remote_interface(args.connect_arg);
+ engine_interface = new_remote_interface(world, args.connect_arg);
} else {
cerr << "Unable to find symbol 'new_remote_interface' in "
"ingen_client module, aborting." << endl;
diff --git a/src/serialisation/Parser.cpp b/src/serialisation/Parser.cpp
index e01adc1f..50e00439 100644
--- a/src/serialisation/Parser.cpp
+++ b/src/serialisation/Parser.cpp
@@ -167,7 +167,7 @@ Parser::parse_update(
target->del(object.to_string());
}
- // Variable settings
+ // Properties
query = Redland::Query(*world->rdf_world,
"SELECT DISTINCT ?s ?p ?o WHERE {\n"
"?s ?p ?o .\n"
@@ -177,17 +177,19 @@ Parser::parse_update(
for (Redland::Query::Results::iterator i = results.begin(); i != results.end(); ++i) {
Glib::Mutex::Lock lock(world->rdf_world->mutex());
- const string obj_uri((*i)["s"].to_string());
+ string obj_uri((*i)["s"].to_string());
const string key(world->rdf_world->qualify((*i)["p"].to_string()));
const Redland::Node& val_node((*i)["o"]);
const Atom a(AtomRDF::node_to_atom(val_node));
+ if (obj_uri.find(":") == string::npos)
+ obj_uri = "path:" + obj_uri;
if (key != "")
target->set_property(obj_uri, key, a);
}
// Connections
- parse_connections(world, target, model, base_uri, "/");
+ //parse_connections(world, target, model, base_uri, "/");
// Port values
query = Redland::Query(*world->rdf_world,
@@ -286,7 +288,7 @@ Parser::parse(
} else if (rdf_class == node_class) {
ret = parse_node(world, target, model, subject, path, data);
} else if (rdf_class == in_port_class || rdf_class == out_port_class) {
- cerr << "PARSE PORT" << endl;
+ parse_properties(world, target, model, subject, string("path:") + path, data);
}
if (!ret) {
@@ -298,8 +300,12 @@ Parser::parse(
root_path = ret;
} else if (is_plugin) {
- if (URI::is_valid(subject.to_string()))
- parse_properties(world, target, model, subject, subject.to_string());
+ string subject_str = subject.to_string();
+ if (URI::is_valid(subject_str)) {
+ if (subject == document_uri)
+ subject_str = Path::root_uri;
+ parse_properties(world, target, model, subject, subject_str);
+ }
}
}