zou 1.0.3__tar.gz → 1.0.5__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 (498) hide show
  1. {zou-1.0.3/zou.egg-info → zou-1.0.5}/PKG-INFO +1 -1
  2. zou-1.0.5/zou/__init__.py +1 -0
  3. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/person.py +1 -0
  4. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/task_type.py +10 -0
  5. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/events/resources.py +24 -9
  6. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/files/resources.py +2 -0
  7. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/index/resources.py +76 -66
  8. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/news/resources.py +2 -2
  9. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/playlists/resources.py +8 -2
  10. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/previews/resources.py +46 -3
  11. {zou-1.0.3 → zou-1.0.5}/zou/app/config.py +2 -0
  12. {zou-1.0.3 → zou-1.0.5}/zou/app/file_trees/default.json +6 -0
  13. {zou-1.0.3 → zou-1.0.5}/zou/app/file_trees/simple.json +6 -0
  14. {zou-1.0.3 → zou-1.0.5}/zou/app/mixin.py +9 -0
  15. zou-1.0.5/zou/app/models/plugin.py +41 -0
  16. {zou-1.0.3 → zou-1.0.5}/zou/app/models/preview_file.py +2 -0
  17. {zou-1.0.3 → zou-1.0.5}/zou/app/services/comments_service.py +2 -1
  18. {zou-1.0.3 → zou-1.0.5}/zou/app/services/deletion_service.py +14 -5
  19. {zou-1.0.3 → zou-1.0.5}/zou/app/services/events_service.py +12 -2
  20. {zou-1.0.3 → zou-1.0.5}/zou/app/services/file_tree_service.py +10 -5
  21. {zou-1.0.3 → zou-1.0.5}/zou/app/services/notifications_service.py +11 -2
  22. {zou-1.0.3 → zou-1.0.5}/zou/app/services/persons_service.py +1 -0
  23. zou-1.0.5/zou/app/services/plugins_service.py +138 -0
  24. {zou-1.0.3 → zou-1.0.5}/zou/app/services/preview_files_service.py +18 -3
  25. {zou-1.0.3 → zou-1.0.5}/zou/app/services/schedule_service.py +2 -1
  26. {zou-1.0.3 → zou-1.0.5}/zou/app/services/tasks_service.py +1 -1
  27. {zou-1.0.3 → zou-1.0.5}/zou/app/services/user_service.py +3 -0
  28. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/commands.py +1 -1
  29. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/plugins.py +114 -10
  30. {zou-1.0.3 → zou-1.0.5}/zou/cli.py +15 -5
  31. zou-1.0.5/zou/migrations/versions/12208e50bf18_add_json_data_field_to_preview_files.py +38 -0
  32. zou-1.0.5/zou/migrations/versions/35ebb38695cd_add_icon_field_to_plugins.py +36 -0
  33. zou-1.0.5/zou/migrations/versions/9a9df20ea5a7_add_frontend_options_to_plugins.py +40 -0
  34. zou-1.0.5/zou/migrations/versions/a0f668430352_add_created_by_field_to_playlists.py +44 -0
  35. zou-1.0.5/zou/plugin_template/__init__.py +28 -0
  36. {zou-1.0.3 → zou-1.0.5}/zou/plugin_template/migrations/env.py +9 -0
  37. {zou-1.0.3 → zou-1.0.5}/zou/plugin_template/models.py +2 -2
  38. zou-1.0.3/zou/plugin_template/routes.py → zou-1.0.5/zou/plugin_template/resources.py +4 -0
  39. {zou-1.0.3 → zou-1.0.5/zou.egg-info}/PKG-INFO +1 -1
  40. {zou-1.0.3 → zou-1.0.5}/zou.egg-info/SOURCES.txt +4 -1
  41. zou-1.0.3/zou/__init__.py +0 -1
  42. zou-1.0.3/zou/app/models/plugin.py +0 -22
  43. zou-1.0.3/zou/app/services/plugins_service.py +0 -66
  44. zou-1.0.3/zou/migrations/versions/a0f668430352_add_created_by_field_to_playlists.py +0 -36
  45. zou-1.0.3/zou/plugin_template/__init__.py +0 -39
  46. {zou-1.0.3 → zou-1.0.5}/LICENSE +0 -0
  47. {zou-1.0.3 → zou-1.0.5}/README.rst +0 -0
  48. {zou-1.0.3 → zou-1.0.5}/pyproject.toml +0 -0
  49. {zou-1.0.3 → zou-1.0.5}/setup.cfg +0 -0
  50. {zou-1.0.3 → zou-1.0.5}/setup.py +0 -0
  51. {zou-1.0.3 → zou-1.0.5}/zou/app/__init__.py +0 -0
  52. {zou-1.0.3 → zou-1.0.5}/zou/app/api.py +0 -0
  53. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/__init__.py +0 -0
  54. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/assets/__init__.py +0 -0
  55. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/assets/resources.py +0 -0
  56. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/auth/__init__.py +0 -0
  57. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/auth/resources.py +0 -0
  58. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/breakdown/__init__.py +0 -0
  59. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/breakdown/resources.py +0 -0
  60. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/chats/__init__.py +0 -0
  61. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/chats/resources.py +0 -0
  62. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/comments/__init__.py +0 -0
  63. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/comments/resources.py +0 -0
  64. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/concepts/__init__.py +0 -0
  65. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/concepts/resources.py +0 -0
  66. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/__init__.py +0 -0
  67. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/asset_instance.py +0 -0
  68. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/attachment_file.py +0 -0
  69. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/base.py +0 -0
  70. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/budget.py +0 -0
  71. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/budget_entry.py +0 -0
  72. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/chat.py +0 -0
  73. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/chat_message.py +0 -0
  74. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/comments.py +0 -0
  75. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/custom_action.py +0 -0
  76. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/day_off.py +0 -0
  77. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/department.py +0 -0
  78. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/entity.py +0 -0
  79. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/entity_link.py +0 -0
  80. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/entity_type.py +0 -0
  81. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/event.py +0 -0
  82. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/file_status.py +0 -0
  83. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/hardware_item.py +0 -0
  84. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/metadata_descriptor.py +0 -0
  85. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/milestone.py +0 -0
  86. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/news.py +0 -0
  87. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/notification.py +0 -0
  88. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/organisation.py +0 -0
  89. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/output_file.py +0 -0
  90. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/output_type.py +0 -0
  91. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/playlist.py +0 -0
  92. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/plugin.py +0 -0
  93. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/preview_background_file.py +0 -0
  94. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/preview_file.py +0 -0
  95. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/production_schedule_version.py +0 -0
  96. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/project.py +0 -0
  97. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/project_status.py +0 -0
  98. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/salary_scale.py +0 -0
  99. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/schedule_item.py +0 -0
  100. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/search_filter.py +0 -0
  101. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/search_filter_group.py +0 -0
  102. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/software.py +0 -0
  103. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/status_automation.py +0 -0
  104. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/studio.py +0 -0
  105. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/subscription.py +0 -0
  106. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/task.py +0 -0
  107. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/task_status.py +0 -0
  108. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/time_spent.py +0 -0
  109. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/crud/working_file.py +0 -0
  110. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/departments/__init__.py +0 -0
  111. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/departments/resources.py +0 -0
  112. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/edits/__init__.py +0 -0
  113. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/edits/resources.py +0 -0
  114. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/entities/__init__.py +0 -0
  115. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/entities/resources.py +0 -0
  116. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/events/__init__.py +0 -0
  117. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/__init__.py +0 -0
  118. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/__init__.py +0 -0
  119. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/assets.py +0 -0
  120. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/base.py +0 -0
  121. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/casting.py +0 -0
  122. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/edits.py +0 -0
  123. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/persons.py +0 -0
  124. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/playlists.py +0 -0
  125. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/projects.py +0 -0
  126. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/shots.py +0 -0
  127. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/task_types.py +0 -0
  128. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/tasks.py +0 -0
  129. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/export/csv/time_spents.py +0 -0
  130. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/files/__init__.py +0 -0
  131. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/index/__init__.py +0 -0
  132. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/news/__init__.py +0 -0
  133. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/persons/__init__.py +0 -0
  134. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/persons/resources.py +0 -0
  135. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/playlists/__init__.py +0 -0
  136. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/previews/__init__.py +0 -0
  137. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/projects/__init__.py +0 -0
  138. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/projects/resources.py +0 -0
  139. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/search/__init__.py +0 -0
  140. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/search/resources.py +0 -0
  141. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/shots/__init__.py +0 -0
  142. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/shots/resources.py +0 -0
  143. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/__init__.py +0 -0
  144. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/csv/__init__.py +0 -0
  145. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/csv/assets.py +0 -0
  146. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/csv/base.py +0 -0
  147. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/csv/casting.py +0 -0
  148. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/csv/edits.py +0 -0
  149. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/csv/persons.py +0 -0
  150. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/csv/shots.py +0 -0
  151. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/csv/task_type_estimations.py +0 -0
  152. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/kitsu.py +0 -0
  153. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/otio.py +0 -0
  154. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/__init__.py +0 -0
  155. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/assets.py +0 -0
  156. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/base.py +0 -0
  157. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/episode.py +0 -0
  158. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/exception.py +0 -0
  159. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/import_errors.py +0 -0
  160. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/notes.py +0 -0
  161. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/person.py +0 -0
  162. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/project.py +0 -0
  163. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/scene.py +0 -0
  164. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/sequence.py +0 -0
  165. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/shot.py +0 -0
  166. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/status.py +0 -0
  167. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/steps.py +0 -0
  168. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/tasks.py +0 -0
  169. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/team.py +0 -0
  170. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/source/shotgun/versions.py +0 -0
  171. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/tasks/__init__.py +0 -0
  172. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/tasks/resources.py +0 -0
  173. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/user/__init__.py +0 -0
  174. {zou-1.0.3 → zou-1.0.5}/zou/app/blueprints/user/resources.py +0 -0
  175. {zou-1.0.3 → zou-1.0.5}/zou/app/indexer/__init__.py +0 -0
  176. {zou-1.0.3 → zou-1.0.5}/zou/app/indexer/indexing.py +0 -0
  177. {zou-1.0.3 → zou-1.0.5}/zou/app/models/__init__.py +0 -0
  178. {zou-1.0.3 → zou-1.0.5}/zou/app/models/asset_instance.py +0 -0
  179. {zou-1.0.3 → zou-1.0.5}/zou/app/models/attachment_file.py +0 -0
  180. {zou-1.0.3 → zou-1.0.5}/zou/app/models/base.py +0 -0
  181. {zou-1.0.3 → zou-1.0.5}/zou/app/models/budget.py +0 -0
  182. {zou-1.0.3 → zou-1.0.5}/zou/app/models/budget_entry.py +0 -0
  183. {zou-1.0.3 → zou-1.0.5}/zou/app/models/build_job.py +0 -0
  184. {zou-1.0.3 → zou-1.0.5}/zou/app/models/chat.py +0 -0
  185. {zou-1.0.3 → zou-1.0.5}/zou/app/models/chat_message.py +0 -0
  186. {zou-1.0.3 → zou-1.0.5}/zou/app/models/comment.py +0 -0
  187. {zou-1.0.3 → zou-1.0.5}/zou/app/models/custom_action.py +0 -0
  188. {zou-1.0.3 → zou-1.0.5}/zou/app/models/data_import_error.py +0 -0
  189. {zou-1.0.3 → zou-1.0.5}/zou/app/models/day_off.py +0 -0
  190. {zou-1.0.3 → zou-1.0.5}/zou/app/models/department.py +0 -0
  191. {zou-1.0.3 → zou-1.0.5}/zou/app/models/desktop_login_log.py +0 -0
  192. {zou-1.0.3 → zou-1.0.5}/zou/app/models/entity.py +0 -0
  193. {zou-1.0.3 → zou-1.0.5}/zou/app/models/entity_type.py +0 -0
  194. {zou-1.0.3 → zou-1.0.5}/zou/app/models/event.py +0 -0
  195. {zou-1.0.3 → zou-1.0.5}/zou/app/models/file_status.py +0 -0
  196. {zou-1.0.3 → zou-1.0.5}/zou/app/models/hardware_item.py +0 -0
  197. {zou-1.0.3 → zou-1.0.5}/zou/app/models/login_log.py +0 -0
  198. {zou-1.0.3 → zou-1.0.5}/zou/app/models/metadata_descriptor.py +0 -0
  199. {zou-1.0.3 → zou-1.0.5}/zou/app/models/milestone.py +0 -0
  200. {zou-1.0.3 → zou-1.0.5}/zou/app/models/news.py +0 -0
  201. {zou-1.0.3 → zou-1.0.5}/zou/app/models/notification.py +0 -0
  202. {zou-1.0.3 → zou-1.0.5}/zou/app/models/organisation.py +0 -0
  203. {zou-1.0.3 → zou-1.0.5}/zou/app/models/output_file.py +0 -0
  204. {zou-1.0.3 → zou-1.0.5}/zou/app/models/output_type.py +0 -0
  205. {zou-1.0.3 → zou-1.0.5}/zou/app/models/person.py +0 -0
  206. {zou-1.0.3 → zou-1.0.5}/zou/app/models/playlist.py +0 -0
  207. {zou-1.0.3 → zou-1.0.5}/zou/app/models/preview_background_file.py +0 -0
  208. {zou-1.0.3 → zou-1.0.5}/zou/app/models/production_schedule_version.py +0 -0
  209. {zou-1.0.3 → zou-1.0.5}/zou/app/models/project.py +0 -0
  210. {zou-1.0.3 → zou-1.0.5}/zou/app/models/project_status.py +0 -0
  211. {zou-1.0.3 → zou-1.0.5}/zou/app/models/salary_scale.py +0 -0
  212. {zou-1.0.3 → zou-1.0.5}/zou/app/models/schedule_item.py +0 -0
  213. {zou-1.0.3 → zou-1.0.5}/zou/app/models/search_filter.py +0 -0
  214. {zou-1.0.3 → zou-1.0.5}/zou/app/models/search_filter_group.py +0 -0
  215. {zou-1.0.3 → zou-1.0.5}/zou/app/models/serializer.py +0 -0
  216. {zou-1.0.3 → zou-1.0.5}/zou/app/models/software.py +0 -0
  217. {zou-1.0.3 → zou-1.0.5}/zou/app/models/status_automation.py +0 -0
  218. {zou-1.0.3 → zou-1.0.5}/zou/app/models/studio.py +0 -0
  219. {zou-1.0.3 → zou-1.0.5}/zou/app/models/subscription.py +0 -0
  220. {zou-1.0.3 → zou-1.0.5}/zou/app/models/task.py +0 -0
  221. {zou-1.0.3 → zou-1.0.5}/zou/app/models/task_status.py +0 -0
  222. {zou-1.0.3 → zou-1.0.5}/zou/app/models/task_type.py +0 -0
  223. {zou-1.0.3 → zou-1.0.5}/zou/app/models/time_spent.py +0 -0
  224. {zou-1.0.3 → zou-1.0.5}/zou/app/models/working_file.py +0 -0
  225. {zou-1.0.3 → zou-1.0.5}/zou/app/services/__init__.py +0 -0
  226. {zou-1.0.3 → zou-1.0.5}/zou/app/services/assets_service.py +0 -0
  227. {zou-1.0.3 → zou-1.0.5}/zou/app/services/auth_service.py +0 -0
  228. {zou-1.0.3 → zou-1.0.5}/zou/app/services/backup_service.py +0 -0
  229. {zou-1.0.3 → zou-1.0.5}/zou/app/services/base_service.py +0 -0
  230. {zou-1.0.3 → zou-1.0.5}/zou/app/services/breakdown_service.py +0 -0
  231. {zou-1.0.3 → zou-1.0.5}/zou/app/services/budget_service.py +0 -0
  232. {zou-1.0.3 → zou-1.0.5}/zou/app/services/chats_service.py +0 -0
  233. {zou-1.0.3 → zou-1.0.5}/zou/app/services/concepts_service.py +0 -0
  234. {zou-1.0.3 → zou-1.0.5}/zou/app/services/custom_actions_service.py +0 -0
  235. {zou-1.0.3 → zou-1.0.5}/zou/app/services/departments_service.py +0 -0
  236. {zou-1.0.3 → zou-1.0.5}/zou/app/services/edits_service.py +0 -0
  237. {zou-1.0.3 → zou-1.0.5}/zou/app/services/emails_service.py +0 -0
  238. {zou-1.0.3 → zou-1.0.5}/zou/app/services/entities_service.py +0 -0
  239. {zou-1.0.3 → zou-1.0.5}/zou/app/services/exception.py +0 -0
  240. {zou-1.0.3 → zou-1.0.5}/zou/app/services/files_service.py +0 -0
  241. {zou-1.0.3 → zou-1.0.5}/zou/app/services/index_service.py +0 -0
  242. {zou-1.0.3 → zou-1.0.5}/zou/app/services/names_service.py +0 -0
  243. {zou-1.0.3 → zou-1.0.5}/zou/app/services/news_service.py +0 -0
  244. {zou-1.0.3 → zou-1.0.5}/zou/app/services/playlists_service.py +0 -0
  245. {zou-1.0.3 → zou-1.0.5}/zou/app/services/projects_service.py +0 -0
  246. {zou-1.0.3 → zou-1.0.5}/zou/app/services/scenes_service.py +0 -0
  247. {zou-1.0.3 → zou-1.0.5}/zou/app/services/shots_service.py +0 -0
  248. {zou-1.0.3 → zou-1.0.5}/zou/app/services/stats_service.py +0 -0
  249. {zou-1.0.3 → zou-1.0.5}/zou/app/services/status_automations_service.py +0 -0
  250. {zou-1.0.3 → zou-1.0.5}/zou/app/services/sync_service.py +0 -0
  251. {zou-1.0.3 → zou-1.0.5}/zou/app/services/telemetry_services.py +0 -0
  252. {zou-1.0.3 → zou-1.0.5}/zou/app/services/templates_service.py +0 -0
  253. {zou-1.0.3 → zou-1.0.5}/zou/app/services/time_spents_service.py +0 -0
  254. {zou-1.0.3 → zou-1.0.5}/zou/app/stores/__init__.py +0 -0
  255. {zou-1.0.3 → zou-1.0.5}/zou/app/stores/auth_tokens_store.py +0 -0
  256. {zou-1.0.3 → zou-1.0.5}/zou/app/stores/file_store.py +0 -0
  257. {zou-1.0.3 → zou-1.0.5}/zou/app/stores/publisher_store.py +0 -0
  258. {zou-1.0.3 → zou-1.0.5}/zou/app/stores/queue_store.py +0 -0
  259. {zou-1.0.3 → zou-1.0.5}/zou/app/swagger.py +0 -0
  260. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/__init__.py +0 -0
  261. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/api.py +0 -0
  262. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/auth.py +0 -0
  263. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/cache.py +0 -0
  264. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/chats.py +0 -0
  265. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/colors.py +0 -0
  266. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/csv_utils.py +0 -0
  267. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/date_helpers.py +0 -0
  268. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/dbhelpers.py +0 -0
  269. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/emails.py +0 -0
  270. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/env.py +0 -0
  271. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/events.py +0 -0
  272. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/fido.py +0 -0
  273. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/fields.py +0 -0
  274. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/flask.py +0 -0
  275. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/fs.py +0 -0
  276. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/git.py +0 -0
  277. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/logs.py +0 -0
  278. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/monitoring.py +0 -0
  279. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/permissions.py +0 -0
  280. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/query.py +0 -0
  281. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/redis.py +0 -0
  282. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/remote_job.py +0 -0
  283. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/saml.py +0 -0
  284. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/shell.py +0 -0
  285. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/string.py +0 -0
  286. {zou-1.0.3 → zou-1.0.5}/zou/app/utils/thumbnail.py +0 -0
  287. {zou-1.0.3 → zou-1.0.5}/zou/debug.py +0 -0
  288. {zou-1.0.3 → zou-1.0.5}/zou/event_stream.py +0 -0
  289. {zou-1.0.3 → zou-1.0.5}/zou/job_settings.py +0 -0
  290. {zou-1.0.3 → zou-1.0.5}/zou/migrations/README +0 -0
  291. {zou-1.0.3 → zou-1.0.5}/zou/migrations/__init__.py +0 -0
  292. {zou-1.0.3 → zou-1.0.5}/zou/migrations/alembic.ini +0 -0
  293. {zou-1.0.3 → zou-1.0.5}/zou/migrations/env.py +0 -0
  294. {zou-1.0.3 → zou-1.0.5}/zou/migrations/script.py.mako +0 -0
  295. {zou-1.0.3 → zou-1.0.5}/zou/migrations/utils/__init__.py +0 -0
  296. {zou-1.0.3 → zou-1.0.5}/zou/migrations/utils/base.py +0 -0
  297. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/003be8a91001_add_start_and_end_dates_to_projects.py +0 -0
  298. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/0596674df51d_add_department_mentions_to_comments.py +0 -0
  299. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/05ac7e8caa21_remove_unique_constraint_for_taskstatus_.py +0 -0
  300. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/05b7dc79a416_add_archived_fields_to_main_tables.py +0 -0
  301. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/06552e22f9e7_add_comment_updated_by.py +0 -0
  302. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/0bd1e89f2a6f_add_productionscheduleversiontasklink_uc.py +0 -0
  303. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/0c05b22194f3_add_performance_indexes.py +0 -0
  304. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/0cf5e0e035fa_drop_column_tasktype_for_shots.py +0 -0
  305. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/0ec3762a745d_add_attachment_table.py +0 -0
  306. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/0ef6416a507b_.py +0 -0
  307. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/10cf267d95c9_fix_schedule_item.py +0 -0
  308. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/16328eae4b5f_add_new_constraint_for_timespent.py +0 -0
  309. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/16df47d76c64_add_some_indexes.py +0 -0
  310. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/17ef8f7be758_disallow_null_choicetype.py +0 -0
  311. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/1b0ab951adca_add_reply_id_to_attachments.py +0 -0
  312. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/1bb55759146f_add_table_studio.py +0 -0
  313. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/1cb44194db49_add_file_size_field_to_preview_file.py +0 -0
  314. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/1e150c2cea4d_add_nb_entities_out.py +0 -0
  315. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/1e2d77a2f0c4_add_hd_by_default_column.py +0 -0
  316. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/1fab8c420678_add_attachments_to_message_chats.py +0 -0
  317. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/20a8ad264659_tasktypeassettypelink_.py +0 -0
  318. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/20dfeb36142b_add_projecttaskstatuslink_roles_for_.py +0 -0
  319. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/23122f290ca2_add_entity_chat_models.py +0 -0
  320. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/269d41bfb73f_add_entity_entity_links.py +0 -0
  321. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/26f96f65cfa3_add_productionversionschedule_uc.py +0 -0
  322. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/2762a797f1f9_add_people_salary_information.py +0 -0
  323. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/29df910f04a4_create_unique_constraint_project_id_.py +0 -0
  324. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/29fe01a6c9eb_add_status_automation_field.py +0 -0
  325. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/2adc020885fa_.py +0 -0
  326. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/2baede80b111_add_entity_status_field.py +0 -0
  327. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/306266361f4f_.py +0 -0
  328. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/307edd8c639d_change_comment_updated_by_in_comment_.py +0 -0
  329. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/328fd44c6347_add_entity_created_by.py +0 -0
  330. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/32f134ff1201_add_is_shared_flag_to_filters.py +0 -0
  331. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/346250b5304c_add_position_to_preview_files.py +0 -0
  332. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/3476e147e632_add_acks_to_comments.py +0 -0
  333. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/389cfb9de776_.py +0 -0
  334. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/38baa9a23b3d_.py +0 -0
  335. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/398150912a3f_validation_status_preview.py +0 -0
  336. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/3b0d1321079e_.py +0 -0
  337. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/3d5c93bafb9d_.py +0 -0
  338. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/3d8e68dffeee_fix_task_person_link.py +0 -0
  339. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/3e0538ddf80f_.py +0 -0
  340. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/3fee3bd10f9d_.py +0 -0
  341. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/4095103c7d01_add_is_clients_isolated_flag_to_projects.py +0 -0
  342. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/40dea9555940_.py +0 -0
  343. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/42ec83db6a01_change_person_preferred_two_factor_.py +0 -0
  344. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/4368137b44e1_productionscheduleversion_add_on_delete_.py +0 -0
  345. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/43d0cf0ed5e7_.py +0 -0
  346. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/443d1e78a932_.py +0 -0
  347. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/45c2de366e66_.py +0 -0
  348. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/45dafbb3f4e1_for_person_contract_type_disallow_null.py +0 -0
  349. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/45f739ef962a_add_people_salary_scale_table.py +0 -0
  350. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/4715c2586036_add_last_preview_file_fields.py +0 -0
  351. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/4aab1f84ad72_introduce_plugin_table.py +0 -0
  352. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/4bd9bfb73f11_add_fields_to_the_software_table.py +0 -0
  353. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/4d585b6956f2_add_taskstatus_is_wip.py +0 -0
  354. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/4e3738cdc34c_.py +0 -0
  355. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/4f2398ebcd49_.py +0 -0
  356. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/523ee9647bee_.py +0 -0
  357. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/539a3a00c417_for_departmentlink_index_person_id_.py +0 -0
  358. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/54ee0d1d60ba_add_build_job_model.py +0 -0
  359. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/556526e47daa_.py +0 -0
  360. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/57222395f2be_add_statusautomation_import_last_revision.py +0 -0
  361. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5798d2c9020b_change_person_role_to_choicetype.py +0 -0
  362. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/590aa1ffe731_add_notifications_enabled_flag.py +0 -0
  363. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/59a7445a966c_add_entity_is_shared.py +0 -0
  364. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5a291251823c_add_max_retake_parameter.py +0 -0
  365. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5ab9d7a75887_.py +0 -0
  366. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5b0fcbb94f24_.py +0 -0
  367. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5b7fa3e51701_add_is_client_allowed_flag_to_task_.py +0 -0
  368. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5b980f0dc365_add_comment_links.py +0 -0
  369. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5b9fd9ddfe43_add_homepage_and_contract_fields.py +0 -0
  370. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5c0498e264bc_add_slack_fields.py +0 -0
  371. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5e2ce62632a6_add_workflow_to_project.py +0 -0
  372. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5f1620d191af_add_playlist_id_field_to_notification.py +0 -0
  373. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/5f715f2b6348_add_new_table_productionscheduleversion.py +0 -0
  374. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/680c64565f9d_for_searchfiltergroup_is_shared.py +0 -0
  375. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/693cc511d28d_add_taskstatus_priority.py +0 -0
  376. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/6aa446ee4072_add_is_for_all_flage_to_playlists.py +0 -0
  377. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/6bd3b102d61b_.py +0 -0
  378. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/6c597e842afa_add_task_type_field_to_playlists.py +0 -0
  379. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/6d1b2c60f58b_add_milestone_model.py +0 -0
  380. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/6d7fa5a8e9a5_add_timesheets_locked_field_to_org.py +0 -0
  381. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/6eeaff945706_add_data_field_on_entity_links.py +0 -0
  382. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/6f6049877105_.py +0 -0
  383. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/71d546ace0ee_add_performance_indexes.py +0 -0
  384. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/7417c8eb70d8_add_for_entity_field_to_playlists.py +0 -0
  385. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/772a5e43f05b_.py +0 -0
  386. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/7748d3d22925_add_columns_to_searchfilter_table_to_.py +0 -0
  387. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/77d6820f494f_add_reply_to_notif.py +0 -0
  388. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/7a16258f2fab_add_currency_field_to_budgets.py +0 -0
  389. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/7b1f765677d8_.py +0 -0
  390. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/7bc746997e8d_add_slack_token_field_to_organisation.py +0 -0
  391. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/7dc79d4ed7cd_.py +0 -0
  392. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/818f7bda2528_.py +0 -0
  393. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/82e7f7a95e84_add_project_id_to_events.py +0 -0
  394. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/82ee682204ab_add_is_generated_from_ldap_column_to_.py +0 -0
  395. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/83e2f33a9b14_add_project_bugdet_table.py +0 -0
  396. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/8588f254d6b8_add_archived_fields.py +0 -0
  397. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/8739ae9fa28b_add_for_client_field.py +0 -0
  398. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/87efceb6745b_add_ready_for_to_entity.py +0 -0
  399. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/892b264937ec_.py +0 -0
  400. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/8a1b4a1b7f4a_add_totp_columns_for_person.py +0 -0
  401. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/8ab98c178903_add_budget_entry_table.py +0 -0
  402. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/8e4f39e321f4_add_day_off_table.py +0 -0
  403. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/8e67c183bed7_add_preference_fields.py +0 -0
  404. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/8fbd40afbe5f_allow_to_set_float_values_for_.py +0 -0
  405. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9010a64e5a2d_add_indices.py +0 -0
  406. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9060dd4f6116_notification_uc.py +0 -0
  407. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/925771029620_.py +0 -0
  408. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/92b40d79ad3f_allow_message_attachments.py +0 -0
  409. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/92bdfe07e5f5_discord_integration.py +0 -0
  410. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/956659992419_add_columns_for_person_to_store_fido_.py +0 -0
  411. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9683bd840dee_add_archived_field_to_software.py +0 -0
  412. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/96c79d31e648_add_mail_otp_columns_for_person.py +0 -0
  413. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/96f58a4a2a58_person_partial_index_for_email_only_.py +0 -0
  414. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/971dbf5a0faf_add_short_name_for_asset_type_entity_.py +0 -0
  415. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/98c90621cf58_add_for_client_flag_to_playlist.py +0 -0
  416. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/99825b9cc778_.py +0 -0
  417. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9a09467f9b2c_.py +0 -0
  418. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9af2df17a9d5_add_hardware_table.py +0 -0
  419. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9b85c14fa8a7_add_day_off_new_columns.py +0 -0
  420. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9bd17364fc18_.py +0 -0
  421. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9d3bb33c6fc6_add_department_keys_to_filter_models.py +0 -0
  422. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9e5b3a9b0cee_add_new_column_metadatadescriptor_data_type_.py +0 -0
  423. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/9f8445f9b42c_add_man_days_fields.py +0 -0
  424. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/a1b2c3d4e5f6_add_position_to_metadata_descriptor.py +0 -0
  425. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/a23682ccc1f1_.py +0 -0
  426. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/a252a094e977_add_descriptions_for_entities_tasks_and_.py +0 -0
  427. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/a519c710877c_.py +0 -0
  428. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/a65bdadbae2f_.py +0 -0
  429. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/a66508788c53_add_nb_assets_ready.py +0 -0
  430. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/a6c25eed3ea1_add_login_failed_attemps_and_last_login_.py +0 -0
  431. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/a7c43f3fbc76_add_duration_column_to_the_preview_file.py +0 -0
  432. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/aa0a60033106_feedback_request.py +0 -0
  433. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/addbad59c706_allow_to_manage_drawings_instead_of_.py +0 -0
  434. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/addbbefa7028_add_departments_link_to_metadata_.py +0 -0
  435. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/ae0127f2fc56_add_previewfile_width_and_previewfile_.py +0 -0
  436. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/af1790868e2c_.py +0 -0
  437. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/b45cb782bb9c_.py +0 -0
  438. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/b4dd0add5f79_.py +0 -0
  439. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/b8c0a0f9d054_drop_task_status_is_reviewable.py +0 -0
  440. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/b8ed0fb263f8_add_person_jti_and_jti_expiration_date.py +0 -0
  441. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/b97a71306fc8_add_is_casting_standby_column_to_entity.py +0 -0
  442. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/be56dc0fb760_for_is_shared_disallow_nullable.py +0 -0
  443. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/bf1347acdee2_.py +0 -0
  444. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/c49e41f1298b_add_previewbackground.py +0 -0
  445. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/c68c2a62cfac_add_mimetype_column_to_attachment.py +0 -0
  446. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/c726b98be194_.py +0 -0
  447. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/c81f3e83bdb5_.py +0 -0
  448. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/ca28796a2a62_add_is_done_field_to_the_task_model.py +0 -0
  449. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/ce7f46f445dc_add_column_estimation_for_.py +0 -0
  450. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/cf3d365de164_add_entity_version_model.py +0 -0
  451. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/cf6cec6d6bf5_add_status_field_to_preview_file.py +0 -0
  452. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/d25118cddcaa_modify_salary_scale_model.py +0 -0
  453. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/d5665dca188b_add_version_field_to_software.py +0 -0
  454. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/d80267806131_task_status_new_column_is_default.py +0 -0
  455. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/d80f02824047_add_plugin_revision.py +0 -0
  456. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/d8dcd5196d57_add_casting_label.py +0 -0
  457. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/d97f2730bf7b_add_.py +0 -0
  458. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/dde6be40f54f_add_departement_links_tables_for_.py +0 -0
  459. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/de8a3de227ef_.py +0 -0
  460. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/deeacd38d373_for_projecttaskstatuslink_set_default_.py +0 -0
  461. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/df1834485f57_.py +0 -0
  462. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/df9f8a147e80_change_file_size_to_big_integer.py +0 -0
  463. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/e1ef93f40d3d_.py +0 -0
  464. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/e29638428dfd_add_schedule_item_table.py +0 -0
  465. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/e3f6db74cc1e_.py +0 -0
  466. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/e4b48ca33539_add_project_production_schedule_version_.py +0 -0
  467. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/e7e633bd6fa2_add_exceptions_to_budget_entries.py +0 -0
  468. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/e839d6603c09_add_person_id_to_shot_history.py +0 -0
  469. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/e8bc24998b34_remove_on_delete_cascade_for_.py +0 -0
  470. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/ee2373fbe3a4_.py +0 -0
  471. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/f0567e8d0c62_.py +0 -0
  472. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/f0c6cbb61869_add_production_style_field.py +0 -0
  473. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/f344b867a911_for_description_of_entity_task_working_.py +0 -0
  474. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/f4ff5a73d283_add_person_ldap_uid.py +0 -0
  475. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/f5b113876a49_add_preferred_two_factor_authentication_.py +0 -0
  476. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/f5bdca075cdc_add_preview_download_flag_to_projects.py +0 -0
  477. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/f874ad5e898a_add_link_entity_type_task_type.py +0 -0
  478. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/f995b28fb749_.py +0 -0
  479. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/fb6b6f188497_.py +0 -0
  480. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/fb87feaaa094_add_missing_unique_constraints.py +0 -0
  481. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/fba149993140_add_missing_index.py +0 -0
  482. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/fc322f908695_.py +0 -0
  483. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/fee7c696166e_.py +0 -0
  484. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/feffd3c5b806_introduce_concepts.py +0 -0
  485. {zou-1.0.3 → zou-1.0.5}/zou/migrations/versions/ffeed4956ab1_add_more_details_to_projects.py +0 -0
  486. {zou-1.0.3 → zou-1.0.5}/zou/plugin_template/migrations/alembic.ini +0 -0
  487. {zou-1.0.3 → zou-1.0.5}/zou/plugin_template/migrations/script.py.mako +0 -0
  488. {zou-1.0.3 → zou-1.0.5}/zou/remote/__init__.py +0 -0
  489. {zou-1.0.3 → zou-1.0.5}/zou/remote/config_payload.py +0 -0
  490. {zou-1.0.3 → zou-1.0.5}/zou/remote/normalize_movie.py +0 -0
  491. {zou-1.0.3 → zou-1.0.5}/zou/remote/playlist.py +0 -0
  492. {zou-1.0.3 → zou-1.0.5}/zou/utils/__init__.py +0 -0
  493. {zou-1.0.3 → zou-1.0.5}/zou/utils/movie.py +0 -0
  494. {zou-1.0.3 → zou-1.0.5}/zou.egg-info/dependency_links.txt +0 -0
  495. {zou-1.0.3 → zou-1.0.5}/zou.egg-info/entry_points.txt +0 -0
  496. {zou-1.0.3 → zou-1.0.5}/zou.egg-info/not-zip-safe +0 -0
  497. {zou-1.0.3 → zou-1.0.5}/zou.egg-info/requires.txt +0 -0
  498. {zou-1.0.3 → zou-1.0.5}/zou.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zou
