Skip to content

Instantly share code, notes, and snippets.

@tomotaka
Last active December 31, 2015 05:29
Show Gist options
  • Save tomotaka/7940980 to your computer and use it in GitHub Desktop.
Save tomotaka/7940980 to your computer and use it in GitHub Desktop.
expanding url(./img/hoge.png) => url(data:image/png;....) with filesystem-based caching
import re
import base64
import hashlib
import os.path
import gevent.fileobject as gfo
def _read_file(filepath):
fh = open(filepath, 'rb')
gfh = gfo.FileObject(fh, 'rb')
ret = gfh.read()
gfh.close()
return ret
def _write_file(filepath, content):
fh = open(filepath, 'wb')
gfh = gfo.FileObject(fh, 'wb')
gfh.write(content)
gfh.close()
class CSSDataUriExpander(object):
def __init__(self, cache_dir):
self.cache_dir = cache_dir
self.urlpat = re.compile(r'url\("([^"]*)"\)')
def expand_file(self, css_file, base_dir=None):
base_dir = base_dir or os.path.dirname(css_file)
css_content = _read_file(css_file)
return self.expand_file(css_content, base_dir);
def expand(self, css_content, base_dir):
ret = css_content
for match in self.urlpat.finditer(css_content):
rel_path = match.groups()[0]
path = os.path.normpath(os.path.join(base_dir, rel_path))
data_uri = self.get_data_uri(path)
ret = ret.replace('url("%s")' % rel_path, 'url("%s")' % data_uri)
return ret
def get_data_uri(self, full_path):
cache_path = self.get_cache_path(full_path)
if os.path.exists(cache_path):
return _read_file(cache_path)
else:
data_uri = self.gen_data_uri(full_path)
_write_file(cache_path, data_uri)
return data_uri
def get_cache_path(self, path):
pathhash = hashlib.md5(path).hexdigest()
return os.path.normpath(os.path.join(self.cache_dir, pathhash))
def gen_data_uri(self, path):
mime = self.get_mime(path)
content = _read_file(path)
b64data = base64.b64encode(content)
return 'data:%s;base64,%s' % (mime, b64data)
def get_mime(self, path):
lp = path.lower()
mime = {
'.png': 'image/png',
'.jpe': 'image/jpeg',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.gif': 'image/gif',
'.ico': 'image/x-icon',
'.bmp': 'image/bmp',
'.svg': 'image/svg+xml',
'.tif': 'image/tiff',
'.tiff': 'image/tiff'
}
for ext in mime:
if lp.endswith(ext):
return mime[ext]
return 'image/jpeg'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment