]> Creatis software - creaImageIO.git/blobdiff - src2/creaImageIOTreeHandlerImageAdder.cpp
Added Settings dialog, customize configuration options and the listener on an externa...
[creaImageIO.git] / src2 / creaImageIOTreeHandlerImageAdder.cpp
index e384e99c7f3c1b674f939b80f668f3e87aaa7c34..471c785317df2e0e0c4289d6dcdcedff6b50a5dd 100644 (file)
@@ -1,13 +1,17 @@
 #include <creaImageIOTreeHandlerImageAdder.h>
 #include <creaImageIOSystem.h>
-//#include <wx/dir.h>
-//#include <wx/filename.h>
-
 #include "boost/filesystem.hpp"
+#include <boost/filesystem/operations.hpp>
+#include <boost/utility.hpp>
+
 
 namespace fs = boost::filesystem;
+using boost::filesystem::path;
+using boost::next;
+using boost::prior;
+
 
-//using namespace crea;
+using namespace crea;
 
 namespace creaImageIO
 {
@@ -41,15 +45,21 @@ namespace creaImageIO
   void TreeHandlerImageAdder::AddFiles( const std::vector<std::string>& filenames)
   {
     mProgress.Reset();
-
+       
     unsigned int nbf = filenames.size(); 
     std::vector<std::string>::const_iterator i;
     for (i=filenames.begin();i!=filenames.end();++i)
       {
+       mTimestampHandler->AddFile((*i), fs::last_write_time(*i), time(0),mCurrentDB);
        mProgress.IncNumberScannedFiles();
        if (IsHandledFile(*i)) 
          {
            mProgress.IncNumberHandledFiles();
+               mSynchronizer->InsertAddOp((*i),"0","1",mCurrentDB);
+               std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i),mCurrentDB);
+               std::stringstream removedOn;
+               removedOn<<time(0);
+               mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str(),mCurrentDB);
            AddFile(*i);
          }
        mProgressSignal(mProgress);
@@ -63,13 +73,19 @@ namespace creaImageIO
                                            bool recurse)
   {
     mProgress.Reset();
-    AddDirectoryRecursor( directory, recurse );
+       std::stringstream files;
+       
+       std::stringstream rec;
+       rec<<recurse;
+       mSynchronizer->InsertAddOp(directory,rec.str(),"0",mCurrentDB);
+       std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
+       AddDirectoryRecursor( directory, recurse, addKey );
+       
+       int nFiles=GetProgress().GetNumberAddedFiles();
+       files<<nFiles;
+       mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey,mCurrentDB);
     GimmickDebugMessage(3,mProgress<<std::endl);
   }
-  //=====================================================================
-
-
-
 
   //=====================================================================
   void TreeHandlerImageAdder::AddFile( const std::string& filename )
@@ -88,15 +104,72 @@ namespace creaImageIO
   }
   //=====================================================================
 
+  void TreeHandlerImageAdder::RemoveFile( tree::Node* node)
+  {
+               int n=node->GetNumberOfChildren();
+               if(n>0)
+               {
+                       RemoveFiles(node->GetChildrenList());
+               }
+               else
+               {
+                 std::string path=node->GetAttribute("FullFileName");
+                 //Gets the add key
+                 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
+                 //Gets the number of files added
+                 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
+                 files=files-1;
+                 std::stringstream out;
+                 out<<files;
+                 //Sets the new number of files
+                 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
+                 //Sets the file as removed
+                 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
+               }
+  }
+
+  //=====================================================================
+
+  void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
+  {
+         std::vector<tree::Node*>::const_iterator it;
+         for(it=nodes.begin();it!=nodes.end();++it)
+         {
+               int n=(*it)->GetNumberOfChildren();
+               if(n>0)
+               {
+                       RemoveFiles((*it)->GetChildrenList());
+               }
+               else
+               {
+                  std::string path=(*it)->GetAttribute("FullFileName");
+                 //Gets the add key
+                 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
+                 //Gets the number of files added
+                 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
+                 files=files-1;
+                 std::stringstream out;
+                 out<<files;
+                 //Sets the new number of files
+                 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey,mCurrentDB);
+                 //Sets the file as removed
+                 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",addKey,mCurrentDB);
+               }
+       
+         }
+  }
+
   //=====================================================================
   void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath, 