3
- Version: 1.0.3
3
+ Version: 1.0.5
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
@@ -0,0 +1 @@
1
+ __version__ = "1.0.5"
@@ -604,6 +604,7 @@ class PersonResource(BaseModelResource, ArgsMixin):
604
604
  if (
605
605
  instance_dict["email"] in config.PROTECTED_ACCOUNTS
606
606
  and instance_dict["id"] != persons_service.get_current_user()["id"]
607
+ and instance_dict.get("is_bot", False) == False
607
608
  ):
608
609
  message = None
609
610
  if data.get("active") is False:
@@ -1,6 +1,7 @@
1
1
  from flask_jwt_extended import jwt_required
2
2
 
3
3
  from zou.app.models.task_type import TaskType
4
+ from zou.app.models.schedule_item import ScheduleItem
4
5
  from zou.app.services.exception import WrongParameterException
5
6
  from zou.app.services import tasks_service
6
7
 
@@ -317,6 +318,15 @@ class TaskTypeResource(BaseModelResource):
317
318
  """
318
319
  return super().delete(instance_id)
319
320
 
321
+ def pre_delete(self, instance_dict):
322
+ """
323
+ Delete related ScheduleItems before deleting the TaskType.
324
+ This runs AFTER check_delete_permissions, preventing foreign key
325
+ constraint violations while maintaining security.
326
+ """
327
+ ScheduleItem.query.filter_by(task_type_id=instance_dict["id"]).delete()
328
+ return instance_dict
329
+
320
330
  def update_data(self, data, instance_id):
321
331
  data = super().update_data(data, instance_id)
322
332
  name = data.get("name", None)
@@ -38,6 +38,13 @@ class EventsResource(Resource, ArgsMixin):
38
38
  default: false
39
39
  description: Return only file-related events
40
40
  example: false
41
+ - in: query
42
+ name: cursor_event_id
43
+ required: False
44
+ type: string
45
+ format: uuid
46
+ example: a24a6ea4-ce75-4665-a070-57453082c25
47
+ description: ID of the last event from previous page for cursor-based pagination
41
48
  - in: query
42
49
  name: limit
43
50
  type: integer
@@ -99,7 +106,8 @@ class EventsResource(Resource, ArgsMixin):
99
106
  ("after", None, False),
100
107
  ("before", None, False),
101
108
  ("only_files", False, False),
102
- ("limit", 100, False),
109
+ ("cursor_event_id", None, False),
110
+ ("limit", 100, False, int),
103
111
  ("project_id", None, False),
104
112
  ("name", None, False),
105
113
  ],
@@ -108,6 +116,7 @@ class EventsResource(Resource, ArgsMixin):
108
116
  permissions.check_manager_permissions()
109
117
  before = self.parse_date_parameter(args["before"])
110
118
  after = self.parse_date_parameter(args["after"])
119
+ cursor_event_id = args["cursor_event_id"]
111
120
  limit = args["limit"]
112
121
  only_files = args["only_files"] == "true"
113
122
  project_id = args.get("project_id", None)
@@ -116,15 +125,21 @@ class EventsResource(Resource, ArgsMixin):
116
125
  raise WrongParameterException(
117
126
  "The project_id parameter is not a valid id"
118
127
  )
119
- else:
120
- return events_service.get_last_events(
121
- after=after,
122
- before=before,
123
- limit=limit,
124
- only_files=only_files,
125
- project_id=project_id,
126
- name=name,
128
+ if cursor_event_id is not None and not fields.is_valid_id(
129
+ cursor_event_id
130
+ ):
131
+ raise WrongParameterException(
132
+ "The cursor_event_id parameter is not a valid id"
127
133
  )
134
+ return events_service.get_last_events(
135
+ after=after,
136
+ before=before,
137
+ cursor_event_id=cursor_event_id,
138
+ limit=limit,
139
+ only_files=only_files,
140
+ project_id=project_id,
141
+ name=name,
142
+ )
128
143
 
129
144
 
130
145
  class LoginLogsResource(Resource, ArgsMixin):
@@ -1303,6 +1303,8 @@ class NewEntityOutputFileResource(Resource, ArgsMixin):
1303
1303
  return {"error": "Cannot find given person."}, 400
1304
1304
  except EntryAlreadyExistsException:
1305
1305
  return {"error": "The given output file already exists."}, 400
1306
+ except MalformedFileTreeException as exception:
1307
+ return {"error": str(exception)}, 400
1306
1308
 
1307
1309
  return output_file_dict, 201
1308
1310
 
@@ -1,16 +1,21 @@
1
+ import datetime
2
+
1
3
  import psutil
2
4
  import redis
3
5
  import requests
4
- import datetime
5
-
6
6
  from flask import Response, abort
7
+ from flask_jwt_extended import jwt_required
7
8
  from flask_restful import Resource
8
- from zou import __version__
9
9
 
10
+ from zou import __version__
10
11
  from zou.app import app, config
11
- from zou.app.utils import permissions, shell, date_helpers
12
- from zou.app.services import projects_service, stats_service, persons_service
13
- from flask_jwt_extended import jwt_required
12
+ from zou.app.indexer import indexing
13
+ from zou.app.services import (
14
+ persons_service,
15
+ projects_service,
16
+ stats_service,
17
+ )
18
+ from zou.app.utils import date_helpers, permissions, shell
14
19
  from zou.app.utils.redis import get_redis_url
15
20
 
16
21
 
@@ -40,14 +45,32 @@ class IndexResource(Resource):
40
45
 
41
46
 
42
47
  class BaseStatusResource(Resource):
48
+
43
49
  def get_status(self):
44
- is_db_up = True
50
+ is_db_up = self._check_database()
51
+ is_kv_up = self._check_key_value_store()
52
+ is_es_up = self._check_event_stream()
53
+ is_jq_up = self._check_job_queue()
54
+ is_indexer_up = self._check_indexer()
55
+
56
+ return (
57
+ config.APP_NAME,
58
+ __version__,
59
+ is_db_up,
60
+ is_kv_up,
61
+ is_es_up,
62
+ is_jq_up,
63
+ is_indexer_up,
64
+ )
65
+
66
+ def _check_database(self):
45
67
  try:
46
68
  projects_service.get_or_create_status("Open")
69
+ return True
47
70
  except Exception:
48
- is_db_up = False
71
+ return False
49
72
 
50
- is_kv_up = True
73
+ def _check_key_value_store(self):
51
74
  try:
52
75
  store = redis.StrictRedis(
53
76
  host=config.KEY_VALUE_STORE["host"],
@@ -57,18 +80,21 @@ class BaseStatusResource(Resource):
57
80
  decode_responses=True,
58
81
  )
59
82
  store.get("test")
83
+ return True
60
84
  except redis.ConnectionError:
61
- is_kv_up = False
85
+ return False
62
86
 
63
- is_es_up = True
87
+ def _check_event_stream(self):
64
88
  try:
65
89
  requests.get(
66
- f"http://{config.EVENT_STREAM_HOST}:{config.EVENT_STREAM_PORT}"
90
+ f"http://{config.EVENT_STREAM_HOST}:{config.EVENT_STREAM_PORT}",
91
+ timeout=5,
67
92
  )
93
+ return True
68
94
  except Exception:
69
- is_es_up = False
95
+ return False
70
96
 
71
- is_jq_up = True
97
+ def _check_job_queue(self):
72
98
  try:
73
99
  args = [
74
100
  "rq",
@@ -77,30 +103,20 @@ class BaseStatusResource(Resource):
77
103
  get_redis_url(config.KV_JOB_DB_INDEX),
78
104
  ]
79
105
  out = shell.run_command(args)
80
- is_jq_up = b"0 workers" not in out
106
+ return b"0 workers" not in out
81
107
  except Exception:
82
108
  app.logger.error("Job queue is not accessible", exc_info=1)
83
- is_jq_up = False
109
+ return False
84
110
 
85
- is_indexer_up = True
111
+ def _check_indexer(self):
86
112
  try:
87
- requests.get(
88
- f"{config.INDEXER['protocol']}://{config.INDEXER['host']}:{config.INDEXER['port']}"
89
- )
113
+ client = indexing.get_client()
114
+ client.get_indexes()
115
+ return True
116
+ except indexing.IndexerNotInitializedError:
117
+ return False
90
118
  except Exception:
91
- is_indexer_up = False
92
-
93
- version = __version__
94
-
95
- return (
96
- config.APP_NAME,
97
- version,
98
- is_db_up,
99
- is_kv_up,
100
- is_es_up,
101
- is_jq_up,
102
- is_indexer_up,
103
- )
119
+ return False
104
120
 
105
121
 
106
122
  class StatusResource(BaseStatusResource):
@@ -224,9 +240,16 @@ class StatusResourcesResource(BaseStatusResource):
224
240
  type: integer
225
241
  example: 3
226
242
  """
