paperclip-storage-aliyun 0.0.3 → 0.1.0

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
2
  SHA1:
3
- metadata.gz: 770e2aba77af7013237abcb823fec49c244d15d3
4
- data.tar.gz: 199af51f6159ab6b0138eab907b7dd7286b2fd2a
3
+ metadata.gz: d8531e6601564efe368735f05147b68f4401c495
4
+ data.tar.gz: e2317360addbbce35acd8bf2947a532cdf11f8c2
5
5
  SHA512:
6
- metadata.gz: 418741aa19eeb9400e7cae5eb9448c671a99688632cb19a9e7c6c8c43a269297c608c2ef53dc84881ff437833ecdaa826db8f7ece5c0052ac453aa61a9703422
7
- data.tar.gz: 27af1cb2c3f924a9f1d736206a57c648d82a3b10b03c3e1ed373dcc8c9d48050f19344c1d7bd22aafe8a021919284c71dbb8fb53170d35142d8a0fddaec3059f
6
+ metadata.gz: 1f7ce3fda9227a3937a1d04e7acce987c60028187496261c493176f87e016fcaba3083fc7a9977b28af313ac9a92b0ffef6af5ba092a052f40baaac65f7b52e6
7
+ data.tar.gz: abef51e1bbeb91ac622f74ed61f17bde84026d91eba1ebf423b11833ff770b2a4912d385ec09de6728d16f4d5d0bfafb44517696f0b43e268d4cc6cd3b10753d
data/.editorconfig ADDED
@@ -0,0 +1,13 @@
1
+ # EditorConfig is awesome: http://EditorConfig.org
2
+
3
+ # top-most EditorConfig file
4
+ root = true
5
+
6
+ # Unix-style newlines with a newline ending every file
7
+ [*]
8
+ charset = utf-8
9
+ indent_style = space
10
+ indent_size = 2
11
+ end_of_line = lf
12
+ insert_final_newline = true
13
+ trim_trailing_whitespace = true
data/.rubocop.yml ADDED
@@ -0,0 +1,11 @@
1
+ Style/Documentation:
2
+ Enabled: false
3
+
4
+ Metrics/AbcSize:
5
+ Max: 18
6
+
7
+ Metrics/LineLength:
8
+ Max: 120
9
+
10
+ Metrics/MethodLength:
11
+ Enabled: false
data/Gemfile CHANGED
@@ -1,15 +1,16 @@
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"
1
+ source 'https://ruby.taobao.org'
7
2
 
8
3
  gemspec
9
4
 
10
5
  group :test do
11
- gem 'activerecord', '~> 4.0.0'
6
+ gem 'activerecord', '~> 4.0.0'
7
+ # A database backend that translates database interactions into no-ops. Using
8
+ # NullDB enables you to test your model business logic - including after_save
9
+ # hooks - without ever touching a real database.
10
+ gem 'activerecord-nulldb-adapter'
12
11
  gem 'rspec', '~> 3.3.0'
12
+ # Use rubocop to lint our Ruby codes
13
+ gem 'rubocop', '~> 0.34.2'
13
14
  gem 'pry'
14
15
  gem 'pry-nav'
15
16
  end
data/README.md CHANGED
@@ -21,24 +21,27 @@ Paperclip::Attachment.default_options[:aliyun] = {
21
21
  access_id: '3VL9XMho8iCushj8',
22
22
  access_key: 'VAUI2q7Tc6yTh1jr3kBsEUzZ84gEa2',
23
23
  bucket: 'xx-test',
24
- data_centre: 'hangzhou',
24
+ data_center: 'hangzhou',
25
25
  internal: false
26
26
  }
27
27
  ```
28
28
  Then, in the model which defines the attachment, specify your storage and other options, for example:
29
29
  ```ruby
30
30
  # [rails_root]/app/models/image.rb
31
- include Paperclip::Storage::Aliyun
32
-
33
31
  class Image < ActiveRecord::Base
34
32
  has_attached_file :attachment, {
35
33
  storage: :aliyun,
36
34
  styles: { thumbnail: "60x60#"},
37
35
  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"
36
+ url: ':aliyun_upload_url'
39
37
  }
40
38
  end
