27 #include <boost/regex.hpp>
33 #include <IceUtil/UUID.h>
38 namespace fs = std::filesystem;
41 databasePrx(databasePrx)
44 if (!armarxCachePath.empty())
46 init(armarxCachePath);
50 static std::string cachePath = (std::filesystem::temp_directory_path() /
std::to_string(std::random_device{}())).
string();
56 databasePrx(databasePrx)
73 if (!fs::exists(cachePath))
75 fs::create_directory(cachePath);
78 fileCachePath = fs::path(cachePath) / fs::path(
"files");
80 if (!fs::exists(fileCachePath))
82 fs::create_directory(fileCachePath);
86 if (!fileCachePath.is_absolute())
89 std::filesystem::path fullPath(std::filesystem::current_path());
90 fileCachePath = fullPath / fileCachePath;
96 return fileCachePath.string();
100 bool preserveOriginalName)
112 fs::path filenameFromProxy(filePrx->getFilename());
114 fs::path localFile = fileCachePath / filenameFromProxy.stem();
116 if (!preserveOriginalName)
118 localFile += fs::path(filePrx->getId() +
"_" + filePrx->getMD5());
120 std::string localFileStr = localFile.string();
121 std::string extensionStr = filenameFromProxy.extension().string();
122 localFile = fs::path(localFileStr + extensionStr);
125 bool cached = fs::exists(localFile);
129 cached = cached && ((std::uintmax_t) filePrx->getFileSize() == fs::file_size(localFile));
132 fs::file_time_type lwt = fs::last_write_time(localFile);
133 auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(lwt - fs::file_time_type::clock::now()
134 + std::chrono::system_clock::now());
135 time_t time = std::chrono::system_clock::to_time_t(sctp);
137 cached = cached && (!preserveOriginalName || (time >= filePrx->getUploadDate() / 1000));
147 std::filesystem::path filePath;
148 filePath = localFile;
149 filePath = filePath.parent_path();
150 create_directories(filePath);
153 const std::string tmpLocalFile = localFile.string() + IceUtil::generateUUID() +
".part";
155 fsOut.open(tmpLocalFile.c_str(), std::ios_base::out | std::ios_base::binary);
157 memoryx::Blob buffer;
160 while (filePrx->getNextChunk(buffer))
162 fsOut.write((
char*) &buffer[0], buffer.size());
166 fs::rename(tmpLocalFile, localFile);
169 cacheFileName = localFile.string();
174 std::string& cacheFileName,
bool preserveOriginalName)
178 GridFileInterfacePrx filePrx = getFileProxyFromAttr(fileAttr);
187 databasePrx->releaseFileProxy(filePrx);
192 bool preserveOriginalNames )
197 GridFileList filePrxList = getFileProxiesFromAttr(fileAttr);
199 if (filePrxList.empty())
204 std::string cacheFileName;
206 for (GridFileList::iterator it = filePrxList.begin(); it != filePrxList.end(); ++it)
210 cacheFileNames.push_back(cacheFileName);
211 databasePrx->releaseFileProxy(*it);
218 bool preserveOriginalNames )
221 std::vector<std::string> cacheFileNames;
228 std::string cacheFileName;
233 fs.open(cacheFileName.c_str(), std::ios_base::in);
243 GridFileInterfacePrx filePrx = getFileProxyFromAttr(fileAttr);
245 databasePrx->releaseFileProxy(filePrx);
250 const std::string& localFileName, EntityAttributeBasePtr& fileAttr,
const std::string& gridFSName )
253 return addFileToAttr(filesDBName, localFileName, fileAttr, gridFSName);
257 const std::string& localFileName, EntityAttributeBasePtr& fileAttr,
const std::string& gridFSName )
260 std::filesystem::path fname(localFileName);
261 fname = std::filesystem::absolute(fname);
266 fileId = databasePrx->storeFile(filesDBName, fname.string(), (gridFSName.empty() ? fname.filename().string() : gridFSName));
268 catch (
const FileNotFoundException& e)
272 std::ifstream fin(fname.string().c_str(), std::ios::binary);
275 throw FileNotFoundException(
"File not found: " + fname.string(), fname.string());
277 std::stringstream contentStream;
278 contentStream << fin.rdbuf();
279 fileId = databasePrx->storeTextFile(filesDBName, contentStream.str(), (gridFSName.empty() ? fname.filename().string() : gridFSName));
285 fileAttr->addValue(fileVar);
291 const std::string& localDirectoryName, EntityAttributeBasePtr& fileAttr, std::string excludeFilter)
294 boost::regex exclude(excludeFilter.c_str());
299 std::filesystem::path relativePathBase = localDirectoryName;
300 relativePathBase = relativePathBase.parent_path();
303 for (std::filesystem::recursive_directory_iterator end, dir(localDirectoryName.c_str()); dir != end; ++dir)
306 if (dir->status().type() != std::filesystem::file_type::directory)
308 if (boost::regex_match(dir->path().filename().c_str(), exclude))
310 dir.disable_recursion_pending();
314 std::string fileName = makeRelativePath(dir->path(), relativePathBase);
315 ARMARX_VERBOSE_S <<
"Adding file '" << dir->path() <<
"' with name " << fileName;
316 const std::string fileId =
addFileToAttr(filesDBName, dir->path().c_str(), fileAttr, fileName);
317 success &= !fileId.empty();
327 const std::string& localBaseDirectoryName,
328 const std::vector<std::string>& localFiles,
329 EntityAttributeBasePtr& fileAttr)
335 std::filesystem::path relativePathBase = localBaseDirectoryName;
336 relativePathBase = relativePathBase.parent_path();
338 for (
size_t i = 0; i < localFiles.size(); i++)
340 std::filesystem::path f = localFiles[i];
341 std::string fileName = makeRelativePath(f, relativePathBase);
343 const std::string fileId =
addFileToAttr(filesDBName, f.c_str(), fileAttr, fileName);
344 success &= !fileId.empty();
353 const MongoDBRefPtr fileRef = extractMongoDBRef(fileAttr->getValueAt(fileIndex));
360 return databasePrx->removeFileById(fileRef->dbName, fileRef->docId);
374 for (
size_t i = 0; i < (size_t) fileAttr->size(); ++i)
384 GridFileInterfacePrx GridFileManager::getFileProxyFromAttr(
const AttributeBasePtr& attr)
const
391 return databasePrx->getFileProxyById(fileRef->dbName, fileRef->docId);
395 ARMARX_WARNING <<
"Could not get fileref for attribute " << attr->getName();
396 return GridFileInterfacePrx();
400 GridFileList GridFileManager::getFileProxiesFromAttr(
const AttributeBasePtr& attr)
const
411 for (
size_t i = 0; i < (size_t) entityAttr->size(); ++i)
413 const MongoDBRefPtr fileRef = extractMongoDBRef(entityAttr->getValueAt(i));
417 const GridFileInterfacePrx prx = databasePrx->getFileProxyById(fileRef->dbName, fileRef->docId);
418 result.push_back(prx);
425 MongoDBRefPtr GridFileManager::extractMongoDBRef(
const AttributeBasePtr& attr)
const
435 return extractMongoDBRef(entityAttr->getValue());
466 std::string GridFileManager::makeRelativePath(
const std::filesystem::path& directory,
const std::filesystem::path& basePath)
469 std::filesystem::path diffpath;
470 std::filesystem::path tmppath = directory;
472 while (tmppath != basePath)
474 diffpath = tmppath.filename() / diffpath;
475 tmppath = tmppath.parent_path();
480 diffpath = directory;
485 return diffpath.string();