Selective Sync fixes
[pithos-ms-client] / trunk / Pithos.Client.WPF / SelectiveSynch / SelectiveSynchViewModel.cs
index ebbd4a9..f7edd53 100644 (file)
-using System;
+#region
+/* -----------------------------------------------------------------------
+ * <copyright file="SelectiveSynchViewModel.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.Collections.ObjectModel;
-using System.Collections.Specialized;
-using System.IO;
 using System.Linq;
-using System.Text;
+using System.Threading.Tasks;
 using Caliburn.Micro;
 using Pithos.Client.WPF.Properties;
+using Pithos.Client.WPF.Utils;
+using Pithos.Core;
 using Pithos.Interfaces;
 using Pithos.Network;
 
 namespace Pithos.Client.WPF.SelectiveSynch
 {
     class SelectiveSynchViewModel:Screen
-    {
-        private IEventAggregator _events ;
+    {        
+        private readonly IEventAggregator _events ;
 
-        private string _rootPath;
-        private string _fragmentsPath;
-        public string RootPath
-        {
-            get { return _rootPath; }
-            set
-            {
-                _rootPath = value;
-                _fragmentsPath = Path.Combine(_rootPath, FolderConstants.FragmentsFolder);
-                _pithosDirectory = new ObservableCollection<DirectoryRecord>{
-                        new DirectoryRecord(_fragmentsPath) {Info = new DirectoryInfo(value)}};
-                NotifyOfPropertyChange(() => RootPath);
-                NotifyOfPropertyChange(()=>PithosDirectory);
-            }
-        }
-
-        private string _title;
-        public string Title
-        {
-            get { return _title; }
-            set
-            {
-                _title = value;
-                NotifyOfPropertyChange(() => Title);
-            }
-        }
 
         public AccountSettings Account { get; set; }
 
-        private ObservableCollection<DirectoryRecord> _pithosDirectory;
-        public ObservableCollection<DirectoryRecord> PithosDirectory
+        private readonly ObservableCollection<DirectoryRecord> _rootNodes=new ObservableCollection<DirectoryRecord>();
+        public ObservableCollection<DirectoryRecord> RootNodes
         {
-            get { return _pithosDirectory; }
+            get { return _rootNodes; }
         }
 
-        private ObservableCollection<DirectoryInfo> _checks;
-        public ObservableCollection<DirectoryInfo> Checks
+        private ObservableCollection<ObjectInfo> _checks;
+        //private readonly PithosMonitor _monitor;
+        private bool _isBusy=true;
+        private string _apiKey;
+
+        public ObservableCollection<ObjectInfo> Checks
         {
             get { return _checks; }
         }
 
         public void GetChecks()
         {
-            var root = PithosDirectory[0];            
-            _checks = new ObservableCollection<DirectoryInfo>(
-                from record in root
+            var root = RootNodes[0];            
+            _checks = new ObservableCollection<ObjectInfo>(
+                from DirectoryRecord record in root
                 where record.IsChecked==true
-                select record.Info);
+                select record.ObjectInfo);
             NotifyOfPropertyChange(() => Checks);
         }
 
-        public SelectiveSynchViewModel(IEventAggregator events, AccountSettings account)
+        public SelectiveSynchViewModel(/*PithosMonitor monitor,*/ IEventAggregator events, AccountSettings account, string apiKey)
         {
             Account = account;
             AccountName = account.AccountName;
-            Title = account.AccountName;
-            RootPath = account.RootPath;
+            DisplayName = String.Format("Selective folder synchronization for {0}",account.AccountName);
+            //_monitor = monitor;
+            _events = events;
+            _apiKey = apiKey;
+            TaskEx.Run(LoadRootNode);
+        }
+
+        private void LoadRootNode()
+        {            
+            //TODO: Check this
+            var client = new CloudFilesClient(AccountName,_apiKey){AuthenticationUrl=Account.ServerUrl,UsePithos=true};
+            client.Authenticate();
+            
 
-            SetInitialSelections(account);
+            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(AccountName, container.Name)                                                     
+                                                     where dir.IsDirectory
+                                                     select dir).ToTree()
+                                  };
+            var ownFolders = dirs.ToList();
+
+            var accountNodes=from account in client.ListSharingAccounts()
+                             select new DirectoryRecord
+                             {
+                                DisplayName=account.name,
+                                Uri=new Uri(client.StorageUrl,"../"+ account.name),
+                                Directories=(from container in client.ListContainers(account.name)
+                                            select new DirectoryRecord
+                                                        {
+                                                            DisplayName=container.Name,
+                                                            Uri = new Uri(client.StorageUrl, "../" + account.name + "/" + container.Name),
+                                                            Directories=(from folder in client.ListObjects(account.name,container.Name)
+                                                                        where folder.IsDirectory
+                                                                        select folder).ToTree()
+                                                        }).ToList()
+                             };                                                          
+
+            var othersNode = new DirectoryRecord
+                                 {
+                                     DisplayName = "Others",
+                                     Directories=accountNodes.ToList()
+                                 };
+
+            
+            var rootItem = new DirectoryRecord
+                               {
+                                   DisplayName = AccountName ,
+                                   Directories = ownFolders.ToList()
+                               };
+
+            Execute.OnUIThread(() =>
+                                   {
+                                       RootNodes.Add(rootItem);
+                                       RootNodes.Add(othersNode);
+                                   });
+
+            SetInitialSelections(Account);
+            
+            IsBusy = false;
+        }
+
+        public bool IsBusy
+        {
+            get {
+                return _isBusy;
+            }
+            set {
+                _isBusy = value;
+                NotifyOfPropertyChange(()=>IsBusy);
+            }
         }
 
         private void SetInitialSelections(AccountSettings account)
         {
             var selections = account.SelectiveFolders;
+
+
+                
+            //Initially, all nodes are checked
+            //We need to *uncheck* the nodes that are not selected
+
+            var allNodes = (from DirectoryRecord rootRecord in RootNodes
+                           from DirectoryRecord record in rootRecord
+                           select record).ToList();
+
+            allNodes.Apply(record => record.IsChecked = false);
+
             if (selections.Count == 0)
+            {
+            //    allNodes.Apply(record => record.IsChecked = false);
                 return;
-            var root = PithosDirectory[0];
-            var selects= from record in root
-                             where selections.Contains(record.Info.FullName)
-                             select record;
-            selects.Apply(record=>record.IsChecked=true);            
+            } 
+            
+            var selects = (from DirectoryRecord rootRecord in RootNodes
+                          from DirectoryRecord record in rootRecord
+                          where record.Uri !=null &&  selections.Contains(record.Uri.ToString())
+                          select record).ToList();
+            //var shouldBeChecked = allNodes.Except(selects).ToList();
+
+            selects.Apply(record=>record.IsExplicitlyChecked=true);
+
+            //shouldBeChecked.Apply(record => record.IsChecked = true);
+            
+            
+
         }
 
         protected string AccountName { get; set; }
 
         public void SaveChanges()
         {
-            var selections = GetSelectedFolderNames();
+            var uris = (from DirectoryRecord root in RootNodes
+                        from DirectoryRecord record in root
+                        where record.IsChecked == true && record.Uri != null
+                        select record.Uri).ToArray();            
 
-            SaveSettings(selections);
-            var root = PithosDirectory[0];
+            SaveSettings(uris);
             
-            var added= (from record in root
-                         where record.Added
-                         select record.Info.FullName.ToLower()).ToArray();
-            var removed= (from record in root
-                         where record.Removed
-                         select record.Info.FullName.ToLower()).ToArray();            
-
-            _events.Publish(new SelectiveSynchChanges{Account=Account,Added=added,Removed=removed});
+            //RootNodes is an ObservableCollection, it can't be enumerated iterativelly
+
+            var added = (from DirectoryRecord root in RootNodes
+                         from DirectoryRecord record in root
+                         where record.Added && record.Uri != null
+                         select record.Uri).ToArray();
+            var removed = (from DirectoryRecord root in RootNodes
+                           from DirectoryRecord record in root
+                          where record.Removed && record.Uri != null
+                         select record.Uri).ToArray();
+            //TODO: Include Uris for the containers as well
+            _events.Publish(new SelectiveSynchChanges{Account=Account,Uris=uris,Added=added,Removed=removed});
             
 
             
@@ -114,21 +232,14 @@ namespace Pithos.Client.WPF.SelectiveSynch
         }
 
         
-        private void SaveSettings(string[] selections)
+        private void SaveSettings(IEnumerable<Uri> uris)
         {
+            var selections = uris.Select(uri => uri.ToString()).ToArray();
+
             Account.SelectiveFolders.Clear();
             Account.SelectiveFolders.AddRange(selections);
             Settings.Default.Save();            
-        }
-
-        private string[] GetSelectedFolderNames()
-        {
-            var root = PithosDirectory[0];
-            var selections = from record in root
-                         where record.IsChecked == true
-                         select record.Info.FullName;
-            return selections.ToArray();
-        }
+        }        
 
         public void RejectChanges()
         {