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