Fixed uploads of shared files. Added check for unauthorized additions to "others...
authorPanagiotis Kanavos <pkanavos@gmail.com>
Tue, 18 Oct 2011 20:08:48 +0000 (23:08 +0300)
committerPanagiotis Kanavos <pkanavos@gmail.com>
Tue, 18 Oct 2011 20:08:48 +0000 (23:08 +0300)
trunk/Pithos.Core.Test/NetworkAgentTest.cs
trunk/Pithos.Core/Agents/CloudTransferAction.cs
trunk/Pithos.Core/Agents/FileAgent.cs
trunk/Pithos.Core/Agents/NetworkAgent.cs
trunk/Pithos.Core/Agents/WorkflowAgent.cs
trunk/Pithos.Core/WorkflowState.cs
trunk/Pithos.Network/FolderConstants.cs
trunk/Pithos.Network/RestClient.cs

index 66e041f..4889515 100644 (file)
@@ -6,6 +6,7 @@ using System.Text;
 using System.Threading.Tasks;
 using NUnit.Framework;
 using Pithos.Core.Agents;
+using Pithos.Interfaces;
 using Pithos.Network;
 
 namespace Pithos.Core.Test
@@ -50,7 +51,10 @@ namespace Pithos.Core.Test
             client.DeleteObject(null, FolderConstants.PithosContainer, fileName);
 
             var task = Signature.CalculateTreeHashAsync(filePath, accountInfo.BlockSize, accountInfo.BlockHash);
-            var tasks=agent.UploadWithHashMap(accountInfo,account,"pithos",new FileInfo(filePath),fileName,task);
+            var cloudFile = new ObjectInfo {Account = account, Container = "pithos"};
+            var fileInfo = new FileInfo(filePath);
+
+            var tasks=agent.UploadWithHashMap(accountInfo,cloudFile,fileInfo,fileName,task);
             Task.Factory.Iterate(tasks).Wait();
 
             var newHash = client.GetHashMap(null, FolderConstants.PithosContainer, fileName).Result;
@@ -86,8 +90,10 @@ namespace Pithos.Core.Test
             if (File.Exists(filePath))
                 File.Delete(filePath);
 
+            var cloudFile = new ObjectInfo {Account = account, Container = FolderConstants.PithosContainer};
+
             var newHash = client.GetHashMap(null, FolderConstants.PithosContainer, fileName).Result;
-            agent.DownloadWithBlocks(accountInfo, client, account, FolderConstants.PithosContainer, new Uri(fileName, UriKind.Relative), filePath, newHash)
+            agent.DownloadWithBlocks(accountInfo, client, cloudFile, new Uri(fileName, UriKind.Relative), filePath, newHash)
                 .Wait();
 
             Assert.IsTrue(File.Exists(filePath));
index 14c510f..1468504 100644 (file)
@@ -65,8 +65,14 @@ namespace Pithos.Core.Agents
             }
         }
 
-
-
+        //Calculate the download path for the cloud file
+        public string GetDownloadPath()
+        {
+            if (CloudFile == null)
+                return String.Empty;
+            var filePath = CloudFile.RelativeUrlToFilePath(AccountInfo.UserName);
+            return Path.Combine(AccountInfo.AccountPath, filePath);
+        }
     }    
 
     public class CloudDownloadAction:CloudAction
@@ -91,6 +97,10 @@ namespace Pithos.Core.Agents
             CloudFile = cloudFile;
             FileState = fileState;
         }
+
+        public CloudDeleteAction(CloudAction action)
+            : this(action.AccountInfo,action.CloudFile,action.FileState)
+        {}
     }
 
     public class CloudUploadAction:CloudAction
index d70d372..ef24ba2 100644 (file)
@@ -213,8 +213,9 @@ namespace Pithos.Core.Agents
             //Ignore events that affect the Fragments folder
             var filePath = e.FullPath;
             if (Ignore(filePath)) 
-                return;
-            _agent.Post(new WorkflowState(AccountInfo) { Path = filePath, FileName = e.Name, TriggeringChange = e.ChangeType });
+                return;           
+            
+            _agent.Post(new WorkflowState{AccountInfo=AccountInfo, Path = filePath, FileName = e.Name, TriggeringChange = e.ChangeType });
         }
 
 
