Synch seems OK. Identified problem with poll differencer
[pithos-ms-client] / trunk / Pithos.Core / Agents / FileAgent.cs
index 8f2d585..5f001e3 100644 (file)
@@ -1,4 +1,45 @@
-using System;
+#region
+/* -----------------------------------------------------------------------
+ * <copyright file="FileAgent.cs" company="GRNet">
+ * 
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials
+ *      provided with the distribution.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either expressed
+ * or implied, of GRNET S.A.
+ * </copyright>
+ * -----------------------------------------------------------------------
+ */
+#endregion
+using System;
 using System.Collections.Generic;
 using System.ComponentModel.Composition;
 using System.Diagnostics;
@@ -63,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));
                 };
@@ -191,19 +231,88 @@ namespace Pithos.Core.Agents
             return monitoredFiles;
         }                
 
+        public IEnumerable<string> EnumerateFilesSystemInfosAsRelativeUrls(string searchPattern="*")
+        {
+            var rootDir = new DirectoryInfo(RootPath);
+            var monitoredFiles = from file in rootDir.EnumerateFileSystemInfos(searchPattern, SearchOption.AllDirectories)
+                                 where !Ignore(file.FullName)
+                                 select file.AsRelativeUrlTo(RootPath);
+            return monitoredFiles;
+        }                
+
 
         
 
         private bool Ignore(string filePath)
         {
-            var pithosPath = Path.Combine(RootPath, "pithos");
-            if (pithosPath.Equals(filePath, StringComparison.InvariantCultureIgnoreCase))
+            //Ignore all first-level directories and files (ie at the container folders level)
+            if (FoundBelowRoot(filePath, RootPath,1))
                 return true;
+
+            //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;
+
+            //Ignore second-level (container) folders under the "others" folder (ie at the container folders level). 
+            if (FoundBelowRoot(filePath, othersPath,2))
+                return true;            
+
+
+            //Ignore anything happening in the cache path
             if (filePath.StartsWith(CachePath))
                 return true;
             if (_ignoreFiles.ContainsKey(filePath.ToLower()))
                 return true;
-            return false;
+
+            //Ignore if selective synchronization is defined, 
+            return SelectivePaths.Count > 0 
+                //And the target file is not below any of the selective paths
+                && !SelectivePaths.Any(filePath.IsAtOrDirectlyBelow);
+        }
+
+/*        private static bool FoundInRoot(string filePath, string rootPath)
+        {
+            //var rootDirectory = new DirectoryInfo(rootPath);
+
+            //If the paths are equal, return true
+            if (filePath.Equals(rootPath, StringComparison.InvariantCultureIgnoreCase))
+                return true;
+
+            //If the filepath is below the root path
+            if (filePath.StartsWith(rootPath,StringComparison.InvariantCulture))
+            {
+                //Get the relative path
+                var relativePath = filePath.Substring(rootPath.Length + 1);
+                //If the relativePath does NOT contains a path separator, we found a match
+                return (!relativePath.Contains(@"\"));
+            }
+
+            //If the filepath is not under the root path, return false
+            return false;            
+        }*/
+
+
+        private static bool FoundBelowRoot(string filePath, string rootPath,int level)
+        {
+            //var rootDirectory = new DirectoryInfo(rootPath);
+
+            //If the paths are equal, return true
+            if (filePath.Equals(rootPath, StringComparison.InvariantCultureIgnoreCase))
+                return true;
+
+            //If the filepath is below the root path
+            if (filePath.StartsWith(rootPath,StringComparison.InvariantCulture))
+            {
+                //Get the relative path
+                var relativePath = filePath.Substring(rootPath.Length + 1);
+                //If the relativePath does NOT contains a path separator, we found a match
+                var levels=relativePath.ToCharArray().Count(c=>c=='\\')+1;                
+                return levels==level;
+            }
+
+            //If the filepath is not under the root path, return false
+            return false;            
         }
 
         //Post a Change message for all events except rename
@@ -259,14 +368,14 @@ namespace Pithos.Core.Agents
 
 
         private Dictionary<WatcherChangeTypes, FileStatus> _statusDict = new Dictionary<WatcherChangeTypes, FileStatus>
-        {
+                                                                             {
             {WatcherChangeTypes.Created,FileStatus.Created},
             {WatcherChangeTypes.Changed,FileStatus.Modified},
             {WatcherChangeTypes.Deleted,FileStatus.Deleted},
             {WatcherChangeTypes.Renamed,FileStatus.Renamed}
         };
 
-        private Dictionary<string,string> _ignoreFiles=new Dictionary<string, string>();
+        private Dictionary<string, string> _ignoreFiles=new Dictionary<string, string>();
 
         private WorkflowState UpdateFileStatus(WorkflowState state)
         {
@@ -369,6 +478,17 @@ namespace Pithos.Core.Agents
             return false;
         }
 
+        public static FileAgent GetFileAgent(AccountInfo accountInfo)
+        {
+            return GetFileAgent(accountInfo.AccountPath);
+        }
+
+        public static FileAgent GetFileAgent(string rootPath)
+        {
+            return AgentLocator<FileAgent>.Get(rootPath.ToLower());
+        }
+
+
         public FileSystemInfo GetFileSystemInfo(string relativePath)
         {
             if (String.IsNullOrWhiteSpace(relativePath))