upload_cache 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/upload_cache.rb +152 -60
  2. data/upload_cache.gemspec +28 -0
  3. metadata +29 -52
data/lib/upload_cache.rb CHANGED
@@ -1,11 +1,13 @@
1
- require 'uuidtools'
2
1
  require 'fileutils'
3
2
  require 'cgi'
3
+ require 'tmpdir'
4
+
5
+ require 'map'
4
6
 
5
7
  class UploadCache
6
- Version = '1.0.0'
8
+ Version = '1.2.0'
7
9
 
8
- README = <<-__
10
+ Readme = <<-__
9
11
  NAME
10
12
  upload_cache.rb
11
13
 
@@ -49,6 +51,9 @@ class UploadCache
49
51
 
50
52
  UploadCache.clear! ### nuke old files once per day
51
53
 
54
+ upload_caches ***does this automatically*** at_exit{}, but you can still
55
+ run it manually if you like.
56
+
52
57
  __
53
58
 
54
59
  class << UploadCache
@@ -56,25 +61,36 @@ class UploadCache
56
61
  UploadCache::Version
57
62
  end
58
63
 
59
- def base
60
- @base ||= 'system/uploads/cache'
64
+ def url
65
+ @url ||= "file:/#{ root }"
61
66
  end
62
67
 
63
- def base=(base)
64
- @base = base.to_s.sub(%r|^/+|, '')
68
+ def url=(url)
69
+ @url = '/' + Array(url).join('/').squeeze('/').sub(%r|^/+|, '').sub(%r|/+$|, '')
65
70
  end
66
71
 
67
- def url
68
- '/' + base
72
+ def root
73
+ @root ||= Dir.tmpdir
69
74
  end
70
75
 
71
- def root
72
- @root ||= File.join(Rails.root, 'public', base)
76
+ def root=(root)
77
+ @root = File.expand_path(root)
73
78
  end
74
79
 
75
- def uuid(*args)
76
- UUIDTools::UUID.timestamp_create.to_s
80
+ {
81
+ 'ffi-uuid' => proc{|*args| FFI::UUID.generate_time.to_s},
82
+ 'uuid' => proc{|*args| UUID.generate.to_s},
83
+ 'uuidtools' => proc{|*args| UUIDTools::UUID.timestamp_create.to_s}
84
+ }.each do |lib, implementation|
85
+ begin
86
+ require(lib)
87
+ define_method(:uuid, &implementation)
88
+ break
89
+ rescue LoadError
90
+ nil
91
+ end
77
92
  end
93
+ abort 'no suitable uuid generation library detected' unless method_defined?(:uuid)
78
94
 
79
95
  def tmpdir(&block)
80
96
  tmpdir = File.join(root, uuid)
@@ -93,35 +109,9 @@ class UploadCache
93
109
  end
94
110
 
95
111
  def cache_key_for(key)
96
- "#{ key }__cache"
97
- end
98
-
99
- def for(params, key = :upload)
100
- upload = params[key]
101
- if upload.respond_to?(:read)
102
- tmpdir do |tmp|
103
- original_basename = upload.respond_to?(:original_path) ? upload.original_path : upload.original_filename
104
- basename = cleanname(original_basename)
105
-
106
- path = File.join(tmp, basename)
107
- open(path, 'w'){|fd| fd.write(upload.read)}
108
- upload_cache = new(key, path)
109
- params[key] = upload_cache.io
110
- return upload_cache
111
- end
112
- end
113
-
114
- cache_key = cache_key_for(key)
115
- upload_cache = params[cache_key]
116
- if upload_cache
117
- dirname, basename = File.split(upload_cache)
118
- path = root + '/' + File.join(File.basename(dirname), basename)
119
- upload_cache = new(key, path)
120
- params[key] = upload_cache.io
121
- return upload_cache
112
+ key.clone.tap do |cache_key|
113
+ cache_key[-1] = "#{ cache_key[-1] }_upload_cache"
122
114
  end
123
-
124
- return new(key, path=nil)
125
115
  end
126
116
 
127
117
  def finalizer(object_id)
@@ -135,6 +125,8 @@ class UploadCache
135
125
  Age = 60 * 60 * 24
136
126
 
137
127
  def clear!(options = {})
128
+ return if UploadCache.turd?
129
+
138
130
  glob = File.join(root, '*')
139
131
  age = Integer(options[:age] || options['age'] || Age)
140
132
  since = options[:since] || options['since'] || Time.now
@@ -163,47 +155,136 @@ class UploadCache
163
155
  end
164
156
  end
165
157
  end
