cloudfuji_paperclip 2.4.6 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +9 -6
  3. data/Appraisals +6 -6
  4. data/CONTRIBUTING.md +34 -2
  5. data/Gemfile +2 -0
  6. data/NEWS +90 -0
  7. data/README.md +62 -29
  8. data/RUNNING_TESTS.md +4 -0
  9. data/Rakefile +7 -2
  10. data/UPGRADING +14 -0
  11. data/features/basic_integration.feature +11 -7
  12. data/features/rake_tasks.feature +1 -1
  13. data/features/step_definitions/attachment_steps.rb +11 -2
  14. data/features/step_definitions/rails_steps.rb +17 -79
  15. data/features/support/env.rb +3 -0
  16. data/features/support/fakeweb.rb +7 -0
  17. data/features/support/file_helpers.rb +24 -0
  18. data/features/support/rails.rb +3 -3
  19. data/gemfiles/{rails3_1.gemfile → 3.0.gemfile} +3 -1
  20. data/gemfiles/{rails2.gemfile → 3.1.gemfile} +3 -1
  21. data/gemfiles/{rails3.gemfile → 3.2.gemfile} +3 -1
  22. data/images.rake +21 -0
  23. data/lib/cloudfuji_paperclip.rb +1 -0
  24. data/lib/generators/paperclip/paperclip_generator.rb +1 -2
  25. data/lib/paperclip.rb +54 -319
  26. data/lib/paperclip/attachment.rb +86 -107
  27. data/lib/paperclip/attachment_options.rb +9 -0
  28. data/lib/paperclip/callbacks.rb +30 -0
  29. data/lib/paperclip/errors.rb +27 -0
  30. data/lib/paperclip/geometry.rb +6 -4
  31. data/lib/paperclip/glue.rb +23 -0
  32. data/lib/paperclip/helpers.rb +71 -0
  33. data/lib/paperclip/instance_methods.rb +35 -0
  34. data/lib/paperclip/interpolations.rb +4 -4
  35. data/lib/paperclip/io_adapters/attachment_adapter.rb +69 -0
  36. data/lib/paperclip/io_adapters/file_adapter.rb +81 -0
  37. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -0
  38. data/lib/paperclip/io_adapters/nil_adapter.rb +34 -0
  39. data/lib/paperclip/io_adapters/registry.rb +32 -0
  40. data/lib/paperclip/io_adapters/stringio_adapter.rb +64 -0
  41. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +63 -0
  42. data/lib/paperclip/locales/en.yml +17 -0
  43. data/lib/paperclip/logger.rb +21 -0
  44. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +5 -5
  45. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +7 -7
  46. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +11 -11
  47. data/lib/paperclip/missing_attachment_styles.rb +6 -9
  48. data/lib/paperclip/processor.rb +32 -17
  49. data/lib/paperclip/railtie.rb +13 -17
  50. data/lib/paperclip/storage/filesystem.rb +4 -13
  51. data/lib/paperclip/storage/fog.rb +33 -24
  52. data/lib/paperclip/storage/s3.rb +36 -28
  53. data/lib/paperclip/tempfile.rb +41 -0
  54. data/lib/paperclip/thumbnail.rb +2 -3
  55. data/lib/paperclip/validators.rb +45 -0
  56. data/lib/paperclip/validators/attachment_content_type_validator.rb +54 -0
  57. data/lib/paperclip/validators/attachment_presence_validator.rb +26 -0
  58. data/lib/paperclip/validators/attachment_size_validator.rb +102 -0
  59. data/lib/paperclip/version.rb +1 -1
  60. data/lib/tasks/paperclip.rake +4 -12
  61. data/paperclip.gemspec +15 -5
  62. data/test/adapter_registry_test.rb +32 -0
  63. data/test/attachment_adapter_test.rb +51 -0
  64. data/test/attachment_options_test.rb +27 -0
  65. data/test/attachment_test.rb +130 -46
  66. data/test/file_adapter_test.rb +88 -0
  67. data/test/generator_test.rb +78 -0
  68. data/test/geometry_test.rb +5 -5
  69. data/test/helper.rb +21 -22
  70. data/test/identity_adapter_test.rb +8 -0
  71. data/test/integration_test.rb +55 -102
  72. data/test/interpolations_test.rb +15 -5
  73. data/test/matchers/validate_attachment_content_type_matcher_test.rb +23 -0
  74. data/test/matchers/validate_attachment_presence_matcher_test.rb +21 -0
  75. data/test/matchers/validate_attachment_size_matcher_test.rb +37 -2
  76. data/test/nil_adapter_test.rb +25 -0
  77. data/test/paperclip_missing_attachment_styles_test.rb +16 -0
  78. data/test/paperclip_test.rb +34 -183
  79. data/test/storage/filesystem_test.rb +27 -27
  80. data/test/storage/fog_test.rb +68 -12
  81. data/test/storage/s3_live_test.rb +79 -38
  82. data/test/storage/s3_test.rb +204 -34
  83. data/test/stringio_adapter_test.rb +42 -0
  84. data/test/thumbnail_test.rb +29 -8
  85. data/test/uploaded_file_adapter_test.rb +98 -0
  86. data/test/url_generator_test.rb +8 -8
  87. data/test/validators/attachment_content_type_validator_test.rb +192 -0
  88. data/test/validators/attachment_presence_validator_test.rb +85 -0
  89. data/test/validators/attachment_size_validator_test.rb +207 -0
  90. data/test/validators_test.rb +25 -0
  91. metadata +166 -59
  92. data/generators/paperclip/USAGE +0 -5
  93. data/generators/paperclip/paperclip_generator.rb +0 -27
  94. data/generators/paperclip/templates/paperclip_migration.rb.erb +0 -19
  95. data/init.rb +0 -4
  96. data/lib/paperclip/callback_compatibility.rb +0 -61
  97. data/lib/paperclip/iostream.rb +0 -45
  98. data/lib/paperclip/upfile.rb +0 -62
  99. data/rails/init.rb +0 -2
  100. data/test/.gitignore +0 -1
  101. data/test/fixtures/question?mark.png +0 -0
  102. data/test/iostream_test.rb +0 -71
  103. data/test/upfile_test.rb +0 -53
