paperclip-storage-aliyun 0.0.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 770e2aba77af7013237abcb823fec49c244d15d3
4
- data.tar.gz: 199af51f6159ab6b0138eab907b7dd7286b2fd2a
2
+ SHA256:
3
+ metadata.gz: ff16e09b8b10e23dd324564800cc616a8a18f10f8b565232cc07828f188e4187
4
+ data.tar.gz: b19db842235f98300bebe578bc0ba04fe5d3901382aea376b14b5ecf49e7eae3
5
5
  SHA512:
6
- metadata.gz: 418741aa19eeb9400e7cae5eb9448c671a99688632cb19a9e7c6c8c43a269297c608c2ef53dc84881ff437833ecdaa826db8f7ece5c0052ac453aa61a9703422
7
- data.tar.gz: 27af1cb2c3f924a9f1d736206a57c648d82a3b10b03c3e1ed373dcc8c9d48050f19344c1d7bd22aafe8a021919284c71dbb8fb53170d35142d8a0fddaec3059f
6
+ metadata.gz: b25f22a60b2c143cb8defa97c95046f7b03520298ba9a9467bd9252ff7629025aa7e3201cf4be8c38b093ea5e3730dc1d35d49eaa93e003953c82ff5b40f6e3f
7
+ data.tar.gz: dc7a329077c64cde95e3ffa7389f18bb386e1cd3d058434301e5e1e9db5ea6b122470b593f10bfc97f885b97e319fa7e83f07387cf752e56ea5ef4932f5baa25
@@ -1,46 +1,54 @@
1
- # encoding: utf-8
2
-
3
1
  require 'openssl'
4
2
  require 'digest/md5'
5
- require "rest-client"
6
- require "base64"
3
+ require 'rest-client'
4
+ require 'base64'
7
5
  require 'uri'
8
6
  require 'aliyun/data_center'
9
7
 
10
8
  module Aliyun
11
9
  class Connection
12
10
  include DataCenter
11
+
12
+ # The upload host according to the connection configurations
13
+ attr_reader :aliyun_upload_host
14
+ # The internal host
15
+ attr_reader :aliyun_internal_host
16
+ # The external host
17
+ attr_reader :aliyun_external_host
18
+ # The alias host
19
+ attr_reader :aliyun_alias_host
20
+
21
+ attr_reader :aliyun_protocol
22
+
23
+ attr_reader :aliyun_protocol_relative_url
24
+
13
25
  # Initialize the OSS connection
14
26
  #
15
27
  # @param [Hash] An options to specify connection details
16
28
  # @option access_id [String] used to set "Authorization" request header
17
29
  # @option access_key [String] the access key
18
30
  # @option bucket [String] bucket used to access
19
- # @option data_center [String] available data center name, e.g. 'hangzhou'
31
+ # @option data_center [String] available data center name, e.g. 'cn-hangzhou'
20
32
  # @option internal [true, false] if the service should be accessed through internal network
21
- # @option host [String] force the host to a given value, only use it when this gem can not work expectly
33
+ # @option host_alias [String] the alias of the host, such as the CDN domain name
34
+ # @option protocol [String] 'http' or 'https', default to 'http'
35
+ # @option protocol_relative_url [true, false] if to use protocol relative url, https://en.wikipedia.org/wiki/Wikipedia:Protocol-relative_URL
22
36
  # @note both access_id and acces_key are related to authorization algorithm:
23
37
  # https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
24
38
  def initialize(options = {})
25
39
  @aliyun_access_id = options[:access_id]
26
40
  @aliyun_access_key = options[:access_key]
27
41
  @aliyun_bucket = options[:bucket]
42
+ @aliyun_protocol_relative_url = !!options[:protocol_relative_url]
43
+ @aliyun_protocol = options[:protocol] || 'http'
28
44
 
29
- @endpoint = get_endpoint(options)
30
-
31
- @aliyun_upload_host = "#{@aliyun_bucket}.#{@endpoint}"
32
-
33
- @aliyun_host = options[:host] || @aliyun_upload_host
34
- end
35
-
36
- # the file host according to the connection configurations
37
- #
38
- # @return [String] the host value
39
- def fetch_file_host
40
- @aliyun_host
45
+ @aliyun_upload_host = "#{@aliyun_bucket}.#{get_endpoint(options)}"
46
+ @aliyun_internal_host = "#{@aliyun_bucket}.#{get_endpoint(options.merge(internal: true))}"
47
+ @aliyun_external_host = "#{@aliyun_bucket}.#{get_endpoint(options.merge(internal: false))}"
48
+ @aliyun_alias_host = options[:host_alias] || @aliyun_upload_host
41
49
  end