158
+
159
+ at_exit{ UploadCache.clear! }
160
+
161
+ def turd?
162
+ @turd ||= !!ENV['UPLOAD_CACHE_TURD']
163
+ end
164
+
165
+ def name_for(key, &block)
166
+ if block
167
+ @name_for = block
168
+ else
169
+ defined?(@name_for) ? @name_for[key] : [prefix, *Array(key)].compact.join('.')
170
+ end
171
+ end
172
+
173
+ def prefix(*value)
174
+ @prefix = value.shift if value
175
+ @prefix
176
+ end
177
+
178
+ def prefix=(value)
179
+ @prefix = value
180
+ end
181
+
182
+ def default
183
+ @default ||= Map[:url, nil, :path, nil]
184
+ end
185
+
186
+ def for(params, *args)
187
+ params = Map.for(params)
188
+ options = Map.options_for!(args)
189
+
190
+ key = Array(options[:key] || args).flatten.compact
191
+ key = [:upload] if key.empty?
192
+
193
+ upload = params.get(key)
194
+
195
+ if upload.respond_to?(:read)
196
+ tmpdir do |tmp|
197
+ original_basename =
198
+ [:path, :filename, :original_path, :original_filename].
199
+ map{|msg| upload.send(msg) if upload.respond_to?(msg)}.compact.first
200
+ basename = cleanname(original_basename)
201
+
202
+ path = File.join(tmp, basename)
203
+ open(path, 'wb'){|fd| fd.write(upload.read)}
204
+ upload_cache = UploadCache.new(key, path, options)
205
+ params.set(key, upload_cache.io)
206
+ return upload_cache
207
+ end
208
+ end
209
+
210
+ cache_key = cache_key_for(key)
211
+ upload_cache = params.get(cache_key)
212
+
213
+ if upload_cache
214
+ dirname, basename = File.split(upload_cache)
215
+ relative_dirname = File.expand_path(File.dirname(dirname))
216
+ relative_basename = File.join(relative_dirname, basename)
217
+ path = root + '/' + relative_basename
218
+ upload_cache = UploadCache.new(key, path, options)
219
+ params.set(key, upload_cache.io)
220
+ return upload_cache
221
+ end
222
+
223
+ upload_cache = UploadCache.new(key, options)
224
+ params.set(key, upload_cache.io) if upload_cache.io
225
+ return upload_cache
226
+ end
166
227
  end
167
228
 
168
229
  attr_accessor :key
169
230
  attr_accessor :cache_key
231
+ attr_accessor :name
170
232
  attr_accessor :path
171
233
  attr_accessor :dirname
172
234
  attr_accessor :basename
173
235
  attr_accessor :value
174
236
  attr_accessor :io
237
+ attr_accessor :default_url
238
+ attr_accessor :default_path
175
239
 
176
240
  IOs = {}
177
241
 
178
- def initialize(key, path)
179
- @key = key.to_s
180
- @cache_key = UploadCache.cache_key_for(key)
242
+ def initialize(key, *args)
243
+ options = Map.options_for!(args)
244
+
245
+ @key = key
246
+ @cache_key = UploadCache.cache_key_for(@key)
247
+ @name = UploadCache.name_for(@cache_key)
248
+
249
+ path = args.shift || options[:path]
250
+
251
+ default = Map.for(options[:default])
252
+
253
+ @default_url = default[:url] || options[:default_url] || UploadCache.default.url
254
+ @default_path = default[:path] || options[:default_path] || UploadCache.default.path
181
255
 
182
256
  if path
183
257
  @path = path
184
258
  @dirname, @basename = File.split(@path)
185
259
  @value = File.join(File.basename(@dirname), @basename).strip
186
- @io = open(@path)
187
- IOs[object_id] = @io.fileno
188
- ObjectSpace.define_finalizer(self, UploadCache.method(:finalizer).to_proc)
189
260
  else
190
261
  @path = nil
191
262
  @value = nil
192
263
  end
264
+
265
+ if @path or @default_path
266
+ @io = open(@path || @default_path, 'rb')
267
+ IOs[object_id] = @io.fileno
268
+ ObjectSpace.define_finalizer(self, UploadCache.method(:finalizer).to_proc)
269
+ end
270
+ end
271
+
272
+ def url
273
+ if @value
274
+ File.join(UploadCache.url, @value)
275
+ else
276
+ @default_url ? @default_url : nil
277
+ end
193
278
  end
194
279
 
195
280
  def hidden
196
- raw("<input type='hidden' name='#{ @cache_key }' value='#{ @value }' />") if @value
281
+ raw("<input type='hidden' name='#{ @name }' value='#{ @value }' class='upload_cache' />") if @value
197
282
  end
198
283
 
199
284
  def to_s
200
285
  hidden.to_s
