app.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. # note: https://responder.kennethreitz.org/en/latest/search.html?q=resp.content
  2. from hub import methods
  3. import traceback
  4. import requests
  5. import importlib
  6. def generate_app():
  7. """"""
  8. # --- define app --- see: https://responder.kennethreitz.org/en/latest/tour.html#cors
  9. import responder
  10. app = responder.API(
  11. # cors=True,
  12. # allow_methods=['*'],
  13. # allow_credentials=True,
  14. )
  15. async def coroutine_method(method, _params):
  16. """协程方法"""
  17. # run_at = time.time()
  18. result = await method(**_params)
  19. # methods.debug_log(f"app.coroutine_method", f"use time {round(time.time() - run_at, 2)}s")
  20. return result
  21. def foreground_method(method, _params):
  22. """等待返回"""
  23. # run_at = time.time()
  24. result = method(**_params)
  25. # methods.debug_log(f"app.foreground_method", f"use time {round(time.time() - run_at, 2)}s")
  26. return result
  27. @app.background.task
  28. def background_method(method, _params):
  29. """不等返回"""
  30. # run_at = time.time()
  31. result = method(**_params)
  32. # methods.debug_log(f"app.background_method", f"use time {round(time.time() - run_at, 2)}s")
  33. return result
  34. async def run_method(code, _params):
  35. config_dict = {
  36. 7000: ('v1', 'f7000', 'IsAsync'),
  37. 70000: ('v1', 'f70000', 'IsBack'),
  38. }
  39. if code not in config_dict:
  40. return dict(code=2, detail=f"{code} not found!")
  41. else:
  42. script_name, method_name, method_type = config_dict[code]
  43. script = importlib.import_module(f"api.httpapi.{script_name}")
  44. method = getattr(script, method_name)
  45. del _params['code']
  46. if method_type == 'IsAsync':
  47. return await coroutine_method(method, _params)
  48. elif method_type == 'IsBack':
  49. return foreground_method(method, _params)
  50. elif method_type == 'NoBack':
  51. return background_method(method, _params)
  52. @app.route('/httpapi')
  53. async def httpapi(request, response):
  54. try:
  55. # --- fill ---
  56. if request.params:
  57. params = dict(request.params.items())
  58. else:
  59. params = await request.media()
  60. # --- debug ---
  61. methods.debug_log('app.httpapi92', f"#params: {params}")
  62. # --- check ---
  63. if 'code' not in params:
  64. response.media = dict(code=-1, reason="error98", detail=f"参数缺失")
  65. else:
  66. code = params.get('code')
  67. result = await run_method(code, params)
  68. methods.debug_log('app.httpapi102', f"#result: {result}")
  69. if result.__class__.__name__ == 'bytes':
  70. response.content = result
  71. elif result.__class__.__name__ == 'str':
  72. response.text = result
  73. elif result.__class__.__name__ == 'dict':
  74. response.media = result
  75. elif result.__class__.__name__ == 'Future':
  76. response.media = dict(code=0, detail=f"{result} is running.")
  77. elif not result:
  78. response.media = dict(code=0, detail=f"return is null.")
  79. else:
  80. response.media = dict(code=0, detail=f"return type is {result.__class__.__name__}.")
  81. except Exception as exception:
  82. methods.debug_log("app.httpapi118", f"#exception: {exception.__class__.__name__}")
  83. methods.debug_log("app.httpapi118", f"#traceback: {traceback.format_exc()}")
  84. response.media = dict(code=-1, reason=exception.__class__.__name__, detail=f"{methods.trace_log()}")
  85. @app.route('/wsapi', websocket=True)
  86. async def wsapi(client):
  87. """
  88. let wsuri = `${location.protocol === 'https' ? 'wss' : 'ws'}://${location.host}:8801/wsapi`;
  89. connect_json_text = {
  90. line_id: 连接id,暂为token
  91. }
  92. )
  93. send_json_text_1 = {
  94. face_uuid: 匹配到的人脸id
  95. face_name: 人脸名称
  96. input_face_b64: 抓拍图片(b64格式字符串)
  97. }
  98. """
  99. try:
  100. await client.accept()
  101. while True:
  102. # --- check ---
  103. data = await client.receive_text() # 消息接受方法 receive_{text/json/bytes}
  104. if not data:
  105. methods.debug_log('app.wsapi140', f"#reason: error140")
  106. await client.send_json({'code': -1, 'reason': 'error140'})
  107. break
  108. # --- debug ---
  109. # methods.debug_log('app.wsapi145', f"#data: {data} | {type(data)}")
  110. # --- check ---
  111. if not methods.is_json(data):
  112. methods.debug_log('app.wsapi133', f"#reason: error146")
  113. await client.send_json({'code': -1, 'reason': 'error146'})
  114. break
  115. # --- check ---
  116. data = methods.json_loads(data)
  117. if not data.get('code'):
  118. methods.debug_log('app.wsapi144', f"#reason: error157")
  119. await client.send_json({'code': -1, 'reason': 'error157'})
  120. break
  121. # --- debug ---
  122. if data.get('code') not in [2008]:
  123. methods.debug_log('app.wsapi160', f"#data: {data}")
  124. # --- check 2000 ---
  125. code = data.get('code')
  126. if code == 2000:
  127. # --- check ---
  128. if 'acct' not in data or 'pw' not in data:
  129. methods.debug_log('app.wsapi166', f"#reason: error164")
  130. await client.send_json({'code': -1, 'reason': 'error164'})
  131. break
  132. # --- check ---
  133. username = data.get('acct')
  134. password = data.get('pw')
  135. url = 'http://58.34.98.13:8099/api/ar/user/login'
  136. data = {
  137. "acct": username,
  138. "pw": password,
  139. "method": "1" # 客户端类型 1 安卓 2 PC端
  140. }
  141. methods.debug_log('app.wsapi179', f"#url: {url}")
  142. response = requests.post(url=url, json=data)
  143. data = response.json()
  144. if data.get('msg') and data.get('msg') == 'success':
  145. data['code'] = 4000
  146. await client.send_json(data)
  147. else:
  148. methods.debug_log('app.wsapi186', f"#reason: error186")
  149. await client.send_json({'code': -1, 'reason': 'error186'})
  150. # --- save ---
  151. # methods.debug_log('app.wsapi179', f"{dir(client)}")
  152. # methods.debug_log('app.wsapi179', f"#id: {id(client)} | {type(id(client))}")
  153. methods.debug_log('app.wsapi179', f"{type(client)} | {methods.now_ts()} | {id(client)}")
  154. LineManage.line_dict[username] = client, methods.now_ts(), id(client)
  155. # --- check 2008 ---
  156. if code == 2008:
  157. # --- 判断该连接是否是已保存的链接 ---
  158. is_ok = False
  159. for key in list(LineManage.line_dict.keys()):
  160. ws, ts, _id = LineManage.line_dict.get(key)
  161. if _id == id(client):
  162. LineManage.line_dict[username] = client, methods.now_ts(), id(client)
  163. is_ok = True
  164. await client.send_json({'code': 4008, 'result': is_ok})
  165. except Exception as exception:
  166. if exception.__class__.__name__ == 'WebSocketDisconnect':
  167. await client.close()
  168. else:
  169. methods.debug_log("app.wsapi163", f"#exception: {exception.__class__.__name__}")
  170. methods.debug_log("app.wsapi163", f"#traceback: {traceback.format_exc()}")
  171. # --- return ---
  172. return app