parser.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
  2. # Copyright: (c) <spug.dev@gmail.com>
  3. # Released under the AGPL-3.0 License.
  4. import json
  5. from .utils import AttrDict
  6. # 自定义的解析异常
  7. class ParseError(BaseException):
  8. def __init__(self, message):
  9. self.message = message
  10. # 需要校验的参数对象
  11. class Argument(object):
  12. """
  13. :param name: name of option
  14. :param default: default value if the argument if absent
  15. :param bool required: is required
  16. """
  17. def __init__(self, name, default=None, handler=None, required=True, type=str, filter=None, help=None,
  18. nullable=False):
  19. self.name = name
  20. self.default = default
  21. self.type = type
  22. self.required = required
  23. self.nullable = nullable
  24. self.filter = filter
  25. self.help = help
  26. self.handler = handler
  27. if not isinstance(self.name, str):
  28. raise TypeError('Argument name must be string')
  29. if filter and not callable(self.filter):
  30. raise TypeError('Argument filter is not callable')
  31. def parse(self, has_key, value):
  32. if not has_key:
  33. if self.required and self.default is None:
  34. raise ParseError(
  35. self.help or 'Required Error: %s is required' % self.name)
  36. else:
  37. return self.default
  38. elif value in [u'', '', None]:
  39. if self.default is not None:
  40. return self.default
  41. elif not self.nullable and self.required:
  42. raise ParseError(
  43. self.help or 'Value Error: %s must not be null' % self.name)
  44. else:
  45. return None
  46. try:
  47. if self.type:
  48. if self.type in (list, dict) and isinstance(value, str):
  49. value = json.loads(value)
  50. assert isinstance(value, self.type)
  51. elif self.type == bool and isinstance(value, str):
  52. assert value.lower() in ['true', 'false']
  53. value = value.lower() == 'true'
  54. elif not isinstance(value, self.type):
  55. value = self.type(value)
  56. except (TypeError, ValueError, AssertionError):
  57. raise ParseError(self.help or 'Type Error: %s type must be %s' % (
  58. self.name, self.type))
  59. if self.filter:
  60. if not self.filter(value):
  61. raise ParseError(
  62. self.help or 'Value Error: %s filter check failed' % self.name)
  63. if self.handler:
  64. value = self.handler(value)
  65. return value
  66. # 解析器基类
  67. class BaseParser(object):
  68. def __init__(self, *args):
  69. self.args = []
  70. for e in args:
  71. if isinstance(e, str):
  72. e = Argument(e)
  73. elif not isinstance(e, Argument):
  74. raise TypeError('%r is not instance of Argument' % e)
  75. self.args.append(e)
  76. def _get(self, key):
  77. raise NotImplementedError
  78. def _init(self, data):
  79. raise NotImplementedError
  80. def add_argument(self, **kwargs):
  81. self.args.append(Argument(**kwargs))
  82. def parse(self, data=None, clear=False):
  83. rst = AttrDict()
  84. try:
  85. self._init(data)
  86. for e in self.args:
  87. has_key, value = self._get(e.name)
  88. if clear and has_key is False and e.required is False:
  89. continue
  90. rst[e.name] = e.parse(has_key, value)
  91. except ParseError as err:
  92. return None, err.message
  93. return rst, None
  94. # Json解析器
  95. class JsonParser(BaseParser):
  96. def __init__(self, *args):
  97. self.__data = None
  98. super(JsonParser, self).__init__(*args)
  99. def _get(self, key):
  100. return key in self.__data, self.__data.get(key)
  101. def _init(self, data):
  102. try:
  103. if isinstance(data, (str, bytes)):
  104. data = data.decode('utf-8')
  105. self.__data = json.loads(data) if data else {}
  106. else:
  107. assert hasattr(data, '__contains__')
  108. assert hasattr(data, 'get')
  109. assert callable(data.get)
  110. self.__data = data
  111. except (ValueError, AssertionError):
  112. raise ParseError('Invalid data type for parse')