Revision 0050438e

b/trunk/Pithos.Core/Pithos.Core.csproj
97 97
      <SpecificVersion>False</SpecificVersion>
98 98
      <HintPath>..\Libraries\Microsoft.WindowsAPICodePack.dll</HintPath>
99 99
    </Reference>
100
    <Reference Include="Microsoft.WindowsAPICodePack.Shell">
101
      <HintPath>..\Libraries\Microsoft.WindowsAPICodePack.Shell.dll</HintPath>
102
    </Reference>
100 103
    <Reference Include="NHibernate, Version=3.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
101 104
      <HintPath>..\Libraries\NHibernate.dll</HintPath>
102 105
    </Reference>
/dev/null
1
using System;
2
using System.Collections.Concurrent;
3
using System.Collections.Generic;
4
using System.ComponentModel.Composition;
5
using System.Diagnostics;
6
using System.Diagnostics.Contracts;
7
using System.IO;
8
using System.Linq;
9
using System.Security.Cryptography;
10
using System.Text;
11
using System.Threading.Tasks;
12
using Castle.ActiveRecord;
13
using Castle.ActiveRecord.Framework;
14
using Castle.ActiveRecord.Framework.Config;
15
using Pithos.Interfaces;
16

  
17
namespace Pithos.Core
18
{
19
    [Export(typeof(IStatusChecker)),Export(typeof(IStatusKeeper))]
20
    public class StatusChecker:IStatusChecker,IStatusKeeper
21
    {
22
        [System.ComponentModel.Composition.Import]
23
        public IPithosSettings Settings { get; set; }
24

  
25

  
26
        public StatusChecker()
27
        {
28
            var source = new XmlConfigurationSource("DbConfig.xml");
29
            ActiveRecordStarter.Initialize(source,typeof(FileState));            
30
            
31
            if (!File.Exists("pithos.db"))
32
                ActiveRecordStarter.CreateSchema();            
33
            
34
        }
35

  
36
        public FileOverlayStatus GetFileOverlayStatus(string path)
37
        {
38
            try
39
            {
40
                var state = FileState.TryFind(path);
41
                return state == null ? FileOverlayStatus.Unversioned : state.OverlayStatus;
42
            }
43
            catch (Exception exc)
44
            {
45
                Trace.TraceError(exc.ToString());
46
                return FileOverlayStatus.Unversioned;
47
            }
48
        }
49

  
50
        public IEnumerable<string> StoreUnversionedFiles(ParallelQuery<string> paths)
51
        {            
52
            var existingFiles =  FileState.FindAll().Select(state=>state.FilePath);
53

  
54
            var newFiles = (from file in paths.Except(existingFiles.AsParallel())
55
                            select new FileState
56
                                       {
57
                                           FilePath = file,
58
                                           OverlayStatus = FileOverlayStatus.Unversioned,
59
                                           FileStatus=FileStatus.Created,     
60
                                           Checksum=Signature.CalculateHash(file)
61
                                       }
62
                           ).AsParallel();
63
            
64
            var files=new ConcurrentBag<string>();
65
            newFiles.ForAll(state=>
66
                                {
67
                                    state.Save();
68
                                    files.Add(state.FilePath);
69
                                });
70
            
71
            return files.GetConsumingEnumerable();
72

  
73
        }
74

  
75
/*
76
        private static Task<string> CalculateHashAsync(string path)
77
        {
78

  
79
            string hash;
80
            using (var hasher = MD5.Create())
81
            {
82
                return FileAsync.ReadAllBytes(path)
83
                    .ContinueWith(t => hasher.ComputeHash(t.Result))
84
                    .ContinueWith(t =>
85
                                      {
86
                                          //var hashBuilder = new StringBuilder();
87
                                          return (from byte b in t.Result.AsParallel()
88
                                                  select b.ToString("x2").ToLower()).Aggregate((s1, s2) => s1 + s2);                                         
89
                                      });
90
            }
91
            /*using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, true))
92
            {
93
                
94
                stream.ReadAllBytes()
95
                    .ContinueWith(result => hasher.ComputeHash(result.Result))
96
                    .;
97
                var hashBytes = hasher.ComputeHash(stream);
98
                var hashBuilder = new StringBuilder();
99
                foreach (byte b in hasher.ComputeHash(stream))
100
                    hashBuilder.Append(b.ToString("x2").ToLower());
101
                hash = hashBuilder.ToString();
102

  
103
            }
104
            return hash;#1#
105
        }
106
*/
107

  
108

  
109
        private PithosStatus _pithosStatus=PithosStatus.InSynch;
110
        public void SetPithosStatus(PithosStatus status)
111
        {
112
            _pithosStatus = status;
113
        }
114

  
115
        public PithosStatus GetPithosStatus()
116
        {
117
            return _pithosStatus;
118
        }
119

  
120
        public void SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus)
121
        {
122
            var state = FileState.TryFind(path);
123
            if (state != null)
124
            {
125
                state.OverlayStatus = overlayStatus;
126
                state.Update();
127
            }
128
            else
129
            {
130
                state=new FileState{FilePath=path,OverlayStatus=overlayStatus};
131
                state.Save();
132
            }
133
        }
134

  
135
        public void RemoveFileOverlayStatus(string path)
136
        {
137
            FileState.DeleteAll(new[] {path});            
138
        }
139

  
140
        public void RenameFileOverlayStatus(string oldPath, string newPath)
141
        {
142
            var state = FileState.Find(oldPath);
143
            //TODO: This will cause problems if path is used as a key in relationships
144
            state.FilePath = newPath;
145
            state.Update();
146
        }
147

  
148
        public void SetFileStatus(string path, FileStatus status)
149
        {
150
            var state = FileState.Find(path);
151
            state.FileStatus = status;
152
        }
153

  
154
        public FileStatus GetFileStatus(string path)
155
        {
156
            var state = FileState.TryFind(path);
157
            return (state==null)?FileStatus.Missing:state.FileStatus ;
158
        }
159

  
160
        public void ClearFileStatus(string path)
161
        {
162
            //TODO:SHOULDN'T need both clear file status and remove overlay status
163
            FileState.DeleteAll(new[] { path });   
164
        }
165

  
166
        public void UpdateFileChecksum(string path, string checksum)
167
        {
168
            var state = FileState.Find(path);
169
            state.Checksum = checksum;
170
            state.Update();
171
        }
172
    }
