Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / PithosMonitor.cs @ 70f12b36

History | View | Annotate | Download (18.9 kB)

1 d78cbf09 Panagiotis Kanavos
using System;
2 d78cbf09 Panagiotis Kanavos
using System.Collections.Concurrent;
3 d78cbf09 Panagiotis Kanavos
using System.Collections.Generic;
4 d78cbf09 Panagiotis Kanavos
using System.ComponentModel.Composition;
5 d78cbf09 Panagiotis Kanavos
using System.Diagnostics;
6 d78cbf09 Panagiotis Kanavos
using System.Diagnostics.Contracts;
7 d78cbf09 Panagiotis Kanavos
using System.IO;
8 d78cbf09 Panagiotis Kanavos
using System.Linq;
9 65282d58 Panagiotis Kanavos
using System.Net;
10 29672672 Panagiotis Kanavos
using System.Net.NetworkInformation;
11 d78cbf09 Panagiotis Kanavos
using System.Security.Cryptography;
12 5bcf6d70 Panagiotis Kanavos
using System.ServiceModel.Description;
13 d78cbf09 Panagiotis Kanavos
using System.Text;
14 d78cbf09 Panagiotis Kanavos
using System.Threading;
15 d78cbf09 Panagiotis Kanavos
using System.Threading.Tasks;
16 0eea575a Panagiotis Kanavos
using Castle.ActiveRecord.Queries;
17 637bc368 Panagiotis Kanavos
using Microsoft.WindowsAPICodePack.Net;
18 9c4346c9 Panagiotis Kanavos
using Pithos.Core.Agents;
19 d78cbf09 Panagiotis Kanavos
using Pithos.Interfaces;
20 eeee29e3 Panagiotis Kanavos
using System.ServiceModel;
21 5ce54458 Panagiotis Kanavos
using Pithos.Network;
22 5120f3cb Panagiotis Kanavos
using log4net;
23 d78cbf09 Panagiotis Kanavos
24 d78cbf09 Panagiotis Kanavos
namespace Pithos.Core
25 d78cbf09 Panagiotis Kanavos
{
26 d78cbf09 Panagiotis Kanavos
    [Export(typeof(PithosMonitor))]
27 d78cbf09 Panagiotis Kanavos
    public class PithosMonitor:IDisposable
28 d78cbf09 Panagiotis Kanavos
    {
29 5ce54458 Panagiotis Kanavos
        private int _blockSize;
30 5ce54458 Panagiotis Kanavos
        private string _blockHash;
31 5ce54458 Panagiotis Kanavos
32 d78cbf09 Panagiotis Kanavos
        [Import]
33 d78cbf09 Panagiotis Kanavos
        public IPithosSettings Settings{get;set;}
34 d78cbf09 Panagiotis Kanavos
35 4ec636f6 Panagiotis Kanavos
        private IStatusKeeper _statusKeeper;
36 4ec636f6 Panagiotis Kanavos
37 d78cbf09 Panagiotis Kanavos
        [Import]
38 4ec636f6 Panagiotis Kanavos
        public IStatusKeeper StatusKeeper
39 4ec636f6 Panagiotis Kanavos
        {
40 4ec636f6 Panagiotis Kanavos
            get { return _statusKeeper; }
41 4ec636f6 Panagiotis Kanavos
            set
42 4ec636f6 Panagiotis Kanavos
            {
43 4ec636f6 Panagiotis Kanavos
                _statusKeeper = value;
44 4ec636f6 Panagiotis Kanavos
                FileAgent.StatusKeeper = value;
45 4ec636f6 Panagiotis Kanavos
            }
46 4ec636f6 Panagiotis Kanavos
        }
47 4ec636f6 Panagiotis Kanavos
48 4ec636f6 Panagiotis Kanavos
49 4ec636f6 Panagiotis Kanavos
        private IPithosWorkflow _workflow;
50 d78cbf09 Panagiotis Kanavos
51 d78cbf09 Panagiotis Kanavos
        [Import]
52 4ec636f6 Panagiotis Kanavos
        public IPithosWorkflow Workflow
53 4ec636f6 Panagiotis Kanavos
        {
54 4ec636f6 Panagiotis Kanavos
            get { return _workflow; }
55 4ec636f6 Panagiotis Kanavos
            set
56 4ec636f6 Panagiotis Kanavos
            {
57 4ec636f6 Panagiotis Kanavos
                _workflow = value;
58 4ec636f6 Panagiotis Kanavos
                FileAgent.Workflow = value;
59 4ec636f6 Panagiotis Kanavos
            }
60 4ec636f6 Panagiotis Kanavos
        }
61 d78cbf09 Panagiotis Kanavos
62 d78cbf09 Panagiotis Kanavos
        public ICloudClient CloudClient { get; set; }
63 d78cbf09 Panagiotis Kanavos
64 0c02aa65 Panagiotis Kanavos
        public IStatusNotification StatusNotification { get; set; }
65 0c02aa65 Panagiotis Kanavos
66 4ec636f6 Panagiotis Kanavos
        //[Import]
67 4ec636f6 Panagiotis Kanavos
        public FileAgent FileAgent { get; private set; }
68 4ec636f6 Panagiotis Kanavos
69 4ec636f6 Panagiotis Kanavos
        private WorkflowAgent _workflowAgent;
70 4ec636f6 Panagiotis Kanavos
71 9c4346c9 Panagiotis Kanavos
        [Import]
72 4ec636f6 Panagiotis Kanavos
        public WorkflowAgent WorkflowAgent
73 4ec636f6 Panagiotis Kanavos
        {
74 4ec636f6 Panagiotis Kanavos
            get { return _workflowAgent; }
75 4ec636f6 Panagiotis Kanavos
            set
76 4ec636f6 Panagiotis Kanavos
            {
77 4ec636f6 Panagiotis Kanavos
                _workflowAgent = value;
78 4ec636f6 Panagiotis Kanavos
                FileAgent.WorkflowAgent = value;
79 4ec636f6 Panagiotis Kanavos
            }
80 4ec636f6 Panagiotis Kanavos
        }
81 9c4346c9 Panagiotis Kanavos
        
82 9c4346c9 Panagiotis Kanavos
        [Import]
83 c28a075a Panagiotis Kanavos
        public NetworkAgent NetworkAgent { get; set; }        
84 9c4346c9 Panagiotis Kanavos
85 0eea575a Panagiotis Kanavos
        public string UserName { get; set; }
86 c92e02f3 Panagiotis Kanavos
        private string _apiKey;
87 c92e02f3 Panagiotis Kanavos
        public string ApiKey
88 c92e02f3 Panagiotis Kanavos
        {
89 c92e02f3 Panagiotis Kanavos
            get { return _apiKey; }
90 c92e02f3 Panagiotis Kanavos
            set
91 c92e02f3 Panagiotis Kanavos
            {
92 c92e02f3 Panagiotis Kanavos
                _apiKey = value;
93 c92e02f3 Panagiotis Kanavos
                if (_accountInfo != null)
94 c92e02f3 Panagiotis Kanavos
                    _accountInfo.Token = value;
95 c92e02f3 Panagiotis Kanavos
            }
96 c92e02f3 Panagiotis Kanavos
        }
97 0eea575a Panagiotis Kanavos
98 0bd56b7c Panagiotis Kanavos
        private AccountInfo _accountInfo;
99 4ec636f6 Panagiotis Kanavos
        
100 4ec636f6 Panagiotis Kanavos
       
101 c53aa229 Panagiotis Kanavos
102 eeee29e3 Panagiotis Kanavos
103 5120f3cb Panagiotis Kanavos
        private static readonly ILog Log = LogManager.GetLogger(typeof(PithosMonitor));
104 5120f3cb Panagiotis Kanavos
105 d78cbf09 Panagiotis Kanavos
106 d78cbf09 Panagiotis Kanavos
        public bool Pause
107 d78cbf09 Panagiotis Kanavos
        {
108 5ce54458 Panagiotis Kanavos
            get { return FileAgent.Pause; }
109 d78cbf09 Panagiotis Kanavos
            set
110 d78cbf09 Panagiotis Kanavos
            {
111 5ce54458 Panagiotis Kanavos
                FileAgent.Pause = value;
112 5bcf6d70 Panagiotis Kanavos
                if (value)
113 5bcf6d70 Panagiotis Kanavos
                {
114 5bcf6d70 Panagiotis Kanavos
                    StatusKeeper.SetPithosStatus(PithosStatus.SyncPaused);
115 0c02aa65 Panagiotis Kanavos
                    StatusNotification.NotifyChange("Paused");
116 5bcf6d70 Panagiotis Kanavos
                }
117 5bcf6d70 Panagiotis Kanavos
                else
118 5bcf6d70 Panagiotis Kanavos
                {
119 5bcf6d70 Panagiotis Kanavos
                    StatusKeeper.SetPithosStatus(PithosStatus.InSynch);
120 9c4346c9 Panagiotis Kanavos
                    StatusNotification.NotifyChange("Synchronizing");
121 5bcf6d70 Panagiotis Kanavos
                }
122 d78cbf09 Panagiotis Kanavos
            }
123 d78cbf09 Panagiotis Kanavos
        }
124 d78cbf09 Panagiotis Kanavos
125 c28a075a Panagiotis Kanavos
        private string _rootPath;
126 c28a075a Panagiotis Kanavos
        public string RootPath
127 c28a075a Panagiotis Kanavos
        {
128 c28a075a Panagiotis Kanavos
            get { return _rootPath; }
129 7e26c075 Panagiotis Kanavos
            set 
130 c28a075a Panagiotis Kanavos
            {
131 7e26c075 Panagiotis Kanavos
                _rootPath = String.IsNullOrWhiteSpace(value) 
132 7e26c075 Panagiotis Kanavos
                    ? String.Empty 
133 7e26c075 Panagiotis Kanavos
                    : value.ToLower();
134 c28a075a Panagiotis Kanavos
            }
135 c28a075a Panagiotis Kanavos
        }
136 0eea575a Panagiotis Kanavos
137 d78cbf09 Panagiotis Kanavos
138 d78cbf09 Panagiotis Kanavos
        CancellationTokenSource _cancellationSource;
139 d78cbf09 Panagiotis Kanavos
140 4ec636f6 Panagiotis Kanavos
        public PithosMonitor()
141 4ec636f6 Panagiotis Kanavos
        {
142 4ec636f6 Panagiotis Kanavos
            FileAgent = new FileAgent();
143 d78cbf09 Panagiotis Kanavos
144 4ec636f6 Panagiotis Kanavos
        }
145 7e26c075 Panagiotis Kanavos
        private bool _started;
146 d78cbf09 Panagiotis Kanavos
147 d78cbf09 Panagiotis Kanavos
        public void Start()
148 c53aa229 Panagiotis Kanavos
        {            
149 c53aa229 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(ApiKey))
150 c53aa229 Panagiotis Kanavos
                throw new InvalidOperationException("The ApiKey is empty");
151 c53aa229 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(UserName))
152 c53aa229 Panagiotis Kanavos
                throw new InvalidOperationException("The UserName is empty");
153 c53aa229 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(AuthenticationUrl))
154 c53aa229 Panagiotis Kanavos
                throw new InvalidOperationException("The Authentication url is empty");
