Setting tag plcapi-5.4-2
[plcapi.git] / cache_utils / utils.py
1 from hashlib import md5
2
3 CONTROL_CHARACTERS = set([chr(i) for i in range(0,33)])
4 CONTROL_CHARACTERS.add(chr(127))
5
6 def sanitize_memcached_key(key, max_length=250):
7     """ Removes control characters and ensures that key will
8         not hit the memcached key length limit by replacing
9         the key tail with md5 hash if key is too long.
10     """
11     key = ''.join([c for c in key if c not in CONTROL_CHARACTERS])
12     if len(key) > max_length:
13         hash = md5(key).hexdigest()
14         key = key[:max_length-33]+'-'+hash
15     return key
16
17 def _args_to_unicode(args, kwargs):
18     key = ""
19     if args:
20         key += unicode(args)
21     if kwargs:
22         key += unicode(kwargs)
23     return key
24
25
26 def _func_type(func):
27     """ returns if callable is a function, method or a classmethod """
28     argnames = func.func_code.co_varnames[:func.func_code.co_argcount]
29     if len(argnames) > 0:
30         if argnames[0] == 'self':
31             return 'method'
32         if argnames[0] == 'cls':
33             return 'classmethod'
34     return 'function'
35
36
37 def _func_info(func, args):
38     ''' introspect function's or method's full name.
39     Returns a tuple (name, normalized_args,) with
40     'cls' and 'self' removed from normalized_args '''
41
42     func_type = _func_type(func)
43
44     if func_type == 'function':
45         return ".".join([func.__module__, func.__name__]), args
46
47     class_name = args[0].__class__.__name__
48     if func_type == 'classmethod':
49         class_name = args[0].__name__
50
51     return ".".join([func.__module__, class_name, func.__name__]), args[1:]
52
53
54 def _cache_key(func_name, func_type, args, kwargs):
55     """ Construct readable cache key """
56     if func_type == 'function':
57         args_string = _args_to_unicode(args, kwargs)
58     else:
59         args_string = _args_to_unicode(args[1:], kwargs)
60     return sanitize_memcached_key('[cached]%s(%s)' % (func_name, args_string,))