#include #include #include "boost/filesystem.hpp" #include #include namespace fs = boost::filesystem; using boost::filesystem::path; using boost::next; using boost::prior; using namespace crea; namespace creaImageIO { //==================================================================== // Ctor TreeHandlerImageAdder::TreeHandlerImageAdder(TreeHandler* tree) : mTreeHandler(tree) { } // Dtor TreeHandlerImageAdder::~TreeHandlerImageAdder() { } //==================================================================== //==================================================================== void TreeHandlerImageAdder::ConnectProgressObserver(ProgressCallbackType callback) { mProgressSignal.connect(callback); } //==================================================================== //===================================================================== bool TreeHandlerImageAdder::IsHandledFile( const std::string& filename) { return (mReader.CanRead(filename)); } //===================================================================== //===================================================================== void TreeHandlerImageAdder::AddFiles( const std::vector& filenames) { mProgress.Reset(); unsigned int nbf = filenames.size(); std::vector::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<InsertIgnoreFile(addKey,(*i),"0",removedOn.str(),mCurrentDB); AddFile(*i); } mProgressSignal(mProgress); if (mProgress.GetStop()) break; } } //===================================================================== //===================================================================== void TreeHandlerImageAdder::AddDirectory( const std::string& directory, bool recurse) { mProgress.Reset(); std::stringstream files; std::stringstream rec; rec<InsertAddOp(directory,rec.str(),"0",mCurrentDB); std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB); AddDirectoryRecursor( directory, recurse, addKey ); int nFiles=GetProgress().GetNumberAddedFiles(); files<SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey,mCurrentDB); GimmickDebugMessage(3,mProgress< attr; mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr); mReader.ReadAttributes(filename,attr); int lev = mTreeHandler->AddBranch(attr); // update the progress according to lev if (levGetTree().GetNumberOfLevels()) mProgress.IncNumberAddedFiles(); } //===================================================================== 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<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& nodes) { std::vector::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<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, const std::string &addKey) { GimmickDebugMessage(4,"Scanning '"<status()) ) { if (recursive) { AddDirectoryRecursor( itr->string(), recursive, addKey); } } else { 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<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 &i_ignorefiles, std::vector & attsModified, std::vector & 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::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 fileList; std::vector ignoreList; std::vector newFiles; std::vector attsModified; std::stringstream mess; std::vector::iterator iter; //Gets the list of added files mSynchronizer->GetFileList(fileList,mCurrentDB); std::vector::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); } //Add to message the result of new found files mess<<"New Files Found: "<0) { mess<<"Filenames: "<0) { mess<<"Filenames: "<0) { mess<<"Filenames: "<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<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<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: "<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: "<& 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) { 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::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::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& filenames, const std::string directory ) { std::vector::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 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<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<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<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<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<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+"%"); } }