Skip to content

Commit b4e436c

Browse files
dlmybaisk
authored andcommitted
Enhencement #241
1 parent e6e38fc commit b4e436c

3 files changed

Lines changed: 60 additions & 51 deletions

File tree

leancloud/cloudfunc.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import leancloud
88
from leancloud import utils
9+
from leancloud.engine import leanengine
910
from leancloud._compat import string_types
1011

1112

@@ -15,7 +16,6 @@
1516
def run(_cloud_func_name, **params):
1617
"""
1718
调用 LeanEngine 上的远程代码
18-
1919
:param name: 需要调用的远程 Cloud Code 的名称
2020
:type name: string_types
2121
:param params: 调用参数
@@ -27,7 +27,9 @@ def run(_cloud_func_name, **params):
2727

2828

2929
def _run_in_local(_cloud_func_name, **params):
30-
result = leancloud.engine.leanengine.dispatch_cloud_func({}, _cloud_func_name, False, params)
30+
if not leanengine.root_engine:
31+
return
32+
result = leanengine.dispatch_cloud_func(leanengine.root_engine.app.cloud_codes, {}, _cloud_func_name, False, params)
3133
return utils.decode(None, result)
3234

3335

@@ -39,7 +41,6 @@ def rpc(_cloud_rpc_name, **params):
3941
"""
4042
调用 LeanEngine 上的远程代码
4143
与cloudfunc.run 类似,但是允许传入 leancloud.Object 作为参数,也允许传入 leancloud.Object 作为结果
42-
4344
:param name: 需要调用的远程 Cloud Code 的名称
4445
:type name: basestring
4546
:param params: 调用参数
@@ -57,7 +58,9 @@ def rpc(_cloud_rpc_name, **params):
5758

5859

5960
def _rpc_in_local(_cloud_rpc_name, **params):
60-
result = leancloud.engine.leanengine.dispatch_cloud_func({}, _cloud_rpc_name, True, params)
61+
if not leanengine.root_engine:
62+
return
63+
result = leanengine.dispatch_cloud_func(leanengine.root_engine.app.cloud_codes, {}, _cloud_rpc_name, True, params)
6164
return utils.decode(None, result)
6265

6366

