zou 0.19.37__tar.gz → 0.19.39__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (421) hide show
  1. {zou-0.19.37/zou.egg-info → zou-0.19.39}/PKG-INFO +6 -6
  2. {zou-0.19.37 → zou-0.19.39}/setup.cfg +5 -5
  3. zou-0.19.39/zou/__init__.py +1 -0
  4. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/__init__.py +3 -0
  5. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/department.py +0 -24
  6. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/person.py +10 -7
  7. zou-0.19.39/zou/app/blueprints/crud/studio.py +33 -0
  8. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/persons/__init__.py +0 -2
  9. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/persons/resources.py +27 -103
  10. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/shots/resources.py +9 -5
  11. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/tasks/resources.py +3 -3
  12. {zou-0.19.37 → zou-0.19.39}/zou/app/mixin.py +2 -2
  13. {zou-0.19.37 → zou-0.19.39}/zou/app/models/person.py +4 -0
  14. zou-0.19.39/zou/app/models/studio.py +13 -0
  15. {zou-0.19.37 → zou-0.19.39}/zou/app/services/exception.py +4 -0
  16. {zou-0.19.37 → zou-0.19.39}/zou/app/services/persons_service.py +13 -7
  17. {zou-0.19.37 → zou-0.19.39}/zou/app/services/shots_service.py +25 -3
  18. {zou-0.19.37 → zou-0.19.39}/zou/app/services/sync_service.py +4 -0
  19. {zou-0.19.37 → zou-0.19.39}/zou/app/services/tasks_service.py +28 -0
  20. {zou-0.19.37 → zou-0.19.39}/zou/app/services/time_spents_service.py +44 -8
  21. {zou-0.19.37 → zou-0.19.39}/zou/app/services/user_service.py +4 -2
  22. {zou-0.19.37 → zou-0.19.39}/zou/app/swagger.py +21 -0
  23. zou-0.19.39/zou/migrations/versions/1bb55759146f_add_table_studio.py +67 -0
  24. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/9b85c14fa8a7_add_day_off_new_columns.py +1 -1
  25. {zou-0.19.37 → zou-0.19.39/zou.egg-info}/PKG-INFO +6 -6
  26. {zou-0.19.37 → zou-0.19.39}/zou.egg-info/SOURCES.txt +3 -0
  27. {zou-0.19.37 → zou-0.19.39}/zou.egg-info/requires.txt +5 -5
  28. zou-0.19.37/zou/__init__.py +0 -1
  29. {zou-0.19.37 → zou-0.19.39}/LICENSE +0 -0
  30. {zou-0.19.37 → zou-0.19.39}/README.rst +0 -0
  31. {zou-0.19.37 → zou-0.19.39}/pyproject.toml +0 -0
  32. {zou-0.19.37 → zou-0.19.39}/setup.py +0 -0
  33. {zou-0.19.37 → zou-0.19.39}/zou/app/__init__.py +0 -0
  34. {zou-0.19.37 → zou-0.19.39}/zou/app/api.py +0 -0
  35. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/__init__.py +0 -0
  36. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/assets/__init__.py +0 -0
  37. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/assets/resources.py +0 -0
  38. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/auth/__init__.py +0 -0
  39. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/auth/resources.py +0 -0
  40. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/breakdown/__init__.py +0 -0
  41. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/breakdown/resources.py +0 -0
  42. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/chats/__init__.py +0 -0
  43. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/chats/resources.py +0 -0
  44. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/comments/__init__.py +0 -0
  45. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/comments/resources.py +0 -0
  46. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/concepts/__init__.py +0 -0
  47. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/concepts/resources.py +0 -0
  48. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/asset_instance.py +0 -0
  49. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/attachment_file.py +0 -0
  50. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/base.py +0 -0
  51. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/chat.py +0 -0
  52. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/chat_message.py +0 -0
  53. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/comments.py +0 -0
  54. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/custom_action.py +0 -0
  55. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/day_off.py +0 -0
  56. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/entity.py +0 -0
  57. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/entity_link.py +0 -0
  58. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/entity_type.py +0 -0
  59. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/event.py +0 -0
  60. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/file_status.py +0 -0
  61. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/metadata_descriptor.py +0 -0
  62. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/milestone.py +0 -0
  63. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/news.py +0 -0
  64. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/notification.py +0 -0
  65. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/organisation.py +0 -0
  66. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/output_file.py +0 -0
  67. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/output_type.py +0 -0
  68. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/playlist.py +0 -0
  69. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/preview_background_file.py +0 -0
  70. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/preview_file.py +0 -0
  71. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/project.py +0 -0
  72. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/project_status.py +0 -0
  73. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/schedule_item.py +0 -0
  74. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/search_filter.py +0 -0
  75. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/search_filter_group.py +0 -0
  76. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/software.py +0 -0
  77. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/status_automation.py +0 -0
  78. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/subscription.py +0 -0
  79. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/task.py +0 -0
  80. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/task_status.py +0 -0
  81. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/task_type.py +0 -0
  82. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/time_spent.py +0 -0
  83. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/crud/working_file.py +0 -0
  84. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/edits/__init__.py +0 -0
  85. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/edits/resources.py +0 -0
  86. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/entities/__init__.py +0 -0
  87. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/entities/resources.py +0 -0
  88. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/events/__init__.py +0 -0
  89. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/events/resources.py +0 -0
  90. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/__init__.py +0 -0
  91. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/__init__.py +0 -0
  92. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/assets.py +0 -0
  93. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/base.py +0 -0
  94. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/casting.py +0 -0
  95. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/edits.py +0 -0
  96. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/persons.py +0 -0
  97. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/playlists.py +0 -0
  98. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/projects.py +0 -0
  99. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/shots.py +0 -0
  100. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/task_types.py +0 -0
  101. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/tasks.py +0 -0
  102. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/export/csv/time_spents.py +0 -0
  103. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/files/__init__.py +0 -0
  104. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/files/resources.py +0 -0
  105. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/index/__init__.py +0 -0
  106. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/index/resources.py +0 -0
  107. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/news/__init__.py +0 -0
  108. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/news/resources.py +0 -0
  109. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/playlists/__init__.py +0 -0
  110. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/playlists/resources.py +0 -0
  111. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/previews/__init__.py +0 -0
  112. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/previews/resources.py +0 -0
  113. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/projects/__init__.py +0 -0
  114. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/projects/resources.py +0 -0
  115. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/search/__init__.py +0 -0
  116. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/search/resources.py +0 -0
  117. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/shots/__init__.py +0 -0
  118. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/__init__.py +0 -0
  119. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/csv/__init__.py +0 -0
  120. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/csv/assets.py +0 -0
  121. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/csv/base.py +0 -0
  122. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/csv/casting.py +0 -0
  123. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/csv/edits.py +0 -0
  124. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/csv/persons.py +0 -0
  125. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/csv/shots.py +0 -0
  126. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/csv/task_type_estimations.py +0 -0
  127. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/kitsu.py +0 -0
  128. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/otio.py +0 -0
  129. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/__init__.py +0 -0
  130. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/assets.py +0 -0
  131. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/base.py +0 -0
  132. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/episode.py +0 -0
  133. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/exception.py +0 -0
  134. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/import_errors.py +0 -0
  135. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/notes.py +0 -0
  136. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/person.py +0 -0
  137. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/project.py +0 -0
  138. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/scene.py +0 -0
  139. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/sequence.py +0 -0
  140. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/shot.py +0 -0
  141. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/status.py +0 -0
  142. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/steps.py +0 -0
  143. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/tasks.py +0 -0
  144. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/team.py +0 -0
  145. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/source/shotgun/versions.py +0 -0
  146. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/tasks/__init__.py +0 -0
  147. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/user/__init__.py +0 -0
  148. {zou-0.19.37 → zou-0.19.39}/zou/app/blueprints/user/resources.py +0 -0
  149. {zou-0.19.37 → zou-0.19.39}/zou/app/config.py +0 -0
  150. {zou-0.19.37 → zou-0.19.39}/zou/app/file_trees/default.json +0 -0
  151. {zou-0.19.37 → zou-0.19.39}/zou/app/file_trees/simple.json +0 -0
  152. {zou-0.19.37 → zou-0.19.39}/zou/app/indexer/__init__.py +0 -0
  153. {zou-0.19.37 → zou-0.19.39}/zou/app/indexer/indexing.py +0 -0
  154. {zou-0.19.37 → zou-0.19.39}/zou/app/models/__init__.py +0 -0
  155. {zou-0.19.37 → zou-0.19.39}/zou/app/models/asset_instance.py +0 -0
  156. {zou-0.19.37 → zou-0.19.39}/zou/app/models/attachment_file.py +0 -0
  157. {zou-0.19.37 → zou-0.19.39}/zou/app/models/base.py +0 -0
  158. {zou-0.19.37 → zou-0.19.39}/zou/app/models/build_job.py +0 -0
  159. {zou-0.19.37 → zou-0.19.39}/zou/app/models/chat.py +0 -0
  160. {zou-0.19.37 → zou-0.19.39}/zou/app/models/chat_message.py +0 -0
  161. {zou-0.19.37 → zou-0.19.39}/zou/app/models/comment.py +0 -0
  162. {zou-0.19.37 → zou-0.19.39}/zou/app/models/custom_action.py +0 -0
  163. {zou-0.19.37 → zou-0.19.39}/zou/app/models/data_import_error.py +0 -0
  164. {zou-0.19.37 → zou-0.19.39}/zou/app/models/day_off.py +0 -0
  165. {zou-0.19.37 → zou-0.19.39}/zou/app/models/department.py +0 -0
  166. {zou-0.19.37 → zou-0.19.39}/zou/app/models/desktop_login_log.py +0 -0
  167. {zou-0.19.37 → zou-0.19.39}/zou/app/models/entity.py +0 -0
  168. {zou-0.19.37 → zou-0.19.39}/zou/app/models/entity_type.py +0 -0
  169. {zou-0.19.37 → zou-0.19.39}/zou/app/models/event.py +0 -0
  170. {zou-0.19.37 → zou-0.19.39}/zou/app/models/file_status.py +0 -0
  171. {zou-0.19.37 → zou-0.19.39}/zou/app/models/login_log.py +0 -0
  172. {zou-0.19.37 → zou-0.19.39}/zou/app/models/metadata_descriptor.py +0 -0
  173. {zou-0.19.37 → zou-0.19.39}/zou/app/models/milestone.py +0 -0
  174. {zou-0.19.37 → zou-0.19.39}/zou/app/models/news.py +0 -0
  175. {zou-0.19.37 → zou-0.19.39}/zou/app/models/notification.py +0 -0
  176. {zou-0.19.37 → zou-0.19.39}/zou/app/models/organisation.py +0 -0
  177. {zou-0.19.37 → zou-0.19.39}/zou/app/models/output_file.py +0 -0
  178. {zou-0.19.37 → zou-0.19.39}/zou/app/models/output_type.py +0 -0
  179. {zou-0.19.37 → zou-0.19.39}/zou/app/models/playlist.py +0 -0
  180. {zou-0.19.37 → zou-0.19.39}/zou/app/models/preview_background_file.py +0 -0
  181. {zou-0.19.37 → zou-0.19.39}/zou/app/models/preview_file.py +0 -0
  182. {zou-0.19.37 → zou-0.19.39}/zou/app/models/project.py +0 -0
  183. {zou-0.19.37 → zou-0.19.39}/zou/app/models/project_status.py +0 -0
  184. {zou-0.19.37 → zou-0.19.39}/zou/app/models/schedule_item.py +0 -0
  185. {zou-0.19.37 → zou-0.19.39}/zou/app/models/search_filter.py +0 -0
  186. {zou-0.19.37 → zou-0.19.39}/zou/app/models/search_filter_group.py +0 -0
  187. {zou-0.19.37 → zou-0.19.39}/zou/app/models/serializer.py +0 -0
  188. {zou-0.19.37 → zou-0.19.39}/zou/app/models/software.py +0 -0
  189. {zou-0.19.37 → zou-0.19.39}/zou/app/models/status_automation.py +0 -0
  190. {zou-0.19.37 → zou-0.19.39}/zou/app/models/subscription.py +0 -0
  191. {zou-0.19.37 → zou-0.19.39}/zou/app/models/task.py +0 -0
  192. {zou-0.19.37 → zou-0.19.39}/zou/app/models/task_status.py +0 -0
  193. {zou-0.19.37 → zou-0.19.39}/zou/app/models/task_type.py +0 -0
  194. {zou-0.19.37 → zou-0.19.39}/zou/app/models/time_spent.py +0 -0
  195. {zou-0.19.37 → zou-0.19.39}/zou/app/models/working_file.py +0 -0
  196. {zou-0.19.37 → zou-0.19.39}/zou/app/services/__init__.py +0 -0
  197. {zou-0.19.37 → zou-0.19.39}/zou/app/services/assets_service.py +0 -0
  198. {zou-0.19.37 → zou-0.19.39}/zou/app/services/auth_service.py +0 -0
  199. {zou-0.19.37 → zou-0.19.39}/zou/app/services/backup_service.py +0 -0
  200. {zou-0.19.37 → zou-0.19.39}/zou/app/services/base_service.py +0 -0
  201. {zou-0.19.37 → zou-0.19.39}/zou/app/services/breakdown_service.py +0 -0
  202. {zou-0.19.37 → zou-0.19.39}/zou/app/services/chats_service.py +0 -0
  203. {zou-0.19.37 → zou-0.19.39}/zou/app/services/comments_service.py +0 -0
  204. {zou-0.19.37 → zou-0.19.39}/zou/app/services/concepts_service.py +0 -0
  205. {zou-0.19.37 → zou-0.19.39}/zou/app/services/custom_actions_service.py +0 -0
  206. {zou-0.19.37 → zou-0.19.39}/zou/app/services/deletion_service.py +0 -0
  207. {zou-0.19.37 → zou-0.19.39}/zou/app/services/edits_service.py +0 -0
  208. {zou-0.19.37 → zou-0.19.39}/zou/app/services/emails_service.py +0 -0
  209. {zou-0.19.37 → zou-0.19.39}/zou/app/services/entities_service.py +0 -0
  210. {zou-0.19.37 → zou-0.19.39}/zou/app/services/events_service.py +0 -0
  211. {zou-0.19.37 → zou-0.19.39}/zou/app/services/file_tree_service.py +0 -0
  212. {zou-0.19.37 → zou-0.19.39}/zou/app/services/files_service.py +0 -0
  213. {zou-0.19.37 → zou-0.19.39}/zou/app/services/index_service.py +0 -0
  214. {zou-0.19.37 → zou-0.19.39}/zou/app/services/names_service.py +0 -0
  215. {zou-0.19.37 → zou-0.19.39}/zou/app/services/news_service.py +0 -0
  216. {zou-0.19.37 → zou-0.19.39}/zou/app/services/notifications_service.py +0 -0
  217. {zou-0.19.37 → zou-0.19.39}/zou/app/services/playlists_service.py +0 -0
  218. {zou-0.19.37 → zou-0.19.39}/zou/app/services/preview_files_service.py +0 -0
  219. {zou-0.19.37 → zou-0.19.39}/zou/app/services/projects_service.py +0 -0
  220. {zou-0.19.37 → zou-0.19.39}/zou/app/services/scenes_service.py +0 -0
  221. {zou-0.19.37 → zou-0.19.39}/zou/app/services/schedule_service.py +0 -0
  222. {zou-0.19.37 → zou-0.19.39}/zou/app/services/stats_service.py +0 -0
  223. {zou-0.19.37 → zou-0.19.39}/zou/app/services/status_automations_service.py +0 -0
  224. {zou-0.19.37 → zou-0.19.39}/zou/app/services/telemetry_services.py +0 -0
  225. {zou-0.19.37 → zou-0.19.39}/zou/app/stores/__init__.py +0 -0
  226. {zou-0.19.37 → zou-0.19.39}/zou/app/stores/auth_tokens_store.py +0 -0
  227. {zou-0.19.37 → zou-0.19.39}/zou/app/stores/file_store.py +0 -0
  228. {zou-0.19.37 → zou-0.19.39}/zou/app/stores/publisher_store.py +0 -0
  229. {zou-0.19.37 → zou-0.19.39}/zou/app/stores/queue_store.py +0 -0
  230. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/__init__.py +0 -0
  231. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/api.py +0 -0
  232. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/auth.py +0 -0
  233. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/cache.py +0 -0
  234. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/chats.py +0 -0
  235. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/colors.py +0 -0
  236. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/commands.py +0 -0
  237. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/csv_utils.py +0 -0
  238. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/date_helpers.py +0 -0
  239. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/dbhelpers.py +0 -0
  240. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/emails.py +0 -0
  241. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/env.py +0 -0
  242. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/events.py +0 -0
  243. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/fields.py +0 -0
  244. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/flask.py +0 -0
  245. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/fs.py +0 -0
  246. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/git.py +0 -0
  247. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/logs.py +0 -0
  248. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/monitoring.py +0 -0
  249. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/permissions.py +0 -0
  250. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/query.py +0 -0
  251. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/remote_job.py +0 -0
  252. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/shell.py +0 -0
  253. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/string.py +0 -0
  254. {zou-0.19.37 → zou-0.19.39}/zou/app/utils/thumbnail.py +0 -0
  255. {zou-0.19.37 → zou-0.19.39}/zou/cli.py +0 -0
  256. {zou-0.19.37 → zou-0.19.39}/zou/debug.py +0 -0
  257. {zou-0.19.37 → zou-0.19.39}/zou/event_stream.py +0 -0
  258. {zou-0.19.37 → zou-0.19.39}/zou/job_settings.py +0 -0
  259. {zou-0.19.37 → zou-0.19.39}/zou/migrations/README +0 -0
  260. {zou-0.19.37 → zou-0.19.39}/zou/migrations/__init__.py +0 -0
  261. {zou-0.19.37 → zou-0.19.39}/zou/migrations/alembic.ini +0 -0
  262. {zou-0.19.37 → zou-0.19.39}/zou/migrations/env.py +0 -0
  263. {zou-0.19.37 → zou-0.19.39}/zou/migrations/script.py.mako +0 -0
  264. {zou-0.19.37 → zou-0.19.39}/zou/migrations/utils/__init__.py +0 -0
  265. {zou-0.19.37 → zou-0.19.39}/zou/migrations/utils/base.py +0 -0
  266. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/003be8a91001_add_start_and_end_dates_to_projects.py +0 -0
  267. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/0596674df51d_add_department_mentions_to_comments.py +0 -0
  268. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/05ac7e8caa21_remove_unique_constraint_for_taskstatus_.py +0 -0
  269. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/05b7dc79a416_add_archived_fields_to_main_tables.py +0 -0
  270. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/0cf5e0e035fa_drop_column_tasktype_for_shots.py +0 -0
  271. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/0ec3762a745d_add_attachment_table.py +0 -0
  272. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/0ef6416a507b_.py +0 -0
  273. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/10cf267d95c9_fix_schedule_item.py +0 -0
  274. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/16328eae4b5f_add_new_constraint_for_timespent.py +0 -0
  275. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/16df47d76c64_add_some_indexes.py +0 -0
  276. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/17ef8f7be758_disallow_null_choicetype.py +0 -0
  277. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/1cb44194db49_add_file_size_field_to_preview_file.py +0 -0
  278. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/1e150c2cea4d_add_nb_entities_out.py +0 -0
  279. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/1e2d77a2f0c4_add_hd_by_default_column.py +0 -0
  280. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/1fab8c420678_add_attachments_to_message_chats.py +0 -0
  281. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/20dfeb36142b_add_projecttaskstatuslink_roles_for_.py +0 -0
  282. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/23122f290ca2_add_entity_chat_models.py +0 -0
  283. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/269d41bfb73f_add_entity_entity_links.py +0 -0
  284. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/29df910f04a4_create_unique_constraint_project_id_.py +0 -0
  285. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/29fe01a6c9eb_add_status_automation_field.py +0 -0
  286. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/2adc020885fa_.py +0 -0
  287. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/2baede80b111_add_entity_status_field.py +0 -0
  288. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/306266361f4f_.py +0 -0
  289. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/328fd44c6347_add_entity_created_by.py +0 -0
  290. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/32f134ff1201_add_is_shared_flag_to_filters.py +0 -0
  291. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/346250b5304c_add_position_to_preview_files.py +0 -0
  292. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/3476e147e632_add_acks_to_comments.py +0 -0
  293. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/389cfb9de776_.py +0 -0
  294. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/38baa9a23b3d_.py +0 -0
  295. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/398150912a3f_validation_status_preview.py +0 -0
  296. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/3b0d1321079e_.py +0 -0
  297. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/3d5c93bafb9d_.py +0 -0
  298. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/3e0538ddf80f_.py +0 -0
  299. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/3fee3bd10f9d_.py +0 -0
  300. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/4095103c7d01_add_is_clients_isolated_flag_to_projects.py +0 -0
  301. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/40dea9555940_.py +0 -0
  302. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/42ec83db6a01_change_person_preferred_two_factor_.py +0 -0
  303. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/43d0cf0ed5e7_.py +0 -0
  304. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/443d1e78a932_.py +0 -0
  305. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/45c2de366e66_.py +0 -0
  306. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/45dafbb3f4e1_for_person_contract_type_disallow_null.py +0 -0
  307. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/4715c2586036_add_last_preview_file_fields.py +0 -0
  308. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/4e3738cdc34c_.py +0 -0
  309. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/4f2398ebcd49_.py +0 -0
  310. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/523ee9647bee_.py +0 -0
  311. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/54ee0d1d60ba_add_build_job_model.py +0 -0
  312. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/556526e47daa_.py +0 -0
  313. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/57222395f2be_add_statusautomation_import_last_revision.py +0 -0
  314. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/5798d2c9020b_change_person_role_to_choicetype.py +0 -0
  315. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/590aa1ffe731_add_notifications_enabled_flag.py +0 -0
  316. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/5a291251823c_add_max_retake_parameter.py +0 -0
  317. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/5ab9d7a75887_.py +0 -0
  318. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/5b0fcbb94f24_.py +0 -0
  319. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/5b7fa3e51701_add_is_client_allowed_flag_to_task_.py +0 -0
  320. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/5b980f0dc365_add_comment_links.py +0 -0
  321. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/5b9fd9ddfe43_add_homepage_and_contract_fields.py +0 -0
  322. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/5c0498e264bc_add_slack_fields.py +0 -0
  323. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/5e2ce62632a6_add_workflow_to_project.py +0 -0
  324. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/680c64565f9d_for_searchfiltergroup_is_shared.py +0 -0
  325. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/693cc511d28d_add_taskstatus_priority.py +0 -0
  326. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/6aa446ee4072_add_is_for_all_flage_to_playlists.py +0 -0
  327. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/6bd3b102d61b_.py +0 -0
  328. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/6c597e842afa_add_task_type_field_to_playlists.py +0 -0
  329. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/6d1b2c60f58b_add_milestone_model.py +0 -0
  330. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/6d7fa5a8e9a5_add_timesheets_locked_field_to_org.py +0 -0
  331. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/6eeaff945706_add_data_field_on_entity_links.py +0 -0
  332. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/6f6049877105_.py +0 -0
  333. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/7417c8eb70d8_add_for_entity_field_to_playlists.py +0 -0
  334. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/772a5e43f05b_.py +0 -0
  335. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/7748d3d22925_add_columns_to_searchfilter_table_to_.py +0 -0
  336. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/77d6820f494f_add_reply_to_notif.py +0 -0
  337. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/7b1f765677d8_.py +0 -0
  338. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/7bc746997e8d_add_slack_token_field_to_organisation.py +0 -0
  339. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/7dc79d4ed7cd_.py +0 -0
  340. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/818f7bda2528_.py +0 -0
  341. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/82e7f7a95e84_add_project_id_to_events.py +0 -0
  342. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/82ee682204ab_add_is_generated_from_ldap_column_to_.py +0 -0
  343. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/8588f254d6b8_add_archived_fields.py +0 -0
  344. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/8739ae9fa28b_add_for_client_field.py +0 -0
  345. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/87efceb6745b_add_ready_for_to_entity.py +0 -0
  346. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/892b264937ec_.py +0 -0
  347. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/8a1b4a1b7f4a_add_totp_columns_for_person.py +0 -0
  348. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/8e4f39e321f4_add_day_off_table.py +0 -0
  349. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/8fbd40afbe5f_allow_to_set_float_values_for_.py +0 -0
  350. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/9010a64e5a2d_add_indices.py +0 -0
  351. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/9060dd4f6116_notification_uc.py +0 -0
  352. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/925771029620_.py +0 -0
  353. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/92b40d79ad3f_allow_message_attachments.py +0 -0
  354. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/92bdfe07e5f5_discord_integration.py +0 -0
  355. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/956659992419_add_columns_for_person_to_store_fido_.py +0 -0
  356. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/96c79d31e648_add_mail_otp_columns_for_person.py +0 -0
  357. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/96f58a4a2a58_person_partial_index_for_email_only_.py +0 -0
  358. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/98c90621cf58_add_for_client_flag_to_playlist.py +0 -0
  359. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/99825b9cc778_.py +0 -0
  360. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/9a09467f9b2c_.py +0 -0
  361. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/9bd17364fc18_.py +0 -0
  362. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/9e5b3a9b0cee_add_new_column_metadatadescriptor_data_type_.py +0 -0
  363. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/9f8445f9b42c_add_man_days_fields.py +0 -0
  364. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/a23682ccc1f1_.py +0 -0
  365. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/a519c710877c_.py +0 -0
  366. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/a65bdadbae2f_.py +0 -0
  367. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/a66508788c53_add_nb_assets_ready.py +0 -0
  368. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/a6c25eed3ea1_add_login_failed_attemps_and_last_login_.py +0 -0
  369. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/a7c43f3fbc76_add_duration_column_to_the_preview_file.py +0 -0
  370. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/aa0a60033106_feedback_request.py +0 -0
  371. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/addbbefa7028_add_departments_link_to_metadata_.py +0 -0
  372. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/ae0127f2fc56_add_previewfile_width_and_previewfile_.py +0 -0
  373. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/af1790868e2c_.py +0 -0
  374. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/b45cb782bb9c_.py +0 -0
  375. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/b4dd0add5f79_.py +0 -0
  376. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/b8c0a0f9d054_drop_task_status_is_reviewable.py +0 -0
  377. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/b8ed0fb263f8_add_person_jti_and_jti_expiration_date.py +0 -0
  378. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/b97a71306fc8_add_is_casting_standby_column_to_entity.py +0 -0
  379. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/be56dc0fb760_for_is_shared_disallow_nullable.py +0 -0
  380. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/bf1347acdee2_.py +0 -0
  381. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/c49e41f1298b_add_previewbackground.py +0 -0
  382. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/c68c2a62cfac_add_mimetype_column_to_attachment.py +0 -0
  383. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/c726b98be194_.py +0 -0
  384. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/c81f3e83bdb5_.py +0 -0
  385. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/cf3d365de164_add_entity_version_model.py +0 -0
  386. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/cf6cec6d6bf5_add_status_field_to_preview_file.py +0 -0
  387. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/d80267806131_task_status_new_column_is_default.py +0 -0
  388. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/d8dcd5196d57_add_casting_label.py +0 -0
  389. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/de8a3de227ef_.py +0 -0
  390. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/deeacd38d373_for_projecttaskstatuslink_set_default_.py +0 -0
  391. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/df1834485f57_.py +0 -0
  392. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/df9f8a147e80_change_file_size_to_big_integer.py +0 -0
  393. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/e1ef93f40d3d_.py +0 -0
  394. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/e29638428dfd_add_schedule_item_table.py +0 -0
  395. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/e3f6db74cc1e_.py +0 -0
  396. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/e839d6603c09_add_person_id_to_shot_history.py +0 -0
  397. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/ee2373fbe3a4_.py +0 -0
  398. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/f0567e8d0c62_.py +0 -0
  399. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/f0c6cbb61869_add_production_style_field.py +0 -0
  400. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/f344b867a911_for_description_of_entity_task_working_.py +0 -0
  401. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/f4ff5a73d283_add_person_ldap_uid.py +0 -0
  402. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/f5b113876a49_add_preferred_two_factor_authentication_.py +0 -0
  403. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/f5bdca075cdc_add_preview_download_flag_to_projects.py +0 -0
  404. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/f874ad5e898a_add_link_entity_type_task_type.py +0 -0
  405. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/f995b28fb749_.py +0 -0
  406. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/fb6b6f188497_.py +0 -0
  407. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/fb87feaaa094_add_missing_unique_constraints.py +0 -0
  408. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/fc322f908695_.py +0 -0
  409. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/fee7c696166e_.py +0 -0
  410. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/feffd3c5b806_introduce_concepts.py +0 -0
  411. {zou-0.19.37 → zou-0.19.39}/zou/migrations/versions/ffeed4956ab1_add_more_details_to_projects.py +0 -0
  412. {zou-0.19.37 → zou-0.19.39}/zou/remote/__init__.py +0 -0
  413. {zou-0.19.37 → zou-0.19.39}/zou/remote/config_payload.py +0 -0
  414. {zou-0.19.37 → zou-0.19.39}/zou/remote/normalize_movie.py +0 -0
  415. {zou-0.19.37 → zou-0.19.39}/zou/remote/playlist.py +0 -0
  416. {zou-0.19.37 → zou-0.19.39}/zou/utils/__init__.py +0 -0
  417. {zou-0.19.37 → zou-0.19.39}/zou/utils/movie.py +0 -0
  418. {zou-0.19.37 → zou-0.19.39}/zou.egg-info/dependency_links.txt +0 -0
  419. {zou-0.19.37 → zou-0.19.39}/zou.egg-info/entry_points.txt +0 -0
  420. {zou-0.19.37 → zou-0.19.39}/zou.egg-info/not-zip-safe +0 -0
  421. {zou-0.19.37 → zou-0.19.39}/zou.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zou