227
- loadavg = list(psutil.getloadavg())
243
+ return {
244
+ "date": datetime.datetime.now().isoformat(),
245
+ "cpu": self._get_cpu_stats(),
246
+ "memory": self._get_memory_stats(),
247
+ "jobs": self._get_job_stats(),
248
+ }
228
249
 
229
- cpu_stats = {
250
+ def _get_cpu_stats(self):
251
+ loadavg = list(psutil.getloadavg())
252
+ return {
230
253
  "percent": psutil.cpu_percent(interval=1, percpu=True),
231
254
  "loadavg": {
232
255
  "last 1 min": loadavg[0],
@@ -235,29 +258,23 @@ class StatusResourcesResource(BaseStatusResource):
235
258
  },
236
259
  }
237
260
 
238
- memory_stats = {
239
- "total": psutil.virtual_memory().total,
240
- "used": psutil.virtual_memory().used,
241
- "available": psutil.virtual_memory().available,
242
- "percent": psutil.virtual_memory().percent,
261
+ def _get_memory_stats(self):
262
+ memory = psutil.virtual_memory()
263
+ return {
264
+ "total": memory.total,
265
+ "used": memory.used,
266
+ "available": memory.available,
267
+ "percent": memory.percent,
243
268
  }
244
269
 
270
+ def _get_job_stats(self):
245
271
  nb_jobs = 0
246
272
  if config.ENABLE_JOB_QUEUE:
247
273
  from zou.app.stores.queue_store import job_queue
248
274
 
249
275
  registry = job_queue.started_job_registry
250
276
  nb_jobs = registry.count
251
- job_stats = {
252
- "running_jobs": nb_jobs,
253
- }
254
-
255
- return {
256
- "date": datetime.datetime.now().isoformat(),
257
- "cpu": cpu_stats,
258
- "memory": memory_stats,
259
- "jobs": job_stats,
260
- }
277
+ return {"running_jobs": nb_jobs}
261
278
 
262
279
 
263
280
  class TxtStatusResource(BaseStatusResource):
@@ -294,22 +311,14 @@ class TxtStatusResource(BaseStatusResource):
294
311
  is_indexer_up,
295
312
  ) = self.get_status()
296
313
 
297
- text = """name: %s
298
- version: %s
299
- database-up: %s
300
- event-stream-up: %s
301
- key-value-store-up: %s
302
- job-queue-up: %s
303
- indexer-up: %s
304
- """ % (
305
- api_name,
306
- version,
307
- "up" if is_db_up else "down",
308
- "up" if is_kv_up else "down",
309
- "up" if is_es_up else "down",
310
- "up" if is_jq_up else "down",
311
- "up" if is_indexer_up else "down",
312
- )
314
+ text = f"""name: {api_name}
315
+ version: {version}
316
+ database-up: {"up" if is_db_up else "down"}
317
+ event-stream-up: {"up" if is_es_up else "down"}
318
+ key-value-store-up: {"up" if is_kv_up else "down"}
319
+ job-queue-up: {"up" if is_jq_up else "down"}
320
+ indexer-up: {"up" if is_indexer_up else "down"}
321
+ """
313
322
  return Response(text, mimetype="text")
314
323
 
315
324
 
@@ -469,6 +478,7 @@ class ConfigResource(Resource):
469
478
  "saml_idp_name": config.SAML_IDP_NAME,
470
479
  "default_locale": config.DEFAULT_LOCALE,
471
480
  "default_timezone": config.DEFAULT_TIMEZONE,
481
+ "enforce_2fa": config.ENFORCE_2FA,
472
482
  }
