Fixes to hashing
authorpkanavos <pkanavos@gmail.com>
Wed, 9 May 2012 19:41:52 +0000 (22:41 +0300)
committerpkanavos <pkanavos@gmail.com>
Wed, 9 May 2012 19:41:52 +0000 (22:41 +0300)
Fixes to selective sync

13 files changed:
trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs
trunk/Pithos.Core.Test/LocalFileComparerTest.cs
trunk/Pithos.Core/Agents/CloudTransferAction.cs
trunk/Pithos.Core/Agents/Downloader.cs
trunk/Pithos.Core/Agents/FileAgent.cs
trunk/Pithos.Core/Agents/PollAgent.cs
trunk/Pithos.Core/Agents/Uploader.cs
trunk/Pithos.Core/Agents/WorkflowAgent.cs
trunk/Pithos.Core/WorkflowState.cs
trunk/Pithos.Interfaces/ObjectInfo.cs
trunk/Pithos.Network/CloudFilesClient.cs
trunk/Pithos.Network/Signature.cs
trunk/Pithos.Network/TreeHash.cs

index c73c8ee..7966319 100644 (file)
@@ -125,6 +125,8 @@ namespace Pithos.Client.WPF {
            private readonly PollAgent _pollAgent;
            private readonly NetworkAgent _networkAgent;
 
+           [Import]
+           public Selectives Selectives { get; set; }
 
            private MiniStatusViewModel _miniStatus;
 
@@ -318,6 +320,8 @@ namespace Pithos.Client.WPF {
 
                            MigrateFolders(account);
 
+                           Selectives.SetIsSelectiveEnabled(account.AccountKey, account.SelectiveSyncEnabled);
+
                                if (Monitors.TryGetValue(account.AccountKey, out monitor))
                                {
                                        //If the account is active
@@ -1012,7 +1016,7 @@ namespace Pithos.Client.WPF {
                        PithosMonitor monitor;
                        if (Monitors.TryGetValue(message.Account.AccountKey, out monitor))
                        {
-                    monitor.Selectives.SetIsSelectiveEnabled(message.Account.AccountKey, message.Enabled);
+                    Selectives.SetIsSelectiveEnabled(message.Account.AccountKey, message.Enabled);
                            monitor.SetSelectivePaths(message.Uris, message.Added, message.Removed);
                        }
 
index a7db6a2..9126f8c 100644 (file)
@@ -16,8 +16,8 @@ namespace Pithos.Core.Test
         {
             var comparer = new LocalFileComparer();
             var account = new AccountInfo();
-            var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a"});
-            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", Hash = "a" });
+            var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a"},null);
+            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", Hash = "a" }, null);
             Assert.That(comparer.Equals(x, y), Is.True);
         }
 
@@ -26,8 +26,8 @@ namespace Pithos.Core.Test
         {
             var comparer = new LocalFileComparer();
             var account = new AccountInfo();
-            var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a"});
-            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a" });
+            var x = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "x", Hash = "a" }, null);
+            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a" }, null);
             Assert.That(comparer.Equals(x, y), Is.True);
         }
         [Test]
@@ -35,8 +35,8 @@ namespace Pithos.Core.Test
         {
             var comparer = new LocalFileComparer();
             var account = new AccountInfo();
-            var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a",Content_Type = "application/directory"});
-            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a", Content_Type = "application/directory" });
+            var x = new Agents.CloudDownloadAction(account, new ObjectInfo {Account="a",Container="c",Name = "x", Hash = "a",Content_Type = "application/directory"},null);
+            var y = new Agents.CloudDownloadAction(account, new ObjectInfo { Account = "a", Container = "c", Name = "y", Hash = "a", Content_Type = "application/directory" }, null);
             Assert.That(comparer.Equals(x, y), Is.False);
         }
 
index 8a81b1b..88ca6d5 100644 (file)
@@ -61,6 +61,8 @@ namespace Pithos.Core.Agents
 
     public class CloudAction
     {
+
+        public object Originator { get; set; }
         public AccountInfo AccountInfo { get; set; }
         public CloudActionType Action { get; set; }
         public FileSystemInfo LocalFile { get; set; }
@@ -86,7 +88,7 @@ namespace Pithos.Core.Agents
             get { return  CloudFile!=null && AccountInfo.UserName != CloudFile.Account; }
         }
 
-        protected CloudAction(AccountInfo accountInfo,CloudActionType action)
+        protected CloudAction(AccountInfo accountInfo,CloudActionType action,object originator)
         {
             if (accountInfo==null)
                 throw new ArgumentNullException("accountInfo");
@@ -94,10 +96,11 @@ namespace Pithos.Core.Agents
 
             Action = action;
             AccountInfo = accountInfo;
+            Originator = originator;
         }
 
-        public CloudAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo localFile, ObjectInfo cloudFile, FileState state, int blockSize, string algorithm)
-            : this(accountInfo,action)
+        public CloudAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo localFile, ObjectInfo cloudFile, FileState state, int blockSize, string algorithm,object originator)
+            : this(accountInfo,action,originator)
         {
             if(blockSize<=0)
                 throw new ArgumentOutOfRangeException("blockSize");
@@ -168,8 +171,8 @@ namespace Pithos.Core.Agents
 
     public class CloudDownloadAction:CloudAction
     {
-        public CloudDownloadAction(AccountInfo accountInfo, ObjectInfo cloudFile)
-            :base(accountInfo,CloudActionType.DownloadUnconditional)
+        public CloudDownloadAction(AccountInfo accountInfo, ObjectInfo cloudFile,object originator)
+            :base(accountInfo,CloudActionType.DownloadUnconditional,originator)
         {            
             if (String.IsNullOrWhiteSpace(cloudFile.Container))
                 throw new ArgumentException("CloudFile.Container","cloudFile");
@@ -192,13 +195,13 @@ namespace Pithos.Core.Agents
     }
     public class CloudDeleteAction:CloudAction
     {
-        public CloudDeleteAction(AccountInfo accountInfo,FileSystemInfo fileInfo, FileState fileState)
-            : this(accountInfo,fileInfo,CreateObjectInfoFor(accountInfo, fileInfo),fileState)
+        public CloudDeleteAction(AccountInfo accountInfo,FileSystemInfo fileInfo, FileState fileState,object originator)
+            : this(accountInfo,fileInfo,CreateObjectInfoFor(accountInfo, fileInfo),fileState,originator)
         {            
         }
 
-        public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState) 
-            : base(accountInfo,CloudActionType.DeleteCloud)
+        public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState,object originator) 
+            : base(accountInfo,CloudActionType.DeleteCloud,originator)
         {
             CloudFile = cloudFile;
             LocalFile = fileInfo;
@@ -206,7 +209,7 @@ namespace Pithos.Core.Agents
         }
 
         public CloudDeleteAction(CloudAction action)
-            : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState)
+            : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState,action)
         {}
 
         [ContractInvariantMethod]
