1 #include <creaImageIOTreeHandlerImageAdder.h>
2 #include <creaImageIOSystem.h>
3 #include "boost/filesystem.hpp"
4 #include <boost/filesystem/operations.hpp>
5 #include <boost/utility.hpp>
7 #include <creaImageIOGimmick.h>
11 namespace fs = boost::filesystem;
12 using boost::filesystem::path;
21 //====================================================================
23 TreeHandlerImageAdder::TreeHandlerImageAdder(TreeHandler* tree)
28 TreeHandlerImageAdder::~TreeHandlerImageAdder()
31 //====================================================================
33 //====================================================================
34 void TreeHandlerImageAdder::ConnectProgressObserver(ProgressCallbackType callback)
36 mProgressSignal.connect(callback);
38 //====================================================================
40 //=====================================================================
41 bool TreeHandlerImageAdder::IsHandledFile( const std::string& filename)
43 return (mReader.CanRead(filename));
45 //=====================================================================
47 //=====================================================================
48 void TreeHandlerImageAdder::AddFiles( const std::vector<std::string>& filenames)
52 unsigned int nbf = filenames.size();
53 std::vector<std::string>::const_iterator i;
54 mSynchronizer->GetList();
55 for (i=filenames.begin();i!=filenames.end();++i)
58 mProgress.IncNumberScannedFiles();
59 if (IsHandledFile(*i))
61 mProgress.IncNumberHandledFiles();
62 if(mSynchronizer->isIndexed(*i))
64 mSynchronizer->InsertAddOp((*i),"0","1",mCurrentDB);
65 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i),mCurrentDB);
66 std::stringstream removedOn;
68 mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str(),mCurrentDB);
72 mProgressSignal(mProgress);
73 if (mProgress.GetStop()) break;
76 //=====================================================================
78 //=====================================================================
79 void TreeHandlerImageAdder::AddDirectory( const std::string& directory,
83 std::stringstream files;
85 std::stringstream rec;
87 mSynchronizer->InsertAddOp(directory,rec.str(),"0",mCurrentDB);
88 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
89 mTreeHandler->BeginTransaction();
90 mSynchronizer->GetList();
91 AddDirectoryRecursor( directory, recurse, addKey );
93 int nFiles=GetProgress().GetNumberAddedFiles();
95 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey,mCurrentDB);
96 mTreeHandler->EndTransaction();
97 GimmickDebugMessage(3,mProgress<<std::endl);
100 //=====================================================================
101 void TreeHandlerImageAdder::AddFile( const std::string& filename )
103 GimmickDebugMessage(4,"Adding '"<<filename<<"'"<<std::endl);
104 std::map< std::string, std::string> attr;
105 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
107 mReader.ReadAttributes(filename,attr);
109 int lev = mTreeHandler->AddBranch(attr);
111 // update the progress according to lev
112 if (lev<mTreeHandler->GetTree().GetNumberOfLevels())
113 mProgress.IncNumberAddedFiles();
115 //=====================================================================
117 void TreeHandlerImageAdder::RemoveFile( tree::Node* node)
119 int n=node->GetNumberOfChildren();
122 RemoveFiles(node->GetChildrenList());
126 std::string path=node->GetAttribute("FullFileName");
128 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
129 //Gets the number of files added
130 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
132 std::stringstream out;
134 //Sets the new number of files
135 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
136 //Sets the file as removed
137 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
141 //=====================================================================
143 void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
145 std::vector<tree::Node*>::const_iterator it;
146 for(it=nodes.begin();it!=nodes.end();++it)
148 int n=(*it)->GetNumberOfChildren();
151 RemoveFiles((*it)->GetChildrenList());
155 std::string path=(*it)->GetAttribute("FullFileName");
157 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
158 //Gets the number of files added
159 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
161 std::stringstream out;
163 //Sets the new number of files
164 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
165 //Sets the file as removed
166 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
173 //=====================================================================
174 void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath,
176 const std::string &addKey)
178 GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
179 mProgress.IncNumberScannedDirs();
181 if ( !fs::exists( dirpath ) ) return;
182 time_t lastModif=fs::last_write_time(dirpath);
185 fs::directory_iterator end_itr; // default construction yields past-the-end
186 for ( fs::directory_iterator itr( dirpath );
190 // If is directory & recurse : do recurse
191 if ( fs::is_directory(itr->status()) )
195 AddDirectoryRecursor( itr->string(), recursive, addKey);
200 std::string parent_id;
201 // tTest if directory (and only it) exists or not.
202 bool valid = mSynchronizer->isIndexed(itr->string());//true;//=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0),mCurrentDB);
205 mProgress.IncNumberScannedFiles();
206 if (IsHandledFile(itr->string()))
208 mProgress.IncNumberHandledFiles();
209 AddFile( itr->string() );
210 mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
211 std::stringstream removedOn;
213 mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
216 mProgressSignal(mProgress);
217 if (mProgress.GetStop())
228 //=======================================================================
230 //=======================================================================
232 void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath,
235 bool checkAttributes,
236 std::vector<std::string> &i_ignorefiles,
237 std::vector<std::string> & attsModified,
238 std::vector<std::string> & newfiles)
240 if ( !fs::exists( dirpath ) ) return;
241 fs::directory_iterator end_itr; // default construction yields past-the-end
243 for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
245 // If is directory & recurse : do recurse
246 if ( fs::is_directory(itr->status()) )
250 CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
255 if (IsHandledFile(itr->string()))
258 for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
260 if((*it_new) == itr->string())
263 //Additional checking of attributes
266 CheckAttributes(repair,(*it_new),attsModified);
268 i_ignorefiles.erase(it_new);
272 if(!bfound && i_ignorefiles.size()>0 )
274 newfiles.push_back( itr->string() );
281 //=======================================================================
283 //=======================================================================
285 std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
287 std::vector<AddList> fileList;
288 std::vector<std::string> ignoreList;
289 std::vector<std::string> newFiles;
290 std::vector<std::string> attsModified;
291 std::stringstream mess;
292 std::vector<AddList>::iterator iter;
294 //Gets the list of added files
295 mSynchronizer->GetFileList(fileList,mCurrentDB);
297 std::vector<std::string>::iterator i;
298 //Actions to take if the user doesn't want to repair
301 //Iterates to see if they are in sync
302 for(iter=fileList.begin();iter!=fileList.end();++iter)
304 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
306 if((*iter).recursive=="0"){rec=false;}
307 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
310 //Add to message the result of new found files
311 mess<<"New Files Found: "<<newFiles.size()<<std::endl;
312 if(newFiles.size()>0)
314 mess<<"Filenames: "<<std::endl;
315 for(i=newFiles.begin();i!=newFiles.end();++i)
321 //Add to message the result of missing files
322 mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
323 if(ignoreList.size()>0)
325 mess<<"Filenames: "<<std::endl;
326 for(i=ignoreList.begin();i!=ignoreList.end();++i)
332 //In the case that the user wants to check the attributes...
335 //... add to message the result of files that have been changed.
336 mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
337 if(attsModified.size()>0)
339 mess<<"Filenames: "<<std::endl;
340 for(i=attsModified.begin();i!=attsModified.end();++i)
349 //Actions to take if the user wants to repair
353 //Iterates to see if they are in sync
354 for(iter=fileList.begin();iter!=fileList.end();++iter)
356 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
358 if((*iter).recursive=="0"){rec=false;}
359 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
361 //For the new files, add them
362 for (i=newFiles.begin();i!=newFiles.end();++i)
364 if (IsHandledFile(*i))
366 std::stringstream removedOn;
368 mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str(),mCurrentDB);
369 //Gets the number of files added
370 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key,mCurrentDB)).c_str());
372 std::stringstream out;
374 //Sets the new number of files
375 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key,mCurrentDB);
383 //Reports number of added files
384 mess<<"Files Added: "<<nf<<std::endl;
386 //Removes the necessary files and reports the results
387 if(ignoreList.size()>0)
390 mTreeHandler->LoadChildren(NULL,4);
391 for(i=ignoreList.begin();i!=ignoreList.end();++i)
393 FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
395 mTreeHandler->Remove(node);
398 mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
399 //In the case that the user wants to check the attributes...
402 //... add to message the result of files that were modified.
403 mess<<"Files Modified: "<<attsModified.size()<<std::endl;
409 //=======================================================================
411 void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
413 std::map< std::string, std::string> attr;
414 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
415 mReader.ReadAttributes(file,attr);
416 tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);
417 tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
418 for (a = adl.begin();a!=adl.end();++a)
420 std::string databaseVal;
421 mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
422 std::string fileVal=attr.find(a->GetKey())->second;
423 if ( a->GetFlags()==0 && databaseVal == fileVal)
427 mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
429 attsModified.push_back(file);
436 //=======================================================================
439 void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
443 std::vector<tree::Node*>::iterator iter;
444 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
446 FindNode(*iter,level-1,searchParam,searchVal,node);
451 if(parent->GetAttribute(searchParam).compare(searchVal)==0)
459 void TreeHandlerImageAdder::SaveAs(const std::vector<std::string>& filenames, std::vector<vtkImageData *> i_images)
461 std::vector<std::string>::const_iterator it_file = filenames.begin();
462 std::vector<vtkImageData *>::iterator it_image = i_images.begin();
463 /* mWriter.CanWrite(".jpeg");
464 for(; it_file != filenames.end(); ++it_file, ++it_image)
465 mWriter.WriteImage(it_file->c_str(), (vtkImageData &)it_image);*/
468 //=======================================================================
469 void TreeHandlerImageAdder::FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
473 std::vector<tree::Node*>::iterator iter;
474 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end() && node==0 ;++iter)
476 FindNodePartial(*iter,level-1,searchParam,searchVal,node);
481 if(parent->GetAttribute(searchParam).find(searchVal)<9000)
490 //=======================================================================
492 void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory )
494 std::vector<std::string>::const_iterator i;
495 if(!boost::filesystem::exists(directory))
497 boost::filesystem::create_directory(boost::filesystem::path(directory));
498 mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
500 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
502 std::vector<std::string> newNames;
503 for(i=filenames.begin();i!=filenames.end();++i)
505 std::string dir=directory.c_str();
506 if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
509 last=(*i).find_last_of('/');
510 std::string f="\\"+(*i).substr(last+1);
513 std::stringstream out;
515 while(boost::filesystem::exists(out.str()))
518 out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
521 std::string result=out.str();
522 boost::filesystem::copy_file((*i),result);
524 //To update image database
525 mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
527 //To update maintenance database
528 //1.Add the new path and increase number of children on new operation.
529 std::stringstream removedOn;
532 mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
533 //Gets the number of files added
534 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
536 std::stringstream fil;
538 //Sets the new number of files
539 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
542 //2.Set the old path as removed and decrease number of children on old operation.
543 //Gets the old add key
544 std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
545 //Sets the file as removed
546 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
547 //Gets the number of files added
548 files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
551 //Sets the new number of files
552 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
559 //=======================================================================
561 void TreeHandlerImageAdder::DeleteDriveFromMainDB(const std::string& drive)
563 //Delete from local database and others
565 mTreeHandler->LoadChildren(NULL,4);
566 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
569 mTreeHandler->Remove(node);
571 mTreeHandler->LoadChildren(NULL,4);
572 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
576 //=======================================================================
578 void TreeHandlerImageAdder::DeleteDriveFromOtherDB(const std::string& drive)
580 //Delete from maintenance
581 mSynchronizer->RemoveEntries("ADD_OPS", "PATH", "LIKE", drive+"%");
582 mSynchronizer->RemoveEntries("IGNORED_FILES", "PATH", "LIKE", drive+"%");
585 //=======================================================================
586 void TreeHandlerImageAdder::EditField(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
588 node->SetAttribute(key,val);
589 mTreeHandler->SetAttribute(node,key,val);
592 //=======================================================================
593 void TreeHandlerImageAdder::GetAttributes(const std::vector<std::string>& params,
594 const std::string& filename,
595 std::vector<std::string>& results)
597 std::vector<std::string>::const_iterator i;
599 for(i=params.begin();i!=params.end();i++)
601 mTreeHandler->GetAttribute("Image","FullFileName",filename,*i,result);
602 results.push_back(result);