Synch seems OK. Identified problem with poll differencer
[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.Collections.Specialized;
46 using System.IO;
47 using System.Linq;
48 using System.Text;
49 using System.Threading.Tasks;
50 using Caliburn.Micro;
51 using Pithos.Client.WPF.Properties;
52 using Pithos.Core;
53 using Pithos.Core.Agents;
54 using Pithos.Interfaces;
55 using Pithos.Network;
56
57 namespace Pithos.Client.WPF.SelectiveSynch
58 {
59     class SelectiveSynchViewModel:Screen
60     {
61         private const string DirectoryType = "application/directory";
62         private IEventAggregator _events ;
63
64         private string _title;
65         public string Title
66         {
67             get { return _title; }
68             set
69             {
70                 _title = value;
71                 NotifyOfPropertyChange(() => Title);
72             }
73         }
74
75         public AccountSettings Account { get; set; }
76
77         private readonly ObservableCollection<DirectoryRecord> _rootNodes=new ObservableCollection<DirectoryRecord>();
78         public ObservableCollection<DirectoryRecord> RootNodes
79         {
80             get { return _rootNodes; }
81         }
82
83         private ObservableCollection<ObjectInfo> _checks;
84         private PithosMonitor _monitor;
85         private bool _isBusy=true;
86
87         public ObservableCollection<ObjectInfo> Checks
88         {
89             get { return _checks; }
90         }
91
92         public void GetChecks()
93         {
94             var root = RootNodes[0];            
95             _checks = new ObservableCollection<ObjectInfo>(
96                 from record in root
97                 where record.IsChecked==true
98                 select record.ObjectInfo);
99             NotifyOfPropertyChange(() => Checks);
100         }
101
102         public SelectiveSynchViewModel(PithosMonitor monitor, IEventAggregator events, AccountSettings account)
103         {
104             Account = account;
105             AccountName = account.AccountName;
106             Title = account.AccountName;
107             _monitor = monitor;
108             _events = events;
109             TaskEx.Run(LoadRootNode);
110         }
111
112         private void LoadRootNode()
113         {
114             var client = _monitor.CloudClient;
115
116             var dirs = from container in client.ListContainers(_monitor.UserName)
117                        select new DirectoryRecord
118                                   {
119                                       DisplayName = container.Name,
120                                       Uri=new Uri(client.StorageUrl,container.Name),
121                                       Directories = (from dir in client.ListObjects(_monitor.UserName, container.Name, "")
122                                                      where dir.Content_Type == DirectoryType
123                                                      select new DirectoryRecord { DisplayName = dir.Name, ObjectInfo = dir }).ToList()
124                                   };
125             var ownFolders = dirs.ToList();
126
127             var accounts = client.ListSharingAccounts();
128
129             var accountNodes=from account in client.ListSharingAccounts()
130                              select new DirectoryRecord
131                              {
132                                 DisplayName=account.name,
133                                 Directories=(from container in client.ListContainers(account.name)
134                                             select new DirectoryRecord
135                                                         {
136                                                             DisplayName=container.Name,
137                                                             Directories=(from folder in client.ListObjects(account.name,container.Name,"")
138                                                                         where folder.Content_Type==DirectoryType
139                                                                         select new DirectoryRecord{DisplayName=folder.Name,ObjectInfo=folder}).ToList()
140                                                         }).ToList()
141                              };                                                          
142
143             var othersNode = new DirectoryRecord
144                                  {
145                                      DisplayName = "Others",
146                                      Directories=accountNodes.ToList()
147                                  };
148
149             
150             var rootItem = new DirectoryRecord
151                                {
152                                    DisplayName = AccountName ,
153                                    Directories = ownFolders.ToList()
154                                };
155
156             this.RootNodes.Add(rootItem);
157             this.RootNodes.Add(othersNode);
158
159             SetInitialSelections(Account);
160             
161             IsBusy = false;
162         }
163
164         public bool IsBusy
165         {
166             get {
167                 return _isBusy;
168             }
169             set {
170                 _isBusy = value;
171                 NotifyOfPropertyChange(()=>IsBusy);
172             }
173         }
174
175         private void SetInitialSelections(AccountSettings account)
176         {
177             var selections = account.SelectiveFolders;
178
179             if (selections.Count == 0)
180                 return;
181             
182             var selects = from rootRecord in RootNodes
183                           from record in rootRecord
184                           where record.Uri !=null &&  selections.Contains(record.Uri.ToString())
185                           select record;
186
187             selects.Apply(record=>record.IsChecked=true);
188         }
189
190         protected string AccountName { get; set; }
191
192         public void SaveChanges()
193         {
194             var uris = (from root in RootNodes
195                         from record in root
196                         where record.IsChecked == true && record.Uri != null
197                         select record.Uri).ToArray();            
198
199             SaveSettings(uris);
200             
201             //RootNodes is an ObservableCollection, it can't be enumerated iterativelly
202             
203             var added= (from root in RootNodes
204                         from record in root
205                          where record.Added && record.Uri != null
206                          select record.Uri).ToArray();
207             var removed = (from root in RootNodes
208                             from record in root
209                           where record.Removed && record.Uri != null
210                          select record.Uri).ToArray();
211             //TODO: Include Uris for the containers as well
212             _events.Publish(new SelectiveSynchChanges{Account=Account,Uris=uris,Added=added,Removed=removed});
213             
214
215             
216
217             TryClose(true);
218         }
219
220         
221         private void SaveSettings(IEnumerable<Uri> uris)
222         {
223             var selections = uris.Select(uri => uri.ToString()).ToArray();
224
225             Account.SelectiveFolders.Clear();
226             Account.SelectiveFolders.AddRange(selections);
227             Settings.Default.Save();            
228         }        
229
230         public void RejectChanges()
231         {
232             TryClose(false);
233         }
234     }
235 }