@@ -226,8 +227,9 @@ namespace Pithos.Core.Agents
             if (Ignore(oldFullPath) || Ignore(fullPath))
                 return;
 
-            _agent.Post(new WorkflowState(AccountInfo)
+            _agent.Post(new WorkflowState
             {
+                AccountInfo=AccountInfo,
                 OldPath = oldFullPath,
                 OldFileName = e.OldName,
                 Path = fullPath,
index aa087af..1a4db48 100644 (file)
@@ -81,39 +81,33 @@ namespace Pithos.Core.Agents
                                action.CloudFile.Name);
 
                 var localFile = action.LocalFile;
-                var cloudFile = action.CloudFile;                
-                var downloadPath = (cloudFile == null)
-                                       ? String.Empty
-                                       : Path.Combine(accountInfo.AccountPath, cloudFile.RelativeUrlToFilePath(accountInfo.UserName));
+                var cloudFile = action.CloudFile;
+                var downloadPath = action.GetDownloadPath();
 
                 try
                 {
-                    var account = action.CloudFile.Account ?? accountInfo.UserName;
-                    var container = action.CloudFile.Container ?? FolderConstants.PithosContainer;
 
                     switch (action.Action)
                     {
                         case CloudActionType.UploadUnconditional:
-                            UploadCloudFile(accountInfo,account, container, localFile, action.LocalHash.Value, action.TopHash.Value);
+                            UploadCloudFile(action);
                             break;
                         case CloudActionType.DownloadUnconditional:
 
-                            DownloadCloudFile(accountInfo, account, container, cloudFile,
-                                              downloadPath);
+                            DownloadCloudFile(accountInfo,  cloudFile,downloadPath);
                             break;
                         case CloudActionType.DeleteCloud:
-                            DeleteCloudFile(accountInfo, account, container, cloudFile.Name);
+                            DeleteCloudFile(accountInfo, cloudFile, cloudFile.Name);
                             break;
                         case CloudActionType.RenameCloud:
                             var moveAction = (CloudMoveAction)action;
-                            RenameCloudFile(accountInfo, account, container, moveAction.OldFileName, moveAction.NewPath,
-                                            moveAction.NewFileName);
+                            RenameCloudFile(accountInfo, cloudFile, moveAction);
                             break;
                         case CloudActionType.MustSynch:
 
                             if (!File.Exists(downloadPath))
                             {                                
-                                DownloadCloudFile(accountInfo, account, container, cloudFile, downloadPath);
+                                DownloadCloudFile(accountInfo, cloudFile, downloadPath);
                             }
                             else
                             {
@@ -132,7 +126,8 @@ namespace Pithos.Core.Agents
                 {
                     Log.ErrorFormat("{0} : {1} -> {2}  failed because the file was not found.\n Rescheduling a delete",
                         action.Action, action.LocalFile, action.CloudFile, exc);
-                    Post(new CloudDeleteAction(accountInfo,action.CloudFile,action.FileState));
+                    //Post a delete action for the missing file
+                    Post(new CloudDeleteAction(action));
                 }
                 catch (Exception exc)
                 {
@@ -163,11 +158,6 @@ namespace Pithos.Core.Agents
             var cloudFile = action.CloudFile;
             var downloadPath=action.LocalFile.FullName.ToLower();
 
-            var account = cloudFile.Account;
-            //Use "pithos" by default if no container is specified
-            var container = cloudFile.Container ?? FolderConstants.PithosContainer;
-
-            var cloudUri = new Uri(cloudFile.Name, UriKind.Relative);
             var cloudHash = cloudFile.Hash.ToLower();
             var localHash = action.LocalHash.Value.ToLower();
             var topHash = action.TopHash.Value.ToLower();
@@ -189,8 +179,7 @@ namespace Pithos.Core.Agents
             if (lastUpTime <= lastLocalTime)
             {
                 //It probably means it was changed while the app was down                        
-                UploadCloudFile(accountInfo,account, container, localFile, action.LocalHash.Value,
-                                action.TopHash.Value);
+                UploadCloudFile(action);
             }
             else
             {
@@ -201,7 +190,7 @@ namespace Pithos.Core.Agents
                 {
                     case FileStatus.Unchanged:                        
                         //If the local file's status is Unchanged, we can go on and download the newer cloud file
-                        DownloadCloudFile(accountInfo,account, container,cloudFile,downloadPath);
+                        DownloadCloudFile(accountInfo,cloudFile,downloadPath);
                         break;
                     case FileStatus.Modified:
                         //If the local file is Modified, we may have a conflict. In this case we should mark the file as Conflict
@@ -236,36 +225,6 @@ namespace Pithos.Core.Agents
             StatusNotification.NotifyChange(message, TraceLevel.Warning);
         }
 
-/*
-        private Task<object> Process(CloudMoveAction action)
-        {
-            if (action == null)
-                throw new ArgumentNullException("action");
-            Contract.EndContractBlock();
-
-            Log.InfoFormat("[ACTION] Start Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
-
-            try
-            {
-                RenameCloudFile(action.OldFileName, action.NewPath, action.NewFileName);
-                Log.InfoFormat("[ACTION] End Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
-            }
-            catch (OperationCanceledException)
-            {
-                throw;
-            }
-            catch (Exception exc)
-            {
-                Log.ErrorFormat("[REQUEUE] {0} : {1} -> {2} due to exception\r\n{3}",
-                                action.Action, action.OldFileName, action.NewFileName, exc);
-
-                _agent.Post(action);
-            }
-            return CompletedTask<object>.Default;
-        }
-*/
-
-
         public void Post(CloudAction cloudAction)
         {
             if (cloudAction == null)
@@ -492,42 +451,36 @@ namespace Pithos.Core.Agents
         }
 
 
-        private void RenameCloudFile(AccountInfo accountInfo,string account, string container,string oldFileName, string newPath, string newFileName)
+        private void RenameCloudFile(AccountInfo accountInfo,ObjectInfo cloudFile,CloudMoveAction action)
         {
             if (accountInfo==null)
                 throw new ArgumentNullException("accountInfo");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
-            if (String.IsNullOrWhiteSpace(oldFileName))
-                throw new ArgumentNullException("oldFileName");
-            if (String.IsNullOrWhiteSpace(oldFileName))
-                throw new ArgumentNullException("newPath");
-            if (String.IsNullOrWhiteSpace(oldFileName))
-                throw new ArgumentNullException("newFileName");
+            if (cloudFile==null)
+                throw new ArgumentNullException("cloudFile");
+            if (action==null)
+                throw new ArgumentNullException("action");
             Contract.EndContractBlock();
             //The local file is already renamed
-            this.StatusKeeper.SetFileOverlayStatus(newPath, FileOverlayStatus.Modified);
+            this.StatusKeeper.SetFileOverlayStatus(action.NewPath, FileOverlayStatus.Modified);
 
+
+            var account = action.CloudFile.Account ?? accountInfo.UserName;
+            var container = action.CloudFile.Container ?? FolderConstants.PithosContainer;
+            
             var client = new CloudFilesClient(accountInfo);
-            client.MoveObject(account, container, oldFileName, container, newFileName);
+            client.MoveObject(account, container, action.OldFileName, container, action.NewFileName);
 
-            this.StatusKeeper.SetFileStatus(newPath, FileStatus.Unchanged);
-            this.StatusKeeper.SetFileOverlayStatus(newPath, FileOverlayStatus.Normal);
-            NativeMethods.RaiseChangeNotification(newPath);
+            this.StatusKeeper.SetFileStatus(action.NewPath, FileStatus.Unchanged);
+            this.StatusKeeper.SetFileOverlayStatus(action.NewPath, FileOverlayStatus.Normal);
+            NativeMethods.RaiseChangeNotification(action.NewPath);
         }
 
-        private void DeleteCloudFile(AccountInfo accountInfo, string account, string container, string fileName)
+        private void DeleteCloudFile(AccountInfo accountInfo, ObjectInfo cloudFile,string fileName)
         {
             if (accountInfo == null)
                 throw new ArgumentNullException("accountInfo");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
+            if (cloudFile==null)
+                throw new ArgumentNullException("cloudFile");
 
             if (String.IsNullOrWhiteSpace(fileName))
                 throw new ArgumentNullException("fileName");
@@ -543,6 +496,9 @@ namespace Pithos.Core.Agents
                 var fullPath = info.FullName.ToLower();
                 this.StatusKeeper.SetFileOverlayStatus(fullPath, FileOverlayStatus.Modified);
 
+                var account = cloudFile.Account ?? accountInfo.UserName;
+                var container = cloudFile.Container ?? FolderConstants.PithosContainer;
+
                 var client = new CloudFilesClient(accountInfo);
                 client.DeleteObject(account, container, fileName);
 
@@ -551,38 +507,35 @@ namespace Pithos.Core.Agents
         }
 
         //Download a file.
-        private void DownloadCloudFile(AccountInfo accountInfo, string account, string container,ObjectInfo cloudFile , string localPath)
+        private void DownloadCloudFile(AccountInfo accountInfo, ObjectInfo cloudFile , string localPath)
         {
             if (accountInfo == null)
                 throw new ArgumentNullException("accountInfo");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
             if (cloudFile == null)
                 throw new ArgumentNullException("cloudFile");
+            if (String.IsNullOrWhiteSpace(cloudFile.Account))
+                throw new ArgumentNullException("cloudFile");
+            if (String.IsNullOrWhiteSpace(cloudFile.Container))
+                throw new ArgumentNullException("cloudFile");
             if (String.IsNullOrWhiteSpace(localPath))
                 throw new ArgumentNullException("localPath");
             if (!Path.IsPathRooted(localPath))
                 throw new ArgumentException("The localPath must be rooted", "localPath");
             Contract.EndContractBlock();
             
-            Debug.Assert(cloudFile.Account==account);
-            Debug.Assert(cloudFile.Container == container);
-
-            var download=Task.Factory.Iterate(DownloadIterator(accountInfo,account,container, cloudFile, localPath));
+            var download=Task.Factory.Iterate(DownloadIterator(accountInfo,cloudFile, localPath));
             download.Wait();
         }
 
-        private IEnumerable<Task> DownloadIterator(AccountInfo accountInfo, string account, string container, ObjectInfo cloudFile, string localPath)
+        private IEnumerable<Task> DownloadIterator(AccountInfo accountInfo,ObjectInfo cloudFile, string localPath)
         {
             if (accountInfo == null)
                 throw new ArgumentNullException("accountInfo");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
-            if (cloudFile==null)
+            if (cloudFile == null)
+                throw new ArgumentNullException("cloudFile");
+            if (String.IsNullOrWhiteSpace(cloudFile.Account))
+                throw new ArgumentNullException("cloudFile");
+            if (String.IsNullOrWhiteSpace(cloudFile.Container))
                 throw new ArgumentNullException("cloudFile");
             if (String.IsNullOrWhiteSpace(localPath))
                 throw new ArgumentNullException("localPath");
@@ -605,6 +558,9 @@ namespace Pithos.Core.Agents
                 //var hashPath = Path.Combine(FileAgent.FragmentsPath, relativePath + ".hashmap");
                 
                 var client = new CloudFilesClient(accountInfo);
+                var account = cloudFile.Account;
+                var container = cloudFile.Container;
+
                 //Retrieve the hashmap from the server
                 var getHashMap = client.GetHashMap(account, container, url);
                 yield return getHashMap;
@@ -613,9 +569,9 @@ namespace Pithos.Core.Agents
                 //If it's a small file
                 var downloadTask=(serverHash.Hashes.Count == 1 )
                     //Download it in one go
-                    ? DownloadEntireFile(accountInfo,client, account, container, relativeUrl, localPath,serverHash) 
+                    ? DownloadEntireFile(accountInfo,client, cloudFile, relativeUrl, localPath, serverHash) 
                     //Otherwise download it block by block
-                    : DownloadWithBlocks(accountInfo,client, account, container, relativeUrl, localPath, serverHash);
+                    : DownloadWithBlocks(accountInfo,client, cloudFile, relativeUrl, localPath, serverHash);
 
                 yield return downloadTask;
 
@@ -624,11 +580,9 @@ namespace Pithos.Core.Agents
                     var attributes=File.GetAttributes(localPath);
                     File.SetAttributes(localPath,attributes|FileAttributes.ReadOnly);
                 }
-                //Retrieve the object's metadata
-                var info=client.GetObjectInfo(account, container, url);
-                Debug.Assert(cloudFile==info);
-                //And store it
-                StatusKeeper.StoreInfo(localPath, info);
+                
+                //Now we can store the object's metadata without worrying about ghost status entries
+                StatusKeeper.StoreInfo(localPath, cloudFile);
                 
                 //Notify listeners that a local file has changed
                 StatusNotification.NotifyChangedFile(localPath);
@@ -637,14 +591,12 @@ namespace Pithos.Core.Agents
         }
 
         //Download a small file with a single GET operation
-        private Task DownloadEntireFile(AccountInfo accountInfo, CloudFilesClient client, string account, string container, Uri relativeUrl, string localPath,TreeHash serverHash)
+        private Task DownloadEntireFile(AccountInfo accountInfo, CloudFilesClient client, ObjectInfo cloudFile, Uri relativeUrl, string localPath,TreeHash serverHash)
         {
             if (client == null)
                 throw new ArgumentNullException("client");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
+            if (cloudFile==null)
+                throw new ArgumentNullException("cloudFile");
             if (relativeUrl == null)
                 throw new ArgumentNullException("relativeUrl");
             if (String.IsNullOrWhiteSpace(localPath))
@@ -679,7 +631,7 @@ namespace Pithos.Core.Agents
                 Directory.CreateDirectory(tempFolder);
 
             //Download the object to the temporary location
-            var getObject = client.GetObject(account, container, relativeUrl.ToString(), tempPath).ContinueWith(t =>
+            var getObject = client.GetObject(cloudFile.Account, cloudFile.Container, relativeUrl.ToString(), tempPath).ContinueWith(t =>
             {
                 t.PropagateExceptions();
                 //Create the local folder if it doesn't exist (necessary for shared objects)
@@ -696,14 +648,12 @@ namespace Pithos.Core.Agents
         }
 
         //Download a file asynchronously using blocks
-        public Task DownloadWithBlocks(AccountInfo accountInfo, CloudFilesClient client, string account, string container, Uri relativeUrl, string localPath, TreeHash serverHash)
+        public Task DownloadWithBlocks(AccountInfo accountInfo, CloudFilesClient client, ObjectInfo cloudFile, Uri relativeUrl, string localPath, TreeHash serverHash)
         {
             if (client == null)
                 throw new ArgumentNullException("client");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
+            if (cloudFile == null)
+                throw new ArgumentNullException("cloudFile");
             if (relativeUrl == null)
                 throw new ArgumentNullException("relativeUrl");
             if (String.IsNullOrWhiteSpace(localPath))
@@ -714,17 +664,15 @@ namespace Pithos.Core.Agents
                 throw new ArgumentNullException("serverHash");
             Contract.EndContractBlock();
             
-            return Task.Factory.Iterate(BlockDownloadIterator(accountInfo,client,account,container, relativeUrl, localPath, serverHash));
+            return Task.Factory.Iterate(BlockDownloadIterator(accountInfo,client,cloudFile, relativeUrl, localPath, serverHash));
         }
 
-        private IEnumerable<Task> BlockDownloadIterator(AccountInfo accountInfo,CloudFilesClient client, string account, string container, Uri relativeUrl, string localPath, TreeHash serverHash)
+        private IEnumerable<Task> BlockDownloadIterator(AccountInfo accountInfo,CloudFilesClient client,  ObjectInfo cloudFile, Uri relativeUrl, string localPath, TreeHash serverHash)
         {
             if (client == null)
                 throw new ArgumentNullException("client");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
+            if (cloudFile==null)
+                throw new ArgumentNullException("cloudFile");
             if (relativeUrl == null)
                 throw new ArgumentNullException("relativeUrl");
             if (String.IsNullOrWhiteSpace(localPath))
@@ -770,7 +718,7 @@ namespace Pithos.Core.Agents
                         end= ((i + 1)*serverHash.BlockSize) ;
                             
                     //Download the missing block
-                    var getBlock = client.GetBlock(account, container, relativeUrl, start, end);
+                    var getBlock = client.GetBlock(cloudFile.Account, cloudFile.Container, relativeUrl, start, end);
                     yield return getBlock;
                     var block = getBlock.Result;
 
@@ -787,47 +735,76 @@ namespace Pithos.Core.Agents
         }
 
 
-        private void UploadCloudFile(AccountInfo accountInfo, string account, string container, FileInfo fileInfo, string hash, string topHash)
+        private void UploadCloudFile(CloudAction action)
         {
-            if (accountInfo == null)
-                throw new ArgumentNullException("accountInfo");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
-            if (fileInfo == null)
-                throw new ArgumentNullException("fileInfo");
-            if (String.IsNullOrWhiteSpace(hash))
-                throw new ArgumentNullException("hash");
-            if (topHash == null)
-                throw new ArgumentNullException("topHash");
+            if (action == null)
+                throw new ArgumentNullException("action");           
             Contract.EndContractBlock();
 
-            var upload = Task.Factory.Iterate(UploadIterator(accountInfo,account,container,fileInfo, hash.ToLower(), topHash.ToLower()));
-            upload.Wait();
+            try
+            {
+                var upload = Task.Factory.Iterate(UploadIterator(action));
+                upload.Wait();
+            }                
+            catch (AggregateException ex)
+            {                
+                var exc = ex.InnerException as WebException;
+                if (exc==null)
+                    throw ex.InnerException;
+                var response = exc.Response as HttpWebResponse;
+                if (response==null)
+                    throw exc;
+                if (response.StatusCode == HttpStatusCode.Unauthorized)
+                {
+                    Log.Error("Not allowed to upload file", exc);
+                    var message = String.Format("Not allowed to uplad file {0}",action.LocalFile.FullName);
+                    StatusKeeper.SetFileState(action.LocalFile.FullName,FileStatus.Unchanged,FileOverlayStatus.Normal);
+                    StatusNotification.NotifyChange(message,TraceLevel.Warning);
+                    return;
+                }
+                throw;
+            }
         }
 
-        private IEnumerable<Task> UploadIterator(AccountInfo accountInfo, string account, string container, FileInfo fileInfo, string hash, string topHash)
+        private IEnumerable<Task> UploadIterator(CloudAction action)
         {
-            if (accountInfo == null)
-                throw new ArgumentNullException("accountInfo");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
-            if (fileInfo == null)
-                throw new ArgumentNullException("fileInfo");
-            if (String.IsNullOrWhiteSpace(hash))
-                throw new ArgumentNullException("hash");
-            if (topHash == null)
-                throw new ArgumentNullException("topHash");
+            if (action == null)
+                throw new ArgumentNullException("action");            
             Contract.EndContractBlock();
 
+            var accountInfo=action.AccountInfo;
+            
+            var fileInfo=action.LocalFile;                        
+
             if (fileInfo.Extension.Equals("ignore", StringComparison.InvariantCultureIgnoreCase))
                 yield break;
-            
+
+            var relativePath = fileInfo.AsRelativeTo(accountInfo.AccountPath);
+            if (relativePath.StartsWith(FolderConstants.OthersFolder))
+            {
+                var parts=relativePath.Split('\\');
+                var accountName = parts[1];
+                var oldName = accountInfo.UserName;
+                   var absoluteUri = accountInfo.StorageUri.AbsoluteUri;
+                var nameIndex=absoluteUri.IndexOf(oldName);
+                var root=absoluteUri.Substring(0, nameIndex);
+
+                accountInfo = new AccountInfo
+                {
+                    UserName = accountName,
+                    AccountPath = Path.Combine(accountInfo.AccountPath, parts[0], parts[1]),
+                    StorageUri = new Uri(root + accountName),
+                    BlockHash=accountInfo.BlockHash,
+                    BlockSize=accountInfo.BlockSize,
+                    Token=accountInfo.Token
+                };
+            }
+
+
             var url = fileInfo.AsRelativeUrlTo(accountInfo.AccountPath);
 
+            
+
             var fullFileName = fileInfo.FullName;
             using(var gate=NetworkGate.Acquire(fullFileName,NetworkOperation.Uploading))
             {
@@ -835,11 +812,18 @@ namespace Pithos.Core.Agents
                 if (gate.Failed)
                     yield break;
 
+                var cloudFile = action.CloudFile;
+                var account = cloudFile.Account ?? accountInfo.UserName;
+                var container = cloudFile.Container ?? FolderConstants.PithosContainer;
+
                 var client = new CloudFilesClient(accountInfo);
                 //Even if GetObjectInfo times out, we can proceed with the upload            
-                var info = client.GetObjectInfo(account, container, url);
+                var info = client.GetObjectInfo(account, container, url);                
                 var cloudHash = info.Hash.ToLower();
 
+                var hash = action.LocalHash.Value;
+                var topHash = action.TopHash.Value;
+
                 //If the file hashes match, abort the upload
                 if (hash == cloudHash  || topHash ==cloudHash)
                 {
@@ -865,7 +849,7 @@ namespace Pithos.Core.Agents
                         accountInfo.BlockHash);
                     yield return treeHash;
                     
-                    yield return Task.Factory.Iterate(UploadWithHashMap(accountInfo,account,container,fileInfo,url,treeHash));
+                    yield return Task.Factory.Iterate(UploadWithHashMap(accountInfo,cloudFile,fileInfo,url,treeHash));
                                         
                 }
                 else
@@ -881,14 +865,12 @@ namespace Pithos.Core.Agents
             StatusNotification.NotifyChangedFile(fullFileName);
         }
 
-        public IEnumerable<Task> UploadWithHashMap(AccountInfo accountInfo,string account,string container,FileInfo fileInfo,string url,Task<TreeHash> treeHash)
+        public IEnumerable<Task> UploadWithHashMap(AccountInfo accountInfo,ObjectInfo cloudFile,FileInfo fileInfo,string url,Task<TreeHash> treeHash)
         {
             if (accountInfo == null)
                 throw new ArgumentNullException("accountInfo");
-            if (String.IsNullOrWhiteSpace(account))
-                throw new ArgumentNullException("account");
-            if (String.IsNullOrWhiteSpace(container))
-                throw new ArgumentNullException("container");
+            if (cloudFile==null)
+                throw new ArgumentNullException("cloudFile");
             if (fileInfo == null)
                 throw new ArgumentNullException("fileInfo");
             if (String.IsNullOrWhiteSpace(url))
@@ -899,6 +881,9 @@ namespace Pithos.Core.Agents
 
             var fullFileName = fileInfo.FullName;
 
+            var account = cloudFile.Account ?? accountInfo.UserName;
+            var container = cloudFile.Container ?? FolderConstants.PithosContainer;
+
             var client = new CloudFilesClient(accountInfo);
             //Send the hashmap to the server            
             var hashPut = client.PutHashMap(account, container, url, treeHash.Result);
index 66842e6..0d828a0 100644 (file)
@@ -72,9 +72,11 @@ namespace Pithos.Core.Agents
 
                     return CompletedTask<object>.Default;
                 }
+
                 var fileState = FileState.FindByFilePath(path);
                 var info = new FileInfo(path);
 
+
                 switch (state.Status)
                 {
                     case FileStatus.Created:
@@ -122,8 +124,9 @@ namespace Pithos.Core.Agents
                     Log.DebugFormat("Found {0} interrupted files",pendingEntries.Count());
 
                 var validEntries = from state in pendingEntries
-                                   select new WorkflowState(accountInfo)
+                                   select new WorkflowState
                                               {
+                                                  AccountInfo=accountInfo,
                                                   Path = state.FilePath.ToLower(),
                                                   FileName = Path.GetFileName(state.FilePath).ToLower(),
                                                   Hash = state.Checksum,
index 33dd077..0efb371 100644 (file)
@@ -25,9 +25,16 @@ namespace Pithos.Core
         public string Hash { get; set; }
         public string LastUpdateHash { get; set; }
 
+/*
         public WorkflowState(AccountInfo accountInfo)
         {
             AccountInfo = accountInfo;
         }
+*/
+
+        public WorkflowState()
+        {
+            
+        }
     }
 }
index 8764264..6ae13d5 100644 (file)
@@ -2,9 +2,10 @@
 {
     public static class FolderConstants
     {
-        public const string PithosContainer = "pithos";
-        public const string TrashContainer = "trash";
+        public static readonly string OthersFolder="others";
+        public static readonly string PithosContainer = "pithos";
+        public static readonly string TrashContainer = "trash";
 
-        public const string FragmentsFolder = "fragments";
+        public static readonly string FragmentsFolder = "fragments";
     }
 }
index b6b5c98..a76722d 100644 (file)
@@ -142,7 +142,7 @@ namespace Pithos.Network
                     if (exc.Response.ContentLength > 0)
                     {
                         string content = GetContent(exc.Response);
-                        Log.ErrorFormat(content);
+                        Log.ErrorFormat(content);                        
                     }
                 }
                 throw;