@@ -0,0 +1,35 @@
1
+ module Paperclip
2
+ module InstanceMethods #:nodoc:
3
+ def attachment_for name
4
+ @_paperclip_attachments ||= {}
5
+ @_paperclip_attachments[name] ||= Attachment.new(name, self, self.class.attachment_definitions[name])
6
+ end
7
+
8
+ def each_attachment
9
+ self.class.attachment_definitions.each do |name, definition|
10
+ yield(name, attachment_for(name))
11
+ end
12
+ end
13
+
14
+ def save_attached_files
15
+ Paperclip.log("Saving attachments.")
16
+ each_attachment do |name, attachment|
17
+ attachment.send(:save)
18
+ end
19
+ end
20
+
21
+ def destroy_attached_files
22
+ Paperclip.log("Deleting attachments.")
23
+ each_attachment do |name, attachment|
24
+ attachment.send(:flush_deletes)
25
+ end
26
+ end
27
+
28
+ def prepare_for_destroy
29
+ Paperclip.log("Scheduling attachments for deletion.")
30
+ each_attachment do |name, attachment|
31
+ attachment.send(:queue_all_for_delete)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -46,7 +46,7 @@ module Paperclip
46
46
  # is used in the default :path to ease default specifications.
47
47
  RIGHT_HERE = "#{__FILE__.gsub(%r{^\./}, "")}:#{__LINE__ + 3}"
48
48
  def url attachment, style_name
49
- raise InfiniteInterpolationError if caller.any?{|b| b.index(RIGHT_HERE) }
49
+ raise Errors::InfiniteInterpolationError if caller.any?{|b| b.index(RIGHT_HERE) }
50
50
  attachment.url(style_name, :timestamp => false, :escape => false)
51
51
  end
52
52
 
@@ -93,7 +93,7 @@ module Paperclip
93
93
  # If the style has a format defined, it will return the format instead
94
94
  # of the actual extension.
95
95
  def extension attachment, style_name
96
- ((style = attachment.styles[style_name]) && style[:format]) ||
96
+ ((style = attachment.styles[style_name.to_s.to_sym]) && style[:format]) ||
97
97
  File.extname(attachment.original_filename).gsub(/^\.+/, "")
98
98
  end
99
99
 
@@ -137,11 +137,11 @@ module Paperclip
137
137
  attachment.fingerprint
138
138
  end
139
139
 
140
- # Returns a the attachment hash. See Paperclip::Attachment#hash for
140
+ # Returns a the attachment hash. See Paperclip::Attachment#hash_key for
141
141
  # more details.
142
142
  def hash attachment=nil, style_name=nil
143
143
  if attachment && style_name
144
- attachment.hash(style_name)
144
+ attachment.hash_key(style_name)
145
145
  else
146
146
  super()
147
147
  end
@@ -0,0 +1,69 @@
1
+ module Paperclip
2
+ class AttachmentAdapter
3
+ def initialize(target)
4
+ @target = target
5
+ cache_current_values
6
+ end
7
+
8
+ def original_filename
9
+ @original_filename
10
+ end
11
+
12
+ def content_type
13
+ @content_type
14
+ end
15
+
16
+ def size
17
+ @size
18
+ end
19
+
20
+ def nil?
21
+ false
22
+ end
23
+
24
+ def fingerprint
25
+ @fingerprint ||= Digest::MD5.file(path).to_s
26
+ end
27
+
28
+ def read(length = nil, buffer = nil)
29
+ @tempfile.read(length, buffer)
30
+ end
31
+
32
+ # We don't use this directly, but aws/sdk does.
33
+ def rewind
34
+ @tempfile.rewind
35
+ end
36
+
37
+ def eof?
38
+ @tempfile.eof?
39
+ end
40
+
41
+ def path
42
+ @tempfile.path
43
+ end
44
+
45
+ private
46
+
47
+ def cache_current_values
48
+ @tempfile = copy_to_tempfile(@target)
49
+ @original_filename = @target.original_filename
50
+ @content_type = @target.content_type
51
+ @size = @tempfile.size || @target.size
52
+ end
53
+
54
+ def copy_to_tempfile(src)
55
+ dest = Tempfile.new(src.original_filename)
56
+ dest.binmode
57
+ if src.respond_to? :copy_to_local_file
58
+ src.copy_to_local_file(:original, dest.path)
59
+ else
60
+ FileUtils.cp(src.path(:original), dest.path)
61
+ end
62
+ dest
63
+ end
64
+ end
65
+ end
66
+
67
+ Paperclip.io_adapters.register Paperclip::AttachmentAdapter do |target|
68
+ Paperclip::Attachment === target
69
+ end
@@ -0,0 +1,81 @@
1
+ module Paperclip
2
+ class FileAdapter
3
+ def initialize(target)
4
+ @target = target
5
+ @tempfile = copy_to_tempfile(@target)
6
+ end
7
+
8
+ def original_filename
9
+ if @target.respond_to?(:original_filename)
10
+ @target.original_filename
11
+ else
12
+ File.basename(@target.path)
13
+ end
14
+ end
15
+
16
+ def content_type
17
+ types = MIME::Types.type_for(original_filename)
18
+ if types.length == 0
19
+ type_from_file_command
20
+ elsif types.length == 1
21
+ types.first.content_type
22
+ else
23
+ best_content_type_option(types)
24
+ end
25
+ end
26
+
27
+ def fingerprint
28
+ @fingerprint ||= Digest::MD5.file(path).to_s
29
+ end
30
+
31
+ def size
32
+ File.size(@tempfile)
33
+ end
34
+
35
+ def nil?
36
+ @target.nil?
37
+ end
38
+
39
+ def read(length = nil, buffer = nil)
40
+ @tempfile.read(length, buffer)
41
+ end
42
+
43
+ # We don't use this directly, but aws/sdk does.
44
+ def rewind
45
+ @tempfile.rewind
46
+ end
47
+
48
+ def eof?
49
+ @tempfile.eof?
50
+ end
51
+
52
+ def path
53
+ @tempfile.path
54
+ end
55
+
56
+ private
57
+
58
+ def copy_to_tempfile(src)
59
+ dest = Tempfile.new(original_filename)
60
+ dest.binmode
61
+ FileUtils.cp(src.path, dest.path)
62
+ dest
63
+ end
64
+
65
+ def best_content_type_option(types)
66
+ types.reject {|type| type.content_type.match(/\/x-/) }.first.content_type
67
+ end
68
+
69
+ def type_from_file_command
70
+ # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
71
+ type = (self.original_filename.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase
72
+ mime_type = (Paperclip.run("file", "-b --mime :file", :file => self.path).split(/[:;\s]+/)[0] rescue "application/x-#{type}")
73
+ mime_type = "application/x-#{type}" if mime_type.match(/\(.*?\)/)
74
+ mime_type
75
+ end
76
+ end
77
+ end
78
+
79
+ Paperclip.io_adapters.register Paperclip::FileAdapter do |target|
80
+ File === target || Tempfile === target
81
+ end
@@ -0,0 +1,12 @@
1
+ module Paperclip
2
+ class IdentityAdapter
3
+ def new(adapter)
4
+ adapter
5
+ end
6
+ end
7
+ end
8
+
9
+ Paperclip.io_adapters.register Paperclip::IdentityAdapter.new do |target|
10
+ Paperclip.io_adapters.registered?(target)
11
+ end
12
+
@@ -0,0 +1,34 @@
1
+ module Paperclip
2
+ class NilAdapter
3
+ def initialize(target)
4
+ end
5
+
6
+ def original_filename
7
+ ""
8
+ end
9
+
10
+ def content_type
11
+ ""
12
+ end
13
+
14
+ def size
15
+ 0
16
+ end
17
+
18
+ def nil?
19
+ true
20
+ end
21
+
22
+ def read(*args)
23
+ nil
24
+ end
25
+
26
+ def eof?
27
+ true
28
+ end
29
+ end
30
+ end
31
+
32
+ Paperclip.io_adapters.register Paperclip::NilAdapter do |target|
33
+ target.nil?
34
+ end
@@ -0,0 +1,32 @@
1
+ module Paperclip
2
+ class AdapterRegistry
3
+ class NoHandlerError < Paperclip::Error; end
4
+
5
+ attr_reader :registered_handlers
6
+
7
+ def initialize
8
+ @registered_handlers = []
9
+ end
10
+
11
+ def register(handler_class, &block)
12
+ @registered_handlers << [block, handler_class]
13
+ end
14
+
15
+ def handler_for(target)
16
+ @registered_handlers.each do |tester, handler|
17
+ return handler if tester.call(target)
18
+ end
19
+ raise NoHandlerError.new("No handler found for #{target.inspect}")
20
+ end
21
+
22
+ def registered?(target)
23
+ @registered_handlers.any? do |tester, handler|
24
+ handler === target
25
+ end
26
+ end
27
+
28
+ def for(target)
29
+ handler_for(target).new(target)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,64 @@
1
+ module Paperclip
2
+ class StringioAdapter
3
+ def initialize(target)
4
+ @target = target
5
+ @tempfile = copy_to_tempfile(@target)
6
+ end
7
+
8
+ attr_writer :original_filename, :content_type
9
+
10
+ def original_filename
11
+ @original_filename ||= @target.original_filename if @target.respond_to?(:original_filename)
12
+ @original_filename ||= "stringio.txt"
13
+ @original_filename.strip
14
+ end
15
+
16
+ def content_type
17
+ @content_type ||= @target.content_type if @target.respond_to?(:content_type)
18
+ @content_type ||= "text/plain"
19
+ @content_type
20
+ end
21
+
22
+ def size
23
+ @target.size
24
+ end
25
+
26
+ def fingerprint
27
+ Digest::MD5.hexdigest(read)
28
+ end
29
+
30
+ def read(length = nil, buffer = nil)
31
+ @tempfile.read(length, buffer)
32
+ end
33
+
34
+ # We don't use this directly, but aws/sdk does.
35
+ def rewind
36
+ @tempfile.rewind
37
+ end
38
+
39
+ def eof?
40
+ @tempfile.eof?
41
+ end
42
+
43
+ def path
44
+ @tempfile.path
45
+ end
46
+
47
+ private
48
+
49
+ def copy_to_tempfile(src)
50
+ dest = Tempfile.new(original_filename)
51
+ dest.binmode
52
+ while data = src.read(16*1024)
53
+ dest.write(data)
54
+ end
55
+ dest.rewind
56
+ dest
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ Paperclip.io_adapters.register Paperclip::StringioAdapter do |target|
63
+ StringIO === target
64
+ end
@@ -0,0 +1,63 @@
1
+ module Paperclip
2
+ class UploadedFileAdapter
3
+ def initialize(target)
4
+ @target = target
5
+
6
+ if @target.respond_to?(:tempfile)
7
+ @tempfile = copy_to_tempfile(@target.tempfile)
8
+ else
9
+ @tempfile = copy_to_tempfile(@target)
10
+ end
11
+ end
12
+
13
+ def original_filename
14
+ @target.original_filename
15
+ end
16
+
17
+ def content_type
18
+ @target.content_type
19
+ end
20
+
21
+ def fingerprint
22
+ @fingerprint ||= Digest::MD5.file(path).to_s
23
+ end
24
+
25
+ def size
26
+ File.size(path)
27
+ end
28
+
29
+ def nil?
30
+ false
31
+ end
32
+
33
+ def read(length = nil, buffer = nil)
34
+ @tempfile.read(length, buffer)
35
+ end
36
+
37
+ # We don't use this directly, but aws/sdk does.
38
+ def rewind
39
+ @tempfile.rewind
40
+ end
41
+
42
+ def eof?
43
+ @tempfile.eof?
44
+ end
45
+
46
+ def path
47
+ @tempfile.path
48
+ end
49
+
50
+ private
51
+
52
+ def copy_to_tempfile(src)
53
+ dest = Tempfile.new(original_filename)
54
+ dest.binmode
55
+ FileUtils.cp(src.path, dest.path)
56
+ dest
57
+ end
58
+ end
59
+ end
60
+
61
+ Paperclip.io_adapters.register Paperclip::UploadedFileAdapter do |target|
62
+ target.class.name.include?("UploadedFile")
63
+ end
@@ -0,0 +1,17 @@
1
+ en:
2
+ errors:
3
+ messages:
4
+ in_between: "must be in between %{min} and %{max}"
5
+
6
+ number:
7
+ human:
8
+ storage_units:
9
+ format: "%n %u"
10
+ units:
11
+ byte:
12
+ one: "Byte"
13
+ other: "Bytes"
14
+ kb: "KB"
15
+ mb: "MB"
16
+ gb: "GB"
17
+ tb: "TB"