201
286
  end
202
287
 
203
- def url
204
- File.join(UploadCache.url, @value) if @value
205
- end
206
-
207
288
  module HtmlSafe
208
289
  def html_safe() self end
209
290
  def html_safe?() self end
@@ -218,23 +299,34 @@ class UploadCache
218
299
  end
219
300
 
220
301
  def clear!
221
- FileUtils.rm_rf(@dirname) if test(?d, @dirname)
222
- rescue
223
- nil
224
- ensure
225
- @io.close
226
- IOs.delete(object_id)
227
- Thread.new{ UploadCache.clear! }
302
+ return if UploadCache.turd?
303
+
304
+ begin
305
+ FileUtils.rm_rf(@dirname) if test(?d, @dirname)
306
+ rescue
307
+ nil
308
+ ensure
309
+ @io.close rescue nil
310
+ IOs.delete(object_id)
311
+ Thread.new{ UploadCache.clear! }
312
+ end
228
313
  end
229
314
  end
230
315
 
231
316
  Upload_cache = UploadCache unless defined?(Upload_cache)
232
317
 
318
+
319
+
233
320
  if defined?(Rails.env)
321
+
322
+ if defined?(Rails.root) and Rails.root
323
+ UploadCache.url = '/system/uploads/cache'
324
+ UploadCache.root = File.join(Rails.root, 'public', UploadCache.url)
325
+ end
326
+
234
327
  unless Rails.env.production?
235
328
  if defined?(unloadable)
236
329
  unloadable(UploadCache)
237
- unloadable(Upload_cache)
238
330
  end
239
331
  end
240
332
  end
@@ -0,0 +1,28 @@
1
+ ## upload_cache.gemspec
2
+ #
3
+
4
+ Gem::Specification::new do |spec|
5
+ spec.name = "upload_cache"
6
+ spec.version = "1.2.0"
7
+ spec.platform = Gem::Platform::RUBY
8
+ spec.summary = "upload_cache"
9
+ spec.description = "description: upload_cache kicks the ass"
10
+
11
+ spec.files = ["lib", "lib/upload_cache.rb", "Rakefile", "README", "upload_cache.gemspec"]
12
+ spec.executables = []
13
+
14
+ spec.require_path = "lib"
15
+
16
+ spec.has_rdoc = true
17
+ spec.test_files = nil
18
+
19
+ # spec.add_dependency 'lib', '>= version'
20
+ spec.add_dependency 'uuidtools'
21
+
22
+ spec.extensions.push(*[])
23
+
24
+ spec.rubyforge_project = "codeforpeople"
25
+ spec.author = "Ara T. Howard"
26
+ spec.email = "ara.t.howard@gmail.com"
27
+ spec.homepage = "http://github.com/ahoward/upload_cache"
28
+ end
metadata CHANGED
@@ -1,82 +1,59 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: upload_cache
3
- version: !ruby/object:Gem::Version
4
- hash: 23
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 0
9
- - 0
10
- version: 1.0.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Ara T. Howard
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-03-16 00:00:00 -06:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2011-12-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: uuidtools
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70226716783500 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
33
22
  type: :runtime
34
- version_requirements: *id001
35
- description: "description: upload_cache kicks the ass"
23
+ prerelease: false
24
+ version_requirements: *70226716783500
25
+ description: ! 'description: upload_cache kicks the ass'
36
26
  email: ara.t.howard@gmail.com
37
27
  executables: []
38
-
39
28
  extensions: []
40
-
41
29
  extra_rdoc_files: []
42
-
43
- files:
30
+ files:
44
31
  - lib/upload_cache.rb
45
32
  - Rakefile
46
33
  - README
47
- has_rdoc: true
34
+ - upload_cache.gemspec
48
35
  homepage: http://github.com/ahoward/upload_cache
49
36
  licenses: []
50
-
51
37
  post_install_message:
52
38
  rdoc_options: []
53
-
54
- require_paths:
39
+ require_paths:
55
40
  - lib
56
- required_ruby_version: !ruby/object:Gem::Requirement
41
+ required_ruby_version: !ruby/object:Gem::Requirement
57
42
  none: false
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- hash: 3
62
- segments:
63
- - 0
64
- version: "0"
65
- required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
48
  none: false
67
- requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- hash: 3
71
- segments:
72
- - 0
73
- version: "0"
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
74
53
  requirements: []
75
-
76
54
  rubyforge_project: codeforpeople
77
- rubygems_version: 1.4.2
55
+ rubygems_version: 1.8.11
78
56
  signing_key:
79
57
  specification_version: 3
80
58
  summary: upload_cache
81
59
  test_files: []
82
-