Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / PithosMonitor.cs @ 3c43ec9b

History | View | Annotate | Download (26.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 29672672 Panagiotis Kanavos
using System.Net.NetworkInformation;
10 d78cbf09 Panagiotis Kanavos
using System.Security.Cryptography;
11 5bcf6d70 Panagiotis Kanavos
using System.ServiceModel.Description;
12 d78cbf09 Panagiotis Kanavos
using System.Text;
13 d78cbf09 Panagiotis Kanavos
using System.Threading;
14 d78cbf09 Panagiotis Kanavos
using System.Threading.Tasks;
15 0eea575a Panagiotis Kanavos
using Castle.ActiveRecord.Queries;
16 637bc368 Panagiotis Kanavos
using Microsoft.WindowsAPICodePack.Net;
17 d78cbf09 Panagiotis Kanavos
using Pithos.Interfaces;
18 eeee29e3 Panagiotis Kanavos
using System.ServiceModel;
19 d78cbf09 Panagiotis Kanavos
20 d78cbf09 Panagiotis Kanavos
namespace Pithos.Core
21 d78cbf09 Panagiotis Kanavos
{
22 d78cbf09 Panagiotis Kanavos
    [Export(typeof(PithosMonitor))]
23 d78cbf09 Panagiotis Kanavos
    public class PithosMonitor:IDisposable
24 d78cbf09 Panagiotis Kanavos
    {
25 3c43ec9b Panagiotis Kanavos
        private const string PithosContainer = "pithos";
26 3c43ec9b Panagiotis Kanavos
        private const string TrashContainer = "trash";
27 3c43ec9b Panagiotis Kanavos
28 d78cbf09 Panagiotis Kanavos
        [Import]
29 d78cbf09 Panagiotis Kanavos
        public IPithosSettings Settings{get;set;}
30 d78cbf09 Panagiotis Kanavos
31 d78cbf09 Panagiotis Kanavos
        [Import]
32 d78cbf09 Panagiotis Kanavos
        public IStatusKeeper StatusKeeper { get; set; }
33 d78cbf09 Panagiotis Kanavos
34 d78cbf09 Panagiotis Kanavos
        [Import]
35 d78cbf09 Panagiotis Kanavos
        public IPithosWorkflow Workflow { get; set; }
36 d78cbf09 Panagiotis Kanavos
37 d78cbf09 Panagiotis Kanavos
        [Import]
38 d78cbf09 Panagiotis Kanavos
        public ICloudClient CloudClient { get; set; }
39 d78cbf09 Panagiotis Kanavos
40 d78cbf09 Panagiotis Kanavos
        [Import]
41 d78cbf09 Panagiotis Kanavos
        public ICloudClient CloudListeningClient { get; set; }
42 d78cbf09 Panagiotis Kanavos
43 0eea575a Panagiotis Kanavos
        public string UserName { get; set; }
44 0eea575a Panagiotis Kanavos
        public string ApiKey { get; set; }
45 0eea575a Panagiotis Kanavos
46 eeee29e3 Panagiotis Kanavos
        private ServiceHost _statusService { get; set; }
47 eeee29e3 Panagiotis Kanavos
48 d78cbf09 Panagiotis Kanavos
        private FileSystemWatcher _watcher;
49 d78cbf09 Panagiotis Kanavos
50 d78cbf09 Panagiotis Kanavos
        public bool Pause
51 d78cbf09 Panagiotis Kanavos
        {
52 d78cbf09 Panagiotis Kanavos
            get { return _watcher == null || !_watcher.EnableRaisingEvents; }
53 d78cbf09 Panagiotis Kanavos
            set
54 d78cbf09 Panagiotis Kanavos
            {
55 d78cbf09 Panagiotis Kanavos
                if (_watcher!=null)
56 5bcf6d70 Panagiotis Kanavos
                    _watcher.EnableRaisingEvents = !value;
57 5bcf6d70 Panagiotis Kanavos
                if (value)
58 5bcf6d70 Panagiotis Kanavos
                {
59 5bcf6d70 Panagiotis Kanavos
                    StatusKeeper.SetPithosStatus(PithosStatus.SyncPaused);
60 5bcf6d70 Panagiotis Kanavos
                }
61 5bcf6d70 Panagiotis Kanavos
                else
62 5bcf6d70 Panagiotis Kanavos
                {
63 5bcf6d70 Panagiotis Kanavos
                    StatusKeeper.SetPithosStatus(PithosStatus.InSynch);
64 5bcf6d70 Panagiotis Kanavos
                }
65 d78cbf09 Panagiotis Kanavos
            }
66 d78cbf09 Panagiotis Kanavos
        }
67 d78cbf09 Panagiotis Kanavos
68 0eea575a Panagiotis Kanavos
        public string RootPath { get; set; }
69 0eea575a Panagiotis Kanavos
70 d78cbf09 Panagiotis Kanavos
71 d78cbf09 Panagiotis Kanavos
        CancellationTokenSource _cancellationSource;
72 d78cbf09 Panagiotis Kanavos
73 29672672 Panagiotis Kanavos
        readonly BlockingCollection<WorkflowState> _fileEvents = new BlockingCollection<WorkflowState>();
74 29672672 Panagiotis Kanavos
        readonly BlockingCollection<WorkflowState> _uploadEvents = new BlockingCollection<WorkflowState>();
75 d78cbf09 Panagiotis Kanavos
76 d78cbf09 Panagiotis Kanavos
        
77 d78cbf09 Panagiotis Kanavos
78 d78cbf09 Panagiotis Kanavos
        public void Start()
79 d78cbf09 Panagiotis Kanavos
        {
80 d78cbf09 Panagiotis Kanavos
81 d78cbf09 Panagiotis Kanavos
            if (_cancellationSource != null)
82 d78cbf09 Panagiotis Kanavos
            {
83 d78cbf09 Panagiotis Kanavos
                if (!_cancellationSource.IsCancellationRequested)
84 d78cbf09 Panagiotis Kanavos
                    return;
85 d78cbf09 Panagiotis Kanavos
            }
86 29672672 Panagiotis Kanavos
            _cancellationSource = new CancellationTokenSource();
87 d78cbf09 Panagiotis Kanavos
88 5bcf6d70 Panagiotis Kanavos
            var proxyUri = ProxyFromSettings();            
89 5bcf6d70 Panagiotis Kanavos
            CloudClient.Proxy = proxyUri;
90 3c43ec9b Panagiotis Kanavos
            CloudClient.UsePithos = this.UsePithos;
91 3c43ec9b Panagiotis Kanavos
            EnsurePithosContainers();
92 3c43ec9b Panagiotis Kanavos
            StatusKeeper.StartProcessing(_cancellationSource.Token);
93 0eea575a Panagiotis Kanavos
            IndexLocalFiles(RootPath);
94 0eea575a Panagiotis Kanavos
            StartMonitoringFiles(RootPath);
95 d78cbf09 Panagiotis Kanavos
96 eeee29e3 Panagiotis Kanavos
            StartStatusService();
97 eeee29e3 Panagiotis Kanavos
98 29672672 Panagiotis Kanavos
            StartNetwork();
99 29672672 Panagiotis Kanavos
        }
100 29672672 Panagiotis Kanavos
101 3c43ec9b Panagiotis Kanavos
        private void EnsurePithosContainers()
102 3c43ec9b Panagiotis Kanavos
        {
103 3c43ec9b Panagiotis Kanavos
            CloudClient.UsePithos = this.UsePithos;
104 3c43ec9b Panagiotis Kanavos
            CloudClient.Authenticate(UserName, ApiKey);
105 3c43ec9b Panagiotis Kanavos
106 3c43ec9b Panagiotis Kanavos
            var pithosContainers = new[] {PithosContainer, TrashContainer};
107 3c43ec9b Panagiotis Kanavos
            foreach (var container in pithosContainers)
108 3c43ec9b Panagiotis Kanavos
            {
109 3c43ec9b Panagiotis Kanavos
                if (!CloudClient.ContainerExists(container))
110 3c43ec9b Panagiotis Kanavos
                    CloudClient.CreateContainer(container);                
111 3c43ec9b Panagiotis Kanavos
            }
112 3c43ec9b Panagiotis Kanavos
        }
113 3c43ec9b Panagiotis Kanavos
114 5bcf6d70 Panagiotis Kanavos
        private Uri ProxyFromSettings()
115 5bcf6d70 Panagiotis Kanavos
        {            
116 5bcf6d70 Panagiotis Kanavos
            if (Settings.UseManualProxy)
117 5bcf6d70 Panagiotis Kanavos
            {
118 5bcf6d70 Panagiotis Kanavos
                var proxyUri = new UriBuilder
119 5bcf6d70 Panagiotis Kanavos
                                   {
120 5bcf6d70 Panagiotis Kanavos
                                       Host = Settings.ProxyServer, 
121 5bcf6d70 Panagiotis Kanavos
                                       Port = Settings.ProxyPort
122 5bcf6d70 Panagiotis Kanavos
                                   };
123 5bcf6d70 Panagiotis Kanavos
                if (Settings.ProxyAuthentication)
124 5bcf6d70 Panagiotis Kanavos
                {
125 5bcf6d70 Panagiotis Kanavos
                    proxyUri.UserName = Settings.ProxyUsername;
126 5bcf6d70 Panagiotis Kanavos
                    proxyUri.Password = Settings.ProxyPassword;
127 5bcf6d70 Panagiotis Kanavos
                }
128 5bcf6d70 Panagiotis Kanavos
                return proxyUri.Uri;
129 5bcf6d70 Panagiotis Kanavos
            }
130 5bcf6d70 Panagiotis Kanavos
            return null;
131 5bcf6d70 Panagiotis Kanavos
        }
132 5bcf6d70 Panagiotis Kanavos
133 b5061ac8 Panagiotis Kanavos
        private void IndexLocalFiles(string path)
134 b5061ac8 Panagiotis Kanavos
        {
135 b5061ac8 Panagiotis Kanavos
            Trace.TraceInformation("[START] Inxed Local");
136 b5061ac8 Panagiotis Kanavos
            try
137 b5061ac8 Panagiotis Kanavos
            {
138 b5061ac8 Panagiotis Kanavos
                var files =
139 b5061ac8 Panagiotis Kanavos
                    from filePath in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories).AsParallel()
140 b5061ac8 Panagiotis Kanavos
                    select filePath;
141 b5061ac8 Panagiotis Kanavos
                StatusKeeper.StoreUnversionedFiles(files);
142 b5061ac8 Panagiotis Kanavos
143 0eea575a Panagiotis Kanavos
                RestartInterruptedFiles();
144 b5061ac8 Panagiotis Kanavos
            }
145 b5061ac8 Panagiotis Kanavos
            catch (Exception exc)
146 b5061ac8 Panagiotis Kanavos
            {
147 b5061ac8 Panagiotis Kanavos
                Trace.TraceError("[ERROR] Index Local - {0}", exc);
148 b5061ac8 Panagiotis Kanavos
            }
149 b5061ac8 Panagiotis Kanavos
            finally
150 b5061ac8 Panagiotis Kanavos
            {
151 b5061ac8 Panagiotis Kanavos
                Trace.TraceInformation("[END] Inxed Local");
152 b5061ac8 Panagiotis Kanavos
            }
153 b5061ac8 Panagiotis Kanavos
        }
154 b5061ac8 Panagiotis Kanavos
155 0eea575a Panagiotis Kanavos
        private void RestartInterruptedFiles()
156 0eea575a Panagiotis Kanavos
        {
157 3c43ec9b Panagiotis Kanavos
            var interruptedStates = new[] { FileOverlayStatus.Unversioned, FileOverlayStatus.Modified };
158 0eea575a Panagiotis Kanavos
            var filesQuery = from state in FileState.Queryable
159 0eea575a Panagiotis Kanavos
                             where interruptedStates.Contains(state.OverlayStatus)
160 0eea575a Panagiotis Kanavos
                             select new WorkflowState
161 0eea575a Panagiotis Kanavos
                                      {
162 0eea575a Panagiotis Kanavos
                                          Path = state.FilePath.ToLower(),
163 0eea575a Panagiotis Kanavos
                                          FileName = Path.GetFileName(state.FilePath).ToLower(),
164 0eea575a Panagiotis Kanavos
                                          Status=state.OverlayStatus==FileOverlayStatus.Unversioned?
165 0eea575a Panagiotis Kanavos
                                                            FileStatus.Created:
166 0eea575a Panagiotis Kanavos
                                                            FileStatus.Modified,
167 0eea575a Panagiotis Kanavos
                                          TriggeringChange = state.OverlayStatus==FileOverlayStatus.Unversioned?
168 0eea575a Panagiotis Kanavos
                                                            WatcherChangeTypes.Created:
169 0eea575a Panagiotis Kanavos
                                                            WatcherChangeTypes.Changed
170 0eea575a Panagiotis Kanavos
                                      };
171 0eea575a Panagiotis Kanavos
            _uploadEvents.AddFromEnumerable(filesQuery,false);           
172 0eea575a Panagiotis Kanavos
            
173 0eea575a Panagiotis Kanavos
        }
174 0eea575a Panagiotis Kanavos
175 eeee29e3 Panagiotis Kanavos
        private void StartStatusService()
176 eeee29e3 Panagiotis Kanavos
        {
177 eeee29e3 Panagiotis Kanavos
            // Create a ServiceHost for the CalculatorService type and provide the base address.
178 5bcf6d70 Panagiotis Kanavos
            var baseAddress = new Uri("net.pipe://localhost/pithos");
179 5bcf6d70 Panagiotis Kanavos
            _statusService = new ServiceHost(typeof(StatusService), baseAddress);
180 eeee29e3 Panagiotis Kanavos
            
181 5bcf6d70 Panagiotis Kanavos
            var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
182 5bcf6d70 Panagiotis Kanavos
            
183 5bcf6d70 Panagiotis Kanavos
            _statusService.AddServiceEndpoint(typeof(IStatusService), binding, "net.pipe://localhost/pithos/statuscache");
184 5bcf6d70 Panagiotis Kanavos
            _statusService.AddServiceEndpoint(typeof (ISettingsService), binding, "net.pipe://localhost/pithos/settings");
185 5bcf6d70 Panagiotis Kanavos
186 5bcf6d70 Panagiotis Kanavos
187 5bcf6d70 Panagiotis Kanavos
            //// Add a mex endpoint
188 5bcf6d70 Panagiotis Kanavos
            var smb = new ServiceMetadataBehavior
189 5bcf6d70 Panagiotis Kanavos
                          {
190 5bcf6d70 Panagiotis Kanavos
                              HttpGetEnabled = true, 
191 5bcf6d70 Panagiotis Kanavos
                              HttpGetUrl = new Uri("http://localhost:30000/pithos/mex")
192 5bcf6d70 Panagiotis Kanavos
                          };
193 5bcf6d70 Panagiotis Kanavos
            _statusService.Description.Behaviors.Add(smb);
194 5bcf6d70 Panagiotis Kanavos
195 5bcf6d70 Panagiotis Kanavos
196 eeee29e3 Panagiotis Kanavos
            _statusService.Open();
197 eeee29e3 Panagiotis Kanavos
        }
198 eeee29e3 Panagiotis Kanavos
199 eeee29e3 Panagiotis Kanavos
        private void StopStatusService()
200 eeee29e3 Panagiotis Kanavos
        {
201 eeee29e3 Panagiotis Kanavos
            if (_statusService == null)
202 eeee29e3 Panagiotis Kanavos
                return;
203 eeee29e3 Panagiotis Kanavos
204 eeee29e3 Panagiotis Kanavos
            if (_statusService.State == CommunicationState.Faulted)
205 eeee29e3 Panagiotis Kanavos
                _statusService.Abort();
206 eeee29e3 Panagiotis Kanavos
            else if (_statusService.State != CommunicationState.Closed)
207 eeee29e3 Panagiotis Kanavos
                _statusService.Close();
208 eeee29e3 Panagiotis Kanavos
            _statusService = null;
209 eeee29e3 Panagiotis Kanavos
210 eeee29e3 Panagiotis Kanavos
        }
211 eeee29e3 Panagiotis Kanavos
212 eeee29e3 Panagiotis Kanavos
213 29672672 Panagiotis Kanavos
        private void StartNetwork()
214 29672672 Panagiotis Kanavos
        {
215 637bc368 Panagiotis Kanavos
216 637bc368 Panagiotis Kanavos
            bool connected = NetworkListManager.IsConnectedToInternet;
217 29672672 Panagiotis Kanavos
            //If we are not connected retry later
218 29672672 Panagiotis Kanavos
            if (!connected)
219 29672672 Panagiotis Kanavos
            {
220 29672672 Panagiotis Kanavos
                Task.Factory.StartNewDelayed(10000, StartNetwork);
221 29672672 Panagiotis Kanavos
                return;
222 29672672 Panagiotis Kanavos
            }
223 29672672 Panagiotis Kanavos
224 29672672 Panagiotis Kanavos
            try
225 29672672 Panagiotis Kanavos
            {
226 3c43ec9b Panagiotis Kanavos
                CloudClient.UsePithos = this.UsePithos;
227 0eea575a Panagiotis Kanavos
                CloudClient.Authenticate(UserName, ApiKey);
228 29672672 Panagiotis Kanavos
229 0eea575a Panagiotis Kanavos
                StartListening(RootPath);
230 29672672 Panagiotis Kanavos
                StartSending();
231 29672672 Panagiotis Kanavos
            }
232 29672672 Panagiotis Kanavos
            catch (Exception)
233 29672672 Panagiotis Kanavos
            {
234 29672672 Panagiotis Kanavos
                //Faild to authenticate due to network or account error
235 29672672 Panagiotis Kanavos
                //Retry after a while
236 29672672 Panagiotis Kanavos
                Task.Factory.StartNewDelayed(10000, StartNetwork);
237 29672672 Panagiotis Kanavos
            }
238 d78cbf09 Panagiotis Kanavos
        }
239 d78cbf09 Panagiotis Kanavos
240 3c43ec9b Panagiotis Kanavos
        public bool UsePithos { get; set; }
241 3c43ec9b Panagiotis Kanavos
242 d78cbf09 Panagiotis Kanavos
        internal enum CloudActionType
243 d78cbf09 Panagiotis Kanavos
        {
244 d78cbf09 Panagiotis Kanavos
            Upload=0,
245 d78cbf09 Panagiotis Kanavos
            Download,
246 d78cbf09 Panagiotis Kanavos
            UploadUnconditional,
247 d78cbf09 Panagiotis Kanavos
            DownloadUnconditional,
248 d78cbf09 Panagiotis Kanavos
            DeleteLocal,
249 d78cbf09 Panagiotis Kanavos
            DeleteCloud
250 d78cbf09 Panagiotis Kanavos
        }
251 d78cbf09 Panagiotis Kanavos
252 d78cbf09 Panagiotis Kanavos
        internal class ListenerAction
253 d78cbf09 Panagiotis Kanavos
        {
254 d78cbf09 Panagiotis Kanavos
            public CloudActionType Action { get; set; }
255 d78cbf09 Panagiotis Kanavos
            public FileInfo LocalFile { get; set; }
256 d78cbf09 Panagiotis Kanavos
            public ObjectInfo CloudFile { get; set; }
257 d78cbf09 Panagiotis Kanavos
258 d78cbf09 Panagiotis Kanavos
            public Lazy<string> LocalHash { get; set; }
259 d78cbf09 Panagiotis Kanavos
260 d78cbf09 Panagiotis Kanavos
            public ListenerAction(CloudActionType action, FileInfo localFile, ObjectInfo cloudFile)
261 d78cbf09 Panagiotis Kanavos
            {
262 d78cbf09 Panagiotis Kanavos
                Action = action;
263 d78cbf09 Panagiotis Kanavos
                LocalFile = localFile;
264 d78cbf09 Panagiotis Kanavos
                CloudFile = cloudFile;
265 b5061ac8 Panagiotis Kanavos
                LocalHash=new Lazy<string>(()=>Signature.CalculateHash(LocalFile.FullName),LazyThreadSafetyMode.ExecutionAndPublication);
266 d78cbf09 Panagiotis Kanavos
            }
267 d78cbf09 Panagiotis Kanavos
            
268 d78cbf09 Panagiotis Kanavos
        }
269 d78cbf09 Panagiotis Kanavos
270 d78cbf09 Panagiotis Kanavos
        internal class LocalFileComparer:EqualityComparer<ListenerAction>
271 d78cbf09 Panagiotis Kanavos
        {
272 d78cbf09 Panagiotis Kanavos
            public override bool Equals(ListenerAction x, ListenerAction y)
273 d78cbf09 Panagiotis Kanavos
            {
274 d78cbf09 Panagiotis Kanavos
                if (x.Action != y.Action)
275 d78cbf09 Panagiotis Kanavos
                    return false;
276 d78cbf09 Panagiotis Kanavos
                if (x.LocalFile != null && y.LocalFile != null && !x.LocalFile.FullName.Equals(y.LocalFile.FullName))
277 d78cbf09 Panagiotis Kanavos
                    return false;
278 d78cbf09 Panagiotis Kanavos
                if (x.CloudFile != null && y.CloudFile != null && !x.CloudFile.Hash.Equals(y.CloudFile.Hash))
279 d78cbf09 Panagiotis Kanavos
                    return false;
280 d78cbf09 Panagiotis Kanavos
                if (x.CloudFile == null ^ y.CloudFile == null ||
281 d78cbf09 Panagiotis Kanavos
                    x.LocalFile == null ^ y.LocalFile == null)
282 d78cbf09 Panagiotis Kanavos
                    return false;
283 d78cbf09 Panagiotis Kanavos
                return true;
284 d78cbf09 Panagiotis Kanavos
            }
285 d78cbf09 Panagiotis Kanavos
286 d78cbf09 Panagiotis Kanavos
            public override int GetHashCode(ListenerAction obj)
287 d78cbf09 Panagiotis Kanavos
            {
288 d78cbf09 Panagiotis Kanavos
                var hash1 = (obj.LocalFile == null) ? int.MaxValue : obj.LocalFile.FullName.GetHashCode();
289 d78cbf09 Panagiotis Kanavos
                var hash2 = (obj.CloudFile == null) ? int.MaxValue : obj.CloudFile.Hash.GetHashCode();
290 d78cbf09 Panagiotis Kanavos
                var hash3 = obj.Action.GetHashCode();
291 d78cbf09 Panagiotis Kanavos
                return hash1 ^ hash2 & hash3;
292 d78cbf09 Panagiotis Kanavos
            }
293 d78cbf09 Panagiotis Kanavos
        }
294 d78cbf09 Panagiotis Kanavos
295 283809f3 Panagiotis Kanavos
        private BlockingCollection<ListenerAction> _networkActions=new BlockingCollection<ListenerAction>();
296 d78cbf09 Panagiotis Kanavos
297 d78cbf09 Panagiotis Kanavos
        private Timer timer;
298 d78cbf09 Panagiotis Kanavos
299 b5061ac8 Panagiotis Kanavos
        private void StartListening(string accountPath)
300 d78cbf09 Panagiotis Kanavos
        {
301 d78cbf09 Panagiotis Kanavos
            
302 b5061ac8 Panagiotis Kanavos
            ProcessRemoteFiles(accountPath);
303 b5061ac8 Panagiotis Kanavos
304 b5061ac8 Panagiotis Kanavos
            Task.Factory.StartNew(ProcessListenerActions);
305 b5061ac8 Panagiotis Kanavos
                        
306 b5061ac8 Panagiotis Kanavos
        }
307 b5061ac8 Panagiotis Kanavos
308 b5061ac8 Panagiotis Kanavos
        private Task ProcessRemoteFiles(string accountPath)
309 b5061ac8 Panagiotis Kanavos
        {
310 b5061ac8 Panagiotis Kanavos
            Trace.TraceInformation("[LISTENER] Scheduled");    
311 b5061ac8 Panagiotis Kanavos
            return Task.Factory.StartNewDelayed(10000)
312 3c43ec9b Panagiotis Kanavos
                .ContinueWith(t=>CloudClient.ListObjects(PithosContainer))
313 d78cbf09 Panagiotis Kanavos
                .ContinueWith(task =>
314 d78cbf09 Panagiotis Kanavos
                                  {
315 b5061ac8 Panagiotis Kanavos
                                      Trace.TraceInformation("[LISTENER] Start Processing");
316 b5061ac8 Panagiotis Kanavos
317 b5061ac8 Panagiotis Kanavos
                                      var remoteObjects = task.Result;
318 b5061ac8 Panagiotis Kanavos
/*
319 b5061ac8 Panagiotis Kanavos
                                      if (remoteObjects.Count == 0)
320 d78cbf09 Panagiotis Kanavos
                                          return;
321 b5061ac8 Panagiotis Kanavos
*/
322 d78cbf09 Panagiotis Kanavos
323 b5061ac8 Panagiotis Kanavos
                                      var pithosDir = new DirectoryInfo(accountPath);
324 d78cbf09 Panagiotis Kanavos
                                      
325 b5061ac8 Panagiotis Kanavos
                                      var remoteFiles = from info in remoteObjects
326 283809f3 Panagiotis Kanavos
                                                    select info.Name.ToLower();
327 d78cbf09 Panagiotis Kanavos
                                      
328 d78cbf09 Panagiotis Kanavos
                                      var onlyLocal = from localFile in pithosDir.EnumerateFiles()
329 283809f3 Panagiotis Kanavos
                                                      where !remoteFiles.Contains(localFile.Name.ToLower()) 
330 d78cbf09 Panagiotis Kanavos
                                                      select new ListenerAction(CloudActionType.UploadUnconditional, localFile,null);
331 d78cbf09 Panagiotis Kanavos
332 283809f3 Panagiotis Kanavos
333 283809f3 Panagiotis Kanavos
334 283809f3 Panagiotis Kanavos
                                      var localNames = from info in pithosDir.EnumerateFiles()
335 283809f3 Panagiotis Kanavos
                                                           select info.Name.ToLower();
336 283809f3 Panagiotis Kanavos
337 b5061ac8 Panagiotis Kanavos
                                      var onlyRemote = from upFile in remoteObjects
338 283809f3 Panagiotis Kanavos
                                                       where !localNames.Contains(upFile.Name.ToLower())
339 d78cbf09 Panagiotis Kanavos
                                                       select new ListenerAction(CloudActionType.DownloadUnconditional,null,upFile);
340 d78cbf09 Panagiotis Kanavos
341 d78cbf09 Panagiotis Kanavos
342 b5061ac8 Panagiotis Kanavos
                                      var commonObjects = from  upFile in remoteObjects
343 d78cbf09 Panagiotis Kanavos
                                                            join  localFile in pithosDir.EnumerateFiles()
344 283809f3 Panagiotis Kanavos
                                                                on upFile.Name.ToLower() equals localFile.Name.ToLower() 
345 b5061ac8 Panagiotis Kanavos
                                                            select new ListenerAction(CloudActionType.Download, localFile, upFile);
346 d78cbf09 Panagiotis Kanavos
347 d78cbf09 Panagiotis Kanavos
                                      var uniques =
348 b5061ac8 Panagiotis Kanavos
                                          onlyLocal.Union(onlyRemote).Union(commonObjects)
349 283809f3 Panagiotis Kanavos
                                              .Except(_networkActions,new LocalFileComparer());
350 b5061ac8 Panagiotis Kanavos
                                      
351 283809f3 Panagiotis Kanavos
                                      _networkActions.AddFromEnumerable(uniques, false);
352 d78cbf09 Panagiotis Kanavos
353 b5061ac8 Panagiotis Kanavos
                                      Trace.TraceInformation("[LISTENER] End Processing");
354 b5061ac8 Panagiotis Kanavos
                                      
355 b5061ac8 Panagiotis Kanavos
                                  }
356 b5061ac8 Panagiotis Kanavos
                ).ContinueWith(t=>
357 b5061ac8 Panagiotis Kanavos
                {
358 b5061ac8 Panagiotis Kanavos
                    if (t.IsFaulted)
359 b5061ac8 Panagiotis Kanavos
                    {
360 b5061ac8 Panagiotis Kanavos
                        Trace.TraceError("[LISTENER] Exception: {0}",t.Exception);                                           
361 b5061ac8 Panagiotis Kanavos
                    }
362 b5061ac8 Panagiotis Kanavos
                    else
363 b5061ac8 Panagiotis Kanavos
                    {
364 b5061ac8 Panagiotis Kanavos
                        Trace.TraceInformation("[LISTENER] Finished");                                           
365 b5061ac8 Panagiotis Kanavos
                    }                    
366 b5061ac8 Panagiotis Kanavos
                    ProcessRemoteFiles(accountPath);
367 b5061ac8 Panagiotis Kanavos
                });
368 b5061ac8 Panagiotis Kanavos
        }
369 b5061ac8 Panagiotis Kanavos
370 b5061ac8 Panagiotis Kanavos
        private void ProcessListenerActions()
371 b5061ac8 Panagiotis Kanavos
        {
372 283809f3 Panagiotis Kanavos
            foreach(var action in _networkActions.GetConsumingEnumerable())
373 b5061ac8 Panagiotis Kanavos
            {
374 3c43ec9b Panagiotis Kanavos
                Trace.TraceInformation("[ACTION] Start Processing {0}:{1}->{2}",action.Action,action.LocalFile,action.CloudFile.Name);
375 b5061ac8 Panagiotis Kanavos
                var localFile = action.LocalFile;
376 b5061ac8 Panagiotis Kanavos
                var cloudFile = action.CloudFile;
377 b5061ac8 Panagiotis Kanavos
                var downloadPath = (cloudFile == null)? String.Empty
378 0eea575a Panagiotis Kanavos
                                        : Path.Combine(RootPath,cloudFile.Name);
379 b5061ac8 Panagiotis Kanavos
                try
380 b5061ac8 Panagiotis Kanavos
                {
381 b5061ac8 Panagiotis Kanavos
                    switch (action.Action)
382 b5061ac8 Panagiotis Kanavos
                    {
383 b5061ac8 Panagiotis Kanavos
                        case CloudActionType.UploadUnconditional:
384 b5061ac8 Panagiotis Kanavos
385 b5061ac8 Panagiotis Kanavos
                            UploadCloudFile(localFile.Name,localFile.Length,localFile.FullName,action.LocalHash.Value);
386 b5061ac8 Panagiotis Kanavos
                            break;
387 b5061ac8 Panagiotis Kanavos
                        case CloudActionType.DownloadUnconditional:
388 3c43ec9b Panagiotis Kanavos
                            DownloadCloudFile(PithosContainer,cloudFile.Name,downloadPath);
389 b5061ac8 Panagiotis Kanavos
                            break;
390 b5061ac8 Panagiotis Kanavos
                        case CloudActionType.Download:
391 b5061ac8 Panagiotis Kanavos
                            if (File.Exists(downloadPath))
392 b5061ac8 Panagiotis Kanavos
                            {
393 b5061ac8 Panagiotis Kanavos
                                if (cloudFile.Hash !=action.LocalHash.Value)
394 b5061ac8 Panagiotis Kanavos
                                {
395 b5061ac8 Panagiotis Kanavos
                                    var lastLocalTime =localFile.LastWriteTime;
396 b5061ac8 Panagiotis Kanavos
                                    var lastUpTime =cloudFile.Last_Modified;
397 b5061ac8 Panagiotis Kanavos
                                    if (lastUpTime <=lastLocalTime)
398 b5061ac8 Panagiotis Kanavos
                                    {
399 b5061ac8 Panagiotis Kanavos
                                        //Files in conflict
400 b5061ac8 Panagiotis Kanavos
                                        StatusKeeper.SetFileOverlayStatus(downloadPath,FileOverlayStatus.Conflict);
401 b5061ac8 Panagiotis Kanavos
                                    }
402 b5061ac8 Panagiotis Kanavos
                                    else
403 3c43ec9b Panagiotis Kanavos
                                        DownloadCloudFile(PithosContainer,action.CloudFile.Name,downloadPath);
404 b5061ac8 Panagiotis Kanavos
                                }
405 b5061ac8 Panagiotis Kanavos
                            }
406 b5061ac8 Panagiotis Kanavos
                            else
407 3c43ec9b Panagiotis Kanavos
                                DownloadCloudFile(PithosContainer,action.CloudFile.Name,downloadPath);
408 b5061ac8 Panagiotis Kanavos
                            break;
409 b5061ac8 Panagiotis Kanavos
                    }
410 3c43ec9b Panagiotis Kanavos
                    Trace.TraceInformation("[ACTION] End Processing {0}:{1}->{2}", action.Action, action.LocalFile, action.CloudFile.Name);
411 b5061ac8 Panagiotis Kanavos
                }
412 b5061ac8 Panagiotis Kanavos
                catch (Exception exc)
413 b5061ac8 Panagiotis Kanavos
                {
414 b5061ac8 Panagiotis Kanavos
                    Trace.TraceError("[REQUEUE] {0} : {1} -> {2} due to exception\r\n{3}",
415 0eea575a Panagiotis Kanavos
                                    action.Action, action.LocalFile,action.CloudFile,exc);                    
416 b5061ac8 Panagiotis Kanavos
417 283809f3 Panagiotis Kanavos
                    _networkActions.Add(action);
418 b5061ac8 Panagiotis Kanavos
                }
419 b5061ac8 Panagiotis Kanavos
            }
420 d78cbf09 Panagiotis Kanavos
        }
421 d78cbf09 Panagiotis Kanavos
422 283809f3 Panagiotis Kanavos
      
423 d78cbf09 Panagiotis Kanavos
424 29672672 Panagiotis Kanavos
        private void StartMonitoringFiles(string path)
425 d78cbf09 Panagiotis Kanavos
        {
426 29672672 Panagiotis Kanavos
            _watcher = new FileSystemWatcher(path);
427 29672672 Panagiotis Kanavos
            _watcher.Changed += OnFileEvent;
428 29672672 Panagiotis Kanavos
            _watcher.Created += OnFileEvent;
429 29672672 Panagiotis Kanavos
            _watcher.Deleted += OnFileEvent;
430 29672672 Panagiotis Kanavos
            _watcher.Renamed += OnRenameEvent;
431 29672672 Panagiotis Kanavos
            _watcher.EnableRaisingEvents = true;
432 29672672 Panagiotis Kanavos
433 283809f3 Panagiotis Kanavos
            Task.Factory.StartNew(ProcesFileEvents,_cancellationSource.Token);
434 283809f3 Panagiotis Kanavos
        }
435 283809f3 Panagiotis Kanavos
436 283809f3 Panagiotis Kanavos
        private void ProcesFileEvents()
437 283809f3 Panagiotis Kanavos
        {
438 283809f3 Panagiotis Kanavos
            foreach (var state in _fileEvents.GetConsumingEnumerable())
439 283809f3 Panagiotis Kanavos
            {
440 283809f3 Panagiotis Kanavos
                try
441 283809f3 Panagiotis Kanavos
                {
442 283809f3 Panagiotis Kanavos
                    var networkState=StatusKeeper.GetNetworkState(state.Path);
443 283809f3 Panagiotis Kanavos
                    //Skip if the file is already being downloaded or uploaded and 
444 283809f3 Panagiotis Kanavos
                    //the change is create or modify
445 283809f3 Panagiotis Kanavos
                    if (networkState != NetworkState.None && 
446 283809f3 Panagiotis Kanavos
                        (
447 283809f3 Panagiotis Kanavos
                            state.TriggeringChange==WatcherChangeTypes.Created ||
448 283809f3 Panagiotis Kanavos
                            state.TriggeringChange==WatcherChangeTypes.Changed
449 283809f3 Panagiotis Kanavos
                        ))
450 283809f3 Panagiotis Kanavos
                        continue;
451 283809f3 Panagiotis Kanavos
                    UpdateFileStatus(state);
452 283809f3 Panagiotis Kanavos
                    UpdateOverlayStatus(state);
453 283809f3 Panagiotis Kanavos
                    UpdateFileChecksum(state);
454 283809f3 Panagiotis Kanavos
                    _uploadEvents.Add(state);
455 283809f3 Panagiotis Kanavos
                }
456 283809f3 Panagiotis Kanavos
                catch (OperationCanceledException exc)
457 283809f3 Panagiotis Kanavos
                {
458 283809f3 Panagiotis Kanavos
                    Trace.TraceError("[ERROR] File Event Processing:\r{0}", exc);
459 283809f3 Panagiotis Kanavos
                    throw;
460 283809f3 Panagiotis Kanavos
                }
461 283809f3 Panagiotis Kanavos
                catch (Exception exc)
462 283809f3 Panagiotis Kanavos
                {
463 283809f3 Panagiotis Kanavos
                    Trace.TraceError("[ERROR] File Event Processing:\r{0}",exc);
464 283809f3 Panagiotis Kanavos
                }
465 283809f3 Panagiotis Kanavos
            }
466 29672672 Panagiotis Kanavos
        }
467 29672672 Panagiotis Kanavos
468 29672672 Panagiotis Kanavos
        private void StartSending()
469 29672672 Panagiotis Kanavos
        {
470 29672672 Panagiotis Kanavos
            Task.Factory.StartNew(() =>
471 29672672 Panagiotis Kanavos
                                      {
472 29672672 Panagiotis Kanavos
                                          foreach (var state in _uploadEvents.GetConsumingEnumerable())
473 29672672 Panagiotis Kanavos
                                          {
474 29672672 Panagiotis Kanavos
                                              try
475 29672672 Panagiotis Kanavos
                                              {
476 d78cbf09 Panagiotis Kanavos
                                                  SynchToCloud(state);
477 d78cbf09 Panagiotis Kanavos
                                              }
478 d78cbf09 Panagiotis Kanavos
                                              catch (OperationCanceledException)
479 d78cbf09 Panagiotis Kanavos
                                              {
480 d78cbf09 Panagiotis Kanavos
                                                  throw;
481 d78cbf09 Panagiotis Kanavos
                                              }
482 d78cbf09 Panagiotis Kanavos
                                              catch(Exception ex)
483 0eea575a Panagiotis Kanavos
                                              {
484 0eea575a Panagiotis Kanavos
                                                  Trace.TraceError("[ERROR] Synch for {0}:\r{1}",state.FileName,ex);
485 0eea575a Panagiotis Kanavos
                                              }
486 d78cbf09 Panagiotis Kanavos
                                          }
487 d78cbf09 Panagiotis Kanavos
                                          
488 d78cbf09 Panagiotis Kanavos
                                      },_cancellationSource.Token);
489 d78cbf09 Panagiotis Kanavos
        }
490 d78cbf09 Panagiotis Kanavos
491 d78cbf09 Panagiotis Kanavos
492 d78cbf09 Panagiotis Kanavos
        private WorkflowState SynchToCloud(WorkflowState state)
493 d78cbf09 Panagiotis Kanavos
        {
494 d78cbf09 Panagiotis Kanavos
            if (state.Skip)
495 d78cbf09 Panagiotis Kanavos
                return state;
496 d78cbf09 Panagiotis Kanavos
            string path = state.Path;
497 d78cbf09 Panagiotis Kanavos
            string fileName = Path.GetFileName(path);
498 d78cbf09 Panagiotis Kanavos
499 d78cbf09 Panagiotis Kanavos
            switch(state.Status)
500 d78cbf09 Panagiotis Kanavos
            {
501 d78cbf09 Panagiotis Kanavos
                case FileStatus.Created:
502 d78cbf09 Panagiotis Kanavos
                case FileStatus.Modified:
503 d78cbf09 Panagiotis Kanavos
                    var info = new FileInfo(path);
504 d78cbf09 Panagiotis Kanavos
                    long fileSize = info.Length;
505 d78cbf09 Panagiotis Kanavos
                    UploadCloudFile(fileName, fileSize, path,state.Hash);
506 d78cbf09 Panagiotis Kanavos
                    break;
507 d78cbf09 Panagiotis Kanavos
                case FileStatus.Deleted:
508 d78cbf09 Panagiotis Kanavos
                    DeleteCloudFile(fileName);
509 d78cbf09 Panagiotis Kanavos
                    break;
510 d78cbf09 Panagiotis Kanavos
                case FileStatus.Renamed:
511 d78cbf09 Panagiotis Kanavos
                    RenameCloudFile(state);
512 d78cbf09 Panagiotis Kanavos
                    break;
513 d78cbf09 Panagiotis Kanavos
            }
514 d78cbf09 Panagiotis Kanavos
            return state;
515 d78cbf09 Panagiotis Kanavos
        }
516 d78cbf09 Panagiotis Kanavos
517 d78cbf09 Panagiotis Kanavos
        private void RenameCloudFile(WorkflowState state)
518 d78cbf09 Panagiotis Kanavos
        {
519 3c43ec9b Panagiotis Kanavos
            this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified);
520 d78cbf09 Panagiotis Kanavos
521 d78cbf09 Panagiotis Kanavos
522 d78cbf09 Panagiotis Kanavos
523 3c43ec9b Panagiotis Kanavos
            CloudClient.MoveObject(PithosContainer, state.OldFileName,PithosContainer, state.FileName);
524 d78cbf09 Panagiotis Kanavos
525 d78cbf09 Panagiotis Kanavos
            this.StatusKeeper.SetFileStatus(state.Path, FileStatus.Unchanged);
526 d78cbf09 Panagiotis Kanavos
            this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Normal);
527 d78cbf09 Panagiotis Kanavos
            Workflow.RaiseChangeNotification(state.Path);
528 d78cbf09 Panagiotis Kanavos
        }
