qiniu_rails 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +165 -0
- data/README.md +39 -7
- data/lib/active_storage/analyzer/qiniu_image_analyzer.rb +14 -0
- data/lib/active_storage/analyzer/qiniu_video_analyzer.rb +46 -0
- data/lib/active_storage/service/qiniu_service.rb +84 -6
- data/lib/assets/javascripts/qiniu_direct_upload.js +31 -0
- data/lib/qiniu_rails.rb +9 -0
- data/lib/qiniu_rails/engine.rb +21 -0
- data/lib/qiniu_rails/qiniu_common.rb +0 -1
- data/lib/qiniu_rails/qiniu_helper.rb +1 -1
- data/lib/qiniu_rails/sprockets.rb +14 -0
- data/lib/qiniu_rails/sprockets/qiniu_exporter.rb +21 -0
- data/lib/qiniu_rails/sprockets/qiniu_non_digest_assets.rb +31 -0
- data/lib/qiniu_rails/variant.rb +18 -0
- data/lib/qiniu_rails/version.rb +1 -1
- metadata +33 -11
- data/MIT-LICENSE +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 699a3030b08ab1cb791159418bfb390fd4a3a041a554331c57c4d89fd9b16eb0
|
4
|
+
data.tar.gz: 243a8bad83670aceb3ee7ba963311d834bf09c373c77e91127aab08d7b37c14b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f57cfb3f363426e8c7047bb0389827df7b61bec91bd690c29294bdb606f445bf1d183570c346afcbe0ecfb011ffccced37e1ed41126cedfb4a5877bfca53c34
|
7
|
+
data.tar.gz: f30f5daa0aca5b8c594baddfa1f94e490a08aa5729c3f1ff7263152534120ca3e3fc0d99083c402219d8bf2d0beef6b55a026baa56ddd16e7a395a156c10fb76
|
data/LICENSE
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
GNU LESSER GENERAL PUBLIC LICENSE
|
2
|
+
Version 3, 29 June 2007
|
3
|
+
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
6
|
+
of this license document, but changing it is not allowed.
|
7
|
+
|
8
|
+
|
9
|
+
This version of the GNU Lesser General Public License incorporates
|
10
|
+
the terms and conditions of version 3 of the GNU General Public
|
11
|
+
License, supplemented by the additional permissions listed below.
|
12
|
+
|
13
|
+
0. Additional Definitions.
|
14
|
+
|
15
|
+
As used herein, "this License" refers to version 3 of the GNU Lesser
|
16
|
+
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
17
|
+
General Public License.
|
18
|
+
|
19
|
+
"The Library" refers to a covered work governed by this License,
|
20
|
+
other than an Application or a Combined Work as defined below.
|
21
|
+
|
22
|
+
An "Application" is any work that makes use of an interface provided
|
23
|
+
by the Library, but which is not otherwise based on the Library.
|
24
|
+
Defining a subclass of a class defined by the Library is deemed a mode
|
25
|
+
of using an interface provided by the Library.
|
26
|
+
|
27
|
+
A "Combined Work" is a work produced by combining or linking an
|
28
|
+
Application with the Library. The particular version of the Library
|
29
|
+
with which the Combined Work was made is also called the "Linked
|
30
|
+
Version".
|
31
|
+
|
32
|
+
The "Minimal Corresponding Source" for a Combined Work means the
|
33
|
+
Corresponding Source for the Combined Work, excluding any source code
|
34
|
+
for portions of the Combined Work that, considered in isolation, are
|
35
|
+
based on the Application, and not on the Linked Version.
|
36
|
+
|
37
|
+
The "Corresponding Application Code" for a Combined Work means the
|
38
|
+
object code and/or source code for the Application, including any data
|
39
|
+
and utility programs needed for reproducing the Combined Work from the
|
40
|
+
Application, but excluding the System Libraries of the Combined Work.
|
41
|
+
|
42
|
+
1. Exception to Section 3 of the GNU GPL.
|
43
|
+
|
44
|
+
You may convey a covered work under sections 3 and 4 of this License
|
45
|
+
without being bound by section 3 of the GNU GPL.
|
46
|
+
|
47
|
+
2. Conveying Modified Versions.
|
48
|
+
|
49
|
+
If you modify a copy of the Library, and, in your modifications, a
|
50
|
+
facility refers to a function or data to be supplied by an Application
|
51
|
+
that uses the facility (other than as an argument passed when the
|
52
|
+
facility is invoked), then you may convey a copy of the modified
|
53
|
+
version:
|
54
|
+
|
55
|
+
a) under this License, provided that you make a good faith effort to
|
56
|
+
ensure that, in the event an Application does not supply the
|
57
|
+
function or data, the facility still operates, and performs
|
58
|
+
whatever part of its purpose remains meaningful, or
|
59
|
+
|
60
|
+
b) under the GNU GPL, with none of the additional permissions of
|
61
|
+
this License applicable to that copy.
|
62
|
+
|
63
|
+
3. Object Code Incorporating Material from Library Header Files.
|
64
|
+
|
65
|
+
The object code form of an Application may incorporate material from
|
66
|
+
a header file that is part of the Library. You may convey such object
|
67
|
+
code under terms of your choice, provided that, if the incorporated
|
68
|
+
material is not limited to numerical parameters, data structure
|
69
|
+
layouts and accessors, or small macros, inline functions and templates
|
70
|
+
(ten or fewer lines in length), you do both of the following:
|
71
|
+
|
72
|
+
a) Give prominent notice with each copy of the object code that the
|
73
|
+
Library is used in it and that the Library and its use are
|
74
|
+
covered by this License.
|
75
|
+
|
76
|
+
b) Accompany the object code with a copy of the GNU GPL and this license
|
77
|
+
document.
|
78
|
+
|
79
|
+
4. Combined Works.
|
80
|
+
|
81
|
+
You may convey a Combined Work under terms of your choice that,
|
82
|
+
taken together, effectively do not restrict modification of the
|
83
|
+
portions of the Library contained in the Combined Work and reverse
|
84
|
+
engineering for debugging such modifications, if you also do each of
|
85
|
+
the following:
|
86
|
+
|
87
|
+
a) Give prominent notice with each copy of the Combined Work that
|
88
|
+
the Library is used in it and that the Library and its use are
|
89
|
+
covered by this License.
|
90
|
+
|
91
|
+
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
92
|
+
document.
|
93
|
+
|
94
|
+
c) For a Combined Work that displays copyright notices during
|
95
|
+
execution, include the copyright notice for the Library among
|
96
|
+
these notices, as well as a reference directing the user to the
|
97
|
+
copies of the GNU GPL and this license document.
|
98
|
+
|
99
|
+
d) Do one of the following:
|
100
|
+
|
101
|
+
0) Convey the Minimal Corresponding Source under the terms of this
|
102
|
+
License, and the Corresponding Application Code in a form
|
103
|
+
suitable for, and under terms that permit, the user to
|
104
|
+
recombine or relink the Application with a modified version of
|
105
|
+
the Linked Version to produce a modified Combined Work, in the
|
106
|
+
manner specified by section 6 of the GNU GPL for conveying
|
107
|
+
Corresponding Source.
|
108
|
+
|
109
|
+
1) Use a suitable shared library mechanism for linking with the
|
110
|
+
Library. A suitable mechanism is one that (a) uses at run time
|
111
|
+
a copy of the Library already present on the user's computer
|
112
|
+
system, and (b) will operate properly with a modified version
|
113
|
+
of the Library that is interface-compatible with the Linked
|
114
|
+
Version.
|
115
|
+
|
116
|
+
e) Provide Installation Information, but only if you would otherwise
|
117
|
+
be required to provide such information under section 6 of the
|
118
|
+
GNU GPL, and only to the extent that such information is
|
119
|
+
necessary to install and execute a modified version of the
|
120
|
+
Combined Work produced by recombining or relinking the
|
121
|
+
Application with a modified version of the Linked Version. (If
|
122
|
+
you use option 4d0, the Installation Information must accompany
|
123
|
+
the Minimal Corresponding Source and Corresponding Application
|
124
|
+
Code. If you use option 4d1, you must provide the Installation
|
125
|
+
Information in the manner specified by section 6 of the GNU GPL
|
126
|
+
for conveying Corresponding Source.)
|
127
|
+
|
128
|
+
5. Combined Libraries.
|
129
|
+
|
130
|
+
You may place library facilities that are a work based on the
|
131
|
+
Library side by side in a single library together with other library
|
132
|
+
facilities that are not Applications and are not covered by this
|
133
|
+
License, and convey such a combined library under terms of your
|
134
|
+
choice, if you do both of the following:
|
135
|
+
|
136
|
+
a) Accompany the combined library with a copy of the same work based
|
137
|
+
on the Library, uncombined with any other library facilities,
|
138
|
+
conveyed under the terms of this License.
|
139
|
+
|
140
|
+
b) Give prominent notice with the combined library that part of it
|
141
|
+
is a work based on the Library, and explaining where to find the
|
142
|
+
accompanying uncombined form of the same work.
|
143
|
+
|
144
|
+
6. Revised Versions of the GNU Lesser General Public License.
|
145
|
+
|
146
|
+
The Free Software Foundation may publish revised and/or new versions
|
147
|
+
of the GNU Lesser General Public License from time to time. Such new
|
148
|
+
versions will be similar in spirit to the present version, but may
|
149
|
+
differ in detail to address new problems or concerns.
|
150
|
+
|
151
|
+
Each version is given a distinguishing version number. If the
|
152
|
+
Library as you received it specifies that a certain numbered version
|
153
|
+
of the GNU Lesser General Public License "or any later version"
|
154
|
+
applies to it, you have the option of following the terms and
|
155
|
+
conditions either of that published version or of any later version
|
156
|
+
published by the Free Software Foundation. If the Library as you
|
157
|
+
received it does not specify a version number of the GNU Lesser
|
158
|
+
General Public License, you may choose any version of the GNU Lesser
|
159
|
+
General Public License ever published by the Free Software Foundation.
|
160
|
+
|
161
|
+
If the Library as you received it specifies that a proxy can decide
|
162
|
+
whether future versions of the GNU Lesser General Public License shall
|
163
|
+
apply, that proxy's public statement of acceptance of any version is
|
164
|
+
permanent authorization for you to choose that version for the
|
165
|
+
Library.
|
data/README.md
CHANGED
@@ -1,24 +1,49 @@
|
|
1
|
-
#
|
2
|
-
qiniu backend for
|
1
|
+
# Qiniu Rails
|
2
|
+
qiniu backend for activestorage and more
|
3
3
|
|
4
|
+
## Features
|
5
|
+
* Qiniu backend for activestorage;
|
6
|
+
* QiniuHelper for simple independent use;
|
7
|
+
* Qiniu extends for sprockets
|
4
8
|
|
5
|
-
##
|
6
|
-
|
9
|
+
## Config
|
7
10
|
|
8
11
|
```yaml
|
12
|
+
# config/qiniu.yml
|
13
|
+
default: &default
|
14
|
+
host: http://examples.com/
|
15
|
+
bucket:
|
16
|
+
access_key:
|
17
|
+
secret_key:
|
18
|
+
|
19
|
+
development:
|
20
|
+
<<: *default
|
21
|
+
|
22
|
+
staging:
|
23
|
+
<<: *default
|
24
|
+
|
25
|
+
test:
|
26
|
+
<<: *default
|
27
|
+
|
28
|
+
production:
|
29
|
+
<<: *default
|
30
|
+
host: http://assets.yigexiangfa.com/
|
31
|
+
bucket: example
|
32
|
+
|
33
|
+
# config/storage.yml
|
9
34
|
qiniu:
|
10
35
|
service: Qiniu
|
11
36
|
host: xxxx.com1.z0.glb.clouddn.com
|
12
37
|
access_key: iX6NuM1xN04Wdh-DogI0F3jLVpc-A4CsTHETssss
|
13
38
|
secret_key: aN44R3yzJFaeswbyM4Y8YaJvnkmsssssssss
|
14
|
-
bucket: xxxx
|
39
|
+
bucket: xxxx
|
15
40
|
```
|
16
41
|
|
17
42
|
## Installation
|
18
43
|
Add this line to your application's Gemfile:
|
19
44
|
|
20
45
|
```ruby
|
21
|
-
gem '
|
46
|
+
gem 'qiniu_rails'
|
22
47
|
```
|
23
48
|
|
24
49
|
And then execute:
|
@@ -28,9 +53,16 @@ $ bundle
|
|
28
53
|
|
29
54
|
Or install it yourself as:
|
30
55
|
```bash
|
31
|
-
$ gem install
|
56
|
+
$ gem install qiniu_rails
|
32
57
|
```
|
33
58
|
|
59
|
+
## Direct Upload
|
60
|
+
* dependent on JS http client sdk `axios`, please add it to your rails project first;
|
61
|
+
* then `require qiniu_direct_upload` in js file where you used qiniu direct upload;
|
62
|
+
|
63
|
+
## Assets Sync(Sprockets) support
|
64
|
+
* add `Sprockets.sync = 'qiniu'` to your initializers file
|
65
|
+
|
34
66
|
## Contributing
|
35
67
|
Contribution directions go here.
|
36
68
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ActiveStorage
|
2
|
+
class Analyzer
|
3
|
+
class QiniuImageAnalyzer < ImageAnalyzer
|
4
|
+
|
5
|
+
def metadata
|
6
|
+
code, result, res = Qiniu::HTTP.api_get(blob.service.url(blob.key, fop: 'imageInfo'))
|
7
|
+
result.symbolize_keys
|
8
|
+
rescue
|
9
|
+
{}
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ActiveStorage
|
2
|
+
class Analyzer
|
3
|
+
class QiniuVideoAnalyzer < VideoAnalyzer
|
4
|
+
|
5
|
+
def metadata
|
6
|
+
{
|
7
|
+
width: width,
|
8
|
+
height: height,
|
9
|
+
duration: duration,
|
10
|
+
aspect_ratio: aspect_ratio
|
11
|
+
}.compact
|
12
|
+
rescue
|
13
|
+
{}
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def width
|
19
|
+
video_stream['width']
|
20
|
+
end
|
21
|
+
|
22
|
+
def height
|
23
|
+
video_stream['height']
|
24
|
+
end
|
25
|
+
|
26
|
+
def duration
|
27
|
+
video_stream['duration']
|
28
|
+
end
|
29
|
+
|
30
|
+
def aspect_ratio
|
31
|
+
video_stream['display_aspect_ratio']
|
32
|
+
end
|
33
|
+
|
34
|
+
def streams
|
35
|
+
@streams ||= begin
|
36
|
+
code, result, res = Qiniu::HTTP.api_get(blob.service.url(blob.key, fop: 'avinfo'))
|
37
|
+
result['streams']
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def video_stream
|
42
|
+
@video_stream ||= streams.detect { |stream| stream['codec_type'] == 'video' } || {}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,17 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require '
|
2
|
+
require 'qiniu_rails/qiniu_common'
|
3
3
|
|
4
4
|
module ActiveStorage
|
5
5
|
# Wraps the Qiniu Cloud Storage as an Active Storage service. See ActiveStorage::Service for the generic API
|
6
6
|
# documentation that applies to all services.
|
7
7
|
class Service::QiniuService < Service
|
8
8
|
include QiniuCommon
|
9
|
-
attr_reader :client
|
9
|
+
attr_reader :client, :protocol
|
10
10
|
|
11
11
|
def initialize(host:, secret_key:, access_key:, bucket:, **options)
|
12
|
-
@client = Qiniu.establish_connection!(access_key: access_key, secret_key: secret_key)
|
13
12
|
@host = host
|
14
13
|
@bucket = bucket
|
14
|
+
@protocol = (options.delete(:protocol) || 'https').to_sym
|
15
|
+
@client = Qiniu.establish_connection!(
|
16
|
+
access_key: access_key,
|
17
|
+
secret_key: secret_key,
|
18
|
+
protocal: @protocal,
|
19
|
+
**options
|
20
|
+
)
|
15
21
|
end
|
16
22
|
|
17
23
|
def upload(key, io, checksum: nil, **options)
|
@@ -36,6 +42,12 @@ module ActiveStorage
|
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
45
|
+
def delete_prefixed(prefix)
|
46
|
+
instrument :delete_prefixed, prefix: prefix do
|
47
|
+
file_for(prefix).each { |item| delete item['key'] }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
39
51
|
def exist?(key)
|
40
52
|
instrument :exist, key: key do |payload|
|
41
53
|
answer = file_for(key)
|
@@ -43,14 +55,80 @@ module ActiveStorage
|
|
43
55
|
end
|
44
56
|
end
|
45
57
|
|
58
|
+
def download(key, &block)
|
59
|
+
if block_given?
|
60
|
+
instrument :streaming_download, key: key do
|
61
|
+
open(url(key, attname: key)) do |file|
|
62
|
+
while data = file.read(64.kilobytes)
|
63
|
+
yield data
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
else
|
68
|
+
instrument :download, key: key do
|
69
|
+
open(url(key, attname: key)).read
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def download_chunk(key, range)
|
75
|
+
instrument :download_chunk, key: key, range: range do
|
76
|
+
uri = URI(url(key, attname: key))
|
77
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |client|
|
78
|
+
client.get(uri, 'Range' => "bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}").body
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
46
83
|
def url(key, **options)
|
47
84
|
instrument :url, key: key do |payload|
|
48
|
-
|
85
|
+
if options[:filename].present?
|
86
|
+
options[:fop] ||= ''
|
87
|
+
options[:fop] = options[:fop] + '&' unless options[:fop].blank? || options[:fop].end_with?('&')
|
88
|
+
options[:fop] = options[:fop] + "attname=#{URI.escape(options[:filename].to_s)}"
|
89
|
+
end
|
90
|
+
url = Qiniu::Auth.authorize_download_url_2(host, key, fop: options[:fop], expires_in: options[:expires_in], schema: protocol)
|
91
|
+
payload[:url] = url
|
92
|
+
url
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
|
97
|
+
instrument :url, key: key do |payload|
|
98
|
+
url = Qiniu::Config.up_host(bucket) + "/mkblk/#{content_length}"
|
99
|
+
payload[:url] = url
|
100
|
+
url
|
49
101
|
end
|
50
102
|
end
|
51
103
|
|
52
|
-
def headers_for_direct_upload(key, content_type:,
|
53
|
-
|
104
|
+
def headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:)
|
105
|
+
uptoken = generate_uptoken(key)
|
106
|
+
_url = url(key, filename: filename)
|
107
|
+
{
|
108
|
+
'Content-Type' => 'application/octet-stream',
|
109
|
+
'Content-MD5' => checksum,
|
110
|
+
'Authorization' => "UpToken #{uptoken}",
|
111
|
+
'Up-Token' => uptoken,
|
112
|
+
'Content-Url' => _url
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def method_for_direct_upload
|
117
|
+
'POST'
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
# Reads the object for the given key in chunks, yielding each to the block.
|
122
|
+
def stream(key)
|
123
|
+
object = object_for(key)
|
124
|
+
|
125
|
+
chunk_size = 5.megabytes
|
126
|
+
offset = 0
|
127
|
+
|
128
|
+
while offset < object.content_length
|
129
|
+
yield object.get(range: "bytes=#{offset}-#{offset + chunk_size - 1}").body.read.force_encoding(Encoding::BINARY)
|
130
|
+
offset += chunk_size
|
131
|
+
end
|
54
132
|
end
|
55
133
|
|
56
134
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
//= require axios/dist/axios.min
|
2
|
+
addEventListener('direct-upload:before-blob-request', function(event){
|
3
|
+
var xhr = event.detail.xhr;
|
4
|
+
var file_size = event.detail.file.size;
|
5
|
+
xhr.addEventListener('load', function(event) {
|
6
|
+
var _headers = this.response.direct_upload.headers;
|
7
|
+
var key = this.response.key;
|
8
|
+
_headers['Content-Type'] = 'text/plain';
|
9
|
+
var url = 'http://up.qiniu.com/mkfile/' + file_size + '/key/' + btoa(key);
|
10
|
+
window.storage_options = {
|
11
|
+
url: url,
|
12
|
+
headers: _headers
|
13
|
+
};
|
14
|
+
});
|
15
|
+
});
|
16
|
+
|
17
|
+
addEventListener('direct-upload:before-storage-request', function(event){
|
18
|
+
var xhr = event.detail.xhr;
|
19
|
+
xhr.addEventListener('load', function(event) {
|
20
|
+
var options = window.storage_options;
|
21
|
+
var res = JSON.parse(this.response);
|
22
|
+
options.method = 'post';
|
23
|
+
options.data = res.ctx;
|
24
|
+
|
25
|
+
axios(options).then(function(response) {
|
26
|
+
console.log(response);
|
27
|
+
}).catch(function(ex) {
|
28
|
+
console.log(ex);
|
29
|
+
})
|
30
|
+
});
|
31
|
+
});
|
data/lib/qiniu_rails.rb
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
require 'active_storage/service/qiniu_service'
|
2
|
+
|
3
|
+
require 'active_storage/analyzer/qiniu_image_analyzer'
|
4
|
+
require 'active_storage/analyzer/qiniu_video_analyzer'
|
5
|
+
|
6
|
+
require 'qiniu_rails/sprockets'
|
7
|
+
require 'qiniu_rails/engine'
|
8
|
+
require 'qiniu_rails/variant'
|
9
|
+
|
2
10
|
autoload :QiniuHelper, 'qiniu_rails/qiniu_helper'
|
11
|
+
|
3
12
|
module QiniuRails
|
4
13
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module QiniuRails
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
|
4
|
+
initializer 'qiniu_rails.variant' do
|
5
|
+
require 'active_storage/variant'
|
6
|
+
if ActiveStorage::Blob.service.is_a?(ActiveStorage::Service::QiniuService)
|
7
|
+
ActiveStorage::Variant.prepend QiniuRails::Variant
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
initializer 'qiniu_rails.analyzers' do |app|
|
12
|
+
if ActiveStorage::Blob.service.is_a?(ActiveStorage::Service::QiniuService)
|
13
|
+
app.config.active_storage.analyzers = [
|
14
|
+
ActiveStorage::Analyzer::QiniuImageAnalyzer,
|
15
|
+
ActiveStorage::Analyzer::QiniuVideoAnalyzer
|
16
|
+
]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'qiniu_rails/sprockets/qiniu_exporter'
|
2
|
+
require 'qiniu_rails/sprockets/qiniu_non_digest_assets'
|
3
|
+
|
4
|
+
module Sprockets
|
5
|
+
|
6
|
+
def self.sync
|
7
|
+
config[:sync]
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.sync=(sync)
|
11
|
+
self.config = hash_reassoc(config, :sync) { sync.dup }
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'sprockets/exporters/base'
|
2
|
+
|
3
|
+
# Writes a an asset file to Qiniu
|
4
|
+
class QiniuExporter < Sprockets::Exporters::Base
|
5
|
+
|
6
|
+
def skip?(logger)
|
7
|
+
if Sprockets.config[:sync].to_s == 'qiniu'
|
8
|
+
logger.info "==> To Upload to Qiniu: #{ target }"
|
9
|
+
false
|
10
|
+
else
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
QiniuHelper.upload target, 'assets/' + asset.digest_path.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
Sprockets.register_exporter '*/*', QiniuExporter
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'sprockets/manifest'
|
2
|
+
|
3
|
+
module QiniuNonDigestAssets
|
4
|
+
|
5
|
+
def compile(*args)
|
6
|
+
super
|
7
|
+
|
8
|
+
environment.paths.find_all { |i| i.include? 'nondigest_assets' }.each do |src|
|
9
|
+
if Sprockets.config[:sync].to_s == 'qiniu'
|
10
|
+
f_src = src.to_s + '/**/*'
|
11
|
+
path_src = Pathname.new src
|
12
|
+
Dir.glob(f_src).select { |f| File.file?(f) }.each do |file|
|
13
|
+
key = Pathname.new(file).relative_path_from(path_src)
|
14
|
+
QiniuHelper.upload file, 'assets/' + key.to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def remove(filename)
|
21
|
+
super
|
22
|
+
|
23
|
+
if Sprockets.config[:sync].to_s == 'qiniu'
|
24
|
+
QiniuHelper.delete 'assets/' + filename.to_s
|
25
|
+
logger.info "--> Removed from Qiniu: #{ filename }"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
Sprockets::Manifest.send(:prepend, QiniuNonDigestAssets)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module QiniuRails::Variant
|
2
|
+
|
3
|
+
def key
|
4
|
+
"#{blob.key}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def mode_1
|
8
|
+
h, w = variation.transformations.fetch(:resize, '35x35').split('x')
|
9
|
+
"imageView2/1/w/#{w}/h/#{h}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def service_url(expires_in: service.url_expires_in, disposition: :inline)
|
13
|
+
service.url key, fop: mode_1, expires_in: expires_in, disposition: disposition, filename: filename, content_type: content_type
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
data/lib/qiniu_rails/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qiniu_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- qinmingyuan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: qiniu
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '6.9'
|
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
|
-
version:
|
26
|
+
version: '6.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.2'
|
27
41
|
description: Description of ActivestorageQiniu.
|
28
42
|
email:
|
29
43
|
- mingyuan0715@foxmail.com
|
@@ -31,18 +45,26 @@ executables: []
|
|
31
45
|
extensions: []
|
32
46
|
extra_rdoc_files: []
|
33
47
|
files:
|
34
|
-
-
|
48
|
+
- LICENSE
|
35
49
|
- README.md
|
36
50
|
- Rakefile
|
51
|
+
- lib/active_storage/analyzer/qiniu_image_analyzer.rb
|
52
|
+
- lib/active_storage/analyzer/qiniu_video_analyzer.rb
|
37
53
|
- lib/active_storage/service/qiniu_service.rb
|
54
|
+
- lib/assets/javascripts/qiniu_direct_upload.js
|
38
55
|
- lib/qiniu_rails.rb
|
56
|
+
- lib/qiniu_rails/engine.rb
|
39
57
|
- lib/qiniu_rails/qiniu_common.rb
|
40
58
|
- lib/qiniu_rails/qiniu_helper.rb
|
59
|
+
- lib/qiniu_rails/sprockets.rb
|
60
|
+
- lib/qiniu_rails/sprockets/qiniu_exporter.rb
|
61
|
+
- lib/qiniu_rails/sprockets/qiniu_non_digest_assets.rb
|
62
|
+
- lib/qiniu_rails/variant.rb
|
41
63
|
- lib/qiniu_rails/version.rb
|
42
64
|
- lib/tasks/activestorage_qiniu_tasks.rake
|
43
65
|
homepage: https://github.com/qinmingyuan/qiniu_rails
|
44
66
|
licenses:
|
45
|
-
-
|
67
|
+
- LGPL-3.0
|
46
68
|
metadata: {}
|
47
69
|
post_install_message:
|
48
70
|
rdoc_options: []
|
@@ -60,8 +82,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
82
|
version: '0'
|
61
83
|
requirements: []
|
62
84
|
rubyforge_project:
|
63
|
-
rubygems_version: 2.7.
|
85
|
+
rubygems_version: 2.7.7
|
64
86
|
signing_key:
|
65
87
|
specification_version: 4
|
66
|
-
summary: qiniu backend for
|
88
|
+
summary: qiniu backend for activestorage
|
67
89
|
test_files: []
|
data/MIT-LICENSE
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
Copyright 2017 qinmingyuan
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|