attachment_saver 1.0.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.
- data/.gitignore +3 -0
- data/MIT-LICENSE +19 -0
- data/README +137 -0
- data/Rakefile +16 -0
- data/attachment_saver.gemspec +41 -0
- data/init.rb +1 -0
- data/lib/attachment_saver.rb +171 -0
- data/lib/attachment_saver/version.rb +3 -0
- data/lib/attachment_saver_errors.rb +3 -0
- data/lib/datastores/file_system.rb +189 -0
- data/lib/datastores/in_column.rb +49 -0
- data/lib/misc/extended_tempfile.rb +12 -0
- data/lib/misc/file_size.rb +5 -0
- data/lib/misc/image_science_extensions.rb +102 -0
- data/lib/misc/mini_magick_extensions.rb +89 -0
- data/lib/processors/image.rb +187 -0
- data/lib/processors/image_science.rb +94 -0
- data/lib/processors/mini_magick.rb +103 -0
- data/lib/processors/r_magick.rb +120 -0
- data/test/attachment_saver_test.rb +162 -0
- data/test/database.yml +3 -0
- data/test/file_system_datastore_test.rb +468 -0
- data/test/fixtures/broken.jpg +1 -0
- data/test/fixtures/emptyextension. +0 -0
- data/test/fixtures/noextension +0 -0
- data/test/fixtures/test.jpg +0 -0
- data/test/fixtures/test.js +1 -0
- data/test/fixtures/wrongextension.png +0 -0
- data/test/image_fixtures.rb +69 -0
- data/test/image_operations.rb +114 -0
- data/test/image_processor_test.rb +67 -0
- data/test/image_processor_test_common.rb +81 -0
- data/test/image_science_processor_test.rb +20 -0
- data/test/in_column_datastore_test.rb +115 -0
- data/test/mini_magick_processor_test.rb +20 -0
- data/test/model_test.rb +205 -0
- data/test/public/.empty +0 -0
- data/test/rmagick_processor_test.rb +20 -0
- data/test/schema.rb +41 -0
- data/test/test_helper.rb +49 -0
- metadata +223 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'image_processor_test_common'))
|
2
|
+
require 'processors/mini_magick'
|
3
|
+
|
4
|
+
class MiniMagickProcessorTest < Test::Unit::TestCase
|
5
|
+
class MiniMagickTestModel
|
6
|
+
include AttachmentSaver::InstanceMethods
|
7
|
+
include AttachmentSaver::Processors::MiniMagick
|
8
|
+
include ImageProcessorTestModel
|
9
|
+
end
|
10
|
+
|
11
|
+
def processor_model
|
12
|
+
MiniMagickTestModel
|
13
|
+
end
|
14
|
+
|
15
|
+
def processor_exception
|
16
|
+
MiniMagickProcessorError
|
17
|
+
end
|
18
|
+
|
19
|
+
include ImageProcessorTests
|
20
|
+
end
|
data/test/model_test.rb
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'image_fixtures'))
|
3
|
+
|
4
|
+
class DerivedImage < ActiveRecord::Base
|
5
|
+
saves_attachment
|
6
|
+
end
|
7
|
+
|
8
|
+
class Image < ActiveRecord::Base
|
9
|
+
FORMATS = {:thumb => [:cover_and_crop, 50, 50],
|
10
|
+
:medium => [:shrink_to_fit, 500, 500],
|
11
|
+
:big => [:shrink_to_fit, 1024, 1024]}
|
12
|
+
saves_attachment :formats => FORMATS
|
13
|
+
end
|
14
|
+
|
15
|
+
class OtherImage < ActiveRecord::Base
|
16
|
+
saves_attachment :formats => {:small => [:shrink_to_fit, 200, 200], :normal => [:shrink_to_fit, 400, 300]}
|
17
|
+
cattr_accessor :want_smalls
|
18
|
+
|
19
|
+
protected
|
20
|
+
def want_format?(format_name, width, height)
|
21
|
+
format_name != :small || self.class.want_smalls
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Unprocessed < ActiveRecord::Base
|
26
|
+
saves_attachment
|
27
|
+
validates_presence_of :original_filename, :content_type, :size
|
28
|
+
end
|
29
|
+
|
30
|
+
class LoadedImage < ActiveRecord::Base
|
31
|
+
set_table_name 'images'
|
32
|
+
saves_attachment :processor => 'image_science' # don't create any derived images, but still process the image to get the attributes
|
33
|
+
end
|
34
|
+
|
35
|
+
class AllInOneTableImages < ActiveRecord::Base
|
36
|
+
saves_attachment :formats => {:small => '200x200', :normal => '400x'},
|
37
|
+
:derived_class => 'AllInOneTableImages'
|
38
|
+
end
|
39
|
+
|
40
|
+
class ImageScienceImage < ActiveRecord::Base
|
41
|
+
set_table_name 'images'
|
42
|
+
saves_attachment :processor => 'ImageScience', :formats => {:small => '200x200'}
|
43
|
+
end
|
44
|
+
|
45
|
+
class RMagickImage < ActiveRecord::Base
|
46
|
+
set_table_name 'images'
|
47
|
+
saves_attachment :processor => 'RMagick', :formats => {:small => '200x200'}
|
48
|
+
end
|
49
|
+
|
50
|
+
class MiniMagickImage < ActiveRecord::Base
|
51
|
+
set_table_name 'images'
|
52
|
+
saves_attachment :processor => 'RMagick', :formats => {:small => '200x200'}
|
53
|
+
end
|
54
|
+
|
55
|
+
class ModelTest < Test::Unit::TestCase
|
56
|
+
module ValidUploadedFileAttributes
|
57
|
+
def fixture=(value)
|
58
|
+
@fixture = value
|
59
|
+
end
|
60
|
+
|
61
|
+
def original_filename
|
62
|
+
@fixture[:original_filename]
|
63
|
+
end
|
64
|
+
|
65
|
+
def content_type
|
66
|
+
@fixture[:content_type]
|
67
|
+
end
|
68
|
+
|
69
|
+
def size
|
70
|
+
stat.size
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def uploaded_file_from(fixture)
|
75
|
+
f = File.open(fixture[:path])
|
76
|
+
f.extend ValidUploadedFileAttributes
|
77
|
+
f.fixture = fixture
|
78
|
+
f
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_unprocessed_attachment
|
82
|
+
model = Unprocessed.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
83
|
+
assert_equal ImageFixtures::valid[:expected_content_type], model.content_type
|
84
|
+
assert_equal ImageFixtures::valid[:expected_extension], model.file_extension
|
85
|
+
assert_equal ImageFixtures::valid[:expected_extension], AttachmentSaver::split_filename(model.storage_filename).last
|
86
|
+
assert File.read(ImageFixtures::valid[:path]) == File.read(model.storage_filename), "stored data doesn't match!"
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_underived_but_processed_attachment
|
90
|
+
model = LoadedImage.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
91
|
+
assert_equal ImageFixtures::valid[:expected_content_type], model.content_type
|
92
|
+
assert_equal ImageFixtures::valid[:expected_extension], model.file_extension
|
93
|
+
assert_equal ImageFixtures::valid[:expected_extension], AttachmentSaver::split_filename(model.storage_filename).last
|
94
|
+
assert File.read(ImageFixtures::valid[:path]) == File.read(model.storage_filename), "stored data doesn't match!"
|
95
|
+
assert_equal ImageFixtures::valid[:width], model.width
|
96
|
+
assert_equal ImageFixtures::valid[:height], model.height
|
97
|
+
assert_equal "#{ImageFixtures::valid[:width]}x#{ImageFixtures::valid[:height]}", model.image_size
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_extension_and_type_correction
|
101
|
+
model = LoadedImage.create!(:uploaded_data => uploaded_file_from(ImageFixtures::wrong_extension))
|
102
|
+
assert_equal ImageFixtures::wrong_extension[:expected_content_type], model.content_type
|
103
|
+
assert_equal ImageFixtures::wrong_extension[:expected_extension], model.file_extension
|
104
|
+
assert_equal ImageFixtures::wrong_extension[:expected_extension], AttachmentSaver::split_filename(model.storage_filename).last
|
105
|
+
assert File.read(ImageFixtures::wrong_extension[:path]) == File.read(model.storage_filename), "stored data doesn't match!"
|
106
|
+
assert_equal ImageFixtures::wrong_extension[:width], model.width
|
107
|
+
assert_equal ImageFixtures::wrong_extension[:height], model.height
|
108
|
+
assert_equal "#{ImageFixtures::wrong_extension[:width]}x#{ImageFixtures::wrong_extension[:height]}", model.image_size
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_image_resizing
|
112
|
+
model = Image.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
113
|
+
assert_equal ImageFixtures::valid[:expected_content_type], model.content_type
|
114
|
+
assert_equal ImageFixtures::valid[:expected_extension], model.file_extension
|
115
|
+
assert_equal ImageFixtures::valid[:expected_extension], AttachmentSaver::split_filename(model.storage_filename).last
|
116
|
+
assert File.read(ImageFixtures::valid[:path]) == File.read(model.storage_filename), "stored data doesn't match!"
|
117
|
+
assert_equal ImageFixtures::valid[:width], model.width
|
118
|
+
assert_equal ImageFixtures::valid[:height], model.height
|
119
|
+
assert_equal "#{ImageFixtures::valid[:width]}x#{ImageFixtures::valid[:height]}", model.image_size
|
120
|
+
|
121
|
+
# full resize operation tests are performed in image_*_processor_test, here we just check enough to ensure that they were executed
|
122
|
+
|
123
|
+
assert_equal Image::FORMATS.keys.collect(&:to_s).sort, model.formats.collect(&:format_name).sort
|
124
|
+
model.formats.each {|size| assert !size.new_record?}
|
125
|
+
|
126
|
+
thumb = model.formats.find_by_format_name('thumb')
|
127
|
+
assert_equal Image::FORMATS[:thumb][1], thumb.width
|
128
|
+
assert_equal Image::FORMATS[:thumb][1], thumb.height
|
129
|
+
|
130
|
+
medium = model.formats.find_by_format_name('medium')
|
131
|
+
assert medium.width <= Image::FORMATS[:medium][1]
|
132
|
+
assert medium.height <= Image::FORMATS[:medium][2]
|
133
|
+
assert medium.width == Image::FORMATS[:medium][1] || medium.height == Image::FORMATS[:medium][2]
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_image_science
|
137
|
+
model = ImageScienceImage.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
138
|
+
assert_equal ['small'], model.formats.collect(&:format_name)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_rmagick
|
142
|
+
model = RMagickImage.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
143
|
+
assert_equal ['small'], model.formats.collect(&:format_name)
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_mini_magick
|
147
|
+
model = MiniMagickImage.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
148
|
+
assert_equal ['small'], model.formats.collect(&:format_name)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_image_rebuilding
|
152
|
+
model = Image.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
153
|
+
old_storage_filenames = [model.storage_filename] + model.formats.sort_by(&:format_name).collect(&:storage_filename)
|
154
|
+
model.update_attributes(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
155
|
+
new_storage_filenames = [model.storage_filename] + model.formats.sort_by(&:format_name).collect(&:storage_filename)
|
156
|
+
model.reload
|
157
|
+
model.formats(true)
|
158
|
+
reloaded_storage_filenames = [model.storage_filename] + model.formats.sort_by(&:format_name).collect(&:storage_filename)
|
159
|
+
|
160
|
+
assert_equal Image::FORMATS.size, model.formats.size
|
161
|
+
assert_equal Image::FORMATS.keys.collect(&:to_s).sort, model.formats.collect(&:format_name).sort
|
162
|
+
|
163
|
+
assert_equal old_storage_filenames.size, new_storage_filenames.size
|
164
|
+
assert_equal old_storage_filenames.size, reloaded_storage_filenames.size
|
165
|
+
old_storage_filenames.each_with_index do |f, i|
|
166
|
+
assert_not_equal f, new_storage_filenames[i]
|
167
|
+
assert_not_equal f, reloaded_storage_filenames[i]
|
168
|
+
assert_equal new_storage_filenames[i], reloaded_storage_filenames[i]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_want_format?
|
173
|
+
OtherImage.want_smalls = false
|
174
|
+
model = OtherImage.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
175
|
+
assert_equal ["normal"], model.formats.collect(&:format_name).sort
|
176
|
+
|
177
|
+
OtherImage.want_smalls = true
|
178
|
+
model = OtherImage.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
179
|
+
assert_equal ["normal", "small"], model.formats.collect(&:format_name).sort
|
180
|
+
|
181
|
+
OtherImage.want_smalls = false
|
182
|
+
model.update_attributes!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
183
|
+
#assert_equal ["normal"], model.formats.collect(&:format_name).sort # because we use formats.destroy(..ids..), they really should be removed from the formats collection in memory, but aren't in Rails 1.2.3 :/. so the normal, expected semantics is that apps must reload to see collection changes.
|
184
|
+
assert_equal ["normal"], model.formats(true).collect(&:format_name).sort
|
185
|
+
# note that the small size has not only been not regenerated, it's been deleted
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_all_in_one_table
|
189
|
+
model = AllInOneTableImages.create!(:uploaded_data => uploaded_file_from(ImageFixtures::valid))
|
190
|
+
assert_equal ImageFixtures::valid[:expected_content_type], model.content_type
|
191
|
+
assert_equal ImageFixtures::valid[:expected_extension], model.file_extension
|
192
|
+
assert_equal ImageFixtures::valid[:expected_extension], AttachmentSaver::split_filename(model.storage_filename).last
|
193
|
+
assert File.read(ImageFixtures::valid[:path]) == File.read(model.storage_filename), "stored data doesn't match!"
|
194
|
+
assert_equal ImageFixtures::valid[:width], model.width
|
195
|
+
assert_equal ImageFixtures::valid[:height], model.height
|
196
|
+
assert_equal "#{ImageFixtures::valid[:width]}x#{ImageFixtures::valid[:height]}", model.image_size
|
197
|
+
|
198
|
+
assert !model.formats.empty?
|
199
|
+
model.formats.each do |size|
|
200
|
+
assert_equal AllInOneTableImages, size.class
|
201
|
+
assert !size.new_record?
|
202
|
+
assert size.formats.empty?
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
data/test/public/.empty
ADDED
File without changes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'image_processor_test_common'))
|
2
|
+
require 'processors/r_magick'
|
3
|
+
|
4
|
+
class RMagickProcessorTest < Test::Unit::TestCase
|
5
|
+
class RMagickTestModel
|
6
|
+
include AttachmentSaver::InstanceMethods
|
7
|
+
include AttachmentSaver::Processors::RMagick
|
8
|
+
include ImageProcessorTestModel
|
9
|
+
end
|
10
|
+
|
11
|
+
def processor_model
|
12
|
+
RMagickTestModel
|
13
|
+
end
|
14
|
+
|
15
|
+
def processor_exception
|
16
|
+
RMagickProcessorError
|
17
|
+
end
|
18
|
+
|
19
|
+
include ImageProcessorTests
|
20
|
+
end
|
data/test/schema.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
def add_generic_attachment_columns(t, want_image_columns)
|
2
|
+
t.string :storage_key, :null => false
|
3
|
+
t.string :content_type, :null => false
|
4
|
+
t.integer :size, :null => false
|
5
|
+
t.datetime :created_at, :null => false
|
6
|
+
t.datetime :updated_at
|
7
|
+
t.integer :width, :null => false if want_image_columns
|
8
|
+
t.integer :height, :null => false if want_image_columns
|
9
|
+
end
|
10
|
+
|
11
|
+
ActiveRecord::Schema.define(:version => 0) do
|
12
|
+
create_table :unprocesseds, :force => true do |t|
|
13
|
+
t.string :original_filename, :null => false
|
14
|
+
add_generic_attachment_columns(t, false)
|
15
|
+
end
|
16
|
+
|
17
|
+
create_table :images, :force => true do |t|
|
18
|
+
t.string :original_filename, :null => false
|
19
|
+
add_generic_attachment_columns(t, true)
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table :derived_images, :force => true do |t|
|
23
|
+
t.string :original_type, :null => false
|
24
|
+
t.integer :original_id, :null => false
|
25
|
+
t.string :format_name, :null => false
|
26
|
+
add_generic_attachment_columns(t, true)
|
27
|
+
end
|
28
|
+
|
29
|
+
create_table :other_images, :force => true do |t| # for testing derived_image owner polymorphism
|
30
|
+
t.string :original_filename, :null => false
|
31
|
+
add_generic_attachment_columns(t, true)
|
32
|
+
end
|
33
|
+
|
34
|
+
create_table :all_in_one_table_images, :force => true do |t|
|
35
|
+
t.string :original_filename # will be null for deriveds
|
36
|
+
t.string :original_type # will be null for originals
|
37
|
+
t.integer :original_id # ditto
|
38
|
+
t.string :format_name # ditto
|
39
|
+
add_generic_attachment_columns(t, true)
|
40
|
+
end
|
41
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
if File.exist?("../../../config/boot.rb")
|
2
|
+
require "../../../config/boot.rb"
|
3
|
+
else
|
4
|
+
require 'rubygems'
|
5
|
+
end
|
6
|
+
|
7
|
+
gem 'activesupport', ENV['RAILS_VERSION']
|
8
|
+
gem 'activerecord', ENV['RAILS_VERSION']
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'active_support'
|
12
|
+
require 'active_support/test_case'
|
13
|
+
require 'active_record'
|
14
|
+
require 'active_record/fixtures'
|
15
|
+
|
16
|
+
begin
|
17
|
+
require 'ruby-debug'
|
18
|
+
Debugger.start
|
19
|
+
rescue LoadError
|
20
|
+
# ruby-debug not installed, no debugging for you
|
21
|
+
end
|
22
|
+
|
23
|
+
RAILS_ROOT = File.dirname(__FILE__)
|
24
|
+
RAILS_ENV = ENV['RAILS_ENV'] ||= 'test'
|
25
|
+
TEST_TEMP_DIR = File.join(File.dirname(__FILE__), 'tmp', 'attachment_saver_test')
|
26
|
+
|
27
|
+
class Rails
|
28
|
+
def self.root; RAILS_ROOT; end
|
29
|
+
def self.env; RAILS_ENV; end
|
30
|
+
end
|
31
|
+
|
32
|
+
class DummyLogger
|
33
|
+
def method_missing(*args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
ActiveRecord::Base.logger = DummyLogger.new
|
38
|
+
|
39
|
+
ActiveRecord::Base.configurations = YAML::load(IO.read(File.join(File.dirname(__FILE__), "database.yml")))
|
40
|
+
ActiveRecord::Base.establish_connection ActiveRecord::Base.configurations[ENV['RAILS_ENV']]
|
41
|
+
load(File.join(File.dirname(__FILE__), "/schema.rb"))
|
42
|
+
|
43
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../init')) # load the plugin
|
44
|
+
|
45
|
+
at_exit do # at_exits are run in reverse of declaration order, and Test::Unit runs from an at_exit, so we must declare ours before that require below
|
46
|
+
FileUtils.rm_rf(File.join(File.dirname(__FILE__), 'tmp'))
|
47
|
+
end
|
48
|
+
|
49
|
+
require 'test/unit'
|
metadata
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: attachment_saver
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Will Bryant
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-04-21 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: activerecord
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rake
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: image_science
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
type: :development
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rmagick
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 3
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
type: :development
|
75
|
+
version_requirements: *id004
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: mini_magick
|
78
|
+
prerelease: false
|
79
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
type: :development
|
89
|
+
version_requirements: *id005
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: sqlite3
|
92
|
+
prerelease: false
|
93
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
hash: 3
|
99
|
+
segments:
|
100
|
+
- 0
|
101
|
+
version: "0"
|
102
|
+
type: :development
|
103
|
+
version_requirements: *id006
|
104
|
+
description: |
|
105
|
+
This plugin implements attachment storage and processing, integrated with
|
106
|
+
ActiveRecord models and Ruby CGI/Rails-style uploads. Image processing
|
107
|
+
operations including a number of different resizing & thumbnailing modes are
|
108
|
+
provided, and the architecture simplifies clean implementation of other types
|
109
|
+
of processing. Errors are carefully handled to minimize the possibility of
|
110
|
+
broken uploads leaving incomplete or corrupt data.
|
111
|
+
|
112
|
+
RMagick, MiniMagick, and ImageScience image processors are supported.
|
113
|
+
|
114
|
+
|
115
|
+
Compatibility
|
116
|
+
=============
|
117
|
+
|
118
|
+
Currently tested against Rails 3.2.13 and 3.1.8, on Ruby 1.8.7 and 2.0.0p0.
|
119
|
+
Was also tested compatible with 2.3.14 and 3.0.17.
|
120
|
+
|
121
|
+
email: will.bryant@gmail.com
|
122
|
+
executables: []
|
123
|
+
|
124
|
+
extensions: []
|
125
|
+
|
126
|
+
extra_rdoc_files: []
|
127
|
+
|
128
|
+
files:
|
129
|
+
- .gitignore
|
130
|
+
- MIT-LICENSE
|
131
|
+
- README
|
132
|
+
- Rakefile
|
133
|
+
- attachment_saver.gemspec
|
134
|
+
- init.rb
|
135
|
+
- lib/attachment_saver.rb
|
136
|
+
- lib/attachment_saver/version.rb
|
137
|
+
- lib/attachment_saver_errors.rb
|
138
|
+
- lib/datastores/file_system.rb
|
139
|
+
- lib/datastores/in_column.rb
|
140
|
+
- lib/misc/extended_tempfile.rb
|
141
|
+
- lib/misc/file_size.rb
|
142
|
+
- lib/misc/image_science_extensions.rb
|
143
|
+
- lib/misc/mini_magick_extensions.rb
|
144
|
+
- lib/processors/image.rb
|
145
|
+
- lib/processors/image_science.rb
|
146
|
+
- lib/processors/mini_magick.rb
|
147
|
+
- lib/processors/r_magick.rb
|
148
|
+
- test/attachment_saver_test.rb
|
149
|
+
- test/database.yml
|
150
|
+
- test/file_system_datastore_test.rb
|
151
|
+
- test/fixtures/broken.jpg
|
152
|
+
- test/fixtures/emptyextension.
|
153
|
+
- test/fixtures/noextension
|
154
|
+
- test/fixtures/test.jpg
|
155
|
+
- test/fixtures/test.js
|
156
|
+
- test/fixtures/wrongextension.png
|
157
|
+
- test/image_fixtures.rb
|
158
|
+
- test/image_operations.rb
|
159
|
+
- test/image_processor_test.rb
|
160
|
+
- test/image_processor_test_common.rb
|
161
|
+
- test/image_science_processor_test.rb
|
162
|
+
- test/in_column_datastore_test.rb
|
163
|
+
- test/mini_magick_processor_test.rb
|
164
|
+
- test/model_test.rb
|
165
|
+
- test/public/.empty
|
166
|
+
- test/rmagick_processor_test.rb
|
167
|
+
- test/schema.rb
|
168
|
+
- test/test_helper.rb
|
169
|
+
homepage: http://github.com/willbryant/attachment_saver
|
170
|
+
licenses: []
|
171
|
+
|
172
|
+
post_install_message:
|
173
|
+
rdoc_options: []
|
174
|
+
|
175
|
+
require_paths:
|
176
|
+
- lib
|
177
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
178
|
+
none: false
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
hash: 3
|
183
|
+
segments:
|
184
|
+
- 0
|
185
|
+
version: "0"
|
186
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
|
+
none: false
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
hash: 3
|
192
|
+
segments:
|
193
|
+
- 0
|
194
|
+
version: "0"
|
195
|
+
requirements: []
|
196
|
+
|
197
|
+
rubyforge_project:
|
198
|
+
rubygems_version: 1.8.15
|
199
|
+
signing_key:
|
200
|
+
specification_version: 3
|
201
|
+
summary: Saves attachments in files, models, or columns.
|
202
|
+
test_files:
|
203
|
+
- test/attachment_saver_test.rb
|
204
|
+
- test/database.yml
|
205
|
+
- test/file_system_datastore_test.rb
|
206
|
+
- test/fixtures/broken.jpg
|
207
|
+
- test/fixtures/emptyextension.
|
208
|
+
- test/fixtures/noextension
|
209
|
+
- test/fixtures/test.jpg
|
210
|
+
- test/fixtures/test.js
|
211
|
+
- test/fixtures/wrongextension.png
|
212
|
+
- test/image_fixtures.rb
|
213
|
+
- test/image_operations.rb
|
214
|
+
- test/image_processor_test.rb
|
215
|
+
- test/image_processor_test_common.rb
|
216
|
+
- test/image_science_processor_test.rb
|
217
|
+
- test/in_column_datastore_test.rb
|
218
|
+
- test/mini_magick_processor_test.rb
|
219
|
+
- test/model_test.rb
|
220
|
+
- test/public/.empty
|
221
|
+
- test/rmagick_processor_test.rb
|
222
|
+
- test/schema.rb
|
223
|
+
- test/test_helper.rb
|