Fixed incorrect account key in PollAgent.cs
[pithos-ms-client] / trunk / Pithos.Client.WPF / SelectiveSynch / SelectiveSynchViewModel.cs
1 #region
2 /* -----------------------------------------------------------------------
3  * <copyright file="SelectiveSynchViewModel.cs" company="GRNet">
4  * 
5  * Copyright 2011-2012 GRNET S.A. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or
8  * without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  *   1. Redistributions of source code must retain the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer.
14  *
15  *   2. Redistributions in binary form must reproduce the above
16  *      copyright notice, this list of conditions and the following
17  *      disclaimer in the documentation and/or other materials
18  *      provided with the distribution.
19  *
20  *
21  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * The views and conclusions contained in the software and
35  * documentation are those of the authors and should not be
36  * interpreted as representing official policies, either expressed
37  * or implied, of GRNET S.A.
38  * </copyright>
39  * -----------------------------------------------------------------------
40  */
41 #endregion
42 using System;
43 using System.Collections.Generic;
44 using System.Collections.ObjectModel;
45 using System.Linq;
46 using System.Threading.Tasks;
47 using Caliburn.Micro;
48 using Pithos.Client.WPF.Properties;
49 using Pithos.Client.WPF.Utils;
50 using Pithos.Core;
51 using Pithos.Interfaces;
52
53 namespace Pithos.Client.WPF.SelectiveSynch
54 {
55     class SelectiveSynchViewModel:Screen
56     {
57         private const string DirectoryType = "application/directory";
58         private readonly IEventAggregator _events ;
59
60
61         public AccountSettings Account { get; set; }
62
63         private readonly ObservableCollection<DirectoryRecord> _rootNodes=new ObservableCollection<DirectoryRecord>();
64         public ObservableCollection<DirectoryRecord> RootNodes
65         {
66             get { return _rootNodes; }
67         }
68
69         private ObservableCollection<ObjectInfo> _checks;
70         private readonly PithosMonitor _monitor;
71         private bool _isBusy=true;
72
73         public ObservableCollection<ObjectInfo> Checks
74         {
75             get { return _checks; }
76         }
77
78         public void GetChecks()
79         {
80             var root = RootNodes[0];            
81             _checks = new ObservableCollection<ObjectInfo>(
82                 from DirectoryRecord record in root
83                 where record.IsChecked==true
84                 select record.ObjectInfo);
85             NotifyOfPropertyChange(() => Checks);
86         }
87
88         public SelectiveSynchViewModel(PithosMonitor monitor, IEventAggregator events, AccountSettings account)
89         {
90             Account = account;
91             AccountName = account.AccountName;
92             DisplayName = String.Format("Selective folder synchronization for {0}",account.AccountName);
93             _monitor = monitor;
94             _events = events;
95             TaskEx.Run(LoadRootNode);
96         }
97
98         private void LoadRootNode()
99         {
100             var client = _monitor.CloudClient;
101
102             var dirs = from container in client.ListContainers(_monitor.UserName)                       
103                        select new DirectoryRecord
104                                   {
105                                       DisplayName = container.Name,
106                                       Uri=new Uri(client.StorageUrl,String.Format(@"{0}/{1}",Account.AccountName, container.Name)),
107                                       Directories = (from dir in client.ListObjects(_monitor.UserName, container.Name)                                                     
108                                                      where dir.Content_Type == DirectoryType
109                                                      select dir).ToTree()
110                                   };
111             var ownFolders = dirs.ToList();
112
113             var accountNodes=from account in client.ListSharingAccounts()
114                              select new DirectoryRecord
115                              {
116                                 DisplayName=account.name,
117                                 Uri=new Uri(client.StorageUrl,"../"+ account.name),
118                                 Directories=(from container in client.ListContainers(account.name)
119                                             select new DirectoryRecord
120                                                         {
121                                                             DisplayName=container.Name,
122                                                             Uri = new Uri(client.StorageUrl, "../" + account.name + "/" + container.Name),
123                                                             Directories=(from folder in client.ListObjects(account.name,container.Name)
124                                                                         where folder.Content_Type==DirectoryType
125                                                                         select folder).ToTree()
126                                                         }).ToList()
127                              };                                                          
128
129             var othersNode = new DirectoryRecord
130                                  {
131                                      DisplayName = "Others",
132                                      Directories=accountNodes.ToList()
133                                  };
134
135             
136             var rootItem = new DirectoryRecord
137                                {
138                                    DisplayName = AccountName ,
139                                    Directories = ownFolders.ToList()
140                                };
141
142             Execute.OnUIThread(() =>
143                                    {
144                                        RootNodes.Add(rootItem);
145                                        RootNodes.Add(othersNode);
146                                    });
147
148             SetInitialSelections(Account);
149             
150             IsBusy = false;
151         }
152
153         public bool IsBusy
154         {
155             get {
156                 return _isBusy;
157             }
158             set {
159                 _isBusy = value;
160                 NotifyOfPropertyChange(()=>IsBusy);
161             }
162         }
163
164         private void SetInitialSelections(AccountSettings account)
165         {
166             var selections = account.SelectiveFolders;
167
168             if (selections.Count == 0)
169                 return;
170             //Initially, all nodes are checked
171             //We need to *uncheck* the nodes that are not selected
172
173             var selects = from DirectoryRecord rootRecord in RootNodes
174                           from DirectoryRecord record in rootRecord
175                           where record.Uri !=null &&  !selections.Contains(record.Uri.ToString())
176                           select record;
177
178             selects.Apply(record=>record.IsChecked=false);
179         }
180
181         protected string AccountName { get; set; }
182
183         public void SaveChanges()
184         {
185             var uris = (from DirectoryRecord root in RootNodes
186                         from DirectoryRecord record in root
187                         where record.IsChecked == true && record.Uri != null
188                         select record.Uri).ToArray();            
189
190             SaveSettings(uris);
191             
192             //RootNodes is an ObservableCollection, it can't be enumerated iterativelly
193
194             var added = (from DirectoryRecord root in RootNodes
195                          from DirectoryRecord record in root
196                          where record.Added && record.Uri != null
197                          select record.Uri).ToArray();
198             var removed = (from DirectoryRecord root in RootNodes
199                            from DirectoryRecord record in root
200                           where record.Removed && record.Uri != null
201                          select record.Uri).ToArray();
202             //TODO: Include Uris for the containers as well
203             _events.Publish(new SelectiveSynchChanges{Account=Account,Uris=uris,Added=added,Removed=removed});
204             
205
206             
207
208             TryClose(true);
209         }
210
211         
212         private void SaveSettings(IEnumerable<Uri> uris)
213         {
214             var selections = uris.Select(uri => uri.ToString()).ToArray();
215
216             Account.SelectiveFolders.Clear();
217             Account.SelectiveFolders.AddRange(selections);
218             Settings.Default.Save();            
219         }        
220
221         public void RejectChanges()
222         {
223             TryClose(false);
224         }
225     }
226 }