@@ -224,8 +227,8 @@ namespace Pithos.Core.Agents
 
     public class CloudUploadAction:CloudAction
     {
-        public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm)
-            : base(accountInfo, CloudActionType.UploadUnconditional,fileInfo,CreateObjectInfoFor(accountInfo,fileInfo),state,blockSize,algorithm)             
+        public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm,object originator)
+            : base(accountInfo, CloudActionType.UploadUnconditional,fileInfo,CreateObjectInfoFor(accountInfo,fileInfo),state,blockSize,algorithm,originator)             
         {
         }
 
@@ -243,8 +246,8 @@ namespace Pithos.Core.Agents
 
         public FileSystemInfo OldLocalFile { get; set; }
 
-        public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile)
-            :base(accountInfo,action)
+        public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile,object originator)
+            :base(accountInfo,action,originator)
         {
             LocalFile = newFile;
             CloudFile = CreateObjectInfoFor(accountInfo, newFile);
index 1bc5332..5b76a74 100644 (file)
@@ -184,6 +184,7 @@ namespace Pithos.Core.Agents
                 if (!localHashes.ContainsKey(upHash))\r
                 {\r
                     StatusNotification.Notify(new CloudNotification { Data = cloudFile });\r
+                    ReportDownloadProgress(Path.GetFileName(localPath), i, upHashes.Length, cloudFile.Bytes);\r
 \r
                     if (blockUpdater.UseOrphan(i, upHash))\r
                     {\r
@@ -244,6 +245,7 @@ namespace Pithos.Core.Agents
             var localPath = FileInfoExtensions.GetProperFilePathCapitalization(filePath);\r
             StatusNotification.SetPithosStatus(PithosStatus.LocalSyncing, String.Format("Downloading {0}", Path.GetFileName(localPath)));\r
             StatusNotification.Notify(new CloudNotification { Data = cloudFile });\r
+            ReportDownloadProgress(Path.GetFileName(localPath), 1, 1, cloudFile.Bytes);\r
 \r
             var fileAgent = GetFileAgent(accountInfo);\r
             //Calculate the relative file path for the new file\r
index 7db1293..1d068a9 100644 (file)
@@ -94,7 +94,7 @@ namespace Pithos.Core.Agents
                     if (change.ChangeType == WatcherChangeTypes.Renamed)
                     {
                         var rename = (MovedEventArgs) change;
-                        _agent.Post(new WorkflowState
+                        _agent.Post(new WorkflowState(change)
                                         {
                                             AccountInfo = AccountInfo,
                                             OldPath = rename.OldFullPath,
@@ -105,7 +105,7 @@ namespace Pithos.Core.Agents
                                         });
                     }
                     else
-                        _agent.Post(new WorkflowState
+                        _agent.Post(new WorkflowState(change)
                         {
                             AccountInfo = AccountInfo,
                             Path = change.FullPath,
index 747fb52..63d5fd5 100644 (file)
@@ -507,13 +507,13 @@ namespace Pithos.Core.Agents
 \r
                         yield return new CloudAction(accountInfo, CloudActionType.MustSynch,\r
                                                      localFile, objectInfo, state, accountInfo.BlockSize,\r
-                                                     accountInfo.BlockHash);\r
+                                                     accountInfo.BlockHash,"Poll Changes");\r
                     }\r
                 }\r
                 else\r
                 {\r
                     //Remote files should be downloaded\r
-                    yield return new CloudDownloadAction(accountInfo, objectInfo);\r
+                    yield return new CloudDownloadAction(accountInfo, objectInfo,"Poll Changes");\r
                 }\r
             }\r
         }\r
@@ -548,17 +548,17 @@ namespace Pithos.Core.Agents
                         //For each moved object we need to move both the local file and update                                                \r
                         yield return new CloudAction(accountInfo, CloudActionType.RenameLocal,\r
                                                      previousFile, objectInfo, state, accountInfo.BlockSize,\r
-                                                     accountInfo.BlockHash);\r
+                                                     accountInfo.BlockHash,"Poll Moves");\r
                         //For modified files, we need to download the changes as well\r
                         if (objectInfo.Hash!=objectInfo.PreviousHash)\r
-                            yield return new CloudDownloadAction(accountInfo,objectInfo);\r
+                            yield return new CloudDownloadAction(accountInfo,objectInfo, "Poll Moves");\r
                     }\r
                 }\r
                 //If the previous file does not exist, we need to download it in the new location\r
                 else\r
                 {\r
                     //Remote files should be downloaded\r
-                    yield return new CloudDownloadAction(accountInfo, objectInfo);\r
+                    yield return new CloudDownloadAction(accountInfo, objectInfo, "Poll Moves");\r
                 }\r
             }\r
         }\r
