context_models.py 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. # coding=utf-8
  2. import typing
  3. from datetime import datetime
  4. from slugify import slugify
  5. from sqlalchemy.orm import Session
  6. from tracim import CFG
  7. from tracim.models import User
  8. from tracim.models.auth import Profile
  9. from tracim.models.data import Content
  10. from tracim.models.data import ContentRevisionRO
  11. from tracim.models.data import Workspace, UserRoleInWorkspace
  12. from tracim.models.workspace_menu_entries import default_workspace_menu_entry
  13. from tracim.models.workspace_menu_entries import WorkspaceMenuEntry
  14. class MoveParams(object):
  15. """
  16. Json body params for move action
  17. """
  18. def __init__(self, new_parent_id: str, new_workspace_id: str = None):
  19. self.new_parent_id = new_parent_id
  20. self.new_workspace_id = new_workspace_id
  21. class LoginCredentials(object):
  22. """
  23. Login credentials model for login
  24. """
  25. def __init__(self, email: str, password: str):
  26. self.email = email
  27. self.password = password
  28. class WorkspaceAndContentPath(object):
  29. """
  30. Paths params with workspace id and content_id
  31. """
  32. def __init__(self, workspace_id: int, content_id: int):
  33. self.content_id = content_id
  34. self.workspace_id = workspace_id
  35. class CommentPath(object):
  36. """
  37. Paths params with workspace id and content_id
  38. """
  39. def __init__(self, workspace_id: int, content_id: int, comment_id: int):
  40. self.content_id = content_id
  41. self.workspace_id = workspace_id
  42. self.comment_id = comment_id
  43. class ContentFilter(object):
  44. """
  45. Content filter model
  46. """
  47. def __init__(
  48. self,
  49. parent_id: int = None,
  50. show_archived: int = 0,
  51. show_deleted: int = 0,
  52. show_active: int = 1,
  53. ):
  54. self.parent_id = parent_id
  55. self.show_archived = bool(show_archived)
  56. self.show_deleted = bool(show_deleted)
  57. self.show_active = bool(show_active)
  58. class ContentCreation(object):
  59. """
  60. Content creation model
  61. """
  62. def __init__(
  63. self,
  64. label: str,
  65. content_type: str,
  66. ):
  67. self.label = label
  68. self.content_type = content_type
  69. class CommentCreation(object):
  70. """
  71. Comment creation model
  72. """
  73. def __init__(
  74. self,
  75. raw_content: str,
  76. ):
  77. self.raw_content = raw_content
  78. class SetContentStatus(object):
  79. """
  80. Set content status
  81. """
  82. def __init__(
  83. self,
  84. status: str,
  85. ):
  86. self.status = status
  87. class HTMLDocumentUpdate(object):
  88. """
  89. Comment creation model
  90. """
  91. def __init__(
  92. self,
  93. label: str,
  94. raw_content: str,
  95. ):
  96. self.label = label
  97. self.raw_content = raw_content
  98. class ThreadUpdate(object):
  99. """
  100. Comment creation model
  101. """
  102. def __init__(
  103. self,
  104. label: str,
  105. raw_content: str,
  106. ):
  107. self.label = label
  108. self.raw_content = raw_content
  109. class UserInContext(object):
  110. """
  111. Interface to get User data and User data related to context.
  112. """
  113. def __init__(self, user: User, dbsession: Session, config: CFG):
  114. self.user = user
  115. self.dbsession = dbsession
  116. self.config = config
  117. # Default
  118. @property
  119. def email(self) -> str:
  120. return self.user.email
  121. @property
  122. def user_id(self) -> int:
  123. return self.user.user_id
  124. @property
  125. def public_name(self) -> str:
  126. return self.display_name
  127. @property
  128. def display_name(self) -> str:
  129. return self.user.display_name
  130. @property
  131. def created(self) -> datetime:
  132. return self.user.created
  133. @property
  134. def is_active(self) -> bool:
  135. return self.user.is_active
  136. @property
  137. def timezone(self) -> str:
  138. return self.user.timezone
  139. @property
  140. def profile(self) -> Profile:
  141. return self.user.profile.name
  142. # Context related
  143. @property
  144. def calendar_url(self) -> typing.Optional[str]:
  145. # TODO - G-M - 20-04-2018 - [Calendar] Replace calendar code to get
  146. # url calendar url.
  147. #
  148. # from tracim.lib.calendar import CalendarManager
  149. # calendar_manager = CalendarManager(None)
  150. # return calendar_manager.get_workspace_calendar_url(self.workspace_id)
  151. return None
  152. @property
  153. def avatar_url(self) -> typing.Optional[str]:
  154. # TODO - G-M - 20-04-2018 - [Avatar] Add user avatar feature
  155. return None
  156. class WorkspaceInContext(object):
  157. """
  158. Interface to get Workspace data and Workspace data related to context.
  159. """
  160. def __init__(self, workspace: Workspace, dbsession: Session, config: CFG):
  161. self.workspace = workspace
  162. self.dbsession = dbsession
  163. self.config = config
  164. @property
  165. def workspace_id(self) -> int:
  166. """
  167. numeric id of the workspace.
  168. """
  169. return self.workspace.workspace_id
  170. @property
  171. def id(self) -> int:
  172. """
  173. alias of workspace_id
  174. """
  175. return self.workspace_id
  176. @property
  177. def label(self) -> str:
  178. """
  179. get workspace label
  180. """
  181. return self.workspace.label
  182. @property
  183. def description(self) -> str:
  184. """
  185. get workspace description
  186. """
  187. return self.workspace.description
  188. @property
  189. def slug(self) -> str:
  190. """
  191. get workspace slug
  192. """
  193. return slugify(self.workspace.label)
  194. @property
  195. def sidebar_entries(self) -> typing.List[WorkspaceMenuEntry]:
  196. """
  197. get sidebar entries, those depends on activated apps.
  198. """
  199. # TODO - G.M - 22-05-2018 - Rework on this in
  200. # order to not use hardcoded list
  201. # list should be able to change (depending on activated/disabled
  202. # apps)
  203. return default_workspace_menu_entry(self.workspace)
  204. class UserRoleWorkspaceInContext(object):
  205. """
  206. Interface to get UserRoleInWorkspace data and related content
  207. """
  208. def __init__(
  209. self,
  210. user_role: UserRoleInWorkspace,
  211. dbsession: Session,
  212. config: CFG,
  213. )-> None:
  214. self.user_role = user_role
  215. self.dbsession = dbsession
  216. self.config = config
  217. @property
  218. def user_id(self) -> int:
  219. """
  220. User who has the role has this id
  221. :return: user id as integer
  222. """
  223. return self.user_role.user_id
  224. @property
  225. def workspace_id(self) -> int:
  226. """
  227. This role apply only on the workspace with this workspace_id
  228. :return: workspace id as integer
  229. """
  230. return self.user_role.workspace_id
  231. # TODO - G.M - 23-05-2018 - Check the API spec for this this !
  232. @property
  233. def role_id(self) -> int:
  234. """
  235. role as int id, each value refer to a different role.
  236. """
  237. return self.user_role.role
  238. @property
  239. def role(self) -> str:
  240. return self.role_slug
  241. @property
  242. def role_slug(self) -> str:
  243. """
  244. simple name of the role of the user.
  245. can be anything from UserRoleInWorkspace SLUG, like
  246. 'not_applicable', 'reader',
  247. 'contributor', 'content-manager', 'workspace-manager'
  248. :return: user workspace role as slug.
  249. """
  250. return UserRoleInWorkspace.SLUG[self.user_role.role]
  251. @property
  252. def user(self) -> UserInContext:
  253. """
  254. User who has this role, with context data
  255. :return: UserInContext object
  256. """
  257. return UserInContext(
  258. self.user_role.user,
  259. self.dbsession,
  260. self.config
  261. )
  262. @property
  263. def workspace(self) -> WorkspaceInContext:
  264. """
  265. Workspace related to this role, with his context data
  266. :return: WorkspaceInContext object
  267. """
  268. return WorkspaceInContext(
  269. self.user_role.workspace,
  270. self.dbsession,
  271. self.config
  272. )
  273. class ContentInContext(object):
  274. """
  275. Interface to get Content data and Content data related to context.
  276. """
  277. def __init__(self, content: Content, dbsession: Session, config: CFG):
  278. self.content = content
  279. self.dbsession = dbsession
  280. self.config = config
  281. # Default
  282. @property
  283. def content_id(self) -> int:
  284. return self.content.content_id
  285. @property
  286. def id(self) -> int:
  287. return self.content_id
  288. @property
  289. def parent_id(self) -> int:
  290. """
  291. Return parent_id of the content
  292. """
  293. return self.content.parent_id
  294. @property
  295. def workspace_id(self) -> int:
  296. return self.content.workspace_id
  297. @property
  298. def label(self) -> str:
  299. return self.content.label
  300. @property
  301. def content_type(self) -> str:
  302. return self.content.type
  303. @property
  304. def sub_content_types(self) -> typing.List[str]:
  305. return [_type.slug for _type in self.content.get_allowed_content_types()]
  306. @property
  307. def status(self) -> str:
  308. return self.content.status
  309. @property
  310. def is_archived(self):
  311. return self.content.is_archived
  312. @property
  313. def is_deleted(self):
  314. return self.content.is_deleted
  315. @property
  316. def raw_content(self):
  317. return self.content.description
  318. @property
  319. def author(self):
  320. return UserInContext(
  321. dbsession=self.dbsession,
  322. config=self.config,
  323. user=self.content.owner
  324. )
  325. @property
  326. def current_revision_id(self):
  327. return self.content.revision_id
  328. @property
  329. def created(self):
  330. return self.content.created
  331. @property
  332. def modified(self):
  333. return self.updated
  334. @property
  335. def updated(self):
  336. return self.content.updated
  337. @property
  338. def last_modifier(self):
  339. # TODO - G.M - 2018-06-173 - Repair owner/last modifier
  340. return self.author
  341. # Context-related
  342. @property
  343. def show_in_ui(self):
  344. # TODO - G.M - 31-05-2018 - Enable Show_in_ui params
  345. # if false, then do not show content in the treeview.
  346. # This may his maybe used for specific contents or for sub-contents.
  347. # Default is True.
  348. # In first version of the API, this field is always True
  349. return True
  350. @property
  351. def slug(self):
  352. return slugify(self.content.label)
  353. class RevisionInContext(object):
  354. """
  355. Interface to get Content data and Content data related to context.
  356. """
  357. def __init__(self, content: ContentRevisionRO, dbsession: Session, config: CFG):
  358. self.revision = content
  359. self.dbsession = dbsession
  360. self.config = config
  361. # Default
  362. @property
  363. def content_id(self) -> int:
  364. return self.revision.content_id
  365. @property
  366. def id(self) -> int:
  367. return self.content_id
  368. @property
  369. def parent_id(self) -> int:
  370. """
  371. Return parent_id of the content
  372. """
  373. return self.revision.parent_id
  374. @property
  375. def workspace_id(self) -> int:
  376. return self.revision.workspace_id
  377. @property
  378. def label(self) -> str:
  379. return self.revision.label
  380. @property
  381. def content_type(self) -> str:
  382. return self.revision.type
  383. @property
  384. def sub_content_types(self) -> typing.List[str]:
  385. return [_type.slug for _type
  386. in self.revision.node.get_allowed_content_types()]
  387. @property
  388. def status(self) -> str:
  389. return self.revision.status
  390. @property
  391. def is_archived(self):
  392. return self.revision.is_archived
  393. @property
  394. def is_deleted(self):
  395. return self.revision.is_deleted
  396. @property
  397. def raw_content(self):
  398. return self.revision.description
  399. @property
  400. def author(self):
  401. return UserInContext(
  402. dbsession=self.dbsession,
  403. config=self.config,
  404. user=self.revision.owner
  405. )
  406. @property
  407. def revision_id(self):
  408. return self.revision.revision_id
  409. @property
  410. def created(self):
  411. return self.revision.created
  412. @property
  413. def modified(self):
  414. return self.updated
  415. @property
  416. def updated(self):
  417. return self.revision.updated
  418. @property
  419. def last_modifier(self):
  420. # TODO - G.M - 2018-06-173 - Repair owner/last modifier
  421. return self.author
  422. @property
  423. def comments_ids(self):
  424. # TODO - G.M - 2018-06-173 - Return comments related to this revision
  425. return []
  426. # Context-related
  427. @property
  428. def show_in_ui(self):
  429. # TODO - G.M - 31-05-2018 - Enable Show_in_ui params
  430. # if false, then do not show content in the treeview.
  431. # This may his maybe used for specific contents or for sub-contents.
  432. # Default is True.
  433. # In first version of the API, this field is always True
  434. return True
  435. @property
  436. def slug(self):
  437. return slugify(self.revision.label)