validator.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. from .apikey import apikey_generator
  2. class validator:
  3. """
  4. This is base validator class. It implements base validator mechanism,
  5. and other validators must implements it.
  6. """
  7. def __init__(self, target: str) -> None:
  8. """
  9. This create new validator, from string.
  10. Parameters:
  11. target (str): Content to validate
  12. """
  13. self.__target = target
  14. self._failed()
  15. @property
  16. def target(self) -> str:
  17. """ This return content to validate. """
  18. return self.__target
  19. def _failed(self) -> None:
  20. """
  21. This would mark content as invalid.
  22. """
  23. self.__result = False
  24. def _check_all(self) -> None:
  25. """
  26. This would check all marks of the content.
  27. It must be overwrite by target validator.
  28. """
  29. pass
  30. def _contain(self, *args) -> bool:
  31. """
  32. This check that target contain any given phrase or letter.
  33. Args:
  34. (str): Phrase to check that content contain it
  35. Returns:
  36. (bool): True when any of given phrase is in the target
  37. """
  38. for letter in args:
  39. if self.__target.find(letter) != -1:
  40. return True
  41. return False
  42. @property
  43. def result(self) -> bool:
  44. """ Validate content, True when valid or False when not. """
  45. self.__result = True
  46. self._check_all()
  47. return self.__result
  48. @property
  49. def invalid(self) -> bool:
  50. """ Validate, and return True when target is invalid. """
  51. return not self.result
  52. @property
  53. def valid(self) -> bool:
  54. """ It validate target, and return True when valid. """
  55. return self.result
  56. class nick_validator(validator):
  57. """
  58. This validate nick. It is slow, and best to use only when loading
  59. users from file.
  60. """
  61. def _check_all(self) -> None:
  62. # Minimum 4 characters
  63. if len(self.target) < 4:
  64. return self._failed()
  65. # Maximum 30 characters
  66. if len(self.target) > 30:
  67. return self._failed()
  68. # Could contain only
  69. for letter in self.target:
  70. # Letters
  71. if letter.isalpha():
  72. continue
  73. # Numbers
  74. if letter.isnumeric():
  75. continue
  76. return self._failed()
  77. class password_validator(validator):
  78. """
  79. This validate password. It is slow, and best to use only when
  80. loading users from file.
  81. """
  82. def _check_all(self) -> None:
  83. # Minimum 8 characters
  84. if len(self.target) < 8:
  85. return self._failed()
  86. # Maximum 40 characters
  87. if len(self.target) > 40:
  88. return self._failed()
  89. # Can not contain white chars
  90. for letter in self.target:
  91. if letter.isspace():
  92. return self._failed()
  93. class apikey_validator(validator):
  94. """ This is simple ApiKey validator """
  95. def _check_all(self) -> None:
  96. # ApiKey must contain proof size
  97. if len(self.target) != apikey_generator.size() * 2:
  98. return self._failed()
  99. class name_validator(validator):
  100. """
  101. This is validator for product name. It check that it is not blank,
  102. and it not contain white chars before and after content. It must have
  103. more or qeual of 4 and less than 40 characters.
  104. """
  105. def _check_all(self) -> None:
  106. # Minimum 4 characters
  107. if len(self.target) < 4:
  108. return self._failed()
  109. # Maximum 40 characters
  110. if len(self.target) > 40:
  111. return self._failed()
  112. # Must be trimed
  113. if len(self.target.strip()) != len(self.target):
  114. return self._failed()
  115. class description_validator(validator):
  116. """
  117. This is validator for product description. It could be blank, but can not
  118. have white chars before and after content (must be trimmed), and coud has
  119. only 500 chars.
  120. """
  121. def _check_all(self) -> None:
  122. # Could be blank
  123. if len(self.target) == 0:
  124. return
  125. # Must be trimmed
  126. if len(self.target.strip()) != len(self.target):
  127. return self._failed()
  128. # Must has max 500 characters.
  129. if len(self.target) > 500:
  130. return self._failed()
  131. class barcode_validator(validator):
  132. """
  133. This is barcode validator. Barcode must be string, which contain number
  134. with 8, 12 or 13 digits. That is standard EAN.
  135. """
  136. def _check_all(self) -> None:
  137. # Must has only digits
  138. if not self.target.isdigit():
  139. return self._failed()
  140. lenght = len(self.target)
  141. # Must has 8, 12 or 13 chars
  142. if lenght != 8 and lenght != 12 and lenght != 13:
  143. return self._failed()
  144. class author_validator(validator):
  145. """
  146. This validate author name. Author can not have less than 3 characters,
  147. and can not have more than 40 characters. It also must be trimmed.
  148. """
  149. def _check_all(self) -> None:
  150. # Must be trimmed
  151. if len(self.target) != len(self.target.strip()):
  152. return self._failed()
  153. # Must have more than 3 characters
  154. if len(self.target) < 3:
  155. return self._failed()
  156. # Must has max 40 characters
  157. if len(self.target) > 40:
  158. return self._failed()
  159. class phone_number_validator(validator):
  160. """
  161. This is phone number validator. Phone number must be in format
  162. like +CC XXXXXXXXX. This is standard of E.123 and E.164.
  163. """
  164. def _check_all(self) -> None:
  165. # Separate country code and number
  166. splited = self.target.split(" ")
  167. if len(splited) != 2:
  168. return self._failed()
  169. # Get it
  170. country_code = splited[0]
  171. number = splited[1]
  172. # Must start with "+"
  173. if country_code[0] != "+":
  174. return self._failed()
  175. country_code = country_code[1:]
  176. # Country code must be numeric
  177. if not country_code.isnumeric():
  178. return self._failed()
  179. # Number of course must be numeric
  180. if not number.isnumeric():
  181. return self._failed()
  182. # Country code length must be <1;3>
  183. if len(country_code) == 0 or len(country_code) > 3:
  184. return self._failed()
  185. # All number must have less than 16
  186. if len(country_code) + len(number) > 15:
  187. return self._failed()
  188. # And number mast has minimum 7 length
  189. if len(number) < 7:
  190. return self._failed()
  191. class email_validator(validator):
  192. """
  193. This is email validator. This validate email address in the standard
  194. format.
  195. """
  196. def _check_all(self) -> None:
  197. # Split name and domain
  198. splited = self.target.split("@")
  199. if len(splited) != 2:
  200. return self._failed()
  201. # Gat it
  202. name = splited[0]
  203. domain = splited[1]
  204. # Name must be in <1;128>
  205. if len(name) < 1 or len(name) > 128:
  206. return self._failed()
  207. # Domain can not has ".."
  208. if domain.find("..") != -1:
  209. return self._failed()
  210. splited = domain.split(".")
  211. # Must has more or equal 2 parts in domain
  212. if len(splited) < 2:
  213. return self._failed()
  214. # All parts must be in <1;128>
  215. for part in splited:
  216. if len(part) < 1 or len(part) > 128:
  217. return self._failed()