asset_oss_rails4 0.3.1448447091
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +44 -0
- data/README_EN.textile +90 -0
- data/lib/asset_oss.rb +3 -0
- data/lib/asset_oss/asset.rb +168 -0
- data/lib/asset_oss/backend/oss.rb +87 -0
- data/lib/asset_oss/cache.rb +37 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 49c765dd6313c120f32a96e4a0b5984c097c64ff
|
4
|
+
data.tar.gz: f7e5c8cc7459a54595621ef84e2651039a566a1b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e746bfd498af8db083135a3345239d165ffc74f384c5947766eb9c0b5d62d10367cbaaa1e21bb9d608ecd7f58eae1ebc68bb2f234296e4f468c7e4feb5550f6c
|
7
|
+
data.tar.gz: 6517a3d315a6aa28e1264ee01ed5e465fa2941690958f5a1ce9f0e131efaceb9c17f3a413de3a2d7b2ab0764bb6edc4486910cac35465902257f75851f8b19f9
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) Richard Taylor
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
Asset OSS - 上传Rails项目静态文件到Aliyun OSS
|
2
|
+
===
|
3
|
+
|
4
|
+
关于
|
5
|
+
---
|
6
|
+
|
7
|
+
基于[asset_id](https://github.com/moocode/asset_id),[aset_sync](https://github.com/rumblelabs/asset_sync)也许是更好的选择
|
8
|
+
|
9
|
+
一个简单的上传Rails assets目录里静态文件到Aliyun OSS工具
|
10
|
+
|
11
|
+
使用和配置
|
12
|
+
---
|
13
|
+
|
14
|
+
添加`gem "asset_oss"`到你的Gemfile
|
15
|
+
|
16
|
+
修改`config/environments/production.rb`文件, `config.action_controller.asset_host = "http://my_live_bucket.oss.aliyuncs.com"`
|
17
|
+
|
18
|
+
新建一个`config/asset_oss.yml`文件
|
19
|
+
```
|
20
|
+
production:
|
21
|
+
host: 'oss.aliyuncs.com'
|
22
|
+
access_key_id: 'MY_ACCESS_KEY'
|
23
|
+
secret_access_key: 'MY_ACCESS_SECRET'
|
24
|
+
bucket: "my_live_bucket"
|
25
|
+
```
|
26
|
+
|
27
|
+
创建rake任务, `lib/tasks/asset_oss.rake`
|
28
|
+
```
|
29
|
+
namespace :asset do
|
30
|
+
namespace :oss do
|
31
|
+
|
32
|
+
desc "uploads the current assets to aliyun oss with stamped ids"
|
33
|
+
task :upload do
|
34
|
+
AssetOSS::Asset.asset_paths += ['assets'] # Configure additional asset paths
|
35
|
+
AssetOSS::OSS.upload
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
其它
|
43
|
+
---
|
44
|
+
也许可以通过修改Rails `config.assets.prefix`实现缓存过期,记得prefix要是assets开头,同时修改`AssetOSS::Asset.asset_paths`
|
data/README_EN.textile
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
h1. Asset OSS - Asset stamping and uploading to Aliyun OSS for Rails
|
2
|
+
|
3
|
+
h2. About
|
4
|
+
|
5
|
+
基于asset_id修改,aset_sync也许是更好的选择
|
6
|
+
|
7
|
+
Uploads static assets to Aliyun OSS with unique identifiers encoded into the path of the asset.
|
8
|
+
|
9
|
+
Only works with Rails 3.x because Rails 3 makes doing this sort of thing a lot easier and
|
10
|
+
that is all I needed it for.
|
11
|
+
|
12
|
+
This library takes standard Rails asset paths such as <code>/stylesheets/main.css?1288717704</code> and converts them
|
13
|
+
into <code>http://my_bucket.oss.aliyuncs.com/stylesheets/main-id-95df8d9bf5237ad08df3115ee74dcb10.css</code>.
|
14
|
+
|
15
|
+
It uses an MD5 hash of the file contents to produce the id so the same asset will always have the same ID.
|
16
|
+
|
17
|
+
In my quest to achieve a Google Page Speed score of 100, this library achieves the following:
|
18
|
+
|
19
|
+
* Assets served from a cookie-less domain
|
20
|
+
* Unique identifier is not encoded into a query parameter (so it is cacheable by proxy servers)
|
21
|
+
* All assets have far-future expires headers for caching
|
22
|
+
* Assets have the Cache-Control: public header for caching
|
23
|
+
* CSS and javascript is GZipped and the correct headers are added
|
24
|
+
|
25
|
+
As an added bonus, all your assets are available over <code>https://</code> as well.
|
26
|
+
|
27
|
+
h2. Usage
|
28
|
+
|
29
|
+
Add the gem to your <code>Gemfile</code>
|
30
|
+
|
31
|
+
<code>gem "asset_oss"</code>
|
32
|
+
|
33
|
+
Configure <code>config/environments/production.rb</code> to use Aliyun OSS as the asset host
|
34
|
+
and to use the id-stamped asset paths in helpers
|
35
|
+
|
36
|
+
<pre><code>config.action_controller.asset_host = Proc.new do |source|
|
37
|
+
'http://my_bucket.oss.aliyuncs.com'
|
38
|
+
end
|
39
|
+
config.action_controller.asset_path = Proc.new do |source|
|
40
|
+
AssetOSS::Asset.fingerprint(source)
|
41
|
+
end
|
42
|
+
</code></pre>
|
43
|
+
|
44
|
+
Add your Aliyun OSS configuration details to <code>config/asset_oss.yml</code>
|
45
|
+
|
46
|
+
<pre><code>production:
|
47
|
+
access_key_id: 'MY_ACCESS_KEY'
|
48
|
+
secret_access_key: 'MY_ACCESS_SECRET'
|
49
|
+
bucket: "my_live_bucket"
|
50
|
+
</code></pre>
|
51
|
+
|
52
|
+
Optionally create a rake task in <code>lib/tasks/asset_oss.rake</code> to
|
53
|
+
perform the upload for use in your deploy scripts
|
54
|
+
|
55
|
+
<pre><code>namespace :asset do
|
56
|
+
namespace :oss do
|
57
|
+
|
58
|
+
desc "uploads the current assets to aliyun oss with stamped ids"
|
59
|
+
task :upload do
|
60
|
+
Aliyun::OSS::DEFAULT_HOST.replace "oss-internal.aliyuncs.com"
|
61
|
+
AssetOSS::Asset.asset_paths += ['assets'] # Configure additional asset paths
|
62
|
+
AssetOSS::OSS.upload
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
</code></pre>
|
68
|
+
|
69
|
+
h2. SSL configuration
|
70
|
+
|
71
|
+
If you want to use the SSL host in your configuration you can do so in <code>config/environments/production.rb</code>
|
72
|
+
|
73
|
+
<pre><code>config.action_controller.asset_host = Proc.new do |source|
|
74
|
+
request.ssl? 'https://my_bucket.oss.aliyuncs.com' : 'http://my_bucket.oss.aliyuncs.com'
|
75
|
+
end
|
76
|
+
</code></pre>
|
77
|
+
|
78
|
+
h2. CSS Images
|
79
|
+
|
80
|
+
By default any relative CSS images that match files on the filesystem are converted to AssetOSS paths as well.
|
81
|
+
|
82
|
+
For aliyun oss, if you don't specify a <code>prefix</code> it will use the <code>http://</code> bucket URL by default. You can override this in <code>config/asset_oss.yml</code>. For example if you wanted to use the <code>https://</code> url:
|
83
|
+
|
84
|
+
<pre><code>production:
|
85
|
+
host: 'oss-internal.aliyuncs.com'
|
86
|
+
access_key_id: 'MY_ACCESS_KEY'
|
87
|
+
secret_access_key: 'MY_ACCESS_SECRET'
|
88
|
+
bucket: "my_live_bucket"
|
89
|
+
prefix: "https://my_bucket.oss.aliyuncs.com"
|
90
|
+
</code></pre>
|
data/lib/asset_oss.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'mime/types'
|
3
|
+
require 'time'
|
4
|
+
require 'zlib'
|
5
|
+
|
6
|
+
module AssetOSS
|
7
|
+
class Asset
|
8
|
+
|
9
|
+
DEFAULT_ASSET_PATHS = ['favicon.ico', 'images', 'javascripts', 'stylesheets']
|
10
|
+
@@asset_paths = DEFAULT_ASSET_PATHS
|
11
|
+
|
12
|
+
#DEFAULT_GZIP_TYPES = ['text/css', 'application/javascript']
|
13
|
+
DEFAULT_GZIP_TYPES = []
|
14
|
+
@@gzip_types = DEFAULT_GZIP_TYPES
|
15
|
+
|
16
|
+
@@debug = false
|
17
|
+
@@nocache = false
|
18
|
+
@@nofingerprint = false
|
19
|
+
|
20
|
+
def self.init(options)
|
21
|
+
@@debug = options[:debug] if options[:debug]
|
22
|
+
@@nocache = options[:nocache] if options[:nocache]
|
23
|
+
@@nofingerprint = options[:nofingerprint] if options[:nofingerprint]
|
24
|
+
@@nofingerprint ||= []
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.asset_paths
|
28
|
+
@@asset_paths
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.gzip_types
|
32
|
+
@@gzip_types
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.asset_paths=(paths)
|
36
|
+
@@asset_paths = paths
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.gzip_types=(types)
|
40
|
+
@@gzip_types = types
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.find(paths=Asset.asset_paths)
|
44
|
+
paths.inject([]) {|assets, path|
|
45
|
+
path = File.join Rails.root, 'public', path
|
46
|
+
a = Asset.new(path)
|
47
|
+
#TODO 暂时不上传gz文件,相好解决ie6 gzip的问题再说
|
48
|
+
assets << a if a.is_file? and !a.cache_hit? and !a.gz_file?
|
49
|
+
assets += Dir.glob(path+'/**/*').inject([]) {|m, file|
|
50
|
+
a = Asset.new(file); m << a if a.is_file? and !a.cache_hit? and !a.gz_file?; m
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.fingerprint(path)
|
56
|
+
asset = Asset.new(path)
|
57
|
+
hit = Cache.get(asset)
|
58
|
+
return hit[:fingerprint] if hit
|
59
|
+
return asset.fingerprint
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_reader :path
|
63
|
+
|
64
|
+
def initialize(path)
|
65
|
+
@path = path
|
66
|
+
@path = absolute_path
|
67
|
+
end
|
68
|
+
|
69
|
+
def path_prefix
|
70
|
+
File.join Rails.root, 'public'
|
71
|
+
end
|
72
|
+
|
73
|
+
def absolute_path
|
74
|
+
path =~ /#{path_prefix}/ ? path : File.join(path_prefix, path)
|
75
|
+
end
|
76
|
+
|
77
|
+
def relative_path
|
78
|
+
path.gsub(path_prefix, '')
|
79
|
+
end
|
80
|
+
|
81
|
+
def gzip_type?
|
82
|
+
Asset.gzip_types.include? mime_type
|
83
|
+
end
|
84
|
+
|
85
|
+
def data
|
86
|
+
@data ||= File.read(path)
|
87
|
+
end
|
88
|
+
|
89
|
+
def md5
|
90
|
+
@digest ||= Digest::MD5.hexdigest(data)
|
91
|
+
end
|
92
|
+
|
93
|
+
def fingerprint
|
94
|
+
p = relative_path
|
95
|
+
return p if relative_path =~ /^\/assets.*\//
|
96
|
+
File.join File.dirname(p), "#{File.basename(p, File.extname(p))}-id-#{md5}#{File.extname(p)}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def mime_type
|
100
|
+
MIME::Types.of(path).first.to_s
|
101
|
+
end
|
102
|
+
|
103
|
+
def css?
|
104
|
+
mime_type == 'text/css'
|
105
|
+
end
|
106
|
+
|
107
|
+
def replace_css_images!(options={})
|
108
|
+
options[:prefix] ||= ''
|
109
|
+
# adapted from https://github.com/blakink/asset_id
|
110
|
+
data.gsub! /url\((?:"([^"]*)"|'([^']*)'|([^)]*))\)/mi do |match|
|
111
|
+
begin
|
112
|
+
# $1 is the double quoted string, $2 is single quoted, $3 is no quotes
|
113
|
+
uri = ($1 || $2 || $3).to_s.strip
|
114
|
+
uri.gsub!(/^\.\.\//, '/')
|
115
|
+
|
116
|
+
# if the uri appears to begin with a protocol then the asset isn't on the local filesystem
|
117
|
+
if uri =~ /[a-z]+:\/\//i
|
118
|
+
"url(#{uri})"
|
119
|
+
else
|
120
|
+
asset = Asset.new(uri)
|
121
|
+
# TODO: Check the referenced asset is in the asset_paths
|
122
|
+
puts " - Changing CSS URI #{uri} to #{options[:prefix]}#{asset.fingerprint}" if @@debug
|
123
|
+
"url(#{options[:prefix]}#{asset.fingerprint})"
|
124
|
+
end
|
125
|
+
rescue Errno::ENOENT => e
|
126
|
+
puts " - Warning: #{uri} not found" if @@debug
|
127
|
+
"url(#{uri})"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def gzip!
|
133
|
+
# adapted from https://github.com/blakink/asset_id
|
134
|
+
@data = returning StringIO.open('', 'w') do |gz_data|
|
135
|
+
gz = Zlib::GzipWriter.new(gz_data, nil, nil)
|
136
|
+
gz.write(data)
|
137
|
+
gz.close
|
138
|
+
end.string
|
139
|
+
end
|
140
|
+
|
141
|
+
def expiry_date
|
142
|
+
@expiry_date ||= (Time.now + (60*60*24*365)).httpdate
|
143
|
+
end
|
144
|
+
|
145
|
+
def cache_headers
|
146
|
+
{'Expires' => expiry_date, 'Cache-Control' => 'public'} # 1 year expiry
|
147
|
+
end
|
148
|
+
|
149
|
+
def gzip_headers
|
150
|
+
{'Content-Encoding' => 'gzip', 'Vary' => 'Accept-Encoding'}
|
151
|
+
end
|
152
|
+
|
153
|
+
def is_file?
|
154
|
+
File.exists? absolute_path and !File.directory? absolute_path
|
155
|
+
end
|
156
|
+
|
157
|
+
def cache_hit?
|
158
|
+
return false if @@nocache or Cache.miss? self
|
159
|
+
puts "AssetOSS: #{relative_path} - Cache Hit"
|
160
|
+
return true
|
161
|
+
end
|
162
|
+
|
163
|
+
def gz_file?
|
164
|
+
path =~ /\.gz$/
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'aliyun/oss'
|
2
|
+
|
3
|
+
module AssetOSS
|
4
|
+
class OSS
|
5
|
+
|
6
|
+
def self.oss_config
|
7
|
+
@@config ||= YAML.load_file(File.join(Rails.root, "config/asset_oss.yml"))[Rails.env] rescue nil || {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.connect_to_oss
|
11
|
+
Aliyun::OSS::Base.establish_connection!(
|
12
|
+
:server => oss_config['host'] || Aliyun::OSS::DEFAULT_HOST,
|
13
|
+
:access_key_id => oss_config['access_key_id'],
|
14
|
+
:secret_access_key => oss_config['secret_access_key']
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.oss_permissions
|
19
|
+
:public_read
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.oss_bucket
|
23
|
+
oss_config['bucket']
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.oss_folder
|
27
|
+
oss_config['folder']
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.oss_prefix
|
31
|
+
oss_config['prefix'] || oss_bucket_url
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.oss_bucket_url
|
35
|
+
"http://#{oss_bucket}.oss.aliyuncs.com#{oss_folder ? "/#{oss_folder}" : '' }"
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.full_path(asset)
|
39
|
+
oss_folder ? "/#{oss_folder}#{asset.fingerprint}" : asset.fingerprint
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.upload(options={})
|
43
|
+
Asset.init(:debug => options[:debug], :nofingerprint => options[:nofingerprint])
|
44
|
+
|
45
|
+
assets = Asset.find
|
46
|
+
return if assets.empty?
|
47
|
+
|
48
|
+
connect_to_oss
|
49
|
+
|
50
|
+
Aliyun::OSS::Bucket.create(oss_bucket, :access => oss_permissions)
|
51
|
+
|
52
|
+
assets.each do |asset|
|
53
|
+
|
54
|
+
puts "AssetOSS: #{asset.relative_path}" if options[:debug]
|
55
|
+
|
56
|
+
headers = {
|
57
|
+
:content_type => asset.mime_type,
|
58
|
+
}.merge(asset.cache_headers)
|
59
|
+
|
60
|
+
asset.replace_css_images!(:prefix => oss_prefix) if asset.css?
|
61
|
+
|
62
|
+
if asset.gzip_type?
|
63
|
+
headers.merge!(asset.gzip_headers)
|
64
|
+
asset.gzip!
|
65
|
+
end
|
66
|
+
|
67
|
+
if options[:debug]
|
68
|
+
puts " - Uploading: #{full_path(asset)} [#{asset.data.size} bytes]"
|
69
|
+
puts " - Headers: #{headers.inspect}"
|
70
|
+
end
|
71
|
+
|
72
|
+
unless options[:dry_run]
|
73
|
+
res = Aliyun::OSS::OSSObject.store(
|
74
|
+
full_path(asset),
|
75
|
+
asset.data,
|
76
|
+
oss_bucket,
|
77
|
+
headers
|
78
|
+
)
|
79
|
+
puts " - Response: #{res.inspect}" if options[:debug]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
Cache.save! unless options[:dry_run]
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module AssetOSS
|
4
|
+
class Cache
|
5
|
+
|
6
|
+
def self.empty
|
7
|
+
@cache = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.cache
|
11
|
+
@cache ||= YAML.load_file(cache_path) rescue {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.cache_path
|
15
|
+
File.join(Rails.root, 'log', 'asset_oss_cache.yml')
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get(asset)
|
19
|
+
cache[asset.relative_path]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.hit?(asset)
|
23
|
+
return true if cache[asset.relative_path] and cache[asset.relative_path][:fingerprint] == asset.fingerprint
|
24
|
+
cache[asset.relative_path] = {:expires => asset.expiry_date.to_s, :fingerprint => asset.fingerprint}
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.miss?(asset)
|
29
|
+
!hit?(asset)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.save!
|
33
|
+
File.open(cache_path, 'w') {|f| f.write(YAML.dump(cache))}
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: asset_oss_rails4
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1448447091
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mangege
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-11-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mime-types
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: aliyun-oss-rails4
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: asset_oss is a library for uploading static assets to Aliyun OSS.
|
42
|
+
email: langyong135@gmail.com
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- LICENSE
|
48
|
+
- README.md
|
49
|
+
- README_EN.textile
|
50
|
+
- lib/asset_oss.rb
|
51
|
+
- lib/asset_oss/asset.rb
|
52
|
+
- lib/asset_oss/backend/oss.rb
|
53
|
+
- lib/asset_oss/cache.rb
|
54
|
+
homepage: http://github.com/mangege/asset_oss
|
55
|
+
licenses: []
|
56
|
+
metadata: {}
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options:
|
59
|
+
- "--inline-source"
|
60
|
+
- "--charset=UTF-8"
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.4.5.1
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: asset_oss is a library for uploading static assets to Aliyun OSS.
|
79
|
+
test_files: []
|