42
50
 
43
- # Return the meta informations for the a file specified by the path
51
+ # Return the meta informations for a file specified by the path
44
52
  # https://docs.aliyun.com/#/pub/oss/api-reference/object&HeadObject
45
53
  #
46
54
  # @param path [String] the path of file storaged in Aliyun OSS
@@ -60,39 +68,48 @@ module Aliyun
60
68
  # :x_oss_request_id=>"55BD83A5D4C05BDFF4A329E0"}}
61
69
  #
62
70
  def head(path)
71
+ path = format_path(path)
72
+ bucket_path = get_bucket_path(path)
73
+ date = gmtdate
74
+ headers = {
75
+ 'Host' => @aliyun_upload_host,
76
+ 'Date' => date,
77
+ 'Authorization' => sign('HEAD', bucket_path, '', '', date)
78
+ }
63
79
  url = path_to_url(path)
64
- RestClient.head(url).headers
80
+ RestClient.head(url, headers).headers
65
81
  rescue RestClient::ResourceNotFound
66
82
  {}
67
83
  end
68
84
 
69
85
  # Upload File to Aliyun OSS
70
86
  # https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject
71
- #
87
+ #
72
88
  # @param path [String] the target storing path on the oss
73
89
  # @param file [File] an instance of File represents a file to be uploaded
74
90
  # @param options [Hash]
75
91
  # - content_type - MimeType value for the file, default is "image/jpg"
76
- #
92
+ #
77
93
  # @return [String] The downloadable url of the uploaded file
78
94
  # @return [nil] if the uploading failed
79
- def put(path, file, options={})
95
+ def put(path, file, options = {})
80
96
  path = format_path(path)
81
97
  bucket_path = get_bucket_path(path)
82
- content_md5 = Digest::MD5.file(file)
83
- content_type = options[:content_type] || "image/jpg"
98
+ content_md5 = Digest::MD5.file(file).base64digest
99
+ content_type = options[:content_type] || 'image/jpg'
84
100
  date = gmtdate
85
101
  url = path_to_url(path)
86
- auth_sign = sign("PUT", bucket_path, content_md5, content_type, date)
102
+ auth_sign = sign('PUT', bucket_path, content_md5, content_type, date)
87
103
  headers = {
88
- "Authorization" => auth_sign,
89
- "Content-Type" => content_type,
90
- "Content-Length" => file.size,
91
- "Date" => date,
92
- "Host" => @aliyun_upload_host,
93
- "Expect" => "100-Continue"
104
+ 'Authorization' => auth_sign,
105
+ 'Content-Md5' => content_md5,
106
+ 'Content-Type' => content_type,
107
+ 'Content-Length' => file.size,
108
+ 'Date' => date,
109
+ 'Host' => @aliyun_upload_host,
110
+ 'Expect' => '100-Continue'
94
111
  }
95
- response = RestClient.put(URI.encode(url), file, headers)
112
+ response = RestClient.put(url, file, headers)
96
113
  response.code == 200 ? path_to_url(path) : nil
97
114
  end
98
115
 
@@ -107,12 +124,12 @@ module Aliyun
107
124
  bucket_path = get_bucket_path(path)
108
125
  date = gmtdate
109
126
  headers = {
110
- "Host" => @aliyun_upload_host,
111
- "Date" => date,
112
- "Authorization" => sign("DELETE", bucket_path, "", "" ,date)
127
+ 'Host' => @aliyun_upload_host,
128
+ 'Date' => date,
129
+ 'Authorization' => sign('DELETE', bucket_path, '', '', date)
113
130
  }
114
131
  url = path_to_url(path)
115
- response = RestClient.delete(URI.encode(url), headers)
132
+ response = RestClient.delete(url, headers)
116
133
  response.code == 204 ? url : nil
117
134
  end
118
135
 
@@ -126,12 +143,12 @@ module Aliyun
126
143
  bucket_path = get_bucket_path(path)
127
144
  date = gmtdate
128
145
  headers = {
129
- "Host" => @aliyun_upload_host,
130
- "Date" => date,
131
- "Authorization" => sign("GET", bucket_path, "", "" ,date)
146
+ 'Host' => @aliyun_upload_host,
147
+ 'Date' => date,
148
+ 'Authorization' => sign('GET', bucket_path, '', '', date)
132
149
  }
