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 for (i=filenames.begin();i!=filenames.end();++i)
53 mTimestampHandler->AddFile((*i), fs::last_write_time(*i), time(0));
54 mProgress.IncNumberScannedFiles();
55 if (IsHandledFile(*i))
57 mProgress.IncNumberHandledFiles();
58 mSynchronizer->InsertAddOp((*i),"0","1");
59 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",(*i));
60 std::stringstream removedOn;
62 mSynchronizer->InsertIgnoreFile(addKey,(*i),"0",removedOn.str());
65 mProgressSignal(mProgress);
66 if (mProgress.GetStop()) break;
69 //=====================================================================
71 //=====================================================================
72 void TreeHandlerImageAdder::AddDirectory( const std::string& directory,
76 std::stringstream files;
78 std::stringstream rec;
80 mSynchronizer->InsertAddOp(directory,rec.str(),"0");
81 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory);
82 AddDirectoryRecursor( directory, recurse, addKey );
84 int nFiles=GetProgress().GetNumberAddedFiles();
86 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",files.str(),"ADD_KEY",addKey);
87 GimmickDebugMessage(3,mProgress<<std::endl);
90 //=====================================================================
91 void TreeHandlerImageAdder::AddFile( const std::string& filename )
93 GimmickDebugMessage(4,"Adding '"<<filename<<"'"<<std::endl);
94 std::map< std::string, std::string> attr;
95 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
97 mReader.ReadAttributes(filename,attr);
99 int lev = mTreeHandler->AddBranch(attr);
101 // update the progress according to lev
102 if (lev<mTreeHandler->GetTree().GetNumberOfLevels())
103 mProgress.IncNumberAddedFiles();
105 //=====================================================================
107 void TreeHandlerImageAdder::RemoveFile( const tree::Node*& node)
109 int n=node->GetNumberOfChildren();
112 RemoveFiles(node->GetChildrenList());
116 std::string path=node->GetAttribute("FullFileName");
118 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path);
119 //Gets the number of files added
120 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey)).c_str());
122 std::stringstream out;
124 //Sets the new number of files
125 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey);
126 //Sets the file as removed
127 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH",path);
131 //=====================================================================
133 void TreeHandlerImageAdder::RemoveFiles(const std::vector<tree::Node*>& nodes)
135 std::vector<tree::Node*>::const_iterator it;
136 for(it=nodes.begin();it!=nodes.end();++it)
138 int n=(*it)->GetNumberOfChildren();
141 RemoveFiles((*it)->GetChildrenList());
145 std::string path=(*it)->GetAttribute("FullFileName");
147 std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path);
148 //Gets the number of files added
149 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey)).c_str());
151 std::stringstream out;
153 //Sets the new number of files
154 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",addKey);
155 //Sets the file as removed
156 mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH",path);
162 //=====================================================================
163 void TreeHandlerImageAdder::AddDirectoryRecursor(const std::string &dirpath,
165 const std::string &addKey)
167 GimmickDebugMessage(4,"Scanning '"<<dirpath<<"'"<<std::endl);
168 mProgress.IncNumberScannedDirs();
170 if ( !fs::exists( dirpath ) ) return;
171 time_t lastModif=fs::last_write_time(dirpath);
173 fs::directory_iterator end_itr; // default construction yields past-the-end
174 for ( fs::directory_iterator itr( dirpath );
178 // If is directory & recurse : do recurse
179 if ( fs::is_directory(itr->status()) )
183 AddDirectoryRecursor( itr->string(), recursive, addKey);
188 std::string parent_id;
189 bool valid=mTimestampHandler->AddDirectory(dirpath, itr->string(), lastModif, time(0));
192 mProgress.IncNumberScannedFiles();
193 if (IsHandledFile(itr->string()))
195 mProgress.IncNumberHandledFiles();
196 AddFile( itr->string() );
197 mTreeHandler->GetTopLevelNodeId("FullFileName",itr->string(),parent_id);
198 mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",itr->string());
199 std::stringstream removedOn;
201 mSynchronizer->InsertIgnoreFile(addKey, itr->string(),"0",removedOn.str());
203 mProgressSignal(mProgress);
204 if (mProgress.GetStop())
210 mTimestampHandler->SetAttribute("TopLevelNodeId",parent_id,"PATH",dirpath);
215 //=======================================================================
217 //=======================================================================
219 void TreeHandlerImageAdder::CheckSyncDirectory(const std::string &dirpath,
222 bool checkAttributes,
223 std::vector<std::string> &i_ignorefiles,
224 std::vector<std::string> & attsModified,
225 std::vector<std::string> & newfiles)
227 if ( !fs::exists( dirpath ) ) return;
228 fs::directory_iterator end_itr; // default construction yields past-the-end
230 for ( fs::directory_iterator itr( dirpath ); itr != end_itr; ++itr )
232 // If is directory & recurse : do recurse
233 if ( fs::is_directory(itr->status()) )
237 CheckSyncDirectory( itr->string(), recursive, repair, checkAttributes, i_ignorefiles, attsModified, newfiles);
242 if (IsHandledFile(itr->string()))
245 for(std::vector<std::string>::iterator it_new = i_ignorefiles.begin(); it_new < i_ignorefiles.end(); ++it_new)
247 if((*it_new) == itr->string())
250 //Additional checking of attributes
253 CheckAttributes(repair,(*it_new),attsModified);
255 i_ignorefiles.erase(it_new);
259 if(!bfound && i_ignorefiles.size()>0 )
261 newfiles.push_back( itr->string() );
268 //=======================================================================
270 //=======================================================================
272 std::string TreeHandlerImageAdder::Synchronize(bool repair, bool checkAttributes)
274 std::vector<AddList> fileList;
275 std::vector<std::string> ignoreList;
276 std::vector<std::string> newFiles;
277 std::vector<std::string> attsModified;
278 std::stringstream mess;
279 std::vector<AddList>::iterator iter;
281 //Gets the list of added files
282 mSynchronizer->GetFileList(fileList);
284 std::vector<std::string>::iterator i;
285 //Actions to take if the user doesn't want to repair
288 //Iterates to see if they are in sync
289 for(iter=fileList.begin();iter!=fileList.end();++iter)
291 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
293 if((*iter).recursive=="0"){rec=false;}
294 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
297 //Add to message the result of new found files
298 mess<<"New Files Found: "<<newFiles.size()<<std::endl;
299 if(newFiles.size()>0)
301 mess<<"Filenames: "<<std::endl;
302 for(i=newFiles.begin();i!=newFiles.end();++i)
308 //Add to message the result of missing files
309 mess<<"Missing Files: "<<ignoreList.size()<<std::endl;
310 if(ignoreList.size()>0)
312 mess<<"Filenames: "<<std::endl;
313 for(i=ignoreList.begin();i!=ignoreList.end();++i)
319 //In the case that the user wants to check the attributes...
322 //... add to message the result of files that have been changed.
323 mess<<"Files with different attributes: "<<attsModified.size()<<std::endl;
324 if(attsModified.size()>0)
326 mess<<"Filenames: "<<std::endl;
327 for(i=attsModified.begin();i!=attsModified.end();++i)
336 //Actions to take if the user wants to repair
340 //Iterates to see if they are in sync
341 for(iter=fileList.begin();iter!=fileList.end();++iter)
343 mSynchronizer->GetIgnoredFiles((*iter).key,ignoreList);
345 if((*iter).recursive=="0"){rec=false;}
346 CheckSyncDirectory((*iter).path,rec,repair,checkAttributes,ignoreList,attsModified,newFiles);
348 //For the new files, add them
349 for (i=newFiles.begin();i!=newFiles.end();++i)
351 mTimestampHandler->AddFile((*i), fs::last_write_time(*i), time(0));
352 if (IsHandledFile(*i))
354 std::stringstream removedOn;
356 mSynchronizer->InsertIgnoreFile((*iter).key,(*i),"0",removedOn.str());
357 //Gets the number of files added
358 int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",(*iter).key)).c_str());
360 std::stringstream out;
362 //Sets the new number of files
363 mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",out.str(),"ADD_KEY",(*iter).key);
371 //Reports number of added files
372 mess<<"Files Added: "<<nf<<std::endl;
374 //Removes the necessary files and reports the results
375 if(ignoreList.size()>0)
378 mTreeHandler->LoadChildren(NULL,4);
379 for(i=ignoreList.begin();i!=ignoreList.end();++i)
381 FindNode(mTreeHandler->GetTree().GetChildrenList()[0],3,"FullFileName",*i,node);
383 mTreeHandler->Remove(node);
386 mess<<"Files Removed: "<<ignoreList.size()<<std::endl;
387 //In the case that the user wants to check the attributes...
390 //... add to message the result of files that were modified.
391 mess<<"Files Modified: "<<attsModified.size()<<std::endl;
397 //=======================================================================
399 void TreeHandlerImageAdder::CheckAttributes(bool repair, std::string& file, std::vector<std::string>& attsModified)
401 std::map< std::string, std::string> attr;
402 mTreeHandler->GetTree().GetDescriptor().BuildAttributeMap(attr);
403 mReader.ReadAttributes(file,attr);
404 tree::LevelDescriptor::AttributeDescriptorListType adl= mTreeHandler->GetTree().GetAttributeDescriptorList(mTreeHandler->GetTree().GetNumberOfLevels()-1);
405 tree::LevelDescriptor::AttributeDescriptorListType::const_iterator a;
406 for (a = adl.begin();a!=adl.end();++a)
408 std::string databaseVal;
409 mTreeHandler->GetAttribute("Image","FullFileName",file,a->GetKey(),databaseVal);
410 std::string fileVal=attr.find(a->GetKey())->second;
411 if ( a->GetFlags()==0 && databaseVal.compare(fileVal)!=0 )
415 mTreeHandler->SetAttribute("Image",a->GetKey(),fileVal,"FullFileName", file);
417 attsModified.push_back(file);
424 //=======================================================================
427 void TreeHandlerImageAdder::FindNode(tree::Node* parent, int level, const std::string& searchParam, const std::string& searchVal, tree::Node*& node)
431 std::vector<tree::Node*>::iterator iter;
432 for(iter=parent->GetChildrenList().begin();iter!=parent->GetChildrenList().end();++iter)
434 FindNode(*iter,level-1,searchParam,searchVal,node);
439 if(parent->GetAttribute(searchParam).compare(searchVal)==0)
447 //=======================================================================