Merge branch 'master' of https://code.grnet.gr/git/pithos-ms-client
authorGeorge Pantazis <gpant@noc.grnet.gr>
Thu, 26 Apr 2012 08:29:30 +0000 (11:29 +0300)
committerGeorge Pantazis <gpant@noc.grnet.gr>
Thu, 26 Apr 2012 08:29:30 +0000 (11:29 +0300)
14 files changed:
trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
trunk/Pithos.Client.WPF/SelectiveSynch/DirectoryRecord.cs
trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchViewModel.cs
trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs
trunk/Pithos.Client.WPF/Utils/EnumerableExtensions.cs
trunk/Pithos.Core/Agents/CloudTransferAction.cs
trunk/Pithos.Core/Agents/CollectionExtensions.cs
trunk/Pithos.Core/Agents/Downloader.cs
trunk/Pithos.Core/Agents/StatusAgent.cs
trunk/Pithos.Core/Agents/Uploader.cs
trunk/Pithos.Core/Agents/WorkflowAgent.cs
trunk/Pithos.Core/PithosMonitor.cs
trunk/Pithos.Interfaces/ObjectInfo.cs
trunk/Pithos.Network/RestClient.cs

index 356557b..5c040d5 100644 (file)
@@ -219,10 +219,10 @@ namespace Pithos.Client.WPF.Preferences
 
         public void SelectiveSyncFolders()
         {
-            var monitor = Shell.Monitors[CurrentAccount.AccountKey];
+            //var monitor = Shell.Monitors[CurrentAccount.AccountKey];
             
 
-            var model = new SelectiveSynchViewModel(monitor,_events,CurrentAccount.Account);
+            var model = new SelectiveSynchViewModel(/*monitor,*/_events,CurrentAccount.Account,CurrentAccount.ApiKey);
             if (_windowManager.ShowDialog(model) == true)
             {
                 
index ce139fe..abd3781 100644 (file)
@@ -163,12 +163,17 @@ namespace Pithos.Client.WPF.SelectiveSynch
             get
             {
                 if (ObjectInfo != null)
-                    return ObjectInfo.Name;
+                    return ObjectInfo.Name.Split('/').Last();
                 return _displayName;
             }
             set { _displayName = value; }
         }
 
+        public bool IsExplicitlyChecked
+        {
+            set { _isChecked=value; }
+        }
+
         public DirectoryRecord(ObjectInfo info)
         {
             ObjectInfo = info;
index ae92d1e..8520ca1 100644 (file)
@@ -49,6 +49,7 @@ using Pithos.Client.WPF.Properties;
 using Pithos.Client.WPF.Utils;
 using Pithos.Core;
 using Pithos.Interfaces;
+using Pithos.Network;
 
 namespace Pithos.Client.WPF.SelectiveSynch
 {
@@ -66,8 +67,9 @@ namespace Pithos.Client.WPF.SelectiveSynch
         }
 
         private ObservableCollection<ObjectInfo> _checks;
-        private readonly PithosMonitor _monitor;
+        //private readonly PithosMonitor _monitor;
         private bool _isBusy=true;
+        private string _apiKey;
 
         public ObservableCollection<ObjectInfo> Checks
         {
@@ -84,26 +86,30 @@ namespace Pithos.Client.WPF.SelectiveSynch
             NotifyOfPropertyChange(() => Checks);
         }
 
-        public SelectiveSynchViewModel(PithosMonitor monitor, IEventAggregator events, AccountSettings account)
+        public SelectiveSynchViewModel(/*PithosMonitor monitor,*/ IEventAggregator events, AccountSettings account, string apiKey)
         {
             Account = account;
             AccountName = account.AccountName;
             DisplayName = String.Format("Selective folder synchronization for {0}",account.AccountName);
-            _monitor = monitor;
+            //_monitor = monitor;
             _events = events;
+            _apiKey = apiKey;
             TaskEx.Run(LoadRootNode);
         }
 
         private void LoadRootNode()
-        {
-            var client = _monitor.CloudClient;
+        {            
+            //TODO: Check this
+            var client = new CloudFilesClient(AccountName,_apiKey){AuthenticationUrl=Account.ServerUrl,UsePithos=true};
+            client.Authenticate();
+            
 
-            var dirs = from container in client.ListContainers(_monitor.UserName)                       
+            var dirs = from container in client.ListContainers(AccountName)                       
                        select new DirectoryRecord
                                   {
                                       DisplayName = container.Name,
                                       Uri=new Uri(client.StorageUrl,String.Format(@"{0}/{1}",Account.AccountName, container.Name)),
-                                      Directories = (from dir in client.ListObjects(_monitor.UserName, container.Name)                                                     
+                                      Directories = (from dir in client.ListObjects(AccountName, container.Name)                                                     
                                                      where dir.IsDirectory
                                                      select dir).ToTree()
                                   };
@@ -173,21 +179,23 @@ namespace Pithos.Client.WPF.SelectiveSynch
                            from DirectoryRecord record in rootRecord
                            select record).ToList();
 
+            allNodes.Apply(record => record.IsChecked = false);
+
             if (selections.Count == 0)
             {
-                allNodes.Apply(record => record.IsChecked = false);
+            //    allNodes.Apply(record => record.IsChecked = false);
                 return;
             } 
             
             var selects = (from DirectoryRecord rootRecord in RootNodes
                           from DirectoryRecord record in rootRecord
-                          where record.Uri !=null &&  !selections.Contains(record.Uri.ToString())
+                          where record.Uri !=null &&  selections.Contains(record.Uri.ToString())
                           select record).ToList();
-            var shouldBeChecked = allNodes.Except(selects).ToList();
+            //var shouldBeChecked = allNodes.Except(selects).ToList();
 
-            selects.Apply(record=>record.IsChecked=false);
+            selects.Apply(record=>record.IsExplicitlyChecked=true);
 
-            shouldBeChecked.Apply(record => record.IsChecked = true);
+            //shouldBeChecked.Apply(record => record.IsChecked = true);
             
             
 
index f95277d..4aef954 100644 (file)
@@ -957,19 +957,22 @@ namespace Pithos.Client.WPF {
                #region Event Handlers
                
                public void Handle(SelectiveSynchChanges message)
-               {            
-                       PithosMonitor monitor;
-                       if (Monitors.TryGetValue(message.Account.AccountKey, out monitor))
-                       {
-                               monitor.SetSelectivePaths(message.Uris,message.Added,message.Removed);
+        {
+            PithosMonitor monitor;
+            if (Monitors.TryGetValue(message.Account.AccountKey, out monitor))
+            {
+                monitor.SetSelectivePaths(message.Uris, message.Added, message.Removed);
 
-                       }
+            }
 
-                   var account = Accounts.First(acc => acc.AccountKey == message.Account.AccountKey);
-                   this._pollAgent.SetSelectivePaths(account, message.Added, message.Removed);
-            
+            var account = Accounts.FirstOrDefault(acc => acc.AccountKey == message.Account.AccountKey);
+            if (account!=null)
+            {
+                this._pollAgent.SetSelectivePaths(account, message.Added, message.Removed);
+            }
 
-               }
+
+        }
 
 
                private bool _pollStarted;
index 9de758a..d76fc09 100644 (file)
@@ -85,7 +85,7 @@ namespace Pithos.Client.WPF.Utils
             foreach (var item in orderedItems)
             {
                 var path = item.Uri.ToString();
-                var newNode = new DirectoryRecord{ DisplayName=item.Name,ObjectInfo=item};
+                var newNode = new DirectoryRecord{ DisplayName=item.Name.Split('/').Last(),ObjectInfo=item};
                 lookups[path] = newNode;
 
                 var lastIndex = path.LastIndexOf("/", StringComparison.Ordinal);
index 7ae68f4..8a81b1b 100644 (file)
@@ -139,7 +139,9 @@ namespace Pithos.Core.Agents
             var capitalizedFileInfo = fileInfo.WithProperCapitalization();
             var fullLocalName = capitalizedFileInfo.FullName;
             var othersPath = Path.Combine(accountInfo.AccountPath, FolderConstants.OthersFolder);
-            
+
+            ObjectInfo objectInfo;
+
             var isShared = fullLocalName.StartsWith(othersPath, StringComparison.InvariantCultureIgnoreCase);
             if (isShared)
             {                
@@ -147,14 +149,20 @@ namespace Pithos.Core.Agents
                 var otherParts = pathRelativeToOther.Split('\\');
                 var otherName = otherParts[0];
                 var otherContainer = otherParts[1];
-                return new ObjectInfo
+                objectInfo=new ObjectInfo
                            {
                                Account = otherName, 
                                Container = otherContainer, 
                                Name = String.Join("/", otherParts.Splice(2))
                            };
             }
-            return new ObjectInfo(accountInfo.AccountPath, accountInfo.UserName, fileInfo);
+            else
+                objectInfo=new ObjectInfo(accountInfo.AccountPath, accountInfo.UserName, fileInfo);
+            
+            objectInfo.Content_Type= (fileInfo is DirectoryInfo)
+                                    ?   "appication/directory"
+                                    :   "application/octet-stream";
+            return objectInfo;
         }
     }    
 
@@ -178,7 +186,7 @@ namespace Pithos.Core.Agents
 
         public override string ToString()
         {
-            return String.Format("{0}: _ <- {1}", this.Action, this.CloudFile.Name);
+            return String.Format("{0}: _ <- {1}", Action, CloudFile.Name);
         }
         
     }
index 2a785cc..b4ecd38 100644 (file)
@@ -168,7 +168,7 @@ namespace Pithos.Core.Agents
             //the target is not below the root\r
             //DON'T FORGET that Uri segments include the slashes. Must remove them to ensure proper checks\r
             var mismatch = rootSegments\r
-                .Where((t, i) => !String.Equals(targetSegments[i].TrimEnd('/'), t.TrimEnd('/')))\r
+                .Where((t, i) => !String.Equals(targetSegments[i].TrimEnd('/'), t.TrimEnd('/'),StringComparison.InvariantCultureIgnoreCase))\r
                 .Any();\r
             return !mismatch;\r
         }\r
index 68b33c6..8e3416c 100644 (file)
@@ -99,7 +99,7 @@ namespace Pithos.Core.Agents
                                     DownloadWithBlocks(accountInfo, client, cloudFile, relativeUrl, localPath,
                                                        serverHash);
 
-                            if (cloudFile.AllowedTo == "read")
+                            if (!cloudFile.IsWritable(accountInfo.UserName))
                             {
                                 var attributes = File.GetAttributes(localPath);
                                 File.SetAttributes(localPath, attributes | FileAttributes.ReadOnly);
index 4423f56..9ec5d00 100644 (file)
@@ -346,6 +346,12 @@ namespace Pithos.Core.Agents
                         command.Parameters.AddWithValue("path", path);
                         
                         var affected = command.ExecuteNonQuery();
+                        if (affected == 0)
+                        {
+                            var createdState = FileState.CreateFor(FileInfoExtensions.FromPath(path));
+                            createdState.FileStatus = status;
+                            _persistenceAgent.Post(createdState.Create);
+                        }
                         return affected;
                     }
                 }
@@ -379,6 +385,13 @@ namespace Pithos.Core.Agents
                         command.Parameters.AddWithValue("overlayStatus", overlayStatus);
                         
                         var affected = command.ExecuteNonQuery();
+                        if (affected == 0)
+                        {
+                            var createdState=FileState.CreateFor(FileInfoExtensions.FromPath(absolutePath));
+                            createdState.FileStatus = fileStatus;
+                            createdState.OverlayStatus = overlayStatus;
+                            _persistenceAgent.Post(createdState.Create);  
+                        }
                         return affected;
                     }
                 }