473
483
  if config.SENTRY_KITSU_ENABLED:
474
484
  conf["sentry"] = {
@@ -228,7 +228,7 @@ class NewsResource(Resource, NewsMixin, ArgsMixin):
228
228
  """
229
229
  Get open projects news
230
230
  ---
231
- description: Returns the latest news and activity feed from all
231
+ description: Returns the latest news and activity feed from all
232
232
  projects the user has access to.
233
233
  tags:
234
234
  - News
@@ -348,7 +348,7 @@ class ProjectSingleNewsResource(Resource):
348
348
  """
349
349
  Get news item
350
350
  ---
351
- description: Retrieves detailed information about a specific news item
351
+ description: Retrieves detailed information about a specific news item
352
352
  from a givenproject.
353
353
  tags:
354
354
  - News
@@ -835,6 +835,11 @@ class NotifyClientsResource(Resource, ArgsMixin):
835
835
  format: uuid
836
836
  description: Studio unique identifier to notify
837
837
  example: b35b7fb5-df86-5776-b181-68564193d36
838
+ department_id:
839
+ type: string
840
+ format: uuid
841
+ description: Department unique identifier to notify
842
+ example: c46c8gc6-eg97-6887-c292-79675204e47
838
843
  responses:
839
844
  200:
840
845
  description: Clients notified successfully
@@ -848,11 +853,12 @@ class NotifyClientsResource(Resource, ArgsMixin):
848
853
  description: Notification status
849
854
  example: "success"
850
855
  """
851
- studio_id = request.json.get("studio_id", None)
856
+ studio_id = self.get_id_parameter("studio_id", None)
857
+ department_id = self.get_id_parameter("department_id", None)
852
858
  playlist = playlists_service.get_playlist(playlist_id)
853
859
  project_id = playlist["project_id"]
854
860
  user_service.check_manager_project_access(project_id)
855
861
  notifications_service.notify_clients_playlist_ready(
856
- playlist, studio_id
862
+ playlist, studio_id, department_id
857
863
  )
858
864
  return {"status": "success"}
@@ -27,6 +27,7 @@ from zou.app.services import (
27
27
  from zou.app.stores import queue_store
28
28
  from zou.utils import movie
29
29
  from zou.app.utils import (
30
+ fields,
30
31
  fs,
31
32
  events,
32
33
  permissions,
@@ -247,15 +248,24 @@ class BaseNewPreviewFilePicture:
247
248
  uploaded_movie_path = movie.save_file(
248
249
  tmp_folder, preview_file_id, uploaded_file
249
250
  )
251
+ save_source_file = config.PREVIEW_SAVE_SOURCE_FILE
250
252
  if normalize and config.ENABLE_JOB_QUEUE and not no_job:
251
253
  queue_store.job_queue.enqueue(
252
254
  preview_files_service.prepare_and_store_movie,
253
- args=(preview_file_id, uploaded_movie_path),
255
+ args=(
256
+ preview_file_id,
257
+ uploaded_movie_path,
258
+ True,
259
+ save_source_file,
260
+ ),
254
261
  job_timeout=int(config.JOB_QUEUE_TIMEOUT),
255
262
  )
256
263
  else:
257
264
  preview_files_service.prepare_and_store_movie(
258
- preview_file_id, uploaded_movie_path, normalize=normalize
265
+ preview_file_id,
266
+ uploaded_movie_path,
267
+ normalize=normalize,
268
+ add_source_to_file_store=save_source_file,
259
269
  )
260
270
  return preview_file_id
261
271
 
@@ -1567,6 +1577,20 @@ class RunningPreviewFiles(Resource, ArgsMixin):
1567
1577
  states equal to processing or broken.
1568
1578
  tags:
1569
1579
  - Previews
1580
+ parameters:
1581
+ - in: query
1582
+ name: cursor_preview_file_id
1583
+ required: false
1584
+ type: string
1585
+ format: uuid
1586
+ description: ID of the last preview file from previous page for cursor-based pagination
1587
+ example: a24a6ea4-ce75-4665-a070-57453082c25
1588
+ - in: query
1589
+ name: limit
1590
+ required: false
1591
+ type: integer
1592
+ description: Maximum number of preview files to return
1593
+ example: 100
1570
1594
  responses:
1571
1595
  200:
1572
1596
  description: All preview files from open productions with processing or broken states
@@ -1588,7 +1612,26 @@ class RunningPreviewFiles(Resource, ArgsMixin):
1588
1612
  example: "processing"
1589
1613
  """
1590
1614
  permissions.check_admin_permissions()
1591
- return preview_files_service.get_running_preview_files()
1615
+ args = self.get_args(
1616
+ [
1617
+ ("cursor_preview_file_id", None, False),
1618
+ ("limit", None, False, int),
1619
+ ],
1620
+ )
1621
+ cursor_preview_file_id = args["cursor_preview_file_id"]
1622
+ limit = args["limit"]
1623
+
1624
+ if cursor_preview_file_id is not None and not fields.is_valid_id(
1625
+ cursor_preview_file_id
1626
+ ):
1627
+ raise WrongParameterException(
1628
+ "The cursor_preview_file_id parameter is not a valid id"
1629
+ )
1630
+
1631
+ return preview_files_service.get_running_preview_files(
1632
+ cursor_preview_file_id=cursor_preview_file_id,
1633
+ limit=limit,
1634
+ )
1592
1635
 
1593
1636
 
1594
1637
  class ExtractFrameFromPreview(Resource, ArgsMixin):
@@ -68,6 +68,7 @@ PREVIEW_FOLDER = os.getenv(
68
68
  "PREVIEW_FOLDER",
69
69
  os.getenv("THUMBNAIL_FOLDER", os.path.join(os.getcwd(), "previews")),
70
70
  )
71
+ PREVIEW_SAVE_SOURCE_FILE = envtobool("PREVIEW_SAVE_SOURCE_FILE", False)
71
72
  TMP_DIR = os.getenv("TMP_DIR", os.path.join(tempfile.gettempdir(), "zou"))
72
73
 
73
74
  EVENT_STREAM_HOST = os.getenv("EVENT_STREAM_HOST", "localhost")
@@ -165,6 +166,7 @@ DEFAULT_LOCALE = os.getenv("DEFAULT_LOCALE", "en_US")
165
166
  USER_LIMIT = int(os.getenv("USER_LIMIT", "100"))
166
167
  MIN_PASSWORD_LENGTH = int(os.getenv("MIN_PASSWORD_LENGTH", 8))
167
168
  PROTECTED_ACCOUNTS = env_with_semicolon_to_list("PROTECTED_ACCOUNTS")
169
+ ENFORCE_2FA = envtobool("ENFORCE_2FA", False)
168
170
 
169
171
  TELEMETRY_URL = os.getenv(
170
172
  "TELEMETRY_URL",
@@ -7,6 +7,7 @@
7
7
  "asset": "<Project>/assets/<AssetType>/<Asset>/<TaskType>",
8
8
  "sequence": "<Project>/sequences/<Sequence>/<TaskType>",
9
9
  "scene": "<Project>/scenes/<Sequence>/<Scene>/<TaskType>",
10
+ "episode": "<Project>/episodes/<Episode>/<TaskType>",
10
11
  "style": "lowercase"
11
12
  },
12
13
  "file_name": {
@@ -14,6 +15,7 @@
14
15
  "asset": "<Project>_<AssetType>_<Asset>_<TaskType>",
15
16
  "sequence": "<Project>_<Sequence>_<TaskType>",
16
17
  "scene": "<Project>_<Sequence>_<Scene>_<TaskType>",
18
+ "episode": "<Project>_<Episode>_<TaskType>",
17
19
  "style": "lowercase"
18
20
  }
19
21
  },
@@ -25,6 +27,7 @@
25
27
  "asset": "<Project>/assets/<AssetType>/<Asset>/<OutputType>",
26
28
  "sequence": "<Project>/sequences/<Sequence>/<OutputType>",
27
29
  "scene": "<Project>/scenes/<Sequence>/<Scene>/<OutputType>",
30
+ "episode": "<Project>/episodes/<Episode>/<OutputType>",
28
31
  "style": "lowercase"
29
32
  },
30
33
  "file_name": {
@@ -32,6 +35,7 @@
32
35
  "asset": "<Project>_<AssetType>_<Asset>_<OutputType>_<OutputFile>",
33
36
  "sequence": "<Project>_<Sequence>_<OuputType>_<OutputFile>",
34
37
  "scene": "<Project>_<Sequence>_<Scene>_<OutputType>_<OutputFile>",
38
+ "episode": "<Project>_<Episode>_<OutputType>_<OutputFile>",
35
39
  "style": "lowercase"
36
40
  }
37
41
  },
@@ -43,6 +47,7 @@
43
47
  "asset": "<Project>/assets/<AssetType>/<Asset>/<TaskType>",
44
48
  "sequence": "<Project>/sequences/<Sequence>/<TaskType>",
45
49
  "scene": "<Project>/scene/<Scene>/<TaskType>",
