~ubuntu-branches/debian/squeeze/f-spot/squeeze

« back to all changes in this revision

Viewing changes to extensions/FlickrExport/FlickrNet/Cache.cs

  • Committer: Bazaar Package Importer
  • Author(s): Iain Lane, Mirco Bauer, Iain Lane
  • Date: 2009-02-07 20:23:32 UTC
  • mfrom: (1.1.18 upstream)
  • Revision ID: james.westby@ubuntu.com-20090207202332-oc93rfjo1st0571s
Tags: 0.5.0.3-2
[ Mirco Bauer]
* Upload to unstable.
* debian/control:
  + Lowered GNOME# build-deps to 2.0 ABI as that transition didn't happen
    yet in unstable.

[ Iain Lane ]
* debian/patches/svn-r4545_locales-import.dpatch: Patch backported from SVN
  trunk revision 4545 - initialize the translation catalog earlier (LP: #293305)
  (Closes: #514457). Thanks to Florian Heinle for finding the patch and to
  Chris Coulson for preparing the update.
* debian/control: Build-depend on libmono-dev (>= 1.2.4) to match configure
  checks.
* debian/rules: Pass CSC=/usr/bin/csc to configure for gio-sharp to fix FTBFS

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
using System;
2
 
using System.Collections;
3
 
using System.IO;
4
 
using System.Text;
5
 
using System.Text.RegularExpressions;
6
 
 
7
 
namespace FlickrNet
8
 
{
9
 
        /// <summary>
10
 
        /// Internal Cache class
11
 
        /// </summary>
12
 
        internal sealed class Cache
13
 
        {
14
 
                private class CacheException : Exception
15
 
                {
16
 
                        public CacheException(string message) : base(message)
17
 
                        {}
18
 
 
19
 
                }
20
 
 
21
 
                private static PersistentCache _downloads;
22
 
 
23
 
 
24
 
                /// <summary>
25
 
                /// A static object containing the list of cached downloaded files.
26
 
                /// </summary>
27
 
                public static PersistentCache Downloads
28
 
                {
29
 
                        get 
30
 
                        {
31
 
                                lock(lockObject)
32
 
                                {
33
 
                                        if( _downloads == null )
34
 
                                                _downloads = new PersistentCache(Path.Combine(CacheLocation, "downloadCache.dat"), new PictureCacheItemPersister(), CacheSizeLimit);
35
 
                                        return _downloads;
36
 
                                }
37
 
                        }
38
 
                }
39
 
 
40
 
                private static PersistentCache _responses;
41
 
 
42
 
                /// <summary>
43
 
                /// A static object containing the list of cached responses from Flickr.
44
 
                /// </summary>
45
 
                public static PersistentCache Responses
46
 
                {
47
 
                        get 
48
 
                        {
49
 
                                lock(lockObject)
50
 
                                {
51
 
                                        if( _responses == null )
52
 
                                                _responses = new PersistentCache(Path.Combine(CacheLocation, "responseCache.dat"), new ResponseCacheItemPersister(), CacheSizeLimit);
53
 
                                        return _responses;
54
 
                                }
55
 
                        }
56
 
                }
57
 
 
58
 
 
59
 
                private Cache()
60
 
                {
61
 
                }
62
 
 
63
 
                private static object lockObject = new object();
64
 
 
65
 
                private enum Tristate
66
 
                {
67
 
                        Null, True, False
68
 
                }
69
 
                private static Tristate _cacheDisabled;
70
 
 
71
 
                internal static bool CacheDisabled
72
 
                {
73
 
                        get
74
 
                        {
75
 
                                if( _cacheDisabled == Tristate.Null && FlickrConfigurationManager.Settings != null )
76
 
                                        _cacheDisabled = (FlickrConfigurationManager.Settings.CacheDisabled?Tristate.True:Tristate.False);
77
 
                                
78
 
                                if( _cacheDisabled == Tristate.Null ) _cacheDisabled = Tristate.False;
79
 
 
80
 
                                return (_cacheDisabled==Tristate.True);
81
 
                        }
82
 
                        set
83
 
                        {
84
 
                                _cacheDisabled = value?Tristate.True:Tristate.False;
85
 
                        }
86
 
                }
87
 
 
88
 
                private static string _cacheLocation;
89
 
 
90
 
                internal static string CacheLocation
91
 
                {
92
 
                        get 
93
 
                        { 
94
 
                                if( _cacheLocation == null && FlickrConfigurationManager.Settings != null )
95
 
                                        _cacheLocation = FlickrConfigurationManager.Settings.CacheLocation;
96
 
                                if( _cacheLocation == null )
97
 
                                {
98
 
                                        try
99
 
                                        {
100
 
                                                _cacheLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "FlickrNet");
101
 
                                        }
102
 
                                        catch(System.Security.SecurityException)
103
 
                                        {
104
 
                                                // Permission to read application directory not provided.
105
 
                                                throw new CacheException("Unable to read default cache location. Please cacheLocation in configuration file or set manually in code");
106
 
                                        }
107
 
                                }
108
 
 
109
 
                                if( _cacheLocation == null )
110
 
                                        throw new CacheException("Unable to determine cache location. Please set cacheLocation in configuration file or set manually in code");
111
 
 
112
 
                                return _cacheLocation;
113
 
                        }
114
 
                        set
115
 
                        {
116
 
                                _cacheLocation = value;
117
 
                        }
118
 
                }
119
 
 
120
 
                internal static long CacheSizeLimit
121
 
                {
122
 
                        get 
123
 
                        {
124
 
                                if( CacheSettings.ContainsKey("SizeLimit") )
125
 
                                        return (long)CacheSettings["SizeLimit"];
126
 
                                else
127
 
                                        return 50 * 1024 * 1024;
128
 
                        }
129
 
                        set 
130
 
                        { 
131
 
                                if( CacheSettings.ContainsKey("SizeLimit") )
132
 
                                        CacheSettings["SizeLimit"] = value;
133
 
                                else
134
 
                                        CacheSettings.Add("SizeLimit", value);
135
 
                        }
136
 
                }
137
 
 
138
 
                internal static long CacheSize
139
 
                {
140
 
                        get 
141
 
                        {
142
 
                                if( CacheSettings.ContainsKey("CurrentSize") )
143
 
                                        return (long)CacheSettings["CurrentSize"];
144
 
                                else
145
 
                                        return 0;
146
 
                        }
147
 
                        set 
148
 
                        { 
149
 
                                if( CacheSettings.ContainsKey("CurrentSize") )
150
 
                                        CacheSettings["CurrentSize"] = value;
151
 
                                else
152
 
                                        CacheSettings.Add("CurrentSize", value);
153
 
                        }
154
 
                }
155
 
 
156
 
 
157
 
                // Default cache timeout is 1 hour
158
 
                private static TimeSpan _cachetimeout = new TimeSpan(0, 1, 0, 0, 0);
159
 
 
160
 
                /// <summary>
161
 
                /// The default timeout for cachable objects within the cache.
162
 
                /// </summary>
163
 
                public static TimeSpan CacheTimeout
164
 
                {
165
 
                        get { return _cachetimeout; }
166
 
                        set { _cachetimeout = value; }
167
 
                }
168
 
                
169
 
                private static Hashtable _cacheSettings;
170
 
 
171
 
                private static Hashtable CacheSettings
172
 
                {
173
 
                        get
174
 
                        {
175
 
                                lock(lockObject)
176
 
                                {
177
 
                                        if( _cacheSettings == null )
178
 
                                                LoadSettings();
179
 
                                        return _cacheSettings;
180
 
                                }
181
 
                        }
182
 
                }
183
 
 
184
 
                private static void SaveSettings()
185
 
                {
186
 
                        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
187
 
 
188
 
                        System.IO.Stream stream;
189
 
 
190
 
                        lock(CacheSettings.SyncRoot)
191
 
                        {
192
 
                                if( CacheLocation == null ) return;
193
 
 
194
 
                                stream = new FileStream(Path.Combine(CacheLocation, "cacheSettings.bin"), FileMode.OpenOrCreate, FileAccess.Write);
195
 
                                try
196
 
                                {
197
 
                                        formatter.Serialize(stream, CacheSettings);
198
 
                                }
199
 
                                finally
200
 
                                {
201
 
                                        stream.Close();
202
 
                                }
203
 
                        }
204
 
                }
205
 
 
206
 
                private static void LoadSettings()
207
 
                {
208
 
                        if( !Directory.Exists(CacheLocation) ) Directory.CreateDirectory(CacheLocation);
209
 
 
210
 
                        System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
211
 
 
212
 
                        System.IO.Stream stream = null;
213
 
 
214
 
                        if( CacheLocation != null ) 
215
 
                        {
216
 
                                stream = new FileStream(Path.Combine(CacheLocation, "cacheSettings.bin"), FileMode.OpenOrCreate);
217
 
                        }
218
 
 
219
 
                        if( stream == null )
220
 
                        {
221
 
                                _cacheSettings = new Hashtable();
222
 
                                return;
223
 
                        }
224
 
                        try
225
 
                        {
226
 
                                _cacheSettings = (Hashtable)formatter.Deserialize(stream);
227
 
                        }
228
 
                        catch(InvalidCastException)
229
 
                        {
230
 
                                _cacheSettings = new Hashtable();
231
 
                        }
232
 
                        catch(System.Runtime.Serialization.SerializationException)
233
 
                        {
234
 
                                _cacheSettings = new Hashtable();
235
 
                        }
236
 
                        finally
237
 
                        {
238
 
                                stream.Close();
239
 
                        }
240
 
                }
241
 
 
242
 
                internal static void FlushCache(string url)
243
 
                {
244
 
                        Responses[url] = null;
245
 
                        Downloads[url] = null;
246
 
                }
247
 
 
248
 
                internal static void FlushCache()
249
 
                {
250
 
                        Responses.Flush();
251
 
                        Downloads.Flush();
252
 
                }
253
 
 
254
 
        }
255
 
 
256
 
        /// <summary>
257
 
        /// A cache item containing details of a REST response from Flickr.
258
 
        /// </summary>
259
 
        [Serializable]
260
 
        public class ResponseCacheItem : ICacheItem
261
 
        {
262
 
                private string url;
263
 
                private string response;
264
 
                private DateTime creationTime;
265
 
 
266
 
                /// <summary>
267
 
                /// Gets or sets the original URL of the request.
268
 
                /// </summary>
269
 
                public string Url { get { return url; } set { url = value; } }
270
 
 
271
 
                /// <summary>
272
 
                /// Gets or sets the XML response.
273
 
                /// </summary>
274
 
                public string Response { get { return response; } set { response = value; } }
275
 
 
276
 
                /// <summary>
277
 
                /// Gets or sets the time the cache item was created.
278
 
                /// </summary>
279
 
                public DateTime CreationTime { get { return creationTime; } set { creationTime = value; } }
280
 
 
281
 
                /// <summary>
282
 
                /// Gets the filesize of the request.
283
 
                /// </summary>
284
 
                public long FileSize { get { return (response==null?0:response.Length); } }
285
 
 
286
 
                void ICacheItem.OnItemFlushed()
287
 
                {
288
 
                }
289
 
 
290
 
        }
291
 
 
292
 
        internal class ResponseCacheItemPersister : CacheItemPersister
293
 
        {
294
 
                public override ICacheItem Read(Stream inputStream)
295
 
                {
296
 
                        string s = Utils.ReadString(inputStream);
297
 
                        string response = Utils.ReadString(inputStream);
298
 
 
299
 
                        string[] chunks = s.Split('\n');
300
 
 
301
 
                        // Corrupted cache record, so throw IOException which is then handled and returns partial cache.
302
 
                        if( chunks.Length != 2 )
303
 
                                throw new IOException("Unexpected number of chunks found");
304
 
 
305
 
                        string url = chunks[0];
306
 
                        DateTime creationTime = new DateTime(long.Parse(chunks[1]));
307
 
                        ResponseCacheItem item = new ResponseCacheItem();
308
 
                        item.Url = url;
309
 
                        item.CreationTime = creationTime;
310
 
                        item.Response = response;
311
 
                        return item;
312
 
                }
313
 
 
314
 
                public override void Write(Stream outputStream, ICacheItem cacheItem)
315
 
                {
316
 
                        ResponseCacheItem item = (ResponseCacheItem) cacheItem;
317
 
                        StringBuilder result = new StringBuilder();
318
 
                        result.Append(item.Url + "\n");
319
 
                        result.Append(item.CreationTime.Ticks.ToString("0"));
320
 
                        Utils.WriteString(outputStream, result.ToString());
321
 
                        Utils.WriteString(outputStream, item.Response);
322
 
                }
323
 
        }
324
 
 
325
 
        /// <summary>
326
 
        /// An item that can be stored in a cache.
327
 
        /// </summary>
328
 
        public interface ICacheItem
329
 
        {
330
 
                /// <summary>
331
 
                /// The time this cache item was created.
332
 
                /// </summary>
333
 
                DateTime CreationTime { get; }
334
 
 
335
 
                /// <summary>
336
 
                /// Gets called back when the item gets flushed
337
 
                /// from the cache.
338
 
                /// </summary>
339
 
                void OnItemFlushed();
340
 
 
341
 
                /// <summary>
342
 
                /// The size of this item, in bytes. Return 0
343
 
                /// if size management is not important.
344
 
                /// </summary>
345
 
                long FileSize { get; }
346
 
        }
347
 
 
348
 
        /// <summary>
349
 
        /// An interface that knows how to read/write subclasses
350
 
        /// of ICacheItem.  Obviously there will be a tight
351
 
        /// coupling between concrete implementations of ICacheItem
352
 
        /// and concrete implementations of ICacheItemPersister.
353
 
        /// </summary>
354
 
        public abstract class CacheItemPersister
355
 
        {
356
 
                /// <summary>
357
 
                /// Read a single cache item from the input stream.
358
 
                /// </summary>
359
 
                public abstract ICacheItem Read(Stream inputStream);
360
 
 
361
 
                /// <summary>
362
 
                /// Write a single cache item to the output stream.
363
 
                /// </summary>
364
 
                public abstract void Write(Stream outputStream, ICacheItem cacheItem);
365
 
        }
366
 
 
367
 
        /// <summary>
368
 
        /// Contains details of image held with the Flickr.Net cache.
369
 
        /// </summary>
370
 
        [Serializable]
371
 
        public class PictureCacheItem : ICacheItem
372
 
        {
373
 
                #region [ Internal Variables ]
374
 
                internal string url;
375
 
                internal DateTime creationTime;
376
 
                internal string filename;
377
 
                internal long fileSize;
378
 
                #endregion
379
 
 
380
 
                #region [ Public Properties ]
381
 
                /// <summary>
382
 
                /// The URL of the original image on Flickr.
383
 
                /// </summary>
384
 
                public string Url { get { return url; } }
385
 
                /// <summary>
386
 
                /// The <see cref="DateTime"/> that the cache item was created.
387
 
                /// </summary>
388
 
                public DateTime CreationTime { get { return creationTime; } }
389
 
 
390
 
                /// <summary>
391
 
                /// The filesize in bytes of the image.
392
 
                /// </summary>
393
 
                public long FileSize { get { return fileSize; } }
394
 
                /// <summary>
395
 
                /// The Flickr photo id of the image.
396
 
                /// </summary>
397
 
                public string PhotoId
398
 
                {
399
 
                        get 
400
 
                        {
401
 
                                if( url == null ) 
402
 
                                        return null;
403
 
                                else
404
 
                                {
405
 
                                        int begin = url.LastIndexOf("/");
406
 
                                        int end = url.IndexOf("_");
407
 
 
408
 
                                        return url.Substring(begin + 1, (end - begin) - 1);
409
 
                                }
410
 
                        }
411
 
                }
412
 
                #endregion
413
 
 
414
 
                #region [ Public Methods ]
415
 
 
416
 
                void ICacheItem.OnItemFlushed()
417
 
                {
418
 
                        File.Delete(filename);
419
 
                }
420
 
 
421
 
                #endregion
422
 
        }
423
 
 
424
 
        /// <summary>
425
 
        /// Persists PictureCacheItem objects.
426
 
        /// </summary>
427
 
        internal class PictureCacheItemPersister : CacheItemPersister
428
 
        {
429
 
                public override ICacheItem Read(Stream inputStream)
430
 
                {
431
 
                        string s = Utils.ReadString(inputStream);
432
 
 
433
 
                        string[] chunks = s.Split('\n');
434
 
                        string url = chunks[0];
435
 
                        DateTime creationTime = new DateTime(long.Parse(chunks[1]));
436
 
                        string filename = chunks[2];
437
 
                        long fileSize = long.Parse(chunks[3]);
438
 
 
439
 
                        PictureCacheItem pci = new PictureCacheItem();
440
 
                        pci.url = url;
441
 
                        pci.creationTime = creationTime;
442
 
                        pci.filename = filename;
443
 
                        pci.fileSize = fileSize;
444
 
                        return pci;
445
 
                }
446
 
 
447
 
                public override void Write(Stream outputStream, ICacheItem cacheItem)
448
 
                {
449
 
                        PictureCacheItem pci = (PictureCacheItem) cacheItem;
450
 
                        StringBuilder output = new StringBuilder();
451
 
 
452
 
                        output.Append(pci.url + "\n");
453
 
                        output.Append(pci.creationTime.Ticks + "\n");
454
 
                        output.Append(pci.filename + "\n");
455
 
                        output.Append(pci.fileSize + "\n");
456
 
 
457
 
                        Utils.WriteString(outputStream, output.ToString());
458
 
                }
459
 
        }
460
 
}