Nenhuma descrição
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

classes.py 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. # -*- coding: utf-8 -*-
  2. ## @file classes.py
  3. # @see EditorialModel::classes::EmClass
  4. import copy
  5. # imports used in classtypes <-> actual model checks
  6. import difflib
  7. import warnings
  8. import EditorialModel
  9. from EditorialModel.components import EmComponent
  10. from EditorialModel.classtypes import EmClassType
  11. ## @brief Manipulate Classes of the Editorial Model
  12. # Create classes of object.
  13. # @see EmClass, EditorialModel.types.EmType, EditorialModel.fieldgroups.EmFieldGroup, EmField
  14. # @todo sortcolumn handling
  15. class EmClass(EmComponent):
  16. ranked_in = 'classtype'
  17. ## EmClass instanciation
  18. # @todo Classtype initialisation and test is not good EmClassType should give an answer or something like that
  19. # @todo defines types check for icon and sortcolumn
  20. def __init__(self, model, uid, name, classtype, icon='0', sortcolumn='rank', string=None, help_text=None, date_update=None, date_create=None, rank=None):
  21. if EmClassType.get(classtype) is None:
  22. raise AttributeError("Unknown classtype '%s'" % classtype)
  23. self.classtype = classtype
  24. self.icon = icon
  25. self.sortcolumn = sortcolumn # 'rank'
  26. super(EmClass, self).__init__(model=model, uid=uid, name=name, string=string, help_text=help_text, date_update=date_update, date_create=date_create, rank=rank)
  27. ## @brief Check if the EmComponent is valid
  28. #
  29. # This function add default and common fields to the EmClass if they are not yet created (and raises warning if existing common fields are outdated given the one describe in EditorialModel.classtypes
  30. # @throw EmComponentCheckError if fails
  31. #
  32. # @warning If default parameters of EmField constructor changes this method can be broken
  33. def check(self):
  34. # Checks that this class is up to date given the common_fields described in EditorialModel.classtypes
  35. # if not just print a warning, don't raise an Exception
  36. for field in self.fields():
  37. if field.name in EditorialModel.classtypes.common_fields:
  38. # Building fieltypes options to match the ones stored in EditorialModel.classtypes
  39. ftype_opts = field.fieldtype_options()
  40. ftype_opts['fieldtype'] = field.fieldtype
  41. ftype_opts['string'] = field.string
  42. ctype_opts = EditorialModel.classtypes.common_fields[field.name]
  43. #Adding default value for options nullable, uniq and internal to fieldtypes options stored in classtypes
  44. defaults = { 'nullable': False, 'uniq': False, 'internal': False}
  45. for opt_name, opt_val in defaults.items():
  46. if opt_name not in ctype_opts:
  47. ctype_opts[opt_name] = opt_val
  48. if ftype_opts != ctype_opts:
  49. field.set_fieldtype_options(**ctype_opts)
  50. # If options mismatch produce a diff and display a warning
  51. ctype_opts = [ "%s: %s\n"%(repr(k), repr(ctype_opts[k])) for k in sorted(ctype_opts.keys())]
  52. ftype_opts = [ "%s: %s\n"%(repr(k), repr(ftype_opts[k])) for k in sorted(ftype_opts.keys())]
  53. diff_list = difflib.unified_diff(
  54. ctype_opts,
  55. ftype_opts,
  56. fromfile="Classtypes.%s" % field.name,
  57. tofile="CurrentModel_%s.%s" % (self.name, field.name)
  58. )
  59. diff = ''.join(diff_list)
  60. warnings.warn("LOADED MODEL IS OUTDATED !!! The common_fields defined in classtypes differs from the fields in this model.\nHere is a diff : \n%s" % diff)
  61. for fname in self.default_fields_list().keys():
  62. if fname not in [f.name for f in self.fields()]:
  63. self.model.add_default_class_fields(self.uid)
  64. super(EmClass, self).check()
  65. ## @brief Return the default fields list for this EmClass
  66. # @return a dict with key = fieldname and value is a dict to pass to the EditorialModel::model::Model::creat_component() method
  67. def default_fields_list(self):
  68. ctype = EditorialModel.classtypes.EmClassType.get(self.classtype)
  69. res = ctype['default_fields']
  70. for k, v in EditorialModel.classtypes.common_fields.items():
  71. res[k] = copy.copy(v)
  72. return res
  73. ## @brief Delete a class if it's ''empty''
  74. # If a class has no fieldgroups delete it
  75. # @return bool : True if deleted False if deletion aborded
  76. def delete_check(self):
  77. for emtype in self.model.components(EditorialModel.types.EmType):
  78. if emtype.class_id == self.uid:
  79. return False
  80. #If the class contains EmField that are not added by default, you cannot delete the EmClass
  81. if len([f for f in self.fields() if f.name not in self.default_fields_list().keys()]) > 0:
  82. return False
  83. return True
  84. ## Retrieve list of the field_groups of this class
  85. # @return A list of fieldgroups instance
  86. def _fieldgroups(self):
  87. ret = []
  88. for fieldgroup in self.model.components(EditorialModel.fieldgroups.EmFieldGroup):
  89. if fieldgroup.class_id == self.uid:
  90. ret.append(fieldgroup)
  91. return ret
  92. ## Retrieve list of fields
  93. # @return fields [EmField]:
  94. def fields(self, relational=True):
  95. if relational:
  96. return [f for f in self.model.components('EmField') if f.class_id == self.uid]
  97. else:
  98. return [f for f in self.model.components('EmField') if f.class_id == self.uid and f.fieldtype != 'rel2type' and f.rel_field_id is None]
  99. ## Retrieve list of type of this class
  100. # @return types [EditorialModel.types.EmType]:
  101. def types(self):
  102. ret = []
  103. for emtype in self.model.components(EditorialModel.types.EmType):
  104. if emtype.class_id == self.uid:
  105. ret.append(emtype)
  106. return ret
  107. ## Add a new EditorialModel.types.EmType that can ben linked to this class
  108. # @param em_type EditorialModel.types.EmType: type to link
  109. # @return success bool: done or not
  110. # @deprecated To do this add a rel2type field to any fieldtype of this EmClass
  111. def link_type(self, em_type):
  112. pass
  113. ## Retrieve list of EditorialModel.types.EmType that are linked to this class
  114. # @return types [EditorialModel.types.EmType]:
  115. def linked_types(self):
  116. res = list()
  117. for field in self.fields():
  118. if field.fieldtype_instance().name == 'rel2type':
  119. res.append(self.model.component(field.rel_to_type_id))
  120. return res