No Description
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.

model.py 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. # -*- coding: utf-8 -*-
  2. ## @file editorialmodel.py
  3. # Manage instance of an editorial model
  4. from EditorialModel.classes import EmClass
  5. from EditorialModel.fieldgroups import EmFieldGroup
  6. from EditorialModel.fields import EmField
  7. from EditorialModel.types import EmType
  8. import EditorialModel
  9. ## Manages the Editorial Model
  10. class Model(object):
  11. components_class = [ EmClass, EmField, EmFieldGroup, EmType ]
  12. ## Constructor
  13. #
  14. # @param backend unknown: A backend object instanciated from one of the classes in the backend module
  15. def __init__(self, backend):
  16. self.backend = backend
  17. self._components = {'uids':{}, 'EmClass':[], 'EmType':[], 'EmField':[], 'EmFieldGroup':[]}
  18. self.load()
  19. @staticmethod
  20. ## Given a name return an EmComponent child class
  21. # @param class_name str : The name to identify an EmComponent class
  22. # @return A python class or False if the class_name is not a name of an EmComponent child class
  23. def emclass_from_name(class_name):
  24. for cls in Model.components_class:
  25. if cls.__name__ == class_name:
  26. return cls
  27. return False
  28. @staticmethod
  29. ## Given a python class return a name
  30. # @param cls : The python class we want the name
  31. # @return A class name as string or False if cls is not an EmComponent child class
  32. def name_from_emclass(cls):
  33. if cls not in Model.components_class:
  34. return False
  35. return cls.__name__
  36. ## Loads the structure of the Editorial Model
  37. #
  38. # Gets all the objects contained in that structure and creates a dict indexed by their uids
  39. def load(self):
  40. data = self.backend.load()
  41. for uid, component in data.items():
  42. cls_name = component['component']
  43. cls = self.emclass_from_name(cls_name)
  44. if cls:
  45. component['uid'] = uid
  46. # create a dict for the component and one indexed by uids, store instanciated component in it
  47. self._components['uids'][uid] = cls(component, self)
  48. self._components[cls_name].append(self._components['uids'][uid])
  49. else:
  50. raise ValueError("Unknow EmComponent class : '"+cls_name+"'")
  51. for emclass in Model.components_class:
  52. comp_list = self.components(emclass)
  53. self._components[self.name_from_emclass] = sorted(comp_list, key=lambda cur_comp: cur_comp.rank)
  54. # TODO : check integrity
  55. ## Saves data using the current backend
  56. def save(self):
  57. return self.backend.save()
  58. ## Given a EmComponent child class return a list of instances
  59. # @param cls EmComponent : A python class
  60. # @return a list of instances or False if the class is not an EmComponent child
  61. def components(self, cls):
  62. key_name = self.name_from_emclass(cls)
  63. return False if key_name is False else self._components[key_name]
  64. ## Return an EmComponent given an uid
  65. # @param uid int : An EmComponent uid
  66. # @return The corresponding instance or False if uid don't exists
  67. def component(self, uid):
  68. return False if uid not in self._components else self._components['uids'][uid]
  69. ## Return a new uid
  70. # @return a new uid
  71. def new_uid(self):
  72. used_uid = self._components.keys()
  73. return sorted(new_uid)[-1] + 1 if len(used_uid) > 0 else 1
  74. ## Create a component from a component type and datas
  75. #
  76. # @param component_type str : a component type ( component_class, component_fieldgroup, component_field or component_type )
  77. # @param datas dict : the options needed by the component creation
  78. def create_component(self, component_type, datas):
  79. datas['uid'] = self.new_uid
  80. em_component = self.emclass_from_name(component_type)(datas, self)
  81. self._components['uids'][em_component.uid] = em_component
  82. self._components[name_from_emclass(em_component.__class__)].append(em_component)
  83. return em_component
  84. ## Delete a component
  85. # @param uid int : Component identifier
  86. # @throw EditorialModel.components.EmComponentNotExistError
  87. # @todo unable uid check
  88. def delete_component(self, uid):
  89. if uid not in self._components[uid]:
  90. raise EditorialModel.components.EmComponentNotExistError()
  91. em_component = self._components[uid]
  92. if em_component.delete_p():
  93. self._components[name_from_emclass(em_component.__class__)].remove(em_component)
  94. del self._components['uids'][uid]
  95. return True
  96. ## Changes the current backend
  97. #
  98. # @param backend unknown: A backend object
  99. def set_backend(self, backend):
  100. self.backend = backend
  101. ## Returns a list of all the EmClass objects of the model
  102. def classes(self):
  103. return list(self._components[Model.name_from_emclass(EmClass)])