28 #include "hugin_config.h"
41 if(s.compare(s.length()-1,1,
"\\")!=0 && s.compare(s.length()-1,1,
"/")!=0)
46 if(s.compare(s.length()-1,1,
"/")!=0)
55 bool RebaseFilename(std::filesystem::path srcFile, std::filesystem::path& destFile, std::string srcPath, std::string destPath)
57 std::filesystem::path input=std::filesystem::absolute(srcFile);
58 std::string fullInputPath=input.string();
60 if(fullInputPath.compare(0, srcPathWithTrailingDelimiter.length(), srcPathWithTrailingDelimiter)!=0)
65 destFile=std::filesystem::path(fullInputPath);
71 pathTo=std::filesystem::path(dir);
75 if(pathTo.extension().string().length()>0)
77 std::cerr <<
"ERROR: Your destination is a file. Copy/Move several files to " << std::endl
78 <<
"a single file is not allowed." << std::endl
79 <<
"Canceled operation." << std::endl;
83 if(!std::filesystem::exists(pathTo))
85 if(!std::filesystem::create_directories(pathTo))
87 std::cerr <<
"ERROR: Could not create destination directory: " << pathTo.string() << std::endl
88 <<
"Maybe you have not sufficient rights to create this directory." << std::endl;
93 catch (
const std::filesystem::filesystem_error& ex)
95 std::cout << ex.what() << std::endl;
98 pathTo=std::filesystem::absolute(pathTo);
102 typedef std::set<std::filesystem::path>
pathVec;
104 bool PTOCopyMove(
bool movingFile, std::filesystem::path src, std::filesystem::path dest,
bool overwriteAllFiles)
107 std::cout << (movingFile ?
"Moving project file " :
"Copying project file ") << src.filename() << std::endl
108 <<
" from " << src.parent_path().string() << std::endl
109 <<
" to " << destFile.parent_path().string() << std::endl;
112 const std::string input=src.string();
120 std::map<std::filesystem::path,std::filesystem::path> imagesTo;
124 std::filesystem::path p(pano.
getImage(i).getFilename());
125 if(!std::filesystem::exists(p) || !std::filesystem::is_regular_file(p))
127 std::cerr <<
"ERROR: image " << p.string() <<
" not found on disc." << std::endl
128 <<
"Skipping project " << input << std::endl;
131 p=std::filesystem::absolute(p);
132 auto result = imagesFrom.insert(p);
141 std::filesystem::path newFilename;
142 if(
RebaseFilename(p, newFilename, inputPathPrefix, outputPathPrefix))
145 imagesTo[p] = newFilename;
148 if(!imagesFrom.empty())
150 if(imagesFrom.size()==imagesTo.size())
152 std::filesystem::path targetDir(destFile);
153 targetDir.remove_filename();
158 if(std::filesystem::exists(destFile) && !overwriteAllFiles)
160 std::cout <<
"Project file " << destFile <<
" does already exists." << std::endl
161 <<
" Overwrite this file? [Y|N] ";
162 std::string userAnswer;
163 while(userAnswer.length()==0)
165 std::cin >> userAnswer;
168 if(userAnswer!=
"YES" && userAnswer!=
"Y")
170 std::cout << std::endl <<
"Moving/Copying of project file " << input <<
" canceled." << std::endl << std::endl;
175 for(
const auto& imgFrom: imagesFrom)
179 targetDir.remove_filename();
185 if(std::filesystem::exists(imagesTo[imgFrom]) && !overwriteAllFiles)
187 std::cout <<
"Images file " << imagesTo[imgFrom] <<
" does already exists." << std::endl
188 <<
" Overwrite this file? [Y|N] ";
189 std::string userAnswer;
190 while(userAnswer.length()==0)
192 std::cin >> userAnswer;
195 if(userAnswer!=
"YES" && userAnswer!=
"Y")
197 std::cout << std::endl <<
"Moving/Copying of project file " << input <<
" canceled." << std::endl << std::endl;
205 std::filesystem::rename(imgFrom, imagesTo[imgFrom]);
207 catch (
const std::filesystem::filesystem_error& ex)
209 std::cout << ex.what() << std::endl;
217 std::filesystem::copy_file(imgFrom, imagesTo[imgFrom], std::filesystem::copy_options::overwrite_existing);
219 catch (
const std::filesystem::filesystem_error& ex)
221 std::cout << ex.what() << std::endl;
228 if (!pano.
WritePTOFile(destFile.string(), outputPathPrefix))
236 std::filesystem::remove(src);
238 catch (
const std::filesystem::filesystem_error& ex)
240 std::cout <<
"Could not remove original file: " << input << std::endl;
241 std::cout << ex.what() << std::endl;
249 std::cout <<
"WARNING: Images location in project file are not consistent. " << std::endl
250 <<
"So don't move/copy project file " << src.string() << std::endl;
259 if (!pano.
WritePTOFile(destFile.string(), outputPathPrefix))
267 std::filesystem::remove(src);
269 catch (
const std::filesystem::filesystem_error& ex)
271 std::cout <<
"Could not remove original file: " << input << std::endl;
272 std::cout << ex.what() << std::endl;
280 template <
class iteratorType>
285 for(iteratorType it(src); it != iteratorType(); it++)
290 projectFiles.insert(*it);
294 catch(std::filesystem::filesystem_error& e)
296 std::cout << e.what() << std::endl;
306 iterateFileSystem<std::filesystem::recursive_directory_iterator>(src, projectFiles);
310 iterateFileSystem<std::filesystem::directory_iterator>(src, projectFiles);
316 std::cout << name <<
": move a project file with all images in it" << std::endl
319 <<
"Usage: pto_move [options] path1/source.pto path2/dest.pto" << std::endl
320 <<
" Rename project file path1/source.pto to " << std::endl
321 <<
" path2/dest.pto. All images contained in the project will" << std::endl
322 <<
" be moved accordingly." << std::endl << std::endl
323 <<
" pto_move [options] sourceFolder destFolder" << std::endl
324 <<
" Moves all project files in the source folder to " << std::endl
325 <<
" the destination folder including all images." << std::endl
327 <<
"Options: " << std::endl
328 <<
" --copy Copy project files and images instead of moving" << std::endl
329 <<
" --recursive Only effective in use case 2. Go recursive in the" << std::endl
330 <<
" the source folder and move all project files with images" << std::endl
331 <<
" to destination folder by maintaining the folder structure" << std::endl
332 <<
" relative to source folder." << std::endl
333 <<
" --overwrite Overwrite all existing files. Otherwise you will be asked" << std::endl
334 <<
" for each existing file." << std::endl
339 int main(
int argc,
char* argv[])
342 const char* optstring =
"croh";
344 static struct option longOptions[] =
346 {
"copy", no_argument, NULL,
'c' },
347 {
"recursive", no_argument, NULL,
'r' },
348 {
"overwrite", no_argument, NULL,
'o' },
349 {
"help", no_argument, NULL,
'h' },
353 bool movingFiles=
true;
354 bool recursive=
false;
355 bool forceOverwrite=
false;
357 while ((c = getopt_long (argc, argv, optstring, longOptions,
nullptr)) != -1)
386 std::cerr <<
hugin_utils::stripPath(argv[0]) <<
": You need to give at least a source and a destination project file or directory." << std::endl;
392 std::filesystem::path p(argv[optind]);
393 if(std::filesystem::exists(p))
395 p=std::filesystem::absolute(p);
396 if(std::filesystem::is_directory(p))
399 std::filesystem::path pathTo;
406 std::cout <<
"Searching project files in " << p << std::endl;
408 if(projectFiles.empty())
410 std::cout <<
"No project files found in given directory " << p.string() << std::endl;
413 std::cout <<
"Found " << projectFiles.size() <<
" project files." << std::endl << std::endl;
414 for(pathVec::const_iterator it=projectFiles.cbegin(); it!=projectFiles.cend(); ++it)
416 std::filesystem::path newPath;
419 PTOCopyMove(movingFiles, *it, newPath, forceOverwrite);
429 std::filesystem::path pathTo;
436 p=std::filesystem::path(argv[optind]);
441 if(std::filesystem::exists(p) && std::filesystem::is_regular_file(p))
443 p=std::filesystem::absolute(p);
444 std::filesystem::path newPath = pathTo / p.filename();
445 PTOCopyMove(movingFiles, p, newPath, forceOverwrite);
449 std::cout <<
"WARNING: File " << p <<
" does not exists" << std::endl
450 <<
"Skipping this file." << std::endl;
459 std::filesystem::path pathTo(argv[argc-1]);
460 if(pathTo.extension().string().length()>0)
464 pathTo=std::filesystem::absolute(pathTo);
465 PTOCopyMove(movingFiles, p, pathTo, forceOverwrite);
474 pathTo=pathTo / p.filename();
477 std::cerr <<
"ERROR: Target and destination file are the same." << std::endl
478 <<
"Skipping file processing." << std::endl;
481 PTOCopyMove(movingFiles, p, pathTo, forceOverwrite);
487 catch (
const std::filesystem::filesystem_error& ex)
489 std::cout << ex.what() << std::endl;
void SearchPTOFilesInDirectory(pathVec &projectFiles, std::string src, bool recursive)
bool checkDestinationDirectory(std::string dir, std::filesystem::path &pathTo)
std::vector< std::filesystem::path > pathVec
std::string toupper(const std::string &s)
bool PTOCopyMove(bool movingFile, std::filesystem::path src, std::filesystem::path dest, bool overwriteAllFiles)
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
std::string GetAbsoluteFilename(const std::string &filename)
returns the full absolute filename
std::size_t getNrOfImages() const
number of images.
bool ReadPTOFile(const std::string &filename, const std::string &prefix="")
read pto file from the given filename into Panorama object it does some checks on the file and issues...
std::string IncludeTrailingDelimiter(std::string path)
void setImageFilename(unsigned int img, const std::string &fname)
set a new image filename
bool iterateFileSystem(std::string src, pathVec &projectFiles)
std::string GetHuginVersion()
return a string with version numbers
bool WritePTOFile(const std::string &filename, const std::string &prefix="")
write data to given pto file
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
bool RebaseFilename(std::filesystem::path srcFile, std::filesystem::path &destFile, std::string srcPath, std::string destPath)
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
int main(int argc, char *argv[])