3
- Version: 0.19.37
3
+ Version: 0.19.39
4
4
  Summary: API to store and manage the data of your animation production
5
5
  Home-page: https://zou.cg-wire.com
6
6
  Author: CG Wire
@@ -49,10 +49,10 @@ Requires-Dist: itsdangerous==2.2.0
49
49
  Requires-Dist: Jinja2==3.1.4
50
50
  Requires-Dist: ldap3==2.9.1
51
51
  Requires-Dist: matterhook==0.2
52
- Requires-Dist: meilisearch==0.31.1
52
+ Requires-Dist: meilisearch==0.31.2
53
53
  Requires-Dist: numpy==1.24.4; python_version == "3.8"
54
54
  Requires-Dist: numpy==1.26.4; python_version >= "3.9"
55
- Requires-Dist: opencv-python==4.9.0.80
55
+ Requires-Dist: opencv-python==4.10.0.82
56
56
  Requires-Dist: OpenTimelineIO==0.16.0
57
57
  Requires-Dist: orjson==3.10.3
58
58
  Requires-Dist: pillow==10.3.0
@@ -63,7 +63,7 @@ Requires-Dist: python-nomad==2.0.1
63
63
  Requires-Dist: python-slugify==8.0.4
64
64
  Requires-Dist: python-socketio==5.11.2
