#include <creaImageIOTreeHandlerImageAdder.h>
#include <creaImageIOSystem.h>
-//#include <wx/dir.h>
-//#include <wx/filename.h>
-
#include "boost/filesystem.hpp"
+#include <boost/filesystem/operations.hpp>
+#include <boost/utility.hpp>
+
namespace fs = boost::filesystem;
+using boost::filesystem::path;
+using boost::next;
+using boost::prior;
-//using namespace crea;
+
+using namespace crea;
namespace creaImageIO
{
void TreeHandlerImageAdder::AddFiles( const std::vector<std::string>& filenames)
{
mProgress.Reset();
-
+
unsigned int nbf = filenames.size();
std::vector<std::string>::const_iterator i;
for (i=filenames.begin();i!=filenames.end();++i)
{
-
+ mTimestampHandler->AddFile((*i), fs::last_write_time(*i), time(0),mCurrentDB);
mProgress.IncNumberScannedFiles();
if (IsHandledFile(*i))
{
mProgress.IncNumberHandledFiles();
+ mSynchronizer->InsertAddOp((*i),"0","1",mCurrentDB);
+ std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i),mCurrentDB);
+ std::stringstream removedOn;
+ removedOn<<time(0);
+ mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str(),mCurrentDB);
AddFile(*i);
}
mProgressSignal(mProgress);
bool recurse)
{
mProgress.Reset();
- AddDirectoryRecursor( directory, recurse );
+ std::stringstream files;
+
+ std::stringstream rec;
+ rec<<recurse;
+ mSynchronizer->InsertAddOp(directory,rec.str(),"0",mCurrentDB);
+ std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
+ mTreeHandler->BeginTransaction();
+ AddDirectoryRecursor( directory, recurse, addKey );
+
+ int nFiles=GetProgress().GetNumberAddedFiles();
+ files<<nFiles;
+ mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey,mCurrentDB);
+ mTreeHandler->EndTransaction();
GimmickDebugMessage(3,mProgress<<std::endl);
}
}
//=====================================================================
+ void TreeHandlerImageAdder::RemoveFile( tree::Node* node)
+ {
+ int n=node->GetNumberOfChildren();
+ if(n>0)
+ {
+ RemoveFiles(node->GetChildrenList());
+ }
+ else
+ {
+ std::string path=node->GetAttribute("FullFileName");
+ //Gets the add key
+ std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
+ //Gets the number of files added
+ int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
+ files=files-1;
+ std::stringstream out;
+ out<<files;
+ //Sets the new number of files
+ mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
+ //Sets the file as removed
+ mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
+ }
+ }
+
+ //=====================================================================
+
+ void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
+ {
+ std::vector<tree::Node*>::const_iterator it;
+ for(it=nodes.begin();it!=nodes.end();++it)
+ {
+ int n=(*it)->GetNumberOfChildren();
+ if(n>0)
+ {
+ RemoveFiles((*it)->GetChildrenList());
+ }
+ else
+ {
+ std::string path=(*it)->GetAttribute("FullFileName");
+ //Gets the add key
+ std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
+ //Gets the number of files added
+ int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
+ files=files-1;
+ std::stringstream out;
+ out<<files;
+ //Sets the new number of files
+ mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
+ //Sets the file as removed
+ mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
+ }
+
+ }
+ }
+
//=====================================================================
void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath,
- bool recursive)
+ bool recursive,
+ const std::string &addKey)
{
GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
mProgress.IncNumberScannedDirs();
if ( !fs::exists( dirpath ) ) return;
-
+ time_t lastModif=fs::last_write_time(dirpath);
+
fs::directory_iterator end_itr; // default construction yields past-the-end
for ( fs::directory_iterator itr( dirpath );
itr != end_itr;
// If is directory & recurse : do recurse
if ( fs::is_directory(itr->status()) )
{
- if (recursive) AddDirectoryRecursor( itr->string(), recursive);
+ if (recursive)
+ {
+ AddDirectoryRecursor( itr->string(), recursive, addKey);
+ }
}
else
{
- mProgress.IncNumberScannedFiles();
- if (IsHandledFile(itr->string()))
- {
- mProgress.IncNumberHandledFiles();
- AddFile( itr->string() );
- }
- mProgressSignal(mProgress);
- if (mProgress.GetStop()) break;
+ std::string parent_id;
+ bool valid=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0),mCurrentDB);
+ if(valid)
+ {
+ mProgress.IncNumberScannedFiles();
+ if (IsHandledFile(itr->string()))
+ {
+ mProgress.IncNumberHandledFiles();
+ AddFile( itr->string() );
+ mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
+ mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",itr->string());
+ std::stringstream removedOn;
+ removedOn<<time(0);
+ mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
+ }
+
+ mProgressSignal(mProgress);
+ if (mProgress.GetStop())
+ {
+ //itr = end_itr;
+ break;
+ }
+
+ }
+ mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",dirpath);
}
}
-
+
}
+ //=======================================================================
+
+ //=======================================================================
+
+ void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath,
+ bool recursive,
+ bool repair,
+ bool checkAttributes,
+ std::vector<std::string> &i_ignorefiles,
+ std::vector<std::string> & attsModified,
+ std::vector<std::string> & newfiles)
+ {
+ if ( !fs::exists( dirpath ) ) return;
+ fs::directory_iterator end_itr; // default construction yields past-the-end
+
+ for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
+ {
+ // If is directory & recurse : do recurse
+ if ( fs::is_directory(itr->status()) )
+ {
+ if (recursive)
+ {
+ CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
+ }
+ }
+ else
+ {
+ if (IsHandledFile(itr->string()))
+ {
+ bool bfound = false;
+ for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
+ {
+ if((*it_new) == itr->string())
+ {
+ bfound = true;
+ //Additional checking of attributes
+ if(checkAttributes)
+ {
+ CheckAttributes(repair,(*it_new),attsModified);
+ }
+ i_ignorefiles.erase(it_new);
+ break;
+ }
+ }
+ if(!bfound && i_ignorefiles.size()>0 )
+ {
+ newfiles.push_back( itr->string() );
+ }
+ }
+ }
+ }
+ }
+
+ //=======================================================================
+
+ //=======================================================================
- /*
+ std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
+ {
+ std::vector<AddList> fileList;
+ std::vector<std::string> ignoreList;
+ std::vector<std::string> newFiles;
+ std::vector<std::string> attsModified;
+ std::stringstream mess;
+ std::vector<AddList>::iterator iter;
- std::string fileName;
- std::string dirName = dirpath;
+ //Gets the list of added files
+ mSynchronizer->GetFileList(fileList,mCurrentDB);
- wxDir dir( std2wx(dirpath) );
+ std::vector<std::string>::iterator i;
+ //Actions to take if the user doesn't want to repair
+ if(!repair)
+ {
+ //Iterates to see if they are in sync
+ for(iter=fileList.begin();iter!=fileList.end();++iter)
+ {
+ mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
+ bool rec=true;
+ if((*iter).recursive=="0"){rec=false;}
+ CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
+ }
- if ( !dir.IsOpened() )
- {
- // deal with the error here - wxDir would already log an error message
- // explaining the exact reason of the failure
- return;
- }
+ //Add to message the result of new found files
+ mess<<"New Files Found: "<<newFiles.size()<<std::endl;
+ if(newFiles.size()>0)
+ {
+ mess<<"Filenames: "<<std::endl;
+ for(i=newFiles.begin();i!=newFiles.end();++i)
+ {
+ mess<<*i<<std::endl;
+ }
+ }
- wxString filename;
+ //Add to message the result of missing files
+ mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
+ if(ignoreList.size()>0)
+ {
+ mess<<"Filenames: "<<std::endl;
+ for(i=ignoreList.begin();i!=ignoreList.end();++i)
+ {
+ mess<<*i<<std::endl;
+ }
+ }
- bool cont = dir.GetFirst(&filename, wxEmptyString,
- wxDIR_FILES | wxDIR_HIDDEN );
- while ( cont )
- {
- mProgress.IncNumberScannedFiles();
+ //In the case that the user wants to check the attributes...
+ if(checkAttributes)
+ {
+ //... add to message the result of files that have been changed.
+ mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
+ if(attsModified.size()>0)
+ {
+ mess<<"Filenames: "<<std::endl;
+ for(i=attsModified.begin();i!=attsModified.end();++i)
+ {
+ mess<<*i<<std::endl;
+ }
+ }
+ }
+
+ }
- wxFileName wxffn(dir.GetName(),filename);
- std::string ffn = wx2std(wxffn.GetFullPath());
- if (IsHandledFile(ffn))
+ //Actions to take if the user wants to repair
+ else
{
- mProgress.IncNumberHandledFiles();
- AddFile( ffn );
+ int nf=0;
+ //Iterates to see if they are in sync
+ for(iter=fileList.begin();iter!=fileList.end();++iter)
+ {
+ mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
+ bool rec=true;
+ if((*iter).recursive=="0"){rec=false;}
+ CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
+
+ //For the new files, add them
+ for (i=newFiles.begin();i!=newFiles.end();++i)
+ {
+ mTimestampHandler->AddFile((*i), fs::last_write_time(*i), time(0),mCurrentDB);
+ if (IsHandledFile(*i))
+ {
+ std::stringstream removedOn;
+ removedOn<<time(0);
+ mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str(),mCurrentDB);
+ //Gets the number of files added
+ int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key,mCurrentDB)).c_str());
+ files=files+1;
+ std::stringstream out;
+ out<<files;
+ //Sets the new number of files
+ mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key,mCurrentDB);
+ AddFile(*i);
+ }
+ }
+ nf+=newFiles.size();
+ newFiles.clear();
+
+ }
+ //Reports number of added files
+ mess<<"Files Added: "<<nf<<std::endl;
+
+ //Removes the necessary files and reports the results
+ if(ignoreList.size()>0)
+ {
+ tree::Node* node;
+ mTreeHandler->LoadChildren(NULL,4);
+ for(i=ignoreList.begin();i!=ignoreList.end();++i)
+ {
+ FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
+ RemoveFile(node);
+ mTreeHandler->Remove(node);
+ }
+ }
+ mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
+ //In the case that the user wants to check the attributes...
+ if(checkAttributes)
+ {
+ //... add to message the result of files that were modified.
+ mess<<"Files Modified: "<<attsModified.size()<<std::endl;
+ }
}
- mProgressSignal(mProgress);
- cont = ( dir.GetNext(&filename) && (!mProgress.GetStop()) );
- }
-
- // Recurse into subdirs
- if ( recursive )
- {
- cont = dir.GetFirst(&filename, wxEmptyString,
- wxDIR_DIRS | wxDIR_HIDDEN );
- while ( cont )
+ return mess.str();
+
+ }
+ //=======================================================================
+
+ void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
+ {
+ std::map< std::string, std::string> attr;
+ mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
+ mReader.ReadAttributes(file,attr);
+ tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);
+ tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
+ for (a = adl.begin();a!=adl.end();++a)
{
- wxFileName wxffn(dir.GetName(),filename);
- std::string ffn = wx2std(wxffn.GetFullPath());
- AddDirectoryRecursor( ffn, recursive);
- cont = dir.GetNext(&filename);
+ std::string databaseVal;
+ mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
+ std::string fileVal=attr.find(a->GetKey())->second;
+ if ( a->GetFlags()==0 && databaseVal.compare(fileVal)!=0 )
+ {
+ if(repair)
+ {
+ mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
+ }
+ attsModified.push_back(file);
+ }
+
}
- }
+
+ }
+
+ //=======================================================================
+
+
+ void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
+ {
+ if(level>1)
+ {
+ std::vector<tree::Node*>::iterator iter;
+ for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
+ {
+ FindNode(*iter,level-1,searchParam,searchVal,node);
+ }
+ }
+ else
+ {
+ if(parent->GetAttribute(searchParam).compare(searchVal)==0)
+ {
+ node=parent;
+ }
+
+ }
+ }
- */
+ //=======================================================================
+ void TreeHandlerImageAdder::FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
+ {
+ if(level>1)
+ {
+ std::vector<tree::Node*>::iterator iter;
+ for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end() && node==0 ;++iter)
+ {
+ FindNodePartial(*iter,level-1,searchParam,searchVal,node);
+ }
+ }
+ else
+ {
+ if(parent->GetAttribute(searchParam).find(searchVal)<9000)
+ {
+ node=parent;
+ return;
+ }
+
+ }
+ }
//=======================================================================
+ void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory )
+ {
+ std::vector<std::string>::const_iterator i;
+ if(!boost::filesystem::exists(directory))
+ {
+ boost::filesystem::create_directory(boost::filesystem::path(directory));
+ mTimestampHandler->AddDirectory("",directory,fs::last_write_time(directory)+10, time(0),mCurrentDB);
+ mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
+ }
+ std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
+ std::string parent_id=mTimestampHandler->IsIndexed(directory,mCurrentDB);
+ size_t last;
+ std::vector<std::string> newNames;
+ for(i=filenames.begin();i!=filenames.end();++i)
+ {
+ std::string dir=directory.c_str();
+ mTimestampHandler->CleanPath(dir);
+ if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
+ {
+ std::string path=*i;
+ last=(*i).find_last_of('/');
+ std::string f="\\"+(*i).substr(last+1);
+
+ int p=1;
+ std::stringstream out;
+ out<<directory<<f;
+ while(boost::filesystem::exists(out.str()))
+ {
+ out.str("");
+ out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
+ p++;
+ }
+ std::string result=out.str();
+ mTimestampHandler->CleanPath(result);
+ boost::filesystem::copy_file((*i),result);
+
+ //To update image database
+ mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
+
+ //To update timestamp database
+ mTimestampHandler->SetAttribute("PATH",result,"PATH",(*i));
+ mTimestampHandler->SetAttribute("PARENT_ID",parent_id,"PATH",result);
+ std::stringstream t;
+ t<<fs::last_write_time(directory)+10;
+ mTimestampHandler->SetAttribute("LastModified",t.str(),"PATH",result);
+
+ //To update maintenance database
+ //1.Add the new path and increase number of children on new operation.
+ std::stringstream removedOn;
+ removedOn<<time(0);
+ //Inserts the file
+ mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
+ //Gets the number of files added
+ int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
+ files=files+1;
+ std::stringstream fil;
+ fil<<files;
+ //Sets the new number of files
+ mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
+ fil.str("");
+
+ //2.Set the old path as removed and decrease number of children on old operation.
+ //Gets the old add key
+ std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
+ //Sets the file as removed
+ mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
+ //Gets the number of files added
+ files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
+ files=files-1;
+ fil<<files;
+ //Sets the new number of files
+ mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
+
+ }
+
+ }
+ }
+
+ //=======================================================================
+
+ void TreeHandlerImageAdder::DeleteDriveFromMainDB(const std::string& drive)
+ {
+ //Delete from local database and others
+ tree::Node* node=0;
+ mTreeHandler->LoadChildren(NULL,4);
+ FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
+ while(node!=0)
+ {
+ mTreeHandler->Remove(node);
+ node=0;
+ mTreeHandler->LoadChildren(NULL,4);
+ FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
+ }
+ }
+
+ //=======================================================================
+
+ void TreeHandlerImageAdder::DeleteDriveFromOtherDB(const std::string& drive)
+ {
+ //Delete from timestamp
+ mTimestampHandler->RemoveEntries("FILES", "PATH", "LIKE", drive+"%");
+
+ //Delete from maintenance
+ mSynchronizer->RemoveEntries("ADD_OPS", "PATH", "LIKE", drive+"%");
+ mSynchronizer->RemoveEntries("IGNORED_FILES", "PATH", "LIKE", drive+"%");
+ }
+
+ //=======================================================================
+ void TreeHandlerImageAdder::EditField(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
+ {
+ node->SetAttribute(key,val);
+ mTreeHandler->SetAttribute(node,key,val);
+ }
+
+ //=======================================================================
+ void TreeHandlerImageAdder::GetAttributes(const std::vector<std::string>& params,
+ const std::string& filename,
+ std::vector<std::string>& results)
+ {
+ std::vector<std::string>::const_iterator i;
+ std::string result;
+ for(i=params.begin();i!=params.end();i++)
+ {
+ mTreeHandler->GetAttribute("Image","FullFileName",filename,*i,result);
+ results.push_back(result);
+ }
+ }
}