1 #include <creaImageIOTreeHandlerImageAdder.h>
2 #include <creaImageIOSystem.h>
3 #include <boost/filesystem.hpp>
4 #include <boost/algorithm/string.hpp>
5 #include <boost/utility.hpp>
8 namespace fs = boost::filesystem;
9 using boost::filesystem::path;
15 using namespace boost;
19 //====================================================================
21 TreeHandlerImageAdder::TreeHandlerImageAdder(TreeHandler* tree)
26 TreeHandlerImageAdder::~TreeHandlerImageAdder()
29 //====================================================================
31 //====================================================================
32 void TreeHandlerImageAdder::ConnectProgressObserver(ProgressCallbackType callback)
34 mProgressSignal.connect(callback);
36 //====================================================================
38 //=====================================================================
39 bool TreeHandlerImageAdder::IsHandledFile( const std::string& filename)
41 return (mReader.CanRead(filename));
43 //=====================================================================
45 //=====================================================================
46 void TreeHandlerImageAdder::AddFiles( const std::vector<std::string>& filenames)
50 unsigned int nbf = filenames.size();
51 std::vector<std::string>::const_iterator i;
52 mSynchronizer->GetList(mCurrentDB);
53 for (i=filenames.begin();i!=filenames.end();++i)
56 mProgress.IncNumberScannedFiles();
57 if (IsHandledFile(*i))
59 mProgress.IncNumberHandledFiles();
60 if(mSynchronizer->isIndexed(*i))
62 mSynchronizer->InsertAddOp((*i),"0","1",mCurrentDB);
63 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i),mCurrentDB);
64 std::stringstream removedOn;
66 mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str(),mCurrentDB);
70 mProgressSignal(mProgress);
71 if (mProgress.GetStop()) break;
74 //=====================================================================
76 //=====================================================================
77 void TreeHandlerImageAdder::AddDirectory( const std::string& directory,
81 std::stringstream files;
83 std::stringstream rec;
85 mSynchronizer->InsertAddOp(directory,rec.str(),"0",mCurrentDB);
86 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
87 mTreeHandler->BeginTransaction();
88 mSynchronizer->GetList(mCurrentDB);
89 AddDirectoryRecursor( directory, recurse, addKey );
90 //DicomImageScanner sc;
91 //AddDirectoryRecursorScanner(directory, recurse, addKey, sc, false );
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);
108 mReader.ReadAttributes(filename,attr);
109 //// TO DO Create a function to test if the SOP Instance ID (0008,0018) is not already on DB
110 //// test befor if this attr is present on DB if not don't perform the test!!!
111 //bool bSOPIID = false;
112 //std::map<std::string, std::string>::iterator it_att = attr.begin();
113 //for(; it_att != attr.end(); it_att++)
115 // if (it_att->first == "D0008_0018")
117 // bSOPIID = mTreeHandler->TestSOPIID(it_attr->second);
124 int lev = mTreeHandler->AddBranch(attr);
126 // update the progress according to lev
127 if (lev<mTreeHandler->GetTree().GetNumberOfLevels())
128 mProgress.IncNumberAddedFiles();
130 //=====================================================================
132 void TreeHandlerImageAdder::RemoveFile( tree::Node* node)
134 int n=node->GetNumberOfChildren();
137 RemoveFiles(node->GetChildrenList());
141 std::string path=node->GetAttribute("FullFileName");
143 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
144 //Gets the number of files added
145 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
147 std::stringstream out;
149 //Sets the new number of files
150 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
151 //Sets the file as removed
152 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
156 //=====================================================================
158 void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
160 std::vector<tree::Node*>::const_iterator it;
161 for(it=nodes.begin();it!=nodes.end();++it)
163 int n=(*it)->GetNumberOfChildren();
166 RemoveFiles((*it)->GetChildrenList());
170 std::string path=(*it)->GetAttribute("FullFileName");
172 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
173 //Gets the number of files added
174 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
176 std::stringstream out;
178 //Sets the new number of files
179 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
180 //Sets the file as removed
181 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
189 //=======================================================================
190 //=====================================================================
191 #if defined(USE_GDCM2)
193 void TreeHandlerImageAdder::AddDirectoryRecursorScanner(const std::string &dirpath,
194 bool recursive,const std::string &addKey, DicomImageScanner i_sc, bool b_loaded)
196 GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
197 mProgress.IncNumberScannedDirs();
199 if ( !fs::exists( dirpath ) ) return;
200 time_t lastModif=fs::last_write_time(dirpath);
204 std::map< std::string, std::string> attr;
205 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
206 std::string path = dirpath.c_str();
207 i_sc.addDirectory(path, attr);
210 fs::directory_iterator end_itr; // default construction yields past-the-end
211 for ( fs::directory_iterator itr( dirpath );
216 // If is directory & recurse : do recurse
217 if ( fs::is_directory(itr->status()) )
221 AddDirectoryRecursorScanner( itr->string(), recursive, addKey, i_sc, true);
226 std::string parent_id;
227 // tTest if directory (and only it) exists or not.
228 bool valid = mSynchronizer->isIndexed(itr->string());//true;//=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0),mCurrentDB);
232 mProgress.IncNumberScannedFiles();
233 boost::algorithm::replace_all( itr->string(),
234 INVALID_FILE_SEPARATOR ,
235 VALID_FILE_SEPARATOR);
236 i_sc.ReadAttributes(itr->string(),attr);
237 // mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
238 mTreeHandler->AddBranch(attr);
239 mProgress.IncNumberHandledFiles();
240 std::stringstream removedOn;
242 mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
245 mProgressSignal(mProgress);
246 if (mProgress.GetStop())
257 //=====================================================================
258 void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath,
260 const std::string &addKey)
262 GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
263 mProgress.IncNumberScannedDirs();
265 if ( !fs::exists( dirpath ) ) return;
266 time_t lastModif=fs::last_write_time(dirpath);
269 fs::directory_iterator end_itr; // default construction yields past-the-end
270 for ( fs::directory_iterator itr( dirpath );
274 // If is directory & recurse : do recurse
275 if ( fs::is_directory(itr->status()) )
279 AddDirectoryRecursor( itr->string(), recursive, addKey);
284 std::string parent_id;
285 // tTest if directory (and only it) exists or not.
286 bool valid = mSynchronizer->isIndexed(itr->string());//true;//=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0),mCurrentDB);
289 mProgress.IncNumberScannedFiles();
290 if (IsHandledFile(itr->string()))
292 mProgress.IncNumberHandledFiles();
293 AddFile( itr->string() );
294 //mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
295 std::stringstream removedOn;
297 mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
300 mProgressSignal(mProgress);
301 if (mProgress.GetStop())
312 //=======================================================================
315 //=======================================================================
317 void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath,
320 bool checkAttributes,
321 std::vector<std::string> &i_ignorefiles,
322 std::vector<std::string> & attsModified,
323 std::vector<std::string> & newfiles)
325 if ( !fs::exists( dirpath ) ) return;
326 fs::directory_iterator end_itr; // default construction yields past-the-end
328 for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
330 // If is directory & recurse : do recurse
331 if ( fs::is_directory(itr->status()) )
335 CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
340 if (IsHandledFile(itr->string()))
343 for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
345 if((*it_new) == itr->string())
348 //Additional checking of attributes
351 CheckAttributes(repair,(*it_new),attsModified);
353 i_ignorefiles.erase(it_new);
357 if(!bfound && i_ignorefiles.size()>0 )
359 newfiles.push_back( itr->string() );
366 //=======================================================================
368 //=======================================================================
370 std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
372 std::vector<AddList> fileList;
373 std::vector<std::string> ignoreList;
374 std::vector<std::string> newFiles;
375 std::vector<std::string> attsModified;
376 std::stringstream mess;
377 std::vector<AddList>::iterator iter;
379 //Gets the list of added files
380 mSynchronizer->GetFileList(fileList,mCurrentDB);
382 std::vector<std::string>::iterator i;
383 //Actions to take if the user doesn't want to repair
386 //Iterates to see if they are in sync
387 for(iter=fileList.begin();iter!=fileList.end();++iter)
389 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
391 if((*iter).recursive=="0"){rec=false;}
392 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
395 //Add to message the result of new found files
396 mess<<"New Files Found: "<<newFiles.size()<<std::endl;
397 if(newFiles.size()>0)
399 mess<<"Filenames: "<<std::endl;
400 for(i=newFiles.begin();i!=newFiles.end();++i)
406 //Add to message the result of missing files
407 mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
408 if(ignoreList.size()>0)
410 mess<<"Filenames: "<<std::endl;
411 for(i=ignoreList.begin();i!=ignoreList.end();++i)
417 //In the case that the user wants to check the attributes...
420 //... add to message the result of files that have been changed.
421 mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
422 if(attsModified.size()>0)
424 mess<<"Filenames: "<<std::endl;
425 for(i=attsModified.begin();i!=attsModified.end();++i)
434 //Actions to take if the user wants to repair
438 //Iterates to see if they are in sync
439 for(iter=fileList.begin();iter!=fileList.end();++iter)
441 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
443 if((*iter).recursive=="0"){rec=false;}
444 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
446 //For the new files, add them
447 for (i=newFiles.begin();i!=newFiles.end();++i)
449 if (IsHandledFile(*i))
451 std::stringstream removedOn;
453 mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str(),mCurrentDB);
454 //Gets the number of files added
455 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key,mCurrentDB)).c_str());
457 std::stringstream out;
459 //Sets the new number of files
460 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key,mCurrentDB);
468 //Reports number of added files
469 mess<<"Files Added: "<<nf<<std::endl;
471 //Removes the necessary files and reports the results
472 if(ignoreList.size()>0)
475 mTreeHandler->LoadChildren(NULL,4);
476 for(i=ignoreList.begin();i!=ignoreList.end();++i)
478 FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
480 mTreeHandler->Remove(node);
483 mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
484 //In the case that the user wants to check the attributes...
487 //... add to message the result of files that were modified.
488 mess<<"Files Modified: "<<attsModified.size()<<std::endl;
494 //=======================================================================
496 void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
498 std::map< std::string, std::string> attr;
499 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
500 mReader.ReadAttributes(file,attr);
501 tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);
502 tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
503 for (a = adl.begin();a!=adl.end();++a)
505 std::string databaseVal;
506 mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
507 std::string fileVal=attr.find(a->GetKey())->second;
508 if ( a->GetFlags()==0 && databaseVal == fileVal)
512 mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
514 attsModified.push_back(file);
521 //=======================================================================
524 void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
528 std::vector<tree::Node*>::iterator iter;
529 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
531 FindNode(*iter,level-1,searchParam,searchVal,node);
536 if(parent->GetAttribute(searchParam).compare(searchVal)==0)
544 void TreeHandlerImageAdder::SaveAs(const std::vector<std::string>& filenames, std::vector<vtkImageData *> i_images)
546 std::vector<std::string>::const_iterator it_file = filenames.begin();
547 std::vector<vtkImageData *>::iterator it_image = i_images.begin();
548 /* mWriter.CanWrite(".jpeg");
549 for(; it_file != filenames.end(); ++it_file, ++it_image)
550 mWriter.WriteImage(it_file->c_str(), (vtkImageData &)it_image);*/
553 //=======================================================================
554 void TreeHandlerImageAdder::FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
558 std::vector<tree::Node*>::iterator iter;
559 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end() && node==0 ;++iter)
561 FindNodePartial(*iter,level-1,searchParam,searchVal,node);
566 if(parent->GetAttribute(searchParam).find(searchVal)<9000)
575 //=======================================================================
577 void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory )
579 std::vector<std::string>::const_iterator i;
580 if(!boost::filesystem::exists(directory))
582 boost::filesystem::create_directory(boost::filesystem::path(directory));
583 mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
585 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
587 std::vector<std::string> newNames;
588 for(i=filenames.begin();i!=filenames.end();++i)
590 std::string dir=directory.c_str();
591 if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
594 last=(*i).find_last_of('/');
595 std::string f="\\"+(*i).substr(last+1);
598 std::stringstream out;
600 while(boost::filesystem::exists(out.str()))
603 out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
606 std::string result=out.str();
607 boost::filesystem::copy_file((*i),result);
609 //To update image database
610 mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
612 //To update maintenance database
613 //1.Add the new path and increase number of children on new operation.
614 std::stringstream removedOn;
617 mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
618 //Gets the number of files added
619 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
621 std::stringstream fil;
623 //Sets the new number of files
624 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
627 //2.Set the old path as removed and decrease number of children on old operation.
628 //Gets the old add key
629 std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
630 //Sets the file as removed
631 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
632 //Gets the number of files added
633 files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
636 //Sets the new number of files
637 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
644 //=======================================================================
646 void TreeHandlerImageAdder::DeleteDriveFromMainDB(const std::string& drive)
648 //Delete from local database and others
650 mTreeHandler->LoadChildren(NULL,4);
651 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
654 mTreeHandler->Remove(node);
656 mTreeHandler->LoadChildren(NULL,4);
657 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
661 //=======================================================================
663 void TreeHandlerImageAdder::DeleteDriveFromOtherDB(const std::string& drive)
665 //Delete from maintenance
666 mSynchronizer->RemoveEntries("ADD_OPS", "PATH", "LIKE", drive+"%");
667 mSynchronizer->RemoveEntries("IGNORED_FILES", "PATH", "LIKE", drive+"%");
670 //=======================================================================
671 void TreeHandlerImageAdder::EditField(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
673 node->SetAttribute(key,val);
674 mTreeHandler->SetAttribute(node,key,val);
677 //=======================================================================
678 void TreeHandlerImageAdder::GetAttributes(const std::vector<std::string>& params,
679 const std::string& filename,
680 std::vector<std::string>& results)
682 std::vector<std::string>::const_iterator i;
684 for(i=params.begin();i!=params.end();i++)
686 mTreeHandler->GetAttribute("Image","FullFileName",filename,*i,result);
687 results.push_back(result);
691 //=======================================================================
692 const std::string TreeHandlerImageAdder::isAttributeExist(const std::string i_attr)
694 return mTreeHandler->GetTree().isAttributeExist(i_attr);