65
65
  Requires-Dist: pytz==2024.1
66
- Requires-Dist: redis==5.0.4
66
+ Requires-Dist: redis==5.0.5
67
67
  Requires-Dist: requests==2.32.3
68
68
  Requires-Dist: rq==1.16.2
69
69
  Requires-Dist: slackclient==2.9.4
@@ -80,11 +80,11 @@ Provides-Extra: test
80
80
  Requires-Dist: fakeredis==2.23.2; extra == "test"
81
81
  Requires-Dist: mixer==7.2.2; extra == "test"
82
82
  Requires-Dist: pytest-cov==5.0.0; extra == "test"
83
- Requires-Dist: pytest==8.2.1; extra == "test"
83
+ Requires-Dist: pytest==8.2.2; extra == "test"
84
84
  Provides-Extra: monitoring
85
85
  Requires-Dist: prometheus-flask-exporter==0.23.0; extra == "monitoring"
86
86
  Requires-Dist: pygelf==0.4.2; extra == "monitoring"
87
- Requires-Dist: sentry-sdk==2.3.1; extra == "monitoring"
87
+ Requires-Dist: sentry-sdk==2.5.0; extra == "monitoring"
88
88
  Provides-Extra: lint
89
89
  Requires-Dist: autoflake==2.3.1; extra == "lint"