155 c53aa229 Panagiotis Kanavos
            Contract.EndContractBlock();
156 c53aa229 Panagiotis Kanavos
157 437abfca Panagiotis Kanavos
            //If the account doesn't have a valid path, don't start monitoring but don't throw either
158 437abfca Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(RootPath))
159 437abfca Panagiotis Kanavos
                //TODO; Warn user?
160 437abfca Panagiotis Kanavos
                return;
161 437abfca Panagiotis Kanavos
162 70f12b36 Panagiotis Kanavos
            WorkflowAgent.StatusNotification = StatusNotification;
163 70f12b36 Panagiotis Kanavos
164 0c02aa65 Panagiotis Kanavos
            StatusNotification.NotifyChange("Starting");
165 7e26c075 Panagiotis Kanavos
            if (_started)
166 d78cbf09 Panagiotis Kanavos
            {
167 d78cbf09 Panagiotis Kanavos
                if (!_cancellationSource.IsCancellationRequested)
168 d78cbf09 Panagiotis Kanavos
                    return;
169 d78cbf09 Panagiotis Kanavos
            }
170 29672672 Panagiotis Kanavos
            _cancellationSource = new CancellationTokenSource();
171 c92e02f3 Panagiotis Kanavos
            
172 d78cbf09 Panagiotis Kanavos
173 c53aa229 Panagiotis Kanavos
            CloudClient=new CloudFilesClient(UserName,ApiKey);
