#include "ScanFileOrFolder.h" #include "TransferThread.h" #include #include #include #include "../../../cpp11addition.h" #ifdef Q_OS_WIN32 #ifndef NOMINMAX #define NOMINMAX #endif #include #endif std::string ScanFileOrFolder::text_slash="/"; std::string ScanFileOrFolder::text_antislash="\\"; std::string ScanFileOrFolder::text_dot="."; ScanFileOrFolder::ScanFileOrFolder(const Ultracopier::CopyMode &mode) { #ifdef ULTRACOPIER_PLUGIN_RSYNC rsync = false; #endif moveTheWholeFolder = true; stopped = true; stopIt = false; this->mode = mode; folder_isolation = std::regex("^(.*/)?([^/]+)/$"); setObjectName(QStringLiteral("ScanFileOrFolder")); #ifdef Q_OS_WIN32 QString userName; DWORD size=255; WCHAR * userNameW=new WCHAR[size]; if(GetUserNameW(userNameW,&size)) { userName=QString::fromWCharArray(userNameW,size-1); blackList.push_back(QFileInfo(QStringLiteral("C:/Users/%1/AppData/Roaming/").arg(userName)).absoluteFilePath().toStdString()); } delete userNameW; #endif } ScanFileOrFolder::~ScanFileOrFolder() { stop(); quit(); wait(); } bool ScanFileOrFolder::isFinished() const { return stopped; } void ScanFileOrFolder::addToList(const std::vector& sources,const std::string& destination) { stopIt=false; this->sources=parseWildcardSources(sources); this->destination=destination; QFileInfo destinationInfo(QString::fromStdString(this->destination)); ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"check symblink: "+destinationInfo.absoluteFilePath().toStdString()); while(destinationInfo.isSymLink()) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"resolv destination to: "+destinationInfo.symLinkTarget().toStdString()); if(QFileInfo(destinationInfo.symLinkTarget()).isAbsolute()) this->destination=destinationInfo.symLinkTarget().toStdString(); else this->destination=destinationInfo.absolutePath().toStdString()+text_slash+destinationInfo.symLinkTarget().toStdString(); destinationInfo.setFile(QString::fromStdString(this->destination)); } if(sources.size()>1 || QFileInfo(QString::fromStdString(destination)).isDir()) /* Disabled because the separator transformation product bug * if(!destination.endsWith(QDir::separator())) this->destination+=QDir::separator();*/ if(!stringEndsWith(destination,'/') && !stringEndsWith(destination,'\\')) this->destination+=text_slash;//put unix separator because it's transformed into that's under windows too ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"addToList("+stringimplode(sources,";")+","+this->destination+")"); } std::vector ScanFileOrFolder::parseWildcardSources(const std::vector &sources) const { std::regex splitFolder("[/\\\\]"); std::vector returnList; unsigned int index=0; while(index<(unsigned int)sources.size()) { if(sources.at(index).find("*") != std::string::npos) { std::vector toParse=stringregexsplit(sources.at(index),splitFolder); ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"before wildcard parse: "+sources.at(index)+", toParse: "+stringimplode(toParse,", ")); std::vector > recomposedSource; { std::vector t; t.push_back(""); recomposedSource.push_back(t); } while(toParse.size()>0) { if(toParse.front().find("*") != std::string::npos) { std::string toParseFirst=toParse.front(); if(toParseFirst.empty()) toParseFirst=text_slash; std::vector > newRecomposedSource; stringreplaceAll(toParseFirst,"*","[^/\\\\]*"); std::regex toResolv=std::regex(toParseFirst); unsigned int index_recomposedSource=0; while(index_recomposedSource tempList=recomposedSource.at(index_recomposedSource); tempList.push_back(fileName); newRecomposedSource.push_back(tempList); } index_fileList++; } } index_recomposedSource++; } recomposedSource=newRecomposedSource; } else { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"add toParse: "+stringimplode(toParse,text_slash)); unsigned int index_recomposedSource=0; while(index_recomposedSource &include, const std::vector &exclude) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start"); QMutexLocker lock(&filtersMutex); this->include_send=include; this->exclude_send=exclude; reloadTheNewFilters=true; haveFilters=include_send.size()>0 || exclude_send.size()>0; ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"haveFilters: "+std::to_string(haveFilters)+", include_send.size(): "+std::to_string(include_send.size())+", exclude_send.size(): "+std::to_string(exclude_send.size())); } //set action if Folder are same or exists void ScanFileOrFolder::setFolderExistsAction(const FolderExistsAction &action, const std::string &newName) { this->newName=newName; folderExistsAction=action; waitOneAction.release(); } //set action if error void ScanFileOrFolder::setFolderErrorAction(const FileErrorAction &action) { fileErrorAction=action; waitOneAction.release(); } void ScanFileOrFolder::stop() { stopIt=true; waitOneAction.release(); } void ScanFileOrFolder::run() { stopped=false; ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"start the listing with destination: "+destination+", mode: "+std::to_string(mode)); destination=resolvDestination(QString::fromStdString(destination)).absoluteFilePath().toStdString(); if(stopIt) { stopped=true; return; } if(fileErrorAction==FileError_Skip) { stopped=true; return; } unsigned int sourceIndex=0; while(sourceIndexinclude=this->include_send; this->exclude=this->exclude_send; } std::string fileName=fileInfo.fileName().toStdString(); if(fileInfo.isDir() && !fileInfo.isSymLink()) { bool excluded=false,included=(include.size()==0); unsigned int filters_index=0; while(filters_indexcheckDestinationExists=checkDestinationFolderExists; } void ScanFileOrFolder::setRenamingRules(const std::string &firstRenamingRule, const std::string &otherRenamingRule) { this->firstRenamingRule=firstRenamingRule; this->otherRenamingRule=otherRenamingRule; } void ScanFileOrFolder::setMoveTheWholeFolder(const bool &moveTheWholeFolder) { this->moveTheWholeFolder=moveTheWholeFolder; } void ScanFileOrFolder::setCopyListOrder(const bool &order) { this->copyListOrder=order; } #ifdef ULTRACOPIER_PLUGIN_RSYNC /// \brief set rsync void ScanFileOrFolder::setRsync(const bool rsync) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"set rsync: "+std::to_string(rsync)); this->rsync=rsync; } #endif void ScanFileOrFolder::set_updateMount() { driveManagement.tryUpdate(); }