]> Creatis software - creaImageIO.git/blobdiff - src2/creaImageIOTreeHandlerImageAdder.cpp
Added synchronization
[creaImageIO.git] / src2 / creaImageIOTreeHandlerImageAdder.cpp
index 057f16eb51e994563a107e3d0f7bfd374c17ba37..679e156df04b130d4ec728bf67b33eca5969edd4 100644 (file)
@@ -1,7 +1,15 @@
 #include <creaImageIOTreeHandlerImageAdder.h>
-#include <creaWx.h>
-#include <wx/dir.h>
-#include <wx/filename.h>
+#include <creaImageIOSystem.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;
 
@@ -37,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));
        mProgress.IncNumberScannedFiles();
        if (IsHandledFile(*i)) 
          {
            mProgress.IncNumberHandledFiles();
+               mSynchronizer->InsertAddOp((*i),"0","1");
+               std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i));
+               std::stringstream removedOn;
+               removedOn<<time(0);
+               mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str());
            AddFile(*i);
          }
        mProgressSignal(mProgress);
@@ -59,17 +73,24 @@ namespace creaImageIO
                                            bool recurse)
   {
     mProgress.Reset();
-    AddDirectoryRecursor( directory, recurse );
+       std::stringstream files;
+       
+       std::stringstream rec;
+       rec<<recurse;
+       mSynchronizer->InsertAddOp(directory,rec.str(),"0");
+       std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory);
+       AddDirectoryRecursor( directory, recurse, addKey );
+       
+       int nFiles=GetProgress().GetNumberAddedFiles();
+       files<<nFiles;
+       mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey);
+    GimmickDebugMessage(3,mProgress<<std::endl);
   }
-  //=====================================================================
-
-
-
 
   //=====================================================================
   void TreeHandlerImageAdder::AddFile( const std::string& filename )
   {
-    
+    GimmickDebugMessage(4,"Adding '"<<filename<<"'"<<std::endl);
     std::map< std::string, std::string>  attr;
     mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
 
@@ -83,58 +104,346 @@ namespace creaImageIO
   }
   //=====================================================================
 
+  void TreeHandlerImageAdder::RemoveFile( const 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);
+                 //Gets the number of files added
+                 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey)).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);
+                 //Sets the file as removed
+                 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH",path);
+               }
+  }
+
+  //=====================================================================
+
+  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);
+                 //Gets the number of files added
+                 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey)).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);
+                 //Sets the file as removed
+                 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH",path);
+               }
+       
+         }
+  }
+
   //=====================================================================
   void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath, 
-                                                  bool recursive)
+                                                  bool recursive,
+                                                  const std::string &addKey)
   {
+    GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
     mProgress.IncNumberScannedDirs();
 
-    std::string fileName;
-    std::string dirName = dirpath;
+    if ( !fs::exists( dirpath ) ) return;
+       time_t lastModif=fs::last_write_time(dirpath);
 
-    wxDir dir( std2wx(dirpath) );
-
-    if ( !dir.IsOpened() )
+    fs::directory_iterator end_itr; // default construction yields past-the-end
+    for ( fs::directory_iterator itr( dirpath );
+         itr != end_itr;
+         ++itr )
       {
-        // deal with the error here - wxDir would already log an error message
-        // explaining the exact reason of the failure
-        return;
+       // If is directory & recurse : do recurse
+       if ( fs::is_directory(itr->status()) )
+         {
+           if (recursive) 
+               {
+                       AddDirectoryRecursor( itr->string(), recursive, addKey);
+               }
+         }
+       else 
+         {
+               std::string parent_id;
+               bool valid=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0));
+               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());
+                       }
+                       mProgressSignal(mProgress);
+                       if (mProgress.GetStop()) 
+                       {
+                       //itr = end_itr;
+                       break;
+                       }
+               }
+               mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",dirpath);
+         }
       }
+       
+  }
+  //=======================================================================
+  
+  //=======================================================================
 
-    wxString filename;
+  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() );
+                }
+                       }
+               }
+        }
+  } 
 
-    bool cont = dir.GetFirst(&filename, wxEmptyString, 
-                            wxDIR_FILES | wxDIR_HIDDEN );
-    while ( cont )
-      {
-       mProgress.IncNumberScannedFiles();
+  //=======================================================================
+  
+  //=======================================================================
 
-       wxFileName wxffn(dir.GetName(),filename);
-       std::string ffn = wx2std(wxffn.GetFullPath());
-       if (IsHandledFile(ffn)) 
+  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;
+
+         //Gets the list of added files
+         mSynchronizer->GetFileList(fileList);
+
+         std::vector<std::string>::iterator i;
+         //Actions to take if the user doesn't want to repair
+         if(!repair)
          {
-           mProgress.IncNumberHandledFiles();
-           AddFile( ffn );
+               //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);
+               }
+
+               //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;
+                       }
+               }
+
+               //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;
+                       }
+               }
+
+               //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;
+                               }
+                       }
+               }
+               
          }
-       mProgressSignal(mProgress);
-       cont = ( dir.GetNext(&filename) && (!mProgress.GetStop()) );
-      }
-    
-    // Recurse into subdirs
-    if ( recursive )
-      {
-       cont = dir.GetFirst(&filename, wxEmptyString, 
-                           wxDIR_DIRS | wxDIR_HIDDEN );
-       while ( cont )
+
+         //Actions to take if the user wants to repair
+         else
          {
-           wxFileName wxffn(dir.GetName(),filename);
-           std::string ffn = wx2std(wxffn.GetFullPath());
-           AddDirectoryRecursor( ffn, recursive);
-           cont = dir.GetNext(&filename);
+                 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));
+                       if (IsHandledFile(*i)) 
+                       {
+                               std::stringstream removedOn;
+                               removedOn<<time(0);
+                               mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str());
+                               //Gets the number of files added
+                               int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key)).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);
+                               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;
+               }
+         }
+         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)
+         {
+          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;
+                 }
+
          }
-      }
-    
   }
+  
   //=======================================================================