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 mTreeHandler->BeginTransaction();
83 AddDirectoryRecursor( directory, recurse, addKey );
85 int nFiles=GetProgress().GetNumberAddedFiles();
87 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey,mCurrentDB);
88 mTreeHandler->EndTransaction();
89 GimmickDebugMessage(3,mProgress<<std::endl);
92 //=====================================================================
93 void TreeHandlerImageAdder::AddFile( const std::string& filename )
95 GimmickDebugMessage(4,"Adding '"<<filename<<"'"<<std::endl);
96 std::map< std::string, std::string> attr;
97 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
99 mReader.ReadAttributes(filename,attr);
101 int lev = mTreeHandler->AddBranch(attr);
103 // update the progress according to lev
104 if (lev<mTreeHandler->GetTree().GetNumberOfLevels())
105 mProgress.IncNumberAddedFiles();
107 //=====================================================================
109 void TreeHandlerImageAdder::RemoveFile( tree::Node* node)
111 int n=node->GetNumberOfChildren();
114 RemoveFiles(node->GetChildrenList());
118 std::string path=node->GetAttribute("FullFileName");
120 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
121 //Gets the number of files added
122 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
124 std::stringstream out;
126 //Sets the new number of files
127 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
128 //Sets the file as removed
129 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
133 //=====================================================================
135 void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
137 std::vector<tree::Node*>::const_iterator it;
138 for(it=nodes.begin();it!=nodes.end();++it)
140 int n=(*it)->GetNumberOfChildren();
143 RemoveFiles((*it)->GetChildrenList());
147 std::string path=(*it)->GetAttribute("FullFileName");
149 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
150 //Gets the number of files added
151 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
153 std::stringstream out;
155 //Sets the new number of files
156 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
157 //Sets the file as removed
158 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
164 //=====================================================================
165 void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath,
167 const std::string &addKey)
169 GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
170 mProgress.IncNumberScannedDirs();
172 if ( !fs::exists( dirpath ) ) return;
173 time_t lastModif=fs::last_write_time(dirpath);
175 fs::directory_iterator end_itr; // default construction yields past-the-end
176 for ( fs::directory_iterator itr( dirpath );
180 // If is directory & recurse : do recurse
181 if ( fs::is_directory(itr->status()) )
185 AddDirectoryRecursor( itr->string(), recursive, addKey);
190 std::string parent_id;
191 bool valid=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0),mCurrentDB);
194 mProgress.IncNumberScannedFiles();
195 if (IsHandledFile(itr->string()))
197 mProgress.IncNumberHandledFiles();
198 AddFile( itr->string() );
199 mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
200 mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",itr->string());
201 std::stringstream removedOn;
203 mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
206 mProgressSignal(mProgress);
207 if (mProgress.GetStop())
214 mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",dirpath);
219 //=======================================================================
221 //=======================================================================
223 void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath,
226 bool checkAttributes,
227 std::vector<std::string> &i_ignorefiles,
228 std::vector<std::string> & attsModified,
229 std::vector<std::string> & newfiles)
231 if ( !fs::exists( dirpath ) ) return;
232 fs::directory_iterator end_itr; // default construction yields past-the-end
234 for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
236 // If is directory & recurse : do recurse
237 if ( fs::is_directory(itr->status()) )
241 CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
246 if (IsHandledFile(itr->string()))
249 for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
251 if((*it_new) == itr->string())
254 //Additional checking of attributes
257 CheckAttributes(repair,(*it_new),attsModified);
259 i_ignorefiles.erase(it_new);
263 if(!bfound && i_ignorefiles.size()>0 )
265 newfiles.push_back( itr->string() );
272 //=======================================================================
274 //=======================================================================
276 std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
278 std::vector<AddList> fileList;
279 std::vector<std::string> ignoreList;
280 std::vector<std::string> newFiles;
281 std::vector<std::string> attsModified;
282 std::stringstream mess;
283 std::vector<AddList>::iterator iter;
285 //Gets the list of added files
286 mSynchronizer->GetFileList(fileList,mCurrentDB);
288 std::vector<std::string>::iterator i;
289 //Actions to take if the user doesn't want to repair
292 //Iterates to see if they are in sync
293 for(iter=fileList.begin();iter!=fileList.end();++iter)
295 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
297 if((*iter).recursive=="0"){rec=false;}
298 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
301 //Add to message the result of new found files
302 mess<<"New Files Found: "<<newFiles.size()<<std::endl;
303 if(newFiles.size()>0)
305 mess<<"Filenames: "<<std::endl;
306 for(i=newFiles.begin();i!=newFiles.end();++i)
312 //Add to message the result of missing files
313 mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
314 if(ignoreList.size()>0)
316 mess<<"Filenames: "<<std::endl;
317 for(i=ignoreList.begin();i!=ignoreList.end();++i)
323 //In the case that the user wants to check the attributes...
326 //... add to message the result of files that have been changed.
327 mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
328 if(attsModified.size()>0)
330 mess<<"Filenames: "<<std::endl;
331 for(i=attsModified.begin();i!=attsModified.end();++i)
340 //Actions to take if the user wants to repair
344 //Iterates to see if they are in sync
345 for(iter=fileList.begin();iter!=fileList.end();++iter)
347 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
349 if((*iter).recursive=="0"){rec=false;}
350 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
352 //For the new files, add them
353 for (i=newFiles.begin();i!=newFiles.end();++i)
355 mTimestampHandler->AddFile((*i), fs::last_write_time(*i), time(0),mCurrentDB);
356 if (IsHandledFile(*i))
358 std::stringstream removedOn;
360 mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str(),mCurrentDB);
361 //Gets the number of files added
362 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key,mCurrentDB)).c_str());
364 std::stringstream out;
366 //Sets the new number of files
367 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key,mCurrentDB);
375 //Reports number of added files
376 mess<<"Files Added: "<<nf<<std::endl;
378 //Removes the necessary files and reports the results
379 if(ignoreList.size()>0)
382 mTreeHandler->LoadChildren(NULL,4);
383 for(i=ignoreList.begin();i!=ignoreList.end();++i)
385 FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
387 mTreeHandler->Remove(node);
390 mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
391 //In the case that the user wants to check the attributes...
394 //... add to message the result of files that were modified.
395 mess<<"Files Modified: "<<attsModified.size()<<std::endl;
401 //=======================================================================
403 void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
405 std::map< std::string, std::string> attr;
406 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
407 mReader.ReadAttributes(file,attr);
408 tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);
409 tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
410 for (a = adl.begin();a!=adl.end();++a)
412 std::string databaseVal;
413 mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
414 std::string fileVal=attr.find(a->GetKey())->second;
415 if ( a->GetFlags()==0 && databaseVal.compare(fileVal)!=0 )
419 mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
421 attsModified.push_back(file);
428 //=======================================================================
431 void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
435 std::vector<tree::Node*>::iterator iter;
436 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
438 FindNode(*iter,level-1,searchParam,searchVal,node);
443 if(parent->GetAttribute(searchParam).compare(searchVal)==0)
451 void TreeHandlerImageAdder::SaveAs(const std::vector<std::string>& filenames, std::vector<vtkImageData *> i_images)
453 std::vector<std::string>::const_iterator it_file = filenames.begin();
454 std::vector<vtkImageData *>::iterator it_image = i_images.begin();
455 /* mWriter.CanWrite(".jpeg");
456 for(; it_file != filenames.end(); ++it_file, ++it_image)
457 mWriter.WriteImage(it_file->c_str(), (vtkImageData &)it_image);*/
460 //=======================================================================
461 void TreeHandlerImageAdder::FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
465 std::vector<tree::Node*>::iterator iter;
466 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end() && node==0 ;++iter)
468 FindNodePartial(*iter,level-1,searchParam,searchVal,node);
473 if(parent->GetAttribute(searchParam).find(searchVal)<9000)
482 //=======================================================================
484 void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory )
486 std::vector<std::string>::const_iterator i;
487 if(!boost::filesystem::exists(directory))
489 boost::filesystem::create_directory(boost::filesystem::path(directory));
490 mTimestampHandler->AddDirectory("",directory,fs::last_write_time(directory)+10, time(0),mCurrentDB);
491 mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
493 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
494 std::string parent_id=mTimestampHandler->IsIndexed(directory,mCurrentDB);
496 std::vector<std::string> newNames;
497 for(i=filenames.begin();i!=filenames.end();++i)
499 std::string dir=directory.c_str();
500 mTimestampHandler->CleanPath(dir);
501 if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
504 last=(*i).find_last_of('/');
505 std::string f="\\"+(*i).substr(last+1);
508 std::stringstream out;
510 while(boost::filesystem::exists(out.str()))
513 out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
516 std::string result=out.str();
517 mTimestampHandler->CleanPath(result);
518 boost::filesystem::copy_file((*i),result);
520 //To update image database
521 mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
523 //To update timestamp database
524 mTimestampHandler->SetAttribute("PATH",result,"PATH",(*i));
525 mTimestampHandler->SetAttribute("PARENT_ID",parent_id,"PATH",result);
527 t<<fs::last_write_time(directory)+10;
528 mTimestampHandler->SetAttribute("LastModified",t.str(),"PATH",result);
530 //To update maintenance database
531 //1.Add the new path and increase number of children on new operation.
532 std::stringstream removedOn;
535 mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
536 //Gets the number of files added
537 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
539 std::stringstream fil;
541 //Sets the new number of files
542 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
545 //2.Set the old path as removed and decrease number of children on old operation.
546 //Gets the old add key
547 std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
548 //Sets the file as removed
549 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
550 //Gets the number of files added
551 files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
554 //Sets the new number of files
555 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
562 //=======================================================================
564 void TreeHandlerImageAdder::DeleteDriveFromMainDB(const std::string& drive)
566 //Delete from local database and others
568 mTreeHandler->LoadChildren(NULL,4);
569 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
572 mTreeHandler->Remove(node);
574 mTreeHandler->LoadChildren(NULL,4);
575 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
579 //=======================================================================
581 void TreeHandlerImageAdder::DeleteDriveFromOtherDB(const std::string& drive)
583 //Delete from timestamp
584 mTimestampHandler->RemoveEntries("FILES", "PATH", "LIKE", drive+"%");
586 //Delete from maintenance
587 mSynchronizer->RemoveEntries("ADD_OPS", "PATH", "LIKE", drive+"%");
588 mSynchronizer->RemoveEntries("IGNORED_FILES", "PATH", "LIKE", drive+"%");
591 //=======================================================================
592 void TreeHandlerImageAdder::EditField(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
594 node->SetAttribute(key,val);
595 mTreeHandler->SetAttribute(node,key,val);
598 //=======================================================================
599 void TreeHandlerImageAdder::GetAttributes(const std::vector<std::string>& params,
600 const std::string& filename,
601 std::vector<std::string>& results)
603 std::vector<std::string>::const_iterator i;
605 for(i=params.begin();i!=params.end();i++)
607 mTreeHandler->GetAttribute("Image","FullFileName",filename,*i,result);
608 results.push_back(result);