Statistics
| Branch: | Revision:

root / trunk / Pithos.Interfaces / ObjectInfo.cs @ 06f11e8b

History | View | Annotate | Download (7.7 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
            var relativeUrl = fileInfo.AsRelativeUrlTo(accountPath);
118
            //The first part of the URL is the container
119
            var slashIndex = relativeUrl.IndexOf('/');
120
            var container = relativeUrl.Substring(0, slashIndex);
121
            //The second is the file's url relative to the container
122
            var fileUrl = relativeUrl.Substring(slashIndex + 1);
123

    
124
            Account = accountName;
125
            Container = container;
126
            Name = fileUrl; 
127
        }
128

    
129

    
130
        private void ExtractKnownExtensions()
131
        {
132
            Version=GetLong(KnownExtensions.X_Object_Version);
133
            VersionTimestamp = GetTimestamp(KnownExtensions.X_Object_Version_Timestamp);
134
            ModifiedBy = GetString(KnownExtensions.X_Object_Modified_By);
135
        }
136

    
137
        private string GetString(string name)
138
        {            
139
            string value;
140
            _extensions.TryGetValue(name, out value);
141
            return value ;                        
142
        }
143

    
144
        private long? GetLong(string name)
145
        {
146
            string version;
147
            long value;
148
            return _extensions.TryGetValue(name, out version) && long.TryParse(version, out value)
149
                       ? (long?) value
150
                       : null;
151
        }
152

    
153
        private DateTime? GetTimestamp(string name)
154
        {
155
            string version;
156
            DateTime value;
157
            if (_extensions.TryGetValue(name, out version) && 
158
                DateTime.TryParse(version,CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal, out value))
159
            {
160
                return value;
161
            }
162
            return null;
163
        }
164

    
165

    
166
        public static ObjectInfo Empty = new ObjectInfo
167
        {
168
            Name = String.Empty,
169
            Hash = String.Empty,
170
            Bytes = 0,
171
            Content_Type = String.Empty,
172
            Last_Modified = DateTime.MinValue
173
        };
174

    
175
        public string RelativeUrlToFilePath(string currentAccount)
176
        {
177
            if (Name==null)
178
                throw new InvalidOperationException("Name can't be null");
179
            if (String.IsNullOrWhiteSpace(currentAccount))
180
                throw new ArgumentNullException("currentAccount");
181
            Contract.EndContractBlock();
182

    
183
            if (this == Empty)
184
                return String.Empty;
185

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

    
204
        public override bool TrySetMember(SetMemberBinder binder, object value)
205
        {
206
            if (binder.Name.StartsWith("x_object_meta"))
207
            {
208
                Tags[binder.Name] = value.ToString();
209
            }
210
            return false;
211
        }
212

    
213
        public string GetPermissionString()
214
        {
215
            if (Permissions==null)
216
                throw new InvalidOperationException();
217
            Contract.EndContractBlock();
218

    
219
            var permissionBuilder = new StringBuilder();
220
            var groupings = Permissions.GroupBy(pair => pair.Value, pair => pair.Key);
221
            foreach (var grouping in groupings)
222
            {
223
                permissionBuilder.AppendFormat("{0}={1};", grouping.Key, String.Join(",", grouping));
224
            }
225
            var permissions = permissionBuilder.ToString().Trim(';');
226
            return permissions;
227
        }
228

    
229
        public void SetPermissions(string permissions)
230
        {
231
            if (String.IsNullOrWhiteSpace(permissions))
232
                return;
233

    
234
            var permDict=new Dictionary<string, string>();
235
            var perms=permissions.Split(';');
236
            foreach (var perm in perms)
237
            {
238
                var permPairs=perm.Split('=');
239
                var right = permPairs[0];
240
                var users= permPairs[1].Split(new[]{','},StringSplitOptions.RemoveEmptyEntries);
241
                foreach (var user in users)
242
                {
243
                    permDict[user] = right;
244
                }
245
            }
246
            Permissions = permDict;
247
        }
248
    }
249
}