Statistics
| Branch: | Revision:

root / trunk / Pithos.Interfaces / ObjectInfo.cs @ aba9e6d9

History | View | Annotate | Download (6.8 kB)

1
using System;
2
using System.Collections.Generic;
3
using System.Diagnostics.Contracts;
4
using System.Dynamic;
5
using System.Globalization;
6
using System.IO;
7
using System.Linq;
8
using System.Text;
9
using System.Text.RegularExpressions;
10
using Newtonsoft.Json;
11

    
12
namespace Pithos.Interfaces
13
{
14
    public class ObjectInfo:DynamicObject 
15
    {
16
        private readonly List<string> _knownContainers= new List<string>{"trash"};
17
        public string Name { get; set; }
18
        public string Hash { get; set; }
19
        public long Bytes { get; set; }
20
        public string Content_Type { get; set; }
21
        public DateTime Last_Modified { get; set; }
22

    
23
        private Dictionary<string, string> _tags=new Dictionary<string, string>();
24
        public Dictionary<string, string> Tags
25
        {
26
            get { return _tags; }
27
            set { _tags = value; }
28
        }
29

    
30
        private Dictionary<string, string> _extensions=new Dictionary<string, string>();
31
        public Dictionary<string, string> Extensions
32
        {
33
            get { return _extensions; }
34
            set
35
            {
36
                _extensions = value;
37
                ExtractKnownExtensions();
38
            }
39
        }
40
        
41
        
42
        private Dictionary<string, string> _permissions=new Dictionary<string, string>();
43
        [JsonProperty("x_object_sharing")]
44
        [JsonConverter(typeof(PermissionConverter))]
45
        public Dictionary<string, string> Permissions
46
        {
47
            get { return _permissions; }
48
            set
49
            {
50
                _permissions = value;                
51
            }
52
        }
53

    
54
        /// <summary>
55
        /// Version number
56
        /// </summary>
57
        [JsonProperty("x_object_version")]
58
        public long? Version { get; set; }
59

    
60

    
61
        /// <summary>
62
        /// Shared object permissions can be Read or Write
63
        /// </summary>
64
        [JsonProperty("x_object_allowed_to")]
65
        public string AllowedTo { get; set; }
66

    
67

    
68
        /// <summary>
69
        /// Version timestamp
70
        /// </summary>
71
        [JsonProperty("X_Object_Version_Timestamp"), JsonConverter(typeof(PithosDateTimeConverter))]
72
        public DateTime? VersionTimestamp { get; set; }
73

    
74
        [JsonProperty("X_Object_Modified_By")]
75
        public string ModifiedBy { get; set; }
76

    
77

    
78
        public Stream Stream { get; set; }
79

    
80
        public string Account { get; set; }
81

    
82
        public string Container { get; set; }
83

    
84
        public string ContendDisposition { get; set; }
85

    
86
        public string ContentEncoding { get; set; }
87

    
88
        public string Manifest { get; set; }
89

    
90
        private bool _isPublic;
91
        public bool IsPublic
92
        {
93
            get { return !String.IsNullOrWhiteSpace(PublicUrl); }
94
            set
95
            {
96
                if (!value)
97
                    PublicUrl = "false";
98
                else if (String.IsNullOrWhiteSpace(PublicUrl))
99
                    PublicUrl="true";                
100
            }
101
        }
102

    
103
        public string PublicUrl { get; set; }
104

    
105
        public ObjectInfo()
106
        {}
107

    
108
        public ObjectInfo(string accountPath,string accountName,FileInfo fileInfo)
109
        {
110
            var relativeUrl = fileInfo.AsRelativeUrlTo(accountPath);
111
            //The first part of the URL is the container
112
            var slashIndex = relativeUrl.IndexOf('/');
113
            var container = relativeUrl.Substring(0, slashIndex);
114
            //The second is the file's url relative to the container
115
            var fileUrl = relativeUrl.Substring(slashIndex + 1);
116

    
117
            Account = accountName;
118
            Container = container;
119
            Name = fileUrl; 
120
        }
121

    
122

    
123
        private void ExtractKnownExtensions()
124
        {
125
            Version=GetLong(KnownExtensions.X_Object_Version);
126
            VersionTimestamp = GetTimestamp(KnownExtensions.X_Object_Version_Timestamp);
127
            ModifiedBy = GetString(KnownExtensions.X_Object_Modified_By);
128
        }
129

    
130
        private string GetString(string name)
131
        {            
132
            var value=String.Empty;
133
            _extensions.TryGetValue(name, out value);
134
            return value ;                        
135
        }
136

    
137
        private long? GetLong(string name)
138
        {
139
            string version;
140
            long value;
141
            return _extensions.TryGetValue(name, out version) && long.TryParse(version, out value)
142
                       ? (long?) value
143
                       : null;
144
        }
145

    
146
        private DateTime? GetTimestamp(string name)
147
        {
148
            string version;
149
            DateTime value;
150
            if (_extensions.TryGetValue(name, out version) && 
151
                DateTime.TryParse(version,CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal, out value))
152
            {
153
                return value;
154
            }
155
            return null;
156
        }
157

    
158

    
159
        public static ObjectInfo Empty = new ObjectInfo
160
        {
161
            Name = String.Empty,
162
            Hash = String.Empty,
163
            Bytes = 0,
164
            Content_Type = String.Empty,
165
            Last_Modified = DateTime.MinValue
166
        };
167

    
168
        public string RelativeUrlToFilePath(string currentAccount)
169
        {
170
            if (Name==null)
171
                throw new InvalidOperationException("Name can't be null");
172
            if (String.IsNullOrWhiteSpace(currentAccount))
173
                throw new ArgumentNullException("currentAccount");
174
            Contract.EndContractBlock();
175

    
176
            if (this == Empty)
177
                return String.Empty;
178

    
179
            var unescaped = Uri.UnescapeDataString(Name);
180
            var path = unescaped.Replace("/", "\\");
181
            var pathParts=new Stack<string>();
182
            pathParts.Push(path);
183
            if (!String.IsNullOrWhiteSpace(Container) && !_knownContainers.Contains(Container))
184
                pathParts.Push(Container);
185
            if (!currentAccount.Equals(Account, StringComparison.InvariantCultureIgnoreCase))
186
            {
187
                if (Account != null)
188
                {
189
                    pathParts.Push(Account);
190
                    pathParts.Push("others");
191
                }
192
            }
193
            var finalPath=Path.Combine(pathParts.ToArray());
194
            return finalPath;
195
        }
196

    
197
        public override bool TrySetMember(SetMemberBinder binder, object value)
198
        {
199
            if (binder.Name.StartsWith("x_object_meta"))
200
            {
201
                Tags[binder.Name] = value.ToString();
202
            }
203
            return false;
204
        }
205

    
206
        public string GetPermissionString()
207
        {
208
            var permissionBuilder = new StringBuilder();
209
            var groupings = Permissions.GroupBy(pair => pair.Value);
210
            foreach (var grouping in groupings)
211
            {
212
                permissionBuilder.AppendFormat("{0}={1}", grouping.Key, String.Join(",", grouping));
213
            }
214
            var permissions = permissionBuilder.ToString();
215
            return permissions;
216
        }
217
    }
218
}