174 65282d58 Panagiotis Kanavos
            var proxy = ProxyFromSettings();            
175 65282d58 Panagiotis Kanavos
            CloudClient.Proxy = proxy;
176 74d78c90 Panagiotis Kanavos
            CloudClient.UsePithos = true;
177 c53aa229 Panagiotis Kanavos
            CloudClient.AuthenticationUrl = this.AuthenticationUrl;            
178 c53aa229 Panagiotis Kanavos
179 23821bd2 Panagiotis Kanavos
            _accountInfo = CloudClient.Authenticate();            
180 23821bd2 Panagiotis Kanavos
            _accountInfo.SiteUri = AuthenticationUrl;
181 c53aa229 Panagiotis Kanavos
            _accountInfo.AccountPath = RootPath;
182 c53aa229 Panagiotis Kanavos
183 5750d7cc Panagiotis Kanavos
184 5750d7cc Panagiotis Kanavos
            var pithosFolder = Path.Combine(RootPath, FolderConstants.PithosContainer);
185 5750d7cc Panagiotis Kanavos
            if (!Directory.Exists(pithosFolder))
186 5750d7cc Panagiotis Kanavos
                Directory.CreateDirectory(pithosFolder);
187 77e10b4f Panagiotis Kanavos
            //Create the cache folder and ensure it is hidden
188 77e10b4f Panagiotis Kanavos
            CreateHiddenFolder(RootPath, FolderConstants.CacheFolder);
189 77e10b4f Panagiotis Kanavos
190 0bd56b7c Panagiotis Kanavos
            var policy=CloudClient.GetAccountPolicies(_accountInfo);
191 c53aa229 Panagiotis Kanavos
192 0bd56b7c Panagiotis Kanavos
            StatusNotification.NotifyAccount(policy);
193 3c43ec9b Panagiotis Kanavos
            EnsurePithosContainers();
194 9c4346c9 Panagiotis Kanavos
            
195 5ce54458 Panagiotis Kanavos
            StatusKeeper.BlockHash = _blockHash;
196 5ce54458 Panagiotis Kanavos
            StatusKeeper.BlockSize = _blockSize;
197 9c4346c9 Panagiotis Kanavos
            
198 3c43ec9b Panagiotis Kanavos
            StatusKeeper.StartProcessing(_cancellationSource.Token);
199 c28a075a Panagiotis Kanavos
            IndexLocalFiles();
200 c28a075a Panagiotis Kanavos
            StartWatcherAgent();
201 c53aa229 Panagiotis Kanavos
202 c53aa229 Panagiotis Kanavos
            StartNetworkAgent();
203 70f12b36 Panagiotis Kanavos
            
204 c92e02f3 Panagiotis Kanavos
            WorkflowAgent.RestartInterruptedFiles(_accountInfo);
205 c92e02f3 Panagiotis Kanavos
            _started = true;
206 29672672 Panagiotis Kanavos
        }
207 29672672 Panagiotis Kanavos
208 3c43ec9b Panagiotis Kanavos
        private void EnsurePithosContainers()
209 3c43ec9b Panagiotis Kanavos
        {
210 3c43ec9b Panagiotis Kanavos
211 cfed7823 Panagiotis Kanavos
            //Create the two default containers if they are missing
212 c53aa229 Panagiotis Kanavos
            var pithosContainers = new List<string>{ FolderConstants.TrashContainer,FolderConstants.PithosContainer};
213 3c43ec9b Panagiotis Kanavos
            foreach (var container in pithosContainers)
214 cfed7823 Panagiotis Kanavos
            {                
215 cfed7823 Panagiotis Kanavos
                var info=CloudClient.GetContainerInfo(this.UserName, container);
216 5ce54458 Panagiotis Kanavos
                if (info == ContainerInfo.Empty)
217 5ce54458 Panagiotis Kanavos
                {
218 cfed7823 Panagiotis Kanavos
                    CloudClient.CreateContainer(this.UserName, container);
219 cfed7823 Panagiotis Kanavos
                    info = CloudClient.GetContainerInfo(this.UserName, container);
220 5ce54458 Panagiotis Kanavos
                }
221 5ce54458 Panagiotis Kanavos
                _blockSize = info.BlockSize;
222 5ce54458 Panagiotis Kanavos
                _blockHash = info.BlockHash;
223 c53aa229 Panagiotis Kanavos
                _accountInfo.BlockSize = _blockSize;
224 c53aa229 Panagiotis Kanavos
                _accountInfo.BlockHash = _blockHash;
225 3c43ec9b Panagiotis Kanavos
            }
226 3c43ec9b Panagiotis Kanavos
        }