50
+ "episode": "<Project>/episodes/<Episode>/<TaskType>",
46
51
  "style": "lowercase"
47
52
  },
48
53
  "file_name": {
@@ -50,6 +55,7 @@
50
55
  "asset": "<Project>_<AssetType>_<Asset>_<TaskType>",
51
56
  "sequence": "<Project>_<Sequence>_<TaskType>",
52
57
  "scene": "<Project>_<Scene>_<TaskType>",
58
+ "episode": "<Project>_<Episode>_<TaskType>",
53
59
  "style": "lowercase"
54
60
  }
55
61
  }
@@ -7,6 +7,7 @@
7
7
  "asset": "<Project>/assets/<AssetType>/<Asset>/<TaskType>/<Software>",
8
8
  "sequence": "<Project>/sequences/<Sequence>/<TaskType>/<Software>",
9
9
  "scene": "<Project>/scenes/<Sequence>/<Scene>/<TaskType>/<Software>",
10
+ "episode": "<Project>/episodes/<Episode>/<TaskType>/<Software>",
10
11
  "style": "lowercase"
11
12
  },
12
13
  "file_name": {
@@ -14,6 +15,7 @@
14
15
  "asset": "<Project>_<AssetType>_<Asset>_<TaskType>_<Name>_v<Version>",
15
16
  "sequence": "<Project>_<Sequence>_<TaskType>_<Name>_v<Version>",
16
17
  "scene": "<Project>_<Scene>_<TaskType>_<Name>_v<Version>",
18
+ "episode": "<Project>_<Episode>_<TaskType>_<Name>_v<Version>",
17
19
  "style": "lowercase"
18
20
  }
