summaryrefslogtreecommitdiff
path: root/plugins-alternative/CopyEngine/Rsync/scanFileOrFolder.cpp
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2013-03-21 11:01:59 +0100
committerThomas Preud'homme <robotux@celest.fr>2013-03-21 11:01:59 +0100
commite297dbd8052ef4e66f069e2dd1865ae7fa8af28e (patch)
tree342fea0a2f6f33b8b62dad2d1729f8209da1a1ba /plugins-alternative/CopyEngine/Rsync/scanFileOrFolder.cpp
parent8f9f382e1c97cab2e72e97495650c73ac4b97314 (diff)
Imported Upstream version 0.3.1.0
Diffstat (limited to 'plugins-alternative/CopyEngine/Rsync/scanFileOrFolder.cpp')
-rw-r--r--plugins-alternative/CopyEngine/Rsync/scanFileOrFolder.cpp511
1 files changed, 511 insertions, 0 deletions
diff --git a/plugins-alternative/CopyEngine/Rsync/scanFileOrFolder.cpp b/plugins-alternative/CopyEngine/Rsync/scanFileOrFolder.cpp
new file mode 100644
index 0000000..197b8c7
--- /dev/null
+++ b/plugins-alternative/CopyEngine/Rsync/scanFileOrFolder.cpp
@@ -0,0 +1,511 @@
+#include "scanFileOrFolder.h"
+
+#include <QDateTime>
+
+scanFileOrFolder::scanFileOrFolder(CopyMode mode)
+{
+ rsync=false;
+ stopped = true;
+ stopIt = false;
+ this->mode=mode;
+ setObjectName("ScanFileOrFolder");
+ folder_isolation=QRegExp("^(.*/)?([^/]+)/$");
+}
+
+scanFileOrFolder::~scanFileOrFolder()
+{
+ stop();
+ quit();
+ wait();
+}
+
+bool scanFileOrFolder::isFinished()
+{
+ return stopped;
+}
+
+void scanFileOrFolder::addToList(const QStringList& sources,const QString& destination)
+{
+ stopIt=false;
+ this->sources=parseWildcardSources(sources);
+ this->destination=destination;
+ if(sources.size()>1 || QFileInfo(destination).isDir())
+ /* Disabled because the separator transformation product bug
+ * if(!destination.endsWith(QDir::separator()))
+ this->destination+=QDir::separator();*/
+ if(!destination.endsWith("/") && !destination.endsWith("\\"))
+ this->destination+="/";//put unix separator because it's transformed into that's under windows too
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"addToList("+sources.join(";")+","+destination+")");
+}
+
+
+QStringList scanFileOrFolder::parseWildcardSources(const QStringList &sources)
+{
+ QRegExp splitFolder("[/\\\\]");
+ QStringList returnList;
+ int index=0;
+ while(index<sources.size())
+ {
+ if(sources.at(index).contains("*"))
+ {
+ QStringList toParse=sources.at(index).split(splitFolder);
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("before wildcard parse: %1, toParse: %2, is valid: %3").arg(sources.at(index)).arg(toParse.join(", ")).arg(splitFolder.isValid()));
+ QList<QStringList> recomposedSource;
+ recomposedSource << (QStringList() << "");
+ while(toParse.size()>0)
+ {
+ if(toParse.first().contains('*'))
+ {
+ QString toParseFirst=toParse.first();
+ if(toParseFirst=="")
+ toParseFirst+="/";
+ QList<QStringList> newRecomposedSource;
+ QRegExp toResolv=QRegExp(toParseFirst.replace('*',"[^/\\\\]*"));
+ int index_recomposedSource=0;
+ while(index_recomposedSource<recomposedSource.size())//parse each url part
+ {
+ QFileInfo info(recomposedSource.at(index_recomposedSource).join("/"));
+ if(info.isDir())
+ {
+ QDir folder(info.absoluteFilePath());
+ QFileInfoList fileFile=folder.entryInfoList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::Hidden|QDir::System);//QStringList() << toResolv
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("list the folder: %1, with the wildcard: %2").arg(info.absoluteFilePath()).arg(toResolv.pattern()));
+ int index_fileList=0;
+ while(index_fileList<fileFile.size())
+ {
+ if(fileFile.at(index_fileList).fileName().contains(toResolv))
+ {
+ QStringList tempList=recomposedSource.at(index_recomposedSource);
+ tempList << fileFile.at(index_fileList).fileName();
+ newRecomposedSource << tempList;
+ }
+ index_fileList++;
+ }
+ }
+ index_recomposedSource++;
+ }
+ recomposedSource=newRecomposedSource;
+ }
+ else
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,QString("add toParse: %1").arg(toParse.join("/")));
+ int index_recomposedSource=0;
+ while(index_recomposedSource<recomposedSource.size())
+ {
+ recomposedSource[index_recomposedSource] << toParse.first();
+ if(!QFileInfo(recomposedSource.at(index_recomposedSource).join("/")).exists())
+ recomposedSource.removeAt(index_recomposedSource);
+ else
+ index_recomposedSource++;
+ }
+ }
+ toParse.removeFirst();
+ }
+ int index_recomposedSource=0;
+ while(index_recomposedSource<recomposedSource.size())
+ {
+ returnList<<recomposedSource.at(index_recomposedSource).join("/");
+ index_recomposedSource++;
+ }
+ }
+ else
+ returnList << sources.at(index);
+ index++;
+ }
+ return returnList;
+}
+
+void scanFileOrFolder::setFilters(QList<Filters_rules> include,QList<Filters_rules> exclude)
+{
+ ULTRACOPIER_DEBUGCONSOLE(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(DebugLevel_Notice,QString("haveFilters: %1, include_send.size(): %2, exclude_send.size(): %3").arg(haveFilters).arg(include_send.size()).arg(exclude_send.size()));
+}
+
+//set action if Folder are same or exists
+void scanFileOrFolder::setFolderExistsAction(FolderExistsAction action,QString newName)
+{
+ this->newName=newName;
+ folderExistsAction=action;
+ waitOneAction.release();
+}
+
+//set action if error
+void scanFileOrFolder::setFolderErrorAction(FileErrorAction action)
+{
+ fileErrorAction=action;
+ waitOneAction.release();
+}
+
+void scanFileOrFolder::stop()
+{
+ stopIt=true;
+ waitOneAction.release();
+}
+
+void scanFileOrFolder::run()
+{
+ stopped=false;
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"start the listing with destination: "+destination+", mode: "+QString::number(mode));
+ QDir destinationFolder(destination);
+ int sourceIndex=0;
+ while(sourceIndex<sources.size())
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"size source to list: "+QString::number(sourceIndex)+"/"+QString::number(sources.size()));
+ if(stopIt)
+ {
+ stopped=true;
+ return;
+ }
+ QFileInfo source=sources.at(sourceIndex);
+ if(source.isDir())
+ {
+ /* Bad way; when you copy c:\source\folder into d:\destination, you wait it create the folder d:\destination\folder
+ //listFolder(source.absoluteFilePath()+QDir::separator(),destination);
+ listFolder(source.absoluteFilePath()+"/",destination);//put unix separator because it's transformed into that's under windows too
+ */
+ //put unix separator because it's transformed into that's under windows too
+ listFolder(source.absolutePath()+"/",destinationFolder.absolutePath()+"/",source.fileName()+"/",source.fileName()+"/");
+ }
+ else
+ emit fileTransfer(source,destination+source.fileName(),mode);
+ sourceIndex++;
+ }
+ stopped=true;
+ if(stopIt)
+ return;
+ emit finishedTheListing();
+}
+
+void scanFileOrFolder::listFolder(const QString& source,const QString& destination,const QString& sourceSuffixPath,QString destinationSuffixPath)
+{
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"source: "+source+", destination: "+destination+", sourceSuffixPath: "+sourceSuffixPath+", destinationSuffixPath: "+destinationSuffixPath);
+ if(stopIt)
+ return;
+ QString newSource = source+sourceSuffixPath;
+ QString finalDest = destination+destinationSuffixPath;
+ //if is same
+ if(newSource==finalDest)
+ {
+ QDir dirSource(newSource);
+ emit folderAlreadyExists(dirSource.absolutePath(),finalDest,true);
+ waitOneAction.acquire();
+ switch(folderExistsAction)
+ {
+ case FolderExists_Merge:
+ break;
+ case FolderExists_Skip:
+ return;
+ break;
+ case FolderExists_Rename:
+ if(newName=="")
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"pattern: "+folder_isolation.pattern());
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"full: "+destinationSuffixPath);
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"prefix: "+prefix);
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"suffix: "+suffix);
+ //resolv the new name
+ QFileInfo destinationInfo;
+ int num=1;
+ do
+ {
+ if(num==1)
+ {
+ if(firstRenamingRule=="")
+ destinationSuffixPath=tr("%1 - copy").arg(suffix);
+ else
+ {
+ destinationSuffixPath=firstRenamingRule;
+ destinationSuffixPath.replace("%name%",suffix);
+ }
+ }
+ else
+ {
+ if(otherRenamingRule=="")
+ destinationSuffixPath=tr("%1 - copy (%2)").arg(suffix).arg(num);
+ else
+ {
+ destinationSuffixPath=otherRenamingRule;
+ destinationSuffixPath.replace("%name%",suffix);
+ destinationSuffixPath.replace("%number%",QString::number(num));
+ }
+ }
+ num++;
+ destinationInfo.setFile(prefix+destinationSuffixPath);
+ }
+ while(destinationInfo.exists());
+ }
+ else
+ destinationSuffixPath = newName;
+ destinationSuffixPath+="/";
+ finalDest = destination+destinationSuffixPath;
+ break;
+ default:
+ return;
+ break;
+ }
+ }
+ //check if destination exists
+ if(checkDestinationExists)
+ {
+ QDir finalSource(newSource);
+ QDir destinationDir(finalDest);
+ if(destinationDir.exists())
+ {
+ emit folderAlreadyExists(finalSource.absolutePath(),destinationDir.absolutePath(),false);
+ waitOneAction.acquire();
+ switch(folderExistsAction)
+ {
+ case FolderExists_Merge:
+ break;
+ case FolderExists_Skip:
+ return;
+ break;
+ case FolderExists_Rename:
+ if(newName=="")
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"pattern: "+folder_isolation.pattern());
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"full: "+destinationSuffixPath);
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"prefix: "+prefix);
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"suffix: "+suffix);
+ //resolv the new name
+ QFileInfo destinationInfo;
+ int num=1;
+ do
+ {
+ if(num==1)
+ {
+ if(firstRenamingRule=="")
+ destinationSuffixPath=tr("%1 - copy").arg(suffix);
+ else
+ {
+ destinationSuffixPath=firstRenamingRule;
+ destinationSuffixPath.replace("%name%",suffix);
+ }
+ }
+ else
+ {
+ if(otherRenamingRule=="")
+ destinationSuffixPath=tr("%1 - copy (%2)").arg(suffix).arg(num);
+ else
+ {
+ destinationSuffixPath=otherRenamingRule;
+ destinationSuffixPath.replace("%name%",suffix);
+ destinationSuffixPath.replace("%number%",QString::number(num));
+ }
+ }
+ destinationInfo.setFile(prefix+destinationSuffixPath);
+ num++;
+ }
+ while(destinationInfo.exists());
+ }
+ else
+ destinationSuffixPath = newName;
+ destinationSuffixPath+="/";
+ finalDest = destination+destinationSuffixPath;
+ break;
+ default:
+ return;
+ break;
+ }
+ }
+ }
+ //do source check
+ QDir finalSource(newSource);
+ QFileInfo dirInfo(newSource);
+ //check of source is readable
+ do
+ {
+ fileErrorAction=FileError_NotSet;
+ if(!dirInfo.isReadable() || !dirInfo.isExecutable() || !dirInfo.exists())
+ {
+ if(!dirInfo.exists())
+ emit errorOnFolder(dirInfo,tr("The folder not exists"));
+ else
+ emit errorOnFolder(dirInfo,tr("The folder is not readable"));
+ waitOneAction.acquire();
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"actionNum: "+QString::number(fileErrorAction));
+ }
+ } while(fileErrorAction==FileError_Retry);
+ /// \todo check here if the folder is not readable or not exists
+ QFileInfoList entryList=finalSource.entryInfoList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::Hidden|QDir::System,QDir::DirsFirst|QDir::Name|QDir::IgnoreCase);//possible wait time here
+ int sizeEntryList=entryList.size();
+ emit newFolderListing(newSource);
+ if(sizeEntryList==0)
+ emit addToMkPath(finalDest);
+ for (int index=0;index<sizeEntryList;++index)
+ {
+ QFileInfo fileInfo=entryList.at(index);
+ if(stopIt)
+ return;
+ if(haveFilters)
+ {
+ if(reloadTheNewFilters)
+ {
+ QMutexLocker lock(&filtersMutex);
+ QCoreApplication::processEvents(QEventLoop::AllEvents);
+ reloadTheNewFilters=false;
+ this->include=this->include_send;
+ this->exclude=this->exclude_send;
+ }
+ QString fileName=fileInfo.fileName();
+ if(fileInfo.isDir())
+ {
+ bool excluded=false,included=(include.size()==0);
+ int filters_index=0;
+ while(filters_index<exclude.size())
+ {
+ if(exclude.at(filters_index).apply_on==ApplyOn_folder || exclude.at(filters_index).apply_on==ApplyOn_fileAndFolder)
+ {
+ if(fileName.contains(exclude.at(filters_index).regex))
+ {
+ excluded=true;
+ break;
+ }
+ }
+ filters_index++;
+ }
+ if(excluded)
+ {}
+ else
+ {
+ filters_index=0;
+ while(filters_index<include.size())
+ {
+ if(include.at(filters_index).apply_on==ApplyOn_folder || include.at(filters_index).apply_on==ApplyOn_fileAndFolder)
+ {
+ if(fileName.contains(include.at(filters_index).regex))
+ {
+ included=true;
+ break;
+ }
+ }
+ filters_index++;
+ }
+ if(!included)
+ {}
+ else
+ listFolder(source,destination,sourceSuffixPath+fileInfo.fileName()+"/",destinationSuffixPath+fileName+"/");
+ }
+ }
+ else
+ {
+ bool excluded=false,included=(include.size()==0);
+ int filters_index=0;
+ while(filters_index<exclude.size())
+ {
+ if(exclude.at(filters_index).apply_on==ApplyOn_file || exclude.at(filters_index).apply_on==ApplyOn_fileAndFolder)
+ {
+ if(fileName.contains(exclude.at(filters_index).regex))
+ {
+ excluded=true;
+ break;
+ }
+ }
+ filters_index++;
+ }
+ if(excluded)
+ {}
+ else
+ {
+ filters_index=0;
+ while(filters_index<include.size())
+ {
+ if(include.at(filters_index).apply_on==ApplyOn_file || include.at(filters_index).apply_on==ApplyOn_fileAndFolder)
+ {
+ if(fileName.contains(include.at(filters_index).regex))
+ {
+ included=true;
+ break;
+ }
+ }
+ filters_index++;
+ }
+ if(!included)
+ {}
+ else
+ {
+ bool sendToTransfer=false;
+ if(!rsync)
+ sendToTransfer=true;
+ else if(!QFile::exists(finalDest+fileName))
+ sendToTransfer=true;
+ else if(fileInfo.lastModified()!=QFileInfo(finalDest+fileName).lastModified())
+ sendToTransfer=true;
+ if(sendToTransfer)
+ emit fileTransfer(fileInfo.absoluteFilePath(),finalDest+fileName,mode);
+ }
+ }
+ }
+ }
+ else
+ {
+ if(fileInfo.isDir())//possible wait time here
+ //listFolder(source,destination,suffixPath+fileInfo.fileName()+QDir::separator());
+ listFolder(source,destination,sourceSuffixPath+fileInfo.fileName()+"/",destinationSuffixPath+fileInfo.fileName()+"/");//put unix separator because it's transformed into that's under windows too
+ else
+ {
+ bool sendToTransfer=false;
+ if(!rsync)
+ sendToTransfer=true;
+ else if(!QFile::exists(finalDest+fileInfo.fileName()))
+ sendToTransfer=true;
+ else if(fileInfo.lastModified()!=QFileInfo(finalDest+fileInfo.fileName()).lastModified())
+ sendToTransfer=true;
+ if(sendToTransfer)
+ emit fileTransfer(fileInfo.absoluteFilePath(),finalDest+fileInfo.fileName(),mode);
+ }
+ }
+ }
+ if(rsync)
+ {
+ //check the reverse path here
+ QFileInfoList entryListDestination=QDir(finalDest).entryInfoList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::Hidden|QDir::System,QDir::DirsFirst|QDir::Name|QDir::IgnoreCase);//possible wait time here
+ int sizeEntryListDestination=entryListDestination.size();
+ int index=0;
+ for (int indexDestination=0;indexDestination<sizeEntryListDestination;++indexDestination)
+ {
+ index=0;
+ while(index<sizeEntryList)
+ {
+ if(entryListDestination.at(indexDestination).fileName()==entryList.at(index).fileName())
+ break;
+ index++;
+ }
+ if(index==sizeEntryList)
+ {
+ //then not found, need be remove
+ emit addToRmForRsync(finalDest+entryListDestination.at(indexDestination).fileName());
+ }
+ }
+ return;
+ }
+
+ if(mode==Move)
+ {
+ ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"newSource: "+newSource+", sizeEntryList: "+QString::number(sizeEntryList));
+ emit addToRmPath(newSource,sizeEntryList);
+ }
+}
+
+//set if need check if the destination exists
+void scanFileOrFolder::setCheckDestinationFolderExists(const bool checkDestinationFolderExists)
+{
+ this->checkDestinationExists=checkDestinationFolderExists;
+}
+
+void scanFileOrFolder::setRenamingRules(QString firstRenamingRule,QString otherRenamingRule)
+{
+ this->firstRenamingRule=firstRenamingRule;
+ this->otherRenamingRule=otherRenamingRule;
+}
+
+/// \brief set rsync
+void scanFileOrFolder::setRsync(const bool rsync)
+{
+ this->rsync=rsync;
+}