133
150
  url = path_to_url(path)
134
- response = RestClient.get(URI.encode(url), headers)
151
+ response = RestClient.get(url, headers)
135
152
  response.body
136
153
  end
137
154
 
@@ -150,7 +167,7 @@ module Aliyun
150
167
  #
151
168
  # @return [String] a string represents the formated time, e.g. "Wed, 05 Sep. 2012 23:00:00 GMT"
152
169
  def gmtdate
153
- Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
170
+ Time.now.gmtime.strftime('%a, %d %b %Y %H:%M:%S GMT')
154
171
  end
155
172
 
156
173
  # remove leading slashes in the path
@@ -158,10 +175,7 @@ module Aliyun
158
175
  # @param path [String] the path to retrieve the file on remote storage
159
176
  # @return [String] the new string after removing leading slashed
160
177
  def format_path(path)
161
- return "" if path.blank?
162
- path.gsub!(/^\/+/,"")
163
-
164
- path
178
+ path.blank? ? '' : path.gsub(%r{^/+}, '')
165
179
  end
166
180
 
167
181
  # A path consis of the bucket name and file name
@@ -170,7 +184,7 @@ module Aliyun
170
184
  # @param path [String] the path to retrieve the file on remote storage
171
185
  # @return [String] the expected bucket path, e.g. "test-bucket/oss-api.pdf"
172
186
  def get_bucket_path(path)
173
- [@aliyun_bucket,path].join("/")
187
+ [@aliyun_bucket, path].join('/')
174
188
  end
175
189
 
176
190
  # The full path contains host name to the file
@@ -178,11 +192,11 @@ module Aliyun
178
192
  # @param path [String] the path to retrieve the file on remote storage
179
193
  # @return [String] the expected full path, e.g. "http://martin-test.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf"
180
194
  def path_to_url(path)
