-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecorator.py
168 lines (128 loc) · 4.96 KB
/
decorator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
from functools import wraps
from django.http import HttpResponse, JsonResponse
from nt_s_common import cache, debug
from nt_s_common.utils import format_return
def common_ajax_response(func):
"""
@note: format return value,e.g.:dict(code=0, msg='', data={})
"""
def _decorator(request, *args, **kwargs):
result = func(request, *args, **kwargs)
if isinstance(result, HttpResponse):
return result
code, msg, data = result
r = dict(code=code, msg=msg, data=data)
response = JsonResponse(r)
return response
return _decorator
def validate_params(func):
"""
@note: validate decorator
"""
def _decorator(*args, **kwargs):
def _get_param_items(func, args, kwargs):
import inspect
parameters = inspect.signature(func).parameters
arg_keys = tuple(parameters.keys())
vparams = [k for k, v in parameters.items() if k == str(v)]
param_items = []
# collect args *args
for i, value in enumerate(args):
_key = arg_keys[i]
if _key in vparams:
param_items.append([_key, value])
# collect kwargs **kwargs
for arg_name, value in kwargs.items():
if arg_name in vparams:
param_items.append([arg_name, value])
return param_items
check_list = _get_param_items(func, args, kwargs)
# cannot be null
for item in check_list:
if item[1] is None:
return format_return(99901)
return func(*args, **kwargs)
return _decorator
def cache_required(cache_key, cache_key_type=0, expire=3600 * 24, cache_config=cache.CACHE_TMP):
"""
@note: cache decorator
cache_key format:1:'answer_summary_%s' as changeable key 2:'global_var' as fixed value
if cache_key should be formatted,use cache_key_type:
0:param:func(self, cache_key_param),取cache_key_param或者cache_key_param.id
1:param:func(cache_key_param)
2:param:func(self) cache_key为self.id
"""
def _wrap_decorator(func):
func.cache_key = cache_key
def _decorator(*args, **kwargs):
cache_key = func.cache_key
must_update_cache = kwargs.get('must_update_cache')
if '%' in cache_key:
assert len(args) > 0
if cache_key_type == 0:
key = args[1].id if hasattr(args[1], 'id') else args[1]
if isinstance(key, (str, int, float)):
cache_key = cache_key % key
else:
return
if cache_key_type == 1:
cache_key = cache_key % args[0]
if cache_key_type == 2:
cache_key = cache_key % args[0].id
return cache.get_or_update_data_from_cache(cache_key, expire, cache_config,
must_update_cache, func, *args, **kwargs)
return _decorator
return _wrap_decorator
def one_by_one_locked(func):
"""
@note: thread lock, avoid Concurrency problems
"""
def _decorator(*args, **kwargs):
import time
import uuid
cache_obj = cache.Cache()
cache_key_suffix = ""
cache_key = None
if len(args) > 1:
# the cache key is the first param
cache_key_suffix = args[1]
else:
if kwargs:
# or the cache key is the val of cahce_key
if kwargs.get('cache_key'):
cache_key = "%s_%s" % ('one_by_one_locker', kwargs.get('cache_key'))
cache_key_suffix = list(kwargs.items())[0][1]
if not cache_key:
cache_key = "%s_%s" % (func.__name__, cache_key_suffix) # cache key
uuid_str = str(uuid.uuid4())
flag = None
while not flag:
flag = cache_obj.set_lock(cache_key, uuid_str, ex=5, nx=True) # add lock
if not flag:
time.sleep(0.002)
r = func(*args, **kwargs)
if cache_obj.get(cache_key) == uuid_str:
cache_obj.delete(cache_key) # delete lock after handling
return r
return _decorator
def lang_translate(func):
"""
lang decorator
@lang_translate
def delete(request):
pass
"""
@wraps(func)
def wrapper(request, *args, **kwargs):
result = list(func(request, *args, **kwargs))
from nt_s_common.consts import ERROR_DICT
# template
lang_msg = ERROR_DICT.get(request.lang, {}).get(result[0], result[1])
default_msg = ERROR_DICT.get('zh', {}).get(result[0])
# the return data contains the template or not
if lang_msg.find('%s') > -1:
result[1] = lang_msg % (result[1])
else:
result[1] = result[1] if result[1] != default_msg else lang_msg
return result
return wrapper