@@ -70,7 +73,6 @@ def request_sms_code(phone_number, idd='+86', sms_type='sms',
7073
params=None):
7174
"""
7275
请求发送手机验证码
73-
7476
:param phone_number: 需要验证的手机号码
7577
:param idd: 号码的所在地国家代码,默认为中国(+86)
7678
:param sms_type: 验证码发送方式,'voice' 为语音,'sms' 为短信
@@ -105,7 +107,6 @@ def request_sms_code(phone_number, idd='+86', sms_type='sms',
105107
def verify_sms_code(phone_number, code):
106108
"""
107109
获取到手机验证码之后,验证验证码是否正确。如果验证失败,抛出异常。
108-
109110
:param phone_number: 需要验证的手机号码
110111
:param code: 接受到的验证码
111112
:return: None
@@ -128,7 +129,6 @@ def __init__(self, token, url):
128129
def verify(self, code):
129130
"""
130131
验证用户输入与图形验证码是否匹配
131-
132132
:params code: 用户填写的验证码
133133
"""
134134
return verify_captcha(code, self.token)
@@ -137,7 +137,6 @@ def verify(self, code):
137137
def request_captcha(size=None, width=None, height=None, ttl=None):
138138
"""
139139
请求生成新的图形验证码
140-
141140
:return: Captcha
142141
"""
143142
params = {
@@ -156,7 +155,6 @@ def request_captcha(size=None, width=None, height=None, ttl=None):
156155
def verify_captcha(code, token):
157156
"""
158157
验证用户输入与图形验证码是否匹配
159-
160158
:params code: 用户填写的验证码
161159
:params token: 图形验证码对应的 token
162160
:return: validate token

leancloud/engine/__init__.py

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from werkzeug.serving import run_simple
1010

1111
import leancloud
12+
from . import leanengine
1213
from .authorization import AuthorizationMiddleware
1314
from .cookie_session import CookieSessionMiddleware
1415
from .cors import CORSMiddleware
@@ -36,17 +37,20 @@ class Engine(object):
3637
"""
3738
LeanEngine middleware.
3839
"""
39-
def __init__(self, wsgi_app, fetch_user=True):
40+
def __init__(self, wsgi_app=None, fetch_user=True):
4041
"""
4142
LeanEngine middleware constructor.
4243
4344
:param wsgi_app: wsgi callable
44-
:param fetch_user: should fetch user's data from server while processing session token.
45+
:param fetch_user: should fetch user's data from server while prNoneocessing session token.
4546
:type fetch_user: bool
4647
"""
4748
self.current = current
49+
if wsgi_app:
50+
leanengine.root_engine = self
4851
self.origin_app = wsgi_app
49-
self.cloud_app = context.local_manager.make_middleware(CORSMiddleware(AuthorizationMiddleware(LeanEngineApplication(fetch_user=fetch_user))))
52+
self.app = LeanEngineApplication(fetch_user=fetch_user)
53+
self.cloud_app = context.local_manager.make_middleware(CORSMiddleware(AuthorizationMiddleware(self.app)))
5054

5155
def __call__(self, environ, start_response):
5256
request = Request(environ)
@@ -67,45 +71,47 @@ def __call__(self, environ, start_response):
6771
return self.cloud_app(environ, start_response)
6872
return self.origin_app(environ, start_response)
6973

70-
@property
71-
def current_user(self):
72-
warnings.warn('Engine.current_user is deprecated, please use Engine.current.user instead', leancloud.LeanCloudWarning)
73-
return user
74+
def wrap(self, wsgi_app):
75+
if leanengine.root_engine:
76+
warnings.warn("Overwrite previous wsgi_app.", leancloud.LeanCloudWarning)
77+
leanengine.root_engine = self
78+
self.origin_app = wsgi_app
79+
return self
7480

75-
@staticmethod
76-
def on_bigquery(*args, **kwargs):
77-
warnings.warn('on_bigquery is deprecated, please use on_insight instead', leancloud.LeanCloudWarning)
78-
return register_on_bigquery(*args, **kwargs)
81+
def register(self, engine):
82+
if not isinstance(engine, Engine):
83+
raise TypeError("Please specify an Engine instance")
84+
self.app.update_cloud_codes(engine.app.cloud_codes)
7985

8086
def define(self, *args, **kwargs):
81-
return register_cloud_func(*args, **kwargs)
87+
return register_cloud_func(self.app.cloud_codes, *args, **kwargs)
8288

8389
def on_verified(self, *args, **kwargs):
84-
return register_on_verified(*args, **kwargs)
90+
return register_on_verified(self.app.cloud_codes, *args, **kwargs)
8591

8692
def on_login(self, *args, **kwargs):
87-
return register_on_login(*args, **kwargs)
93+
return register_on_login(self.app.cloud_codes, *args, **kwargs)
8894

8995
def before_save(self, *args, **kwargs):
90-
return before_save(*args, **kwargs)
96+
return before_save(self.app.cloud_codes, *args, **kwargs)
9197

9298
def after_save(self, *args, **kwargs):
93-
return after_save(*args, **kwargs)
99+
return after_save(self.app.cloud_codes, *args, **kwargs)
94100

95101
def before_update(self, *args, **kwargs):
96-
return before_update(*args, **kwargs)
102+
return before_update(self.app.cloud_codes, *args, **kwargs)
97103

98104
def after_update(self, *args, **kwargs):
99-
return after_update(*args, **kwargs)
105+
return after_update(self.app.cloud_codes, *args, **kwargs)
100106

101107
def before_delete(self, *args, **kwargs):
102-
return before_delete(*args, **kwargs)
108+
return before_delete(self.app.cloud_codes, *args, **kwargs)
103109

104110
def after_delete(self, *args, **kwargs):
105-
return after_delete(*args, **kwargs)
111+
return after_delete(self.app.cloud_codes, *args, **kwargs)
106112

107113
def on_insight(self, *args, **kwargs):
108-
return register_on_bigquery(*args, **kwargs)
114+
return register_on_bigquery(self.app.cloud_codes, *args, **kwargs)
109115

110116
def run(self, *args, **kwargs):
111117
return run_simple(*args, **kwargs)

leancloud/engine/leanengine.py

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def __init__(self, fetch_user):
7272
Rule('/1/functions/_ops/metadatas', endpoint='ops_meta_data'),
7373
Rule('/1.1/functions/_ops/metadatas', endpoint='ops_meta_data'),
7474
])
75+
self.cloud_codes = {}
7576

7677
def __call__(self, environ, start_response):
7778
self.process_session(environ)
@@ -124,22 +125,22 @@ def dispatch_request(self, environ):
124125

125126
try:
126127
if endpoint == 'cloud_function':
127-
result = {'result': dispatch_cloud_func(app_params, decode_object=False, **values)}
128+
result = {'result': dispatch_cloud_func(self.cloud_codes, app_params, decode_object=False, **values)}
128129
elif endpoint == 'rpc_function':
129-
result = {'result': dispatch_cloud_func(app_params, decode_object=True, **values)}
130+
result = {'result': dispatch_cloud_func(self.cloud_codes, app_params, decode_object=True, **values)}
130131
elif endpoint == 'cloud_hook':
131-
result = dispatch_cloud_hook(app_params, **values)
132+
result = dispatch_cloud_hook(self.cloud_codes, app_params, **values)
132133
elif endpoint == 'on_verified':
133-
result = {'result': dispatch_on_verified(app_params, **values)}
134+
result = {'result': dispatch_on_verified(self.cloud_codes, app_params, **values)}
134135
elif endpoint == 'on_login':
135-
result = {'result': dispatch_on_login(app_params, **values)}
136+
result = {'result': dispatch_on_login(self.cloud_codes, app_params, **values)}
136137
elif endpoint == 'ops_meta_data':
137138
from .authorization import MASTER_KEY
138139
if request.environ.get('_app_params', {}).get('master_key') != MASTER_KEY:
139140
raise LeanEngineError(code=401, message='Unauthorized.')
140-
result = {'result': dispatch_ops_meta_data()}
141+
result = {'result': dispatch_ops_meta_data(self.cloud_codes)}
141142
elif endpoint == 'on_bigquery':
142-
result = {'result': dispatch_on_bigquery(app_params, **values)}
143+
result = {'result': dispatch_on_bigquery(self.cloud_codes, app_params, **values)}
143144
else:
144145
raise ValueError # impossible
145146
return Response(json.dumps(result), mimetype='application/json')
@@ -157,6 +158,12 @@ def dispatch_request(self, environ):
157158
mimetype='application/json'
158159
)
159160

161+
def update_cloud_codes(self, engine_cloud_codes):
162+
already_register_func_name = set(self.cloud_codes.keys()).intersection(set(engine_cloud_codes.keys()))
163+
if already_register_func_name:
164+
is_are = "is" if len(already_register_func_name) == 1 else "are"
165+
raise RuntimeError("cloud function: {0} {1} already registerd.".format(",".join(already_register_func_name), is_are))
166+
self.cloud_codes.update(engine_cloud_codes)
160167

161168
hook_name_mapping = {
162169
'beforeSave': '__before_save_for_',
@@ -167,10 +174,9 @@ def dispatch_request(self, environ):
167174
'afterDelete': '__after_delete_for_',
168175
}
169176

170-
_cloud_codes = {}
177+
root_engine = None
171178

172-
173-
def register_cloud_func(func_or_func_name):
179+
def register_cloud_func(_cloud_codes, func_or_func_name):
174180
if isinstance(func_or_func_name, string_types):
175181
func_name = func_or_func_name
176182
def inner_func(func):
@@ -188,7 +194,7 @@ def inner_func(func):
188194
return func
189195

190196

191-
def dispatch_cloud_func(app_params, func_name, decode_object, params):
197+
def dispatch_cloud_func(_cloud_codes, app_params, func_name, decode_object, params):
192198
# let's check realtime hook sign first
193199
realtime_hook_funcs = [
194200
'_messageReceived', '_receiversOffline', '_messageSent', '_conversationStart', '_conversationStarted',
@@ -221,7 +227,7 @@ def dispatch_cloud_func(app_params, func_name, decode_object, params):
221227
return result
222228

223229

224-
def register_cloud_hook(class_name, hook_name):
230+
def register_cloud_hook(_cloud_codes, class_name, hook_name):
225231
# hack the hook name
226232
hook_name = hook_name_mapping[hook_name] + class_name
227233

@@ -230,7 +236,6 @@ def register_cloud_hook(class_name, hook_name):
230236

231237
def new_func(func):
232238
_cloud_codes[hook_name] = func
233-
234239
return new_func
235240

236241

@@ -247,7 +252,7 @@ def new_func(func):
247252
after_delete = functools.partial(register_cloud_hook, hook_name='afterDelete')
248253

249254

250-
def dispatch_cloud_hook(app_params, class_name, hook_name, params):
255+
def dispatch_cloud_hook(_cloud_codes, app_params, class_name, hook_name, params):
251256
from .authorization import HOOK_KEY
252257
current_hook_key = app_params.get('hook_key')
253258
if not current_hook_key or current_hook_key != HOOK_KEY:
@@ -288,7 +293,7 @@ def dispatch_cloud_hook(app_params, class_name, hook_name, params):
288293
return obj.dump()
289294

290295

291-
def register_on_verified(verify_type):
296+
def register_on_verified(_cloud_codes, verify_type):
292297
if verify_type not in set(['sms', 'email']):
293298
raise RuntimeError('verify_type must be sms or email')
294299

@@ -301,7 +306,7 @@ def new_func(func):
301306
return new_func
302307

303308

304-
def dispatch_on_verified(app_params, verify_type, params):
309+
def dispatch_on_verified(_cloud_codes, app_params, verify_type, params):
305310
func_name = '__on_verified_' + verify_type
306311
from .authorization import HOOK_KEY
307312
hook_key = app_params.get('hook_key')
@@ -317,15 +322,15 @@ def dispatch_on_verified(app_params, verify_type, params):
317322
return func(user)
318323

319324

320-
def register_on_login(func):
325+
def register_on_login(_cloud_codes, func):
321326
func_name = '__on_login__User'
322327

323328
if func_name in _cloud_codes:
324329
raise RuntimeError('on login is already registered')
325330
_cloud_codes[func_name] = func
326331

327332

328-
def dispatch_on_login(app_params, params):
333+
def dispatch_on_login(_cloud_codes, app_params, params):
329334
from .authorization import HOOK_KEY
330335
current_hook_key = app_params.get('hook_key')
331336
if not current_hook_key or current_hook_key != HOOK_KEY:
@@ -341,11 +346,11 @@ def dispatch_on_login(app_params, params):
341346
return func(user)
342347

343348

344-
def dispatch_ops_meta_data():
349+
def dispatch_ops_meta_data(_cloud_codes):
345350
return list(_cloud_codes.keys())
346351

347352

348-
def register_on_bigquery(event):
353+
def register_on_bigquery(_cloud_codes, event):
349354
if event == 'end':
350355
func_name = '__on_complete_bigquery_job'
351356
else:
@@ -358,7 +363,7 @@ def inner_func(func):
358363
return inner_func
359364

360365

361-
def dispatch_on_bigquery(app_params, event, params):
366+
def dispatch_on_bigquery(_cloud_codes, app_params, event, params):
362367
if event == 'onComplete':
363368
func_name = '__on_complete_bigquery_job'
364369
else:

0 commit comments

Comments
 (0)