paperclip_oss_storage 0.0.2 → 0.0.3

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: 5010fe49679aa7259bcf92f289b20ec7e6d4e042
4
- data.tar.gz: 213ccbd837979ea57f30b98aeb95ad3cc1f97ad5
3
+ metadata.gz: b6f6609164daccce0a8193a6c45146baf9bcde65
4
+ data.tar.gz: e97c77aa5a4634c4c0862fd53f4fa76e8879e7d8
5
5
  SHA512:
6
- metadata.gz: 72b0a75bb6aeb077370adc3bf66600bec645f44c16fa10c49f63ea8e99a1c2e51fa267af421d792c8e7d3a4d6dbf0a11df27296244cdb56ac6ba60023caabf72
7
- data.tar.gz: c455957df3cedb196807a867806f750c9a79d6f1672ca08f46b208024cb7060b5254a333fed899b926ba9b40e7595fb5b0cdafd8649e69f7bcc52c2a5da109e2
6
+ metadata.gz: 06c66a0fbef1bc638c40213c7073e51d10ef9e7d0c625d196a8d5c11c702523142bb4af2d3cf97e0fa20f908993671264000bdf70c29d91df6e146c2485aad1d
7
+ data.tar.gz: 2a1068fb172c4be299035e5876776c070bfdb8c77f99458bd0041515cc210a81888416b7eefbcf94d5ed3f3332e53f4ead39743e9381127a077afb127559c13b
@@ -0,0 +1,171 @@
1
+ # encoding: utf-8
2
+
3
+ require 'digest/hmac'
4
+ require 'digest/md5'
5
+ require "rest-client"
6
+ require "base64"
7
+ require 'uri'
8
+
9
+ module Aliyun
10
+ class Connection
11
+ def initialize(options = Paperclip::Attachment.default_options[:aliyun])
12
+ @aliyun_access_id = options[:access_id]
13
+ @aliyun_access_key = options[:access_key]
14
+ @aliyun_bucket = options[:bucket]
15
+
16
+ data_centre = options[:data_centre].to_s.downcase == 'qingdao' ? 'qingdao' : 'hangzhou'
17
+ internal = options[:internal] == true ? true : false
18
+ @aliyun_data_centre = "oss-cn-#{data_centre}#{internal ? '-internal' : nil}.aliyuncs.com"
19
+
20
+ @aliyun_upload_host = "#{@aliyun_bucket}.#{@aliyun_data_centre}"
21
+
22
+ @aliyun_host = options[:host] || @aliyun_upload_host
23
+ end
24
+
25
+ def fetch_file_host
26
+ @aliyun_host
27
+ end
28
+
29
+ =begin rdoc
30
+ 上传文件
31
+
32
+ == 参数:
33
+ - path - remote 存储路径
34
+ - file - 需要上传文件的 File 对象
35
+ - options:
36
+ - content_type - 上传文件的 MimeType,默认 `image/jpg`
37
+
38
+ == 返回值:
39
+ 图片的下载地址
40
+ =end
41
+ def put(path, file, options={})
42
+ path = format_path(path)
43
+ bucket_path = get_bucket_path(path)
44
+ content_md5 = Digest::MD5.file(file)
45
+ content_type = options[:content_type] || "image/jpg"
46
+ date = gmtdate
47
+ url = path_to_url(path)
48
+ auth_sign = sign("PUT", bucket_path, content_md5, content_type, date)
49
+ headers = {
50
+ "Authorization" => auth_sign,
51
+ "Content-Type" => content_type,
52
+ "Content-Length" => file.size,
53
+ "Date" => date,
54
+ "Host" => @aliyun_upload_host,
55
+ "Expect" => "100-Continue"
56
+ }
57
+ response = RestClient.put(URI.encode(url), file, headers)
58
+ response.code == 200 ? path_to_url(path) : nil
59
+ end
60
+
61
+ =begin rdoc
62
+ 删除 Remote 的文件
63
+
64
+ == 参数:
65
+ - path - remote 存储路径
66
+
67
+ == 返回值:
68
+ 图片的下载地址
69
+ =end
70
+ def delete(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("DELETE", bucket_path, "", "" ,date)
78
+ }
79
+ url = path_to_url(path)
80
+ response = RestClient.delete(URI.encode(url), headers)
81
+ response.code == 204 ? url : nil
82
+ end
83
+
84
+ =begin rdoc
85
+ 下载 Remote 的文件
86
+
87
+ == 参数:
88
+ - path - remote 存储路径
89
+
90
+ == 返回值:
91
+ 请求的图片的数据流
92
+ =end
93
+ def get(path)
94
+ path = format_path(path)
95
+ bucket_path = get_bucket_path(path)
96
+ date = gmtdate
97
+ headers = {
98
+ "Host" => @aliyun_upload_host,
99
+ "Date" => date,
100
+ "Authorization" => sign("GET", bucket_path, "", "" ,date)
101
+ }
102
+ url = path_to_url(path)
103
+ response = RestClient.get(URI.encode(url), headers)
104
+ response.body
105
+ end
106
+
107
+ =begin rdoc
108
+ 检查远程服务器是否已存在指定文件
109
+
110
+ == 参数:
111
+ - path - remote 存储路径
112
+
113
+ == 返回值:
114
+ true/false
115
+ =end
116
+ def exists?(path)
117
+ path = format_path(path)
118
+ bucket_path = get_bucket_path(path)
119
+ date = gmtdate
120
+ headers = {
121
+ "Host" => @aliyun_upload_host,
122
+ "Date" => date,
123
+ "Authorization" => sign("HEAD", bucket_path, "", "", date)
124
+ }
125
+ url = path_to_url(path)
126
+
127
+ # rest_client will throw exception if requested resource not found
128
+ begin
129
+ response = RestClient.head(URI.encode(url), headers)
130
+ rescue RestClient::ResourceNotFound
131
+ return false
132
+ end
133
+
134
+ true
135
+ end
136
+
137
+ ##
138
+ # 阿里云需要的 GMT 时间格式
139
+ def gmtdate
140
+ Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
141
+ end
142
+
143
+ def format_path(path)
144
+ return "" if path.blank?
145
+ path.gsub!(/^\/+/,"")
146
+
147
+ path
148
+ end
149
+
150
+ def get_bucket_path(path)
151
+ [@aliyun_bucket,path].join("/")
152
+ end
153
+
154
+ ##
155
+ # 根据配置返回完整的上传文件的访问地址
156
+ def path_to_url(path)
157
+ "http://#{fetch_file_host}/#{path}"
158
+ end
159
+
160
+ private
161
+ def sign(verb, path, content_md5 = '', content_type = '', date)
162
+ canonicalized_oss_headers = ''
163
+ canonicalized_resource = "/#{path}"
164
+ string_to_sign = "#{verb}\n\n#{content_type}\n#{date}\n#{canonicalized_oss_headers}#{canonicalized_resource}"
165
+ digest = OpenSSL::Digest::Digest.new('sha1')
166
+ h = OpenSSL::HMAC.digest(digest, @aliyun_access_key, string_to_sign)
167
+ h = Base64.encode64(h)
168
+ "OSS #{@aliyun_access_id}:#{h}"
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,44 @@
1
+ module Paperclip
2
+ module Storage
3
+ module Aliyun
4
+ def self.extended(base)
5
+ end
6
+
7
+ def exists?(style = default_style)
8
+ oss_connection.exists? path(style)
9
+ end
10
+
11
+ def flush_writes #:nodoc:
12
+ @queued_for_write.each do |style_name, file|
13
+ oss_connection.put path(style_name), (File.new file.path)
14
+ end
15
+
16
+ after_flush_writes
17
+
18
+ @queued_for_write = {}
19
+ end
20
+
21
+ def flush_deletes #:nodoc:
22
+ @queued_for_delete.each do |path|
23
+ oss_connection.delete path
24
+ end
25
+
26
+ @queued_for_delete = []
27
+ end
28
+
29
+ def copy_to_local_file(style = default_style, local_dest_path)
30
+ log("copying #{path(style)} to local file #{local_dest_path}")
31
+ local_file = ::File.open(local_dest_path, 'wb')
32
+ remote_file_str = oss_connection.get path(style)
33
+ local_file.write(remote_file_str)
34
+ local_file.close
35
+ end
36
+
37
+ def oss_connection
38
+ return @oss_connection if @oss_connection
39
+
40
+ @oss_connection ||= ::Aliyun::Connection.new
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module PaperclipOssStorage
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip_oss_storage
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
  - Elite
@@ -50,6 +50,8 @@ files:
50
50
  - LICENSE.txt
51
51
  - README.md
52
52
  - Rakefile
53
+ - lib/aliyun/connection.rb
54
+ - lib/paperclip/storage/aliyun.rb
53
55
  - lib/paperclip_oss_storage.rb
54
56
  - lib/paperclip_oss_storage/version.rb
55
57
  - paperclip_oss_storage.gemspec