using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using Newtonsoft.Json; namespace Pithos.Interfaces { public class ObjectInfo:DynamicObject { private readonly List _knownContainers= new List{"trash"}; public string Name { get; set; } public string Hash { get; set; } public long Bytes { get; set; } public string Content_Type { get; set; } public DateTime Last_Modified { get; set; } private Dictionary _tags=new Dictionary(); public Dictionary Tags { get { return _tags; } set { _tags = value; } } private Dictionary _extensions=new Dictionary(); public Dictionary Extensions { get { return _extensions; } set { _extensions = value; ExtractKnownExtensions(); } } private Dictionary _permissions=new Dictionary(); [JsonProperty("x_object_sharing")] [JsonConverter(typeof(PermissionConverter))] public Dictionary Permissions { get { return _permissions; } set { _permissions = value; } } /// /// Version number /// [JsonProperty("x_object_version")] public long? Version { get; set; } /// /// Shared object permissions can be Read or Write /// [JsonProperty("x_object_allowed_to")] public string AllowedTo { get; set; } /// /// Version timestamp /// [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 string Account { get; set; } public string Container { get; set; } public string ContendDisposition { get; set; } public string ContentEncoding { get; set; } public string Manifest { get; set; } private bool _isPublic; public bool IsPublic { get { return !String.IsNullOrWhiteSpace(PublicUrl); } set { if (!value) PublicUrl = "false"; else if (String.IsNullOrWhiteSpace(PublicUrl)) PublicUrl="true"; } } public string PublicUrl { 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(); 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; } public string GetPermissionString() { var permissionBuilder = new StringBuilder(); var groupings = Permissions.GroupBy(pair => pair.Value); foreach (var grouping in groupings) { permissionBuilder.AppendFormat("{0}={1}", grouping.Key, String.Join(",", grouping)); } var permissions = permissionBuilder.ToString(); return permissions; } } }