529 d78cbf09 Panagiotis Kanavos
530 d78cbf09 Panagiotis Kanavos
        private void DeleteCloudFile(string fileName)
531 d78cbf09 Panagiotis Kanavos
        {
532 d78cbf09 Panagiotis Kanavos
            Contract.Requires(!Path.IsPathRooted(fileName));
533 d78cbf09 Panagiotis Kanavos
534 3c43ec9b Panagiotis Kanavos
            this.StatusKeeper.SetFileOverlayStatus(fileName, FileOverlayStatus.Modified);
535 3c43ec9b Panagiotis Kanavos
536 3c43ec9b Panagiotis Kanavos
            CloudClient.MoveObject(PithosContainer,fileName,TrashContainer,fileName);
537 d78cbf09 Panagiotis Kanavos
            this.StatusKeeper.ClearFileStatus(fileName);
538 d78cbf09 Panagiotis Kanavos
            this.StatusKeeper.RemoveFileOverlayStatus(fileName);            
539 d78cbf09 Panagiotis Kanavos
        }
540 d78cbf09 Panagiotis Kanavos
541 283809f3 Panagiotis Kanavos
        private void DownloadCloudFile(string container, string fileName, string localPath)
542 283809f3 Panagiotis Kanavos
        {
543 283809f3 Panagiotis Kanavos
            StatusKeeper.SetNetworkState(localPath,NetworkState.Downloading);
544 283809f3 Panagiotis Kanavos
            CloudClient.GetObject(container, fileName, localPath)
545 283809f3 Panagiotis Kanavos
            .ContinueWith(t=>
546 283809f3 Panagiotis Kanavos
                CloudClient.GetObjectInfo(container,fileName))
547 283809f3 Panagiotis Kanavos
            .ContinueWith(t=>
548 283809f3 Panagiotis Kanavos
                StatusKeeper.StoreInfo(fileName,t.Result))
549 283809f3 Panagiotis Kanavos
            .ContinueWith(t=>
550 283809f3 Panagiotis Kanavos
                StatusKeeper.SetNetworkState(localPath,NetworkState.None))
551 283809f3 Panagiotis Kanavos
            .Wait();
552 283809f3 Panagiotis Kanavos
        }
