RemoteResourcesManager.cpp
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2023 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>
61  RemoteResourcesManager::zip_uri_split(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()),
98  &cacheUsageStats))
99  {
100  // usage stats are valid.
101  }
102  }
103  MRPT_LOG_ONCE_INFO(
104  "Using local storage directory: '"s + localDir + "' (Usage: "s +
105  cacheUsageStats + ")"s);
106 
107  const auto [isZipPkg, zipOrFileURI, internalURI] = zip_uri_split(uri);
108 
109  MRPT_LOG_DEBUG_STREAM(
110  "Split URI: isZipPkg=" << isZipPkg << " zipOrFileURI=" << zipOrFileURI
111  << " internalURI=" << internalURI);
112 
113  const auto fileName = mrpt::system::extractFileName(zipOrFileURI) + "." +
114  mrpt::system::extractFileExtension(zipOrFileURI);
115  const auto localFil = localDir + fileName;
116 
117  // Download if it does not exist already from a past download:
118  if (!mrpt::system::fileExists(localFil))
119  {
120  const auto cmd = mrpt::format(
121  "wget -q -O \"%s\" %s", localFil.c_str(), zipOrFileURI.c_str());
122 
123  MRPT_LOG_INFO_STREAM(
124  "Downloading remote resources from: '" << uri << "'");
125 
126  if (int ret = ::system(cmd.c_str()); ret != 0)
127  {
128  THROW_EXCEPTION_FMT(
129  "[mvsim] Error (code=%i) executing the following command "
130  "trying to acquire a remote resource:\n%s",
131  ret, cmd.c_str());
132  }
133  }
134 
135  // Is it a simple model file, or a zip?
136  if (isZipPkg)
137  {
138  // process the ZIP package:
139  return handle_local_zip_package(localFil, internalURI);
140  }
141  else
142  {
143  // simple file:
144  return localFil;
145  }
146 }
147 
149  const std::string& localZipFil, const std::string& internalURI)
150 {
151  using namespace std::string_literals;
152 
153  ASSERT_FILE_EXISTS_(localZipFil);
154 
155  const auto filExtension = mrpt::system::extractFileExtension(localZipFil);
156  ASSERT_EQUAL_(filExtension, "zip");
157 
158  // already decompressed?
159  const auto zipOutDir =
160  mrpt::system::fileNameChangeExtension(localZipFil, "out");
161 
162  if (!mrpt::system::directoryExists(zipOutDir))
163  {
164  mrpt::system::createDirectory(zipOutDir);
165  ASSERT_DIRECTORY_EXISTS_(zipOutDir);
166 
167  const std::string cmd =
168  "unzip -q \""s + localZipFil + "\" -d \""s + zipOutDir + "\""s;
169 
170  if (int ret = ::system(cmd.c_str()); ret != 0)
171  {
172  THROW_EXCEPTION_FMT(
173  "[mvsim] Error (code=%i) executing the following command "
174  "trying to unzip a remote resource:\n%s",
175  ret, cmd.c_str());
176  }
177  }
178 
179  return zipOutDir + "/"s + internalURI;
180 }
static const char * fileName
Definition: settings.cpp:28
string cmd
XmlRpcServer s
std::string resolve_path(const std::string &uri)
static bool is_remote(const std::string &uri)
std::string handle_local_zip_package(const std::string &localZipFil, const std::string &internalURI)
static std::tuple< bool, std::string, std::string > zip_uri_split(const std::string &uri)
std::string handle_remote_uri(const std::string &uri)


mvsim
Author(s):
autogenerated on Tue Jul 4 2023 03:08:21