diff options
author | Luciano Iam <lucianito@gmail.com> | 2020-04-09 16:07:19 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2020-04-09 20:56:46 +0200 |
commit | c946eb3132f36578f1a4cae75c938348c6d9822a (patch) | |
tree | 90ab2c6c87f08ed6e0f7aac14f813aac4faabcae /libs/surfaces | |
parent | 40520a6dc61de135c09cdfb0097910b766ccb6ee (diff) |
Add classes for serving content over HTTP
Diffstat (limited to 'libs/surfaces')
-rw-r--r-- | libs/surfaces/websockets/manifest.cc | 83 | ||||
-rw-r--r-- | libs/surfaces/websockets/manifest.h | 46 | ||||
-rw-r--r-- | libs/surfaces/websockets/resources.cc | 171 | ||||
-rw-r--r-- | libs/surfaces/websockets/resources.h | 53 |
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_ |