553 283809f3 Panagiotis Kanavos
554 d78cbf09 Panagiotis Kanavos
        private void UploadCloudFile(string fileName, long fileSize, string path,string hash)
555 d78cbf09 Panagiotis Kanavos
        {
556 d78cbf09 Panagiotis Kanavos
            Contract.Requires(!Path.IsPathRooted(fileName));
557 283809f3 Panagiotis Kanavos
558 283809f3 Panagiotis Kanavos
            StatusKeeper.SetNetworkState(fileName,NetworkState.Uploading);
559 283809f3 Panagiotis Kanavos
            
560 283809f3 Panagiotis Kanavos
            //Even if GetObjectInfo times out, we can proceed with the upload            
561 3c43ec9b Panagiotis Kanavos
            var info = CloudClient.GetObjectInfo(PithosContainer, fileName);
562 0eea575a Panagiotis Kanavos
            Task.Factory.StartNew(() =>
563 d78cbf09 Panagiotis Kanavos
            {
564 0eea575a Panagiotis Kanavos
                if (hash != info.Hash)
565 0eea575a Panagiotis Kanavos
                {
566 0eea575a Panagiotis Kanavos
                    Task.Factory.StartNew(() => 
567 3c43ec9b Panagiotis Kanavos
                        this.StatusKeeper.SetFileOverlayStatus(path, FileOverlayStatus.Modified))
568 0eea575a Panagiotis Kanavos
                    .ContinueWith(t => 
569 3c43ec9b Panagiotis Kanavos
                        CloudClient.PutObject(PithosContainer, fileName, path, hash));
570 0eea575a Panagiotis Kanavos
                }
571 283809f3 Panagiotis Kanavos
                else
572 283809f3 Panagiotis Kanavos
                {
573 283809f3 Panagiotis Kanavos
                    this.StatusKeeper.StoreInfo(path,info);
574 283809f3 Panagiotis Kanavos
                }
575 d78cbf09 Panagiotis Kanavos
            }
576 0eea575a Panagiotis Kanavos
            )
577 283809f3 Panagiotis Kanavos
            .ContinueWith(t => 
578 283809f3 Panagiotis Kanavos
                this.StatusKeeper.SetFileState(path, FileStatus.Unchanged, FileOverlayStatus.Normal))
579 283809f3 Panagiotis Kanavos
                .ContinueWith(t=>
580 283809f3 Panagiotis Kanavos
                    this.StatusKeeper.SetNetworkState(path,NetworkState.None))
581 0eea575a Panagiotis Kanavos
            .Wait();
582 d78cbf09 Panagiotis Kanavos
            Workflow.RaiseChangeNotification(path);
583 d78cbf09 Panagiotis Kanavos
        }
584 d78cbf09 Panagiotis Kanavos
585 d78cbf09 Panagiotis Kanavos
        private Dictionary<WatcherChangeTypes, FileStatus> _statusDict = new Dictionary<WatcherChangeTypes, FileStatus>
586 d78cbf09 Panagiotis Kanavos
        {
587 d78cbf09 Panagiotis Kanavos
            {WatcherChangeTypes.Created,FileStatus.Created},
588 d78cbf09 Panagiotis Kanavos
            {WatcherChangeTypes.Changed,FileStatus.Modified},
589 d78cbf09 Panagiotis Kanavos
            {WatcherChangeTypes.Deleted,FileStatus.Deleted},
590 d78cbf09 Panagiotis Kanavos
            {WatcherChangeTypes.Renamed,FileStatus.Renamed}
591 d78cbf09 Panagiotis Kanavos
        };
592 d78cbf09 Panagiotis Kanavos
593 d78cbf09 Panagiotis Kanavos
        private WorkflowState UpdateFileStatus(WorkflowState  state)
594 d78cbf09 Panagiotis Kanavos
        {
595 d78cbf09 Panagiotis Kanavos
            string path = state.Path;
596 d78cbf09 Panagiotis Kanavos
            FileStatus status = _statusDict[state.TriggeringChange];
597 d78cbf09 Panagiotis Kanavos
            var oldStatus = Workflow.StatusKeeper.GetFileStatus(path);
598 d78cbf09 Panagiotis Kanavos
            if (status == oldStatus)
599 d78cbf09 Panagiotis Kanavos
            {
600 d78cbf09 Panagiotis Kanavos
                state.Status = status;
601 d78cbf09 Panagiotis Kanavos
                state.Skip = true;
602 d78cbf09 Panagiotis Kanavos
                return state;
603 d78cbf09 Panagiotis Kanavos
            }
604 d78cbf09 Panagiotis Kanavos
            if (state.Status == FileStatus.Renamed)
605 d78cbf09 Panagiotis Kanavos
                Workflow.ClearFileStatus(path);                
606 d78cbf09 Panagiotis Kanavos
607 d78cbf09 Panagiotis Kanavos
            state.Status = Workflow.SetFileStatus(path, status);                
608 d78cbf09 Panagiotis Kanavos
            return state;
609 d78cbf09 Panagiotis Kanavos
        }