227 3c43ec9b Panagiotis Kanavos
228 79736291 Panagiotis Kanavos
        public string AuthenticationUrl { get; set; }
229 79736291 Panagiotis Kanavos
230 65282d58 Panagiotis Kanavos
        private WebProxy ProxyFromSettings()
231 5bcf6d70 Panagiotis Kanavos
        {            
232 5bcf6d70 Panagiotis Kanavos
            if (Settings.UseManualProxy)
233 5bcf6d70 Panagiotis Kanavos
            {
234 65282d58 Panagiotis Kanavos
                var proxy = new WebProxy(Settings.ProxyServer, Settings.ProxyPort);
235 65282d58 Panagiotis Kanavos
                //If the proxy requires specific authentication settings, use them
236 5bcf6d70 Panagiotis Kanavos
                if (Settings.ProxyAuthentication)
237 5bcf6d70 Panagiotis Kanavos
                {
238 65282d58 Panagiotis Kanavos
                    proxy.Credentials=new NetworkCredential(Settings.ProxyUsername,Settings.ProxyPassword,Settings.ProxyDomain);
239 5bcf6d70 Panagiotis Kanavos
                }
240 65282d58 Panagiotis Kanavos
                    //Otherwise, if there are generic authentication settings, use them
241 65282d58 Panagiotis Kanavos
                if (!String.IsNullOrWhiteSpace(CredentialCache.DefaultNetworkCredentials.UserName))
242 65282d58 Panagiotis Kanavos
                {
243 65282d58 Panagiotis Kanavos
                    proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
244 65282d58 Panagiotis Kanavos
                }
245 65282d58 Panagiotis Kanavos
                return proxy;
246 5bcf6d70 Panagiotis Kanavos
            }
247 5bcf6d70 Panagiotis Kanavos
            return null;
248 5bcf6d70 Panagiotis Kanavos
        }
249 5bcf6d70 Panagiotis Kanavos
250 c28a075a Panagiotis Kanavos
        private void IndexLocalFiles()
251 b5061ac8 Panagiotis Kanavos
        {
252 0c02aa65 Panagiotis Kanavos
            StatusNotification.NotifyChange("Indexing Local Files",TraceLevel.Info);
253 5120f3cb Panagiotis Kanavos
            using (log4net.ThreadContext.Stacks["Monitor"].Push("Indexing local files"))
254 b5061ac8 Panagiotis Kanavos
            {
255 5120f3cb Panagiotis Kanavos
                Log.Info("START");
256 5120f3cb Panagiotis Kanavos
                try
257 5120f3cb Panagiotis Kanavos
                {
258 77e10b4f Panagiotis Kanavos
                    var cachePath = Path.Combine(RootPath, FolderConstants.CacheFolder);
259 c28a075a Panagiotis Kanavos
                    var directory = new DirectoryInfo(RootPath);
260 5120f3cb Panagiotis Kanavos
                    var files =
261 5120f3cb Panagiotis Kanavos
                        from file in directory.EnumerateFiles("*", SearchOption.AllDirectories)
262 77e10b4f Panagiotis Kanavos
                        where !file.FullName.StartsWith(cachePath, StringComparison.InvariantCultureIgnoreCase) &&
263 5120f3cb Panagiotis Kanavos
                              !file.Extension.Equals("ignore", StringComparison.InvariantCultureIgnoreCase)
264 5120f3cb Panagiotis Kanavos
                        select file;
265 5120f3cb Panagiotis Kanavos
                    StatusKeeper.ProcessExistingFiles(files);
266 5120f3cb Panagiotis Kanavos
267 5120f3cb Panagiotis Kanavos
                }
268 5120f3cb Panagiotis Kanavos
                catch (Exception exc)
269 5120f3cb Panagiotis Kanavos
                {
270 5120f3cb Panagiotis Kanavos
                    Log.Error("[ERROR]", exc);
271 5120f3cb Panagiotis Kanavos
                }
272 5120f3cb Panagiotis Kanavos
                finally
273 5120f3cb Panagiotis Kanavos
                {
274 5120f3cb Panagiotis Kanavos
                    Log.Info("[END]");
275 5120f3cb Panagiotis Kanavos
                }
276 b5061ac8 Panagiotis Kanavos
            }
277 b5061ac8 Panagiotis Kanavos
        }
278 b5061ac8 Panagiotis Kanavos
279 9c4346c9 Panagiotis Kanavos
        
280 c53aa229 Panagiotis Kanavos
  
