Statistics
| Branch: | Revision:

root / trunk / Pithos.Interfaces / ObjectInfo.cs @ 5e31048f

History | View | Annotate | Download (8.1 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 Newtonsoft.Json;
10

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

    
21
        public string X_Object_Hash { get { return Hash; } set { Hash = value; } }
22

    
23
        [JsonProperty("x_object_uuid")]
24
        public string UUID { get; set; }
25

    
26
        public long Bytes { get; set; }
27
        public string Content_Type { get; set; }
28
        public DateTime Last_Modified { get; set; }
29

    
30
        private Dictionary<string, string> _tags=new Dictionary<string, string>();
31
        public Dictionary<string, string> Tags
32
        {
33
            get { return _tags; }
34
            set { _tags = value; }
35
        }
36

    
37
        private Dictionary<string, string> _extensions=new Dictionary<string, string>();
38
        public Dictionary<string, string> Extensions
39
        {
40
            get { return _extensions; }
41
            set
42
            {
43
                _extensions = value;
44
                ExtractKnownExtensions();
45
            }
46
        }
47
        
48
        
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
53
        {
54
            get { return _permissions; }
55
            set
56
            {
57
                _permissions = value;                
58
            }
59
        }
60

    
61
        /// <summary>
62
        /// Version number
63
        /// </summary>
64
        [JsonProperty("x_object_version")]
65
        public long? Version { get; set; }
66

    
67

    
68
        /// <summary>
69
        /// Shared object permissions can be Read or Write
70
        /// </summary>
71
        [JsonProperty("x_object_allowed_to")]
72
        public string AllowedTo { get; set; }
73

    
74

    
75
        /// <summary>
76
        /// Version timestamp
77
        /// </summary>
78
        [JsonProperty("X_Object_Version_Timestamp"), JsonConverter(typeof(PithosDateTimeConverter))]
79
        public DateTime? VersionTimestamp { get; set; }
80

    
81
        [JsonProperty("X_Object_Modified_By")]
82
        public string ModifiedBy { get; set; }
83

    
84

    
85
        public Stream Stream { get; set; }
86

    
87
        public string Account { get; set; }
88

    
89
        public string Container { get; set; }
90

    
91
        public string ContendDisposition { get; set; }
92

    
93
        public string ContentEncoding { get; set; }
94

    
95
        public string Manifest { get; set; }
96
        
97
        public bool IsPublic
98
        {
99
            get { return !String.IsNullOrWhiteSpace(PublicUrl); }
100
            set
101
            {
102
                if (!value)
103
                    PublicUrl = null;
104
                else if (String.IsNullOrWhiteSpace(PublicUrl))
105
                    PublicUrl="true";                
106
            }
107
        }
108

    
109
        [JsonProperty("X_Object_Public")]
110
        public string PublicUrl { get; set; }
111

    
112
        public ObjectInfo()
113
        {}
114

    
115
        public ObjectInfo(string accountPath,string accountName,FileInfo fileInfo)
116
        {
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();
124

    
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);
131

    
132
            Account = accountName;
133
            Container = container;
134
            Name = fileUrl; 
135
        }
136

    
137

    
138
        private void ExtractKnownExtensions()
139
        {
140
            Version=GetLong(KnownExtensions.X_Object_Version);
141
            VersionTimestamp = GetTimestamp(KnownExtensions.X_Object_Version_Timestamp);
142
            ModifiedBy = GetString(KnownExtensions.X_Object_Modified_By);
143
        }
144

    
145
        private string GetString(string name)
146
        {            
147
            string value;
148
            _extensions.TryGetValue(name, out value);
149
            return value ;                        
150
        }
151

    
152
        private long? GetLong(string name)
153
        {
154
            string version;
155
            long value;
156
            return _extensions.TryGetValue(name, out version) && long.TryParse(version, out value)
157
                       ? (long?) value
158
                       : null;
159
        }
160

    
161
        private DateTime? GetTimestamp(string name)
162
        {
163
            string version;
164
            DateTime value;
165
            if (_extensions.TryGetValue(name, out version) && 
166
                DateTime.TryParse(version,CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal, out value))
167
            {
168
                return value;
169
            }
170
            return null;
171
        }
172

    
173

    
174
        public static ObjectInfo Empty = new ObjectInfo
175
        {
176
            Name = String.Empty,
177
            Hash = String.Empty,
178
            Bytes = 0,
179
            Content_Type = String.Empty,
180
            Last_Modified = DateTime.MinValue
181
        };
182

    
183
        public string RelativeUrlToFilePath(string currentAccount)
184
        {
185
            if (Name==null)
186
                throw new InvalidOperationException("Name can't be null");
187
            if (String.IsNullOrWhiteSpace(currentAccount))
188
                throw new ArgumentNullException("currentAccount");
189
            Contract.EndContractBlock();
190

    
191
            if (this == Empty)
192
                return String.Empty;
193

    
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))
201
            {
202
                if (Account != null)
203
                {
204
                    pathParts.Push(Account);
205
                    pathParts.Push("others");
206
                }
207
            }
208
            var finalPath=Path.Combine(pathParts.ToArray());
209
            return finalPath;
210
        }
211

    
212
        public override bool TrySetMember(SetMemberBinder binder, object value)
213
        {
214
            if (binder.Name.StartsWith("x_object_meta"))
215
            {
216
                Tags[binder.Name] = value.ToString();
217
            }
218
            return false;
219
        }
220

    
221
        public string GetPermissionString()
222
        {
223
            if (Permissions==null)
224
                throw new InvalidOperationException();
225
            Contract.EndContractBlock();
226

    
227
            var permissionBuilder = new StringBuilder();
228
            var groupings = Permissions.GroupBy(pair => pair.Value, pair => pair.Key);
229
            foreach (var grouping in groupings)
230
            {
231
                permissionBuilder.AppendFormat("{0}={1};", grouping.Key, String.Join(",", grouping));
232
            }
233
            var permissions = permissionBuilder.ToString().Trim(';');
234
            return permissions;
235
        }
236

    
237
        public void SetPermissions(string permissions)
238
        {
239
            if (String.IsNullOrWhiteSpace(permissions))
240
                return;
241

    
242
            var permDict=new Dictionary<string, string>();
243
            var perms=permissions.Split(';');
244
            foreach (var perm in perms)
245
            {
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)
250
                {
251
                    permDict[user] = right;
252
                }
253
            }
254
            Permissions = permDict;
255
        }
256
    }
257
}