610 d78cbf09 Panagiotis Kanavos
611 d78cbf09 Panagiotis Kanavos
        private WorkflowState UpdateOverlayStatus(WorkflowState state)
612 d78cbf09 Panagiotis Kanavos
        {            
613 d78cbf09 Panagiotis Kanavos
            if (state.Skip)
614 d78cbf09 Panagiotis Kanavos
                return state;
615 d78cbf09 Panagiotis Kanavos
616 d78cbf09 Panagiotis Kanavos
            switch (state.Status)
617 d78cbf09 Panagiotis Kanavos
            {
618 d78cbf09 Panagiotis Kanavos
                case FileStatus.Created:
619 d78cbf09 Panagiotis Kanavos
                case FileStatus.Modified:
620 d78cbf09 Panagiotis Kanavos
                    this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified);
621 d78cbf09 Panagiotis Kanavos
                    break;
622 d78cbf09 Panagiotis Kanavos
                case FileStatus.Deleted:
623 d78cbf09 Panagiotis Kanavos
                    this.StatusKeeper.RemoveFileOverlayStatus(state.Path);
624 d78cbf09 Panagiotis Kanavos
                    break;
625 d78cbf09 Panagiotis Kanavos
                case FileStatus.Renamed:
626 d78cbf09 Panagiotis Kanavos
                    this.StatusKeeper.RemoveFileOverlayStatus(state.OldPath);
627 d78cbf09 Panagiotis Kanavos
                    this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified);