90
90
  Requires-Dist: black==24.4.2; extra == "lint"
@@ -55,10 +55,10 @@ install_requires =
55
55
  Jinja2==3.1.4
56
56
  ldap3==2.9.1
57
57
  matterhook==0.2
58
- meilisearch==0.31.1
58
+ meilisearch==0.31.2
59
59
  numpy==1.24.4; python_version == '3.8'
60
60
  numpy==1.26.4; python_version >= '3.9'
61
- opencv-python==4.9.0.80
61
+ opencv-python==4.10.0.82
62
62
  OpenTimelineIO==0.16.0
63
63
  orjson==3.10.3
64
64
  pillow==10.3.0
@@ -69,7 +69,7 @@ install_requires =
69
69
  python-slugify==8.0.4
70
70
  python-socketio==5.11.2
71
71
  pytz==2024.1
72
- redis==5.0.4
72
+ redis==5.0.5
73
73
  requests==2.32.3
74
74
  rq==1.16.2
75
75
  slackclient==2.9.4
@@ -94,11 +94,11 @@ test =
94
94
  fakeredis==2.23.2
95
95
  mixer==7.2.2
96
96
  pytest-cov==5.0.0
97
- pytest==8.2.1
97
+ pytest==8.2.2
98
98
  monitoring =