281 eeee29e3 Panagiotis Kanavos
282 eeee29e3 Panagiotis Kanavos
283 70f12b36 Panagiotis Kanavos
       /* private void StartWorkflowAgent()
284 29672672 Panagiotis Kanavos
        {
285 65282d58 Panagiotis Kanavos
            WorkflowAgent.StatusNotification = StatusNotification;
286 65282d58 Panagiotis Kanavos
287 65282d58 Panagiotis Kanavos
/*            //On Vista and up we can check for a network connection
288 56b53955 Panagiotis Kanavos
            bool connected=Environment.OSVersion.Version.Major < 6 || NetworkListManager.IsConnectedToInternet;
289 29672672 Panagiotis Kanavos
            //If we are not connected retry later
290 29672672 Panagiotis Kanavos
            if (!connected)
291 29672672 Panagiotis Kanavos
            {
292 9c4346c9 Panagiotis Kanavos
                Task.Factory.StartNewDelayed(10000, StartWorkflowAgent);
293 29672672 Panagiotis Kanavos
                return;
294 70f12b36 Panagiotis Kanavos
            }#1#
295 29672672 Panagiotis Kanavos
296 29672672 Panagiotis Kanavos
            try
297 29672672 Panagiotis Kanavos
            {
298 9c4346c9 Panagiotis Kanavos
                WorkflowAgent.Start();                
299 29672672 Panagiotis Kanavos
            }
300 29672672 Panagiotis Kanavos
            catch (Exception)
301 29672672 Panagiotis Kanavos
            {
302 29672672 Panagiotis Kanavos
                //Faild to authenticate due to network or account error
303 29672672 Panagiotis Kanavos
                //Retry after a while
304 9c4346c9 Panagiotis Kanavos
                Task.Factory.StartNewDelayed(10000, StartWorkflowAgent);
305 29672672 Panagiotis Kanavos
            }
306 70f12b36 Panagiotis Kanavos
        }*/
307 d78cbf09 Panagiotis Kanavos
308 9c4346c9 Panagiotis Kanavos
        internal class LocalFileComparer:EqualityComparer<CloudAction>
309 d78cbf09 Panagiotis Kanavos
        {
310 9c4346c9 Panagiotis Kanavos
            public override bool Equals(CloudAction x, CloudAction y)
311 d78cbf09 Panagiotis Kanavos
            {
312 d78cbf09 Panagiotis Kanavos
                if (x.Action != y.Action)
313 d78cbf09 Panagiotis Kanavos
                    return false;
314 d78cbf09 Panagiotis Kanavos
                if (x.LocalFile != null && y.LocalFile != null && !x.LocalFile.FullName.Equals(y.LocalFile.FullName))
315 d78cbf09 Panagiotis Kanavos
                    return false;
316 0af3141d Panagiotis Kanavos
                if (x.CloudFile != null && y.CloudFile != null )
317 0af3141d Panagiotis Kanavos
                {
318 0af3141d Panagiotis Kanavos
                    if (x.CloudFile.Hash == null & y.CloudFile.Hash != null)
319 0af3141d Panagiotis Kanavos
                        return false;
320 0af3141d Panagiotis Kanavos
                    if (x.CloudFile.Hash != null & y.CloudFile.Hash == null)
321 0af3141d Panagiotis Kanavos
                        return false;
322 0af3141d Panagiotis Kanavos
                    if (x.CloudFile.Hash == null & y.CloudFile.Hash == null)
323 0af3141d Panagiotis Kanavos
                        return (x.CloudFile.Name == y.CloudFile.Name);
324 0af3141d Panagiotis Kanavos
                    if (!x.CloudFile.Hash.Equals(y.CloudFile.Hash))
325 0af3141d Panagiotis Kanavos
                        return false;
326 0af3141d Panagiotis Kanavos
                }
327 d78cbf09 Panagiotis Kanavos
                if (x.CloudFile == null ^ y.CloudFile == null ||
328 d78cbf09 Panagiotis Kanavos
                    x.LocalFile == null ^ y.LocalFile == null)
329 d78cbf09 Panagiotis Kanavos
                    return false;
330 d78cbf09 Panagiotis Kanavos
                return true;
331 d78cbf09 Panagiotis Kanavos
            }
332 d78cbf09 Panagiotis Kanavos
333 9c4346c9 Panagiotis Kanavos
            public override int GetHashCode(CloudAction obj)
334 d78cbf09 Panagiotis Kanavos
            {
335 d78cbf09 Panagiotis Kanavos
                var hash1 = (obj.LocalFile == null) ? int.MaxValue : obj.LocalFile.FullName.GetHashCode();
336 cfed7823 Panagiotis Kanavos
                var hash2 = (obj.CloudFile == null) ? int.MaxValue : (obj.CloudFile.Hash ?? obj.CloudFile.Name??"").GetHashCode();
337 d78cbf09 Panagiotis Kanavos
                var hash3 = obj.Action.GetHashCode();
338 d78cbf09 Panagiotis Kanavos
                return hash1 ^ hash2 & hash3;
339 d78cbf09 Panagiotis Kanavos
            }
340 9c4346c9 Panagiotis Kanavos
        }        
341 d78cbf09 Panagiotis Kanavos
342 d78cbf09 Panagiotis Kanavos
        private Timer timer;
343 d78cbf09 Panagiotis Kanavos
344 c53aa229 Panagiotis Kanavos
        private void StartNetworkAgent()
345 d78cbf09 Panagiotis Kanavos
        {
346 c53aa229 Panagiotis Kanavos
347 c53aa229 Panagiotis Kanavos
            NetworkAgent.AddAccount(_accountInfo);
348 c53aa229 Panagiotis Kanavos
349 9c4346c9 Panagiotis Kanavos
            NetworkAgent.StatusNotification = StatusNotification;
350 c28a075a Panagiotis Kanavos
                        
351 c53aa229 Panagiotis Kanavos
            NetworkAgent.Start();
352 d78cbf09 Panagiotis Kanavos
353 133f83c2 Panagiotis Kanavos
            NetworkAgent.PollRemoteFiles();
354 d78cbf09 Panagiotis Kanavos
        }
