attache 2.2.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 228685a6b1038b73b233cf5165570252f271f447
4
- data.tar.gz: df3611d3b73a8c2120b9fda08fab214bfaa55ecb
3
+ metadata.gz: 40d8defcee67748b1a0bffcb19211ea6a784f4a0
4
+ data.tar.gz: 2c4448d76d29a7115f6ebec5448ab76835ba2883
5
5
  SHA512:
6
- metadata.gz: d8556bbf47617561a3bafd4bacb72ae3445e52357ee1acd5e5fd92473f4d1fbfe9336a86a3c6af30df01392a207a3be05881d88290c3cbf95dff3335dc515899
7
- data.tar.gz: 71ec695990a228854eb3ba24fdcb5462f70b106670fa370d08d89584e04ae7e4ab8f9d5788cbf800f6d312a0fc6093bd8e82a86af27b8e8f605907de28199ee8
6
+ metadata.gz: 025d0526f38962154e8a5e4ff88973778e6ca97722d0a81310b8a8e869634d886cbcc262408a7db7fccc4ad4e5f92853f7bb69d5e5abad07ba3a0c262c2da339
7
+ data.tar.gz: 932a2b35ad81e8a554c94bd43fa414964d0a72d6263eefdcadb6e5f71a75b8d2f78f39757228878e59654287de7e4be74b659265d721931a63b1d389649c8895
data/README.md CHANGED
@@ -143,11 +143,7 @@ Users will upload files directly into the `attache` server from their browser, b
143
143
  > ```
144
144
  > PUT /upload?file=image123.jpg
145
145
  > ```
146
- > file content is the http request body as raw binary (preferred) or encoded as base64 uri like this:
147
- > ```
148
- > PUT /upload?file=image123.jpg
149
- > data:image/jpeg;base64,/9j/4QBiR....
150
- > ```
146
+ > file content is the http request body
151
147
 
152
148
  The main app front end will receive a unique `path` for each uploaded file - the only information to store in the main app database.
153
149
 
@@ -5,6 +5,7 @@ class Attache::Download < Attache::Base
5
5
 
6
6
  def initialize(app)
7
7
  @app = app
8
+ @mutexes = {}
8
9
  end
9
10
 
10
11
  def _call(env, config)
@@ -23,52 +24,20 @@ class Attache::Download < Attache::Base
23
24
  return [302, headers, []]
24
25
  end
25
26
 
26
- file = begin
27
- cachekey = File.join(request_hostname(env), relpath)
28
- Attache.cache.fetch(cachekey) do
29
- name_with_vhost_pairs = vhosts.inject({}) { |sum,(k,v)| (v ? sum.merge(k => v) : sum) }
30
- get_first_result_present_async(name_with_vhost_pairs.collect {|name, vhost|
31
- lambda { Thread.handle_interrupt(BasicObject => :on_blocking) {
32
- begin
33
- Attache.logger.info "[POOL] looking for #{name} #{relpath}..."
34
- vhost.storage_get(relpath: relpath).tap do |v|
35
- Attache.logger.info "[POOL] found #{name} #{relpath} = #{v.inspect}"
36
- end
37
- rescue Exception
38
- Attache.logger.error $!
39
- Attache.logger.error $@
40
- Attache.logger.info "[POOL] not found #{name} #{relpath}"
41
- nil
42
- end
43
- } }
44
- })
27
+ thumbnail = case geometry
28
+ when 'original', *vhosts.keys
29
+ get_original_file(relpath, vhosts, env)
30
+ else
31
+ get_thumbnail_file(geometry, basename, relpath, vhosts, env)
45
32
  end
46
- rescue Exception # Errno::ECONNREFUSED, OpenURI::HTTPError, Excon::Errors, Fog::Errors::Error
47
- Attache.logger.error "ERROR REFERER #{env['HTTP_REFERER'].inspect}"
48
- nil
49
- end
50
33
 
51
- unless file && file.try(:size).to_i > 0
52
- return [404, config.download_headers, []]
53
- end
54
-
55
- thumbnail = case geometry
56
- when 'original', *vhosts.keys
57
- file
58
- else
59
- extension = basename.split(/\W+/).last
60
- make_thumbnail_for(file.tap(&:close), geometry, extension, basename)
61
- end
34
+ return [404, config.download_headers, []] if thumbnail.try(:size).to_i == 0
62
35
 
