paperclip-storage-aliyun 0.0.2 → 0.0.3

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,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NDE1YjU0M2RkOGFkNGJmODBkYTAwOGRhNzIwYmFmNjk1MTQwMzg1Yg==
5
- data.tar.gz: !binary |-
6
- ZGZkN2MzZDM4OTI2MjdkMjFjNzY2NDQ0MDE0OGY0YTk4YjZiODJkOA==
2
+ SHA1:
3
+ metadata.gz: 770e2aba77af7013237abcb823fec49c244d15d3
4
+ data.tar.gz: 199af51f6159ab6b0138eab907b7dd7286b2fd2a
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- N2NjZjUzZGZlYjQxNTU0YzEyZTJmMzZlNGY4YmZhMTlkMzMxY2NjNDY5NzIy
10
- NDIyZTA5ZDFhMmQ0YWQzNmZlNGUxNDEwMzU1NDhmOGUyZjM1NDhiMjJhNTgw
11
- OGRhOWU5MWI5Mjk4MTZjZDNjNmNhMGNkNzdiNjM3ODI3NTM2NDI=
12
- data.tar.gz: !binary |-
13
- ZGFiNmFmNTQ2MjNiMDMxZjExZWU2NmU4ZWQxMzdjYTY5ZDQ1NWZlZDFjYmEz
14
- MjNmOWM1NTBmNzViOGRmY2I1ZmY0MjY5NmJmMzYwYjJmMTI4YzEyZDhjYmU5
15
- MmFiZGQzMGZkMTVlNjEyMjA3ZWM4NjM4YWJjMTAyZDQxN2E0OWU=
6
+ metadata.gz: 418741aa19eeb9400e7cae5eb9448c671a99688632cb19a9e7c6c8c43a269297c608c2ef53dc84881ff437833ecdaa826db8f7ece5c0052ac453aa61a9703422
7
+ data.tar.gz: 27af1cb2c3f924a9f1d736206a57c648d82a3b10b03c3e1ed373dcc8c9d48050f19344c1d7bd22aafe8a021919284c71dbb8fb53170d35142d8a0fddaec3059f
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ .yardoc/
3
+ doc/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,15 @@
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 ADDED
@@ -0,0 +1,44 @@
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**先生的开源代码。
@@ -0,0 +1,203 @@
1
+ # encoding: utf-8
2
+
3
+ require 'openssl'
4
+ require 'digest/md5'
5
+ require "rest-client"
6
+ require "base64"
7
+ require 'uri'
8
+ require 'aliyun/data_center'
9
+
10
+ module Aliyun
11
+ class Connection
12
+ include DataCenter
13
+ # Initialize the OSS connection
14
+ #
15
+ # @param [Hash] An options to specify connection details
16
+ # @option access_id [String] used to set "Authorization" request header
17
+ # @option access_key [String] the access key
18
+ # @option bucket [String] bucket used to access
19
+ # @option data_center [String] available data center name, e.g. 'hangzhou'
20
+ # @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
22
+ # @note both access_id and acces_key are related to authorization algorithm:
23
+ # https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
24
+ def initialize(options = {})
25
+ @aliyun_access_id = options[:access_id]
26
+ @aliyun_access_key = options[:access_key]
27
+ @aliyun_bucket = options[:bucket]
28
+
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
41
+ end
42
+
43
+ # Return the meta informations for the a file specified by the path
44
+ # https://docs.aliyun.com/#/pub/oss/api-reference/object&HeadObject
45
+ #
46
+ # @param path [String] the path of file storaged in Aliyun OSS
47
+ # @return [Hash] the meta data of the file
48
+ # @note the example headers will be like:
49
+ #
50
+ # {
51
+ # {:date=>"Sun, 02 Aug 2015 02:42:45 GMT",
52
+ # :content_type=>"image/jpg",
53
+ # :content_length=>"125198",
54
+ # :connection=>"close",
55
+ # :accept_ranges=>"bytes",
56
+ # :etag=>"\"336262A42E5B99AFF5B8BC66611FC156\"",
57
+ # :last_modified=>"Sun, 01 Dec 2013 16:39:57 GMT",
58
+ # :server=>"AliyunOSS",
59
+ # :x_oss_object_type=>"Normal",
60
+ # :x_oss_request_id=>"55BD83A5D4C05BDFF4A329E0"}}
61
+ #
62
+ def head(path)
63
+ url = path_to_url(path)
64
+ RestClient.head(url).headers
65
+ rescue RestClient::ResourceNotFound
66
+ {}
67
+ end
68
+
69
+ # Upload File to Aliyun OSS
70
+ # https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject
71
+ #
72
+ # @param path [String] the target storing path on the oss
73
+ # @param file [File] an instance of File represents a file to be uploaded
74
+ # @param options [Hash]
75
+ # - content_type - MimeType value for the file, default is "image/jpg"
76
+ #
77
+ # @return [String] The downloadable url of the uploaded file
78
+ # @return [nil] if the uploading failed
79
+ def put(path, file, options={})
80
+ path = format_path(path)
81
+ bucket_path = get_bucket_path(path)
82
+ content_md5 = Digest::MD5.file(file)
83
+ content_type = options[:content_type] || "image/jpg"
84
+ date = gmtdate
85
+ url = path_to_url(path)
86
+ auth_sign = sign("PUT", bucket_path, content_md5, content_type, date)
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"
94
+ }
95
+ response = RestClient.put(URI.encode(url), file, headers)
96
+ response.code == 200 ? path_to_url(path) : nil
97
+ end
98
+
99
+ # Delete a file from the OSS
100
+ # https://docs.aliyun.com/#/pub/oss/api-reference/object&DeleteObject
101
+ #
102
+ # @param path [String] the path to retrieve the file on remote storage
103
+ # @return [String] the expired url to the file, if the file deleted successfully
104
+ # @return [nil] if the delete operation failed
105
+ def delete(path)
106
+ path = format_path(path)
107
+ bucket_path = get_bucket_path(path)
108
+ date = gmtdate
109
+ headers = {
110
+ "Host" => @aliyun_upload_host,
111
+ "Date" => date,
112
+ "Authorization" => sign("DELETE", bucket_path, "", "" ,date)
113
+ }
114
+ url = path_to_url(path)
115
+ response = RestClient.delete(URI.encode(url), headers)
116
+ response.code == 204 ? url : nil
117
+ end
118
+
119
+ # Download the file from OSS
120
+ # https://docs.aliyun.com/#/pub/oss/api-reference/object&GetObject
121
+ #
122
+ # @param path [String] the path to retrieve the file on remote storage
123
+ # @return [?] the file content consist of bytes
124
+ def get(path)
125
+ path = format_path(path)
126
+ bucket_path = get_bucket_path(path)
127
+ date = gmtdate
128
+ headers = {
129
+ "Host" => @aliyun_upload_host,
130
+ "Date" => date,
131
+ "Authorization" => sign("GET", bucket_path, "", "" ,date)
132
+ }
133
+ url = path_to_url(path)
134
+ response = RestClient.get(URI.encode(url), headers)
135
+ response.body
136
+ end
137
+
138
+ # Determine if the file exists on the OSS
139
+ # https://docs.aliyun.com/#/pub/oss/api-reference/object&HeadObject
140
+ #
141
+ # @param path [String] the path to retrieve the file on remote storage
142
+ # @return [true] if file exists
143
+ # @return [false] if file could not be found
144
+ def exists?(path)
145
+ head(path).empty? ? false : true
146
+ end
147
+
148
+ # The GMT format time referenced from HTTP 1.1
149
+ # https://docs.aliyun.com/#/pub/oss/api-reference/public-header
150
+ #
151
+ # @return [String] a string represents the formated time, e.g. "Wed, 05 Sep. 2012 23:00:00 GMT"
152
+ def gmtdate
153
+ Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
154
+ end
155
+
156
+ # remove leading slashes in the path
157
+ #
158
+ # @param path [String] the path to retrieve the file on remote storage
159
+ # @return [String] the new string after removing leading slashed
160
+ def format_path(path)
161
+ return "" if path.blank?
162
+ path.gsub!(/^\/+/,"")
163
+
164
+ path
165
+ end
166
+
167
+ # A path consis of the bucket name and file name
168
+ # https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
169
+ #
170
+ # @param path [String] the path to retrieve the file on remote storage
171
+ # @return [String] the expected bucket path, e.g. "test-bucket/oss-api.pdf"
172
+ def get_bucket_path(path)
173
+ [@aliyun_bucket,path].join("/")
174
+ end
175
+
176
+ # The full path contains host name to the file
177
+ #
178
+ # @param path [String] the path to retrieve the file on remote storage
179
+ # @return [String] the expected full path, e.g. "http://martin-test.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf"
180
+ def path_to_url(path)
181
+ return path if path =~ /^https?:\/{2}/ # 已经是全路径
182
+ "http://#{fetch_file_host}/#{path}"
183
+ end
184
+
185
+ private
186
+ # The signature algorithm
187
+ # https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
188
+ #
189
+ # @param verb [String] the request verb, e.g. "GET" or "DELETE"
190
+ # @param content_md5 [String] the md5 value for the content to be uploaded
191
+ # @param content_type [String] the content type of the file, e.g. "application/pdf"
192
+ # @param date [String] the GMT formatted date string
193
+ def sign(verb, path, content_md5 = '', content_type = '', date)
194
+ canonicalized_oss_headers = ''
195
+ canonicalized_resource = "/#{path}"
196
+ string_to_sign = "#{verb}\n\n#{content_type}\n#{date}\n#{canonicalized_oss_headers}#{canonicalized_resource}"
197
+ digest = OpenSSL::Digest.new('sha1')
198
+ h = OpenSSL::HMAC.digest(digest, @aliyun_access_key, string_to_sign)
199
+ h = Base64.encode64(h)
200
+ "OSS #{@aliyun_access_id}:#{h}"
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,20 @@
1
+ require 'aliyun/errors'
2
+
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)
8
+
9
+ 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
14
+
15
+ internal = options[:internal] ? "-internal" : ''
16
+ country = AVAILABLE_CHINA_DATA_CENTERS.include?(data_center) ? 'cn' : 'us'
17
+ "oss-#{country}-#{data_center}#{internal}.aliyuncs.com"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ module Aliyun
2
+ class InvalildDataCenter < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'paperclip'
2
+
3
+ require 'paperclip/storage/aliyun'
4
+ require 'aliyun/connection'
@@ -0,0 +1,46 @@
1
+ module Paperclip
2
+ module Storage
3
+ module Aliyun
4
+ def self.extended(base)
5
+ end
6
+
7
+ def exists?(style = default_style)
8
+ return false unless path(style)
9
+
10
+ oss_connection.exists? path(style)
11
+ end
12
+
13
+ def flush_writes #:nodoc:
14
+ @queued_for_write.each do |style_name, file|
15
+ oss_connection.put path(style_name), (File.new file.path), content_type: file.content_type
16
+ end
17
+
18
+ after_flush_writes
19
+
20
+ @queued_for_write = {}
21
+ end
22
+
23
+ def flush_deletes #:nodoc:
24
+ @queued_for_delete.each do |path|
25
+ oss_connection.delete path
26
+ end
27
+
28
+ @queued_for_delete = []
29
+ end
30
+
31
+ def copy_to_local_file(style = default_style, local_dest_path)
32
+ log("copying #{path(style)} to local file #{local_dest_path}")
33
+ local_file = ::File.open(local_dest_path, 'wb')
34
+ remote_file_str = oss_connection.get path(style)
35
+ local_file.write(remote_file_str)
36
+ local_file.close
37
+ end
38
+
39
+ def oss_connection
40
+ return @oss_connection if @oss_connection
41
+
42
+ @oss_connection ||= ::Aliyun::Connection.new Paperclip::Attachment.default_options[:aliyun]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,16 @@
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
@@ -0,0 +1,59 @@
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
@@ -0,0 +1,8 @@
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
@@ -0,0 +1,76 @@
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
@@ -0,0 +1,29 @@
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
@@ -0,0 +1,24 @@
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
@@ -0,0 +1,10 @@
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
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip-storage-aliyun
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Hong
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-01 00:00:00.000000000 Z
11
+ date: 2015-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: paperclip
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 3.5.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.5.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rest-client
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 1.6.7
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.6.7
41
41
  description: Extend a Aliyun OSS storage for paperclip