355 d78cbf09 Panagiotis Kanavos
356 77e10b4f Panagiotis Kanavos
        //Make sure a hidden cache folder exists to store partial downloads
357 5ce54458 Panagiotis Kanavos
        private static string CreateHiddenFolder(string rootPath, string folderName)
358 5ce54458 Panagiotis Kanavos
        {
359 5ce54458 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(rootPath))
360 5ce54458 Panagiotis Kanavos
                throw new ArgumentNullException("rootPath");
361 5ce54458 Panagiotis Kanavos
            if (!Path.IsPathRooted(rootPath))
362 5ce54458 Panagiotis Kanavos
                throw new ArgumentException("rootPath");
363 5ce54458 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(folderName))
364 5ce54458 Panagiotis Kanavos
                throw new ArgumentNullException("folderName");
365 5ce54458 Panagiotis Kanavos
            Contract.EndContractBlock();
366 5ce54458 Panagiotis Kanavos
367 5ce54458 Panagiotis Kanavos
            var folder = Path.Combine(rootPath, folderName);
368 5ce54458 Panagiotis Kanavos
            if (!Directory.Exists(folder))
369 5ce54458 Panagiotis Kanavos
            {
370 5ce54458 Panagiotis Kanavos
                var info = Directory.CreateDirectory(folder);
371 5ce54458 Panagiotis Kanavos
                info.Attributes |= FileAttributes.Hidden;
372 5ce54458 Panagiotis Kanavos
373 77e10b4f Panagiotis Kanavos
                Log.InfoFormat("Created cache Folder: {0}", folder);
374 77e10b4f Panagiotis Kanavos
            }
375 77e10b4f Panagiotis Kanavos
            else
376 77e10b4f Panagiotis Kanavos
            {
377 77e10b4f Panagiotis Kanavos
                var info = new DirectoryInfo(folder);
378 77e10b4f Panagiotis Kanavos
                if ((info.Attributes & FileAttributes.Hidden) == 0)
379 77e10b4f Panagiotis Kanavos
                {
380 77e10b4f Panagiotis Kanavos
                    info.Attributes |= FileAttributes.Hidden;
381 77e10b4f Panagiotis Kanavos
                    Log.InfoFormat("Reset cache folder to hidden: {0}", folder);
382 77e10b4f Panagiotis Kanavos
                }                                
383 5ce54458 Panagiotis Kanavos
            }
384 5ce54458 Panagiotis Kanavos
            return folder;
385 5ce54458 Panagiotis Kanavos
        }
386 5ce54458 Panagiotis Kanavos
387 b5061ac8 Panagiotis Kanavos
       
388 d78cbf09 Panagiotis Kanavos
389 d78cbf09 Panagiotis Kanavos
390 c28a075a Panagiotis Kanavos
        private void StartWatcherAgent()
391 d78cbf09 Panagiotis Kanavos
        {
392 c28a075a Panagiotis Kanavos
            AgentLocator<FileAgent>.Register(FileAgent,RootPath);
393 c28a075a Panagiotis Kanavos
394 5ce54458 Panagiotis Kanavos
            FileAgent.StatusKeeper = StatusKeeper;
395 5ce54458 Panagiotis Kanavos
            FileAgent.Workflow = Workflow;
396 77e10b4f Panagiotis Kanavos
            FileAgent.CachePath = Path.Combine(RootPath, FolderConstants.CacheFolder);
397 c28a075a Panagiotis Kanavos
            FileAgent.Start(_accountInfo, RootPath);
398 d78cbf09 Panagiotis Kanavos
        }
399 d78cbf09 Panagiotis Kanavos
400 d78cbf09 Panagiotis Kanavos
        public void Stop()
401 c28a075a Panagiotis Kanavos
        {
402 c28a075a Panagiotis Kanavos
            AgentLocator<FileAgent>.Remove(RootPath);
403 c28a075a Panagiotis Kanavos
404 c53aa229 Panagiotis Kanavos
            if (FileAgent!=null)
405 c53aa229 Panagiotis Kanavos
                FileAgent.Stop();
406 c53aa229 Panagiotis Kanavos
            FileAgent = null;
407 d78cbf09 Panagiotis Kanavos
            if (timer != null)
408 d78cbf09 Panagiotis Kanavos
                timer.Dispose();
409 c53aa229 Panagiotis Kanavos
            timer = null;            
410 d78cbf09 Panagiotis Kanavos
        }
411 d78cbf09 Panagiotis Kanavos
412 eeee29e3 Panagiotis Kanavos
413 d78cbf09 Panagiotis Kanavos
        ~PithosMonitor()
414 d78cbf09 Panagiotis Kanavos
        {
415 d78cbf09 Panagiotis Kanavos
            Dispose(false);
416 d78cbf09 Panagiotis Kanavos
        }
417 d78cbf09 Panagiotis Kanavos
418 d78cbf09 Panagiotis Kanavos
        public void Dispose()
419 d78cbf09 Panagiotis Kanavos
        {
420 d78cbf09 Panagiotis Kanavos
            Dispose(true);
421 d78cbf09 Panagiotis Kanavos
            GC.SuppressFinalize(this);
422 d78cbf09 Panagiotis Kanavos
        }
423 d78cbf09 Panagiotis Kanavos
424 d78cbf09 Panagiotis Kanavos
        protected virtual void Dispose(bool disposing)
425 d78cbf09 Panagiotis Kanavos
        {
426 d78cbf09 Panagiotis Kanavos
            if (disposing)
427 d78cbf09 Panagiotis Kanavos
            {
428 d78cbf09 Panagiotis Kanavos
                Stop();
429 d78cbf09 Panagiotis Kanavos
            }
430 d78cbf09 Panagiotis Kanavos
        }
431 d78cbf09 Panagiotis Kanavos
432 d78cbf09 Panagiotis Kanavos
433 5120f3cb Panagiotis Kanavos
        public void MoveFileStates(string oldPath, string newPath)
434 5120f3cb Panagiotis Kanavos
        {
435 5120f3cb Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(oldPath))
436 5120f3cb Panagiotis Kanavos
                throw new ArgumentNullException("oldPath");
437 5120f3cb Panagiotis Kanavos
            if (!Path.IsPathRooted(oldPath))
438 5120f3cb Panagiotis Kanavos
                throw new ArgumentException("oldPath must be an absolute path","oldPath");
439 5120f3cb Panagiotis Kanavos
            if (string.IsNullOrWhiteSpace(newPath))
440 5120f3cb Panagiotis Kanavos
                throw new ArgumentNullException("newPath");
441 5120f3cb Panagiotis Kanavos
            if (!Path.IsPathRooted(newPath))
442 5120f3cb Panagiotis Kanavos
                throw new ArgumentException("newPath must be an absolute path","newPath");
443 5120f3cb Panagiotis Kanavos
            Contract.EndContractBlock();
444 5120f3cb Panagiotis Kanavos
445 5120f3cb Panagiotis Kanavos
            StatusKeeper.ChangeRoots(oldPath, newPath);
446 5120f3cb Panagiotis Kanavos
        }
447 d3a13891 Panagiotis Kanavos
448 d3a13891 Panagiotis Kanavos
        public void AddSelectivePaths(string[] added)
449 d3a13891 Panagiotis Kanavos
        {
450 d3a13891 Panagiotis Kanavos
           /* FileAgent.SelectivePaths.AddRange(added);
451 d3a13891 Panagiotis Kanavos
            NetworkAgent.SyncPaths(added);*/
452 d3a13891 Panagiotis Kanavos
        }
453 d3a13891 Panagiotis Kanavos
454 d3a13891 Panagiotis Kanavos
        public void RemoveSelectivePaths(string[] removed)
455 d3a13891 Panagiotis Kanavos
        {
456 d3a13891 Panagiotis Kanavos
            FileAgent.SelectivePaths.RemoveAll(removed.Contains);
457 d3a13891 Panagiotis Kanavos
            foreach (var removedPath in removed.Where(Directory.Exists))
458 d3a13891 Panagiotis Kanavos
            {
459 d3a13891 Panagiotis Kanavos
                Directory.Delete(removedPath,true);
460 d3a13891 Panagiotis Kanavos
            }
461 d3a13891 Panagiotis Kanavos
        }
462 7e26c075 Panagiotis Kanavos
463 7e26c075 Panagiotis Kanavos
        public IEnumerable<string> GetRootFolders()
464 7e26c075 Panagiotis Kanavos
        {
465 ec6f3895 Panagiotis Kanavos
            var dirs = from container in CloudClient.ListContainers(UserName)
466 ec6f3895 Panagiotis Kanavos
                       from dir in CloudClient.ListObjects(UserName, container.Name, "")
467 ec6f3895 Panagiotis Kanavos
                       select dir.Name;
468 ec6f3895 Panagiotis Kanavos
            return dirs;
469 7e26c075 Panagiotis Kanavos
        }
470 7b0a5fec Panagiotis Kanavos
471 7b0a5fec Panagiotis Kanavos
        public ObjectInfo GetObjectInfo(string filePath)
472 7b0a5fec Panagiotis Kanavos
        {
473 7b0a5fec Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(filePath))
474 7b0a5fec Panagiotis Kanavos
                throw new ArgumentNullException("filePath");
475 7b0a5fec Panagiotis Kanavos
            Contract.EndContractBlock();
476 7b0a5fec Panagiotis Kanavos
477 7b0a5fec Panagiotis Kanavos
            var file=new FileInfo(filePath);
478 7b0a5fec Panagiotis Kanavos
            string relativeUrl;//=file.AsRelativeUrlTo(this.RootPath);
479 7b0a5fec Panagiotis Kanavos
            var relativePath = file.AsRelativeTo(RootPath);
480 7b0a5fec Panagiotis Kanavos
            
481 7b0a5fec Panagiotis Kanavos
            string accountName,container;
482 7b0a5fec Panagiotis Kanavos
            
483 7b0a5fec Panagiotis Kanavos
            var parts=relativePath.Split('\\');
484 7b0a5fec Panagiotis Kanavos
485 7b0a5fec Panagiotis Kanavos
            var accountInfo = _accountInfo;
486 7b0a5fec Panagiotis Kanavos
            if (relativePath.StartsWith(FolderConstants.OthersFolder))
487 7b0a5fec Panagiotis Kanavos
            {                
488 7b0a5fec Panagiotis Kanavos
                accountName = parts[1];
489 7b0a5fec Panagiotis Kanavos
                container = parts[2];
490 7b0a5fec Panagiotis Kanavos
                relativeUrl = String.Join("/", parts.Splice(3));
491 7b0a5fec Panagiotis Kanavos
                //Create the root URL for the target account
492 7b0a5fec Panagiotis Kanavos
                var oldName = UserName;
493 7b0a5fec Panagiotis Kanavos
                var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;
494 7b0a5fec Panagiotis Kanavos
                var nameIndex=absoluteUri.IndexOf(oldName);
495 7b0a5fec Panagiotis Kanavos
                var root=absoluteUri.Substring(0, nameIndex);
496 7b0a5fec Panagiotis Kanavos
497 7b0a5fec Panagiotis Kanavos
                accountInfo = new AccountInfo
498 7b0a5fec Panagiotis Kanavos
                {
499 7b0a5fec Panagiotis Kanavos
                    UserName = accountName,
500 7b0a5fec Panagiotis Kanavos
                    AccountPath = Path.Combine(accountInfo.AccountPath, parts[0], parts[1]),
501 7b0a5fec Panagiotis Kanavos
                    StorageUri = new Uri(root + accountName),
502 7b0a5fec Panagiotis Kanavos
                    BlockHash=accountInfo.BlockHash,
503 7b0a5fec Panagiotis Kanavos
                    BlockSize=accountInfo.BlockSize,
504 7b0a5fec Panagiotis Kanavos
                    Token=accountInfo.Token
505 7b0a5fec Panagiotis Kanavos
                };
506 7b0a5fec Panagiotis Kanavos
            }
