attachment_saver 1.3.0 → 1.4.0

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: c35a16fce5a99e7ed88cc052759edcfbe3888202
4
- data.tar.gz: 79cb33e50d35f9dd4828a42e07cb11781637e3eb
3
+ metadata.gz: 1ab301b6cb41a742a469e6570ee68098947546bf
4
+ data.tar.gz: b2b922db15fc14b957f9fe6c3ef3ad7493ab4f3a
5
5
  SHA512:
6
- metadata.gz: '0911d907f27e14f6f75c1e3c80dc70f492e465868de2f38c6f7325d52eb7fa79dbaef9007070be838da7ddf76d4302b64e59b41fa268f8c176ac32191cb7612d'
7
- data.tar.gz: 649583ca6636e12a6f3f4e03ea1a8ea71124c09f5c728f116b1765e4457cdbe8ef874800b5acdc4c3c08bdbdb346fc8f954b42ee1b8d6bb6a4802b9d43f5fe78
6
+ metadata.gz: 73d1c02e925c5855493f40c313cd5320d169cfc55da1a613cdf15c15484c74e1406db90c18fed8dcb9d728dd4e89b0938fbe2cf3da2e08b092001e383684366f
7
+ data.tar.gz: c7a870a119aca14f8fb6696841f13dc8fe6300eea0db95e317eb88cc6a0d226d5771d50d1ddd649b7198b9e8466dfeeaeb55e0aedf13cde0dd40cac9895b6e5f
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
1
  test/log/*
2
2
  test/tmp/*
3
3
  test/attachment_saver_test_sqlite.db
4
+ samples.html
5
+ samples/
data/Gemfile CHANGED
@@ -9,3 +9,5 @@ gemspec
9
9
  # your gemspec. These might include edge Rails or gems from your path or
10
10
  # Git. Remember to move these dependencies to your gemspec before releasing
11
11
  # your gem to rubygems.org.
12
+
13
+ gem 'activerecord', ENV['RAILS_VERSION']
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- attachment_saver (1.2.0)
4
+ attachment_saver (1.4.0)
5
5
  activerecord
6
6
  mimemagic
7
7
 
@@ -11,19 +11,23 @@ GEM
11
11
  RubyInline (3.12.4)
12
12
  ZenTest (~> 4.3)
13
13
  ZenTest (4.11.1)
14
- activemodel (5.1.4)
15
- activesupport (= 5.1.4)
16
- activerecord (5.1.4)
17
- activemodel (= 5.1.4)
18
- activesupport (= 5.1.4)
19
- arel (~> 8.0)
20
- activesupport (5.1.4)
14
+ activemodel (5.2.0.beta2)
15
+ activesupport (= 5.2.0.beta2)
16
+ activerecord (5.2.0.beta2)
17
+ activemodel (= 5.2.0.beta2)
18
+ activesupport (= 5.2.0.beta2)
19
+ arel (>= 9.0)
20
+ activesupport (5.2.0.beta2)
21
21
  concurrent-ruby (~> 1.0, >= 1.0.2)
22
22
  i18n (~> 0.7)
23
23
  minitest (~> 5.1)
24
24
  tzinfo (~> 1.1)
25
- arel (8.0.0)
25
+ arel (9.0.0)
26
26
  concurrent-ruby (1.0.5)
27
+ gdk_pixbuf2 (2.2.5)
28
+ glib2 (= 2.2.5)
29
+ glib2 (2.2.5)
30
+ pkg-config
27
31
  i18n (0.9.1)
28
32
  concurrent-ruby (~> 1.0)
29
33
  image_science (1.3.0)
@@ -32,9 +36,10 @@ GEM
32
36
  metaclass (0.0.4)
33
37
  mimemagic (0.3.2)
34
38
  mini_magick (4.8.0)
35
- minitest (5.10.3)
39
+ minitest (5.11.0)
36
40
  mocha (1.3.0)
37
41
  metaclass (~> 0.0.1)
42
+ pkg-config (1.2.8)
38
43
  rake (12.3.0)
39
44
  rmagick (2.16.0)
40
45
  sqlite3 (1.3.13)
@@ -46,7 +51,9 @@ PLATFORMS
46
51
  ruby
47
52
 
48
53
  DEPENDENCIES
54
+ activerecord
49
55
  attachment_saver!
56
+ gdk_pixbuf2
50
57
  image_science
51
58
  image_size
52
59
  mini_magick
@@ -56,4 +63,4 @@ DEPENDENCIES
56
63
  sqlite3
57
64
 
58
65
  BUNDLED WITH
59
- 1.15.3
66
+ 1.16.1
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007 Will Bryant, Sekuda Ltd
1
+ Copyright (c) 2007-2018 Will Bryant, Sekuda Ltd
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README CHANGED
@@ -8,14 +8,16 @@ provided, and the architecture simplifies clean implementation of other types
8
8
  of processing. Errors are carefully handled to minimize the possibility of
9
9
  broken uploads leaving incomplete or corrupt data.
10
10
 
11
- RMagick, MiniMagick, and ImageScience image processors are supported.
11
+ RMagick, MiniMagick, ImageScience, and GdkPixbuf image processors are supported.
12
+
13
+ The pure-ruby ImageSize image processor is also supported (for inspecting images but not resizing them).
12
14
 
13
15
 
14
16
  Compatibility
15
17
  =============
16
18
 
17
- Currently tested against Rails 3.2.13 and 3.1.8, on Ruby 1.8.7 and 2.0.0p0.
18
- Was also tested compatible with 2.3.14 and 3.0.17.
19
+ Currently tested against Rails 5.2 (up to 5.2.0.beta2), 5.1 (up to 5.1.4), 5.0 (up to 5.0.6), and 4.2 (up to 4.2.10), on Ruby 2.3.6, 2.4.3, and 2.5.0.
20
+ Was also tested compatible with 2.3.14, 3.0.17, 3.1.8, 3.2.13, 4.2, and 5.0.
19
21
 
20
22
 
21
23
  Examples
@@ -116,7 +118,7 @@ A custom image-processing format using your image-processor's features
116
118
  ----------------------------------------------------------------------
117
119
 
118
120
  # in a file in your lib/ directory that's required in somewhere:
119
- module AttachmentSaver::Processors::RMagick::Operations # or MiniMagick::Operations or ImageScience::Operations - see lib/processors
121
+ module AttachmentSaver::Processors::RMagick::Operations # or MiniMagick::Operations or ImageScience::Operations or GdkPixbuf::Operations - see lib/processors
120
122
  # this module is mixed in to the actual image objects built by the processor, so you can call its' methods directly
121
123
  def wavy_black_and_white(wave_height, wave_length, &block)
122
124
  # RMagick returns the new object; MiniMagick acts on the same object (so you must dup); ImageScience yields; so, look at the existing lib/processors to see the appropriate pattern
@@ -33,6 +33,7 @@ EOF
33
33
  gem.add_development_dependency "rmagick"
34
34
  gem.add_development_dependency "mini_magick"
35
35
  gem.add_development_dependency "image_size"
36
+ gem.add_development_dependency "gdk_pixbuf2"
36
37
  gem.add_development_dependency "sqlite3"
37
38
  gem.add_development_dependency "mocha"
38
39
  end
@@ -1,3 +1,3 @@
1
1
  module AttachmentSaver
2
- VERSION = '1.3.0'
2
+ VERSION = '1.4.0'
3
3
  end
@@ -0,0 +1,106 @@
1
+ require 'gdk_pixbuf2'
2
+ require 'misc/extended_tempfile'
3
+ require 'processors/image'
4
+
5
+ class GdkPixbufProcessorError < ImageProcessorError; end
6
+
7
+ module AttachmentSaver
8
+ module Processors
9
+ module GdkPixbuf
10
+ include Image
11
+
12
+ def with_image(filename, &block)
13
+ # we use Gdk::PixbufLoader rather than Gdk::Pixbuf.new(filename) so that we can learn the format of the
14
+ # image, which process_image wants to know so that it can save the derived images in the same format.
15
+ loader = Gdk::PixbufLoader.new
16
+ File.open(filename, "rb") do |file|
17
+ while buf = file.read(65536)
18
+ loader.write(buf)
19
+ end
20
+ end
21
+ loader.close
22
+ image = loader.pixbuf
23
+ image.extend(Operations)
24
+ image.format = loader.format.name
25
+ block.call(image)
26
+ end
27
+
28
+ def examine_image
29
+ fileinfo, width, height = Gdk::Pixbuf.get_file_info(uploaded_file_path)
30
+ raise GdkPixbufProcessorError, "Not an image" if fileinfo.nil?
31
+
32
+ self.width = width if respond_to?(:width)
33
+ self.height = height if respond_to?(:height)
34
+ self.content_type = fileinfo.mime_types.first unless self.class.attachment_options[:keep_content_type] || fileinfo.mime_types.empty?
35
+ self.file_extension = normalize_extension(fileinfo.extensions.first) unless self.class.attachment_options[:keep_file_extension] || fileinfo.extensions.empty?
36
+ rescue AttachmentSaverError
37
+ raise
38
+ rescue Exception => ex
39
+ raise GdkPixbufProcessorError, "#{ex.class}: #{ex.message}", ex.backtrace
40
+ end
41
+
42
+ def normalize_extension(extension)
43
+ case extension
44
+ when 'jpeg' then 'jpg'
45
+ else extension
46
+ end
47
+ end
48
+
49
+ def process_image(original_image, derived_format_name, resize_format)
50
+ resize_format = Image.from_geometry_string(resize_format) if resize_format.is_a?(String)
51
+
52
+ result = original_image.send(*resize_format) do |derived_image|
53
+ return nil unless want_format?(derived_format_name, derived_image.width, derived_image.height)
54
+
55
+ # both original_filename and content_type must be defined for parents when using image processing
56
+ # - but apps can just define them using attr_accessor if they don't want them persisted to db
57
+ derived_content_type = content_type
58
+ derived_extension = derived_image.file_type_extension
59
+
60
+ # we leverage tempfiles as discussed in the uploaded_file method
61
+ temp = ExtendedTempfile.new("asgtemp", tempfile_directory, derived_extension)
62
+ temp.binmode
63
+ temp.close
64
+ derived_image.save(temp.path, original_image.format)
65
+ temp.open # we close & reopen so we see the file the processor wrote to, even if it created a new file rather than writing into our tempfile
66
+
67
+ { :format_name => derived_format_name.to_s,
68
+ :width => derived_image.width,
69
+ :height => derived_image.height,
70
+ :content_type => derived_content_type,
71
+ :file_extension => derived_extension,
72
+ :uploaded_data => temp }
73
+ end
74
+
75
+ result
76
+ end
77
+
78
+ module Operations
79
+ include AttachmentSaver::Processors::Image::Operations
80
+
81
+ attr_accessor :format
82
+
83
+ def file_type_extension
84
+ case format
85
+ when 'jpeg' then 'jpg'
86
+ else format.downcase
87
+ end
88
+ end
89
+
90
+ def resize_to(new_width, new_height, &block)
91
+ image = scale(new_width, new_height)
92
+ image.extend Operations
93
+ image.format = format
94
+ block.call(image)
95
+ end
96
+
97
+ def crop_to(new_width, new_height, &block) # crops to the center
98
+ image = Gdk::Pixbuf.new(self, (width - new_width)/2, (height - new_height)/2, new_width, new_height)
99
+ image.extend Operations
100
+ image.format = format
101
+ block.call(image)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -132,7 +132,7 @@ module AttachmentSaver
132
132
  module Operations
133
133
  # if they choose to use this module to implement the resize operations, the processor
134
134
  # module just needs to implement width, height, resize_to(new_width, new_height, &block),
135
- # and crop_to(new_width, new_height, &block)
135
+ # and crop_to(new_width, new_height, &block). they also need with_image for process_attachment.
136
136
 
137
137
  # squishes the image to the given width and height, without preserving the aspect ratio.
138
138
  # yields this image itself if it is already the given size.
@@ -0,0 +1,42 @@
1
+ require 'image_size'
2
+ require 'misc/extended_tempfile'
3
+ require 'processors/image'
4
+
5
+ class ImageSizeProcessorError < ImageProcessorError; end
6
+
7
+ module AttachmentSaver
8
+ module Processors
9
+ module ImageSize
10
+ include Image
11
+
12
+ def examine_image
13
+ image_size = ::ImageSize.path(uploaded_file_path)
14
+ raise ImageSizeProcessorError, "Not an image" if image_size.format.nil?
15
+
16
+ self.width = image_size.width if respond_to?(:width)
17
+ self.height = image_size.height if respond_to?(:height)
18
+ self.file_extension = extension_for_image_format(image_size.format) unless self.class.attachment_options[:keep_file_extension]
19
+ self.content_type = mime_type_for_image_format(image_size.format) unless self.class.attachment_options[:keep_content_type]
20
+ rescue AttachmentSaverError
21
+ raise
22
+ rescue Exception => ex
23
+ raise ImageSizeProcessorError, "#{ex.class}: #{ex.message}", ex.backtrace
24
+ end
25
+
26
+ def extension_for_image_format(format)
27
+ case format
28
+ when :jpeg then 'jpg'
29
+ else format.to_s
30
+ end
31
+ end
32
+
33
+ def mime_type_for_image_format(format)
34
+ "image/#{format}"
35
+ end
36
+
37
+ def with_image(*args)
38
+ raise NotImplementedError, "the image_size processor can only be used to check image types and dimensions, not produce resized images"
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ require 'active_record'
4
+ require 'active_support/inflector'
5
+ require 'attachment_saver'
6
+ require File.expand_path(File.join(File.dirname(__FILE__), 'test', 'image_operations'))
7
+
8
+ sample_dir = File.expand_path(File.join(File.dirname(__FILE__), 'samples'))
9
+ FileUtils.rm_r(sample_dir)
10
+ FileUtils.mkdir(sample_dir)
11
+
12
+ original_filenames = %w(test/fixtures/test.jpg test/fixtures/pd.png)
13
+
14
+ processors = %w(ImageScience RMagick MiniMagick GdkPixbuf).each.with_object({}) do |processor, results|
15
+ require "processors/#{processor.underscore}"
16
+
17
+ instance = Object.new
18
+ instance.class_eval { attr_accessor :content_type }
19
+ instance.extend(AttachmentSaver::InstanceMethods)
20
+ instance.extend(AttachmentSaver::Processors.const_get(processor))
21
+
22
+ results[processor] = instance
23
+ end
24
+
25
+ File.open("samples.html", "w") do |html|
26
+ html.write "<html><body>"
27
+
28
+ original_filenames.each do |original_filename|
29
+ html.write "<h1>#{original_filename}</h1><table border='2'><tr><th></th>"
30
+ processors.each do |processor, instance|
31
+ html.write "<th>#{processor}</th>"
32
+ end
33
+ html.write "</tr>"
34
+
35
+ ImageOperations.resize_operations.each do |derived_format_name, format_definition|
36
+ html.write "<tr><th>#{derived_format_name}<br/><pre>#{format_definition.inspect}</pre></th>"
37
+ processors.each do |processor, instance|
38
+ instance.with_image(original_filename) do |original_image|
39
+ result = instance.process_image(original_image, derived_format_name, format_definition)
40
+
41
+ filename = "#{sample_dir}/#{processor.underscore}-#{File.basename original_filename}-#{result[:format_name]}.#{result[:file_extension]}"
42
+ File.open(filename, "wb") do |f|
43
+ result[:uploaded_data].rewind
44
+ IO.copy_stream(result[:uploaded_data], f)
45
+ end
46
+ size = result[:uploaded_data].size < 1024 ? "#{result[:uploaded_data].size} bytes" : "%0.1fkb" % (result[:uploaded_data].size/1024.0)
47
+ html.write "<td><img src='#{filename}' width='#{result[:width]}' height='#{result[:height]}'><br/>#{size}</td>"
48
+ end
49
+ end
50
+ html.write "</tr>"
51
+ end
52
+
53
+ html.write "</table>"
54
+ end
55
+
56
+ html.write "</html></body>"
57
+ end
Binary file
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'image_processor_test_common'))
2
+ require 'processors/gdk_pixbuf'
3
+
4
+ class GdkPixbufProcessorTest < ActiveSupport::TestCase
5
+ class GdkPixbufTestModel
6
+ include AttachmentSaver::InstanceMethods
7
+ include AttachmentSaver::Processors::GdkPixbuf
8
+ include ImageProcessorTestModel
9
+ end
10
+
11
+ def processor_model
12
+ GdkPixbufTestModel
13
+ end
14
+
15
+ def processor_exception
16
+ GdkPixbufProcessorError
17
+ end
18
+
19
+ include ImageProcessorTests
20
+ end
@@ -40,7 +40,8 @@ class ImageOperations
40
40
  :scaletocover2 => [:scale_to_cover, 720, 900],
41
41
 
42
42
  :coverandcrop1 => [:cover_and_crop, 200, 300],
43
- :coverandcrop2 => [:cover_and_crop, 720, 900],
43
+ :coverandcrop2 => [:cover_and_crop, 300, 200],
44
+ :coverandcrop3 => [:cover_and_crop, 720, 900],
44
45
  }
45
46
  end
46
47
 
@@ -75,7 +76,8 @@ class ImageOperations
75
76
  :scaletocover2 => [720, 720*600/448],
76
77
 
77
78
  :coverandcrop1 => [200, 300],
78
- :coverandcrop2 => [720, 900],
79
+ :coverandcrop2 => [300, 200],
80
+ :coverandcrop3 => [720, 900],
79
81
  }
80
82
  end
81
83
 
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'image_processor_test_common'))
2
+ require 'processors/image_size'
3
+
4
+ class ImageSizeProcessorTest < ActiveSupport::TestCase
5
+ class ImageSizeTestModel
6
+ include AttachmentSaver::InstanceMethods
7
+ include AttachmentSaver::Processors::ImageSize
8
+ include ImageProcessorTestModel
9
+ end
10
+
11
+ def processor_model
12
+ ImageSizeTestModel
13
+ end
14
+
15
+ def processor_exception
16
+ ImageSizeProcessorError
17
+ end
18
+
19
+ include ImageProcessorTests
20
+
21
+ def processes_images?
22
+ false
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ for version in 4.2.10 5.0.6 5.1.4 5.2.0.beta2
6
+ do
7
+ RAILS_VERSION=$version bundle update activerecord
8
+ bundle exec rake
9
+ done
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attachment_saver
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Will Bryant
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-20 00:00:00.000000000 Z
11
+ date: 2018-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: gdk_pixbuf2
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: sqlite3
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -166,25 +180,31 @@ files:
166
180
  - lib/misc/extended_tempfile.rb
167
181
  - lib/misc/image_science_extensions.rb
168
182
  - lib/misc/mini_magick_extensions.rb
183
+ - lib/processors/gdk_pixbuf.rb
169
184
  - lib/processors/image.rb
170
185
  - lib/processors/image_science.rb
186
+ - lib/processors/image_size.rb
171
187
  - lib/processors/mini_magick.rb
172
188
  - lib/processors/r_magick.rb
189
+ - samples.rb
173
190
  - test/attachment_saver_test.rb
174
191
  - test/database.yml
175
192
  - test/file_system_datastore_test.rb
176
193
  - test/fixtures/broken.jpg
177
194
  - test/fixtures/emptyextension.
178
195
  - test/fixtures/noextension
196
+ - test/fixtures/pd.png
179
197
  - test/fixtures/ssrf.png
180
198
  - test/fixtures/test.jpg
181
199
  - test/fixtures/test.js
182
200
  - test/fixtures/wrongextension.png
201
+ - test/gdk_pixbuf_processor_test.rb
183
202
  - test/image_fixtures.rb
184
203
  - test/image_operations.rb
185
204
  - test/image_processor_test.rb
186
205
  - test/image_processor_test_common.rb
187
206
  - test/image_science_processor_test.rb
207
+ - test/image_size_processor_test.rb
188
208
  - test/in_column_datastore_test.rb
189
209
  - test/mini_magick_processor_test.rb
190
210
  - test/model_test.rb
@@ -192,6 +212,7 @@ files:
192
212
  - test/rmagick_processor_test.rb
193
213
  - test/schema.rb
194
214
  - test/test_helper.rb
215
+ - test_all.sh
195
216
  homepage: http://github.com/willbryant/attachment_saver
196
217
  licenses:
197
218
  - MIT
@@ -223,15 +244,18 @@ test_files:
223
244
  - test/fixtures/broken.jpg
224
245
  - test/fixtures/emptyextension.
225
246
  - test/fixtures/noextension
247
+ - test/fixtures/pd.png
226
248
  - test/fixtures/ssrf.png
227
249
  - test/fixtures/test.jpg
228
250
  - test/fixtures/test.js
229
251
  - test/fixtures/wrongextension.png
252
+ - test/gdk_pixbuf_processor_test.rb
230
253
  - test/image_fixtures.rb
231
254
  - test/image_operations.rb
232
255
  - test/image_processor_test.rb
233
256
  - test/image_processor_test_common.rb
234
257
  - test/image_science_processor_test.rb
258
+ - test/image_size_processor_test.rb
235
259
  - test/in_column_datastore_test.rb
236
260
  - test/mini_magick_processor_test.rb
237
261
  - test/model_test.rb