winton-attachment_fu 1.0.5 → 1.0.6

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.
Files changed (44) hide show
  1. metadata +16 -14
  2. data/CHANGELOG +0 -35
  3. data/README +0 -186
  4. data/Rakefile +0 -22
  5. data/amazon_s3.yml.tpl +0 -14
  6. data/init.rb +0 -17
  7. data/install.rb +0 -5
  8. data/lib/geometry.rb +0 -93
  9. data/lib/technoweenie/attachment_fu.rb +0 -473
  10. data/lib/technoweenie/attachment_fu/backends/db_file_backend.rb +0 -39
  11. data/lib/technoweenie/attachment_fu/backends/file_system_backend.rb +0 -101
  12. data/lib/technoweenie/attachment_fu/backends/s3_backend.rb +0 -303
  13. data/lib/technoweenie/attachment_fu/processors/core_image_processor.rb +0 -59
  14. data/lib/technoweenie/attachment_fu/processors/gd2_processor.rb +0 -54
  15. data/lib/technoweenie/attachment_fu/processors/image_science_processor.rb +0 -61
  16. data/lib/technoweenie/attachment_fu/processors/mini_magick_processor.rb +0 -59
  17. data/lib/technoweenie/attachment_fu/processors/rmagick_processor.rb +0 -54
  18. data/test/backends/db_file_test.rb +0 -16
  19. data/test/backends/file_system_test.rb +0 -80
  20. data/test/backends/remote/s3_test.rb +0 -119
  21. data/test/base_attachment_tests.rb +0 -77
  22. data/test/basic_test.rb +0 -70
  23. data/test/database.yml +0 -18
  24. data/test/extra_attachment_test.rb +0 -67
  25. data/test/fixtures/attachment.rb +0 -148
  26. data/test/fixtures/files/fake/rails.png +0 -0
  27. data/test/fixtures/files/foo.txt +0 -1
  28. data/test/fixtures/files/rails.png +0 -0
  29. data/test/geometry_test.rb +0 -101
  30. data/test/processors/core_image_test.rb +0 -37
  31. data/test/processors/gd2_test.rb +0 -31
  32. data/test/processors/image_science_test.rb +0 -31
  33. data/test/processors/mini_magick_test.rb +0 -31
  34. data/test/processors/rmagick_test.rb +0 -255
  35. data/test/schema.rb +0 -108
  36. data/test/test_helper.rb +0 -150
  37. data/test/validation_test.rb +0 -55
  38. data/vendor/red_artisan/core_image/filters/color.rb +0 -27
  39. data/vendor/red_artisan/core_image/filters/effects.rb +0 -31
  40. data/vendor/red_artisan/core_image/filters/perspective.rb +0 -25
  41. data/vendor/red_artisan/core_image/filters/quality.rb +0 -25
  42. data/vendor/red_artisan/core_image/filters/scale.rb +0 -47
  43. data/vendor/red_artisan/core_image/filters/watermark.rb +0 -32
  44. data/vendor/red_artisan/core_image/processor.rb +0 -123