index db0735e..67e6db1 100644 (file)
@@ -47,14 +47,16 @@ namespace Pithos.Core.Agents
                         return;
                     }
 
+                    var latestState = action.FileState;
+
                     //Do not upload files in conflict
-                    if (action.FileState.FileStatus == FileStatus.Conflict)
+                    if (latestState.FileStatus == FileStatus.Conflict)
                     {
                         Log.InfoFormat("Skipping file in conflict [{0}]", fileInfo.FullName);
                         return;
                     }
                     //Do not upload files when we have no permission
-                    if (action.FileState.FileStatus == FileStatus.Forbidden)
+                    if (latestState.FileStatus == FileStatus.Forbidden)
                     {
                         Log.InfoFormat("Skipping forbidden file [{0}]", fileInfo.FullName);
                         return;
@@ -85,7 +87,7 @@ namespace Pithos.Core.Agents
                             var cloudInfo = client.GetObjectInfo(account, cloudFile.Container, cloudFile.Name);
 
                             //If this is a read-only file, do not upload changes
-                            if (cloudInfo.AllowedTo == "read")
+                            if (!cloudInfo.IsWritable(action.AccountInfo.UserName))
                                 return;
 
                             if (fileInfo is DirectoryInfo)
@@ -139,6 +141,7 @@ namespace Pithos.Core.Agents
                             if (response.StatusCode == HttpStatusCode.Forbidden)
                             {
                                 StatusKeeper.SetFileState(fileInfo.FullName, FileStatus.Forbidden, FileOverlayStatus.Conflict, "Forbidden");
+                                
                             }
                             else
                                 //In any other case, propagate the error
index 5ff697e..b53691a 100644 (file)
@@ -73,6 +73,12 @@ namespace Pithos.Core.Agents
         [System.ComponentModel.Composition.Import]
         public IPithosSettings Settings { get; set; }
 
+        private List<string> _selectivePaths = new List<string>();
+        public List<string> SelectivePaths
+        {
+            get { return _selectivePaths; }
+            set { _selectivePaths = value; }
+        }
 
         public WorkflowAgent()
         {
@@ -245,7 +251,8 @@ namespace Pithos.Core.Agents
                 var pendingStates = pendingEntries
                     .Select(state => new WorkflowState(account, state))
                     .ToList();
-
+                
+                                
                 if (Log.IsDebugEnabled)
                     Log.DebugFormat("Found {0} interrupted files", pendingStates.Count);
 
@@ -266,6 +273,17 @@ namespace Pithos.Core.Agents
                 return;*/
             //TODO: Need to handle folder renames            
 
+            //If there are selective sync paths defined
+            if (SelectivePaths.Count > 0
+                //And the target file is not below any of the selective paths
+                && !SelectivePaths.Any(workflowState.Path.IsAtOrDirectlyBelow))
+            //abort the post
+            {
+                Log.InfoFormat("File skipped, not under a selected folder [{0}] ",workflowState.Path);
+                return;
+            }
+
+
             Debug.Assert(workflowState.Path.StartsWith(workflowState.AccountInfo.AccountPath, StringComparison.InvariantCultureIgnoreCase), "File from wrong account posted");
 
             _agent.Post(workflowState);
index 55d6c82..7ca5a30 100644 (file)
@@ -193,12 +193,12 @@ namespace Pithos.Core
             }
             _cancellationSource = new CancellationTokenSource();
 
-
-            CloudClient = new CloudFilesClient(UserName, ApiKey)
-                              {UsePithos = true, AuthenticationUrl = AuthenticationUrl};
-
-
-            _accountInfo = CloudClient.Authenticate();            
+            lock (this)
+            {
+                CloudClient = new CloudFilesClient(UserName, ApiKey)
+                                  {UsePithos = true, AuthenticationUrl = AuthenticationUrl};
+                _accountInfo = CloudClient.Authenticate();
+            }
             _accountInfo.SiteUri = AuthenticationUrl;
             _accountInfo.AccountPath = RootPath;
 
@@ -432,6 +432,7 @@ namespace Pithos.Core
             var selectivePaths = UrisToFilePaths(uris);
             
             FileAgent.SelectivePaths=selectivePaths;
+            WorkflowAgent.SelectivePaths = selectivePaths;
             PollAgent.SetSyncUris(_accountInfo.AccountKey,uris);
             
             var removedPaths = UrisToFilePaths(removed);
index 4c43701..484a39a 100644 (file)
@@ -328,6 +328,25 @@ namespace Pithos.Interfaces
                    && (this.Name == null || other.Name.StartsWith(this.Name));
         }
 