99
99
  prometheus-flask-exporter==0.23.0
100
100
  pygelf==0.4.2
101
- sentry-sdk==2.3.1
101
+ sentry-sdk==2.5.0
102
102
  lint =
103
103
  autoflake==2.3.1
104
104
  black==24.4.2
@@ -0,0 +1 @@
1
+ __version__ = "0.19.39"
@@ -128,6 +128,7 @@ from zou.app.blueprints.crud.chat_message import (
128
128
  ChatMessageResource,
129
129
  ChatMessagesResource,
130
130
  )
131
+ from zou.app.blueprints.crud.studio import StudioResource, StudiosResource
131
132
 
132
133
  routes = [
133
134
  ("/data/persons", PersonsResource),
@@ -209,6 +210,8 @@ routes = [
209
210
  "/data/preview-background-files/<instance_id>",
210
211
  PreviewBackgroundFileResource,
211
212
  ),
213
+ ("/data/studios", StudiosResource),
214
+ ("/data/studios/<instance_id>", StudioResource),
212
215
  ]
213
216
 
214
217
  blueprint = Blueprint("/data", "data")
@@ -3,9 +3,6 @@ from zou.app.blueprints.crud.base import BaseModelResource, BaseModelsResource
3
3
  from zou.app.models.department import Department
4
4
 
5
5
  from zou.app.services import tasks_service
6
- from zou.app.services.exception import (
7
- ArgumentsException,
8
- )
9
6
 
10
7
 
11
8
  class DepartmentsResource(BaseModelsResource):
