activestorage_qinium 0.4.0 → 0.4.2
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 +4 -4
- data/CHANGELOG.md +62 -3
- data/Gemfile.lock +106 -3
- data/README.md +198 -29
- data/activestorage_qinium.gemspec +7 -2
- data/lib/active_storage/service/qinium_service.rb +74 -9
- data/lib/active_storage_qinium/version.rb +1 -1
- metadata +47 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0b6ef8d150c7dfdd39e09884bd2938787b9000d04114104661c64ce69556fd32
|
|
4
|
+
data.tar.gz: 618db182e05524e22984995769199f38e9c4df22c9d4da1d8e6f0476daa4870f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 777126f04943c53249d89a478c8cdebf58d47ed8b79ab061c724342e7f1f5550cb987259acde03f0563bb5a3306cab7f4f7fd8923f30fb737e390b8f38a74882
|
|
7
|
+
data.tar.gz: a4b7f0c854eeb5962b27bcbd658794f9db49c0351ab5040fc58bda667a8a8f381143a0928dfbc9799437a99efa5372caef3adc4ac35e5484e0d35645e21efb60
|
data/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,68 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
所有对 `activestorage_qinium` 的显著更改都将记录在此文件中。
|
|
4
|
+
|
|
5
|
+
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
|
|
6
|
+
并且本项目遵循 [语义化版本控制](https://semver.org/lang/zh-CN/)。
|
|
7
|
+
|
|
1
8
|
## [Unreleased]
|
|
2
9
|
|
|
3
|
-
## [0.
|
|
10
|
+
## [0.4.2] - 2026-04-02
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- 完善测试覆盖:添加 `upload`、`download`、`delete`、`copy`、`fetch`、`exist?` 等核心方法的测试
|
|
15
|
+
- 更新 README:添加详细配置示例、使用说明、URL 参数详解
|
|
16
|
+
- 添加 WebMock 测试依赖
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- 修复 gemspec 中的拼写错误(muti-tenant -> multi-tenant)
|
|
21
|
+
|
|
22
|
+
## [0.4.1] - 2024-03-15
|
|
23
|
+
|
|
24
|
+
### Added
|
|
4
25
|
|
|
5
|
-
-
|
|
26
|
+
- 增强 URL 生成功能:支持更多响应头参数自定义
|
|
27
|
+
- `response_content_type` - 自定义 Content-Type
|
|
28
|
+
- `response_cache_control` - 自定义 Cache-Control
|
|
29
|
+
- `response_content_disposition` - 自定义 Content-Disposition
|
|
30
|
+
- `response_content_encoding` - 自定义 Content-Encoding
|
|
31
|
+
- `response_content_language` - 自定义 Content-Language
|
|
32
|
+
- `response_expires` - 自定义 Expires
|
|
33
|
+
- `traffic_limit` - 下载限速
|
|
34
|
+
- 改进附件下载:使用 `attname` 和 `response-content-disposition` 双重参数确保浏览器正确下载
|
|
35
|
+
- 添加中文文件名下载支持
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- 优化 `url` 方法:重构查询参数构建逻辑
|
|
40
|
+
- 改进 URL 编码:对 key 的路径部分正确编码
|
|
41
|
+
- 完善私有资源下载:将 fop 参数传递给授权 URL 生成
|
|
42
|
+
|
|
43
|
+
## [0.4.0] - 2024-XX-XX
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- 支持多租户配置
|
|
48
|
+
- 添加 `QiniumImageAnalyzer` 自定义图片分析器
|
|
49
|
+
- 实现 `http_response_type_for_direct_upload` 方法
|
|
50
|
+
- 支持 `update_metadata` 方法(空实现,因七牛云不支持此操作)
|
|
6
51
|
|
|
7
52
|
## [0.2.1] - 2024-05-09
|
|
8
53
|
|
|
9
|
-
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- 支持私有空间下载 URL 生成
|
|
57
|
+
- 添加 `Qinium::Auth.authorize_download_url` 签名机制
|
|
58
|
+
|
|
59
|
+
## [0.1.0] - 2022-08-10
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- 初始发布
|
|
64
|
+
- 实现 Active Storage 服务所有必需方法
|
|
65
|
+
- 支持七牛云公有空间
|
|
66
|
+
- 支持分块上传
|
|
67
|
+
- 支持直接上传(浏览器直传)
|
|
68
|
+
- 添加 `QiniumImageAnalyzer` 图片分析器
|
data/Gemfile.lock
CHANGED
|
@@ -1,18 +1,109 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
activestorage_qinium (0.
|
|
5
|
-
qinium (~> 0.
|
|
4
|
+
activestorage_qinium (0.4.2)
|
|
5
|
+
qinium (~> 0.4.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
+
actionpack (8.1.3)
|
|
11
|
+
actionview (= 8.1.3)
|
|
12
|
+
activesupport (= 8.1.3)
|
|
13
|
+
nokogiri (>= 1.8.5)
|
|
14
|
+
rack (>= 2.2.4)
|
|
15
|
+
rack-session (>= 1.0.1)
|
|
16
|
+
rack-test (>= 0.6.3)
|
|
17
|
+
rails-dom-testing (~> 2.2)
|
|
18
|
+
rails-html-sanitizer (~> 1.6)
|
|
19
|
+
useragent (~> 0.16)
|
|
20
|
+
actionview (8.1.3)
|
|
21
|
+
activesupport (= 8.1.3)
|
|
22
|
+
builder (~> 3.1)
|
|
23
|
+
erubi (~> 1.11)
|
|
24
|
+
rails-dom-testing (~> 2.2)
|
|
25
|
+
rails-html-sanitizer (~> 1.6)
|
|
26
|
+
activejob (8.1.3)
|
|
27
|
+
activesupport (= 8.1.3)
|
|
28
|
+
globalid (>= 0.3.6)
|
|
29
|
+
activemodel (8.1.3)
|
|
30
|
+
activesupport (= 8.1.3)
|
|
31
|
+
activerecord (8.1.3)
|
|
32
|
+
activemodel (= 8.1.3)
|
|
33
|
+
activesupport (= 8.1.3)
|
|
34
|
+
timeout (>= 0.4.0)
|
|
35
|
+
activestorage (8.1.3)
|
|
36
|
+
actionpack (= 8.1.3)
|
|
37
|
+
activejob (= 8.1.3)
|
|
38
|
+
activerecord (= 8.1.3)
|
|
39
|
+
activesupport (= 8.1.3)
|
|
40
|
+
marcel (~> 1.0)
|
|
41
|
+
activesupport (8.1.3)
|
|
42
|
+
base64
|
|
43
|
+
bigdecimal
|
|
44
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
45
|
+
connection_pool (>= 2.2.5)
|
|
46
|
+
drb
|
|
47
|
+
i18n (>= 1.6, < 2)
|
|
48
|
+
json
|
|
49
|
+
logger (>= 1.4.2)
|
|
50
|
+
minitest (>= 5.1)
|
|
51
|
+
securerandom (>= 0.3)
|
|
52
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
53
|
+
uri (>= 0.13.1)
|
|
54
|
+
addressable (2.8.9)
|
|
55
|
+
public_suffix (>= 2.0.2, < 8.0)
|
|
10
56
|
ast (2.4.2)
|
|
57
|
+
base64 (0.3.0)
|
|
58
|
+
bigdecimal (4.1.0)
|
|
59
|
+
builder (3.3.0)
|
|
60
|
+
concurrent-ruby (1.3.6)
|
|
61
|
+
connection_pool (3.0.2)
|
|
62
|
+
crack (1.0.1)
|
|
63
|
+
bigdecimal
|
|
64
|
+
rexml
|
|
65
|
+
crass (1.0.6)
|
|
11
66
|
diff-lcs (1.5.0)
|
|
67
|
+
drb (2.2.3)
|
|
68
|
+
erubi (1.13.1)
|
|
69
|
+
globalid (1.3.0)
|
|
70
|
+
activesupport (>= 6.1)
|
|
71
|
+
hashdiff (1.2.1)
|
|
72
|
+
i18n (1.14.8)
|
|
73
|
+
concurrent-ruby (~> 1.0)
|
|
74
|
+
json (2.19.3)
|
|
75
|
+
logger (1.7.0)
|
|
76
|
+
loofah (2.25.1)
|
|
77
|
+
crass (~> 1.0.2)
|
|
78
|
+
nokogiri (>= 1.12.0)
|
|
79
|
+
marcel (1.1.0)
|
|
80
|
+
mini_portile2 (2.8.9)
|
|
81
|
+
minitest (6.0.3)
|
|
82
|
+
drb (~> 2.0)
|
|
83
|
+
prism (~> 1.5)
|
|
84
|
+
nokogiri (1.19.2)
|
|
85
|
+
mini_portile2 (~> 2.8.2)
|
|
86
|
+
racc (~> 1.4)
|
|
12
87
|
parallel (1.22.1)
|
|
13
88
|
parser (3.1.1.0)
|
|
14
89
|
ast (~> 2.4.1)
|
|
15
|
-
|
|
90
|
+
prism (1.9.0)
|
|
91
|
+
public_suffix (7.0.2)
|
|
92
|
+
qinium (0.4.0)
|
|
93
|
+
racc (1.8.1)
|
|
94
|
+
rack (3.2.6)
|
|
95
|
+
rack-session (2.1.1)
|
|
96
|
+
base64 (>= 0.1.0)
|
|
97
|
+
rack (>= 3.0.0)
|
|
98
|
+
rack-test (2.2.0)
|
|
99
|
+
rack (>= 1.3)
|
|
100
|
+
rails-dom-testing (2.3.0)
|
|
101
|
+
activesupport (>= 5.0.0)
|
|
102
|
+
minitest
|
|
103
|
+
nokogiri (>= 1.6)
|
|
104
|
+
rails-html-sanitizer (1.7.0)
|
|
105
|
+
loofah (~> 2.25)
|
|
106
|
+
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
|
16
107
|
rainbow (3.1.1)
|
|
17
108
|
rake (13.0.6)
|
|
18
109
|
regexp_parser (2.5.0)
|
|
@@ -42,16 +133,28 @@ GEM
|
|
|
42
133
|
rubocop-ast (1.17.0)
|
|
43
134
|
parser (>= 3.1.1.0)
|
|
44
135
|
ruby-progressbar (1.11.0)
|
|
136
|
+
securerandom (0.4.1)
|
|
137
|
+
timeout (0.6.1)
|
|
138
|
+
tzinfo (2.0.6)
|
|
139
|
+
concurrent-ruby (~> 1.0)
|
|
45
140
|
unicode-display_width (2.1.0)
|
|
141
|
+
uri (1.1.1)
|
|
142
|
+
useragent (0.16.11)
|
|
143
|
+
webmock (3.26.1)
|
|
144
|
+
addressable (>= 2.8.0)
|
|
145
|
+
crack (>= 0.3.2)
|
|
146
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
|
46
147
|
|
|
47
148
|
PLATFORMS
|
|
48
149
|
ruby
|
|
49
150
|
|
|
50
151
|
DEPENDENCIES
|
|
152
|
+
activestorage (>= 6.1)
|
|
51
153
|
activestorage_qinium!
|
|
52
154
|
rake (~> 13.0)
|
|
53
155
|
rspec (~> 3.0)
|
|
54
156
|
rubocop (~> 1.21)
|
|
157
|
+
webmock (~> 3.0)
|
|
55
158
|
|
|
56
159
|
BUNDLED WITH
|
|
57
160
|
2.3.9
|
data/README.md
CHANGED
|
@@ -1,33 +1,202 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ActiveStorage Qinium
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/activestorage_qinium)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Active Storage 的七牛云存储服务扩展,支持多租户配置和图片分析器。
|
|
7
|
+
|
|
8
|
+
## 功能特性
|
|
9
|
+
|
|
10
|
+
- **完整 Active Storage 支持**:实现所有必需的服务方法(upload、download、delete、url 等)
|
|
11
|
+
- **分块上传**:支持大文件分块上传,断点续传
|
|
12
|
+
- **公有/私有空间**:支持七牛云公有和私有 bucket 配置
|
|
13
|
+
- **自定义图片分析器**:利用七牛云 imageInfo API 获取图片元数据
|
|
14
|
+
- **直接上传**:支持浏览器直传七牛云,减轻服务器压力
|
|
15
|
+
- **URL 参数支持**:支持 disposition、content_type、fop 等参数自定义
|
|
16
|
+
- **多租户支持**:通过 qinium gem 实现灵活的多租户配置
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
添加到你的 Gemfile:
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
gem 'activestorage_qinium', '~> 0.4'
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
然后执行:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
$ bundle install
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 配置
|
|
33
|
+
|
|
34
|
+
### 基础配置
|
|
35
|
+
|
|
36
|
+
在 `config/storage.yml` 中配置七牛云存储:
|
|
37
|
+
|
|
38
|
+
```yaml
|
|
39
|
+
# 公有空间(适合图片、静态资源)
|
|
40
|
+
qiniu_public:
|
|
41
|
+
service: Qinium
|
|
42
|
+
public: true
|
|
43
|
+
bucket: your-public-bucket
|
|
44
|
+
domain: your-domain.clouddn.com
|
|
45
|
+
access_key: <%= ENV['QINIU_ACCESS_KEY'] %>
|
|
46
|
+
secret_key: <%= ENV['QINIU_SECRET_KEY'] %>
|
|
47
|
+
protocol: https
|
|
48
|
+
block_size: 4194304 # 可选,分块大小(字节),默认 4MB
|
|
49
|
+
expires_in: 3600 # 可选,私有 URL 过期时间(秒)
|
|
50
|
+
|
|
51
|
+
# 私有空间(适合敏感文件)
|
|
52
|
+
qiniu_private:
|
|
53
|
+
service: Qinium
|
|
54
|
+
public: false
|
|
55
|
+
bucket: your-private-bucket
|
|
56
|
+
domain: your-private-domain.clouddn.com
|
|
57
|
+
access_key: <%= ENV['QINIU_ACCESS_KEY'] %>
|
|
58
|
+
secret_key: <%= ENV['QINIU_SECRET_KEY'] %>
|
|
59
|
+
protocol: https
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 环境变量
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
export QINIU_ACCESS_KEY=your_access_key
|
|
66
|
+
export QINIU_SECRET_KEY=your_secret_key
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 多租户配置
|
|
70
|
+
|
|
71
|
+
通过 Qinium gem 的配置系统实现多租户:
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
# config/initializers/qinium.rb
|
|
75
|
+
Qinium.configure do |config|
|
|
76
|
+
config.tenant_settings = {
|
|
77
|
+
tenant_a: {
|
|
78
|
+
bucket: 'tenant-a-bucket',
|
|
79
|
+
access_key: ENV['TENANT_A_ACCESS_KEY'],
|
|
80
|
+
secret_key: ENV['TENANT_A_SECRET_KEY']
|
|
81
|
+
},
|
|
82
|
+
tenant_b: {
|
|
83
|
+
bucket: 'tenant-b-bucket',
|
|
84
|
+
access_key: ENV['TENANT_B_ACCESS_KEY'],
|
|
85
|
+
secret_key: ENV['TENANT_B_SECRET_KEY']
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 使用
|
|
92
|
+
|
|
93
|
+
### 基本使用
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
# 存储文件
|
|
97
|
+
user.avatar.attach(io: File.open('/path/to/avatar.jpg'), filename: 'avatar.jpg')
|
|
98
|
+
|
|
99
|
+
# 获取 URL
|
|
100
|
+
user.avatar.url # 内联显示
|
|
101
|
+
user.avatar.url(disposition: :attachment) # 下载附件
|
|
102
|
+
user.avatar.url(disposition: :attachment, filename: "自定义文件名.jpg")
|
|
103
|
+
|
|
104
|
+
# 图片处理(fop 参数)
|
|
105
|
+
user.avatar.url(fop: 'imageView2/0/w/200/h/200')
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 直接上传(浏览器直传)
|
|
109
|
+
|
|
110
|
+
```erb
|
|
111
|
+
<%= form_with model: @user, local: true do |form| %>
|
|
112
|
+
<%= form.file_field :avatar,
|
|
113
|
+
direct_upload: true,
|
|
114
|
+
data: {
|
|
115
|
+
direct_upload_url: rails_direct_uploads_url
|
|
116
|
+
} %>
|
|
117
|
+
<%= form.submit %>
|
|
118
|
+
<% end %>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### URL 参数详解
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
# 强制下载
|
|
125
|
+
blob.url(disposition: :attachment)
|
|
126
|
+
blob.url(disposition: :attachment, filename: "报告.pdf")
|
|
127
|
+
|
|
128
|
+
# 自定义响应头(仅公有资源支持)
|
|
129
|
+
blob.url(
|
|
130
|
+
response_content_type: "application/octet-stream",
|
|
131
|
+
response_cache_control: "max-age=3600",
|
|
132
|
+
response_content_disposition: "attachment; filename=doc.pdf"
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
# 下载限速(单位:bit/s,范围 819200 ~ 838860800)
|
|
136
|
+
blob.url(traffic_limit: 819200)
|
|
137
|
+
|
|
138
|
+
# 图片处理
|
|
139
|
+
blob.url(fop: 'imageInfo') # 图片信息
|
|
140
|
+
blob.url(fop: 'imageView2/2/w/200') # 缩略图
|
|
141
|
+
blob.url(fop: 'imageMogr2/rotate/90') # 旋转
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## 图片分析器
|
|
145
|
+
|
|
146
|
+
QiniumImageAnalyzer 利用七牛云 imageInfo API 获取图片元数据:
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
# 自动注册的分析器
|
|
150
|
+
ActiveStorage::Service::QiniumService.analyzers
|
|
151
|
+
# => [ActiveStorage::Analyzer::QiniumImageAnalyzer]
|
|
152
|
+
|
|
153
|
+
# 获取图片元数据
|
|
154
|
+
blob.metadata
|
|
155
|
+
# => {
|
|
156
|
+
# size: 39504,
|
|
157
|
+
# format: "jpg",
|
|
158
|
+
# width: 708,
|
|
159
|
+
# height: 576,
|
|
160
|
+
# colorModel: "ycbcr"
|
|
161
|
+
# }
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## 支持的 Active Storage 版本
|
|
165
|
+
|
|
166
|
+
| Gem 版本 | Active Storage 版本 |
|
|
167
|
+
|---------|-------------------|
|
|
168
|
+
| 0.4.x | >= 6.1 |
|
|
169
|
+
|
|
170
|
+
## 开发
|
|
171
|
+
|
|
172
|
+
克隆仓库后运行测试:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
$ bundle install
|
|
176
|
+
$ bundle exec rspec
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
运行特定测试:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
$ bundle exec rspec spec/active_storage/service/qinium_service_url_spec.rb
|
|
183
|
+
$ bundle exec rspec spec/active_storage/service/qinium_service_spec.rb
|
|
184
|
+
```
|
|
2
185
|
|
|
3
|
-
|
|
186
|
+
## 贡献
|
|
4
187
|
|
|
5
|
-
|
|
188
|
+
1. Fork 项目
|
|
189
|
+
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
|
|
190
|
+
3. 提交更改 (`git commit -m 'Add some amazing feature'`)
|
|
191
|
+
4. 推送到分支 (`git push origin feature/amazing-feature`)
|
|
192
|
+
5. 创建 Pull Request
|
|
6
193
|
|
|
7
|
-
##
|
|
194
|
+
## 许可证
|
|
195
|
+
|
|
196
|
+
[MIT 许可证](https://opensource.org/licenses/MIT)
|
|
8
197
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
$ gem install activestorage_qinium
|
|
16
|
-
|
|
17
|
-
## Usage
|
|
18
|
-
|
|
19
|
-
TODO: Write usage instructions here
|
|
20
|
-
|
|
21
|
-
## Development
|
|
22
|
-
|
|
23
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
24
|
-
|
|
25
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
26
|
-
|
|
27
|
-
## Contributing
|
|
28
|
-
|
|
29
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/activestorage_qinium.
|
|
30
|
-
|
|
31
|
-
## License
|
|
32
|
-
|
|
33
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
198
|
+
## 相关项目
|
|
199
|
+
|
|
200
|
+
- [qinium](https://github.com/xiaohui-zhangxh/qinium) - 底层七牛云 SDK
|
|
201
|
+
- [Active Storage](https://edgeguides.rubyonrails.org/active_storage_overview.html) - Rails 官方文档
|
|
202
|
+
- [七牛云文档](https://developer.qiniu.com/kodo) - 七牛云开发者中心
|
|
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.authors = ["xiaohui"]
|
|
9
9
|
spec.email = ["xiaohui@tanmer.com"]
|
|
10
10
|
|
|
11
|
-
spec.summary = "A
|
|
12
|
-
spec.description = "Wraps the Qiniu Storage Service as an Active Storage service, support
|
|
11
|
+
spec.summary = "A multi-tenant SDK wrap the Qiniu Storage Service as an Active Storage service"
|
|
12
|
+
spec.description = "Wraps the Qiniu Storage Service as an Active Storage service, support multi-tenant settings. https://www.qiniu.com"
|
|
13
13
|
spec.homepage = "https://github.com/xiaohui-zhangxh/activestorage_qinium"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
spec.required_ruby_version = ">= 2.6.0"
|
|
@@ -17,6 +17,7 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
|
18
18
|
spec.metadata["source_code_uri"] = spec.homepage
|
|
19
19
|
spec.metadata["changelog_uri"] = "#{spec.homepage}/CHANGELOG.md"
|
|
20
|
+
spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
|
|
20
21
|
|
|
21
22
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
22
23
|
`git ls-files -z`.split("\x0").reject do |f|
|
|
@@ -27,4 +28,8 @@ Gem::Specification.new do |spec|
|
|
|
27
28
|
spec.require_paths = ["lib"]
|
|
28
29
|
|
|
29
30
|
spec.add_dependency "qinium", "~> 0.4.0"
|
|
31
|
+
|
|
32
|
+
spec.add_development_dependency "activestorage", ">= 6.1"
|
|
33
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
|
34
|
+
spec.add_development_dependency "webmock", "~> 3.0"
|
|
30
35
|
end
|
|
@@ -10,7 +10,7 @@ module ActiveStorage
|
|
|
10
10
|
to: :config
|
|
11
11
|
|
|
12
12
|
def self.analyzers
|
|
13
|
-
[ActiveStorage::Analyzer::QiniumImageAnalyzer]
|
|
13
|
+
@analyzers ||= [ActiveStorage::Analyzer::QiniumImageAnalyzer]
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def initialize(options)
|
|
@@ -117,7 +117,8 @@ module ActiveStorage
|
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
def copy(source_bucket, source_key, target_bucket, target_key)
|
|
120
|
-
instrument :fetch, source_bucket: source_bucket, source_key: source_key, target_bucket: target_bucket,
|
|
120
|
+
instrument :fetch, source_bucket: source_bucket, source_key: source_key, target_bucket: target_bucket,
|
|
121
|
+
target_key: target_key do
|
|
121
122
|
qiniu.object.copy(source_bucket, source_key, target_bucket, target_key)
|
|
122
123
|
end
|
|
123
124
|
end
|
|
@@ -132,20 +133,84 @@ module ActiveStorage
|
|
|
132
133
|
|
|
133
134
|
def url(key, **options)
|
|
134
135
|
instrument :url, key: key do |payload|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
# 根据七牛云文档:https://developer.qiniu.com/kodo/1659/download-setting
|
|
137
|
+
# 1. 使用 attname 参数可以让浏览器下载而不是打开
|
|
138
|
+
# 2. 使用 response-content-disposition 参数可以自定义 Content-Disposition 响应头
|
|
139
|
+
# 3. 使用 response-content-type 参数可以自定义 Content-Type 响应头
|
|
140
|
+
# 4. 使用 response-cache-control 参数可以自定义 Cache-Control 响应头
|
|
141
|
+
# 5. 使用 response-content-encoding 参数可以自定义 Content-Encoding 响应头
|
|
142
|
+
# 6. 使用 response-content-language 参数可以自定义 Content-Language 响应头
|
|
143
|
+
# 7. 使用 response-expires 参数可以自定义 Expires 响应头
|
|
144
|
+
# 8. 使用 X-Qiniu-Traffic-Limit 参数可以限制下载速度
|
|
145
|
+
|
|
146
|
+
disposition = options[:disposition]
|
|
147
|
+
content_type = options[:content_type]
|
|
148
|
+
|
|
149
|
+
# 构建查询参数
|
|
150
|
+
query_params = []
|
|
151
|
+
|
|
152
|
+
# 内容预处理(图片处理、视频处理等)
|
|
153
|
+
query_params << options[:fop] if options[:fop].present?
|
|
154
|
+
|
|
155
|
+
# 处理 disposition 相关参数
|
|
156
|
+
if disposition.to_s == "attachment" # 下载附件
|
|
157
|
+
# attname:触发「下载」行为;部分节点仍用对象 key 填 Content-Disposition,须同时传 response-content-disposition。
|
|
158
|
+
# 文档:https://developer.qiniu.com/kodo/1659/download-setting
|
|
159
|
+
display_name = (options[:filename].presence || File.basename(key)).to_s
|
|
160
|
+
query_params << "attname=#{URI.encode_www_form_component(display_name)}"
|
|
161
|
+
cd = ActionDispatch::Http::ContentDisposition.format(
|
|
162
|
+
disposition: "attachment",
|
|
163
|
+
filename: ActiveStorage::Filename.new(display_name).sanitized
|
|
164
|
+
)
|
|
165
|
+
query_params << "response-content-disposition=#{ERB::Util.url_encode(cd)}"
|
|
166
|
+
# elsif disposition.to_s == "inline" # 预览(inline)
|
|
167
|
+
# # 明确设置 Content-Disposition 为 inline,确保浏览器预览而不是下载
|
|
168
|
+
# query_params << "response-content-disposition=inline"
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# 自定义响应头参数
|
|
172
|
+
# 注意:这些参数只有请求成功(即返回码为 200 OK)才会生效
|
|
173
|
+
# 且不支持在匿名访问的下载请求中自定义标准响应头
|
|
174
|
+
if options[:response_content_type].present? || content_type.present?
|
|
175
|
+
value = options[:response_content_type] || content_type
|
|
176
|
+
query_params << "response-content-type=#{URI.encode_www_form_component(value)}"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
if options[:response_cache_control].present?
|
|
180
|
+
query_params << "response-cache-control=#{URI.encode_www_form_component(options[:response_cache_control])}"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
if options[:response_content_disposition].present?
|
|
184
|
+
query_params << "response-content-disposition=#{ERB::Util.url_encode(options[:response_content_disposition])}"
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
if options[:response_content_encoding].present?
|
|
188
|
+
query_params << "response-content-encoding=#{URI.encode_www_form_component(options[:response_content_encoding])}"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
if options[:response_content_language].present?
|
|
192
|
+
query_params << "response-content-language=#{URI.encode_www_form_component(options[:response_content_language])}"
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
if options[:response_expires].present?
|
|
196
|
+
query_params << "response-expires=#{URI.encode_www_form_component(options[:response_expires])}"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# 下载限速:X-Qiniu-Traffic-Limit
|
|
200
|
+
# 取值范围为 819200 ~ 838860800,单位为 bit/s
|
|
201
|
+
query_params << "X-Qiniu-Traffic-Limit=#{options[:traffic_limit].to_i}" if options[:traffic_limit].present?
|
|
141
202
|
|
|
203
|
+
# 构建 URL
|
|
142
204
|
url = if config.public
|
|
143
205
|
url_encoded_key = key.split("/").map { |x| CGI.escape(x) }.join("/")
|
|
144
|
-
|
|
206
|
+
base_url = "#{protocol}://#{domain}/#{url_encoded_key}"
|
|
207
|
+
query_params.any? ? "#{base_url}?#{query_params.join("&")}" : base_url
|
|
145
208
|
else
|
|
146
209
|
expires_in = options[:expires_in] ||
|
|
147
210
|
Rails.application.config.active_storage.service_urls_expire_in ||
|
|
148
211
|
3600
|
|
212
|
+
# 对于私有资源,需要将查询参数传递给授权 URL 生成
|
|
213
|
+
fop = query_params.join("&") if query_params.any?
|
|
149
214
|
Qinium::Auth.authorize_download_url(domain, key,
|
|
150
215
|
access_key, secret_key,
|
|
151
216
|
schema: protocol, fop: fop, expires_in: expires_in)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activestorage_qinium
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- xiaohui
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-04-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: qinium
|
|
@@ -24,8 +24,50 @@ dependencies:
|
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 0.4.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: activestorage
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '6.1'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '6.1'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: webmock
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '3.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.0'
|
|
27
69
|
description: Wraps the Qiniu Storage Service as an Active Storage service, support
|
|
28
|
-
|
|
70
|
+
multi-tenant settings. https://www.qiniu.com
|
|
29
71
|
email:
|
|
30
72
|
- xiaohui@tanmer.com
|
|
31
73
|
executables: []
|
|
@@ -54,6 +96,7 @@ metadata:
|
|
|
54
96
|
homepage_uri: https://github.com/xiaohui-zhangxh/activestorage_qinium
|
|
55
97
|
source_code_uri: https://github.com/xiaohui-zhangxh/activestorage_qinium
|
|
56
98
|
changelog_uri: https://github.com/xiaohui-zhangxh/activestorage_qinium/CHANGELOG.md
|
|
99
|
+
bug_tracker_uri: https://github.com/xiaohui-zhangxh/activestorage_qinium/issues
|
|
57
100
|
post_install_message:
|
|
58
101
|
rdoc_options: []
|
|
59
102
|
require_paths:
|
|
@@ -72,5 +115,5 @@ requirements: []
|
|
|
72
115
|
rubygems_version: 3.5.16
|
|
73
116
|
signing_key:
|
|
74
117
|
specification_version: 4
|
|
75
|
-
summary: A
|
|
118
|
+
summary: A multi-tenant SDK wrap the Qiniu Storage Service as an Active Storage service
|
|
76
119
|
test_files: []
|