paperclip-storage-aliyun 0.0.3 → 0.1.0

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