-                                                  bool recursive)
+                                                  bool recursive,
+                                                  const std::string &addKey)
   {
     GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
     mProgress.IncNumberScannedDirs();
 
     if ( !fs::exists( dirpath ) ) return;
-    
+       time_t lastModif=fs::last_write_time(dirpath);
+
     fs::directory_iterator end_itr; // default construction yields past-the-end
     for ( fs::directory_iterator itr( dirpath );
          itr != end_itr;
@@ -105,73 +178,404 @@ namespace creaImageIO
        // If is directory & recurse : do recurse
        if ( fs::is_directory(itr->status()) )
          {
-           if (recursive) AddDirectoryRecursor( itr->string(), recursive);
+           if (recursive) 
+               {
+                       AddDirectoryRecursor( itr->string(), recursive, addKey);
+               }
          }
        else 
          {
-           mProgress.IncNumberScannedFiles();
-           if (IsHandledFile(itr->string()))
-             {
-               mProgress.IncNumberHandledFiles();
-               AddFile( itr->string() );
-             }
-           mProgressSignal(mProgress);
-           if (mProgress.GetStop()) break;
+               std::string parent_id;
+               bool valid=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0),mCurrentDB);
+               if(valid)
+               {
+                       mProgress.IncNumberScannedFiles();
+                       if (IsHandledFile(itr->string()))
+                       {
+                       mProgress.IncNumberHandledFiles();
+                       AddFile( itr->string() );
+                       mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
+                       mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",itr->string());
+                       std::stringstream removedOn;
+                       removedOn<<time(0);
+                       mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str(),mCurrentDB);
+                       }
+                       
+                       mProgressSignal(mProgress);
+                       if (mProgress.GetStop()) 
+                       {
+                       //itr = end_itr;
+                       break;
+                       }
+                       
+               }
+               mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",dirpath);
          }
       }
+       
   }
+  //=======================================================================
+  
+  //=======================================================================
+
+  void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath, 
+                                                                                               bool recursive, 
+                                                                                               bool repair,
+                                                                                               bool checkAttributes,
+                                                                                               std::vector<std::string> &i_ignorefiles,
+                                                                                               std::vector<std::string> & attsModified,
+                                                                                               std::vector<std::string> & newfiles)
+  {
+    if ( !fs::exists( dirpath ) ) return;
+    fs::directory_iterator end_itr; // default construction yields past-the-end
+                         
+    for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr ) 
+       {
+        // If is directory & recurse : do recurse
+        if ( fs::is_directory(itr->status()) )
+        {
+            if (recursive)
+                       {
+                CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
+                       }
+        }
+        else
+        {
+            if (IsHandledFile(itr->string()))
+            {
+                bool bfound = false;
+                for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
+                {
+                                       if((*it_new) == itr->string())
+                    {
+                        bfound = true;
+                                               //Additional checking of attributes
+                                               if(checkAttributes)
+                                               {
+                                                       CheckAttributes(repair,(*it_new),attsModified);
+                                               }
+                        i_ignorefiles.erase(it_new);
+                        break;
+                    }
+                               }
+                               if(!bfound && i_ignorefiles.size()>0 )
+                {
+                    newfiles.push_back( itr->string() );
+                }
+                       }
+               }
+        }
+  } 
 
-    /*
+  //=======================================================================
+  
+  //=======================================================================
 
-    std::string fileName;
-    std::string dirName = dirpath;
+  std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
+  {
+         std::vector<AddList> fileList;
+         std::vector<std::string> ignoreList;
+         std::vector<std::string> newFiles;
+         std::vector<std::string> attsModified;
+         std::stringstream mess;
+         std::vector<AddList>::iterator iter;
 
-    wxDir dir( std2wx(dirpath) );
+         //Gets the list of added files
+         mSynchronizer->GetFileList(fileList,mCurrentDB);
 
-    if ( !dir.IsOpened() )
-      {
-        // deal with the error here - wxDir would already log an error message
-        // explaining the exact reason of the failure
-        return;
-      }
+         std::vector<std::string>::iterator i;
+         //Actions to take if the user doesn't want to repair
+         if(!repair)
+         {
+               //Iterates to see if they are in sync
+               for(iter=fileList.begin();iter!=fileList.end();++iter)
+               {
+                       mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
+                       bool rec=true;
+                       if((*iter).recursive=="0"){rec=false;}
+                       CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
+               }
 
-    wxString filename;
+               //Add to message the result of new found files
+               mess<<"New Files Found: "<<newFiles.size()<<std::endl;
+               if(newFiles.size()>0)
+               {
+                       mess<<"Filenames: "<<std::endl;
+                       for(i=newFiles.begin();i!=newFiles.end();++i)
+                       {
+                               mess<<*i<<std::endl;
+                       }
+               }
 
-    bool cont = dir.GetFirst(&filename, wxEmptyString, 
-                            wxDIR_FILES | wxDIR_HIDDEN );
-    while ( cont )
-      {
-       mProgress.IncNumberScannedFiles();
+               //Add to message the result of missing files
+               mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
+               if(ignoreList.size()>0)
+               {
+                       mess<<"Filenames: "<<std::endl;
+                       for(i=ignoreList.begin();i!=ignoreList.end();++i)
+                       {
+                               mess<<*i<<std::endl;
+                       }
+               }
 
-       wxFileName wxffn(dir.GetName(),filename);
-       std::string ffn = wx2std(wxffn.GetFullPath());
-       if (IsHandledFile(ffn)) 
+               //In the case that the user wants to check the attributes...
+               if(checkAttributes)
+               {
+                       //... add to message the result of files that have been changed.
+                       mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
+                       if(attsModified.size()>0)
+                       {
+                               mess<<"Filenames: "<<std::endl;
+                               for(i=attsModified.begin();i!=attsModified.end();++i)
+                               {
+                                       mess<<*i<<std::endl;
+                               }
+                       }
+               }
+               
+         }
+
+         //Actions to take if the user wants to repair
+         else
          {
-           mProgress.IncNumberHandledFiles();
-           AddFile( ffn );
+                 int nf=0;
+               //Iterates to see if they are in sync
+               for(iter=fileList.begin();iter!=fileList.end();++iter)
+               {
+                       mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
+                       bool rec=true;
+                       if((*iter).recursive=="0"){rec=false;}
+                       CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
+
+                       //For the new files, add them
+                       for (i=newFiles.begin();i!=newFiles.end();++i)
+                       {
+                       mTimestampHandler->AddFile((*i), fs::last_write_time(*i), time(0),mCurrentDB);
+                       if (IsHandledFile(*i)) 
+                       {
+                               std::stringstream removedOn;
+                               removedOn<<time(0);
+                               mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str(),mCurrentDB);
+                               //Gets the number of files added
+                               int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key,mCurrentDB)).c_str());
+                               files=files+1;
+                               std::stringstream out;
+                               out<<files;
+                               //Sets the new number of files
+                               mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key,mCurrentDB);
+                               AddFile(*i);
+                       }
+                       }
+                       nf+=newFiles.size();
+                       newFiles.clear();
+
+               }
+               //Reports number of added files
+               mess<<"Files Added: "<<nf<<std::endl;
+               
+               //Removes the necessary files and reports the results
+               if(ignoreList.size()>0)
+               {
+                       tree::Node* node;
+                       mTreeHandler->LoadChildren(NULL,4);
+                       for(i=ignoreList.begin();i!=ignoreList.end();++i)
+                       {
+                               FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
+                               RemoveFile(node);
+                               mTreeHandler->Remove(node);
+                       }
+               }
+               mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
+               //In the case that the user wants to check the attributes...
+               if(checkAttributes)
+               {
+                       //... add to message the result of files that were modified.
+                       mess<<"Files Modified: "<<attsModified.size()<<std::endl;
+               }
          }
-       mProgressSignal(mProgress);
-       cont = ( dir.GetNext(&filename) && (!mProgress.GetStop()) );
-      }
-    
-    // Recurse into subdirs
-    if ( recursive )
-      {
-       cont = dir.GetFirst(&filename, wxEmptyString, 
-                           wxDIR_DIRS | wxDIR_HIDDEN );
-       while ( cont )
+         return mess.str();
+
+  }
+  //=======================================================================
+
+  void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
+  {
+         std::map< std::string, std::string>  attr;
+         mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
+      mReader.ReadAttributes(file,attr);
+         tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);    
+         tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
+         for (a = adl.begin();a!=adl.end();++a)
          {
-           wxFileName wxffn(dir.GetName(),filename);
-           std::string ffn = wx2std(wxffn.GetFullPath());
-           AddDirectoryRecursor( ffn, recursive);
-           cont = dir.GetNext(&filename);
+          std::string databaseVal;
+          mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
+          std::string fileVal=attr.find(a->GetKey())->second;
+          if ( a->GetFlags()==0 && databaseVal.compare(fileVal)!=0 ) 
+           {
+                       if(repair)
+                       {
+                               mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);   
+                       }
+                       attsModified.push_back(file);
+           }
+               
          }
-      }
+         
+  }
+
+  //=======================================================================
+
+
+  void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
+  {
+         if(level>1)
+         {
+                 std::vector<tree::Node*>::iterator iter;
+                 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
+                 {
+                         FindNode(*iter,level-1,searchParam,searchVal,node);
+                 }
+         }
+         else
+         {
+                 if(parent->GetAttribute(searchParam).compare(searchVal)==0)
+                 {
+                         node=parent;
+                 }
+
+         }
+  }
   
-  */
+  //=======================================================================
+  void TreeHandlerImageAdder::FindNodePartial(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
+  {
+         if(level>1)
+         {
+                 std::vector<tree::Node*>::iterator iter;
+                 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end() && node==0 ;++iter)
+                 {
+                         FindNodePartial(*iter,level-1,searchParam,searchVal,node);
+                 }
+         }
+         else
+         {
+                 if(parent->GetAttribute(searchParam).find(searchVal)<9000)
+                 {
+                         node=parent;
+                         return;
+                 }
+
+         }
+  }
   
   //=======================================================================
 
+  void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory  )
+  {
+         std::vector<std::string>::const_iterator i;
+         if(!boost::filesystem::exists(directory))
+         {
+         boost::filesystem::create_directory(boost::filesystem::path(directory));
+         mTimestampHandler->AddDirectory("",directory,fs::last_write_time(directory)+10, time(0),mCurrentDB);
+         mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
+         }
+         std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
+         std::string parent_id=mTimestampHandler->IsIndexed(directory,mCurrentDB);
+         size_t last;
+         std::vector<std::string> newNames;
+         for(i=filenames.begin();i!=filenames.end();++i)
+         {
+                 std::string dir=directory.c_str();
+                 mTimestampHandler->CleanPath(dir);
+                 if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
+                 {
+                 std::string path=*i;
+                 last=(*i).find_last_of('/');
+                 std::string f="\\"+(*i).substr(last+1);
+       
+                 int p=1;
+                 std::stringstream out;
+                 out<<directory<<f;
+                 while(boost::filesystem::exists(out.str()))
+                 {
+                         out.str("");
+                         out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
+                         p++;
+                 }
+                 std::string result=out.str();
+                 mTimestampHandler->CleanPath(result);
+                 boost::filesystem::copy_file((*i),result);
+
+                 //To update image database
+                 mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
+                 
+                 //To update timestamp database
+                 mTimestampHandler->SetAttribute("PATH",result,"PATH",(*i));
+                 mTimestampHandler->SetAttribute("PARENT_ID",parent_id,"PATH",result);
+                 std::stringstream t;
+                 t<<fs::last_write_time(directory)+10;
+                 mTimestampHandler->SetAttribute("LastModified",t.str(),"PATH",result);
+
+                 //To update maintenance database
+                 //1.Add the new path and increase number of children on new operation.
+                 std::stringstream removedOn;
+                 removedOn<<time(0);
+                 //Inserts the file
+                 mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
+                 //Gets the number of files added
+                 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
+                 files=files+1;
+                 std::stringstream fil;
+                 fil<<files;
+                 //Sets the new number of files
+                 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
+                 fil.str("");
+
+                 //2.Set the old path as removed and decrease number of children on old operation.
+                 //Gets the old add key
+                 std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
+                 //Sets the file as removed
+                 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
+                 //Gets the number of files added
+                 files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
+                 files=files-1;
+                 fil<<files;
+                 //Sets the new number of files
+                 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
+                 
+                 }
+
+         }
+  }
+
+  //=======================================================================
+
+  void TreeHandlerImageAdder::DeleteDriveFromMainDB(const std::string& drive)
+  {
+         //Delete from local database and others
+         tree::Node* node=0;
+         mTreeHandler->LoadChildren(NULL,4);
+         FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node);
+         while(node!=0)
+         {
+         mTreeHandler->Remove(node);
+         node=0;
+         mTreeHandler->LoadChildren(NULL,4);
+         FindNodePartial(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",drive,node); 
+         }
+  }
+
+   //=======================================================================
+
+  void TreeHandlerImageAdder::DeleteDriveFromOtherDB(const std::string& drive)
+  {
+         //Delete from timestamp
+         mTimestampHandler->RemoveEntries("FILES", "PATH", "LIKE", drive+"%");
+
+         //Delete from maintenance
+         mSynchronizer->RemoveEntries("ADD_OPS", "PATH", "LIKE", drive+"%");
+         mSynchronizer->RemoveEntries("IGNORED_FILES", "PATH", "LIKE", drive+"%");
+  }
 
  
 }