181
- return path if path =~ /^https?:\/{2}/ # 已经是全路径
182
- "http://#{fetch_file_host}/#{path}"
195
+ URI.encode(path =~ %r{^https?://} ? path : "http://#{aliyun_upload_host}/#{path}")
183
196
  end
184
197
 
185
198
  private
199
+
186
200
  # The signature algorithm
187
201
  # https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
188
202
  #
@@ -190,14 +204,16 @@ module Aliyun
190
204
  # @param content_md5 [String] the md5 value for the content to be uploaded
191
205
  # @param content_type [String] the content type of the file, e.g. "application/pdf"
192
206
  # @param date [String] the GMT formatted date string
193
- def sign(verb, path, content_md5 = '', content_type = '', date)
207
+ def sign(verb, path, content_md5, content_type, date)
194
208
  canonicalized_oss_headers = ''
195
209
  canonicalized_resource = "/#{path}"
196
- string_to_sign = "#{verb}\n\n#{content_type}\n#{date}\n#{canonicalized_oss_headers}#{canonicalized_resource}"
210
+ string_to_sign = [
211
+ verb, content_md5, content_type, date,
212
+ canonicalized_oss_headers + canonicalized_resource
213
+ ].join("\n")
197
214
  digest = OpenSSL::Digest.new('sha1')
198
215
  h = OpenSSL::HMAC.digest(digest, @aliyun_access_key, string_to_sign)
199
- h = Base64.encode64(h)
200
- "OSS #{@aliyun_access_id}:#{h}"
216
+ "OSS #{@aliyun_access_id}:#{Base64.encode64(h)}"
201
217
  end
202
218
  end
203
219
  end
@@ -1,20 +1,42 @@
1
1
  require 'aliyun/errors'
2
2
 
3
3
  module Aliyun
4
- module DataCenter
5
- # https://docs.aliyun.com/#/pub/oss/product-documentation/domain-region
6
- AVAILABLE_CHINA_DATA_CENTERS = %w(hangzhou qingdao beijing hongkong shenzhen shanghai)
7
- AVAILABLE_US_DATA_CENTERS = %w(us-west-1)
4
+ module DataCenter
5
+ # https://help.aliyun.com/document_detail/31837.html
6
+ AVAILABLE_DATA_CENTERS = %w(
7
+ oss-cn-hangzhou
8
+ oss-cn-shanghai
9
+ oss-cn-qingdao
10
+ oss-cn-beijing
11
+ oss-cn-zhangjiakou
12
+ oss-cn-huhehaote
13
+ oss-cn-shenzhen
14
+ oss-cn-heyuan
15
+ oss-cn-chengdu
16
+ oss-cn-hongkong
17
+ oss-us-west-1
18
+ oss-us-east-1
19
+ oss-ap-southeast-1
20
+ oss-ap-southeast-2
21
+ oss-ap-southeast-3
22
+ oss-ap-southeast-5
23
+ oss-ap-northeast-1
24
+ oss-ap-south-1
25
+ oss-eu-central-1
26
+ oss-eu-west-1
27
+ oss-me-east-1
28
+ )
8
29
 
9
30
  def get_endpoint(options)
10
- data_center = options[:data_center]
11
- if (AVAILABLE_CHINA_DATA_CENTERS + AVAILABLE_US_DATA_CENTERS).exclude?(data_center)
12
- raise InvalildDataCenter, "Unsupported Data Center #{data_center} Detected"
13
- end
31
+ data_center = options[:data_center]
14
32
 
15
- internal = options[:internal] ? "-internal" : ''
16
- country = AVAILABLE_CHINA_DATA_CENTERS.include?(data_center) ? 'cn' : 'us'
17
- "oss-#{country}-#{data_center}#{internal}.aliyuncs.com"
33
+ data_center.prepend('oss-') unless data_center.match(/^oss/)
34
+
35
+ unless AVAILABLE_DATA_CENTERS.include?(data_center)
36
+ fail InvalildDataCenter, "Unsupported Data Center #{options[:data_center]} Detected"
37
+ end
38
+
39
+ "#{data_center}#{options[:internal] ? '-internal' : ''}.aliyuncs.com"
18
40
  end
19
- end
20
- end
41
+ end
42
+ end
@@ -1,4 +1,4 @@
1
1
  module Aliyun
2
- class InvalildDataCenter < StandardError
3
- end
4
- end
2
+ class InvalildDataCenter < StandardError
3
+ end
4
+ end
@@ -2,12 +2,46 @@ module Paperclip
2
2
  module Storage
3
3
  module Aliyun
4
4
  def self.extended(base)
5
+ base.instance_eval do
6
+ @aliyun_options = @options[:aliyun]
7
+ end
8
+
9
+ [
10
+ :aliyun_upload_url, :aliyun_internal_url,
11
+ :aliyun_external_url, :aliyun_alias_url
12
+ ].each do |url_style|
13
+ Paperclip.interpolates(url_style) do |attachment, style|
14
+ attachment.send(url_style, style)
15
+ end unless Paperclip::Interpolations.respond_to? url_style
16
+ end
5
17
  end
6
18
 
7
- def exists?(style = default_style)
8
- return false unless path(style)
19
+ def build_aliyun_object_url(host, style)
20
+ if oss_connection.aliyun_protocol_relative_url
21
+ "//#{host}/#{path(style).sub(%r{\A/}, '')}"
22
+ else
23
+ "#{oss_connection.aliyun_protocol}://#{host}/#{path(style).sub(%r{\A/}, '')}"
24
+ end
25
+ end
26
+
27
+ def aliyun_upload_url(style = default_style)
28
+ build_aliyun_object_url(oss_connection.aliyun_upload_host, style)
29
+ end
9
30
 
10
- oss_connection.exists? path(style)
31
+ def aliyun_internal_url(style = default_style)
32
+ build_aliyun_object_url(oss_connection.aliyun_internal_host, style)
33
+ end
34
+
35
+ def aliyun_external_url(style = default_style)
36
+ build_aliyun_object_url(oss_connection.aliyun_external_host, style)
37
+ end
38
+
39
+ def aliyun_alias_url(style = default_style)
40
+ build_aliyun_object_url(oss_connection.aliyun_alias_host, style)
41
+ end
42
+
43
+ def exists?(style = default_style)
44
+ path(style) ? oss_connection.exists?(path(style)) : false
11
45
  end
12
46
 
13
47
  def flush_writes #:nodoc:
@@ -28,7 +62,7 @@ module Paperclip
28
62
  @queued_for_delete = []
29
63
  end
30
64
 
31
- def copy_to_local_file(style = default_style, local_dest_path)
65
+ def copy_to_local_file(style, local_dest_path)
32
66
  log("copying #{path(style)} to local file #{local_dest_path}")
33
67
  local_file = ::File.open(local_dest_path, 'wb')
34
68
  remote_file_str = oss_connection.get path(style)
@@ -37,9 +71,9 @@ module Paperclip
37
71
  end
38
72
 
39
73
  def oss_connection
40
- return @oss_connection if @oss_connection
41
-
42
- @oss_connection ||= ::Aliyun::Connection.new Paperclip::Attachment.default_options[:aliyun]
74
+ @oss_connection ||= ::Aliyun::Connection.new(
75
+ Paperclip::Attachment.default_options[:aliyun].merge(@aliyun_options)
76
+ )
43
77
  end
44
78
  end
45
79
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip-storage-aliyun
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Hong
8
+ - Aidi Stan
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-08-02 00:00:00.000000000 Z
12
+ date: 2020-06-14 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: paperclip
@@ -44,24 +45,11 @@ executables: []
44
45
  extensions: []
45
46
  extra_rdoc_files: []
46
47
  files:
47
- - ".gitignore"
48
- - ".rspec"
49
- - Gemfile
50
- - README.md
51
48
  - lib/aliyun/connection.rb
52
49
  - lib/aliyun/data_center.rb
53
50
  - lib/aliyun/errors.rb
54
51
  - lib/paperclip-storage-aliyun.rb
55
52
  - lib/paperclip/storage/aliyun.rb
56
- - paperclip-storage-aliyun.gemspec
57
- - spec/aliyun_spec.rb
58
- - spec/attachments/girl.jpg
59
- - spec/attachments/masu.pdf
60
- - spec/fixtures/schema.rb
61
- - spec/lib/paperclip/storage/aliyun_spec.rb
62
- - spec/spec_helper.rb
63
- - spec/support/post.rb
64
- - spec/support/rails.rb
65
53
  homepage: https://github.com/Martin91/paperclip-storage-aliyun
66
54
  licenses:
67
55
  - MIT
@@ -81,10 +69,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
69
  - !ruby/object:Gem::Version
82
70
  version: '0'
83
71
  requirements: []
84
- rubyforge_project:
85
- rubygems_version: 2.4.8
72
+ rubygems_version: 3.0.6
86
73
  signing_key:
87
74
  specification_version: 4
88
75
  summary: Extend a Aliyun OSS storage for paperclip
89
76
  test_files: []
90
- has_rdoc:
data/.gitignore DELETED
@@ -1,3 +0,0 @@
1
- Gemfile.lock
2
- .yardoc/
3
- doc/
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --color
data/Gemfile DELETED
@@ -1,15 +0,0 @@
1
- source 'http://ruby.taobao.org'
2
-
3
- # A database backend that translates database interactions into no-ops. Using
4
- # NullDB enables you to test your model business logic - including after_save
5
- # hooks - without ever touching a real database.
6
- gem "activerecord-nulldb-adapter"
7
-
8
- gemspec
9
-
10
- group :test do
11
- gem 'activerecord', '~> 4.0.0'
12
- gem 'rspec', '~> 3.3.0'
13
- gem 'pry'
14
- gem 'pry-nav'
15
- end
data/README.md DELETED
@@ -1,44 +0,0 @@
1
- Aliyun Open Storage Service for Paperclip
2
- ===
3
- This gem implement the support for [Aliyun open storage service(OSS)](http://oss.aliyun.com) to [Paperclip](https://github.com/thoughtbot/paperclip).
4
-
5
- #### Installation
6
- ```shell
7
- gem install paperclip-storage-aliyun
8
- ```
9
- Or, if you are using a bundler, you can append the following line into your **Gemfile**:
10
- ```ruby
11
- gem 'paperclip-storage-aliyun'
12
- ```
13
-
14
- #### Configuration
15
- In order to make all the things work, you should do some important configurations through a initializer:
16
-
17
- If you are developing a Rails application, you can append a new initializer like:
18
- ```ruby
19
- # [rails_root]/config/initializers/paperclip-aliyun-configuration.rb
20
- Paperclip::Attachment.default_options[:aliyun] = {
21
- access_id: '3VL9XMho8iCushj8',
22
- access_key: 'VAUI2q7Tc6yTh1jr3kBsEUzZ84gEa2',
23
- bucket: 'xx-test',
24
- data_centre: 'hangzhou',
25
- internal: false
26
- }
27
- ```
28
- Then, in the model which defines the attachment, specify your storage and other options, for example:
29
- ```ruby
30
- # [rails_root]/app/models/image.rb
31
- include Paperclip::Storage::Aliyun
32
-
33
- class Image < ActiveRecord::Base
34
- has_attached_file :attachment, {
35
- storage: :aliyun,
36
- styles: { thumbnail: "60x60#"},
37
- path: 'public/system/:class/:attachment/:id_partition/:style/:filename',
38
- url: "http://#{oss_connection.fetch_file_host}/public/system/:class/:attachment/:id_partition/:style/:filename"
39
- }
40
- end
41
- ```
42
-
43
- ### Thanks
44
- 这个gem是在参考[Jason Lee](https://github.com/huacnlee)先生写的gem [carrierwave-aliyun](https://github.com/huacnlee/carrierwave-aliyun)的基础上写出来的,其中主要直接用了阿里云接口的代码以及对应的测试代码,在此基础上自行实现Paperclip必要的`get`方法以及`exists?`方法。在此特别感谢**Jason Lee**先生的开源代码。
@@ -1,16 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = 'paperclip-storage-aliyun'
3
- s.platform = Gem::Platform::RUBY
4
- s.require_path = 'lib'
5
- s.summary = 'Extend a Aliyun OSS storage for paperclip'
6
- s.description = 'Extend a Aliyun OSS storage for paperclip'
7
- s.version = '0.0.3'
8
- s.files = `git ls-files`.split("\n")
9
- s.authors = ['Martin Hong']
10
- s.email = 'hongzeqin@gmail.com'
11
- s.homepage = 'https://github.com/Martin91/paperclip-storage-aliyun'
12
- s.license = 'MIT'
13
-
14
- s.add_runtime_dependency 'paperclip', '>= 3.5.2'
15
- s.add_runtime_dependency 'rest-client', '>= 1.6.7'
16
- end
@@ -1,59 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require "net/http"
4
-
5
- describe Aliyun::Connection do
6
- before :all do
7
- @connection = ::Aliyun::Connection.new OSS_CONNECTION_OPTIONS
8
- @path = 'a/a.jpg'
9
- end
10
-
11
- describe '#initialize' do
12
- it "raise error when use invalid data center" do
13
- expect do
14
- ::Aliyun::Connection.new data_center: 'guangzhou'
15
- end.to raise_error(Aliyun::InvalildDataCenter)
16
- end
17
- end
18
-
19
- describe '#put' do
20
- it "upload the attachment" do
21
- url = @connection.put @path, load_attachment("girl.jpg")
22
- response_code = Net::HTTP.get_response(URI.parse(url)).code
23
- expect(response_code).to eq("200")
24
- end
25
-
26
- it "support setting content type" do
27
- content_type = "application/pdf"
28
- path = 'pdfs/masu.pdf'
29
- @connection.put path, load_attachment("masu.pdf"), content_type: content_type
30
- file_meta = @connection.head(path)
31
- expect(file_meta[:content_type]).to eq(content_type)
32
-
33
- @connection.delete path
34
- end
35
- end
36
-
37
- describe '#delete' do
38
- it "delete the attachment" do
39
- url = @connection.delete @path
40
- response_code = Net::HTTP.get_response(URI.parse(url)).code
41
- expect(response_code).to eq("404")
42
- end
43
- end
44
-
45
- describe "#exists?" do
46
- before :all do
47
- @connection.put @path, load_attachment("girl.jpg")
48
- end
49
-
50
- it "return true if the file has been uploaded" do
51
- expect(@connection.exists?(@path)).to be_truthy
52
- end
53
-
54
- it "return false if the specified file didn't exist" do
55
- @connection.delete @path
56
- expect(@connection.exists?(@path)).to be_falsey
57
- end
58
- end
59
- end
Binary file
Binary file
@@ -1,8 +0,0 @@
1
- require "active_record"
2
- require "paperclip"
3
-
4
- ActiveRecord::Schema.define do
5
- create_table :posts, force: true do |t|
6
- t.attachment :attachment
7
- end
8
- end
@@ -1,76 +0,0 @@
1
- require 'spec_helper'
2
- require "open-uri"
3
- require 'net/http'
4
- require 'support/post'
5
-
6
- describe Paperclip::Storage::Aliyun do
7
- before :all do
8
- @file = load_attachment('girl.jpg')
9
- @post = Post.create attachment: @file
10
- end
11
-
12
- after :all do
13
- if @post && @post.respond_to?(:id)
14
- @post.destroy!
15
- end
16
-
17
- @file.close
18
- end
19
-
20
- describe "#flush_writes" do
21
- it "uploads the attachment to Aliyun" do
22
- response = open(@post.attachment.url)
23
- expect(response).to be_truthy
24
- end
25
-
26
- it "get uploaded file from Aliyun" do
27
- attachment = open @post.attachment.url
28
- expect(attachment.size).to eq(@file.size)
29
- end
30
-
31
- it "set content type according to the original file" do
32
- attachment = load_attachment('masu.pdf')
33
- post = Post.create attachment: attachment
34
- headers = RestClient.head(post.attachment.url).headers
35
- expect(headers[:content_type]).to eq('application/pdf')
36
-
37
- post.destroy
38
- end
39
- end
40
-
41
- describe "#exists?" do
42
- it "returns true if the file exists on Aliyun" do
43
- expect(@post.attachment).to exist
44
- end
45
-
46
- it "returns false if the file doesn't exist on Aliyun" do
47
- post = Post.new attachment: @file
48
- expect(post.attachment).not_to exist
49
- end
50
-
51
- it "not raise exception when attachment not saved" do
52
- post = Post.create
53
- expect{post.attachment.exists?}.not_to raise_error
54
- end
55
- end
56
-
57
- describe "#copy_to_local_file" do
58
- it "copies file from Aliyun to a local file" do
59
- destination = File.join(Bundler.root, "tmp/photo.jpg")
60
- @post.attachment.copy_to_local_file(:original, destination)
61
- expect(File.exists?(destination)).to be_truthy
62
-
63
- File.delete destination
64
- end
65
- end
66
-
67
- describe "#flush_deletes" do
68
- it "deletes the attachment from Aliyun" do
69
- attachment_url = @post.attachment.url
70
- @post.destroy
71
-
72
- response_code = Net::HTTP.get_response(URI.parse(attachment_url)).code
73
- expect(response_code).to eq("404")
74
- end
75
- end
76
- end
@@ -1,29 +0,0 @@
1
- require 'pry'
2
- require 'pry-nav'
3
- require 'paperclip-storage-aliyun'
4
-
5
- Dir[File.join(Bundler.root, "spec/support/**/*.rb")].each &method(:require)
6
-
7
- include Paperclip::Storage::Aliyun
8
- def file_host
9
- oss_connection.fetch_file_host
10
- end
11
-
12
- OSS_CONNECTION_OPTIONS = {
13
- access_id: '3VL9XMho8iCuslj8',
14
- access_key: 'VAUI2q7Tc6yTf1jr3kBsEUzZ84gEa2',
15
- bucket: 'martin-test',
16
- data_center: 'hangzhou',
17
- internal: false
18
- # host: nil
19
- }
20
-
21
- # paperclip初始化设置
22
- Paperclip::Attachment.default_options[:storage] = :aliyun
23
- Paperclip::Attachment.default_options[:path] = 'public/system/:class/:attachment/:id_partition/:style/:filename'
24
- Paperclip::Attachment.default_options[:aliyun] = OSS_CONNECTION_OPTIONS
25
- Paperclip::Attachment.default_options[:url] = "http://#{file_host}/public/system/:class/:attachment/:id_partition/:style/:filename"
26
-
27
- def load_attachment(file_name)
28
- File.open (File.expand_path "attachments/#{file_name}", File.dirname(__FILE__)), 'rb'
29
- end
@@ -1,24 +0,0 @@
1
- require "active_record"
2
- require "nulldb"
3
- require "paperclip"
4
-
5
- class Post < ActiveRecord::Base
6
- include Paperclip::Glue
7
-
8
- has_attached_file :attachment
9
- do_not_validate_attachment_file_type :attachment
10
- end
11
-
12
- RSpec.configure do |config|
13
- config.before(:all) do
14
- FileUtils.mkdir_p File.join(Bundler.root, "tmp")
15
- ActiveRecord::Base.establish_connection(
16
- adapter: "nulldb",
17
- schema: File.join(Bundler.root, "spec/fixtures/schema.rb"),
18
- )
19
- end
20
-
21
- config.after(:all) do
22
- ActiveRecord::Base.remove_connection
23
- end
24
- end
@@ -1,10 +0,0 @@
1
- require "paperclip"
2
-
3
- module Paperclip
4
- module Interpolations
5
- module Rails
6
- def self.root
7
- end
8
- end
9
- end
10
- end