41
39
  ```
42
40
 
43
- ### Thanks
44
- 这个gem是在参考[Jason Lee](https://github.com/huacnlee)先生写的gem [carrierwave-aliyun](https://github.com/huacnlee/carrierwave-aliyun)的基础上写出来的,其中主要直接用了阿里云接口的代码以及对应的测试代码,在此基础上自行实现Paperclip必要的`get`方法以及`exists?`方法。在此特别感谢**Jason Lee**先生的开源代码。
41
+ Similar to Paperclip::Storage::S3, there are four options for the url by now:
42
+ - `:aliyun_upload_url` : the url based on the options you give
43
+ - `:aliyun_internal_url` : the internal url, no matter what `options[:aliyun][:internal]` is
44
+ - `:aliyun_external_url` : the external url, no matter what `options[:aliyun][:internal]` is
45
+ - `:aliyun_alias_url` : the alias url based on the `host_alias` you give, typically used together with CDN
46
+
47
+ Please note the values above are all strings, not symbols. You could still make your own url if only you know what you are doing.
@@ -1,15 +1,23 @@
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
+
13
21
  # Initialize the OSS connection
14
22
  #
15
23
  # @param [Hash] An options to specify connection details
@@ -18,7 +26,7 @@ module Aliyun
18
26
  # @option bucket [String] bucket used to access
19
27
  # @option data_center [String] available data center name, e.g. 'hangzhou'
20
28
  # @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
29
+ # @option host_alias [String] the alias of the host, such as the CDN domain name
22
30
  # @note both access_id and acces_key are related to authorization algorithm:
23
31
  # https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
24
32
  def initialize(options = {})
@@ -26,18 +34,10 @@ module Aliyun
26
34
  @aliyun_access_key = options[:access_key]
27
35
  @aliyun_bucket = options[:bucket]
28
36
 
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
37
+ @aliyun_upload_host = "#{@aliyun_bucket}.#{get_endpoint(options)}"
38
+ @aliyun_internal_host = "#{@aliyun_bucket}.#{get_endpoint(options.merge(internal: true))}"
39
+ @aliyun_external_host = "#{@aliyun_bucket}.#{get_endpoint(options.merge(internal: false))}"
40
+ @aliyun_alias_host = options[:host_alias] || @aliyun_upload_host
41
41
  end
42
42
 
43
43
  # Return the meta informations for the a file specified by the path
@@ -68,29 +68,30 @@ module Aliyun
68
68
 
69
69
  # Upload File to Aliyun OSS
70
70
  # https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject
71
- #
71
+ #
72
72
  # @param path [String] the target storing path on the oss
73
73
  # @param file [File] an instance of File represents a file to be uploaded
74
74
  # @param options [Hash]
75
75
  # - content_type - MimeType value for the file, default is "image/jpg"
76
- #
76
+ #
77
77
  # @return [String] The downloadable url of the uploaded file
78
78
  # @return [nil] if the uploading failed
79
- def put(path, file, options={})
79
+ def put(path, file, options = {})
80
80
  path = format_path(path)
81
81
  bucket_path = get_bucket_path(path)
82
- content_md5 = Digest::MD5.file(file)
83
- content_type = options[:content_type] || "image/jpg"
82
+ content_md5 = Digest::MD5.file(file).base64digest
83
+ content_type = options[:content_type] || 'image/jpg'
84
84
  date = gmtdate
85
85
  url = path_to_url(path)
86
- auth_sign = sign("PUT", bucket_path, content_md5, content_type, date)
86
+ auth_sign = sign('PUT', bucket_path, content_md5, content_type, date)
87
87
  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"
88
+ 'Authorization' => auth_sign,
89
+ 'Content-Md5' => content_md5,
90
+ 'Content-Type' => content_type,
91
+ 'Content-Length' => file.size,
92
+ 'Date' => date,
93
+ 'Host' => @aliyun_upload_host,
94
+ 'Expect' => '100-Continue'
94
95
  }
95
96
  response = RestClient.put(URI.encode(url), file, headers)
96
97
  response.code == 200 ? path_to_url(path) : nil
@@ -107,9 +108,9 @@ module Aliyun
107
108
  bucket_path = get_bucket_path(path)
108
109
  date = gmtdate
109
110
  headers = {
110
- "Host" => @aliyun_upload_host,
111
- "Date" => date,
112
- "Authorization" => sign("DELETE", bucket_path, "", "" ,date)
111
+ 'Host' => @aliyun_upload_host,
112
+ 'Date' => date,
113
+ 'Authorization' => sign('DELETE', bucket_path, '', '', date)
113
114
  }
114
115
  url = path_to_url(path)
115
116
  response = RestClient.delete(URI.encode(url), headers)
@@ -126,9 +127,9 @@ module Aliyun
126
127
  bucket_path = get_bucket_path(path)
127
128
  date = gmtdate
128
129
  headers = {
129
- "Host" => @aliyun_upload_host,
130
- "Date" => date,
131
- "Authorization" => sign("GET", bucket_path, "", "" ,date)
130
+ 'Host' => @aliyun_upload_host,
131
+ 'Date' => date,
132
+ 'Authorization' => sign('GET', bucket_path, '', '', date)
132
133
  }
133
134
  url = path_to_url(path)
134
135
  response = RestClient.get(URI.encode(url), headers)
@@ -150,7 +151,7 @@ module Aliyun
150
151
  #
151
152
  # @return [String] a string represents the formated time, e.g. "Wed, 05 Sep. 2012 23:00:00 GMT"
152
153
  def gmtdate
153
- Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
154
+ Time.now.gmtime.strftime('%a, %d %b %Y %H:%M:%S GMT')
154
155
  end
155
156
 
156
157
  # remove leading slashes in the path
@@ -158,10 +159,7 @@ module Aliyun
158
159
  # @param path [String] the path to retrieve the file on remote storage
159
160
  # @return [String] the new string after removing leading slashed
160
161
  def format_path(path)
161
- return "" if path.blank?
162
- path.gsub!(/^\/+/,"")
163
-
164
- path
162
+ path.blank? ? '' : path.gsub(%r{^/+}, '')
165
163
  end
166
164
 
167
165
  # A path consis of the bucket name and file name
@@ -170,7 +168,7 @@ module Aliyun
170
168
  # @param path [String] the path to retrieve the file on remote storage
171
169
  # @return [String] the expected bucket path, e.g. "test-bucket/oss-api.pdf"
172
170
  def get_bucket_path(path)
173
- [@aliyun_bucket,path].join("/")
171
+ [@aliyun_bucket, path].join('/')
174
172
  end
175
173
 
176
174
  # The full path contains host name to the file
@@ -178,11 +176,11 @@ module Aliyun
178
176
  # @param path [String] the path to retrieve the file on remote storage
179
177
  # @return [String] the expected full path, e.g. "http://martin-test.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf"
180
178
  def path_to_url(path)
181
- return path if path =~ /^https?:\/{2}/ # 已经是全路径
182
- "http://#{fetch_file_host}/#{path}"
179
+ path =~ %r{^https?://} ? path : "http://#{aliyun_upload_host}/#{path}"
183
180
  end
184
181
 
185
182
  private
183
+
186
184
  # The signature algorithm
187
185
  # https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
188
186
  #
@@ -190,14 +188,16 @@ module Aliyun
190
188
  # @param content_md5 [String] the md5 value for the content to be uploaded
191
189
  # @param content_type [String] the content type of the file, e.g. "application/pdf"
192
190
  # @param date [String] the GMT formatted date string
193
- def sign(verb, path, content_md5 = '', content_type = '', date)
191
+ def sign(verb, path, content_md5, content_type, date)
194
192
  canonicalized_oss_headers = ''
195
193
  canonicalized_resource = "/#{path}"
196
- string_to_sign = "#{verb}\n\n#{content_type}\n#{date}\n#{canonicalized_oss_headers}#{canonicalized_resource}"
194
+ string_to_sign = [
195
+ verb, content_md5, content_type, date,
196
+ canonicalized_oss_headers + canonicalized_resource
197
+ ].join("\n")
197
198
  digest = OpenSSL::Digest.new('sha1')
198
199
  h = OpenSSL::HMAC.digest(digest, @aliyun_access_key, string_to_sign)
199
- h = Base64.encode64(h)
200
- "OSS #{@aliyun_access_id}:#{h}"
200
+ "OSS #{@aliyun_access_id}:#{Base64.encode64(h)}"
201
201
  end
202
202
  end
203
203
  end
@@ -1,20 +1,34 @@
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://docs.aliyun.com/#/pub/oss/product-documentation/domain-region
6
+ AVAILABLE_DATA_CENTERS = %w(
7
+ oss-cn-hangzhou
8
+ oss-cn-qingdao
9
+ oss-cn-beijing
10
+ oss-cn-hongkong
11
+ oss-cn-shenzhen
12
+ oss-cn-shanghai
13
+ oss-us-west-1
14
+ oss-ap-southeast-1
15
+ )
8
16
 
9
17
  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
18
+ data_center = find_center(options[:data_center])
14
19
 
15
- internal = options[:internal] ? "-internal" : ''
16
- country = AVAILABLE_CHINA_DATA_CENTERS.include?(data_center) ? 'cn' : 'us'
17
- "oss-#{country}-#{data_center}#{internal}.aliyuncs.com"
20
+ unless data_center && AVAILABLE_DATA_CENTERS.include?(data_center)
21
+ fail InvalildDataCenter, "Unsupported Data Center #{options[:data_center]} Detected"
22
+ end
23
+
24
+ "#{data_center}#{options[:internal] ? '-internal' : ''}.aliyuncs.com"
25
+ end
26
+
27
+ def find_center(data_center)
28
+ return if /^(oss|cn|us|ap|oss-cn)$/.match(data_center)
29
+
30
+ regexp = Regexp.new(data_center)
31
+ AVAILABLE_DATA_CENTERS.find { |center| regexp.match(center) }
18
32
  end
19
- end
20
- end
33
+ end
34
+ end
data/lib/aliyun/errors.rb CHANGED
@@ -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,38 @@ 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 aliyun_upload_url(style = default_style)
20
+ "http://#{oss_connection.aliyun_upload_host}/#{path(style).sub(%r{\A/}, '')}"
21
+ end
22
+
23
+ def aliyun_internal_url(style = default_style)
24
+ "http://#{oss_connection.aliyun_internal_host}/#{path(style).sub(%r{\A/}, '')}"
25
+ end
9
26
 
10
- oss_connection.exists? path(style)
27
+ def aliyun_external_url(style = default_style)
28
+ "http://#{oss_connection.aliyun_external_host}/#{path(style).sub(%r{\A/}, '')}"
29
+ end
30
+
31
+ def aliyun_alias_url(style = default_style)
32
+ "http://#{oss_connection.aliyun_alias_host}/#{path(style).sub(%r{\A/}, '')}"
33
+ end
34
+
35
+ def exists?(style = default_style)
36
+ path(style) ? oss_connection.exists?(path(style)) : false
11
37
  end
12
38
 
13
39
  def flush_writes #:nodoc:
@@ -28,7 +54,7 @@ module Paperclip
28
54
  @queued_for_delete = []
29
55
  end
30
56
 
31
- def copy_to_local_file(style = default_style, local_dest_path)
57
+ def copy_to_local_file(style, local_dest_path)
32
58
  log("copying #{path(style)} to local file #{local_dest_path}")
33
59
  local_file = ::File.open(local_dest_path, 'wb')
34
60
  remote_file_str = oss_connection.get path(style)
@@ -37,9 +63,9 @@ module Paperclip
37
63
  end
38
64
 
39
65
  def oss_connection
40
- return @oss_connection if @oss_connection
41
-
42
- @oss_connection ||= ::Aliyun::Connection.new Paperclip::Attachment.default_options[:aliyun]
66
+ @oss_connection ||= ::Aliyun::Connection.new(
67
+ Paperclip::Attachment.default_options[:aliyun].merge(@aliyun_options)
68
+ )
43
69
  end
44
70
  end
45
71
  end
@@ -4,9 +4,9 @@ Gem::Specification.new do |s|
4
4
  s.require_path = 'lib'
5
5
  s.summary = 'Extend a Aliyun OSS storage for paperclip'
6
6
  s.description = 'Extend a Aliyun OSS storage for paperclip'
7
- s.version = '0.0.3'
7
+ s.version = '0.1.0'
8
8
  s.files = `git ls-files`.split("\n")
9
- s.authors = ['Martin Hong']
9
+ s.authors = ['Martin Hong', 'Aidi Stan']
10
10
  s.email = 'hongzeqin@gmail.com'
11
11
  s.homepage = 'https://github.com/Martin91/paperclip-storage-aliyun'
12
12
  s.license = 'MIT'
data/spec/aliyun_spec.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- require "net/http"
3
+ require 'net/http'
4
4
 
5
5
  describe Aliyun::Connection do
6
6
  before :all do
@@ -9,7 +9,7 @@ describe Aliyun::Connection do
9
9
  end
10
10
 
11
11
  describe '#initialize' do
12
- it "raise error when use invalid data center" do
12
+ it 'raise error when use invalid data center' do
13
13
  expect do
14
14
  ::Aliyun::Connection.new data_center: 'guangzhou'
15
15
  end.to raise_error(Aliyun::InvalildDataCenter)
@@ -17,16 +17,16 @@ describe Aliyun::Connection do
17
17
  end
18
18
 
19
19
  describe '#put' do
20
- it "upload the attachment" do
21
- url = @connection.put @path, load_attachment("girl.jpg")
20
+ it 'upload the attachment' do
21
+ url = @connection.put @path, load_attachment('girl.jpg')
22
22
  response_code = Net::HTTP.get_response(URI.parse(url)).code
23
- expect(response_code).to eq("200")
23
+ expect(response_code).to eq('200')
24
24
  end
25
25
 
26
- it "support setting content type" do
27
- content_type = "application/pdf"
26
+ it 'support setting content type' do
27
+ content_type = 'application/pdf'
28
28
  path = 'pdfs/masu.pdf'
29
- @connection.put path, load_attachment("masu.pdf"), content_type: content_type
29
+ @connection.put path, load_attachment('masu.pdf'), content_type: content_type
30
30
  file_meta = @connection.head(path)
31
31
  expect(file_meta[:content_type]).to eq(content_type)
32
32
 
@@ -35,19 +35,19 @@ describe Aliyun::Connection do
35
35
  end
36
36
 
37
37
  describe '#delete' do
38
- it "delete the attachment" do
38
+ it 'delete the attachment' do
39
39
  url = @connection.delete @path
40
40
  response_code = Net::HTTP.get_response(URI.parse(url)).code
41
- expect(response_code).to eq("404")
41
+ expect(response_code).to eq('404')
42
42
  end
43
43
  end
44
44
 
45
- describe "#exists?" do
45
+ describe '#exists?' do
46
46
  before :all do
47
- @connection.put @path, load_attachment("girl.jpg")
47
+ @connection.put @path, load_attachment('girl.jpg')
48
48
  end
49
49
 
50
- it "return true if the file has been uploaded" do
50
+ it 'return true if the file has been uploaded' do
51
51
  expect(@connection.exists?(@path)).to be_truthy
52
52
  end
53
53
 
@@ -1,5 +1,5 @@
1
- require "active_record"
2
- require "paperclip"
1
+ require 'active_record'
2
+ require 'paperclip'
3
3
 
4
4
  ActiveRecord::Schema.define do
5
5
  create_table :posts, force: true do |t|
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require "open-uri"
2
+ require 'open-uri'
3
3
  require 'net/http'
4
4
  require 'support/post'
5
5
 
@@ -10,25 +10,22 @@ describe Paperclip::Storage::Aliyun do
10
10
  end
11
11
 
12
12
  after :all do
13
- if @post && @post.respond_to?(:id)
14
- @post.destroy!
15
- end
16
-
13
+ @post.destroy! if @post && @post.respond_to?(:id)
17
14
  @file.close
18
15
  end
19
16
 
20
- describe "#flush_writes" do
21
- it "uploads the attachment to Aliyun" do
17
+ describe '#flush_writes' do
18
+ it 'uploads the attachment to Aliyun' do
22
19
  response = open(@post.attachment.url)
23
20
  expect(response).to be_truthy
24
21
  end
25
22
 
26
- it "get uploaded file from Aliyun" do
23
+ it 'get uploaded file from Aliyun' do
27
24
  attachment = open @post.attachment.url
28
25
  expect(attachment.size).to eq(@file.size)
29
26
  end
30
27
 
31
- it "set content type according to the original file" do
28
+ it 'set content type according to the original file' do
32
29
  attachment = load_attachment('masu.pdf')
33
30
  post = Post.create attachment: attachment
34
31
  headers = RestClient.head(post.attachment.url).headers
@@ -38,8 +35,8 @@ describe Paperclip::Storage::Aliyun do
38
35
  end
39
36
  end
40
37
 
41
- describe "#exists?" do
42
- it "returns true if the file exists on Aliyun" do
38
+ describe '#exists?' do
39
+ it 'returns true if the file exists on Aliyun' do
43
40
  expect(@post.attachment).to exist
44
41
  end
45
42
 
@@ -48,29 +45,29 @@ describe Paperclip::Storage::Aliyun do
48
45
  expect(post.attachment).not_to exist
49
46
  end
50
47
 
51
- it "not raise exception when attachment not saved" do
48
+ it 'not raise exception when attachment not saved' do
52
49
  post = Post.create
53
- expect{post.attachment.exists?}.not_to raise_error
50
+ expect { post.attachment.exists? }.not_to raise_error
54
51
  end
55
52
  end
56
53
 
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")
54
+ describe '#copy_to_local_file' do
55
+ it 'copies file from Aliyun to a local file' do
56
+ destination = File.join(Bundler.root, 'tmp/photo.jpg')
60
57
  @post.attachment.copy_to_local_file(:original, destination)
61
- expect(File.exists?(destination)).to be_truthy
62
-
58
+ expect(File.exist?(destination)).to be_truthy
59
+
63
60
  File.delete destination
64
61
  end
65
62
  end
66
63
 
67
- describe "#flush_deletes" do
68
- it "deletes the attachment from Aliyun" do
64
+ describe '#flush_deletes' do
65
+ it 'deletes the attachment from Aliyun' do
69
66
  attachment_url = @post.attachment.url
70
67
  @post.destroy
71
68
 
72
69
  response_code = Net::HTTP.get_response(URI.parse(attachment_url)).code
73
- expect(response_code).to eq("404")
70
+ expect(response_code).to eq('404')
74
71
  end
75
72
  end
76
73
  end
data/spec/spec_helper.rb CHANGED
@@ -2,28 +2,26 @@ require 'pry'
2
2
  require 'pry-nav'
3
3
  require 'paperclip-storage-aliyun'
4
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
5
+ Paperclip.logger.level = ::Logger::UNKNOWN
6
+ Dir[Bundler.root.join('spec/support/**/*.rb')].each(&method(:require))
11
7
 
8
+ # Aliyun defaults
12
9
  OSS_CONNECTION_OPTIONS = {
13
10
  access_id: '3VL9XMho8iCuslj8',
14
11
  access_key: 'VAUI2q7Tc6yTf1jr3kBsEUzZ84gEa2',
15
12
  bucket: 'martin-test',
16
13
  data_center: 'hangzhou',
17
14
  internal: false
18
- # host: nil
15
+ # host_alias: nil
19
16
  }
20
17
 
21
- # paperclip初始化设置
18
+ # Paperclip defaults
22
19
  Paperclip::Attachment.default_options[:storage] = :aliyun
23
- Paperclip::Attachment.default_options[:path] = 'public/system/:class/:attachment/:id_partition/:style/:filename'
24
20
  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"
21
+ Paperclip::Attachment.default_options[:path] = 'public/system/:class/:attachment/:id_partition/:style/:filename'
22
+ Paperclip::Attachment.default_options[:url] = ':aliyun_upload_url'
26
23
 
24
+ # Utility methods
27
25
  def load_attachment(file_name)
28
- File.open (File.expand_path "attachments/#{file_name}", File.dirname(__FILE__)), 'rb'
26
+ File.open(Bundler.root.join("spec/attachments/#{file_name}"), 'rb')
29
27
  end
data/spec/support/post.rb CHANGED
@@ -1,6 +1,6 @@
1
- require "active_record"
2
- require "nulldb"
3
- require "paperclip"
1
+ require 'active_record'
2
+ require 'nulldb'
3
+ require 'paperclip'
4
4
 
5
5
  class Post < ActiveRecord::Base
6
6
  include Paperclip::Glue
@@ -11,10 +11,10 @@ end
11
11
 
12
12
  RSpec.configure do |config|
13
13
  config.before(:all) do
14
- FileUtils.mkdir_p File.join(Bundler.root, "tmp")
14
+ FileUtils.mkdir_p File.join(Bundler.root, 'tmp')
15
15
  ActiveRecord::Base.establish_connection(
16
- adapter: "nulldb",
17
- schema: File.join(Bundler.root, "spec/fixtures/schema.rb"),
16
+ adapter: 'nulldb',
17
+ schema: File.join(Bundler.root, 'spec/fixtures/schema.rb')
18
18
  )
19
19
  end
20
20
 
@@ -1,4 +1,4 @@
1
- require "paperclip"
1
+ require 'paperclip'
2
2
 
3
3
  module Paperclip
4
4
  module Interpolations
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.0
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: 2015-11-01 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: paperclip
@@ -44,8 +45,10 @@ executables: []
44
45
  extensions: []
45
46
  extra_rdoc_files: []
46
47
  files:
48
+ - ".editorconfig"
47
49
  - ".gitignore"
48
50
  - ".rspec"
51
+ - ".rubocop.yml"
49
52
  - Gemfile
50
53
  - README.md
51
54
  - lib/aliyun/connection.rb