summaryrefslogtreecommitdiff
path: root/libs/surfaces
diff options
context:
space:
mode:
authorLuciano Iam <lucianito@gmail.com>2020-04-09 16:07:19 +0200
committerRobin Gareus <robin@gareus.org>2020-04-09 20:56:46 +0200
commitc946eb3132f36578f1a4cae75c938348c6d9822a (patch)
tree90ab2c6c87f08ed6e0f7aac14f813aac4faabcae /libs/surfaces
parent40520a6dc61de135c09cdfb0097910b766ccb6ee (diff)
Add classes for serving content over HTTP
Diffstat (limited to 'libs/surfaces')
-rw-r--r--libs/surfaces/websockets/manifest.cc83
-rw-r--r--libs/surfaces/websockets/manifest.h46
-rw-r--r--libs/surfaces/websockets/resources.cc171
-rw-r--r--libs/surfaces/websockets/resources.h53
4 files changed, 353 insertions, 0 deletions
diff --git a/libs/surfaces/websockets/manifest.cc b/libs/surfaces/websockets/manifest.cc
new file mode 100644
index 0000000000..80c900ecf7
--- /dev/null
+++ b/libs/surfaces/websockets/manifest.cc
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2020 Luciano Iam <lucianito@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the/GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <iostream>
+#include <sstream>
+#include <glibmm/miscutils.h>
+
+#include "pbd/xml++.h"
+
+#include "manifest.h"
+
+SurfaceManifest::SurfaceManifest (std::string xml_path)
+{
+ XMLTree tree;
+
+ if (!tree.read (xml_path.c_str())) {
+#ifndef NDEBUG
+ std::cerr << "SurfaceManifest: could not parse " << xml_path << std::endl;
+#endif
+ return;
+ }
+
+ XMLNodeList nlist = tree.root ()->children ();
+
+ for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
+ XMLNode* node = *niter;
+ std::string name = node->name ();
+ std::string value;
+
+ node->get_property ("value", value);
+
+ if (name == "Id") {
+ _id = value;
+ } else if (name == "Name") {
+ _name = value;
+ } else if (name == "Description") {
+ _description = value;
+ }
+ }
+
+#ifndef NDEBUG
+ if (_name.empty () || _description.empty ()) {
+ std::cerr << "SurfaceManifest: missing properties in " << xml_path << std::endl;
+ return;
+ }
+#endif
+
+ if (_id.empty ()) {
+ // default to manifest subdirectory name
+ _id = Glib::path_get_basename (Glib::path_get_dirname (xml_path));
+ }
+
+ _valid = true;
+}
+
+std::string
+SurfaceManifest::to_json ()
+{
+ std::stringstream ss;
+
+ ss << "{"
+ << "\"id\":\"" << _id << "\""
+ << ",\"name\":\"" << _name << "\""
+ << ",\"description\":\"" << _description << "\""
+ << "}";
+
+ return ss.str ();
+}
diff --git a/libs/surfaces/websockets/manifest.h b/libs/surfaces/websockets/manifest.h
new file mode 100644
index 0000000000..19e6ba943e
--- /dev/null
+++ b/libs/surfaces/websockets/manifest.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 Luciano Iam <lucianito@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the/GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _ardour_surface_websockets_manifest_h_
+#define _ardour_surface_websockets_manifest_h_
+
+#include <string>
+
+class SurfaceManifest
+{
+public:
+ // all ardour control surfaces store presets in xml format
+ SurfaceManifest (std::string);
+
+ bool valid () { return _valid; }
+
+ std::string id () { return _id; }
+ std::string name () { return _name; }
+ std::string description () { return _description; }
+
+ std::string to_json ();
+
+private:
+ bool _valid;
+
+ std::string _id;
+ std::string _name;
+ std::string _description;
+};
+
+#endif // _ardour_surface_websockets_manifest_h_
diff --git a/libs/surfaces/websockets/resources.cc b/libs/surfaces/websockets/resources.cc
new file mode 100644
index 0000000000..1bb8cd1eb1
--- /dev/null
+++ b/libs/surfaces/websockets/resources.cc
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2020 Luciano Iam <lucianito@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the/GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <iostream>
+#include <sstream>
+
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+
+#include "ardour/filesystem_paths.h"
+#include "pbd/file_utils.h"
+
+#include "resources.h"
+
+static const char* const data_dir_env_var = "ARDOUR_WEBSURFACES_PATH";
+static const char* const data_dir_name = "web_surfaces";
+static const char* const builtin_dir_name = "builtin";
+static const char* const manifest_filename = "manifest.xml";
+
+static bool
+dir_filter (const std::string &str, void* /*arg*/)
+{
+ return Glib::file_test (str, Glib::FILE_TEST_IS_DIR);
+}
+
+ServerResources::ServerResources ()
+ : _index_dir ("")
+ , _builtin_dir ("")
+ , _user_dir ("")
+{
+}
+
+const std::string&
+ServerResources::index_dir ()
+{
+ if (_index_dir.empty ()) {
+ _index_dir = server_data_dir ();
+ }
+
+ return _index_dir;
+}
+
+const std::string&
+ServerResources::builtin_dir ()
+{
+ if (_builtin_dir.empty ()) {
+ _builtin_dir = Glib::build_filename (server_data_dir (), builtin_dir_name);
+ }
+
+ return _builtin_dir;
+}
+
+const std::string&
+ServerResources::user_dir ()
+{
+ if (_user_dir.empty ()) {
+ _user_dir = Glib::build_filename (ARDOUR::user_config_directory (), data_dir_name);
+ }
+
+ return _user_dir;
+}
+
+std::string
+ServerResources::scan ()
+{
+ std::stringstream ss;
+
+ ss << "{\"builtin\":[";
+
+ SurfaceManifestVector builtin = read_manifests (builtin_dir ());
+
+ for (SurfaceManifestVector::iterator it = builtin.begin (); it != builtin.end (); ) {
+ ss << it->to_json ();
+ if (++it != builtin.end()) {
+ ss << ",";
+ }
+ }
+
+ ss << "],\"user\":[";
+
+ SurfaceManifestVector user = read_manifests (user_dir ());
+
+ for (SurfaceManifestVector::iterator it = user.begin (); it != user.end (); ) {
+ ss << it->to_json ();
+ if (++it != user.end()) {
+ ss << ",";
+ }
+ }
+
+ ss << "]}";
+
+ return ss.str ();
+}
+
+std::string
+ServerResources::server_data_dir ()
+{
+ std::string data_dir;
+
+ bool defined = false;
+ std::string env_dir (Glib::getenv (data_dir_env_var, defined));
+
+ if (defined) {
+ // useful for development
+ data_dir = env_dir;
+ } else {
+ data_dir = Glib::build_filename (ardour_data_dir (), data_dir_name);
+ }
+
+ return data_dir;
+}
+
+std::string
+ServerResources::ardour_data_dir ()
+{
+ std::string data_dir;
+
+#ifdef PLATFORM_WINDOWS
+ // windows_search_path() returns a Searchpath with a single item
+ data_dir = ARDOUR::windows_search_path ().to_string ();
+#else
+ data_dir = Glib::getenv ("ARDOUR_DATA_PATH");
+ if (data_dir.empty()) {
+ std::cerr << "ARDOUR_CONFIG_PATH not set in environment" << std::endl;
+ }
+#endif
+
+ return data_dir;
+}
+
+SurfaceManifestVector
+ServerResources::read_manifests (std::string dir)
+{
+ SurfaceManifestVector result;
+ std::vector<std::string> subdirs;
+ PBD::Searchpath spath (dir);
+
+ find_paths_matching_filter (subdirs, spath, dir_filter,
+ 0 /*arg*/, true /*pass_fullpath*/, true /*return_fullpath*/, false /*recurse*/);
+
+ for (std::vector<std::string>::const_iterator it = subdirs.cbegin (); it != subdirs.cend (); ++it) {
+ std::string xml_path = Glib::build_filename (*it, manifest_filename);
+
+ if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
+ continue;
+ }
+
+ SurfaceManifest manifest (xml_path);
+
+ if (manifest.valid ()) {
+ result.push_back (manifest);
+ }
+ }
+
+ return result;
+}
diff --git a/libs/surfaces/websockets/resources.h b/libs/surfaces/websockets/resources.h
new file mode 100644
index 0000000000..b7bb0daee9
--- /dev/null
+++ b/libs/surfaces/websockets/resources.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 Luciano Iam <lucianito@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the/GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _ardour_surface_websockets_resources_h_
+#define _ardour_surface_websockets_resources_h_
+
+#include <string>
+#include <vector>
+
+#include "manifest.h"
+
+typedef std::vector<SurfaceManifest> SurfaceManifestVector;
+
+class ServerResources
+{
+public:
+ ServerResources ();
+
+ const std::string& index_dir ();
+ const std::string& builtin_dir ();
+ const std::string& user_dir ();
+
+ std::string scan ();
+
+private:
+
+ std::string _index_dir;
+ std::string _builtin_dir;
+ std::string _user_dir;
+
+ std::string server_data_dir ();
+ std::string ardour_data_dir ();
+
+ SurfaceManifestVector read_manifests (std::string);
+
+};
+
+#endif // _ardour_surface_websockets_resources_h_