RemoteResourcesManager.cpp
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2024 Jose Luis Blanco Claraco |
5  | Copyright (C) 2017 Borys Tymchenko (Odessa Polytechnic University) |
6  | Distributed under 3-clause BSD License |
7  | See COPYING |
8  +-------------------------------------------------------------------------+ */
9 
10 #include <mrpt/system/filesystem.h>
12 
13 #include <cstdlib>
14 #include <cstring>
15 
16 using namespace mvsim;
17 
19  : mrpt::system::COutputLogger("mvsim::RemoteResourcesManager")
20 {
21 }
22 
23 bool RemoteResourcesManager::is_remote(const std::string& url)
24 {
25  return 0 == ::strncmp(url.c_str(), "http://", strlen("http://")) ||
26  0 == ::strncmp(url.c_str(), "https://", strlen("https://"));
27 }
28 
29 std::string RemoteResourcesManager::resolve_path(const std::string& uri)
30 {
31  if (is_remote(uri))
32  {
33  return handle_remote_uri(uri);
34  }
35  else if (uri.substr(0, 7) == "file://")
36  {
37  return uri.substr(7);
38  }
39  else
40  {
41  return uri;
42  }
43 }
44 
46 {
47  std::string local_directory;
48 #ifdef _WIN32
49  local_directory = std::getenv("APPDATA");
50 #else
51  local_directory = std::getenv("HOME");
52  local_directory += "/.cache/";
53 #endif
54 
55  local_directory += "mvsim-storage/";
56 
57  return local_directory;
58 }
59 
60 std::tuple<bool, std::string, std::string> RemoteResourcesManager::zip_uri_split(
61  const std::string& uri)
62 {
63  auto pos = uri.find(".zip/");
64 
65  if (pos == std::string::npos) return {false, uri, ""};
66 
67  const auto zipUri = uri.substr(0, pos + 4);
68  const auto internalUri = uri.substr(pos + 5);
69 
70  return {true, zipUri, internalUri};
71 }
72 
73 std::string RemoteResourcesManager::handle_remote_uri(const std::string& uri)
74 {
75  using namespace std::string_literals;
76 
77  const auto localDir = cache_directory();
78  std::string cacheUsageStats;
79 
80  if (!mrpt::system::directoryExists(localDir))
81  {
82 #ifdef _WIN32
83  mrpt::system::createDirectory(localDir);
84 #else
85  const auto cmd = "mkdir -p \""s + localDir + "\""s;
86  if (int ret = ::system(cmd.c_str()); ret != 0)
87  {
88  MRPT_LOG_ERROR_STREAM("Error executing command: " << cmd);
89  }
90 #endif
91  ASSERT_DIRECTORY_EXISTS_(localDir);
92  }
93  else
94  {
95  // get usage stats:
96  if (0 == mrpt::system::executeCommand(
97  mrpt::format("du -sh0 \"%s\"", localDir.c_str()), &cacheUsageStats))
98  {
99  // usage stats are valid.
100  }
101  }
102  MRPT_LOG_ONCE_INFO(
103  "Using local storage directory: '"s + localDir + "' (Usage: "s + cacheUsageStats + ")"s);
104 
105  const auto [isZipPkg, zipOrFileURI, internalURI] = zip_uri_split(uri);
106 
107  MRPT_LOG_DEBUG_STREAM(
108  "Split URI: isZipPkg=" << isZipPkg << " zipOrFileURI=" << zipOrFileURI
109  << " internalURI=" << internalURI);
110 
111  const auto fileName = mrpt::system::extractFileName(zipOrFileURI) + "." +
112  mrpt::system::extractFileExtension(zipOrFileURI);
113  const auto localFil = localDir + fileName;
114 
115  // Download if it does not exist already from a past download:
116  if (!mrpt::system::fileExists(localFil))
117  {
118  const auto cmd =
119  mrpt::format("wget -q -O \"%s\" %s", localFil.c_str(), zipOrFileURI.c_str());
120 
121  MRPT_LOG_INFO_STREAM("Downloading remote resources from: '" << uri << "'");
122 
123  if (int ret = ::system(cmd.c_str()); ret != 0)
124  {
125  THROW_EXCEPTION_FMT(
126  "[mvsim] Error (code=%i) executing the following command "
127  "trying to acquire a remote resource:\n%s",
128  ret, cmd.c_str());
129  }
130  }
131 
132  // Is it a simple model file, or a zip?
133  if (isZipPkg)
134  {
135  // process the ZIP package:
136  return handle_local_zip_package(localFil, internalURI);
137  }
138  else
139  {
140  // simple file:
141  return localFil;
142  }
143 }
144 
146  const std::string& localZipFil, const std::string& internalURI)
147 {
148  using namespace std::string_literals;
149 
150  ASSERT_FILE_EXISTS_(localZipFil);
151 
152  const auto filExtension = mrpt::system::extractFileExtension(localZipFil);
153  ASSERT_EQUAL_(filExtension, "zip");
154 
155  // already decompressed?
156  const auto zipOutDir = mrpt::system::fileNameChangeExtension(localZipFil, "out");
157 
158  if (!mrpt::system::directoryExists(zipOutDir))
159  {
160  mrpt::system::createDirectory(zipOutDir);
161  ASSERT_DIRECTORY_EXISTS_(zipOutDir);
162 
163  const std::string cmd = "unzip -q \""s + localZipFil + "\" -d \""s + zipOutDir + "\""s;
164 
165  if (int ret = ::system(cmd.c_str()); ret != 0)
166  {
167  THROW_EXCEPTION_FMT(
168  "[mvsim] Error (code=%i) executing the following command "
169  "trying to unzip a remote resource:\n%s",
170  ret, cmd.c_str());
171  }
172  }
173 
174  return zipOutDir + "/"s + internalURI;
175 }
mvsim
Definition: Client.h:21
mvsim::RemoteResourcesManager::handle_remote_uri
std::string handle_remote_uri(const std::string &uri)
Definition: RemoteResourcesManager.cpp:73
fileName
static const char * fileName
Definition: settings.cpp:28
RemoteResourcesManager.h
s
XmlRpcServer s
mrpt
Definition: basic_types.h:36
mvsim::RemoteResourcesManager::resolve_path
std::string resolve_path(const std::string &uri)
Definition: RemoteResourcesManager.cpp:29
mvsim::RemoteResourcesManager::cache_directory
static std::string cache_directory()
Definition: RemoteResourcesManager.cpp:45
mvsim::RemoteResourcesManager::RemoteResourcesManager
RemoteResourcesManager()
Definition: RemoteResourcesManager.cpp:18
mvsim::RemoteResourcesManager::is_remote
static bool is_remote(const std::string &uri)
Definition: RemoteResourcesManager.cpp:23
mvsim::RemoteResourcesManager::zip_uri_split
static std::tuple< bool, std::string, std::string > zip_uri_split(const std::string &uri)
Definition: RemoteResourcesManager.cpp:60
mvsim::RemoteResourcesManager::handle_local_zip_package
std::string handle_local_zip_package(const std::string &localZipFil, const std::string &internalURI)
Definition: RemoteResourcesManager.cpp:145
cmd
string cmd


mvsim
Author(s):
autogenerated on Wed May 28 2025 02:13:08