summaryrefslogtreecommitdiff
path: root/processmodel/processmodel.cpp
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-06-05 15:18:54 +0100
committerTim Redfern <tim@eclectronics.org>2013-06-05 15:18:54 +0100
commita8c3d2a9432f397f5098594f0572cc6999b63f3a (patch)
tree7709a215dd0e6b7fe488d34fee2cfe1a04084109 /processmodel/processmodel.cpp
parent66210c73084c643c9c7169ca6f46d1cf47489248 (diff)
working version
Diffstat (limited to 'processmodel/processmodel.cpp')
-rw-r--r--processmodel/processmodel.cpp274
1 files changed, 267 insertions, 7 deletions
diff --git a/processmodel/processmodel.cpp b/processmodel/processmodel.cpp
index 19ad57f..ec78099 100644
--- a/processmodel/processmodel.cpp
+++ b/processmodel/processmodel.cpp
@@ -1,16 +1,249 @@
-#include "Poco/Process.h"
-#include "Poco/PipeStream.h"
-#include "Poco/StreamCopier.h"
-#include <fstream>
-#include <iostream>
-using Poco::Process;
-using Poco::ProcessHandle;
+#include "processmodel.h"
//1. make a basic executable that represents a render context
//get message passing going
//incorporate in REST server
//fill in the details
+RotorRequestHandler::RotorRequestHandler(const std::string& format): _format(format){
+}
+
+void RotorRequestHandler::handleRequest(HTTPServerRequest& request,HTTPServerResponse& response) {
+
+ Timestamp now;
+ std::string dt(DateTimeFormatter::format(now, _format));
+
+ response.setChunkedTransferEncoding(true);
+ response.setContentType("text/html");
+
+ std::ostream& ostr = response.send();
+ ostr << "<html><head><title>RotorServer powered by "
+ "POCO C++ Libraries</title>";
+ ostr << "</head>";
+ ostr << "<body><p style=\"text-align: center; "
+ "font-size: 48px;\">";
+ ostr << dt;
+ ostr << "</p></body></html>";
+}
+
+
+AudioAnalyserHandler::AudioAnalyserHandler(const vampHost::Settings& _settings): settings(_settings){
+}
+
+void AudioAnalyserHandler::handleRequest(HTTPServerRequest& request,HTTPServerResponse& response) {
+
+ response.setChunkedTransferEncoding(true);
+ response.setContentType("text/html");
+
+ //string audioData=vampHost::runPlugin();
+
+ std::ostream& ostr = response.send();
+ ostr << "<html><head><title>RotorServer powered by "
+ "POCO C++ Libraries</title>";
+ ostr << "</head>";
+ ostr << "<body><p style=\"text-align: center; "
+ "font-size: 48px;\">";
+ vampHost::runPlugin("",settings.soname,settings.filtername, "",0, settings.inputFile, ostr,true);
+ ostr << "</p></body></html>";
+}
+
+RenderContextHandler::RenderContextHandler(const std::string _content,const HTTPServerResponse::HTTPStatus _status){
+ content=_content;
+ status=_status;
+}
+
+
+void RenderContextHandler::handleRequest(HTTPServerRequest& request,HTTPServerResponse& response) {
+
+ response.setChunkedTransferEncoding(true);
+ response.setContentType("text/html");
+ response.setStatus(status);
+
+ std::ostream& ostr = response.send();
+
+ ostr << "<?xml version='1.0' encoding='ISO-8859-1'?>\n";
+ ostr << content;
+
+}
+
+
+HTTPRequestHandler* RotorRequestHandlerFactory::createRequestHandler(const HTTPServerRequest& request){
+ Application& app = Application::instance();
+
+ Poco::URI theuri=Poco::URI(request.getURI());
+ std::vector <std::string> command;
+ theuri.getPathSegments(command);
+
+ app.logger().information(request.clientAddress().toString()+" "+request.getMethod());
+
+ string content="";
+ HTTPResponse::HTTPStatus status=HTTPResponse::HTTP_BAD_REQUEST; //by default
+
+ std::string body;
+ std::ostringstream os;
+ os<<request.stream().rdbuf();
+ body=os.str();
+
+ /*
+
+ if (command.size()) {
+ if (command[0]=="new") {
+ if (request.getMethod()=="GET") {
+ string sID=idGen.createOne().toString(); //create() seems to cause problems
+ //Creates a new time-based UUID, using the MAC address of one of the system's ethernet adapters.
+ //Throws a SystemException if no MAC address can be obtained.
+ //
+ //seems to hang, to me
+ cerr << "Rotor: starting thread "<< sID << endl;
+ manager.start(new Rotor::Render_context(sID));
+ content="<sID>"+sID+"</sID>\n";
+ status=HTTPResponse::HTTP_OK;
+ }
+ if (request.getMethod()=="PUT") { //undocumented manual thread name
+ if (body.size()) {
+ string sID=body;
+ cerr << "Rotor: starting thread "<< sID << endl;
+ manager.start(new Rotor::Render_context(sID));
+ content="<sID>"+sID+"</sID>\n";
+ status=HTTPResponse::HTTP_OK;
+ }
+ }
+ }
+ else if (command[0]=="list") {
+ if (request.getMethod()=="GET") {
+ //std::list < Poco::AutoPtr < Poco::Task > >::iterator it;
+ //it=manager.taskList().begin();
+ //for (it=manager.taskList().begin();it !=manager.taskList().end();++it) {
+ //content+="<sID>"+(*it)->name()+"</sID>\n";
+ //}
+
+ //massive problems making an iterator for the tasklist, the above crashes
+ //solution: auto type range-based for-loop
+ //this is c++11 specific but works
+
+ for (auto& task: manager.taskList()) { //c++11
+ content+="<sID>"+task->name()+" </sID>\n";
+ }
+ status=HTTPResponse::HTTP_OK;
+ }
+ }
+ else if (command[0]=="styles") {
+ //eventually retrieve from sql;
+ //a bit of weirdness here: prefer to just get whole file to a string.
+ if (request.getMethod()=="GET") {
+ std::string stylesfile = "styles.xml";
+ Poco::File f=Poco::File(stylesfile);
+ if (f.exists()) {
+ Poco::FileInputStream file(stylesfile);
+ //while (!file.eof()) {
+ // file >> content;
+ //}
+ Poco::StreamCopier::copyToString(file, content);
+ status=HTTPResponse::HTTP_OK;
+ }
+ else {
+ content="<status>Rotor: internal error: styles not found</status>\n";
+ }
+
+ }
+ else {
+ content="<status>Rotor: bad request</status>\n";
+ }
+ }
+ else if (command[0]=="exit") {
+ exit(0);
+ }
+ else {
+ bool found=false;
+ for (auto& task: manager.taskList()) { //c++11
+ if(task->name()==command[0]) {
+ //valid session command
+ found=true;
+ if (command.size()==1) {
+ //just invoking sID
+ if (request.getMethod()=="DELETE") {
+ task->cancel();
+ content="<status>1</status>\n";
+ status=HTTPResponse::HTTP_OK;
+ }
+ else {
+ content="<status>Rotor: render context invoked with no command</status>\n";
+ }
+ }
+ else { //session modifier command- to be passed to render context
+ //some commands need to return error codes
+ //ie where the audio file isn't found
+ //on the other hand, some commands need to know state of the renderer?
+
+
+ vector<string> sc; //method,id,command1,{command2,}{body}
+ sc.push_back(request.getMethod());
+ for (auto& i: command){
+ sc.push_back(i);
+ }
+ sc.push_back(body);
+
+ Rotor::Command_response response=((Poco::AutoPtr<Rotor::Render_context>)task)->session_command(sc);
+
+ content=response.description;
+ status=response.status;
+
+ }
+ }
+ }
+ if (!found) {
+ status=HTTPResponse::HTTP_NOT_FOUND;
+ content="<status>Rotor: render context not found</status>\n";
+ }
+ }
+ }
+ else {
+ content="<status>Rotor: empty request</status>";
+ }
+ */
+ return new RenderContextHandler(content, status);
+}
+
+
+RotorServer::RotorServer(): _helpRequested(false)
+{
+}
+
+RotorServer::~RotorServer()
+{
+}
+
+void RotorServer::initialize(Application& self){
+ loadConfiguration();
+ ServerApplication::initialize(self);
+}
+
+void RotorServer::uninitialize(){
+ ServerApplication::uninitialize();
+}
+
+void RotorServer::defineOptions(OptionSet& options) {
+ ServerApplication::defineOptions(options);
+ options.addOption(
+ Option("help", "h", "display argument help information")
+ .required(false)
+ .repeatable(false)
+ .callback(OptionCallback<RotorServer>(this, &RotorServer::handleHelp)
+ )
+ );
+}
+
+void RotorServer::handleHelp(const std::string& name, const std::string& value){
+ HelpFormatter helpFormatter(options());
+ helpFormatter.setCommand(commandName());
+ helpFormatter.setUsage("OPTIONS");
+ helpFormatter.setHeader(
+ "Rotor");
+ helpFormatter.format(std::cout);
+ stopOptionsProcessing();
+ _helpRequested = true;
+}
+
int main(int argc, char** argv)
{
@@ -33,4 +266,31 @@ int main(int argc, char** argv)
return 0;
}
else std::cerr<<"usage: processmodel [executable]"<<std::endl;
+}
+
+
+int RotorServer::main(const std::vector<std::string>& args){
+ if (!_helpRequested) {
+
+ unsigned short port;
+
+ xmlIO xml;
+ if(xml.loadFile("settings.xml") ){
+ port=xml.getAttribute("Rotor","port",9980,0);
+ }
+ else cerr<<"Rotord: settings.xml not found, using defaults"<<endl;
+
+ port = (unsigned short) config().getInt("port", port); //override from command line
+
+ std::string format(config().getString("format", DateTimeFormat::SORTABLE_FORMAT));
+
+
+
+ ServerSocket svs(port);
+ HTTPServer srv(new RotorRequestHandlerFactory(),svs, new HTTPServerParams);
+ srv.start();
+ waitForTerminationRequest();
+ srv.stop();
+ }
+ return Application::EXIT_OK;
} \ No newline at end of file