@@ -593,12 +593,12 @@ namespace Pithos.Core.Agents
                     var state = StatusKeeper.GetStateByFilePath(localFile.WithProperCapitalization().FullName);\r
                     yield return new CloudAction(accountInfo, CloudActionType.MustSynch,\r
                                                      localFile, objectInfo, state, accountInfo.BlockSize,\r
-                                                     accountInfo.BlockHash);                    \r
+                                                     accountInfo.BlockHash,"Poll Creates");                    \r
                 }\r
                 else\r
                 {\r
                     //Remote files should be downloaded\r
-                    yield return new CloudDownloadAction(accountInfo, objectInfo);\r
+                    yield return new CloudDownloadAction(accountInfo, objectInfo,"Poll Creates");\r
                 }\r
 \r
             }\r
index 7ac3dd3..c6e7441 100644 (file)
@@ -7,6 +7,7 @@ using System.IO;
 using System.Linq;\r
 using System.Net;\r
 using System.Reflection;\r
+using System.Security.Cryptography;\r
 using System.Threading;\r
 using System.Threading.Tasks;\r
 using Pithos.Interfaces;\r
@@ -144,8 +145,10 @@ namespace Pithos.Core.Agents
                                     topHash = treeHash.TopHash.ToHashString();\r
                                 }\r
 \r
+\r
+\r
                                 //If the file hashes match, abort the upload\r
