No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

175 líneas
6.2 KiB

  1. from . import base
  2. #------------------------ Abstract class for behavior --------------------------
  3. class Behavior(object):
  4. """
  5. Behavior (validation, encoding, and transformations) for vobjects.
  6. Abstract class to describe vobject options, requirements and encodings.
  7. Behaviors are used for root components like VCALENDAR, for subcomponents
  8. like VEVENT, and for individual lines in components.
  9. Behavior subclasses are not meant to be instantiated, all methods should
  10. be classmethods.
  11. @cvar name:
  12. The uppercase name of the object described by the class, or a generic
  13. name if the class defines behavior for many objects.
  14. @cvar description:
  15. A brief excerpt from the RFC explaining the function of the component or
  16. line.
  17. @cvar versionString:
  18. The string associated with the component, for instance, 2.0 if there's a
  19. line like VERSION:2.0, an empty string otherwise.
  20. @cvar knownChildren:
  21. A dictionary with uppercased component/property names as keys and a
  22. tuple (min, max, id) as value, where id is the id used by
  23. L{registerBehavior}, min and max are the limits on how many of this child
  24. must occur. None is used to denote no max or no id.
  25. @cvar quotedPrintable:
  26. A boolean describing whether the object should be encoded and decoded
  27. using quoted printable line folding and character escaping.
  28. @cvar defaultBehavior:
  29. Behavior to apply to ContentLine children when no behavior is found.
  30. @cvar hasNative:
  31. A boolean describing whether the object can be transformed into a more
  32. Pythonic object.
  33. @cvar isComponent:
  34. A boolean, True if the object should be a Component.
  35. @cvar sortFirst:
  36. The lower-case list of children which should come first when sorting.
  37. @cvar allowGroup:
  38. Whether or not vCard style group prefixes are allowed.
  39. """
  40. name = ''
  41. description = ''
  42. versionString = ''
  43. knownChildren = {}
  44. quotedPrintable = False
  45. defaultBehavior = None
  46. hasNative = False
  47. isComponent = False
  48. allowGroup = False
  49. forceUTC = False
  50. sortFirst = []
  51. def __init__(self):
  52. err = "Behavior subclasses are not meant to be instantiated"
  53. raise base.VObjectError(err)
  54. @classmethod
  55. def validate(cls, obj, raiseException=False, complainUnrecognized=False):
  56. """Check if the object satisfies this behavior's requirements.
  57. @param obj:
  58. The L{ContentLine<base.ContentLine>} or
  59. L{Component<base.Component>} to be validated.
  60. @param raiseException:
  61. If True, raise a L{base.ValidateError} on validation failure.
  62. Otherwise return a boolean.
  63. @param complainUnrecognized:
  64. If True, fail to validate if an uncrecognized parameter or child is
  65. found. Otherwise log the lack of recognition.
  66. """
  67. if not cls.allowGroup and obj.group is not None:
  68. err = "{0} has a group, but this object doesn't support groups".format(obj)
  69. raise base.VObjectError(err)
  70. if isinstance(obj, base.ContentLine):
  71. return cls.lineValidate(obj, raiseException, complainUnrecognized)
  72. elif isinstance(obj, base.Component):
  73. count = {}
  74. for child in obj.getChildren():
  75. if not child.validate(raiseException, complainUnrecognized):
  76. return False
  77. name = child.name.upper()
  78. count[name] = count.get(name, 0) + 1
  79. for key, val in cls.knownChildren.items():
  80. if count.get(key, 0) < val[0]:
  81. if raiseException:
  82. m = "{0} components must contain at least {1} {2}"
  83. raise base.ValidateError(m .format(cls.name, val[0], key))
  84. return False
  85. if val[1] and count.get(key, 0) > val[1]:
  86. if raiseException:
  87. m = "{0} components cannot contain more than {1} {2}"
  88. raise base.ValidateError(m.format(cls.name, val[1], key))
  89. return False
  90. return True
  91. else:
  92. err = "{0} is not a Component or Contentline".format(obj)
  93. raise base.VObjectError(err)
  94. @classmethod
  95. def lineValidate(cls, line, raiseException, complainUnrecognized):
  96. """Examine a line's parameters and values, return True if valid."""
  97. return True
  98. @classmethod
  99. def decode(cls, line):
  100. if line.encoded:
  101. line.encoded = 0
  102. @classmethod
  103. def encode(cls, line):
  104. if not line.encoded:
  105. line.encoded = 1
  106. @classmethod
  107. def transformToNative(cls, obj):
  108. """
  109. Turn a ContentLine or Component into a Python-native representation.
  110. If appropriate, turn dates or datetime strings into Python objects.
  111. Components containing VTIMEZONEs turn into VtimezoneComponents.
  112. """
  113. return obj
  114. @classmethod
  115. def transformFromNative(cls, obj):
  116. """
  117. Inverse of transformToNative.
  118. """
  119. raise base.NativeError("No transformFromNative defined")
  120. @classmethod
  121. def generateImplicitParameters(cls, obj):
  122. """Generate any required information that don't yet exist."""
  123. pass
  124. @classmethod
  125. def serialize(cls, obj, buf, lineLength, validate=True, *args, **kwargs):
  126. """
  127. Set implicit parameters, do encoding, return unicode string.
  128. If validate is True, raise VObjectError if the line doesn't validate
  129. after implicit parameters are generated.
  130. Default is to call base.defaultSerialize.
  131. """
  132. cls.generateImplicitParameters(obj)
  133. if validate:
  134. cls.validate(obj, raiseException=True)
  135. if obj.isNative:
  136. transformed = obj.transformFromNative()
  137. undoTransform = True
  138. else:
  139. transformed = obj
  140. undoTransform = False
  141. out = base.defaultSerialize(transformed, buf, lineLength)
  142. if undoTransform:
  143. obj.transformToNative()
  144. return out
  145. @classmethod
  146. def valueRepr(cls, line):
  147. """return the representation of the given content line value"""
  148. return line.value