paperclip-storage-aliyun 0.0.3 → 0.1.5

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.
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