using System;
using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Dynamic;
+using System.Globalization;
using System.IO;
+using System.Text.RegularExpressions;
+using Newtonsoft.Json;
namespace Pithos.Interfaces
{
- public class ObjectInfo
+ public class ObjectInfo:DynamicObject
{
+ private readonly List<string> _knownContainers= new List<string>{"trash"};
public string Name { get; set; }
public string Hash { get; set; }
public long Bytes { get; set; }
public Dictionary<string, string> Extensions
{
get { return _extensions; }
- set { _extensions = value; }
+ set
+ {
+ _extensions = value;
+ ExtractKnownExtensions();
+ }
}
+
+
+ private Dictionary<string, string> _permissions=new Dictionary<string, string>();
+ [JsonProperty("x_object_sharing")]
+ [JsonConverter(typeof(PermissionConverter))]
+ public Dictionary<string, string> Permissions
+ {
+ get { return _permissions; }
+ set
+ {
+ _permissions = value;
+ }
+ }
+
+ /// <summary>
+ /// Version number
+ /// </summary>
+ [JsonProperty("x_object_version")]
+ public long? Version { get; set; }
+
+
+ /// <summary>
+ /// Shared object permissions can be Read or Write
+ /// </summary>
+ [JsonProperty("x_object_allowed_to")]
+ public string AllowedTo { get; set; }
+ /// <summary>
+ /// Version timestamp
+ /// </summary>
+ [JsonProperty("X_Object_Version_Timestamp"), JsonConverter(typeof(PithosDateTimeConverter))]
+ public DateTime? VersionTimestamp { get; set; }
+
+ [JsonProperty("X_Object_Modified_By")]
+ public string ModifiedBy { get; set; }
+
public Stream Stream { get; set; }
- public static ObjectInfo Empty=new ObjectInfo {Name=String.Empty,Hash=String.Empty,Bytes=0,Content_Type=String.Empty,Last_Modified=DateTime.MinValue};
+ public string Account { get; set; }
+
+ public string Container { get; set; }
+
+ public ObjectInfo()
+ {}
+
+ public ObjectInfo(string accountPath,string accountName,FileInfo fileInfo)
+ {
+ var relativeUrl = fileInfo.AsRelativeUrlTo(accountPath);
+ //The first part of the URL is the container
+ var slashIndex = relativeUrl.IndexOf('/');
+ var container = relativeUrl.Substring(0, slashIndex);
+ //The second is the file's url relative to the container
+ var fileUrl = relativeUrl.Substring(slashIndex + 1);
+
+ Account = accountName;
+ Container = container;
+ Name = fileUrl;
+ }
+
+
+ private void ExtractKnownExtensions()
+ {
+ Version=GetLong(KnownExtensions.X_Object_Version);
+ VersionTimestamp = GetTimestamp(KnownExtensions.X_Object_Version_Timestamp);
+ ModifiedBy = GetString(KnownExtensions.X_Object_Modified_By);
+ }
+
+ private string GetString(string name)
+ {
+ var value=String.Empty;
+ _extensions.TryGetValue(name, out value);
+ return value ;
+ }
+
+ private long? GetLong(string name)
+ {
+ string version;
+ long value;
+ return _extensions.TryGetValue(name, out version) && long.TryParse(version, out value)
+ ? (long?) value
+ : null;
+ }
+
+ private DateTime? GetTimestamp(string name)
+ {
+ string version;
+ DateTime value;
+ if (_extensions.TryGetValue(name, out version) &&
+ DateTime.TryParse(version,CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal, out value))
+ {
+ return value;
+ }
+ return null;
+ }
+
+
+ public static ObjectInfo Empty = new ObjectInfo
+ {
+ Name = String.Empty,
+ Hash = String.Empty,
+ Bytes = 0,
+ Content_Type = String.Empty,
+ Last_Modified = DateTime.MinValue
+ };
+
+ public string RelativeUrlToFilePath(string currentAccount)
+ {
+ if (Name==null)
+ throw new InvalidOperationException("Name can't be null");
+ if (String.IsNullOrWhiteSpace(currentAccount))
+ throw new ArgumentNullException("currentAccount");
+ Contract.EndContractBlock();
+
+ if (this == Empty)
+ return String.Empty;
+
+ var unescaped = Uri.UnescapeDataString(Name);
+ var path = unescaped.Replace("/", "\\");
+ var pathParts=new Stack<string>();
+ pathParts.Push(path);
+ if (!String.IsNullOrWhiteSpace(Container) && !_knownContainers.Contains(Container))
+ pathParts.Push(Container);
+ if (!currentAccount.Equals(Account, StringComparison.InvariantCultureIgnoreCase))
+ {
+ if (Account != null)
+ {
+ pathParts.Push(Account);
+ pathParts.Push("others");
+ }
+ }
+ var finalPath=Path.Combine(pathParts.ToArray());
+ return finalPath;
+ }
+
+ public override bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ if (binder.Name.StartsWith("x_object_meta"))
+ {
+ Tags[binder.Name] = value.ToString();
+ }
+ return false;
+ }
+
}
}
\ No newline at end of file