@@ -19,16 +16,6 @@ class DepartmentsResource(BaseModelsResource):
19
16
  tasks_service.clear_department_cache(str(instance.id))
20
17
  return instance.serialize()
21
18
 
22
- def update_data(self, data):
23
- data = super().update_data(data)
24
- name = data.get("name", None)
25
- department = Department.get_by(name=name)
26
- if department is not None:
27
- raise ArgumentsException(
28
- "A department type with similar name already exists"
29
- )
30
- return data
31
-
32
19
 
33
20
  class DepartmentResource(BaseModelResource):
34
21
  def __init__(self):
@@ -37,17 +24,6 @@ class DepartmentResource(BaseModelResource):
37
24
  def check_read_permissions(self, instance):
38
25
  return True
39
26
 
40
- def update_data(self, data, instance_id):
41
- data = super().update_data(data, instance_id)
42
- name = data.get("name", None)
43
- if name is not None:
44
- department = Department.get_by(name=name)
45
- if department is not None and instance_id != str(department.id):
46
- raise ArgumentsException(
47
- "A department with similar name already exists"
48
- )
49
- return data
50
-
51
27
  def post_update(self, instance_dict, data):
52
28
  tasks_service.clear_department_cache(instance_dict["id"])
53
29
  return instance_dict
@@ -151,6 +151,7 @@ class PersonResource(BaseModelResource, ArgsMixin):
151
151
  data.pop("is_generated_from_ldap", None)
152
152
  data.pop("ldap_uid", None)
153
153
  data.pop("last_presence", None)
154
+ data.pop("studio_id", None)
154
155
 
155
156
  if "role" in data and data["role"] not in [
156
157
  role for role, _ in ROLE_TYPES
@@ -204,13 +205,15 @@ class PersonResource(BaseModelResource, ArgsMixin):
204
205
  and persons_service.is_user_limit_reached()
205
206
  ):
206
207
  raise ArgumentsException("User limit reached.")
207
- if (
208
- data.get("active") is False
209
- and instance_dict["email"] in config.PROTECTED_ACCOUNTS
210
- ):
211
- raise PersonInProtectedAccounts(
212
- "Can't set this person as inactive it's a protected account."
213
- )
208
+ if instance_dict["email"] in config.PROTECTED_ACCOUNTS:
209
+ message = None
210
+ if data.get("active") is False:
211
+ message = "Can't set this person as inactive it's a protected account."
212
+ elif data.get("role") is not None:
213
+ message = "Can't change the role of this person it's a protected account."
214
+
215
+ if message is not None:
216
+ raise PersonInProtectedAccounts(message)
214
217
  return data
215
218
 
216
219
  def post_update(self, instance_dict, data):