628 d78cbf09 Panagiotis Kanavos
                    break;
629 d78cbf09 Panagiotis Kanavos
                case FileStatus.Unchanged:
630 d78cbf09 Panagiotis Kanavos
                    this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Normal);
631 d78cbf09 Panagiotis Kanavos
                    break;
632 d78cbf09 Panagiotis Kanavos
            }
633 d78cbf09 Panagiotis Kanavos
634 d78cbf09 Panagiotis Kanavos
            if (state.Status==FileStatus.Deleted)
635 d78cbf09 Panagiotis Kanavos
                Workflow.RaiseChangeNotification(Path.GetDirectoryName(state.Path));
636 d78cbf09 Panagiotis Kanavos
            else
637 d78cbf09 Panagiotis Kanavos
                Workflow.RaiseChangeNotification(state.Path);
638 d78cbf09 Panagiotis Kanavos
            return state;
639 d78cbf09 Panagiotis Kanavos
        }
640 d78cbf09 Panagiotis Kanavos
641 d78cbf09 Panagiotis Kanavos
642 d78cbf09 Panagiotis Kanavos
        private WorkflowState UpdateFileChecksum(WorkflowState state)
643 d78cbf09 Panagiotis Kanavos
        {
644 d78cbf09 Panagiotis Kanavos
            if (state.Skip)
645 d78cbf09 Panagiotis Kanavos
                return state;
646 d78cbf09 Panagiotis Kanavos
647 d78cbf09 Panagiotis Kanavos
            if (state.Status == FileStatus.Deleted)
648 d78cbf09 Panagiotis Kanavos
                return state;
649 d78cbf09 Panagiotis Kanavos
650 d78cbf09 Panagiotis Kanavos
            string path = state.Path;
651 b5061ac8 Panagiotis Kanavos
            string hash = Signature.CalculateHash(path);
652 d78cbf09 Panagiotis Kanavos
653 d78cbf09 Panagiotis Kanavos
            StatusKeeper.UpdateFileChecksum(path, hash);
654 d78cbf09 Panagiotis Kanavos
655 d78cbf09 Panagiotis Kanavos
            state.Hash = hash;
656 d78cbf09 Panagiotis Kanavos
            return state;
657 d78cbf09 Panagiotis Kanavos
        }