@@ -1,150 +0,0 @@
1
- $:.unshift(File.dirname(__FILE__) + '/../lib')
2
-
3
- ENV['RAILS_ENV'] = 'test'
4
- ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'
5
-
6
- require 'test/unit'
7
- require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))
8
- require 'active_record/fixtures'
9
- require 'action_controller/test_process'
10
-
11
- config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
12
- ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
13
-
14
- db_adapter = ENV['DB']
15
-
16
- # no db passed, try one of these fine config-free DBs before bombing.
17
- db_adapter ||=
18
- begin
19
- require 'rubygems'
20
- require 'sqlite'
21
- 'sqlite'
22
- rescue MissingSourceFile
23
- begin
24
- require 'sqlite3'
25
- 'sqlite3'
26
- rescue MissingSourceFile
27
- end
28
- end
29
-
30
- if db_adapter.nil?
31
- raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3."
32
- end
33
-
34
- ActiveRecord::Base.establish_connection(config[db_adapter])
35
-
36
- load(File.dirname(__FILE__) + "/schema.rb")
37
-
38
- Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures"
39
- $LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
40
-
41
- class Test::Unit::TestCase #:nodoc:
42
- include ActionController::TestProcess
43
- def create_fixtures(*table_names)
44
- if block_given?
45
- Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) { yield }
46
- else
47
- Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
48
- end
49
- end
50
-
51
- def setup
52
- Attachment.saves = 0
53
- DbFile.transaction { [Attachment, FileAttachment, OrphanAttachment, MinimalAttachment, DbFile].each { |klass| klass.delete_all } }
54
- attachment_model self.class.attachment_model
55
- end
56
-
57
- def teardown
58
- FileUtils.rm_rf File.join(File.dirname(__FILE__), 'files')
59
- end
60
-
61
- self.use_transactional_fixtures = true
62
- self.use_instantiated_fixtures = false
63
-
64
- def self.attachment_model(klass = nil)
65
- @attachment_model = klass if klass
66
- @attachment_model
67
- end
68
-
69
- def self.test_against_class(test_method, klass, subclass = false)
70
- define_method("#{test_method}_on_#{:sub if subclass}class") do
71
- klass = Class.new(klass) if subclass
72
- attachment_model klass
73
- send test_method, klass
74
- end
75
- end
76
-
77
- def self.test_against_subclass(test_method, klass)
78
- test_against_class test_method, klass, true
79
- end
80
-
81
- protected
82
- def upload_file(options = {})
83
- use_temp_file options[:filename] do |file|
84
- att = attachment_model.create :uploaded_data => fixture_file_upload(file, options[:content_type] || 'image/png')
85
- att.reload unless att.new_record?
86
- return att
87
- end
88
- end
89
-
90
- def upload_merb_file(options = {})
91
- use_temp_file options[:filename] do |file|
92
- att = attachment_model.create :uploaded_data => {"size" => file.size, "content_type" => options[:content_type] || 'image/png', "filename" => file, 'tempfile' => fixture_file_upload(file, options[:content_type] || 'image/png')}
93
- att.reload unless att.new_record?
94
- return att
95
- end
96
- end
97
-
98
- def use_temp_file(fixture_filename)
99
- temp_path = File.join('/tmp', File.basename(fixture_filename))
100
- FileUtils.mkdir_p File.join(fixture_path, 'tmp')
101
- FileUtils.cp File.join(fixture_path, fixture_filename), File.join(fixture_path, temp_path)
102
- yield temp_path
103
- ensure
104
- FileUtils.rm_rf File.join(fixture_path, 'tmp')
105
- end
106
-
107
- def assert_created(num = 1)
108
- assert_difference attachment_model.base_class, :count, num do
109
- if attachment_model.included_modules.include? DbFile
110
- assert_difference DbFile, :count, num do
111
- yield
112
- end
113
- else
114
- yield
115
- end
116
- end
117
- end
118
-
119
- def assert_not_created
120
- assert_created(0) { yield }
121
- end
122
-
123
- def should_reject_by_size_with(klass)
124
- attachment_model klass
125
- assert_not_created do
126
- attachment = upload_file :filename => '/files/rails.png'
127
- assert attachment.new_record?
128
- assert attachment.errors.on(:size)
129
- assert_nil attachment.db_file if attachment.respond_to?(:db_file)
130
- end
131
- end
132
-
133
- def assert_difference(object, method = nil, difference = 1)
134
- initial_value = object.send(method)
135
- yield
136
- assert_equal initial_value + difference, object.send(method)
137
- end
138
-
139
- def assert_no_difference(object, method, &block)
140
- assert_difference object, method, 0, &block
141
- end
142
-
143
- def attachment_model(klass = nil)
144
- @attachment_model = klass if klass
145
- @attachment_model
146
- end
147
- end
148
-
149
- require File.join(File.dirname(__FILE__), 'fixtures/attachment')
150
- require File.join(File.dirname(__FILE__), 'base_attachment_tests')
@@ -1,55 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
2
-
3
- class ValidationTest < Test::Unit::TestCase
4
- def test_should_invalidate_big_files
5
- @attachment = SmallAttachment.new
6
- assert !@attachment.valid?
7
- assert @attachment.errors.on(:size)
8
-
9
- @attachment.size = 2000
10
- assert !@attachment.valid?
11
- assert @attachment.errors.on(:size), @attachment.errors.full_messages.to_sentence
12
-
13
- @attachment.size = 1000
14
- assert !@attachment.valid?
15
- assert_nil @attachment.errors.on(:size)
16
- end
17
-
18
- def test_should_invalidate_small_files
19
- @attachment = BigAttachment.new
20
- assert !@attachment.valid?
21
- assert @attachment.errors.on(:size)
22
-
23
- @attachment.size = 2000
24
- assert !@attachment.valid?
25
- assert @attachment.errors.on(:size), @attachment.errors.full_messages.to_sentence
26
-
27
- @attachment.size = 1.megabyte
28
- assert !@attachment.valid?
29
- assert_nil @attachment.errors.on(:size)
30
- end
31
-
32
- def test_should_validate_content_type
33
- @attachment = PdfAttachment.new
34
- assert !@attachment.valid?
35
- assert @attachment.errors.on(:content_type)
36
-
37
- @attachment.content_type = 'foo'
38
- assert !@attachment.valid?
39
- assert @attachment.errors.on(:content_type)
40
-
41
- @attachment.content_type = 'pdf'
42
- assert !@attachment.valid?
43
- assert_nil @attachment.errors.on(:content_type)
44
- end
45
-
46
- def test_should_require_filename
47
- @attachment = Attachment.new
48
- assert !@attachment.valid?
49
- assert @attachment.errors.on(:filename)
50
-
51
- @attachment.filename = 'foo'
52
- assert !@attachment.valid?
53
- assert_nil @attachment.errors.on(:filename)
54
- end
55
- end
@@ -1,27 +0,0 @@
1
- module RedArtisan
2
- module CoreImage
3
- module Filters
4
- module Color
5
-
6
- def greyscale(color = nil, intensity = 1.00)
7
- create_core_image_context(@original.extent.size.width, @original.extent.size.height)
8
-
9
- color = OSX::CIColor.colorWithString("1.0 1.0 1.0 1.0") unless color
10
-
11
- @original.color_monochrome :inputColor => color, :inputIntensity => intensity do |greyscale|
12
- @target = greyscale
13
- end
14
- end
15
-
16
- def sepia(intensity = 1.00)
17
- create_core_image_context(@original.extent.size.width, @original.extent.size.height)
18
-
19
- @original.sepia_tone :inputIntensity => intensity do |sepia|
20
- @target = sepia
21
- end
22
- end
23
-
24
- end
25
- end
26
- end
27
- end
@@ -1,31 +0,0 @@
1
- module RedArtisan
2
- module CoreImage
3
- module Filters
4
- module Effects
5
-
6
- def spotlight(position, points_at, brightness, concentration, color)
7
- create_core_image_context(@original.extent.size.width, @original.extent.size.height)
8
-
9
- @original.spot_light :inputLightPosition => vector3(*position), :inputLightPointsAt => vector3(*points_at),
10
- :inputBrightness => brightness, :inputConcentration => concentration, :inputColor => color do |spot|
11
- @target = spot
12
- end
13
- end
14
-
15
- def edges(intensity = 1.00)
16
- create_core_image_context(@original.extent.size.width, @original.extent.size.height)
17
-
18
- @original.edges :inputIntensity => intensity do |edged|
19
- @target = edged
20
- end
21
- end
22
-
23
- private
24
-
25
- def vector3(x, y, w)
26
- OSX::CIVector.vectorWithX_Y_Z(x, y, w)
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,25 +0,0 @@
1
- module RedArtisan
2
- module CoreImage
3
- module Filters
4
- module Perspective
5
-
6
- def perspective(top_left, top_right, bottom_left, bottom_right)
7
- create_core_image_context(@original.extent.size.width, @original.extent.size.height)
8
-
9
- @original.perspective_transform :inputTopLeft => top_left, :inputTopRight => top_right, :inputBottomLeft => bottom_left, :inputBottomRight => bottom_right do |transformed|
10
- @target = transformed
11
- end
12
- end
13
-
14
- def perspective_tiled(top_left, top_right, bottom_left, bottom_right)
15
- create_core_image_context(@original.extent.size.width, @original.extent.size.height)
16
-
17
- @original.perspective_tile :inputTopLeft => top_left, :inputTopRight => top_right, :inputBottomLeft => bottom_left, :inputBottomRight => bottom_right do |tiled|
18
- @target = tiled
19
- end
20
- end
21
-
22
- end
23
- end
24
- end
25
- end
@@ -1,25 +0,0 @@
1
- module RedArtisan
2
- module CoreImage
3
- module Filters
4
- module Quality
5
-
6
- def reduce_noise(level = 0.02, sharpness = 0.4)
7
- create_core_image_context(@original.extent.size.width, @original.extent.size.height)
8
-
9
- @original.noise_reduction :inputNoiseLevel => level, :inputSharpness => sharpness do |noise_reduced|
10
- @target = noise_reduced
11
- end
12
- end
13
-
14
- def adjust_exposure(input_ev = 0.5)
15
- create_core_image_context(@original.extent.size.width, @original.extent.size.height)
16
-
17
- @original.exposure_adjust :inputEV => input_ev do |adjusted|
18
- @target = adjusted
19
- end
20
- end
21
-
22
- end
23
- end
24
- end
25
- end
@@ -1,47 +0,0 @@
1
- module RedArtisan
2
- module CoreImage
3
- module Filters
4
- module Scale
5
-
6
- def resize(width, height)
7
- create_core_image_context(width, height)
8
-
9
- scale_x, scale_y = scale(width, height)
10
-
11
- @original.affine_clamp :inputTransform => OSX::NSAffineTransform.transform do |clamped|
12
- clamped.lanczos_scale_transform :inputScale => scale_x > scale_y ? scale_x : scale_y, :inputAspectRatio => scale_x / scale_y do |scaled|
13
- scaled.crop :inputRectangle => vector(0, 0, width, height) do |cropped|
14
- @target = cropped
15
- end
16
- end
17
- end
18
- end
19
-
20
- def thumbnail(width, height)
21
- create_core_image_context(width, height)
22
-
23
- transform = OSX::NSAffineTransform.transform
24
- transform.scaleXBy_yBy *scale(width, height)
25
-
26
- @original.affine_transform :inputTransform => transform do |scaled|
27
- @target = scaled
28
- end
29
- end
30
-
31
- def fit(size)
32
- original_size = @original.extent.size
33
- scale = size.to_f / (original_size.width > original_size.height ? original_size.width : original_size.height)
34
- resize (original_size.width * scale).to_i, (original_size.height * scale).to_i
35
- end
36
-
37
- private
38
-
39
- def scale(width, height)
40
- original_size = @original.extent.size
41
- return width.to_f / original_size.width.to_f, height.to_f / original_size.height.to_f
42
- end
43
-
44
- end
45
- end
46
- end
47
- end
@@ -1,32 +0,0 @@
1
- module RedArtisan
2
- module CoreImage
3
- module Filters
4
- module Watermark
5
-
6
- def watermark(watermark_image, tile = false, strength = 0.1)
7
- create_core_image_context(@original.extent.size.width, @original.extent.size.height)
8
-
9
- if watermark_image.respond_to? :to_str
10
- watermark_image = OSX::CIImage.from(watermark_image.to_str)
11
- end
12
-
13
- if tile
14
- tile_transform = OSX::NSAffineTransform.transform
15
- tile_transform.scaleXBy_yBy 1.0, 1.0
16
-
17
- watermark_image.affine_tile :inputTransform => tile_transform do |tiled|
18
- tiled.crop :inputRectangle => vector(0, 0, @original.extent.size.width, @original.extent.size.height) do |tiled_watermark|
19
- watermark_image = tiled_watermark
20
- end
21
- end
22
- end
23
-
24
- @original.dissolve_transition :inputTargetImage => watermark_image, :inputTime => strength do |watermarked|
25
- @target = watermarked
26
- end
27
- end
28
-
29
- end
30
- end
31
- end
32
- end
@@ -1,123 +0,0 @@
1
- require 'rubygems'
2
- require 'osx/cocoa'
3
- require 'active_support'
4
-
5
- require 'red_artisan/core_image/filters/scale'
6
- require 'red_artisan/core_image/filters/color'
7
- require 'red_artisan/core_image/filters/watermark'
8
- require 'red_artisan/core_image/filters/quality'
9
- require 'red_artisan/core_image/filters/perspective'
10
- require 'red_artisan/core_image/filters/effects'
11
-
12
- # Generic image processor for scaling images based on CoreImage via RubyCocoa.
13
- #
14
- # Example usage:
15
- #
16
- # p = Processor.new OSX::CIImage.from(path_to_image)
17
- # p.resize(640, 480)
18
- # p.render do |result|
19
- # result.save('resized.jpg', OSX::NSJPEGFileType)
20
- # end
21
- #
22
- # This will resize the image to the given dimensions exactly, if you'd like to ensure that aspect ratio is preserved:
23
- #
24
- # p = Processor.new OSX::CIImage.from(path_to_image)
25
- # p.fit(640)
26
- # p.render do |result|
27
- # result.save('resized.jpg', OSX::NSJPEGFileType)
28
- # end
29
- #
30
- # fit(size) will attempt its best to resize the image so that the longest width/height (depending on image orientation) will match
31
- # the given size. The second axis will be calculated automatically based on the aspect ratio.
32
- #
33
- # Scaling is performed by first clamping the image so that its external bounds become infinite, this helps when scaling so that any
34
- # rounding discrepencies in dimensions don't affect the resultant image. We then perform a Lanczos transform on the image which scales
35
- # it to the target size. We then crop the image to the traget dimensions.
36
- #
37
- # If you are generating smaller images such as thumbnails where high quality rendering isn't as important, an additional method is
38
- # available:
39
- #
40
- # p = Processor.new OSX::CIImage.from(path_to_image)
41
- # p.thumbnail(100, 100)
42
- # p.render do |result|
43
- # result.save('resized.jpg', OSX::NSJPEGFileType)
44
- # end
45
- #
46
- # This will perform a straight affine transform and scale the X and Y boundaries to the requested size. Generally, this will be faster
47
- # than a lanczos scale transform, but with a scaling quality trade.
48
- #
49
- # More than welcome to intregrate any patches, improvements - feel free to mail me with ideas.
50
- #
51
- # Thanks to
52
- # * Satoshi Nakagawa for working out that OCObjWrapper needs inclusion when aliasing method_missing on existing OSX::* classes.
53
- # * Vasantha Crabb for general help and inspiration with Cocoa
54
- # * Ben Schwarz for example image data and collaboration during performance testing
55
- #
56
- # Copyright (c) Marcus Crafter <crafterm@redartisan.com> released under the MIT license
57
- #
58
- module RedArtisan
59
- module CoreImage
60
- class Processor
61
-
62
- def initialize(original)
63
- if original.respond_to? :to_str
64
- @original = OSX::CIImage.from(original.to_str)
65
- else
66
- @original = original
67
- end
68
- end
69
-
70
- def render(&block)
71
- raise "unprocessed image: #{@original}" unless @target
72
- block.call @target
73
- end
74
-
75
- include Filters::Scale, Filters::Color, Filters::Watermark, Filters::Quality, Filters::Perspective, Filters::Effects
76
-
77
- private
78
-
79
- def create_core_image_context(width, height)
80
- output = OSX::NSBitmapImageRep.alloc.initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bytesPerRow_bitsPerPixel(nil, width, height, 8, 4, true, false, OSX::NSDeviceRGBColorSpace, 0, 0)
81
- context = OSX::NSGraphicsContext.graphicsContextWithBitmapImageRep(output)
82
- OSX::NSGraphicsContext.setCurrentContext(context)
83
- @ci_context = context.CIContext
84
- end
85
-
86
- def vector(x, y, w, h)
87
- OSX::CIVector.vectorWithX_Y_Z_W(x, y, w, h)
88
- end
89
- end
90
- end
91
- end
92
-
93
- module OSX
94
- class CIImage
95
- include OCObjWrapper
96
-
97
- def method_missing_with_filter_processing(sym, *args, &block)
98
- f = OSX::CIFilter.filterWithName("CI#{sym.to_s.camelize}")
99
- return method_missing_without_filter_processing(sym, *args, &block) unless f
100
-
101
- f.setDefaults if f.respond_to? :setDefaults
102
- f.setValue_forKey(self, 'inputImage')
103
- options = args.last.is_a?(Hash) ? args.last : {}
104
- options.each { |k, v| f.setValue_forKey(v, k.to_s) }
105
-
106
- block.call f.valueForKey('outputImage')
107
- end
108
-
109
- alias_method_chain :method_missing, :filter_processing
110
-
111
- def save(target, format = OSX::NSJPEGFileType, properties = nil)
112
- bitmapRep = OSX::NSBitmapImageRep.alloc.initWithCIImage(self)
113
- blob = bitmapRep.representationUsingType_properties(format, properties)
114
- blob.writeToFile_atomically(target, false)
115
- end
116
-
117
- def self.from(filepath)
118
- raise Errno::ENOENT, "No such file or directory - #{filepath}" unless File.exists?(filepath)
119
- OSX::CIImage.imageWithContentsOfURL(OSX::NSURL.fileURLWithPath(filepath))
120
- end
121
- end
122
- end
123
-