63
36
  headers = {
64
37
  'Content-Type' => content_type_of(thumbnail.path),
65
38
  }.merge(config.download_headers)
66
39
 
67
- [200, headers, rack_response_body_for(thumbnail)].tap do
68
- unless file == thumbnail # cleanup
69
- File.unlink(thumbnail.path) rescue Errno::ENOENT
70
- end
71
- end
40
+ [200, headers, rack_response_body_for(thumbnail)]
72
41
  end
73
42
  else
74
43
  @app.call(env)
@@ -86,11 +55,55 @@ class Attache::Download < Attache::Base
86
55
  yield dirname, geometry, basename, relpath
87
56
  end
88
57
 
89
- def make_thumbnail_for(file, geometry, extension, basename)
90
- Attache.logger.info "[POOL] new job"
91
- RESIZE_JOB_POOL.with do |job|
92
- job.perform(file, geometry, extension, basename)
58
+ def synchronize(key, &block)
59
+ mutex = @mutexes[key] ||= Mutex.new
60
+ mutex.synchronize(&block)
61
+ ensure
62
+ @mutexes.delete(key)
63
+ end
64
+
65
+ def get_thumbnail_file(geometry, basename, relpath, vhosts, env)
66
+ cachekey = File.join(request_hostname(env), relpath, geometry)
67
+ synchronize(cachekey) do
68
+ tempfile = nil
69
+ Attache.cache.fetch(cachekey) do
70
+ Attache.logger.info "[POOL] new job"
71
+ tempfile = RESIZE_JOB_POOL.with do |job|
72
+ job.perform(geometry, basename, relpath, vhosts, env) do
73
+ # opens up possibility that job implementation
74
+ # does not require we download original file prior
75
+ get_original_file(relpath, vhosts, env)
76
+ end
77
+ end
78
+ end.tap { File.unlink(tempfile.path) if tempfile.try(:path) }
79
+ end
80
+ end
81
+
82
+ def get_original_file(relpath, vhosts, env)
83
+ cachekey = File.join(request_hostname(env), relpath)
84
+ synchronize(cachekey) do
85
+ Attache.cache.fetch(cachekey) do
86
+ name_with_vhost_pairs = vhosts.inject({}) { |sum,(k,v)| (v ? sum.merge(k => v) : sum) }
87
+ get_first_result_present_async(name_with_vhost_pairs.collect {|name, vhost|
88
+ lambda { Thread.handle_interrupt(BasicObject => :on_blocking) {
89
+ begin
90
+ Attache.logger.info "[POOL] looking for #{name} #{relpath}..."
91
+ vhost.storage_get(relpath: relpath).tap do |v|
92
+ Attache.logger.info "[POOL] found #{name} #{relpath} = #{v.inspect}"
93
+ end
94
+ rescue Exception
95
+ Attache.logger.error $!
96
+ Attache.logger.error $@
97
+ Attache.logger.info "[POOL] not found #{name} #{relpath}"
98
+ nil
99
+ end
100
+ } }
101
+ })
102
+ end
93
103
  end
104
+ rescue Exception # Errno::ECONNREFUSED, OpenURI::HTTPError, Excon::Errors, Fog::Errors::Error
105
+ Attache.logger.error "ERROR REFERER #{env['HTTP_REFERER'].inspect}"
106
+ nil
94
107
  end
95
108
 
96
109
  # Ref https://gist.github.com/sferik/39831f34eb87686b639c#gistcomment-1652888
@@ -1,8 +1,12 @@
1
1
  require 'digest/sha1'
2
+ require 'stringio'
2
3
 
3
4
  class Attache::ResizeJob
4
- def perform(closed_file, target_geometry_string, extension, basename)
5
- t = Time.now
5
+ def perform(target_geometry_string, basename, relpath, vhosts, env, t = Time.now)
6
+ closed_file = yield
7
+ return StringIO.new if closed_file.try(:size).to_i == 0
8
+
9
+ extension = basename.split(/\W+/).last
6
10
  Attache.logger.info "[POOL] start"
7
11
  return make_nonimage_preview(closed_file, basename) if ['pdf', 'txt'].include?(extension.to_s.downcase)
8
12
 
@@ -1,3 +1,3 @@
1
1
  module Attache
2
- VERSION = "2.2.0"
2
+ VERSION = "2.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attache
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - choonkeat
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-29 00:00:00.000000000 Z
11
+ date: 2016-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack