00001 #include <creaImageIOTreeHandlerImageAdder.h>
00002 #include <creaImageIOSystem.h>
00003 #include <boost/filesystem.hpp>
00004 #include <boost/algorithm/string.hpp>
00005 #include <boost/utility.hpp>
00006
00007
00008 namespace fs = boost::filesystem;
00009 using boost::filesystem::path;
00010 using boost::next;
00011 using boost::prior;
00012
00013
00014 using namespace crea;
00015 using namespace boost;
00016
00017 namespace creaImageIO
00018 {
00019
00020
00021 TreeHandlerImageAdder::TreeHandlerImageAdder(TreeHandler* tree)
00022 : mTreeHandler(tree)
00023 {
00024 }
00025
00026 TreeHandlerImageAdder::~TreeHandlerImageAdder()
00027 {
00028 }
00029
00030
00031
00032 void TreeHandlerImageAdder::ConnectProgressObserver(ProgressCallbackType callback)
00033 {
00034 mProgressSignal.connect(callback);
00035 }
00036
00037
00038
00039 bool TreeHandlerImageAdder::IsHandledFile( const std::string& filename)
00040 {
00041 return (mReader.CanRead(filename));
00042 }
00043
00044
00045
00046 void TreeHandlerImageAdder::AddFiles( const std::vector<std::string>& filenames)
00047 {
00048 mProgress.Reset();
00049
00050 unsigned int nbf = filenames.size();
00051 std::vector<std::string>::const_iterator i;
00052 mSynchronizer->GetList(mCurrentDB);
00053 for (i=filenames.begin();i!=filenames.end();++i)
00054 {
00055
00056 mProgress.IncNumberScannedFiles();
00057 if (IsHandledFile(*i))
00058 {
00059 mProgress.IncNumberHandledFiles();
00060 if(mSynchronizer->isIndexed(*i))
00061 {
00062 mSynchronizer->InsertAddOp((*i),"0","1",mCurrentDB);
00063 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i),mCurrentDB);
00064 std::stringstream removedOn;
00065 removedOn<<time(0);
00066 mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str(),mCurrentDB);
00067 AddFile(*i);
00068 }
00069 }
00070 mProgressSignal(mProgress);
00071 if (mProgress.GetStop()) break;
00072 }
00073 }
00074
00075
00076
00077 void TreeHandlerImageAdder::AddDirectory( const std::string& directory,
00078 bool recurse)
00079 {
00080 mProgress.Reset();
00081 std::stringstream files;
00082
00083 std::stringstream rec;
00084 rec<<recurse;
00085 mSynchronizer->InsertAddOp(directory,rec.str(),"0",mCurrentDB);
00086 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
00087 mTreeHandler->BeginTransaction();
00088 mSynchronizer->GetList(mCurrentDB);
00089 AddDirectoryRecursor( directory, recurse, addKey );
00090
00091
00092
00093 int nFiles=GetProgress().GetNumberAddedFiles();
00094 files<<nFiles;
00095 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey,mCurrentDB);
00096 mTreeHandler->EndTransaction();
00097 GimmickDebugMessage(3,mProgress<<std::endl);
00098 }
00099
00100
00101 void TreeHandlerImageAdder::AddFile( const std::string& filename )
00102 {
00103 GimmickDebugMessage(4,"Adding '"<<filename<<"'"<<std::endl);
00104 std::map< std::string, std::string> attr;
00105 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
00106
00107
00108 mReader.ReadAttributes(filename,attr);
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 int lev = mTreeHandler->AddBranch(attr);
00125
00126
00127 if (lev<mTreeHandler->GetTree().GetNumberOfLevels())
00128 mProgress.IncNumberAddedFiles();
00129 }
00130
00131
00132 void TreeHandlerImageAdder::RemoveFile( tree::Node* node)
00133 {
00134 int n=node->GetNumberOfChildren();
00135 if(n>0)
00136 {
00137 RemoveFiles(node->GetChildrenList());
00138 }
00139 else
00140 {
00141 remove(node);
00142 }
00143 }
00144
00145
00146
00147 void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
00148 {
00149 std::vector<tree::Node*>::const_iterator it;
00150 for(it=nodes.begin();it!=nodes.end();++it)
00151 {
00152 int n=(*it)->GetNumberOfChildren();
00153 if(n>0)
00154 {
00155 RemoveFiles((*it)->GetChildrenList());
00156 }
00157 else
00158 {
00159 remove(*it);
00160 }
00161
00162 }
00163 }
00164
00165
00166 void TreeHandlerImageAdder::remove( tree::Node* i_node)
00167 {
00168 std::string path=i_node->GetAttribute("FullFileName");
00169
00170 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
00171
00172 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
00173 files=files-1;
00174 std::stringstream out;
00175 out<<files;
00176
00177 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
00178
00179 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
00180 }
00181
00182
00183
00184
00185 #if defined(USE_GDCM2)
00186
00187 void TreeHandlerImageAdder::AddDirectoryRecursorScanner(const std::string &dirpath,
00188 bool recursive,const std::string &addKey, DicomImageScanner i_sc, bool b_loaded)
00189 {
00190 GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
00191 mProgress.IncNumberScannedDirs();
00192
00193 if ( !fs::exists( dirpath ) ) return;
00194 time_t lastModif=fs::last_write_time(dirpath);
00195
00196
00197
00198 std::map< std::string, std::string> attr;
00199 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
00200 std::string path = dirpath.c_str();
00201 i_sc.addDirectory(path, attr);
00202
00203
00204 fs::directory_iterator end_itr;
00205 for ( fs::directory_iterator itr( dirpath );
00206 itr != end_itr;
00207 ++itr )
00208 {
00209
00210
00211 if ( fs::is_directory(itr->status()) )
00212 {
00213 if (recursive)
00214 {
00215 AddDirectoryRecursorScanner( itr->string(), recursive, addKey, i_sc, true);
00216 }
00217 }
00218 else
00219 {
00220 std::string parent_id;
00221
00222 bool valid = mSynchronizer->isIndexed(itr->string());
00223 if(valid)
00224 {
00225 std::string path(itr->string());
00226 mProgress.IncNumberScannedFiles();
00227 boost::algorithm::replace_all( path,INVALID_FILE_SEPARATOR,VALID_FILE_SEPARATOR);
00228 i_sc.ReadAttributes(itr->string(),attr);
00229
00230 mTreeHandler->AddBranch(attr);
00231 mProgress.IncNumberHandledFiles();
00232 std::stringstream removedOn;
00233 removedOn<<time(0);
00234 mSynchronizer->InsertIgnoreFile(addKey, path,"0",removedOn.str(),mCurrentDB);
00235
00236
00237 mProgressSignal(mProgress);
00238 if (mProgress.GetStop())
00239 {
00240
00241 break;
00242 }
00243 }
00244
00245 }
00246 }
00247 }
00248 #endif
00249
00250 void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath,
00251 bool recursive,
00252 const std::string &addKey)
00253 {
00254 GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
00255 mProgress.IncNumberScannedDirs();
00256
00257 if ( !fs::exists( dirpath ) ) return;
00258 time_t lastModif=fs::last_write_time(dirpath);
00259
00260
00261 fs::directory_iterator end_itr;
00262 for ( fs::directory_iterator itr( dirpath );
00263 itr != end_itr;
00264 ++itr )
00265 {
00266
00267 if ( fs::is_directory(itr->status()) )
00268 {
00269 if (recursive)
00270 {
00271 AddDirectoryRecursor( itr->string(), recursive, addKey);
00272 }
00273 }
00274 else
00275 {
00276 std::string parent_id;
00277
00278 bool valid = mSynchronizer->isIndexed(itr->string());
00279 if(valid)
00280 {
00281 mProgress.IncNumberScannedFiles();
00282 if (IsHandledFile(itr->string()))
00283 {
00284 mProgress.IncNumberHandledFiles();
00285 AddFile( itr->string() );
00286
00287 std::stringstream removedOn;
00288 removedOn<<time(0);
00289 mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
00290 }
00291
00292 mProgressSignal(mProgress);
00293 if (mProgress.GetStop())
00294 {
00295
00296 break;
00297 }
00298
00299 }
00300 }
00301 }
00302
00303 }
00304
00305
00306
00307
00308
00309 void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath,
00310 bool recursive,
00311 bool repair,
00312 bool checkAttributes,
00313 std::vector<std::string> &i_ignorefiles,
00314 std::vector<std::string> & attsModified,
00315 std::vector<std::string> & newfiles)
00316 {
00317 if ( !fs::exists( dirpath ) ) return;
00318 fs::directory_iterator end_itr;
00319
00320 for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
00321 {
00322
00323 if ( fs::is_directory(itr->status()) )
00324 {
00325 if (recursive)
00326 {
00327 CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
00328 }
00329 }
00330 else
00331 {
00332 if (IsHandledFile(itr->string()))
00333 {
00334 bool bfound = false;
00335 for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
00336 {
00337 if((*it_new) == itr->string())
00338 {
00339 bfound = true;
00340
00341 if(checkAttributes)
00342 {
00343 CheckAttributes(repair,(*it_new),attsModified);
00344 }
00345 i_ignorefiles.erase(it_new);
00346 break;
00347 }
00348 }
00349 if(!bfound && i_ignorefiles.size()>0 )
00350 {
00351 newfiles.push_back( itr->string() );
00352 }
00353 }
00354 }
00355 }
00356 }
00357
00358
00359
00360
00361
00362 std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
00363 {
00364 std::vector<AddList> fileList;
00365 std::vector<std::string> ignoreList;
00366 std::vector<std::string> newFiles;
00367 std::vector<std::string> attsModified;
00368 std::stringstream mess;
00369 std::vector<AddList>::iterator iter;
00370
00371
00372 mSynchronizer->GetFileList(fileList,mCurrentDB);
00373
00374 std::vector<std::string>::iterator i;
00375
00376 if(!repair)
00377 {
00378
00379 for(iter=fileList.begin();iter!=fileList.end();++iter)
00380 {
00381 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
00382 bool rec=true;
00383 if((*iter).recursive=="0"){rec=false;}
00384 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
00385 }
00386
00387
00388 mess<<"New Files Found: "<<newFiles.size()<<std::endl;
00389 if(newFiles.size()>0)
00390 {
00391 mess<<"Filenames: "<<std::endl;
00392 for(i=newFiles.begin();i!=newFiles.end();++i)
00393 {
00394 mess<<*i<<std::endl;
00395 }
00396 }
00397
00398
00399 mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
00400 if(ignoreList.size()>0)
00401 {
00402 mess<<"Filenames: "<<std::endl;
00403 for(i=ignoreList.begin();i!=ignoreList.end();++i)
00404 {
00405 mess<<*i<<std::endl;
00406 }
00407 }
00408
00409
00410 if(checkAttributes)
00411 {
00412
00413 mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
00414 if(attsModified.size()>0)
00415 {
00416 mess<<"Filenames: "<<std::endl;
00417 for(i=attsModified.begin();i!=attsModified.end();++i)
00418 {
00419 mess<<*i<<std::endl;
00420 }
00421 }
00422 }
00423
00424 }
00425
00426
00427 else
00428 {
00429 int nf=0;
00430
00431 for(iter=fileList.begin();iter!=fileList.end();++iter)
00432 {
00433 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
00434 bool rec=true;
00435 if((*iter).recursive=="0"){rec=false;}
00436 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
00437
00438
00439 for (i=newFiles.begin();i!=newFiles.end();++i)
00440 {
00441 if (IsHandledFile(*i))
00442 {
00443 std::stringstream removedOn;
00444 removedOn<<time(0);
00445 mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str(),mCurrentDB);
00446
00447 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key,mCurrentDB)).c_str());
00448 files=files+1;
00449 std::stringstream out;
00450 out<<files;
00451
00452 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key,mCurrentDB);
00453 AddFile(*i);
00454 }
00455 }
00456 nf+=newFiles.size();
00457 newFiles.clear();
00458
00459 }
00460
00461 mess<<"Files Added: "<<nf<<std::endl;
00462
00463
00464 if(ignoreList.size()>0)
00465 {
00466 tree::Node* node;
00467 mTreeHandler->LoadChildren(NULL,4);
00468 for(i=ignoreList.begin();i!=ignoreList.end();++i)
00469 {
00470 FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
00471 RemoveFile(node);
00472 mTreeHandler->Remove(node);
00473 }
00474 }
00475 mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
00476
00477 if(checkAttributes)
00478 {
00479
00480 mess<<"Files Modified: "<<attsModified.size()<<std::endl;
00481 }
00482 }
00483 return mess.str();
00484
00485 }
00486
00487
00488 void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
00489 {
00490 std::map< std::string, std::string> attr;
00491 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
00492 mReader.ReadAttributes(file,attr);
00493 tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);
00494 tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
00495 for (a = adl.begin();a!=adl.end();++a)
00496 {
00497 std::string databaseVal;
00498 mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
00499 std::string fileVal=attr.find(a->GetKey())->second;
00500 if ( a->GetFlags()==0 && databaseVal == fileVal)
00501 {
00502 if(repair)
00503 {
00504 mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
00505 }
00506 attsModified.push_back(file);
00507 }
00508
00509 }
00510
00511 }
00512
00513
00514
00515
00516 void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
00517 {
00518 if(level>1)
00519 {
00520 std::vector<tree::Node*>::iterator iter;
00521 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
00522 {
00523 FindNode(*iter,level-1,searchParam,searchVal,node);
00524 }
00525 }
00526 else
00527 {
00528 if(parent->GetAttribute(searchParam).compare(searchVal)==0)
00529 {
00530 node=parent;
00531 }
00532
00533 }
00534 }
00535
00536 void TreeHandlerImageAdder::SaveAs(const std::vector<std::string>& filenames, std::vector<vtkImageData *> i_images)
00537 {
00538 std::vector<std::string>::const_iterator it_file = filenames.begin();
00539 std::vector<vtkImageData *>::iterator it_image = i_images.begin();
00540
00541
00542
00543 }
00544
00545
00546 void TreeHandlerImageAdder::FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
00547 {
00548 if(level>1)
00549 {
00550 std::vector<tree::Node*>::iterator iter;
00551 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end() && node==0 ;++iter)
00552 {
00553 FindNodePartial(*iter,level-1,searchParam,searchVal,node);
00554 }
00555 }
00556 else
00557 {
00558 if(parent->GetAttribute(searchParam).find(searchVal)<9000)
00559 {
00560 node=parent;
00561 return;
00562 }
00563
00564 }
00565 }
00566
00567
00568
00569 void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory )
00570 {
00571 std::vector<std::string>::const_iterator i;
00572 if(!boost::filesystem::exists(directory))
00573 {
00574 boost::filesystem::create_directory(boost::filesystem::path(directory));
00575 mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
00576 }
00577 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
00578 size_t last;
00579 std::vector<std::string> newNames;
00580 for(i=filenames.begin();i!=filenames.end();++i)
00581 {
00582 std::string dir=directory.c_str();
00583 if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
00584 {
00585 std::string path=*i;
00586 last=(*i).find_last_of('/');
00587 std::string f="\\"+(*i).substr(last+1);
00588
00589 int p=1;
00590 std::stringstream out;
00591 out<<directory<<f;
00592 while(boost::filesystem::exists(out.str()))
00593 {
00594 out.str("");
00595 out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
00596 p++;
00597 }
00598 std::string result=out.str();
00599 boost::filesystem::copy_file((*i),result);
00600
00601
00602 mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
00603
00604
00605
00606 std::stringstream removedOn;
00607 removedOn<<time(0);
00608
00609 mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
00610
00611 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
00612 files=files+1;
00613 std::stringstream fil;
00614 fil<<files;
00615
00616 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
00617 fil.str("");
00618
00619
00620
00621 std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
00622
00623 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
00624
00625 files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
00626 files=files-1;
00627 fil<<files;
00628
00629 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
00630
00631 }
00632
00633 }
00634 }
00635
00636
00637
00638 void TreeHandlerImageAdder::DeleteDriveFromMainDB(const std::string& drive)
00639 {
00640
00641 tree::Node* node=0;
00642 mTreeHandler->LoadChildren(NULL,4);
00643 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
00644 while(node!=0)
00645 {
00646 mTreeHandler->Remove(node);
00647 node=0;
00648 mTreeHandler->LoadChildren(NULL,4);
00649 FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
00650 }
00651 }
00652
00653
00654
00655 void TreeHandlerImageAdder::DeleteDriveFromOtherDB(const std::string& drive)
00656 {
00657
00658 mSynchronizer->RemoveEntries("ADD_OPS", "PATH", "LIKE", drive+"%");
00659 mSynchronizer->RemoveEntries("IGNORED_FILES", "PATH", "LIKE", drive+"%");
00660 }
00661
00662
00663 void TreeHandlerImageAdder::EditField(tree::Node* node, const std::string& name, const std::string& key, const std::string& val)
00664 {
00665 node->SetAttribute(key,val);
00666 mTreeHandler->SetAttribute(node,key,val);
00667 }
00668
00669
00670 void TreeHandlerImageAdder::GetAttributes(const std::vector<std::string>& params,
00671 const std::string& filename,
00672 std::vector<std::string>& results)
00673 {
00674 std::vector<std::string>::const_iterator i;
00675 std::string result;
00676 for(i=params.begin();i!=params.end();i++)
00677 {
00678 mTreeHandler->GetAttribute("Image","FullFileName",filename,*i,result);
00679 results.push_back(result);
00680 }
00681 }
00682
00683
00684 const std::string TreeHandlerImageAdder::isAttributeExist(const std::string i_attr)
00685 {
00686 return mTreeHandler->GetTree().isAttributeExist(i_attr);
00687 }
00688
00689 }