507 7b0a5fec Panagiotis Kanavos
            else
508 7b0a5fec Panagiotis Kanavos
            {
509 7b0a5fec Panagiotis Kanavos
                accountName = this.UserName;
510 7b0a5fec Panagiotis Kanavos
                container = parts[0];
511 7b0a5fec Panagiotis Kanavos
                relativeUrl = String.Join("/", parts.Splice(1));
512 7b0a5fec Panagiotis Kanavos
            }
513 42800be8 Panagiotis Kanavos
            
514 7b0a5fec Panagiotis Kanavos
            var client = new CloudFilesClient(accountInfo);
515 7b0a5fec Panagiotis Kanavos
            var objectInfo=client.GetObjectInfo(accountName, container, relativeUrl);
516 7b0a5fec Panagiotis Kanavos
            return objectInfo;
517 7b0a5fec Panagiotis Kanavos
        }
518 42800be8 Panagiotis Kanavos
        
519 c92e02f3 Panagiotis Kanavos
        public Task<ContainerInfo> GetContainerInfo(string filePath)
520 42800be8 Panagiotis Kanavos
        {
521 42800be8 Panagiotis Kanavos
            if (String.IsNullOrWhiteSpace(filePath))
522 42800be8 Panagiotis Kanavos
                throw new ArgumentNullException("filePath");
523 42800be8 Panagiotis Kanavos
            Contract.EndContractBlock();
524 42800be8 Panagiotis Kanavos
525 42800be8 Panagiotis Kanavos
            var file=new FileInfo(filePath);
526 42800be8 Panagiotis Kanavos
            var relativePath = file.AsRelativeTo(RootPath);
527 42800be8 Panagiotis Kanavos
            
528 42800be8 Panagiotis Kanavos
            string accountName,container;
529 42800be8 Panagiotis Kanavos
            
530 42800be8 Panagiotis Kanavos
            var parts=relativePath.Split('\\');
531 42800be8 Panagiotis Kanavos
532 42800be8 Panagiotis Kanavos
            var accountInfo = _accountInfo;
533 42800be8 Panagiotis Kanavos
            if (relativePath.StartsWith(FolderConstants.OthersFolder))
534 42800be8 Panagiotis Kanavos
            {                
535 42800be8 Panagiotis Kanavos
                accountName = parts[1];
536 42800be8 Panagiotis Kanavos
                container = parts[2];                
537 42800be8 Panagiotis Kanavos
                //Create the root URL for the target account
538 42800be8 Panagiotis Kanavos
                var oldName = UserName;
539 42800be8 Panagiotis Kanavos
                var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;
540 42800be8 Panagiotis Kanavos
                var nameIndex=absoluteUri.IndexOf(oldName);
541 42800be8 Panagiotis Kanavos
                var root=absoluteUri.Substring(0, nameIndex);
542 42800be8 Panagiotis Kanavos
543 42800be8 Panagiotis Kanavos
                accountInfo = new AccountInfo
544 42800be8 Panagiotis Kanavos
                {
545 42800be8 Panagiotis Kanavos
                    UserName = accountName,
546 42800be8 Panagiotis Kanavos
                    AccountPath = Path.Combine(accountInfo.AccountPath, parts[0], parts[1]),
547 42800be8 Panagiotis Kanavos
                    StorageUri = new Uri(root + accountName),
548 42800be8 Panagiotis Kanavos
                    BlockHash=accountInfo.BlockHash,
549 42800be8 Panagiotis Kanavos
                    BlockSize=accountInfo.BlockSize,
550 42800be8 Panagiotis Kanavos
                    Token=accountInfo.Token
551 42800be8 Panagiotis Kanavos
                };
552 42800be8 Panagiotis Kanavos
            }
553 42800be8 Panagiotis Kanavos
            else
554 42800be8 Panagiotis Kanavos
            {
555 42800be8 Panagiotis Kanavos
                accountName = UserName;
556 42800be8 Panagiotis Kanavos
                container = parts[0];                
557 42800be8 Panagiotis Kanavos
            }
558 c92e02f3 Panagiotis Kanavos
559 c92e02f3 Panagiotis Kanavos
            return Task.Factory.StartNew(() =>
560 c92e02f3 Panagiotis Kanavos
            {
561 c92e02f3 Panagiotis Kanavos
                var client = new CloudFilesClient(accountInfo);
562 c92e02f3 Panagiotis Kanavos
                var containerInfo = client.GetContainerInfo(accountName, container);
563 c92e02f3 Panagiotis Kanavos
                return containerInfo;
564 c92e02f3 Panagiotis Kanavos
            });
565 42800be8 Panagiotis Kanavos
        }
566 d78cbf09 Panagiotis Kanavos
    }
567 d78cbf09 Panagiotis Kanavos
}