When we use css-sprites it's important to make browser cache them for longest period possible. On other hand, we need to refresh them when they are updated. This is especially visible when all icons are stored in single sprite. When it's outdated - entire site becomes ugly.
To solve this task I've implemented this small script that adds file's hash to url:
background-image: url(images/icons.png); background-image: url(images/icons.png?a3844c660);
#!/usr/bin/python import os.path import re import hashlib def file_hash(filename, block_size=2**20): md5 = hashlib.md5() with open(filename, 'rb') as f: for data in iter(lambda: f.read(block_size), ''): md5.update(data) return md5.hexdigest() def find_replace(match, basedir): match = match.replace("'", '') if '?' in match or '#' in match or match.startswith('http://'): print 'skipping: ', match return None filename = os.path.join(basedir, match) return '%s?%s' % (match, file_hash(filename)[:10]) def insert_hash(filename, debug=False): basedir = os.path.dirname(filename) css = open(filename).read() matches = re.findall(r"url\((.*?)\)", css) replacements = dict([ (match, find_replace(match, basedir)) for match in matches ]) if debug: for key, value in replacements.iteritems(): print key, ' => ', value else: for match, repl in replacements.iteritems(): if repl: css = css.replace(match, repl) out = open(filename, 'w') out.write(css) out.close() if __name__ == '__main__': from optparse import OptionParser usage = 'usage: %prog filename.css' parser = OptionParser(usage=usage) parser.add_option("", "--debug", action="store_true", dest="debug", default=False, help="When set, just output list of substitutions.") (options, args) = parser.parse_args() if len(args) < 1: print 'You must provide file name.' insert_hash(os.path.realpath(args), options.debug)
This is pretty old article. Now it's better to use something integrated to your build process - grunt, webassets, etc.
Lead management is an important part of the marketing strategy of every company of any size. Besides automating various business processes, privately-held organizations should consider implementing an IT solution that would help them manage their leads. So, how should you make a web-based leads management system for a University in order to significantly increase sales?
It appears that not everyone knows that in python you can create classes dynamically without metaclasses. I'll show an example of how to do it.So we've learned how to use custom QuerySet to chain requests:Article.objects.old().public()Now we need to make it work for related objects:user.articles.old().public()This is done using use_for_related_fields, but it needs a little trick.