658 d78cbf09 Panagiotis Kanavos
659 b5061ac8 Panagiotis Kanavos
       
660 d78cbf09 Panagiotis Kanavos
661 d78cbf09 Panagiotis Kanavos
        private FileSystemEventArgs CalculateSignature(FileSystemEventArgs arg)
662 d78cbf09 Panagiotis Kanavos
        {
663 d78cbf09 Panagiotis Kanavos
            Debug.WriteLine(String.Format("{0} {1} {2}", arg.ChangeType, arg.Name, arg.FullPath), "INFO");
664 d78cbf09 Panagiotis Kanavos
            return arg;
665 d78cbf09 Panagiotis Kanavos
        }
666 d78cbf09 Panagiotis Kanavos
667 d78cbf09 Panagiotis Kanavos
        void OnFileEvent(object sender, FileSystemEventArgs e)
668 d78cbf09 Panagiotis Kanavos
        {
669 d78cbf09 Panagiotis Kanavos
            _fileEvents.Add(new WorkflowState{Path=e.FullPath,FileName = e.Name,TriggeringChange=e.ChangeType});            
670 d78cbf09 Panagiotis Kanavos
        }
671 d78cbf09 Panagiotis Kanavos
672 d78cbf09 Panagiotis Kanavos
        void OnRenameEvent(object sender, RenamedEventArgs e)
