Class: AssetID::Asset

Inherits:
Object
  • Object
show all
Defined in:
lib/asset_id/asset.rb

Constant Summary collapse

DEFAULT_ASSET_PATHS =
['favicon.ico', 'images', 'javascripts', 'stylesheets']
DEFAULT_GZIP_TYPES =
['text/css', 'application/javascript']
@@asset_paths =
DEFAULT_ASSET_PATHS
@@gzip_types =
DEFAULT_GZIP_TYPES
@@debug =
false
@@nocache =
false

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Asset

Returns a new instance of Asset.



56
57
58
59
# File 'lib/asset_id/asset.rb', line 56

def initialize(path)
  @path = path
  @path = absolute_path
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



54
55
56
# File 'lib/asset_id/asset.rb', line 54

def path
  @path
end

Class Method Details

.asset_pathsObject



23
24
25
# File 'lib/asset_id/asset.rb', line 23

def self.asset_paths
  @@asset_paths
end

.asset_paths=(paths) ⇒ Object



31
32
33
# File 'lib/asset_id/asset.rb', line 31

def self.asset_paths=(paths)
  @@asset_paths = paths
end

.find(paths = Asset.asset_paths) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/asset_id/asset.rb', line 39

def self.find(paths=Asset.asset_paths)
  paths.inject([]) {|assets, path|
    path = File.join Rails.root, 'public', path
    a = Asset.new(path)
    assets << a if a.is_file? and !a.cache_hit?
    assets += Dir.glob(path+'/**/*').inject([]) {|m, file|
      a = Asset.new(file); m << a if a.is_file? and !a.cache_hit?; m 
    }
  }
end

.fingerprint(path) ⇒ Object



50
51
52
# File 'lib/asset_id/asset.rb', line 50

def self.fingerprint(path)
  Asset.new(path).fingerprint
end

.gzip_typesObject



27
28
29
# File 'lib/asset_id/asset.rb', line 27

def self.gzip_types
  @@gzip_types
end

.gzip_types=(types) ⇒ Object



35
36
37
# File 'lib/asset_id/asset.rb', line 35

def self.gzip_types=(types)
  @@gzip_types = types
end

.init(options) ⇒ Object



18
19
20
21
# File 'lib/asset_id/asset.rb', line 18

def self.init(options)
  @@debug = options[:debug] if options[:debug]
  @@nocache = options[:nocache] if options[:nocache]
end

Instance Method Details

#absolute_pathObject



65
66
67
# File 'lib/asset_id/asset.rb', line 65

def absolute_path
  path =~ /#{path_prefix}/ ? path : File.join(path_prefix, path)
end

#cache_headersObject



135
136
137
# File 'lib/asset_id/asset.rb', line 135

def cache_headers
  {'Expires' => expiry_date, 'Cache-Control' => 'public'} # 1 year expiry
end

#cache_hit?Boolean

Returns:

  • (Boolean)


147
148
149
150
151
# File 'lib/asset_id/asset.rb', line 147

def cache_hit?
  return false if @@nocache or Cache.miss? self
  puts "AssetID: #{relative_path} - Cache Hit" 
  return true 
end

#css?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/asset_id/asset.rb', line 94

def css?
  mime_type == 'text/css'
end

#dataObject



77
78
79
# File 'lib/asset_id/asset.rb', line 77

def data
  @data ||= File.read(path)
end

#expiry_dateObject



131
132
133
# File 'lib/asset_id/asset.rb', line 131

def expiry_date
  @expiry_date ||= (Time.now + (60*60*24*365)).httpdate
end

#fingerprintObject



85
86
87
88
# File 'lib/asset_id/asset.rb', line 85

def fingerprint
  p = relative_path
  File.join File.dirname(p), "#{File.basename(p, File.extname(p))}-id-#{md5}#{File.extname(p)}"
end

#gzip!Object



122
123
124
125
126
127
128
129
# File 'lib/asset_id/asset.rb', line 122

def gzip!
  # adapted from https://github.com/blakink/asset_id
  @data = returning StringIO.open('', 'w') do |gz_data|
    gz = Zlib::GzipWriter.new(gz_data, nil, nil)
    gz.write(data)
    gz.close
  end.string
end

#gzip_headersObject



139
140
141
# File 'lib/asset_id/asset.rb', line 139

def gzip_headers
  {'Content-Encoding' => 'gzip', 'Vary' => 'Accept-Encoding'}
end

#gzip_type?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/asset_id/asset.rb', line 73

def gzip_type?
  Asset.gzip_types.include? mime_type
end

#is_file?Boolean

Returns:

  • (Boolean)


143
144
145
# File 'lib/asset_id/asset.rb', line 143

def is_file?
  File.exists? absolute_path and !File.directory? absolute_path
end

#md5Object



81
82
83
# File 'lib/asset_id/asset.rb', line 81

def md5
  @digest ||= Digest::MD5.hexdigest(data)
end

#mime_typeObject



90
91
92
# File 'lib/asset_id/asset.rb', line 90

def mime_type
  MIME::Types.of(path).first.to_s
end

#path_prefixObject



61
62
63
# File 'lib/asset_id/asset.rb', line 61

def path_prefix
  File.join Rails.root, 'public'
end

#relative_pathObject



69
70
71
# File 'lib/asset_id/asset.rb', line 69

def relative_path
  path.gsub(path_prefix, '')
end

#replace_css_images!(options = {}) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/asset_id/asset.rb', line 98

def replace_css_images!(options={})
  options[:prefix] ||= ''
  # adapted from https://github.com/blakink/asset_id
  data.gsub! /url\((?:"([^"]*)"|'([^']*)'|([^)]*))\)/mi do |match|
    begin
      # $1 is the double quoted string, $2 is single quoted, $3 is no quotes
      uri = ($1 || $2 || $3).to_s.strip
      uri.gsub!(/^\.\.\//, '/')
      
      # if the uri appears to begin with a protocol then the asset isn't on the local filesystem
      if uri =~ /[a-z]+:\/\//i
        "url(#{uri})"
      else
        asset = Asset.new(uri)
        puts "  - Changing CSS URI #{uri} to #{options[:prefix]}#{asset.fingerprint}" if @@debug
        "url(#{options[:prefix]}#{asset.fingerprint})"
      end
    rescue Errno::ENOENT => e
      puts "  - Warning: #{uri} not found" if @@debug
      "url(#{uri})"
    end
  end
end