1 #include <creaImageIOTreeHandlerImageAdder.h>
2 #include <creaImageIOSystem.h>
3 #include "boost/filesystem.hpp"
4 #include <boost/filesystem/operations.hpp>
5 #include <boost/utility.hpp>
8 namespace fs = boost::filesystem;
9 using boost::filesystem::path;
18 //====================================================================
20 TreeHandlerImageAdder::TreeHandlerImageAdder(TreeHandler* tree)
25 TreeHandlerImageAdder::~TreeHandlerImageAdder()
28 //====================================================================
30 //====================================================================
31 void TreeHandlerImageAdder::ConnectProgressObserver(ProgressCallbackType callback)
33 mProgressSignal.connect(callback);
35 //====================================================================
37 //=====================================================================
38 bool TreeHandlerImageAdder::IsHandledFile( const std::string& filename)
40 return (mReader.CanRead(filename));
42 //=====================================================================
44 //=====================================================================
45 void TreeHandlerImageAdder::AddFiles( const std::vector<std::string>& filenames)
49 unsigned int nbf = filenames.size();
50 std::vector<std::string>::const_iterator i;
51 for (i=filenames.begin();i!=filenames.end();++i)
53 mTimestampHandler->AddFile((*i), fs::last_write_time(*i), time(0),mCurrentDB);
54 mProgress.IncNumberScannedFiles();
55 if (IsHandledFile(*i))
57 mProgress.IncNumberHandledFiles();
58 mSynchronizer->InsertAddOp((*i),"0","1",mCurrentDB);
59 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i),mCurrentDB);
60 std::stringstream removedOn;
62 mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str(),mCurrentDB);
65 mProgressSignal(mProgress);
66 if (mProgress.GetStop()) break;
69 //=====================================================================
71 //=====================================================================
72 void TreeHandlerImageAdder::AddDirectory( const std::string& directory,
76 std::stringstream files;
78 std::stringstream rec;
80 mSynchronizer->InsertAddOp(directory,rec.str(),"0",mCurrentDB);
81 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
82 AddDirectoryRecursor( directory, recurse, addKey );
84 int nFiles=GetProgress().GetNumberAddedFiles();
86 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey,mCurrentDB);
87 GimmickDebugMessage(3,mProgress<<std::endl);
90 //=====================================================================
91 void TreeHandlerImageAdder::AddFile( const std::string& filename )
93 GimmickDebugMessage(4,"Adding '"<<filename<<"'"<<std::endl);
94 std::map< std::string, std::string> attr;
95 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
97 mReader.ReadAttributes(filename,attr);
99 int lev = mTreeHandler->AddBranch(attr);
101 // update the progress according to lev
102 if (lev<mTreeHandler->GetTree().GetNumberOfLevels())
103 mProgress.IncNumberAddedFiles();
105 //=====================================================================
107 void TreeHandlerImageAdder::RemoveFile( tree::Node* node)
109 int n=node->GetNumberOfChildren();
112 RemoveFiles(node->GetChildrenList());
116 std::string path=node->GetAttribute("FullFileName");
118 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
119 //Gets the number of files added
120 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
122 std::stringstream out;
124 //Sets the new number of files
125 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
126 //Sets the file as removed
127 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
131 //=====================================================================
133 void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
135 std::vector<tree::Node*>::const_iterator it;
136 for(it=nodes.begin();it!=nodes.end();++it)
138 int n=(*it)->GetNumberOfChildren();
141 RemoveFiles((*it)->GetChildrenList());
145 std::string path=(*it)->GetAttribute("FullFileName");
147 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
148 //Gets the number of files added
149 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
151 std::stringstream out;
153 //Sets the new number of files
154 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
155 //Sets the file as removed
156 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
162 //=====================================================================
163 void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath,
165 const std::string &addKey)
167 GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
168 mProgress.IncNumberScannedDirs();
170 if ( !fs::exists( dirpath ) ) return;
171 time_t lastModif=fs::last_write_time(dirpath);
173 fs::directory_iterator end_itr; // default construction yields past-the-end
174 for ( fs::directory_iterator itr( dirpath );
178 // If is directory & recurse : do recurse
179 if ( fs::is_directory(itr->status()) )
183 AddDirectoryRecursor( itr->string(), recursive, addKey);
188 std::string parent_id;
189 bool valid=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0),mCurrentDB);
192 mProgress.IncNumberScannedFiles();
193 if (IsHandledFile(itr->string()))
195 mProgress.IncNumberHandledFiles();
196 AddFile( itr->string() );
197 mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
198 mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",itr->string());
199 std::stringstream removedOn;
201 mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
204 mProgressSignal(mProgress);
205 if (mProgress.GetStop())
212 mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",dirpath);
217 //=======================================================================
219 //=======================================================================
221 void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath,
224 bool checkAttributes,
225 std::vector<std::string> &i_ignorefiles,
226 std::vector<std::string> & attsModified,
227 std::vector<std::string> & newfiles)
229 if ( !fs::exists( dirpath ) ) return;
230 fs::directory_iterator end_itr; // default construction yields past-the-end
232 for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
234 // If is directory & recurse : do recurse
235 if ( fs::is_directory(itr->status()) )
239 CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
244 if (IsHandledFile(itr->string()))
247 for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
249 if((*it_new) == itr->string())
252 //Additional checking of attributes
255 CheckAttributes(repair,(*it_new),attsModified);
257 i_ignorefiles.erase(it_new);
261 if(!bfound && i_ignorefiles.size()>0 )
263 newfiles.push_back( itr->string() );
270 //=======================================================================
272 //=======================================================================
274 std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
276 std::vector<AddList> fileList;
277 std::vector<std::string> ignoreList;
278 std::vector<std::string> newFiles;
279 std::vector<std::string> attsModified;
280 std::stringstream mess;
281 std::vector<AddList>::iterator iter;
283 //Gets the list of added files
284 mSynchronizer->GetFileList(fileList,mCurrentDB);
286 std::vector<std::string>::iterator i;
287 //Actions to take if the user doesn't want to repair
290 //Iterates to see if they are in sync
291 for(iter=fileList.begin();iter!=fileList.end();++iter)
293 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
295 if((*iter).recursive=="0"){rec=false;}
296 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
299 //Add to message the result of new found files
300 mess<<"New Files Found: "<<newFiles.size()<<std::endl;
301 if(newFiles.size()>0)
303 mess<<"Filenames: "<<std::endl;
304 for(i=newFiles.begin();i!=newFiles.end();++i)
310 //Add to message the result of missing files
311 mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
312 if(ignoreList.size()>0)
314 mess<<"Filenames: "<<std::endl;
315 for(i=ignoreList.begin();i!=ignoreList.end();++i)
321 //In the case that the user wants to check the attributes...
324 //... add to message the result of files that have been changed.
325 mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
326 if(attsModified.size()>0)
328 mess<<"Filenames: "<<std::endl;
329 for(i=attsModified.begin();i!=attsModified.end();++i)
338 //Actions to take if the user wants to repair
342 //Iterates to see if they are in sync
343 for(iter=fileList.begin();iter!=fileList.end();++iter)
345 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
347 if((*iter).recursive=="0"){rec=false;}
348 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
350 //For the new files, add them
351 for (i=newFiles.begin();i!=newFiles.end();++i)
353 mTimestampHandler->AddFile((*i), fs::last_write_time(*i), time(0),mCurrentDB);
354 if (IsHandledFile(*i))
356 std::stringstream removedOn;
358 mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str(),mCurrentDB);
359 //Gets the number of files added
360 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key,mCurrentDB)).c_str());
362 std::stringstream out;
364 //Sets the new number of files
365 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key,mCurrentDB);
373 //Reports number of added files
374 mess<<"Files Added: "<<nf<<std::endl;
376 //Removes the necessary files and reports the results
377 if(ignoreList.size()>0)
380 mTreeHandler->LoadChildren(NULL,4);
381 for(i=ignoreList.begin();i!=ignoreList.end();++i)
383 FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
385 mTreeHandler->Remove(node);
388 mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
389 //In the case that the user wants to check the attributes...
392 //... add to message the result of files that were modified.
393 mess<<"Files Modified: "<<attsModified.size()<<std::endl;
399 //=======================================================================
401 void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
403 std::map< std::string, std::string> attr;
404 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
405 mReader.ReadAttributes(file,attr);
406 tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);
407 tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
408 for (a = adl.begin();a!=adl.end();++a)
410 std::string databaseVal;
411 mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
412 std::string fileVal=attr.find(a->GetKey())->second;
413 if ( a->GetFlags()==0 && databaseVal.compare(fileVal)!=0 )
417 mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
419 attsModified.push_back(file);
426 //=======================================================================
429 void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
433 std::vector<tree::Node*>::iterator iter;
434 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
436 FindNode(*iter,level-1,searchParam,searchVal,node);
441 if(parent->GetAttribute(searchParam).compare(searchVal)==0)
449 //=======================================================================
450 void TreeHandlerImageAdder::FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
454 std::vector<tree::Node*>::iterator iter;
455 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end() && node==0 ;++iter)
457 FindNodePartial(*iter,level-1,searchParam,searchVal,node);
462 if(parent->GetAttribute(searchParam).find(searchVal)<9000)
471 //=======================================================================
473 void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory )
475 std::vector<std::string>::const_iterator i;
476 if(!boost::filesystem::exists(directory))
478 boost::filesystem::create_directory(boost::filesystem::path(directory));
479 mTimestampHandler->AddDirectory("",directory,fs::last_write_time(directory)+10, time(0),mCurrentDB);
480 mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
482 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
483 std::string parent_id=mTimestampHandler->IsIndexed(directory,mCurrentDB);
485 std::vector<std::string> newNames;
486 for(i=filenames.begin();i!=filenames.end();++i)
488 std::string dir=directory.c_str();
489 mTimestampHandler->CleanPath(dir);
490 if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
493 last=(*i).find_last_of('/');
494 std::string f="\\"+(*i).substr(last+1);
497 std::stringstream out;
499 while(boost::filesystem::exists(out.str()))
502 out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
505 std::string result=out.str();
506 mTimestampHandler->CleanPath(result);
507 boost::filesystem::copy_file((*i),result);
509 //To update image database
510 mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
512 //To update timestamp database
513 mTimestampHandler->SetAttribute("PATH",result,"PATH",(*i));
514 mTimestampHandler->SetAttribute("PARENT_ID",parent_id,"PATH",result);
516 t<<fs::last_write_time(directory)+10;
517 mTimestampHandler->SetAttribute("LastModified",t.str(),"PATH",result);
519 //To update maintenance database
520 //1.Add the new path and increase number of children on new operation.
521 std::stringstream removedOn;
524 mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
525 //Gets the number of files added
526 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
528 std::stringstream fil;
530 //Sets the new number of files
531 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
534 //2.Set the old path as removed and decrease number of children on old operation.
535 //Gets the old add key
536 std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
537 //Sets the file as removed
538 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
539 //Gets the number of files added
540 files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
543 //Sets the new number of files
544 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
551 //=======================================================================
553 void TreeHandlerImageAdder::DeleteDriveFromMainDB(const std::string& drive)
555 //Delete from local database and others
557 mTreeHandler->LoadChildren(NULL,4);
558 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
561 mTreeHandler->Remove(node);
563 mTreeHandler->LoadChildren(NULL,4);
564 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
568 //=======================================================================
570 void TreeHandlerImageAdder::DeleteDriveFromOtherDB(const std::string& drive)
572 //Delete from timestamp
573 mTimestampHandler->RemoveEntries("FILES", "PATH", "LIKE", drive+"%");
575 //Delete from maintenance
576 mSynchronizer->RemoveEntries("ADD_OPS", "PATH", "LIKE", drive+"%");
577 mSynchronizer->RemoveEntries("IGNORED_FILES", "PATH", "LIKE", drive+"%");
580 //=======================================================================
581 void TreeHandlerImageAdder::EditField(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
583 node->SetAttribute(key,val);
584 mTreeHandler->SetAttribute(node,key,val);