attache 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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