2 using System.Collections.Generic;
3 using System.Diagnostics.Contracts;
5 using System.Globalization;
11 namespace Pithos.Interfaces
13 public class ObjectInfo:DynamicObject
15 private readonly List<string> _knownContainers= new List<string>{"trash"};
16 public string Name { get; set; }
19 public string Hash { get; set; }
21 public string X_Object_Hash { get { return Hash; } set { Hash = value; } }
23 [JsonProperty("x_object_uuid")]
24 public string UUID { get; set; }
26 public long Bytes { get; set; }
27 public string Content_Type { get; set; }
28 public DateTime Last_Modified { get; set; }
30 private Dictionary<string, string> _tags=new Dictionary<string, string>();
31 public Dictionary<string, string> Tags
34 set { _tags = value; }
37 private Dictionary<string, string> _extensions=new Dictionary<string, string>();
38 public Dictionary<string, string> Extensions
40 get { return _extensions; }
44 ExtractKnownExtensions();
49 private Dictionary<string, string> _permissions=new Dictionary<string, string>();
50 [JsonProperty("x_object_sharing")]
51 [JsonConverter(typeof(PermissionConverter))]
52 public Dictionary<string, string> Permissions
54 get { return _permissions; }
64 [JsonProperty("x_object_version")]
65 public long? Version { get; set; }
69 /// Shared object permissions can be Read or Write
71 [JsonProperty("x_object_allowed_to")]
72 public string AllowedTo { get; set; }
78 [JsonProperty("X_Object_Version_Timestamp"), JsonConverter(typeof(PithosDateTimeConverter))]
79 public DateTime? VersionTimestamp { get; set; }
81 [JsonProperty("X_Object_Modified_By")]
82 public string ModifiedBy { get; set; }
85 public Stream Stream { get; set; }
87 public string Account { get; set; }
89 public string Container { get; set; }
91 public string ContendDisposition { get; set; }
93 public string ContentEncoding { get; set; }
95 public string Manifest { get; set; }
99 get { return !String.IsNullOrWhiteSpace(PublicUrl); }
104 else if (String.IsNullOrWhiteSpace(PublicUrl))
109 [JsonProperty("X_Object_Public")]
110 public string PublicUrl { get; set; }
115 public ObjectInfo(string accountPath,string accountName,FileInfo fileInfo)
117 if (String.IsNullOrWhiteSpace(accountPath))
118 throw new ArgumentNullException("accountPath");
119 if (string.IsNullOrWhiteSpace(accountName))
120 throw new ArgumentNullException("accountName");
121 if (fileInfo == null)
122 throw new ArgumentNullException("fileInfo");
123 Contract.EndContractBlock();
125 var relativeUrl = fileInfo.AsRelativeUrlTo(accountPath);
126 //The first part of the URL is the container
127 var slashIndex = relativeUrl.IndexOf('/');
128 var container = relativeUrl.Substring(0, slashIndex);
129 //The second is the file's url relative to the container
130 var fileUrl = relativeUrl.Substring(slashIndex + 1);
132 Account = accountName;
133 Container = container;
138 private void ExtractKnownExtensions()
140 Version=GetLong(KnownExtensions.X_Object_Version);
141 VersionTimestamp = GetTimestamp(KnownExtensions.X_Object_Version_Timestamp);
142 ModifiedBy = GetString(KnownExtensions.X_Object_Modified_By);
145 private string GetString(string name)
148 _extensions.TryGetValue(name, out value);
152 private long? GetLong(string name)
156 return _extensions.TryGetValue(name, out version) && long.TryParse(version, out value)
161 private DateTime? GetTimestamp(string name)
165 if (_extensions.TryGetValue(name, out version) &&
166 DateTime.TryParse(version,CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal, out value))
174 public static ObjectInfo Empty = new ObjectInfo
179 Content_Type = String.Empty,
180 Last_Modified = DateTime.MinValue
183 public string RelativeUrlToFilePath(string currentAccount)
186 throw new InvalidOperationException("Name can't be null");
187 if (String.IsNullOrWhiteSpace(currentAccount))
188 throw new ArgumentNullException("currentAccount");
189 Contract.EndContractBlock();
194 var unescaped = Uri.UnescapeDataString(Name);
195 var path = unescaped.Replace("/", "\\");
196 var pathParts=new Stack<string>();
197 pathParts.Push(path);
198 if (!String.IsNullOrWhiteSpace(Container) && !_knownContainers.Contains(Container))
199 pathParts.Push(Container);
200 if (!currentAccount.Equals(Account, StringComparison.InvariantCultureIgnoreCase))
204 pathParts.Push(Account);
205 pathParts.Push("others");
208 var finalPath=Path.Combine(pathParts.ToArray());
212 public override bool TrySetMember(SetMemberBinder binder, object value)
214 if (binder.Name.StartsWith("x_object_meta"))
216 Tags[binder.Name] = value.ToString();
221 public string GetPermissionString()
223 if (Permissions==null)
224 throw new InvalidOperationException();
225 Contract.EndContractBlock();
227 var permissionBuilder = new StringBuilder();
228 var groupings = Permissions.GroupBy(pair => pair.Value, pair => pair.Key);
229 foreach (var grouping in groupings)
231 permissionBuilder.AppendFormat("{0}={1};", grouping.Key, String.Join(",", grouping));
233 var permissions = permissionBuilder.ToString().Trim(';');
237 public void SetPermissions(string permissions)
239 if (String.IsNullOrWhiteSpace(permissions))
242 var permDict=new Dictionary<string, string>();
243 var perms=permissions.Split(';');
244 foreach (var perm in perms)
246 var permPairs=perm.Split('=');
247 var right = permPairs[0];
248 var users= permPairs[1].Split(new[]{','},StringSplitOptions.RemoveEmptyEntries);
249 foreach (var user in users)
251 permDict[user] = right;
254 Permissions = permDict;