jnicklas-carrierwave 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,21 +17,20 @@ module CarrierWave
17
17
  # Possible values are the 'canned access control policies' provided in the aws/s3 gem,
18
18
  # they are:
19
19
  #
20
- # :private No one else has any access rights.
21
- # :public_read The anonymous principal is granted READ access.
22
- # If this policy is used on an object, it can be read from a
23
- # browser with no authentication.
24
- # :public_read_write The anonymous principal is granted READ and WRITE access.
25
- # :authenticated_read Any principal authenticated as a registered Amazon S3 user
26
- # is granted READ access.
20
+ # [:private] No one else has any access rights.
21
+ # [:public_read] The anonymous principal is granted READ access.
22
+ # If this policy is used on an object, it can be read from a
23
+ # browser with no authentication.
24
+ # [:public_read_write] The anonymous principal is granted READ and WRITE access.
25
+ # [:authenticated_read] Any principal authenticated as a registered Amazon S3 user
26
+ # is granted READ access.
27
27
  #
28
28
  # The default is :public_read, it should work in most cases.
29
29
  #
30
30
  class S3 < Abstract
31
31
 
32
- def initialize(bucket, store_dir, identifier)
33
- @bucket = bucket
34
- @store_dir = store_dir
32
+ def initialize(store_path, identifier)
33
+ @store_path = store_path
35
34
  @identifier = identifier
36
35
  end
37
36
 
@@ -47,14 +46,18 @@ module CarrierWave
47
46
  end
48
47
 
49
48
  ##
50
- # @return [String] the bucket set in the config options
49
+ # === Returns
50
+ #
51
+ # [String] the bucket set in the config options
51
52
  #
52
53
  def self.bucket
53
54
  CarrierWave.config[:s3][:bucket]
54
55
  end
55
56
 
56
57
  ##
57
- # @return [Symbol] the access priviliges the uploaded files should have
58
+ # === Returns
59
+ #
60
+ # [Symbol] the access priviliges the uploaded files should have
58
61
  #
59
62
  def self.access
60
63
  CarrierWave.config[:s3][:access]
@@ -63,14 +66,18 @@ module CarrierWave
63
66
  ##
64
67
  # Store the file on S3
65
68
  #
66
- # @param [CarrierWave::Uploader] uploader an uploader object
67
- # @param [CarrierWave::SanitizedFile] file the file to store
69
+ # === Parameters
70
+ #
71
+ # [uploader (CarrierWave::Uploader)] an uploader object
72
+ # [file (CarrierWave::SanitizedFile)] the file to store
68
73
  #
69
- # @return [#identifier] an object
74
+ # === Returns
75
+ #
76
+ # [CarrierWave::Storage::S3] the stored file
70
77
  #
71
78
  def self.store!(uploader, file)
72
- AWS::S3::S3Object.store(::File.join(uploader.store_dir, uploader.filename), file.read, bucket, :access => access)
73
- self.new(bucket, uploader.store_dir, uploader.filename)
79
+ AWS::S3::S3Object.store(::File.join(uploader.store_path), file.read, bucket, :access => access)
80
+ self.new(uploader.store_dir, uploader.filename)
74
81
  end
75
82
 
76
83
  # Do something to retrieve the file
@@ -78,28 +85,48 @@ module CarrierWave
78
85
  # @param [CarrierWave::Uploader] uploader an uploader object
79
86
  # @param [String] identifier uniquely identifies the file
80
87
  #
81
- # @return [#identifier] an object
88
+ # [uploader (CarrierWave::Uploader)] an uploader object
89
+ # [identifier (String)] uniquely identifies the file
90
+ #
91
+ # === Returns
92
+ #
93
+ # [CarrierWave::Storage::S3] the stored file
82
94
  #
83
95
  def self.retrieve!(uploader, identifier)
84
- self.new(bucket, uploader.store_dir, identifier)
96
+ self.new(uploader.store_path(identifier), identifier)
85
97
  end
86
98
 
87
99
  ##
88
100
  # Returns the filename on S3
89
101
  #
90
- # @return [String] path to the file
102
+ # === Returns
103
+ #
104
+ # [String] path to the file
91
105
  #
92
106
  def identifier
93
107
  @identifier
94
108
  end
95
109
 
110
+ ##
111
+ # Reads the contents of the file from S3
112
+ #
113
+ # === Returns
114
+ #
115
+ # [String] contents of the file
116
+ #
117
+ def read
118
+ S3Object.value @store_path, self.class.bucket
119
+ end
120
+
96
121
  ##
