2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Diagnostics.Contracts;
6 using System.Globalization;
10 using Newtonsoft.Json;
12 namespace Pithos.Interfaces
14 [DebuggerDisplay("Name {Name}")]
15 public class ObjectInfo:DynamicObject
17 private readonly List<string> _knownContainers= new List<string>{"trash"};
18 public string Name { get; set; }
21 public string Hash { get; set; }
23 public string X_Object_Hash { get { return Hash; } set { Hash = value; } }
25 [JsonProperty("x_object_uuid")]
26 public string UUID { get; set; }
28 public long Bytes { get; set; }
29 public string Content_Type { get; set; }
30 public DateTime Last_Modified { get; set; }
32 private Dictionary<string, string> _tags=new Dictionary<string, string>();
33 public Dictionary<string, string> Tags
36 set { _tags = value; }
39 private Dictionary<string, string> _extensions=new Dictionary<string, string>();
40 public Dictionary<string, string> Extensions
42 get { return _extensions; }
46 ExtractKnownExtensions();
51 private Dictionary<string, string> _permissions=new Dictionary<string, string>();
52 [JsonProperty("x_object_sharing")]
53 [JsonConverter(typeof(PermissionConverter))]
54 public Dictionary<string, string> Permissions
56 get { return _permissions; }
66 [JsonProperty("x_object_version")]
67 public long? Version { get; set; }
71 /// Shared object permissions can be Read or Write
73 [JsonProperty("x_object_allowed_to")]
74 public string AllowedTo { get; set; }
80 [JsonProperty("X_Object_Version_Timestamp"), JsonConverter(typeof(PithosDateTimeConverter))]
81 public DateTime? VersionTimestamp { get; set; }
83 [JsonProperty("X_Object_Modified_By")]
84 public string ModifiedBy { get; set; }
87 public Stream Stream { get; set; }
89 public string Account { get; set; }
91 public string Container { get; set; }
93 public string ContendDisposition { get; set; }
95 public string ContentEncoding { get; set; }
97 public string Manifest { get; set; }
101 get { return !String.IsNullOrWhiteSpace(PublicUrl); }
106 else if (String.IsNullOrWhiteSpace(PublicUrl))
111 [JsonProperty("X_Object_Public")]
112 public string PublicUrl { get; set; }
117 public ObjectInfo(string accountPath,string accountName,FileInfo fileInfo)
119 if (String.IsNullOrWhiteSpace(accountPath))
120 throw new ArgumentNullException("accountPath");
121 if (string.IsNullOrWhiteSpace(accountName))
122 throw new ArgumentNullException("accountName");
123 if (fileInfo == null)
124 throw new ArgumentNullException("fileInfo");
125 Contract.EndContractBlock();
127 var relativeUrl = fileInfo.AsRelativeUrlTo(accountPath);
128 //The first part of the URL is the container
129 var slashIndex = relativeUrl.IndexOf('/');
130 var container = relativeUrl.Substring(0, slashIndex);
131 //The second is the file's url relative to the container
132 var fileUrl = relativeUrl.Substring(slashIndex + 1);
134 Account = accountName;
135 Container = container;
140 private void ExtractKnownExtensions()
142 Version=GetLong(KnownExtensions.X_Object_Version);
143 VersionTimestamp = GetTimestamp(KnownExtensions.X_Object_Version_Timestamp);
144 ModifiedBy = GetString(KnownExtensions.X_Object_Modified_By);
147 private string GetString(string name)
150 _extensions.TryGetValue(name, out value);
154 private long? GetLong(string name)
158 return _extensions.TryGetValue(name, out version) && long.TryParse(version, out value)
163 private DateTime? GetTimestamp(string name)
167 if (_extensions.TryGetValue(name, out version) &&
168 DateTime.TryParse(version,CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal, out value))
176 public static ObjectInfo Empty = new ObjectInfo
181 Content_Type = String.Empty,
182 Last_Modified = DateTime.MinValue
185 public string RelativeUrlToFilePath(string currentAccount)
188 throw new InvalidOperationException("Name can't be null");
189 if (String.IsNullOrWhiteSpace(currentAccount))
190 throw new ArgumentNullException("currentAccount");
191 Contract.EndContractBlock();
196 var unescaped = Uri.UnescapeDataString(Name);
197 var path = unescaped.Replace("/", "\\");
198 var pathParts=new Stack<string>();
199 pathParts.Push(path);
200 if (!String.IsNullOrWhiteSpace(Container) && !_knownContainers.Contains(Container))
201 pathParts.Push(Container);
202 if (!currentAccount.Equals(Account, StringComparison.InvariantCultureIgnoreCase))
206 pathParts.Push(Account);
207 pathParts.Push("others");
210 var finalPath=Path.Combine(pathParts.ToArray());
214 public override bool TrySetMember(SetMemberBinder binder, object value)
216 if (binder.Name.StartsWith("x_object_meta"))
218 Tags[binder.Name] = value.ToString();
223 public string GetPermissionString()
225 if (Permissions==null)
226 throw new InvalidOperationException();
227 Contract.EndContractBlock();
229 var permissionBuilder = new StringBuilder();
230 var groupings = Permissions.GroupBy(pair => pair.Value, pair => pair.Key);
231 foreach (var grouping in groupings)
233 permissionBuilder.AppendFormat("{0}={1};", grouping.Key, String.Join(",", grouping));
235 var permissions = permissionBuilder.ToString().Trim(';');
239 public void SetPermissions(string permissions)
241 if (String.IsNullOrWhiteSpace(permissions))
244 var permDict=new Dictionary<string, string>();
245 var perms=permissions.Split(';');
246 foreach (var perm in perms)
248 var permPairs=perm.Split('=');
249 var right = permPairs[0];
250 var users= permPairs[1].Split(new[]{','},StringSplitOptions.RemoveEmptyEntries);
251 foreach (var user in users)
253 permDict[user] = right;
256 Permissions = permDict;