19
21
  },
@@ -25,6 +27,7 @@
25
27
  "asset": "<Project>/assets/<AssetType>/<Asset>/<TaskType>/<OutputType>",
26
28
  "sequence": "<Project>/sequences/<Sequence>/<TaskType>/<OutputType>",
27
29
  "scene": "<Project>/scenes/<Sequence>/<Scene>/<TaskType>/<OutputType>",
30
+ "episode": "<Project>/episodes/<Episode>/<TaskType>/<OutputType>",
28
31
  "instance_asset": "<Project>/assets/<TemporalEntityType>/<TemporalEntity>/<TaskType>/<OutputType>/<AssetType>/<Asset>/instance_<Instance.number>/<Representation>",
29
32
  "instance": "<Project>/<TemporalEntityType>/<Sequence>/<TemporalEntity>/<TaskType>/<OutputType>/<AssetType>/<Asset>/instance_<Instance.number>/<Representation>",
30
33
  "style": "lowercase"
@@ -34,6 +37,7 @@
34
37
  "asset": "<Project>_<AssetType>_<Asset>_<TaskType>_<OutputType>_<Name>_v<Version>",
35
38
  "sequence": "<Project>_<Sequence>_<TaskType>_<OutputType>_<Name>_v<Version>",
36
39
  "scene": "<Project>_<Scene>_<TaskType>_<OutputType>_<Name>_v<Version>",