+        public bool IsWritable(string account)
+        {
+            //If the Allowed To header has no value, try to determine the Share permissions
+            if (AllowedTo == null)
+            {
+                //If this file has no permissions defined, we can probably write it
+                //This case should occur only when the info comes from a listing of the user's own files
+                if (Permissions == null || Permissions.Count == 0)
+                    return true;
+                string perms;
+
+                //Do we have an explicit write share to this account?
+                return Permissions.TryGetValue(account, out perms) 
+                    && perms.Equals("write",StringComparison.InvariantCultureIgnoreCase);
+                
+            }
+            //Otherwise return the permissions specified by AllowedTo
+            return AllowedTo.Equals("write",StringComparison.InvariantCultureIgnoreCase) ;
+        }
 
         public ObjectInfo Previous { get; private set; }
 
@@ -335,6 +354,8 @@ namespace Pithos.Interfaces
         {
             get
             {
+                if (Content_Type == null)
+                    return false;
                 if (Content_Type.StartsWith(@"application/directory",StringComparison.InvariantCultureIgnoreCase))
                     return true;
                 if (Content_Type.StartsWith(@"application/folder",StringComparison.InvariantCultureIgnoreCase))
index 4657d4a..45e0420 100644 (file)
@@ -107,8 +107,8 @@ namespace Pithos.Network
             : base()
         {
             if (other==null)
-                Log.ErrorFormat("[ERROR] No parameters provided to the rest client. \n{0}\n", other);
-                //throw new ArgumentNullException("other");
+                //Log.ErrorFormat("[ERROR] No parameters provided to the rest client. \n{0}\n", other);
+                throw new ArgumentNullException("other");
             Contract.EndContractBlock();
 
             //The maximum error response must be large because missing server hashes are return as a Conflivt (409) error response