@@ -0,0 +1,33 @@
1
+ from zou.app.models.studio import Studio
2
+
3
+ from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
4
+
5
+ from zou.app.services import tasks_service
6
+
7
+
8
+ class StudiosResource(BaseModelsResource):
9
+ def __init__(self):
10
+ BaseModelsResource.__init__(self, Studio)
11
+
12
+ def check_read_permissions(self):
13
+ return True
14
+
15
+ def post_creation(self, instance):
16
+ tasks_service.clear_studio_cache(str(instance.id))
17
+ return instance.serialize()
18
+
19
+
20
+ class StudioResource(BaseModelResource):
21
+ def __init__(self):
22
+ BaseModelResource.__init__(self, Studio)
23
+
24
+ def check_read_permissions(self, instance):
25
+ return True
26
+
27
+ def post_update(self, instance_dict, data):
28
+ tasks_service.clear_studio_cache(instance_dict["id"])
29
+ return instance_dict
30
+
31
+ def post_delete(self, instance_dict):
32
+ tasks_service.clear_studio_cache(instance_dict["id"])
33
+ return instance_dict
@@ -7,7 +7,6 @@ from zou.app.blueprints.persons.resources import (
7
7
  DayOffForMonthResource,
8
8
  DesktopLoginsResource,
9
9
  InvitePersonResource,
10
- NewPersonResource,
11
10
  PersonMonthQuotaShotsResource,
12
11
  PersonWeekQuotaShotsResource,
13
12
  PersonDayQuotaShotsResource,
@@ -34,7 +33,6 @@ from zou.app.blueprints.persons.resources import (
34
33
  )
35
34
 
36
35
  routes = [
37
- ("/data/persons/new", NewPersonResource),
38
36
  ("/data/persons/<person_id>/desktop-login-logs", DesktopLoginsResource),
39
37
  ("/data/persons/presence-logs/<month_date>", PresenceLogsResource),
40
38
  ("/data/persons/<person_id>/time-spents", TimeSpentsResource),
@@ -29,113 +29,14 @@ from zou.app.services.exception import (
29
29
  WrongParameterException,
30
30
  UnactiveUserException,
31
31
  TwoFactorAuthenticationNotEnabledException,
32
+ PersonInProtectedAccounts,
33
+ ArgumentsException,
32
34
  )
33
35
  from zou.app.services.auth_service import (
34
36
  disable_two_factor_authentication_for_person,
35
37
  )
36
38
 
37
39
 
38
- class NewPersonResource(Resource, ArgsMixin):
39
- """
40
- Create a new user in the database.
41
- """
42
-
43
- # TODO: Remove this route in the future.
44
- @jwt_required()
45
- @permissions.require_admin
46
- def post(self):
47
- """
48
- Create a new user in the database.
49
- This route will be removed in the future.
50
- Please use POST /data/persons instead.
51
- ---
52
- tags:
53
- - Persons
54
- description: Set password to None if not provided.
55
- User role can be set but only admins can create admin users.
56
- parameters:
57
- - in: formData
58
- name: email
59
- required: True
60
- type: string
61
- format: email
62
- x-example: admin@example.com
63
- - in: formData
64
- name: phone
65
- required: False
66
- type: integer
67
- x-example: 06 12 34 56 78
68
- - in: formData
69
- name: role
70
- required: False
71
- type: string
72
- x-example: user
73
- - in: formData
74
- name: first_name
75
- required: True
76
- type: string
77
- - in: formData
78
- name: last_name
79
- required: False
80
- type: string
81
- responses:
82
- 201:
83
- description: User created
84
- """
85
- data = self.get_arguments()
86
-
87
- if not data["is_bot"] and persons_service.is_user_limit_reached():
88
- return {
89
- "error": True,
90
- "message": "User limit reached.",
91
- "limit": config.USER_LIMIT,
92
- }, 400
93
- else:
94
- if data["password"] is not None:
95
- data["password"] = auth.encrypt_password(data["password"])
96
- person = persons_service.create_person(
97
- data["email"],
98
- data["password"],
99
- data["first_name"],
100
- data["last_name"],
101
- data["phone"],
102
- role=data["role"],
103
- desktop_login=data["desktop_login"],
104
- departments=data["departments"],
105
- is_bot=data["is_bot"],
106
- expiration_date=data["expiration_date"],
107
- active=data["active"],
108
- )
109
- return person, 201
110
-
111
- def get_arguments(self):
112
- args = self.get_args(
113
- [
114
- {
115
- "name": "email",
116
- "help": "The email is required.",
117
- "required": True,
118
- },
119
- {
120
- "name": "first_name",
121
- "help": "The first name is required.",
122
- "required": True,
123
- },
124
- ("last_name", ""),
125
- ("phone", ""),
126
- ("role", "user"),
127
- ("desktop_login", ""),
128
- {"name": "departments", "action": "append"},
129
- "password",
130
- {"name": "is_bot", "default": False, "type": bool},
131
- {"name": "expiration_date", "default": None, "type": str},
132
- {"name": "active", "default": True, "type": bool},
133
- ]
134
- )
135
-
136
- return args
137
-
138
-
139
40
  class DesktopLoginsResource(Resource, ArgsMixin):
140
41
  """
141
42
  Allow to create and retrieve desktop login logs. Desktop login logs can only
@@ -813,7 +714,12 @@ class TimeSpentDurationResource(Resource, ArgsMixin):
813
714
  def get_person_project_department_arguments(self):
814
715
  project_id = self.get_project_id()
815
716
  person_id = None
816
- department_ids = None
717
+ department_id = self.get_text_parameter("department_id")
718
+ if department_id is not None:
719
+ department_ids = [department_id]
720
+ else:
721
+ department_ids = None
722
+ studio_id = self.get_text_parameter("studio_id")
817
723
  if not permissions.has_admin_permissions():
818
724
  if (
819
725
  permissions.has_manager_permissions()
@@ -827,9 +733,16 @@ class TimeSpentDurationResource(Resource, ArgsMixin):
827
733
  elif project_id not in project_ids:
828
734
  raise permissions.PermissionDenied
829
735
  if permissions.has_supervisor_permissions():
830
- department_ids = persons_service.get_current_user(
736
+ persons_departments = persons_service.get_current_user(
831
737
  relations=True
832
738
  )["departments"]
739
+ if department_id is not None:
740
+ if department_id not in persons_departments:
741
+ raise ArgumentsException(
742
+ "Supervisor not allowed to access this department"
743
+ )
744
+ else:
745
+ department_ids = persons_departments
833
746
  else:
834
747
  person_id = persons_service.get_current_user()["id"]
835
748
 
@@ -837,6 +750,7 @@ class TimeSpentDurationResource(Resource, ArgsMixin):
837
750
  "person_id": person_id,
838
751
  "project_id": project_id,
839
752
  "department_ids": department_ids,
753
+ "studio_id": studio_id,
840
754
  }
841
755
 
842
756
 
@@ -1300,6 +1214,8 @@ class ChangePasswordForPersonResource(Resource, ArgsMixin):
1300
1214
  permissions.check_admin_permissions()
1301
1215
  try:
1302
1216
  person = persons_service.get_person(person_id)
1217
+ if person["email"] in config.PROTECTED_ACCOUNTS:
1218
+ raise PersonInProtectedAccounts()
1303
1219
  current_user = persons_service.get_current_user()
1304
1220
  auth.validate_password(password, password_2)
1305
1221
  password = auth.encrypt_password(password)
@@ -1343,6 +1259,14 @@ Thank you and see you soon on Kitsu,
1343
1259
  return {"error": True, "message": "Password is too short."}, 400
1344
1260
  except UnactiveUserException:
1345
1261
  return {"error": True, "message": "User is unactive."}, 400
1262
+ except PersonInProtectedAccounts:
1263
+ return (
1264
+ {
1265
+ "error": True,
1266
+ "message": "This user is in protected accounts.",
1267
+ },
1268
+ 400,
1269
+ )
1346
1270
 
1347
1271
  def get_arguments(self):
1348
1272
  args = self.get_args(
@@ -1512,13 +1512,17 @@ class ProjectQuotasResource(Resource, ArgsMixin):
1512
1512
  """
1513
1513
  projects_service.get_project(project_id)
1514
1514
  user_service.check_project_access(project_id)
1515
- detail_level = self.get_text_parameter("detail")
1516
- weighted = self.get_bool_parameter("weighted", default="true")
1517
- if weighted:
1515
+ args = self.get_args(
1516
+ [
1517
+ ("weighted", False, False, bool),
1518
+ ("studio_id", None, False, str),
1519
+ ]
1520
+ )
1521
+ if args["weighted"]:
1518
1522
  return shots_service.get_weighted_quotas(
1519
- project_id, task_type_id, detail_level
1523
+ project_id, task_type_id, args["studio_id"]
1520
1524
  )
1521
1525
  else:
1522
1526
  return shots_service.get_raw_quotas(
1523
- project_id, task_type_id, detail_level
1527
+ project_id, task_type_id, args["studio_id"]
1524
1528
  )
@@ -844,7 +844,7 @@ class ClearAssignationResource(Resource, ArgsMixin):
844
844
  tasks = []
845
845
  for task_id in task_ids:
846
846
  try:
847
- user_service.check_task_departement_access_for_unassign(
847
+ user_service.check_task_department_access_for_unassign(
848
848
  task_id, person_id
849
849
  )
850
850
  tasks_service.clear_assignation(task_id, person_id=person_id)
@@ -925,7 +925,7 @@ class TasksAssignResource(Resource, ArgsMixin):
925
925
  for task_id in args["task_ids"]:
926
926
  try:
927
927
  user_service.check_person_is_not_bot(person_id)
928
- user_service.check_task_departement_access(task_id, person_id)
928
+ user_service.check_task_department_access(task_id, person_id)
929
929
  task = tasks_service.assign_task(
930
930
  task_id, person_id, current_user["id"]
931
931
  )
@@ -995,7 +995,7 @@ class TaskAssignResource(Resource, ArgsMixin):
995
995
  current_user = persons_service.get_current_user()
996
996
  try:
997
997
  user_service.check_person_is_not_bot(person_id)
998
- user_service.check_task_departement_access(task_id, person_id)
998
+ user_service.check_task_department_access(task_id, person_id)
999
999
  task = tasks_service.assign_task(
1000
1000
  task_id, person_id, current_user["id"]
1001
1001
  )
@@ -121,12 +121,12 @@ class ArgsMixin(object):
121
121
  """
122
122
  return self.get_bool_parameter("no_job")
123
123
 
124
- def get_text_parameter(self, field_name):
124
+ def get_text_parameter(self, field_name, default=None):
125
125
  """
126
126
  Returns text parameter value matching `field_name`.
127
127
  """
128
128
  options = request.args
129
- return options.get(field_name, None)
129
+ return options.get(field_name, default)
130
130
 
131
131
  def get_bool_parameter(self, field_name, default="false"):
132
132
  """
@@ -114,6 +114,9 @@ class Person(db.Model, BaseMixin, SerializerMixin):
114
114
  departments = db.relationship(
115
115
  "Department", secondary="department_link", lazy="joined"
116
116
  )
117
+ studio_id = db.Column(
118
+ UUIDType(binary=False), db.ForeignKey("studio.id"), index=True
119
+ )
117
120
 
118
121
  is_generated_from_ldap = db.Column(db.Boolean(), default=False)
119
122
  ldap_uid = db.Column(db.String(60), unique=True, default=None)
@@ -185,6 +188,7 @@ class Person(db.Model, BaseMixin, SerializerMixin):
185
188
  "has_avatar": data["has_avatar"],
186
189
  "active": data["active"],
187
190
  "departments": data.get("departments", []),
191
+ "studio_id": data["studio_id"],
188
192
  "role": data["role"],
189
193
  "desktop_login": data["desktop_login"],
190
194
  "is_bot": data["is_bot"],
@@ -0,0 +1,13 @@
1
+ from zou.app import db
2
+ from zou.app.models.serializer import SerializerMixin
3
+ from zou.app.models.base import BaseMixin
4
+
5
+
6
+ class Studio(db.Model, BaseMixin, SerializerMixin):
7
+ """
8
+ Describe a studio.
9
+ """
10
+
11
+ name = db.Column(db.String(80), unique=True, nullable=False)
12
+ color = db.Column(db.String(7), nullable=False)
13
+ archived = db.Column(db.Boolean(), default=False)
@@ -49,6 +49,10 @@ class DepartmentNotFoundException(NotFound):
49
49
  pass
50
50
 
51
51
 
52
+ class StudioNotFoundException(NotFound):
53
+ pass
54
+
55
+
52
56
  class TaskStatusNotFoundException(NotFound):
53
57
  pass
54
58
 
@@ -210,6 +210,7 @@ def create_person(
210
210
  ldap_uid=None,
211
211
  is_bot=False,
212
212
  expiration_date=None,
213
+ studio_id=None,
213
214
  active=True,
214
215
  serialize=True,
215
216
  ):
@@ -245,6 +246,7 @@ def create_person(
245
246
  ldap_uid=ldap_uid,
246
247
  is_bot=is_bot,
247
248
  expiration_date=expiration_date,
249
+ studio_id=studio_id,
248
250
  active=active,
249
251
  )
250
252
  if is_bot:
@@ -279,13 +281,17 @@ def update_person(person_id, data):
279
281
  Update person entry with data given in parameter.
280
282
  """
281
283
  person = Person.get(person_id)
282
- if (
283
- data.get("active") is False
284
- and person.email in config.PROTECTED_ACCOUNTS
285
- ):
286
- raise PersonInProtectedAccounts(
287
- "Can't set this person as inactive it's a protected account."
288
- )
284
+ if person.email in config.PROTECTED_ACCOUNTS:
285
+ message = None
286
+ if data.get("active") is False:
287
+ message = (
288
+ "Can't set this person as inactive it's a protected account."
289
+ )
290
+ elif data.get("role") is not None:
291
+ message = "Can't change the role of this person it's a protected account."
292
+
293
+ if message is not None:
294
+ raise PersonInProtectedAccounts(message)
289
295
 
290
296
  if "email" in data and data["email"] is not None:
291
297
  data["email"] = data["email"].strip()
@@ -2,7 +2,7 @@ from datetime import timedelta
2
2
  from operator import itemgetter
3
3
  from sqlalchemy.orm import aliased
4
4
  from sqlalchemy.exc import IntegrityError, StatementError
5
- from sqlalchemy import func
5
+ from sqlalchemy import func, or_
6
6
 
7
7
  from zou.app.utils import (
8
8
  cache,
@@ -1112,7 +1112,7 @@ def get_base_entity_type_name(entity_dict):
1112
1112
  return type_name
1113
1113
 
1114
1114
 
1115
- def get_weighted_quotas(project_id, task_type_id, detail_level):
1115
+ def get_weighted_quotas(project_id, task_type_id, studio_id=None):
1116
1116
  """
1117
1117
  Build quota statistics. It counts the number of frames done for each day.
1118
1118
  A shot is considered done at the first feedback request. If time spent is
@@ -1140,6 +1140,14 @@ def get_weighted_quotas(project_id, task_type_id, detail_level):
1140
1140
  TimeSpent.person_id,
1141
1141
  )
1142
1142
  )
1143
+
1144
+ if studio_id is not None:
1145
+ persons_from_studio = Person.query.filter(
1146
+ Person.studio_id == studio_id
1147
+ ).all()
1148
+ query = query.filter(
1149
+ or_(*[Task.assignees.contains(p) for p in persons_from_studio])
1150
+ )
1143
1151
  result = query.all()
1144
1152
 
1145
1153
  for task, nb_frames, date, duration, person_id in result:
@@ -1161,6 +1169,11 @@ def get_weighted_quotas(project_id, task_type_id, detail_level):
1161
1169
  .join(Task.assignees)
1162
1170
  .add_columns(Entity.nb_frames, Person.id)
1163
1171
  )
