asset_id 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +36 -0
  3. data/lib/asset_id.rb +132 -0
  4. metadata +100 -0
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.textile ADDED
@@ -0,0 +1,36 @@
1
+ Asset ID
2
+
3
+ Only works with Rails 3 +
4
+
5
+ Uploads static assets to Amazon S3 with unique identifiers encoded into the path of the asset.
6
+
7
+ - Assets served from a cookie-less domain
8
+ - Unique identifier is not encoded into a query parameter (so it is cacheable by proxy servers)
9
+ - All assets have far-future expires headers for caching
10
+ - Assets have the Cache-Control: public header for caching
11
+ - CSS and javascript is GZipped
12
+
13
+ config/environments/production.rb
14
+
15
+ config.action_controller.asset_host = Proc.new do |source|
16
+ 'http://my_bucket.s3.amazonaws.com'
17
+ end
18
+ config.action_controller.asset_path = Proc.new do |source|
19
+ AssetID::S3.fingerprint(source)
20
+ end
21
+
22
+ lib/tasks/asset_id_tasks.rake
23
+
24
+ namespace :asset do
25
+ namespace :id do
26
+
27
+ desc "uploads the current assets to s3 with fingerprints"
28
+ task :upload do
29
+ AWS::S3::DEFAULT_HOST.replace "s3-eu-west-1.amazonaws.com"
30
+ AssetID::Base.asset_paths += ['favicon.png']
31
+ AssetID::S3.upload
32
+ end
33
+
34
+ end
35
+ end
36
+
data/lib/asset_id.rb ADDED
@@ -0,0 +1,132 @@
1
+ require 'digest/md5'
2
+ require 'mime/types'
3
+ require 'aws/s3'
4
+
5
+ module AssetID
6
+
7
+ class Base
8
+ DEFAULT_ASSET_PATHS = ['favicon.ico', 'images', 'javascripts', 'stylesheets']
9
+ @@asset_paths = DEFAULT_ASSET_PATHS
10
+
11
+ def self.path_prefix
12
+ File.join Rails.root, 'public'
13
+ end
14
+
15
+ def self.asset_paths=(paths)
16
+ @@asset_paths = paths
17
+ end
18
+
19
+ def self.asset_paths
20
+ @@asset_paths
21
+ end
22
+
23
+ def self.assets
24
+ a = []
25
+ asset_paths.each do |asset_path|
26
+ path = File.join path_prefix, asset_path
27
+ next unless File.exists? path
28
+ if File.directory? path
29
+ a += gather_assets_for(path)
30
+ else
31
+ a << path
32
+ end
33
+ end
34
+ a
35
+ end
36
+
37
+ def self.gather_assets_for(dir)
38
+ a = []
39
+ Dir.glob(File.join dir, '/*').each do |file|
40
+ if File.directory? file
41
+ a += gather_assets_for(file)
42
+ else
43
+ a << file
44
+ end
45
+ end
46
+ a
47
+ end
48
+
49
+ def self.fingerprint(path)
50
+ path = File.join path_prefix, path unless path =~ /#{path_prefix}/
51
+ #d = File.mtime(path).to_i.to_s
52
+ d = Digest::MD5.hexdigest(File.read(path))
53
+ path = path.gsub(path_prefix, '')
54
+ File.join File.dirname(path), "#{File.basename(path, File.extname(path))}-id-#{d}#{File.extname(path)}"
55
+ end
56
+
57
+ end
58
+
59
+ class S3 < AssetID::Base
60
+
61
+ DEFAULT_GZIP_TYPES = ['text/css', 'application/javascript']
62
+ @@gzip_types = DEFAULT_GZIP_TYPES
63
+
64
+ def self.gzip_types=(types)
65
+ @@gzip_types = types
66
+ end
67
+
68
+ def self.gzip_types
69
+ @@gzip_types
70
+ end
71
+
72
+ def self.s3_config
73
+ @@config ||= YAML.load_file(File.join(Rails.root, "config/asset_id.yml"))[Rails.env] rescue nil || {}
74
+ end
75
+
76
+ def self.connect_to_s3
77
+ AWS::S3::Base.establish_connection!(
78
+ :access_key_id => s3_config['access_key_id'],
79
+ :secret_access_key => s3_config['secret_access_key']
80
+ )
81
+ end
82
+
83
+ def self.cache_headers
84
+ {'Expires' => 1.year.from_now.httpdate, 'Cache-Control' => 'public'}
85
+ end
86
+
87
+ def self.gzip_headers
88
+ {'Content-Encoding' => 'gzip', 'Vary' => 'Accept-Encoding'}
89
+ end
90
+
91
+ def self.s3_permissions
92
+ :public_read
93
+ end
94
+
95
+ def self.s3_bucket
96
+ s3_config['bucket']
97
+ end
98
+
99
+ def self.fingerprint(path)
100
+ #File.join "/#{self.s3_bucket}", fingerprint(path)
101
+ super(path)
102
+ end
103
+
104
+ def self.upload(options={})
105
+ connect_to_s3
106
+ assets.each do |asset|
107
+ puts "Uploading #{asset} as #{fingerprint(asset)}"
108
+ mime_type = MIME::Types.of(asset).first
109
+
110
+ headers = {
111
+ :content_type => mime_type,
112
+ :access => s3_permissions,
113
+ }.merge(cache_headers)
114
+
115
+ if gzip_types.include? mime_type
116
+ data = `gzip -c #{asset}`
117
+ headers.merge!(gzip_headers)
118
+ else
119
+ data = File.read(asset)
120
+ end
121
+
122
+ AWS::S3::S3Object.store(
123
+ fingerprint(asset),
124
+ data,
125
+ s3_bucket,
126
+ headers
127
+ ) unless options[:dry_run]
128
+ end
129
+ end
130
+
131
+ end
132
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asset_id
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Richard Taylor
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-04 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: mime-types
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 47
30
+ segments:
31
+ - 1
32
+ - 16
33
+ version: "1.16"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: aws-s3
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ - 6
48
+ - 2
49
+ version: 0.6.2
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ description: asset_id is a library for uploading static assets to Amazon S3.
53
+ email: moomerman@gmail.com
54
+ executables: []
55
+
56
+ extensions: []
57
+
58
+ extra_rdoc_files: []
59
+
60
+ files:
61
+ - LICENSE
62
+ - README.textile
63
+ - lib/asset_id.rb
64
+ has_rdoc: true
65
+ homepage: http://github.com/moomerman/asset_id
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options:
70
+ - --inline-source
71
+ - --charset=UTF-8
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project: asset_id
95
+ rubygems_version: 1.3.7
96
+ signing_key:
97
+ specification_version: 2
98
+ summary: asset_id is a library for uploading static assets to Amazon S3.
99
+ test_files: []
100
+