winton-attachment_fu 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
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,39 +0,0 @@
1
- module Technoweenie # :nodoc:
2
- module AttachmentFu # :nodoc:
3
- module Backends
4
- # Methods for DB backed attachments
5
- module DbFileBackend
6
- def self.included(base) #:nodoc:
7
- Object.const_set(:DbFile, Class.new(ActiveRecord::Base)) unless Object.const_defined?(:DbFile)
8
- base.belongs_to :db_file, :class_name => '::DbFile', :foreign_key => 'db_file_id'
9
- end
10
-
11
- # Creates a temp file with the current db data.
12
- def create_temp_file
13
- write_to_temp_file current_data
14
- end
15
-
16
- # Gets the current data from the database
17
- def current_data
18
- db_file.data
19
- end
20
-
21
- protected
22
- # Destroys the file. Called in the after_destroy callback
23
- def destroy_file
24
- db_file.destroy if db_file
25
- end
26
-
27
- # Saves the data to the DbFile model
28
- def save_to_storage
29
- if save_attachment?
30
- (db_file || build_db_file).data = temp_data
31
- db_file.save!
32
- self.class.update_all ['db_file_id = ?', self.db_file_id = db_file.id], ['id = ?', id]
33
- end
34
- true
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,101 +0,0 @@
1
- require 'ftools'
2
- module Technoweenie # :nodoc:
3
- module AttachmentFu # :nodoc:
4
- module Backends
5
- # Methods for file system backed attachments
6
- module FileSystemBackend
7
- def self.included(base) #:nodoc:
8
- base.before_update :rename_file
9
- end
10
-
11
- # Gets the full path to the filename in this format:
12
- #
13
- # # This assumes a model name like MyModel
14
- # # public/#{table_name} is the default filesystem path
15
- # RAILS_ROOT/public/my_models/5/blah.jpg
16
- #
17
- # Overwrite this method in your model to customize the filename.
18
- # The optional thumbnail argument will output the thumbnail's filename.
19
- def full_filename(thumbnail = nil)
20
- file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix].to_s
21
- File.join(RAILS_ROOT, file_system_path, *partitioned_path(thumbnail_name_for(thumbnail)))
22
- end
23
-
24
- # Used as the base path that #public_filename strips off full_filename to create the public path
25
- def base_path
26
- @base_path ||= File.join(RAILS_ROOT, 'public')
27
- end
28
-
29
- # The attachment ID used in the full path of a file
30
- def attachment_path_id
31
- ((respond_to?(:parent_id) && parent_id) || id).to_i
32
- end
33
-
34
- # by default paritions files into directories e.g. 0000/0001/image.jpg
35
- # to turn this off set :partition => false
36
- def partitioned_path(*args)
37
- if respond_to?(:attachment_options) && attachment_options[:partition] == false
38
- args
39
- else
40
- ("%08d" % attachment_path_id).scan(/..../) + args
41
- end
42
- end
43
-
44
- # Gets the public path to the file
45
- # The optional thumbnail argument will output the thumbnail's filename.
46
- def public_filename(thumbnail = nil)
47
- full_filename(thumbnail).gsub %r(^#{Regexp.escape(base_path)}), ''
48
- end
49
-
50
- def filename=(value)
51
- @old_filename = full_filename unless filename.nil? || @old_filename
52
- write_attribute :filename, sanitize_filename(value)
53
- end
54
-
55
- # Creates a temp file from the currently saved file.
56
- def create_temp_file
57
- copy_to_temp_file full_filename
58
- end
59
-
60
- protected
61
- # Destroys the file. Called in the after_destroy callback
62
- def destroy_file
63
- FileUtils.rm full_filename
64
- # remove directory also if it is now empty
65
- Dir.rmdir(File.dirname(full_filename)) if (Dir.entries(File.dirname(full_filename))-['.','..']).empty?
66
- rescue
67
- logger.info "Exception destroying #{full_filename.inspect}: [#{$!.class.name}] #{$1.to_s}"
68
- logger.warn $!.backtrace.collect { |b| " > #{b}" }.join("\n")
69
- end
70
-
71
- # Renames the given file before saving
72
- def rename_file
73
- return unless @old_filename && @old_filename != full_filename
74
- if save_attachment? && File.exists?(@old_filename)
75
- FileUtils.rm @old_filename
76
- elsif File.exists?(@old_filename)
77
- FileUtils.mv @old_filename, full_filename
78
- end
79
- @old_filename = nil
80
- true
81
- end
82
-
83
- # Saves the file to the file system
84
- def save_to_storage
85
- if save_attachment?
86
- # TODO: This overwrites the file if it exists, maybe have an allow_overwrite option?
87
- FileUtils.mkdir_p(File.dirname(full_filename))
88
- File.cp(temp_path, full_filename)
89
- File.chmod(attachment_options[:chmod] || 0644, full_filename)
90
- end
91
- @old_filename = nil
92
- true
93
- end
94
-
95
- def current_data
96
- File.file?(full_filename) ? File.read(full_filename) : nil
97
- end
98
- end
99
- end
100
- end
101
- end
@@ -1,303 +0,0 @@
1
- module Technoweenie # :nodoc:
2
- module AttachmentFu # :nodoc:
3
- module Backends
4
- # = AWS::S3 Storage Backend
5
- #
6
- # Enables use of {Amazon's Simple Storage Service}[http://aws.amazon.com/s3] as a storage mechanism
7
- #
8
- # == Requirements
9
- #
10
- # Requires the {AWS::S3 Library}[http://amazon.rubyforge.org] for S3 by Marcel Molina Jr. installed either
11
- # as a gem or a as a Rails plugin.
12
- #
13
- # == Configuration
14
- #
15
- # Configuration is done via <tt>RAILS_ROOT/config/amazon_s3.yml</tt> and is loaded according to the <tt>RAILS_ENV</tt>.
16
- # The minimum connection options that you must specify are a bucket name, your access key id and your secret access key.
17
- # If you don't already have your access keys, all you need to sign up for the S3 service is an account at Amazon.
18
- # You can sign up for S3 and get access keys by visiting http://aws.amazon.com/s3.
19
- #
20
- # Example configuration (RAILS_ROOT/config/amazon_s3.yml)
21
- #
22
- # development:
23
- # bucket_name: appname_development
24
- # access_key_id: <your key>
25
- # secret_access_key: <your key>
26
- #
27
- # test:
28
- # bucket_name: appname_test
29
- # access_key_id: <your key>
30
- # secret_access_key: <your key>
31
- #
32
- # production:
33
- # bucket_name: appname
34
- # access_key_id: <your key>
35
- # secret_access_key: <your key>
36
- #
37
- # You can change the location of the config path by passing a full path to the :s3_config_path option.
38
- #
39
- # has_attachment :storage => :s3, :s3_config_path => (RAILS_ROOT + '/config/s3.yml')
40
- #
41
- # === Required configuration parameters
42
- #
43
- # * <tt>:access_key_id</tt> - The access key id for your S3 account. Provided by Amazon.
44
- # * <tt>:secret_access_key</tt> - The secret access key for your S3 account. Provided by Amazon.
45
- # * <tt>:bucket_name</tt> - A unique bucket name (think of the bucket_name as being like a database name).
46
- #
47
- # If any of these required arguments is missing, a MissingAccessKey exception will be raised from AWS::S3.
48
- #
49
- # == About bucket names
50
- #
51
- # Bucket names have to be globaly unique across the S3 system. And you can only have up to 100 of them,
52
- # so it's a good idea to think of a bucket as being like a database, hence the correspondance in this
53
- # implementation to the development, test, and production environments.
54
- #
55
- # The number of objects you can store in a bucket is, for all intents and purposes, unlimited.
56
- #
57
- # === Optional configuration parameters
58
- #
59
- # * <tt>:server</tt> - The server to make requests to. Defaults to <tt>s3.amazonaws.com</tt>.
60
- # * <tt>:port</tt> - The port to the requests should be made on. Defaults to 80 or 443 if <tt>:use_ssl</tt> is set.
61
- # * <tt>:use_ssl</tt> - If set to true, <tt>:port</tt> will be implicitly set to 443, unless specified otherwise. Defaults to false.
62
- #
63
- # == Usage
64
- #
65
- # To specify S3 as the storage mechanism for a model, set the acts_as_attachment <tt>:storage</tt> option to <tt>:s3</tt>.
66
- #
67
- # class Photo < ActiveRecord::Base
68
- # has_attachment :storage => :s3
69
- # end
70
- #
71
- # === Customizing the path
72
- #
73
- # By default, files are prefixed using a pseudo hierarchy in the form of <tt>:table_name/:id</tt>, which results
74
- # in S3 urls that look like: http(s)://:server/:bucket_name/:table_name/:id/:filename with :table_name
75
- # representing the customizable portion of the path. You can customize this prefix using the <tt>:path_prefix</tt>
76
- # option:
77
- #
78
- # class Photo < ActiveRecord::Base
79
- # has_attachment :storage => :s3, :path_prefix => 'my/custom/path'
80
- # end
81
- #
82
- # Which would result in URLs like <tt>http(s)://:server/:bucket_name/my/custom/path/:id/:filename.</tt>
83
- #
84
- # === Permissions
85
- #
86
- # By default, files are stored on S3 with public access permissions. You can customize this using
87
- # the <tt>:s3_access</tt> option to <tt>has_attachment</tt>. Available values are
88
- # <tt>:private</tt>, <tt>:public_read_write</tt>, and <tt>:authenticated_read</tt>.
89
- #
90
- # === Other options
91
- #
92
- # Of course, all the usual configuration options apply, such as content_type and thumbnails:
93
- #
94
- # class Photo < ActiveRecord::Base
95
- # has_attachment :storage => :s3, :content_type => ['application/pdf', :image], :resize_to => 'x50'
96
- # has_attachment :storage => :s3, :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }
97
- # end
98
- #
99
- # === Accessing S3 URLs
100
- #
101
- # You can get an object's URL using the s3_url accessor. For example, assuming that for your postcard app
102
- # you had a bucket name like 'postcard_world_development', and an attachment model called Photo:
103
- #
104
- # @postcard.s3_url # => http(s)://s3.amazonaws.com/postcard_world_development/photos/1/mexico.jpg
105
- #
106
- # The resulting url is in the form: http(s)://:server/:bucket_name/:table_name/:id/:file.
107
- # The optional thumbnail argument will output the thumbnail's filename (if any).
108
- #
109
- # Additionally, you can get an object's base path relative to the bucket root using
110
- # <tt>base_path</tt>:
111
- #
112
- # @photo.file_base_path # => photos/1
113
- #
114
- # And the full path (including the filename) using <tt>full_filename</tt>:
115
- #
116
- # @photo.full_filename # => photos/
117
- #
118
- # Niether <tt>base_path</tt> or <tt>full_filename</tt> include the bucket name as part of the path.
119
- # You can retrieve the bucket name using the <tt>bucket_name</tt> method.
120
- module S3Backend
121
- class RequiredLibraryNotFoundError < StandardError; end
122
- class ConfigFileNotFoundError < StandardError; end
123
-
124
- def self.included(base) #:nodoc:
125
- mattr_reader :bucket_name, :s3_config
126
-
127
- begin
128
- require 'aws/s3'
129
- include AWS::S3
130
- rescue LoadError
131
- raise RequiredLibraryNotFoundError.new('AWS::S3 could not be loaded')
132
- end
133
-
134
- begin
135
- @@s3_config_path = base.attachment_options[:s3_config_path] || (RAILS_ROOT + '/config/amazon_s3.yml')
136
- @@s3_config = @@s3_config = YAML.load(ERB.new(File.read(@@s3_config_path)).result)[RAILS_ENV].symbolize_keys
137
- #rescue
138
- # raise ConfigFileNotFoundError.new('File %s not found' % @@s3_config_path)
139
- end
140
-
141
- @@bucket_name = s3_config[:bucket_name]
142
-
143
- Base.establish_connection!(s3_config.slice(:access_key_id, :secret_access_key, :server, :port, :use_ssl, :persistent, :proxy))
144
-
145
- # Bucket.create(@@bucket_name)
146
-
147
- base.before_update :rename_file
148
- end
149
-
150
- def self.protocol
151
- @protocol ||= s3_config[:use_ssl] ? 'https://' : 'http://'
152
- end
153
-
154
- def self.hostname
155
- @hostname ||= s3_config[:server] || AWS::S3::DEFAULT_HOST
156
- end
157
-
158
- def self.port_string
159
- @port_string ||= (s3_config[:port].nil? || s3_config[:port] == (s3_config[:use_ssl] ? 443 : 80)) ? '' : ":#{s3_config[:port]}"
160
- end
161
-
162
- module ClassMethods
163
- def s3_protocol
164
- Technoweenie::AttachmentFu::Backends::S3Backend.protocol
165
- end
166
-
167
- def s3_hostname
168
- Technoweenie::AttachmentFu::Backends::S3Backend.hostname
169
- end
170
-
171
- def s3_port_string
172
- Technoweenie::AttachmentFu::Backends::S3Backend.port_string
173
- end
174
- end
175
-
176
- # Overwrites the base filename writer in order to store the old filename
177
- def filename=(value)
178
- @old_filename = filename unless filename.nil? || @old_filename
179
- write_attribute :filename, sanitize_filename(value)
180
- end
181
-
182
- # The attachment ID used in the full path of a file
183
- def attachment_path_id
184
- ((respond_to?(:parent_id) && parent_id) || id).to_s
185
- end
186
-
187
- # The pseudo hierarchy containing the file relative to the bucket name
188
- # Example: <tt>:table_name/:id</tt>
189
- def base_path
190
- File.join(attachment_options[:path_prefix], attachment_path_id)
191
- end
192
-
193
- # The full path to the file relative to the bucket name
194
- # Example: <tt>:table_name/:id/:filename</tt>
195
- def full_filename(thumbnail = nil)
196
- File.join(base_path, thumbnail_name_for(thumbnail))
197
- end
198
-
199
- # All public objects are accessible via a GET request to the S3 servers. You can generate a
200
- # url for an object using the s3_url method.
201
- #
202
- # @photo.s3_url
203
- #
204
- # The resulting url is in the form: <tt>http(s)://:server/:bucket_name/:table_name/:id/:file</tt> where
205
- # the <tt>:server</tt> variable defaults to <tt>AWS::S3 URL::DEFAULT_HOST</tt> (s3.amazonaws.com) and can be
206
- # set using the configuration parameters in <tt>RAILS_ROOT/config/amazon_s3.yml</tt>.
207
- #
208
- # The optional thumbnail argument will output the thumbnail's filename (if any).
209
- def s3_url(thumbnail = nil)
210
- File.join(s3_protocol + s3_hostname + s3_port_string, bucket_name, full_filename(thumbnail))
211
- end
212
- alias :public_filename :s3_url
213
-
214
- # All private objects are accessible via an authenticated GET request to the S3 servers. You can generate an
215
- # authenticated url for an object like this:
216
- #
217
- # @photo.authenticated_s3_url
218
- #
219
- # By default authenticated urls expire 5 minutes after they were generated.
220
- #
221
- # Expiration options can be specified either with an absolute time using the <tt>:expires</tt> option,
222
- # or with a number of seconds relative to now with the <tt>:expires_in</tt> option:
223
- #
224
- # # Absolute expiration date (October 13th, 2025)
225
- # @photo.authenticated_s3_url(:expires => Time.mktime(2025,10,13).to_i)
226
- #
227
- # # Expiration in five hours from now
228
- # @photo.authenticated_s3_url(:expires_in => 5.hours)
229
- #
230
- # You can specify whether the url should go over SSL with the <tt>:use_ssl</tt> option.
231
- # By default, the ssl settings for the current connection will be used:
232
- #
233
- # @photo.authenticated_s3_url(:use_ssl => true)
234
- #
235
- # Finally, the optional thumbnail argument will output the thumbnail's filename (if any):
236
- #
237
- # @photo.authenticated_s3_url('thumbnail', :expires_in => 5.hours, :use_ssl => true)
238
- def authenticated_s3_url(*args)
239
- options = args.extract_options!
240
- thumbnail = args.shift
241
- S3Object.url_for(full_filename(thumbnail), bucket_name, options)
242
- end
243
-
244
- def create_temp_file
245
- write_to_temp_file current_data
246
- end
247
-
248
- def current_data
249
- S3Object.value full_filename, bucket_name
250
- end
251
-
252
- def s3_protocol
253
- Technoweenie::AttachmentFu::Backends::S3Backend.protocol
254
- end
255
-
256
- def s3_hostname
257
- Technoweenie::AttachmentFu::Backends::S3Backend.hostname
258
- end
259
-
260
- def s3_port_string
261
- Technoweenie::AttachmentFu::Backends::S3Backend.port_string
262
- end
263
-
264
- protected
265
- # Called in the after_destroy callback
266
- def destroy_file
267
- S3Object.delete full_filename, bucket_name
268
- end
269
-
270
- def rename_file
271
- return unless @old_filename && @old_filename != filename
272
-
273
- old_full_filename = File.join(base_path, @old_filename)
274
-
275
- S3Object.rename(
276
- old_full_filename,
277
- full_filename,
278
- bucket_name,
279
- :access => attachment_options[:s3_access]
280
- )
281
-
282
- @old_filename = nil
283
- true
284
- end
285
-
286
- def save_to_storage
287
- if save_attachment?
288
- S3Object.store(
289
- full_filename,
290
- (temp_path ? File.open(temp_path) : temp_data),
291
- bucket_name,
292
- :content_type => content_type,
293
- :access => attachment_options[:s3_access]
294
- )
295
- end
296
-
297
- @old_filename = nil
298
- true
299
- end
300
- end
301
- end
302
- end
303
- end
@@ -1,59 +0,0 @@
1
- require 'red_artisan/core_image/processor'
2
-
3
- module Technoweenie # :nodoc:
4
- module AttachmentFu # :nodoc:
5
- module Processors
6
- module CoreImageProcessor
7
- def self.included(base)
8
- base.send :extend, ClassMethods
9
- base.alias_method_chain :process_attachment, :processing
10
- end
11
-
12
- module ClassMethods
13
- def with_image(file, &block)
14
- block.call OSX::CIImage.from(file)
15
- end
16
- end
17
-
18
- protected
19
- def process_attachment_with_processing
20
- return unless process_attachment_without_processing
21
- with_image do |img|
22
- self.width = img.extent.size.width if respond_to?(:width)
23
- self.height = img.extent.size.height if respond_to?(:height)
24
- resize_image_or_thumbnail! img
25
- callback_with_args :after_resize, img
26
- end if image?
27
- end
28
-
29
- # Performs the actual resizing operation for a thumbnail
30
- def resize_image(img, size)
31
- processor = ::RedArtisan::CoreImage::Processor.new(img)
32
- size = size.first if size.is_a?(Array) && size.length == 1
33
- if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
34
- if size.is_a?(Fixnum)
35
- processor.fit(size)
36
- else
37
- processor.resize(size[0], size[1])
38
- end
39
- else
40
- new_size = [img.extent.size.width, img.extent.size.height] / size.to_s
41
- processor.resize(new_size[0], new_size[1])
42
- end
43
-
44
- processor.render do |result|
45
- self.width = result.extent.size.width if respond_to?(:width)
46
- self.height = result.extent.size.height if respond_to?(:height)
47
-
48
- # Get a new temp_path for the image before saving
49
- self.temp_path = Tempfile.new(random_tempfile_filename, Technoweenie::AttachmentFu.tempfile_path).path
50
- result.save self.temp_path, OSX::NSJPEGFileType
51
- self.size = File.size(self.temp_path)
52
- end
53
- end
54
- end
55
- end
56
- end
57
- end
58
-
59
-