""" This module provides a KEY_FUNCTION suitable for use with a memcache backend so that we can cache any keys, not just ones that memcache would ordinarily accept """ from django.utils.encoding import smart_str import hashlib import urllib def fasthash(string): """ Hashes `string` into a string representation of a 128-bit digest. """ md4 = hashlib.new("md4") md4.update(string) return md4.hexdigest() def cleaned_string(val): """ Converts `val` to unicode and URL-encodes special characters (including quotes and spaces) """ return urllib.quote_plus(smart_str(val)) def safe_key(key, key_prefix, version): """ Given a `key`, `key_prefix`, and `version`, return a key that is safe to use with memcache. `key`, `key_prefix`, and `version` can be numbers, strings, or unicode. """ # Clean for whitespace and control characters, which # cause memcache to raise an exception key = cleaned_string(key) key_prefix = cleaned_string(key_prefix) version = cleaned_string(version) # Attempt to combine the prefix, version, and key combined = ":".join([key_prefix, version, key]) # If the total length is too long for memcache, hash it if len(combined) > 250: combined = fasthash(combined) # Return the result return combined