1172
+
1173
+ if studio_id is not None:
1174
+ query = query.filter(
1175
+ or_(*[Task.assignees.contains(p) for p in persons_from_studio])
1176
+ )
1164
1177
  result = query.all()
1165
1178
 
1166
1179
  for task, nb_frames, person_id in result:
@@ -1182,7 +1195,7 @@ def get_weighted_quotas(project_id, task_type_id, detail_level):
1182
1195
  return quotas
1183
1196
 
1184
1197
 
1185
- def get_raw_quotas(project_id, task_type_id, detail_level):
1198
+ def get_raw_quotas(project_id, task_type_id, studio_id=None):
1186
1199
  """
1187
1200
  Build quota statistics in a raw way. It counts the number of frames done
1188
1201
  for each day. A shot is considered done at the first feedback request (end
@@ -1203,6 +1216,15 @@ def get_raw_quotas(project_id, task_type_id, detail_level):
1203
1216
  .join(Task.assignees)
1204
1217
  .add_columns(Entity.nb_frames, Person.id)
1205
1218
  )
1219
+
1220
+ if studio_id is not None:
1221
+ persons_from_studio = Person.query.filter(
1222
+ Person.studio_id == studio_id
1223
+ ).all()
1224
+ query = query.filter(
1225
+ or_(*[Task.assignees.contains(p) for p in persons_from_studio])
1226
+ )
1227
+
1206
1228
  result = query.all()
1207
1229
 
1208
1230
  for task, nb_frames, person_id in result:
@@ -42,6 +42,7 @@ from zou.app.models.task import Task
42
42
  from zou.app.models.task_status import TaskStatus
43
43
  from zou.app.models.task_type import TaskType
44
44
  from zou.app.models.time_spent import TimeSpent
45
+ from zou.app.models.studio import Studio
45
46
 
46
47
  from zou.app.services import deletion_service, tasks_service, projects_service
47
48
  from zou.app.stores import file_store
@@ -102,6 +103,7 @@ event_name_model_map = {
102
103
  "subscription": Subscription,
103
104
  "search-filter": SearchFilter,
104
105
  "search-filter-group": SearchFilterGroup,
106
+ "studio": Studio,
105
107
  "task": Task,
106
108
  "task-status": TaskStatus,
107
109
  "task-type": TaskType,
@@ -140,6 +142,7 @@ event_name_model_path_map = {
140
142
  "search-filter": "search-filters",
141
143
  "search-filter-group": "search-filter-groups",
142
144
  "subscription": "subscriptions",
145
+ "studio": "studios",
143
146
  "task": "tasks",
144
147
  "task-status": "task-status",
145
148
  "task-type": "task-types",
@@ -173,6 +176,7 @@ main_events = [
173
176
  "organisation",
174
177
  "project-status",
175
178
  "department",
179
+ "studio",
176
180
  "task-type",
177
181
  "task-status",
178
182
  "custom-action",