X-Git-Url: https://code.grnet.gr/git/pithos-ms-client/blobdiff_plain/0a9d4d1838a4783c898ec6e10a5cec1fec045b63..2313b22d680c12277646ac923c3954b91f25d5f6:/trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchViewModel.cs?ds=sidebyside
diff --git a/trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchViewModel.cs b/trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchViewModel.cs
index dd1cc21..4141d0f 100644
--- a/trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchViewModel.cs
+++ b/trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchViewModel.cs
@@ -1,242 +1,285 @@
-#region
-/* -----------------------------------------------------------------------
- *
- *
- * 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.
- *
- * -----------------------------------------------------------------------
- */
-#endregion
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Threading.Tasks;
-using Caliburn.Micro;
-using Pithos.Client.WPF.Properties;
-using Pithos.Client.WPF.Utils;
-using Pithos.Core;
-using Pithos.Interfaces;
-
-namespace Pithos.Client.WPF.SelectiveSynch
-{
- class SelectiveSynchViewModel:Screen
- {
- private const string DirectoryType = "application/directory";
- private readonly IEventAggregator _events ;
-
-
- public AccountSettings Account { get; set; }
-
- private readonly ObservableCollection _rootNodes=new ObservableCollection();
- public ObservableCollection RootNodes
- {
- get { return _rootNodes; }
- }
-
- private ObservableCollection _checks;
- private readonly PithosMonitor _monitor;
- private bool _isBusy=true;
-
- public ObservableCollection Checks
- {
- get { return _checks; }
- }
-
- public void GetChecks()
- {
- var root = RootNodes[0];
- _checks = new ObservableCollection(
- from DirectoryRecord record in root
- where record.IsChecked==true
- select record.ObjectInfo);
- NotifyOfPropertyChange(() => Checks);
- }
-
- public SelectiveSynchViewModel(PithosMonitor monitor, IEventAggregator events, AccountSettings account)
- {
- Account = account;
- AccountName = account.AccountName;
- DisplayName = String.Format("Selective folder synchronization for {0}",account.AccountName);
- _monitor = monitor;
- _events = events;
- TaskEx.Run(LoadRootNode);
- }
-
- private void LoadRootNode()
- {
- var client = _monitor.CloudClient;
-
- var dirs = from container in client.ListContainers(_monitor.UserName)
- 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)
- where dir.Content_Type == DirectoryType
- 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.Content_Type==DirectoryType
- 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();
-
- if (selections.Count == 0)
- {
- 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())
- select record).ToList();
- var shouldBeChecked = allNodes.Except(selects).ToList();
-
- selects.Apply(record=>record.IsChecked=false);
-
- shouldBeChecked.Apply(record => record.IsChecked = true);
-
-
-
- }
-
- protected string AccountName { get; set; }
-
- public void SaveChanges()
- {
- var uris = (from DirectoryRecord root in RootNodes
- from DirectoryRecord record in root
- where record.IsChecked == true && record.Uri != null
- select record.Uri).ToArray();
-
- SaveSettings(uris);
-
- //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});
-
-
-
-
- TryClose(true);
- }
-
-
- private void SaveSettings(IEnumerable uris)
- {
- var selections = uris.Select(uri => uri.ToString()).ToArray();
-
- Account.SelectiveFolders.Clear();
- Account.SelectiveFolders.AddRange(selections);
- Settings.Default.Save();
- }
-
- public void RejectChanges()
- {
- TryClose(false);
- }
- }
-}
+#region
+/* -----------------------------------------------------------------------
+ *
+ *
+ * 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.
+ *
+ * -----------------------------------------------------------------------
+ */
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+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 readonly IEventAggregator _events ;
+
+
+ public AccountSettings Account { get; set; }
+
+ private readonly ObservableCollection _rootNodes=new ObservableCollection();
+ public ObservableCollection RootNodes
+ {
+ get { return _rootNodes; }
+ }
+
+ private ObservableCollection _checks;
+ //private readonly PithosMonitor _monitor;
+ private bool _isBusy=true;
+ private string _apiKey;
+
+ public ObservableCollection Checks
+ {
+ get { return _checks; }
+ }
+
+ public void GetChecks()
+ {
+ var root = RootNodes[0];
+ _checks = new ObservableCollection(
+ from DirectoryRecord record in root
+ where record.IsChecked==true
+ select record.ObjectInfo);
+ NotifyOfPropertyChange(() => Checks);
+ }
+
+ 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;
+ _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();
+
+ //NEED to get the local folders here as well,
+ // and combine them with the cloud folders
+
+
+ var dirs = from container in client.ListContainers(AccountName)
+ where container.Name != "trash"
+ 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)
+ 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)
+ select folder).ToTree()
+ }).ToList()
+ };
+
+ var othersNode = new DirectoryRecord
+ {
+ DisplayName = "Shared to me",
+ Directories=accountNodes.ToList()
+ };
+
+
+ var rootItem = new DirectoryRecord
+ {
+ DisplayName = AccountName ,
+ Directories = ownFolders.ToList()
+ };
+
+ var localFolders = SelectiveExtensions.LocalFolders(AccountName, Account.RootPath,client.StorageUrl.AbsoluteUri);
+
+ foreach (var folder in localFolders)
+ {
+ //If this folder is not included in the server folders
+ if (!rootItem.Directories.Any(dir => dir.Uri == folder.Uri))
+ {
+ //we need to add it
+ //Find the best parent
+
+ //One way to do this, is to break the the Uri to its parts
+ //and try to find a parent using progressively fewer parts
+ var parts = folder.Uri.AbsoluteUri.Split('/');
+ for (var i = parts.Length - 1; i > 0; i--)
+ {
+ var parentUrl = String.Join("/",parts.Splice(0, i));
+ var parentUri = new Uri(parentUrl);
+
+ var parent = rootItem.Directories.FirstOrDefault(dir => dir.Uri == parentUri);
+ if (parent != null)
+ {
+ parent.Directories.Add(folder);
+ break;
+ }
+ }
+ }
+ }
+
+ //For each local folder that doesn't exist in the server nodes
+ //find the best matching parent and add the folder below it.
+
+ 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();
+ //WARNING: Using IsChecked marks the item as REMOVED
+ allNodes.Apply(record => record.IsExplicitlyChecked = false);
+
+ if (selections.Count == 0)
+ {
+ // 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())
+ select record).ToList();
+ //var shouldBeChecked = allNodes.Except(selects).ToList();
+
+ //WARNING: Using IsChecked marks the item as ADDED
+ selects.Apply(record=>record.IsExplicitlyChecked=true);
+
+ //shouldBeChecked.Apply(record => record.IsChecked = true);
+
+
+
+ }
+
+ protected string AccountName { get; set; }
+
+ public void SaveChanges()
+ {
+ var uris = (from DirectoryRecord root in RootNodes
+ from DirectoryRecord record in root
+ where record.IsChecked == true && record.Uri != null
+ select record.Uri).ToArray();
+
+ SaveSettings(uris);
+
+ //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});
+
+
+
+
+ TryClose(true);
+ }
+
+
+ private void SaveSettings(IEnumerable uris)
+ {
+ var selections = uris.Select(uri => uri.ToString()).ToArray();
+
+ Account.SelectiveFolders.Clear();
+ Account.SelectiveFolders.AddRange(selections);
+ Settings.Default.Save();
+ }
+
+ public void RejectChanges()
+ {
+ TryClose(false);
+ }
+ }
+}