utils.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from functools import wraps
  4. import commands
  5. from flask import make_response, g, request
  6. from flask.wrappers import Response
  7. from werkzeug.utils import import_string, cached_property
  8. import jwt
  9. from models.initialize import *
  10. __author__ = 'James Iter'
  11. __date__ = '2017/03/01'
  12. __contact__ = 'james.iter.cn@gmail.com'
  13. __copyright__ = '(c) 2017 by James Iter.'
  14. class Utils(object):
  15. exit_flag = False
  16. thread_counter = 0
  17. @staticmethod
  18. def shell_cmd(cmd):
  19. try:
  20. exit_status, output = commands.getstatusoutput(cmd)
  21. return exit_status, str(output)
  22. except Exception as e:
  23. return -1, e.message
  24. @classmethod
  25. def signal_handle(cls, signum=0, frame=None):
  26. cls.exit_flag = True
  27. @staticmethod
  28. def dumps2response(func):
  29. """
  30. 视图装饰器
  31. http://dormousehole.readthedocs.org/en/latest/patterns/viewdecorators.html
  32. """
  33. @wraps(func)
  34. def _dumps2response(*args, **kwargs):
  35. ret = func(*args, **kwargs)
  36. if func.func_name != 'r_before_request' and ret is None:
  37. ret = dict()
  38. ret['state'] = ji.Common.exchange_state(20000)
  39. if isinstance(ret, dict) and 'state' in ret:
  40. response = make_response()
  41. response.data = json.dumps(ret, ensure_ascii=False)
  42. response.status_code = int(ret['state']['code'])
  43. if 'redirect' in ret and request.args.get('auto_redirect', 'True') == 'True':
  44. response.status_code = int(ret['redirect'].get('code', ret['state']['code']))
  45. response.headers['location'] = ret['redirect'].get('location', request.host_url)
  46. # 参考链接:
  47. # http://werkzeug.pocoo.org/docs/0.11/wrappers/#werkzeug.wrappers.BaseResponse.autocorrect_location_header
  48. # 变量操纵位置 werkzeug/wrappers.py
  49. response.autocorrect_location_header = False
  50. return response
  51. if isinstance(ret, Response):
  52. return ret
  53. return _dumps2response
  54. @staticmethod
  55. def superuser(func):
  56. @wraps(func)
  57. def _superuser(*args, **kwargs):
  58. if not g.superuser:
  59. ret = dict()
  60. ret['state'] = ji.Common.exchange_state(40301)
  61. return ret
  62. return func(*args, **kwargs)
  63. return _superuser
  64. @staticmethod
  65. def generate_token(uid):
  66. payload = {
  67. 'iat': ji.Common.ts(), # 创建于
  68. 'nbf': ji.Common.ts(), # 在此之前不可用
  69. 'exp': ji.Common.ts() + app.config['token_ttl'], # 过期时间
  70. 'uid': uid
  71. }
  72. return jwt.encode(payload=payload, key=app.config['jwt_secret'], algorithm=app.config['jwt_algorithm'])
  73. @staticmethod
  74. def verify_token(token):
  75. ret = dict()
  76. ret['state'] = ji.Common.exchange_state(20000)
  77. try:
  78. payload = jwt.decode(jwt=token, key=app.config['jwt_secret'], algorithms=app.config['jwt_algorithm'])
  79. return payload
  80. except jwt.InvalidTokenError, e:
  81. logger.error(e.message)
  82. ret['state'] = ji.Common.exchange_state(41208)
  83. raise ji.JITError(json.dumps(ret))
  84. class LazyView(object):
  85. """
  86. 惰性载入视图
  87. http://dormousehole.readthedocs.org/en/latest/patterns/lazyloading.html
  88. """
  89. def __init__(self, import_name):
  90. self.__module__, self.__name__ = import_name.rsplit('.', 1)
  91. self.import_name = import_name
  92. @cached_property
  93. def view(self):
  94. return import_string(self.import_name)
  95. def __call__(self, *args, **kwargs):
  96. return self.view(*args, **kwargs)
  97. def add_rule(blueprint, rule, view_func=None, **options):
  98. blueprint.add_url_rule(rule=rule, view_func=LazyView(''.join(['views.', view_func])), **options)