173
}
b/trunk/Pithos.Core/StatusKeeper.cs
173 173

  
174 174
        private static void InnerRenameFileOverlayStatus(string oldPath, string newPath)
175 175
        {
176
            var state = FileState.Find(oldPath);
176
            var state = FileState.TryFind(oldPath);
177
            if (state == null)
178
            {
179
                Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", oldPath);
180
                return;
181
            }
177 182
            //NOTE: This will cause problems if path is used as a key in relationships
178 183
            state.FilePath = newPath;
179 184
            state.Update();
......
187 192

  
188 193
        private static void InnerSetFileStatus(string path, FileStatus status)
189 194
        {
190
            var state = FileState.Find(path);
195
            var state = FileState.TryFind(path.ToLower());
196
            if (state == null)
197
            {
198
                Trace.TraceWarning("[NOFILE] Unable to set status for {0}.", path);
199
                return;
200
            }
191 201
            state.FileStatus = status;
192 202
        }
193 203

  
......
200 210
        public void ClearFileStatus(string path)
201 211
        {
202 212
            //TODO:SHOULDN'T need both clear file status and remove overlay status
203
            FileState.DeleteAll(new[] { path });   
213
            _statusUpdateQueue.Add(()=>
214
                FileState.DeleteAll(new[] { path.ToLower() }));   
204 215
        }
205 216

  
206 217
        public void UpdateFileChecksum(string path, string checksum)
207 218
        {
208
            var state = FileState.Find(path);
219
            var state = FileState.TryFind(path);
220
            if (state == null)
221
            {
222
                Trace.TraceWarning("[NOFILE] Unable to set checkesum for {0}.",path);
223
                return;
224
            }
209 225
            state.Checksum = checksum;
210 226
            state.Update();
211 227
        }
b/trunk/Pithos.Interfaces/ICloudClient.cs
211 211
        public string Content_Type { get; set; }
212 212
        public DateTime Last_Modified { get; set; }
213 213

  
214
        private Dictionary<string, string> _tags=new Dictionary<string, string>();
215
        public Dictionary<string, string> Tags
216
        {
217
            get { return _tags; }
218
            set { _tags = value; }
219
        }
220

  
214 221
        public static ObjectInfo Empty=new ObjectInfo {Name=String.Empty,Hash=String.Empty,Bytes=0,Content_Type=String.Empty,Last_Modified=DateTime.MinValue};
215 222
    }
216 223
}
b/trunk/Pithos.Network/CloudFilesClient.cs
266 266
                case HttpStatusCode.OK:
267 267
                case HttpStatusCode.NoContent:
268 268
                    var keys = response.Headers.AllKeys.AsQueryable();
269
                    var tags=(from key in keys
270
                             where key.StartsWith("X-Object-Meta-")
271
                             let name=key.Substring(14)
272
                             select new {Name=name,Value=response.Headers[name]})
273
                             .ToDictionary(t=>t.Name,t=>t.Value);
269 274
                    return new ObjectInfo
270 275
                               {
271 276
                                   Name = objectName,
272 277
                                   Bytes = long.Parse(GetHeaderValue("Content-Length", response, keys)),
273 278
                                   Hash = GetHeaderValue("ETag", response, keys),
274
                                   Content_Type = GetHeaderValue("Content-Type", response, keys)
279
                                   Content_Type = GetHeaderValue("Content-Type", response, keys),
280
                                   Tags=tags
275 281
                               };
276 282
                case HttpStatusCode.NotFound:
277 283
                    return ObjectInfo.Empty;
......
455 461
            }                
456 462

  
457 463
        }
464
       
458 465

  
459 466
        /// <summary>
460 467
        /// Copies headers from a Hammock RestClient to a WebClient

Also available in: Unified diff