@@ -43,7 +43,25 @@ email: hongzeqin@gmail.com
43
43
  executables: []
44
44
  extensions: []
45
45
  extra_rdoc_files: []
46
- files: []
46
+ files:
47
+ - ".gitignore"
48
+ - ".rspec"
49
+ - Gemfile
50
+ - README.md
51
+ - lib/aliyun/connection.rb
52
+ - lib/aliyun/data_center.rb
53
+ - lib/aliyun/errors.rb
54
+ - lib/paperclip-storage-aliyun.rb
55
+ - 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
47
65
  homepage: https://github.com/Martin91/paperclip-storage-aliyun
48
66
  licenses:
49
67
  - MIT
@@ -54,18 +72,19 @@ require_paths:
54
72
  - lib
55
73
  required_ruby_version: !ruby/object:Gem::Requirement
56
74
  requirements:
57
- - - ! '>='
75
+ - - ">="
58
76
  - !ruby/object:Gem::Version
59
77
  version: '0'
60
78
  required_rubygems_version: !ruby/object:Gem::Requirement
61
79
  requirements:
62
- - - ! '>='
80
+ - - ">="
63
81
  - !ruby/object:Gem::Version
64
82
  version: '0'
65
83
  requirements: []
66
84
  rubyforge_project:
67
- rubygems_version: 2.1.11
85
+ rubygems_version: 2.4.8
68
86
  signing_key:
69
87
  specification_version: 4
70
88
  summary: Extend a Aliyun OSS storage for paperclip
71
89
  test_files: []
90
+ has_rdoc: