Selective Sync filtering modified to allow uploading only of new root-level folders
[pithos-ms-client] / trunk / Pithos.Core / Agents / Uploader.cs
index 7ac3dd3..9a36adc 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
@@ -23,7 +24,6 @@ namespace Pithos.Core.Agents
         [Import]\r
         private IStatusKeeper StatusKeeper { get; set; }\r
 \r
-        \r
         public IStatusNotification StatusNotification { get; set; }\r
 \r
         \r
@@ -33,7 +33,7 @@ namespace Pithos.Core.Agents
             _cts.Cancel();\r
         }*/\r
 \r
-        public async Task UploadCloudFile(CloudAction action,CancellationToken cancellationToken)\r
+        public async Task UploadCloudFile(CloudUploadAction action,CancellationToken cancellationToken)\r
         {\r
             if (action == null)\r
                 throw new ArgumentNullException("action");\r
@@ -50,7 +50,7 @@ namespace Pithos.Core.Agents
                     if (fileInfo.Extension.Equals("ignore", StringComparison.InvariantCultureIgnoreCase))\r
                         return;\r
 \r
-                    if (!Selectives.IsSelected(action.AccountInfo, fileInfo))\r
+                    if (!Selectives.IsSelected(action.AccountInfo, fileInfo) && !action.IsCreation)\r
                         return;\r
 \r
                     //Try to load the action's local state, if it is empty\r
@@ -105,17 +105,23 @@ namespace Pithos.Core.Agents
                             //If this a shared file\r
                             if (!cloudFile.Account.Equals(action.AccountInfo.UserName,StringComparison.InvariantCultureIgnoreCase))\r
                             {\r
-                                //If this is a read-only file, do not upload changes\r
+                                \r
+/*\r
                                 if (!cloudInfo.IsWritable(action.AccountInfo.UserName))\r
                                 {\r
                                     MakeFileReadOnly(fullFileName);\r
+                                    StatusKeeper.SetFileState(fullFileName, FileStatus.Unchanged, FileOverlayStatus.Normal, "");\r
                                     return;\r
                                 }\r
+*/\r
 \r
-                                //If the file is new, can we upload it?\r
-                                if ( !cloudInfo.Exists && !client.CanUpload(account, cloudFile))\r
+                                //If this is a read-only file, do not upload changes\r
+                                if ( !cloudInfo.IsWritable(action.AccountInfo.UserName) ||\r
+                                    //If the file is new, but we can't upload it\r
+                                    (!cloudInfo.Exists && !client.CanUpload(account, cloudFile)) )\r
                                 {\r
                                     MakeFileReadOnly(fullFileName);\r
+                                    StatusKeeper.SetFileState(fullFileName, FileStatus.Unchanged, FileOverlayStatus.Normal, "");\r
                                     return;\r
                                 }\r
 \r
@@ -130,6 +136,15 @@ namespace Pithos.Core.Agents
                                     //Go on and create the directory\r
                                     await client.PutObject(account, cloudFile.Container, cloudFile.Name, fullFileName,\r
                                                          String.Empty, "application/directory");\r
+                                //If the upload is in response to a Folder create with Selective Sync enabled\r
+                                if (action.IsCreation)\r
+                                {\r
+                                    //Add the folder to the Selected URls\r
+                                    var selections = Selectives.SelectiveUris[accountInfo.AccountKey];\r
+                                    var selectiveUri = new Uri(client.RootAddressUri, cloudFile.Uri);\r
+                                    selections.Add(selectiveUri);\r
+                                    Selectives.Save(accountInfo);\r
+                                }\r
                             }\r
                             else\r
                             {\r
@@ -144,8 +159,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
@@ -155,7 +172,7 @@ namespace Pithos.Core.Agents
 \r
 \r
                                 //Mark the file as modified while we upload it\r
-                                StatusKeeper.SetFileOverlayStatus(fullFileName, FileOverlayStatus.Modified);\r
+                                await StatusKeeper.SetFileOverlayStatus(fullFileName, FileOverlayStatus.Modified);\r
                                 //And then upload it\r
 \r
                                 //Upload even small files using the Hashmap. The server may already contain\r
@@ -216,7 +233,7 @@ namespace Pithos.Core.Agents
             //Do not make any modifications if not necessary\r
             if (attributes.HasFlag(FileAttributes.ReadOnly))\r
                 return;\r
-            File.SetAttributes(fullFileName, attributes | FileAttributes.ReadOnly);\r
+            File.SetAttributes(fullFileName, attributes | FileAttributes.ReadOnly);            \r
         }\r
 \r
         private static AccountInfo GetSharerAccount(string relativePath, AccountInfo accountInfo)\r
@@ -298,9 +315,13 @@ namespace Pithos.Core.Agents
                         try\r
                         {\r
                             //And upload the block                \r
-                            await client.PostBlock(account, container, buffer, 0, read);\r
+                            await client.PostBlock(account, container, buffer, 0, read, token);\r
                             Log.InfoFormat("[BLOCK] Block {0} of {1} uploaded", blockIndex, fullFileName);\r
                         }\r
+                        catch (TaskCanceledException exc)\r
+                        {\r
+                            throw new OperationCanceledException(token);\r
+                        }\r
                         catch (Exception exc)\r
                         {\r
                             Log.Error(String.Format("Uploading block {0} of {1}", blockIndex, fullFileName), exc);\r