40
+ "episode": "<Project>_<Episode>_<TaskType>_<OutputType>_<Name>_v<Version>",
37
41
  "instance_asset": "<Project>_<TemporalEntityType>_<TemporalEntity>_<TaskType>_<OutputType>_<Name>_<Instance.name>_v<Version>",
38
42
  "instance": "<Project>_<Sequence>_<TemporalEntity>_<TaskType>_<OutputType>_<Name>_<Instance.name>_v<Version>",
39
43
  "style": "lowercase"
@@ -47,6 +51,7 @@
47
51
  "asset": "<Project>/assets/<AssetType>/<Asset>/<TaskType>",
48
52
  "sequence": "<Project>/sequences/<Sequence>/<TaskType>",
49
53
  "scene": "<Project>/scenes/<Sequence>/<Scene>/<TaskType>",
54
+ "episode": "<Project>/episodes/<Episode>/<TaskType>",
50
55
  "style": "lowercase"
51
56
  },
52
57
  "file_name": {
@@ -54,6 +59,7 @@
54
59
  "asset": "<Project>_<AssetType>_<Asset>_<TaskType>",
55
60
  "sequence": "<Project>_<Sequence>_<TaskType>",
56
61
  "scene": "<Project>_<Scene>_<TaskType>",
62
+ "episode": "<Project>_<Episode>_<TaskType>",
57
63
  "style": "lowercase"
58
64
  }
59
65
  }
@@ -168,3 +168,12 @@ class ArgsMixin(object):
168
168
  if not fields.is_valid_id(uuid):
169
169
  raise WrongParameterException("Wrong UUID format.")
170
170
  return True
171
+
172
+ def get_id_parameter(self, field_name, default=None):
173
+ """
174
+ Returns ID parameter value matching `field_name`.
175
+ """
176
+ entity_id = self.get_text_parameter(field_name + "_id", default)
177
+ if entity_id is not None and entity_id != "":
178
+ self.check_id_parameter(entity_id)
179
+ return entity_id
@@ -0,0 +1,41 @@
1
+ from sqlalchemy_utils import EmailType, URLType
2
+
3
+ from zou.app import db
4
+ from zou.app.models.serializer import SerializerMixin
5
+ from zou.app.models.base import BaseMixin
6
+
7
+
8
+ class Plugin(db.Model, BaseMixin, SerializerMixin):
9
+ """
10
+ A plugin is a module used to extend the functionality of Zou.
11
+ You can extend the REST API routes and the database models.
12
+ """
13
+
14
+ plugin_id = db.Column(
15
+ db.String(80), unique=True, nullable=False, index=True
16
+ )
17
+ name = db.Column(db.String(80), nullable=False, index=True)
18
+ description = db.Column(db.Text())
19
+ version = db.Column(db.String(50), nullable=False)
20
+ maintainer_name = db.Column(db.String(200), nullable=False)
21
+ maintainer_email = db.Column(EmailType)
22
+ website = db.Column(URLType)
23
+ license = db.Column(db.String(80), nullable=False)
24
+ revision = db.Column(db.String(12), nullable=True)
25
+ frontend_project_enabled = db.Column(db.Boolean(), default=False)
26
+ frontend_studio_enabled = db.Column(db.Boolean(), default=False)
27
+ icon = db.Column(db.String(255), nullable=True) # lucide-vue icon name
28
+
29
+ def present(self):
30
+ return {
31
+ "id": self.id,
32
+ "plugin_id": self.plugin_id,
33
+ "name": self.name,
34
+ "description": self.description,
35
+ "version": self.version,
36
+ "maintainer_name": self.maintainer_name,
37
+ "maintainer_email": self.maintainer_email,
38
+ "frontend_project_enabled": self.frontend_project_enabled,
39
+ "frontend_studio_enabled": self.frontend_studio_enabled,
40
+ "icon": self.icon,
41
+ }
@@ -1,4 +1,5 @@
1
1
  from sqlalchemy_utils import UUIDType, ChoiceType
2
+ from sqlalchemy.dialects.postgresql import JSONB
2
3
 
3
4
  from zou.app import db
4
5
  from zou.app.models.serializer import SerializerMixin
@@ -45,6 +46,7 @@ class PreviewFile(db.Model, BaseMixin, SerializerMixin):
45
46
  width = db.Column(db.Integer(), default=0)
46
47
  height = db.Column(db.Integer(), default=0)
47
48
  duration = db.Column(db.Float, default=0)
49
+ data = db.Column(JSONB)
48
50
 
49
51
  task_id = db.Column(
50
52
  UUIDType(binary=False), db.ForeignKey("task.id"), index=True
@@ -188,7 +188,8 @@ def _manage_status_change(task_status, task, comment):
188
188
  new_data["retake_count"] = retake_count + 1
189
189
 
190
190
  if task_status["is_feedback_request"]:
191
- new_data["end_date"] = date_helpers.get_utc_now_datetime()
191
+ if task.get("end_date") is None:
192
+ new_data["end_date"] = date_helpers.get_utc_now_datetime()
192
193
 
193
194
  if task_status["is_wip"] and task["real_start_date"] is None:
194
195
  new_data["real_start_date"] = datetime.datetime.now(