97
122
  # Returns the url on Amazon's S3 service
98
123
  #
99
- # @return [String] file's url
124
+ # === Returns
125
+ #
126
+ # [String] file's url
100
127
  #
101
128
  def url
102
- ["http://s3.amazonaws.com", self.class.bucket, @store_dir, @identifier].compact.join('/')
129
+ ["http://s3.amazonaws.com", self.class.bucket, @store_path].compact.join('/')
103
130
  end
104
131
 
105
132
  end # S3
@@ -0,0 +1,112 @@
1
+ module CarrierWave
2
+ module Test
3
+
4
+ ##
5
+ # These are some matchers that can be used in RSpec specs, to simplify the testing
6
+ # of uploaders.
7
+ #
8
+ module Matchers
9
+
10
+ class BeIdenticalTo
11
+ def initialize(expected)
12
+ @expected = expected
13
+ end
14
+ def matches?(actual)
15
+ @actual = actual
16
+ FileUtils.identical?(@actual, @expected)
17
+ end
18
+ def failure_message
19
+ "expected #{@actual.inspect} to be identical to #{@expected.inspect}"
20
+ end
21
+ def negative_failure_message
22
+ "expected #{@actual.inspect} to not be identical to #{@expected.inspect}"
23
+ end
24
+ end
25
+
26
+ def be_identical_to(expected)
27
+ BeIdenticalTo.new(expected)
28
+ end
29
+
30
+ class HavePermissions
31
+ def initialize(expected)
32
+ @expected = expected
33
+ end
34
+
35
+ def matches?(actual)
36
+ @actual = actual
37
+ # Satisfy expectation here. Return false or raise an error if it's not met.
38
+ (File.stat(@actual.path).mode & 0777) == @expected
39
+ end
40
+
41
+ def failure_message
42
+ "expected #{@actual.inspect} to have permissions #{@expected.to_s(8)}, but they were #{(File.stat(@actual.path).mode & 0777).to_s(8)}"
43
+ end
44
+
45
+ def negative_failure_message
46
+ "expected #{@actual.inspect} not to have permissions #{@expected.to_s(8)}, but it did"
47
+ end
48
+ end
49
+
50
+ def have_permissions(expected)
51
+ HavePermissions.new(expected)
52
+ end
53
+
54
+ class BeNoLargerThan
55
+ def initialize(width, height)
56
+ @width, @height = width, height
57
+ end
58
+
59
+ def matches?(actual)
60
+ @actual = actual
61
+ # Satisfy expectation here. Return false or raise an error if it's not met.
62
+ require 'RMagick'
63
+ img = ::Magick::Image.read(@actual.path).first
64
+ @actual_width = img.columns
65
+ @actual_height = img.rows
66
+ @actual_width <= @width && @actual_height <= @height
67
+ end
68
+
69
+ def failure_message
70
+ "expected #{@actual.inspect} to be no larger than #{@width} by #{@height}, but it was #{@actual_height} by #{@actual_width}."
71
+ end
72
+
73
+ def negative_failure_message
74
+ "expected #{@actual.inspect} to be larger than #{@width} by #{@height}, but it wasn't."
75
+ end
76
+ end
77
+
78
+ def be_no_larger_than(width, height)
79
+ BeNoLargerThan.new(width, height)
80
+ end
81
+
82
+ class HaveDimensions
83
+ def initialize(width, height)
84
+ @width, @height = width, height
85
+ end
86
+
87
+ def matches?(actual)
88
+ @actual = actual
89
+ # Satisfy expectation here. Return false or raise an error if it's not met.
90
+ require 'RMagick'
91
+ img = ::Magick::Image.read(@actual.path).first
92
+ @actual_width = img.columns
93
+ @actual_height = img.rows
94
+ @actual_width == @width && @actual_height == @height
95
+ end
96
+
97
+ def failure_message
98
+ "expected #{@actual.inspect} to have an exact size of #{@width} by #{@height}, but it was #{@actual_height} by #{@actual_width}."
99
+ end
100
+
101
+ def negative_failure_message
102
+ "expected #{@actual.inspect} not to have an exact size of #{@width} by #{@height}, but it did."
103
+ end
104
+ end
105
+
106
+ def have_dimensions(width, height)
107
+ HaveDimensions.new(width, height)
108
+ end
109
+
110
+ end # SpecHelper
111
+ end # Test
112
+ end # CarrierWave