Modifications to raise move events for moved child objects from the FileAgent
authorPanagiotis Kanavos <pkanavos@gmail.com>
Mon, 20 Feb 2012 12:35:36 +0000 (14:35 +0200)
committerPanagiotis Kanavos <pkanavos@gmail.com>
Mon, 20 Feb 2012 12:35:36 +0000 (14:35 +0200)
trunk/Pithos.Core/Agents/FileAgent.cs
trunk/Pithos.Core/Agents/FileSystemWatcherAdapter.cs
trunk/Pithos.Core/Agents/WorkflowAgent.cs
trunk/Pithos.Network/TreeHash.cs

index 4005d2b..c93a029 100644 (file)
@@ -104,8 +104,7 @@ namespace Pithos.Core.Agents
                 loop = () =>
                 {
                     var message = inbox.Receive();
-                    var process=message.Then(Process,inbox.CancellationToken);
-
+                    var process=message.Then(Process,inbox.CancellationToken);                    
                     inbox.LoopAsync(process,loop,ex=>
                         Log.ErrorFormat("[ERROR] File Event Processing:\r{0}", ex));
                 };
@@ -246,16 +245,16 @@ namespace Pithos.Core.Agents
 
         private bool Ignore(string filePath)
         {
-            //Ignore all first-level directories and files            
+            //Ignore all first-level directories and files (ie at the container folders level)
             if (FoundBelowRoot(filePath, RootPath,1))
-                return true;            
+                return true;
 
-            //Ignore first-level items under the "others" folder.
+            //Ignore first-level items under the "others" folder (ie at the accounts folders level).
             var othersPath = Path.Combine(RootPath, FolderConstants.OthersFolder);
             if (FoundBelowRoot(filePath, othersPath,1))
-                return true;            
+                return true;
 
-            //Ignore second-level (container) folders under the "others" folder. 
+            //Ignore second-level (container) folders under the "others" folder (ie at the container folders level). 
             if (FoundBelowRoot(filePath, othersPath,2))
                 return true;            
 
@@ -265,6 +264,15 @@ namespace Pithos.Core.Agents
                 return true;
             if (_ignoreFiles.ContainsKey(filePath.ToLower()))
                 return true;
+
+            //If selective synchronization is defined, 
+            if (SelectivePaths.Count>0)
+            {
+                //Abort if the file is not located under any of the selected folders
+                if (!SelectivePaths.Any(filePath.StartsWith))
+                    return true;
+            }
+
             return false;
         }
 
index 55aeea2..54592df 100644 (file)
@@ -42,6 +42,7 @@
 using System.Diagnostics.Contracts;\r
 using System.IO;\r
 using System.Threading.Tasks;\r
+using Pithos.Interfaces;\r
 \r
 namespace Pithos.Core.Agents\r
 {\r
@@ -106,7 +107,7 @@ namespace Pithos.Core.Agents
             //      as this is actually a MOVE operation\r
             //Deleting by Shift+Delete results in a delete event for each file followed by the delete of the folder itself\r
             _cachedDeletedFullPath = e.FullPath;\r
-\r
+            \r
             //TODO: This requires synchronization of the _cachedDeletedFullPath field\r
             //TODO: This creates a new task for each file even though we can cancel any existing tasks if a new event arrives\r
             //Maybe, use a timer instead of a task\r
@@ -199,8 +200,30 @@ namespace Pithos.Core.Agents
                 //If the actual action is a Move, raise a Move event instead of the actual event\r
                 var newDirectory = Path.GetDirectoryName(e.FullPath);\r
                 var oldDirectory = Path.GetDirectoryName(_cachedDeletedFullPath);\r
+\r
                 if (Moved != null)\r
+                {\r
                     Moved(sender, new MovedEventArgs(newDirectory, newName, oldDirectory, oldName));\r
+                    //If the moved item is a dictionary, we need to raise a change event for each child item\r
+                    //When a directory is moved within the same volume, Windows raises events only for the directory object,\r
+                    //not its children. This happens because the move actually changes a single directory entry. It doesn't\r
+                    //affect the entries of the children.\r
+                    var directory = new DirectoryInfo(e.FullPath);\r
+                    if (directory.Exists)\r
+                    {\r
+                        foreach (var child in directory.EnumerateFileSystemInfos("*", SearchOption.AllDirectories))\r
+                        {\r
+                            var newChildDirectory = Path.GetDirectoryName(child.FullName);\r
+\r
+                            var relativePath=child.AsRelativeTo(newDirectory);\r
+                            var relativeFolder = Path.GetDirectoryName(relativePath);\r
+                            var oldChildDirectory = Path.Combine(oldDirectory, relativeFolder);\r
+                            Moved(sender,new MovedEventArgs(newChildDirectory,child.Name,oldChildDirectory,child.Name));\r
+                        }\r
+                    }\r
+\r
+                }\r
+\r
             }\r
             finally\r
             {\r
@@ -223,8 +246,12 @@ namespace Pithos.Core.Agents
             var deletedFileName = Path.GetFileName(_cachedDeletedFullPath);\r
             var deletedFileDirectory = Path.GetDirectoryName(_cachedDeletedFullPath);\r
 \r
-            if (Deleted!=null)\r
-                Deleted(sender, new FileSystemEventArgs(WatcherChangeTypes.Deleted, deletedFileDirectory, deletedFileName));\r
+            //Only a single file Delete event is raised when moving a file to the Recycle Bin, as this is actually a MOVE operation\r
+            //In this case we need to raise the proper events for all child objects of the deleted directory.\r
+            //UNFORTUNATELY, this can't be detected here, eg. by retrieving the child objects, because they are already deleted\r
+            //This should be done at a higher level, eg by checking the stored state\r
+            if (Deleted != null)            \r
+                Deleted(sender,new FileSystemEventArgs(WatcherChangeTypes.Deleted, deletedFileDirectory, deletedFileName));\r
 \r
             _cachedDeletedFullPath = null;\r
         }\r
index 77875ed..aafc377 100644 (file)
@@ -145,7 +145,7 @@ namespace Pithos.Core.Agents
                                                                       newInfo));                                
                                 //TODO: Do I have to move children as well or will Pithos handle this?
                                //Need to find all children of the OLD filepath
-                                MoveChildObjects(state);
+                                //MoveChildObjects(state);
                                 break;
                         }
                     }
@@ -160,6 +160,7 @@ namespace Pithos.Core.Agents
             }
         }
 
+
         private void DeleteChildObjects(WorkflowState state, FileState fileState)
         {
             if (fileState != null)
@@ -175,7 +176,7 @@ namespace Pithos.Core.Agents
             }
         }
 
-        private void MoveChildObjects(WorkflowState state)
+        /*private void MoveChildObjects(WorkflowState state)
         {
             var oldFileState = StatusKeeper.GetStateByFilePath(state.OldPath);
             if (oldFileState != null)
@@ -198,7 +199,7 @@ namespace Pithos.Core.Agents
                                                           oldMoveInfo, newMoveInfo));
                 }
             }
-        }
+        }*/
 
 
         //Starts interrupted files for a specific account
index fa55ea1..6da39ba 100644 (file)
@@ -89,7 +89,7 @@ namespace Pithos.Network
             get { return _topHash.Value; }
         }
 
-        private IList<byte[]> _hashes;
+        private IList<byte[]> _hashes=new List<byte[]>();
 
         public IList<byte[]> Hashes
         {