Bez popisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

datas.py 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #-*- coding: utf-8 -*-
  2. import warnings
  3. import inspect
  4. import re
  5. from lodel.context import LodelContext
  6. LodelContext.expose_modules(globals(), {
  7. 'lodel.leapi.datahandlers.datas_base': ['Boolean', 'Integer', 'Varchar',
  8. 'DateTime', 'Text', 'File'],
  9. 'lodel.exceptions': ['LodelException', 'LodelExceptions',
  10. 'LodelFatalError', 'DataNoneValid', 'FieldValidationError']})
  11. ##@brief Data field designed to handle formated strings
  12. class FormatString(Varchar):
  13. help = 'Automatic string field, designed to use the str % operator to \
  14. build its content'
  15. base_type = 'char'
  16. ##@brief Build its content with a field list and a format string
  17. # @param format_string str
  18. # @param field_list list : List of field to use
  19. # @param **kwargs
  20. def __init__(self, format_string, field_list, **kwargs):
  21. self._field_list = field_list
  22. self._format_string = format_string
  23. super().__init__(internal='automatic', **kwargs)
  24. def _construct_data(self, emcomponent, fname, datas, cur_value):
  25. ret = self._format_string % tuple(
  26. datas[fname] for fname in self._field_list)
  27. if len(ret) > self.max_length:
  28. warnings.warn("Format field overflow. Truncating value")
  29. ret = ret[:self.max_length]
  30. return ret
  31. ##@brief Varchar validated by a regex
  32. class Regex(Varchar):
  33. help = 'String field validated with a regex. Takes two options : \
  34. max_length and regex'
  35. base_type = 'char'
  36. ##@brief A string field validated by a regex
  37. # @param regex str : a regex string (passed as argument to re.compile())
  38. # @param max_length int : the max length for this field (default : 10)
  39. # @param **kwargs
  40. def __init__(self, regex='', max_length=10, **kwargs):
  41. self.regex = regex
  42. self.compiled_re = re.compile(regex) # trigger an error if invalid regex
  43. super(self.__class__, self).__init__(max_length=max_length, **kwargs)
  44. ##@brief Check and cast value in appropriate type
  45. #@param value *
  46. #@throw FieldValidationError if value is unappropriate or can not be cast
  47. #@return value
  48. def _check_data_value(self, value):
  49. value = super()._check_data_value(value)
  50. if not self.compiled_re.match(value) or len(value) > self.max_length:
  51. msg = '"%s" doesn\'t match the regex "%s"' % (value, self.regex)
  52. raise FieldValidationError(msg)
  53. return value
  54. def can_override(self, data_handler):
  55. if not super().can_override(data_handler):
  56. return False
  57. if data_handler.max_length != self.max_length:
  58. return False
  59. return True
  60. ##@brief Handles uniq ID
  61. class UniqID(Integer):
  62. help = 'Fieldtype designed to handle editorial model UID'
  63. base_type = 'int'
  64. ##@brief A uid field
  65. # @param **kwargs
  66. def __init__(self, **kwargs):
  67. kwargs['internal'] = 'automatic'
  68. super(self.__class__, self).__init__(primary_key = True, **kwargs)
  69. def construct_data(self, emcomponent, fname, datas, cur_value):
  70. if cur_value is None:
  71. #Ask datasource to provide a new uniqID
  72. return emcomponent._ro_datasource.new_numeric_id(emcomponent)
  73. return cur_value
  74. class LeobjectSubclassIdentifier(Varchar):
  75. help = 'Datahandler designed to handle LeObject subclass identifier in DB'
  76. base_type = 'varchar'
  77. def __init__(self, **kwargs):
  78. if 'internal' in kwargs and not kwargs['internal']:
  79. raise RuntimeError(self.__class__.__name__+" datahandler can only \
  80. be internal")
  81. kwargs['internal'] = True
  82. super().__init__(**kwargs)
  83. def construct_data(self, emcomponent, fname, datas, cur_value):
  84. cls = emcomponent
  85. if not inspect.isclass(emcomponent):
  86. cls = emcomponent.__class__
  87. return cls.__name__
  88. ##@brief Data field designed to handle concatenated fields
  89. class Concat(FormatString):
  90. help = 'Automatic strings concatenation'
  91. base_type = 'char'
  92. ##@brief Build its content with a field list and a separator
  93. # @param field_list list : List of field to use
  94. # @param separator str
  95. # @param **kwargs
  96. def __init__(self, field_list, separator=' ', **kwargs):
  97. format_string = separator.join(['%s' for _ in field_list])
  98. super().__init__(format_string=format_string,
  99. field_list=field_list,
  100. **kwargs)
  101. class Password(Varchar):
  102. help = 'Handle passwords'
  103. base_type = 'password'
  104. pass
  105. class VarcharList(Varchar):
  106. help = 'DataHandler designed to make a list out of a string.'
  107. base_type = 'varchar'
  108. def __init__(self, delimiter=' ', **kwargs):
  109. if not isinstance(delimiter, str):
  110. raise LodelException("The delimiter has to be a string, %s given" % type(delimiter))
  111. self.delimiter = str(delimiter)
  112. super().__init__(**kwargs)
  113. def construct_data(self, emcomponent, fname, datas, cur_value):
  114. result = cur_value.split(self.delimiter)
  115. return result