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