673 d78cbf09 Panagiotis Kanavos
        {
674 d78cbf09 Panagiotis Kanavos
            _fileEvents.Add(new WorkflowState { OldPath=e.OldFullPath,OldFileName=e.OldName,
675 d78cbf09 Panagiotis Kanavos
                Path = e.FullPath, FileName = e.Name, TriggeringChange = e.ChangeType });
676 d78cbf09 Panagiotis Kanavos
        }
677 d78cbf09 Panagiotis Kanavos
678 d78cbf09 Panagiotis Kanavos
        public void Stop()
679 d78cbf09 Panagiotis Kanavos
        {
680 d78cbf09 Panagiotis Kanavos
            if (_watcher != null)
681 d78cbf09 Panagiotis Kanavos
            {
682 d78cbf09 Panagiotis Kanavos
                _watcher.Changed -= OnFileEvent;
683 d78cbf09 Panagiotis Kanavos
                _watcher.Created -= OnFileEvent;
684 d78cbf09 Panagiotis Kanavos
                _watcher.Deleted -= OnFileEvent;
685 d78cbf09 Panagiotis Kanavos
                _watcher.Renamed -= OnRenameEvent;
686 d78cbf09 Panagiotis Kanavos
                _watcher.Dispose();
687 d78cbf09 Panagiotis Kanavos
            }
688 d78cbf09 Panagiotis Kanavos
            _watcher = null;
689 d78cbf09 Panagiotis Kanavos
            _fileEvents.CompleteAdding();
690 d78cbf09 Panagiotis Kanavos
            if (timer != null)
691 d78cbf09 Panagiotis Kanavos
                timer.Dispose();
692 d78cbf09 Panagiotis Kanavos
            timer = null;
693 eeee29e3 Panagiotis Kanavos
            StopStatusService();
694 d78cbf09 Panagiotis Kanavos
        }
695 d78cbf09 Panagiotis Kanavos
696 eeee29e3 Panagiotis Kanavos
697 d78cbf09 Panagiotis Kanavos
        ~PithosMonitor()
698 d78cbf09 Panagiotis Kanavos
        {
699 d78cbf09 Panagiotis Kanavos
            Dispose(false);
700 d78cbf09 Panagiotis Kanavos
        }
701 d78cbf09 Panagiotis Kanavos
702 d78cbf09 Panagiotis Kanavos
        public void Dispose()
703 d78cbf09 Panagiotis Kanavos
        {
704 d78cbf09 Panagiotis Kanavos
            Dispose(true);
705 d78cbf09 Panagiotis Kanavos
            GC.SuppressFinalize(this);
706 d78cbf09 Panagiotis Kanavos
        }
707 d78cbf09 Panagiotis Kanavos
708 d78cbf09 Panagiotis Kanavos
        protected virtual void Dispose(bool disposing)
709 d78cbf09 Panagiotis Kanavos
        {
710 d78cbf09 Panagiotis Kanavos
            if (disposing)
711 d78cbf09 Panagiotis Kanavos
            {
712 d78cbf09 Panagiotis Kanavos
                Stop();
713 d78cbf09 Panagiotis Kanavos
            }
714 d78cbf09 Panagiotis Kanavos
        }
715 d78cbf09 Panagiotis Kanavos
716 d78cbf09 Panagiotis Kanavos
717 d78cbf09 Panagiotis Kanavos
    }
718 d78cbf09 Panagiotis Kanavos
}