Class: AssetOSS::Asset

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

Constant Summary collapse

DEFAULT_ASSET_PATHS =
['favicon.ico', 'images', 'javascripts', 'stylesheets']
DEFAULT_GZIP_TYPES =

DEFAULT_GZIP_TYPES = [‘text/css’, ‘application/javascript’]

[]
@@asset_paths =
DEFAULT_ASSET_PATHS
@@gzip_types =
DEFAULT_GZIP_TYPES
@@debug =
false
@@nocache =
false
@@nofingerprint =
false

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Asset

Returns a new instance of Asset.



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

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

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



62
63
64
# File 'lib/asset_oss/asset.rb', line 62

def path
  @path
end

Class Method Details

.asset_pathsObject



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

def self.asset_paths
  @@asset_paths
end

.asset_paths=(paths) ⇒ Object



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

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

.find(paths = Asset.asset_paths) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/asset_oss/asset.rb', line 43

def self.find(paths=Asset.asset_paths)
  paths.inject([]) {|assets, path|
    path = File.join Rails.root, 'public', path
    a = Asset.new(path)
    #TODO 暂时不上传gz文件,相好解决ie6 gzip的问题再说
    assets << a if a.is_file? and !a.cache_hit? and !a.gz_file?
    assets += Dir.glob(path+'/**/*').inject([]) {|m, file|
      a = Asset.new(file); m << a if a.is_file? and !a.cache_hit? and !a.gz_file?; m 
    }
  }
end

.fingerprint(path) ⇒ Object



55
56
57
58
59
60
# File 'lib/asset_oss/asset.rb', line 55

def self.fingerprint(path)
  asset = Asset.new(path)
  hit = Cache.get(asset)
  return hit[:fingerprint] if hit
  return asset.fingerprint
end

.gzip_typesObject



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

def self.gzip_types
  @@gzip_types
end

.gzip_types=(types) ⇒ Object



39
40
41
# File 'lib/asset_oss/asset.rb', line 39

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

.init(options) ⇒ Object



20
21
22
23
24
25
# File 'lib/asset_oss/asset.rb', line 20

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

Instance Method Details

#absolute_pathObject



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

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

#cache_headersObject



145
146
147
# File 'lib/asset_oss/asset.rb', line 145

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

#cache_hit?Boolean

Returns:

  • (Boolean)


157
158
159
160
161
# File 'lib/asset_oss/asset.rb', line 157

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

#css?Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/asset_oss/asset.rb', line 103

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

#dataObject



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

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

#expiry_dateObject



141
142
143
# File 'lib/asset_oss/asset.rb', line 141

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

#fingerprintObject



93
94
95
96
97
# File 'lib/asset_oss/asset.rb', line 93

def fingerprint
  p = relative_path
  return p if relative_path =~ /^\/assets.*\//
  File.join File.dirname(p), "#{File.basename(p, File.extname(p))}-id-#{md5}#{File.extname(p)}"
end

#gz_file?Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/asset_oss/asset.rb', line 163

def gz_file?
  path =~ /\.gz$/
end

#gzip!Object



132
133
134
135
136
137
138
139
# File 'lib/asset_oss/asset.rb', line 132

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



149
150
151
# File 'lib/asset_oss/asset.rb', line 149

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

#gzip_type?Boolean

Returns:

  • (Boolean)


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

def gzip_type?
  Asset.gzip_types.include? mime_type
end

#is_file?Boolean

Returns:

  • (Boolean)


153
154
155
# File 'lib/asset_oss/asset.rb', line 153

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

#md5Object



89
90
91
# File 'lib/asset_oss/asset.rb', line 89

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

#mime_typeObject



99
100
101
# File 'lib/asset_oss/asset.rb', line 99

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

#path_prefixObject



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

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

#relative_pathObject



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

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

#replace_css_images!(options = {}) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/asset_oss/asset.rb', line 107

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)
        # TODO: Check the referenced asset is in the asset_paths
        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