Statistics
| Branch: | Revision:

root / trunk / Pithos.Interfaces / ObjectInfo.cs @ 3ddbb7b8

History | View | Annotate | Download (7.5 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
        public string Hash { get; set; }
18
        public long Bytes { get; set; }
19
        public string Content_Type { get; set; }
20
        public DateTime Last_Modified { get; set; }
21

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

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

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

    
59

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

    
66

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

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

    
76

    
77
        public Stream Stream { get; set; }
78

    
79
        public string Account { get; set; }
80

    
81
        public string Container { get; set; }
82

    
83
        public string ContendDisposition { get; set; }
84

    
85
        public string ContentEncoding { get; set; }
86

    
87
        public string Manifest { get; set; }
88

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

    
101
        public string PublicUrl { get; set; }
102

    
103
        public ObjectInfo()
104
        {}
105

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

    
115
            Account = accountName;
116
            Container = container;
117
            Name = fileUrl; 
118
        }
119

    
120

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

    
128
        private string GetString(string name)
129
        {            
130
            string value;
131
            _extensions.TryGetValue(name, out value);
132
            return value ;                        
133
        }
134

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

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

    
156

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

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

    
174
            if (this == Empty)
175
                return String.Empty;
176

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

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

    
204
        public string GetPermissionString()
205
        {
206
            if (Permissions==null)
207
                throw new InvalidOperationException();
208
            Contract.EndContractBlock();
209

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

    
220
        public void SetPermissions(string permissions)
221
        {
222
            if (String.IsNullOrWhiteSpace(permissions))
223
                return;
224

    
225
            var permDict=new Dictionary<string, string>();
226
            var perms=permissions.Split(';');
227
            foreach (var perm in perms)
228
            {
229
                var permPairs=perm.Split('=');
230
                var right = permPairs[0];
231
                var users= permPairs[1].Split(new[]{','},StringSplitOptions.RemoveEmptyEntries);
232
                foreach (var user in users)
233
                {
234
                    permDict[user] = right;
235
                }
236
            }
237
            Permissions = permDict;
238
        }
239
    }
240
}