memcache.py 1.31 KB
Newer Older
1 2 3 4 5
"""
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
6 7 8
import hashlib
import urllib

9

10
def fasthash(string):
11 12 13 14 15 16 17 18 19 20 21 22 23 24
    """
    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))
25

26

27
def safe_key(key, key_prefix, version):
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
    """
    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])
43

44
    # If the total length is too long for memcache, hash it
45
    if len(combined) > 250:
46
        combined = fasthash(combined)
47

48 49
    # Return the result
    return combined