-                                if (cloudInfo != ObjectInfo.Empty && topHash == cloudHash)\r
+                                if (cloudInfo != ObjectInfo.Empty && (topHash == cloudHash ))\r
                                 {\r
                                     //but store any metadata changes \r
                                     StatusKeeper.StoreInfo(fullFileName, cloudInfo);\r
index b286e56..b2c3b51 100644 (file)
@@ -134,11 +134,11 @@ namespace Pithos.Core.Agents
                             case FileStatus.Modified:
                                 NetworkAgent.Post(new CloudUploadAction(accountInfo, info, fileState,
                                                                         accountInfo.BlockSize,
-                                                                        accountInfo.BlockHash));
+                                                                        accountInfo.BlockHash,state));
                                 break;
                             case FileStatus.Deleted:
                                 DeleteChildObjects(state, fileState);
-                                NetworkAgent.Post(new CloudDeleteAction(accountInfo, info, fileState));
+                                NetworkAgent.Post(new CloudDeleteAction(accountInfo, info, fileState,state));
                                 break;
                             case FileStatus.Renamed:
                                 if (state.OldPath == null)
@@ -156,7 +156,7 @@ namespace Pithos.Core.Agents
                                                              : new FileInfo(state.Path);
                                 NetworkAgent.Post(new CloudMoveAction(accountInfo, CloudActionType.RenameCloud,
                                                                       oldInfo,
-                                                                      newInfo));                                
+                                                                      newInfo,state));                                
                                 //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);
@@ -185,7 +185,7 @@ namespace Pithos.Core.Agents
                     var childInfo = child.IsFolder
                                         ? (FileSystemInfo) new DirectoryInfo(child.FilePath)
                                         : new FileInfo(child.FilePath);
-                    NetworkAgent.Post(new CloudDeleteAction(state.AccountInfo, childInfo, child));
+                    NetworkAgent.Post(new CloudDeleteAction(state.AccountInfo, childInfo, child,state));
                 }
             }
         }
index 68b799e..99943aa 100644 (file)
@@ -52,6 +52,7 @@ namespace Pithos.Core
 {
     public class WorkflowState
     {
+        public object Originator { get; set; }
         public AccountInfo AccountInfo { get; set; }
 
         public string Path { get; set; }
@@ -76,9 +77,9 @@ namespace Pithos.Core
         }
 */
 
-        public WorkflowState()
+        public WorkflowState(object originator)
         {
-            
+            Originator = originator;
         }
 
         public WorkflowState(AccountInfo accountInfo, FileState state)
@@ -89,6 +90,7 @@ namespace Pithos.Core
                 throw new ArgumentNullException("state");
             Contract.EndContractBlock();
 
+            Originator = "Restart";
             AccountInfo = accountInfo;
             Path = state.FilePath.ToLower();
             FileName = System.IO.Path.GetFileName(state.FilePath).ToLower();
index cccd13a..7301002 100644 (file)
@@ -57,8 +57,9 @@ namespace Pithos.Interfaces
     {
         private readonly List<string> _knownContainers= new List<string>{"trash"};
         public string Name { get; set; }
-        
-        
+
+        public string ETag { get; set; }
+
         public string Hash { get; set; }
 
         public string X_Object_Hash { get { return Hash; } set { Hash = value; } }
index 48ed896..2b11626 100644 (file)
@@ -788,7 +788,8 @@ namespace Pithos.Network
                                                    Account = account,
                                                    Container = container,
                                                    Name = objectName,
-                                                   Hash = client.GetHeaderValue("ETag"),
+                                                   ETag = client.GetHeaderValue("ETag"),
+                                                   X_Object_Hash = client.GetHeaderValue("X-Object-Hash"),
                                                    Content_Type = client.GetHeaderValue("Content-Type"),
                                                    Bytes = Convert.ToInt64(client.GetHeaderValue("Content-Length",true)),
                                                    Tags = tags,
index c8faac8..389dd79 100644 (file)
@@ -204,9 +204,14 @@ namespace Pithos.Network
                 {
                     Bytes = length,
                     BlockSize = blockSize,
-                    Hashes = list
+                    Hashes = list,
                 };
 
+                string fileHash;
+                var hasher = HashAlgorithm.Create("MD5");
+                stream.Position = 0;
+                treeHash.MD5= hasher.ComputeHash(stream).ToHashString();
+
                 return treeHash;
             }
         }
index fe90121..ecd26e1 100644 (file)
@@ -172,6 +172,8 @@ namespace Pithos.Network
             }
         }
 
+        public string MD5 { get; set; }
+
         //Saves the Json representation to a file
         public async Task Save(string filePath)
         {