contents.py 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. # -*- coding: utf-8 -*-
  2. import typing
  3. from enum import Enum
  4. from tracim_backend.extensions import app_list
  5. from tracim_backend.exceptions import ContentTypeNotExist
  6. from tracim_backend.exceptions import ContentStatusNotExist
  7. ####
  8. # Content Status
  9. from tracim_backend.lib.core.application import ApplicationApi
  10. if typing.TYPE_CHECKING:
  11. from tracim_backend.app_models.applications import Application
  12. class GlobalStatus(Enum):
  13. OPEN = 'open'
  14. CLOSED = 'closed'
  15. class ContentStatus(object):
  16. """
  17. ContentStatus object class
  18. """
  19. def __init__(
  20. self,
  21. slug: str,
  22. global_status: str,
  23. label: str,
  24. fa_icon: str,
  25. hexcolor: str,
  26. ):
  27. self.slug = slug
  28. self.global_status = global_status
  29. self.label = label
  30. self.fa_icon = fa_icon
  31. self.hexcolor = hexcolor
  32. open_status = ContentStatus(
  33. slug='open',
  34. global_status=GlobalStatus.OPEN.value,
  35. label='Open',
  36. fa_icon='square-o',
  37. hexcolor='#3f52e3',
  38. )
  39. closed_validated_status = ContentStatus(
  40. slug='closed-validated',
  41. global_status=GlobalStatus.CLOSED.value,
  42. label='Validated',
  43. fa_icon='check-square-o',
  44. hexcolor='#008000',
  45. )
  46. closed_unvalidated_status = ContentStatus(
  47. slug='closed-unvalidated',
  48. global_status=GlobalStatus.CLOSED.value,
  49. label='Cancelled',
  50. fa_icon='close',
  51. hexcolor='#f63434',
  52. )
  53. closed_deprecated_status = ContentStatus(
  54. slug='closed-deprecated',
  55. global_status=GlobalStatus.CLOSED.value,
  56. label='Deprecated',
  57. fa_icon='warning',
  58. hexcolor='#ababab',
  59. )
  60. class ContentStatusList(object):
  61. OPEN = open_status
  62. def __init__(self, extend_content_status: typing.List[ContentStatus]):
  63. self._content_status = [self.OPEN]
  64. self._content_status.extend(extend_content_status)
  65. def get_one_by_slug(self, slug: str) -> ContentStatus:
  66. for item in self._content_status:
  67. if item.slug == slug:
  68. return item
  69. raise ContentStatusNotExist()
  70. def get_all_slugs_values(self) -> typing.List[str]:
  71. """ Get alls slugs"""
  72. return [item.slug for item in self._content_status]
  73. def get_all(self) -> typing.List[ContentStatus]:
  74. """ Get all status"""
  75. return [item for item in self._content_status]
  76. def get_default_status(self) -> ContentStatus:
  77. return self.OPEN
  78. CONTENT_STATUS = ContentStatusList(
  79. [
  80. closed_validated_status,
  81. closed_unvalidated_status,
  82. closed_deprecated_status,
  83. ]
  84. )
  85. ####
  86. # ContentType
  87. class ContentType(object):
  88. """
  89. Future ContentType object class
  90. """
  91. def __init__(
  92. self,
  93. slug: str,
  94. fa_icon: str,
  95. hexcolor: str,
  96. label: str,
  97. creation_label: str,
  98. available_statuses: typing.List[ContentStatus],
  99. slug_alias: typing.List[str] = None,
  100. allow_sub_content: bool = False,
  101. ):
  102. self.slug = slug
  103. self.fa_icon = fa_icon
  104. self.hexcolor = hexcolor
  105. self.label = label
  106. self.creation_label = creation_label
  107. self.available_statuses = available_statuses
  108. self.slug_alias = slug_alias
  109. self.allow_sub_content = allow_sub_content
  110. THREAD_TYPE = 'thread'
  111. FILE_TYPE = 'file'
  112. MARKDOWNPLUSPAGE_TYPE = 'markdownpage'
  113. HTML_DOCUMENTS_TYPE = 'html-document'
  114. FOLDER_TYPE = 'folder'
  115. # TODO - G.M - 31-05-2018 - Set Better Event params
  116. event_type = ContentType(
  117. slug='event',
  118. fa_icon='',
  119. hexcolor='',
  120. label='Event',
  121. creation_label='Event',
  122. available_statuses=CONTENT_STATUS.get_all(),
  123. )
  124. # TODO - G.M - 31-05-2018 - Set Better Event params
  125. comment_type = ContentType(
  126. slug='comment',
  127. fa_icon='',
  128. hexcolor='',
  129. label='Comment',
  130. creation_label='Comment',
  131. available_statuses=CONTENT_STATUS.get_all(),
  132. )
  133. class ContentTypeList(object):
  134. """
  135. ContentType List
  136. """
  137. Any_SLUG = 'any'
  138. Comment = comment_type
  139. Event = event_type
  140. @property
  141. def Folder(self):
  142. return self.get_one_by_slug(FOLDER_TYPE)
  143. @property
  144. def File(self):
  145. return self.get_one_by_slug(FILE_TYPE)
  146. @property
  147. def Page(self):
  148. return self.get_one_by_slug(HTML_DOCUMENTS_TYPE)
  149. @property
  150. def Thread(self):
  151. return self.get_one_by_slug(THREAD_TYPE)
  152. def __init__(self, app_list: typing.List['Application']):
  153. self.app_list = app_list
  154. self._special_contents_types = [self.Comment]
  155. self._extra_slugs = [self.Any_SLUG]
  156. @property
  157. def _content_types(self):
  158. app_api = ApplicationApi(self.app_list)
  159. content_types = app_api.get_content_types()
  160. return content_types
  161. def get_one_by_slug(self, slug: str) -> ContentType:
  162. """
  163. Get ContentType object according to slug
  164. match for both slug and slug_alias
  165. """
  166. content_types = self._content_types.copy()
  167. content_types.extend(self._special_contents_types)
  168. content_types.append(self.Event)
  169. for item in content_types:
  170. if item.slug == slug or (item.slug_alias and slug in item.slug_alias): # nopep8
  171. return item
  172. raise ContentTypeNotExist()
  173. def restricted_allowed_types_slug(self) -> typing.List[str]:
  174. """
  175. Return restricted list of content_type: don't return
  176. "any" slug, dont return content type slug alias , don't return event.
  177. Useful to restrict slug param in schema.
  178. """
  179. allowed_type_slug = [contents_type.slug for contents_type in self._content_types] # nopep8
  180. return allowed_type_slug
  181. def endpoint_allowed_types_slug(self) -> typing.List[str]:
  182. """
  183. Same as restricted_allowed_types_slug but with special content_type
  184. included like comments.
  185. """
  186. content_types = self._content_types
  187. content_types.extend(self._special_contents_types)
  188. allowed_type_slug = [contents_type.slug for contents_type in content_types] # nopep8
  189. return allowed_type_slug
  190. def query_allowed_types_slugs(self) -> typing.List[str]:
  191. """
  192. Return alls allowed types slug : content_type slug + all alias, any
  193. and special content_type like comment. Do not return event.
  194. Usefull allowed value to perform query to database.
  195. """
  196. allowed_types_slug = []
  197. content_types = self._content_types
  198. content_types.extend(self._special_contents_types)
  199. for content_type in content_types:
  200. allowed_types_slug.append(content_type.slug)
  201. if content_type.slug_alias:
  202. allowed_types_slug.extend(content_type.slug_alias)
  203. allowed_types_slug.extend(self._extra_slugs)
  204. return allowed_types_slug
  205. def default_allowed_content_properties(self, slug) -> dict:
  206. content_type = self.get_one_by_slug(slug)
  207. if content_type.allow_sub_content:
  208. sub_content_allowed = self.endpoint_allowed_types_slug()
  209. else:
  210. sub_content_allowed = [self.Comment.slug]
  211. properties_dict = {}
  212. for elem in sub_content_allowed:
  213. properties_dict[elem] = True
  214. return properties_dict
  215. CONTENT_TYPES = ContentTypeList(app_list)