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 mSynchronizer->GetList(mCurrentDB);
52 for (i=filenames.begin();i!=filenames.end();++i)
55 mProgress.IncNumberScannedFiles();
56 if (IsHandledFile(*i))
58 mProgress.IncNumberHandledFiles();
59 if(mSynchronizer->isIndexed(*i))
61 mSynchronizer->InsertAddOp((*i),"0","1",mCurrentDB);
62 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i),mCurrentDB);
63 std::stringstream removedOn;
65 mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str(),mCurrentDB);
69 mProgressSignal(mProgress);
70 if (mProgress.GetStop()) break;
73 //=====================================================================
75 //=====================================================================
76 void TreeHandlerImageAdder::AddDirectory( const std::string& directory,
80 std::stringstream files;
82 std::stringstream rec;
84 mSynchronizer->InsertAddOp(directory,rec.str(),"0",mCurrentDB);
85 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
86 mTreeHandler->BeginTransaction();
87 mSynchronizer->GetList(mCurrentDB);
88 AddDirectoryRecursor( directory, recurse, addKey );
90 int nFiles=GetProgress().GetNumberAddedFiles();
92 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey,mCurrentDB);
93 mTreeHandler->EndTransaction();
94 GimmickDebugMessage(3,mProgress<<std::endl);
97 //=====================================================================
98 void TreeHandlerImageAdder::AddFile( const std::string& filename )
100 GimmickDebugMessage(4,"Adding '"<<filename<<"'"<<std::endl);
101 std::map< std::string, std::string> attr;
102 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
105 mReader.ReadAttributes(filename,attr);
106 //// TO DO Create a function to test if the SOP Instance ID (0008,0018) is not already on DB
107 //// test befor if this attr is present on DB if not don't perform the test!!!
108 //bool bSOPIID = false;
109 //std::map<std::string, std::string>::iterator it_att = attr.begin();
110 //for(; it_att != attr.end(); it_att++)
112 // if (it_att->first == "D0008_0018")
114 // bSOPIID = mTreeHandler->TestSOPIID(it_attr->second);
121 int lev = mTreeHandler->AddBranch(attr);
123 // update the progress according to lev
124 if (lev<mTreeHandler->GetTree().GetNumberOfLevels())
125 mProgress.IncNumberAddedFiles();
127 //=====================================================================
129 void TreeHandlerImageAdder::RemoveFile( tree::Node* node)
131 int n=node->GetNumberOfChildren();
134 RemoveFiles(node->GetChildrenList());
138 std::string path=node->GetAttribute("FullFileName");
140 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
141 //Gets the number of files added
142 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
144 std::stringstream out;
146 //Sets the new number of files
147 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
148 //Sets the file as removed
149 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
153 //=====================================================================
155 void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
157 std::vector<tree::Node*>::const_iterator it;
158 for(it=nodes.begin();it!=nodes.end();++it)
160 int n=(*it)->GetNumberOfChildren();
163 RemoveFiles((*it)->GetChildrenList());
167 std::string path=(*it)->GetAttribute("FullFileName");
169 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
170 //Gets the number of files added
171 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
173 std::stringstream out;
175 //Sets the new number of files
176 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
177 //Sets the file as removed
178 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
185 //=====================================================================
186 void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath,
188 const std::string &addKey)
190 GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
191 mProgress.IncNumberScannedDirs();
193 if ( !fs::exists( dirpath ) ) return;
194 time_t lastModif=fs::last_write_time(dirpath);
197 fs::directory_iterator end_itr; // default construction yields past-the-end
198 for ( fs::directory_iterator itr( dirpath );
202 // If is directory & recurse : do recurse
203 if ( fs::is_directory(itr->status()) )
207 AddDirectoryRecursor( itr->string(), recursive, addKey);
212 std::string parent_id;
213 // tTest if directory (and only it) exists or not.
214 bool valid = mSynchronizer->isIndexed(itr->string());//true;//=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0),mCurrentDB);
217 mProgress.IncNumberScannedFiles();
218 if (IsHandledFile(itr->string()))
220 mProgress.IncNumberHandledFiles();
221 AddFile( itr->string() );
222 mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
223 std::stringstream removedOn;
225 mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
228 mProgressSignal(mProgress);
229 if (mProgress.GetStop())
240 //=======================================================================
242 //=======================================================================
244 void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath,
247 bool checkAttributes,
248 std::vector<std::string> &i_ignorefiles,
249 std::vector<std::string> & attsModified,
250 std::vector<std::string> & newfiles)
252 if ( !fs::exists( dirpath ) ) return;
253 fs::directory_iterator end_itr; // default construction yields past-the-end
255 for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
257 // If is directory & recurse : do recurse
258 if ( fs::is_directory(itr->status()) )
262 CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
267 if (IsHandledFile(itr->string()))
270 for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
272 if((*it_new) == itr->string())
275 //Additional checking of attributes
278 CheckAttributes(repair,(*it_new),attsModified);
280 i_ignorefiles.erase(it_new);
284 if(!bfound && i_ignorefiles.size()>0 )
286 newfiles.push_back( itr->string() );
293 //=======================================================================
295 //=======================================================================
297 std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
299 std::vector<AddList> fileList;
300 std::vector<std::string> ignoreList;
301 std::vector<std::string> newFiles;
302 std::vector<std::string> attsModified;
303 std::stringstream mess;
304 std::vector<AddList>::iterator iter;
306 //Gets the list of added files
307 mSynchronizer->GetFileList(fileList,mCurrentDB);
309 std::vector<std::string>::iterator i;
310 //Actions to take if the user doesn't want to repair
313 //Iterates to see if they are in sync
314 for(iter=fileList.begin();iter!=fileList.end();++iter)
316 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
318 if((*iter).recursive=="0"){rec=false;}
319 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
322 //Add to message the result of new found files
323 mess<<"New Files Found: "<<newFiles.size()<<std::endl;
324 if(newFiles.size()>0)
326 mess<<"Filenames: "<<std::endl;
327 for(i=newFiles.begin();i!=newFiles.end();++i)
333 //Add to message the result of missing files
334 mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
335 if(ignoreList.size()>0)
337 mess<<"Filenames: "<<std::endl;
338 for(i=ignoreList.begin();i!=ignoreList.end();++i)
344 //In the case that the user wants to check the attributes...
347 //... add to message the result of files that have been changed.
348 mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
349 if(attsModified.size()>0)
351 mess<<"Filenames: "<<std::endl;
352 for(i=attsModified.begin();i!=attsModified.end();++i)
361 //Actions to take if the user wants to repair
365 //Iterates to see if they are in sync
366 for(iter=fileList.begin();iter!=fileList.end();++iter)
368 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
370 if((*iter).recursive=="0"){rec=false;}
371 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
373 //For the new files, add them
374 for (i=newFiles.begin();i!=newFiles.end();++i)
376 if (IsHandledFile(*i))
378 std::stringstream removedOn;
380 mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str(),mCurrentDB);
381 //Gets the number of files added
382 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key,mCurrentDB)).c_str());
384 std::stringstream out;
386 //Sets the new number of files
387 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key,mCurrentDB);
395 //Reports number of added files
396 mess<<"Files Added: "<<nf<<std::endl;
398 //Removes the necessary files and reports the results
399 if(ignoreList.size()>0)
402 mTreeHandler->LoadChildren(NULL,4);
403 for(i=ignoreList.begin();i!=ignoreList.end();++i)
405 FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
407 mTreeHandler->Remove(node);
410 mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
411 //In the case that the user wants to check the attributes...
414 //... add to message the result of files that were modified.
415 mess<<"Files Modified: "<<attsModified.size()<<std::endl;
421 //=======================================================================
423 void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
425 std::map< std::string, std::string> attr;
426 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
427 mReader.ReadAttributes(file,attr);
428 tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);
429 tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
430 for (a = adl.begin();a!=adl.end();++a)
432 std::string databaseVal;
433 mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
434 std::string fileVal=attr.find(a->GetKey())->second;
435 if ( a->GetFlags()==0 && databaseVal == fileVal)
439 mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
441 attsModified.push_back(file);
448 //=======================================================================
451 void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
455 std::vector<tree::Node*>::iterator iter;
456 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
458 FindNode(*iter,level-1,searchParam,searchVal,node);
463 if(parent->GetAttribute(searchParam).compare(searchVal)==0)
471 void TreeHandlerImageAdder::SaveAs(const std::vector<std::string>& filenames, std::vector<vtkImageData *> i_images)
473 std::vector<std::string>::const_iterator it_file = filenames.begin();
474 std::vector<vtkImageData *>::iterator it_image = i_images.begin();
475 /* mWriter.CanWrite(".jpeg");
476 for(; it_file != filenames.end(); ++it_file, ++it_image)
477 mWriter.WriteImage(it_file->c_str(), (vtkImageData &)it_image);*/
480 //=======================================================================
481 void TreeHandlerImageAdder::FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
485 std::vector<tree::Node*>::iterator iter;
486 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end() && node==0 ;++iter)
488 FindNodePartial(*iter,level-1,searchParam,searchVal,node);
493 if(parent->GetAttribute(searchParam).find(searchVal)<9000)
502 //=======================================================================
504 void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory )
506 std::vector<std::string>::const_iterator i;
507 if(!boost::filesystem::exists(directory))
509 boost::filesystem::create_directory(boost::filesystem::path(directory));
510 mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
512 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
514 std::vector<std::string> newNames;
515 for(i=filenames.begin();i!=filenames.end();++i)
517 std::string dir=directory.c_str();
518 if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
521 last=(*i).find_last_of('/');
522 std::string f="\\"+(*i).substr(last+1);
525 std::stringstream out;
527 while(boost::filesystem::exists(out.str()))
530 out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
533 std::string result=out.str();
534 boost::filesystem::copy_file((*i),result);
536 //To update image database
537 mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
539 //To update maintenance database
540 //1.Add the new path and increase number of children on new operation.
541 std::stringstream removedOn;
544 mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
545 //Gets the number of files added
546 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
548 std::stringstream fil;
550 //Sets the new number of files
551 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
554 //2.Set the old path as removed and decrease number of children on old operation.
555 //Gets the old add key
556 std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
557 //Sets the file as removed
558 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
559 //Gets the number of files added
560 files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
563 //Sets the new number of files
564 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
571 //=======================================================================
573 void TreeHandlerImageAdder::DeleteDriveFromMainDB(const std::string& drive)
575 //Delete from local database and others
577 mTreeHandler->LoadChildren(NULL,4);
578 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
581 mTreeHandler->Remove(node);
583 mTreeHandler->LoadChildren(NULL,4);
584 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
588 //=======================================================================
590 void TreeHandlerImageAdder::DeleteDriveFromOtherDB(const std::string& drive)
592 //Delete from maintenance
593 mSynchronizer->RemoveEntries("ADD_OPS", "PATH", "LIKE", drive+"%");
594 mSynchronizer->RemoveEntries("IGNORED_FILES", "PATH", "LIKE", drive+"%");
597 //=======================================================================
598 void TreeHandlerImageAdder::EditField(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
600 node->SetAttribute(key,val);
601 mTreeHandler->SetAttribute(node,key,val);
604 //=======================================================================
605 void TreeHandlerImageAdder::GetAttributes(const std::vector<std::string>& params,
606 const std::string& filename,
607 std::vector<std::string>& results)
609 std::vector<std::string>::const_iterator i;
611 for(i=params.begin();i!=params.end();i++)
613 mTreeHandler->GetAttribute("Image","FullFileName",filename,*i,result);
614 results.push_back(result);