zou 0.20.22__tar.gz → 0.20.23__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 (435) hide show
  1. {zou-0.20.22/zou.egg-info → zou-0.20.23}/PKG-INFO +2 -2
  2. {zou-0.20.22 → zou-0.20.23}/setup.cfg +1 -1
  3. zou-0.20.23/zou/__init__.py +1 -0
  4. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/comments/resources.py +7 -1
  5. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/previews/resources.py +2 -5
  6. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/shots/__init__.py +5 -0
  7. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/shots/resources.py +74 -0
  8. {zou-0.20.22 → zou-0.20.23}/zou/app/models/project.py +1 -0
  9. {zou-0.20.22 → zou-0.20.23}/zou/app/models/task.py +2 -0
  10. {zou-0.20.22 → zou-0.20.23}/zou/app/services/assets_service.py +3 -1
  11. {zou-0.20.22 → zou-0.20.23}/zou/app/services/shots_service.py +159 -70
  12. {zou-0.20.22 → zou-0.20.23}/zou/app/services/stats_service.py +47 -9
  13. {zou-0.20.22 → zou-0.20.23}/zou/app/services/user_service.py +2 -3
  14. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/commands.py +1 -1
  15. zou-0.20.23/zou/migrations/versions/addbad59c706_allow_to_manage_drawings_instead_of_.py +35 -0
  16. {zou-0.20.22 → zou-0.20.23/zou.egg-info}/PKG-INFO +2 -2
  17. {zou-0.20.22 → zou-0.20.23}/zou.egg-info/SOURCES.txt +1 -0
  18. {zou-0.20.22 → zou-0.20.23}/zou.egg-info/requires.txt +1 -1
  19. zou-0.20.22/zou/__init__.py +0 -1
  20. {zou-0.20.22 → zou-0.20.23}/LICENSE +0 -0
  21. {zou-0.20.22 → zou-0.20.23}/README.rst +0 -0
  22. {zou-0.20.22 → zou-0.20.23}/pyproject.toml +0 -0
  23. {zou-0.20.22 → zou-0.20.23}/setup.py +0 -0
  24. {zou-0.20.22 → zou-0.20.23}/zou/app/__init__.py +0 -0
  25. {zou-0.20.22 → zou-0.20.23}/zou/app/api.py +0 -0
  26. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/__init__.py +0 -0
  27. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/assets/__init__.py +0 -0
  28. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/assets/resources.py +0 -0
  29. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/auth/__init__.py +0 -0
  30. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/auth/resources.py +0 -0
  31. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/breakdown/__init__.py +0 -0
  32. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/breakdown/resources.py +0 -0
  33. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/chats/__init__.py +0 -0
  34. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/chats/resources.py +0 -0
  35. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/comments/__init__.py +0 -0
  36. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/concepts/__init__.py +0 -0
  37. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/concepts/resources.py +0 -0
  38. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/__init__.py +0 -0
  39. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/asset_instance.py +0 -0
  40. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/attachment_file.py +0 -0
  41. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/base.py +0 -0
  42. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/chat.py +0 -0
  43. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/chat_message.py +0 -0
  44. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/comments.py +0 -0
  45. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/custom_action.py +0 -0
  46. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/day_off.py +0 -0
  47. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/department.py +0 -0
  48. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/entity.py +0 -0
  49. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/entity_link.py +0 -0
  50. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/entity_type.py +0 -0
  51. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/event.py +0 -0
  52. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/file_status.py +0 -0
  53. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/metadata_descriptor.py +0 -0
  54. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/milestone.py +0 -0
  55. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/news.py +0 -0
  56. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/notification.py +0 -0
  57. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/organisation.py +0 -0
  58. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/output_file.py +0 -0
  59. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/output_type.py +0 -0
  60. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/person.py +0 -0
  61. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/playlist.py +0 -0
  62. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/preview_background_file.py +0 -0
  63. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/preview_file.py +0 -0
  64. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/project.py +0 -0
  65. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/project_status.py +0 -0
  66. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/schedule_item.py +0 -0
  67. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/search_filter.py +0 -0
  68. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/search_filter_group.py +0 -0
  69. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/software.py +0 -0
  70. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/status_automation.py +0 -0
  71. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/studio.py +0 -0
  72. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/subscription.py +0 -0
  73. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/task.py +0 -0
  74. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/task_status.py +0 -0
  75. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/task_type.py +0 -0
  76. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/time_spent.py +0 -0
  77. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/crud/working_file.py +0 -0
  78. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/edits/__init__.py +0 -0
  79. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/edits/resources.py +0 -0
  80. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/entities/__init__.py +0 -0
  81. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/entities/resources.py +0 -0
  82. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/events/__init__.py +0 -0
  83. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/events/resources.py +0 -0
  84. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/__init__.py +0 -0
  85. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/__init__.py +0 -0
  86. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/assets.py +0 -0
  87. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/base.py +0 -0
  88. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/casting.py +0 -0
  89. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/edits.py +0 -0
  90. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/persons.py +0 -0
  91. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/playlists.py +0 -0
  92. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/projects.py +0 -0
  93. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/shots.py +0 -0
  94. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/task_types.py +0 -0
  95. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/tasks.py +0 -0
  96. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/export/csv/time_spents.py +0 -0
  97. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/files/__init__.py +0 -0
  98. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/files/resources.py +0 -0
  99. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/index/__init__.py +0 -0
  100. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/index/resources.py +0 -0
  101. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/news/__init__.py +0 -0
  102. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/news/resources.py +0 -0
  103. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/persons/__init__.py +0 -0
  104. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/persons/resources.py +0 -0
  105. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/playlists/__init__.py +0 -0
  106. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/playlists/resources.py +0 -0
  107. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/previews/__init__.py +0 -0
  108. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/projects/__init__.py +0 -0
  109. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/projects/resources.py +0 -0
  110. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/search/__init__.py +0 -0
  111. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/search/resources.py +0 -0
  112. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/__init__.py +0 -0
  113. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/csv/__init__.py +0 -0
  114. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/csv/assets.py +0 -0
  115. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/csv/base.py +0 -0
  116. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/csv/casting.py +0 -0
  117. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/csv/edits.py +0 -0
  118. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/csv/persons.py +0 -0
  119. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/csv/shots.py +0 -0
  120. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/csv/task_type_estimations.py +0 -0
  121. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/kitsu.py +0 -0
  122. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/otio.py +0 -0
  123. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/__init__.py +0 -0
  124. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/assets.py +0 -0
  125. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/base.py +0 -0
  126. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/episode.py +0 -0
  127. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/exception.py +0 -0
  128. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/import_errors.py +0 -0
  129. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/notes.py +0 -0
  130. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/person.py +0 -0
  131. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/project.py +0 -0
  132. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/scene.py +0 -0
  133. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/sequence.py +0 -0
  134. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/shot.py +0 -0
  135. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/status.py +0 -0
  136. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/steps.py +0 -0
  137. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/tasks.py +0 -0
  138. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/team.py +0 -0
  139. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/source/shotgun/versions.py +0 -0
  140. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/tasks/__init__.py +0 -0
  141. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/tasks/resources.py +0 -0
  142. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/user/__init__.py +0 -0
  143. {zou-0.20.22 → zou-0.20.23}/zou/app/blueprints/user/resources.py +0 -0
  144. {zou-0.20.22 → zou-0.20.23}/zou/app/config.py +0 -0
  145. {zou-0.20.22 → zou-0.20.23}/zou/app/file_trees/default.json +0 -0
  146. {zou-0.20.22 → zou-0.20.23}/zou/app/file_trees/simple.json +0 -0
  147. {zou-0.20.22 → zou-0.20.23}/zou/app/indexer/__init__.py +0 -0
  148. {zou-0.20.22 → zou-0.20.23}/zou/app/indexer/indexing.py +0 -0
  149. {zou-0.20.22 → zou-0.20.23}/zou/app/mixin.py +0 -0
  150. {zou-0.20.22 → zou-0.20.23}/zou/app/models/__init__.py +0 -0
  151. {zou-0.20.22 → zou-0.20.23}/zou/app/models/asset_instance.py +0 -0
  152. {zou-0.20.22 → zou-0.20.23}/zou/app/models/attachment_file.py +0 -0
  153. {zou-0.20.22 → zou-0.20.23}/zou/app/models/base.py +0 -0
  154. {zou-0.20.22 → zou-0.20.23}/zou/app/models/build_job.py +0 -0
  155. {zou-0.20.22 → zou-0.20.23}/zou/app/models/chat.py +0 -0
  156. {zou-0.20.22 → zou-0.20.23}/zou/app/models/chat_message.py +0 -0
  157. {zou-0.20.22 → zou-0.20.23}/zou/app/models/comment.py +0 -0
  158. {zou-0.20.22 → zou-0.20.23}/zou/app/models/custom_action.py +0 -0
  159. {zou-0.20.22 → zou-0.20.23}/zou/app/models/data_import_error.py +0 -0
  160. {zou-0.20.22 → zou-0.20.23}/zou/app/models/day_off.py +0 -0
  161. {zou-0.20.22 → zou-0.20.23}/zou/app/models/department.py +0 -0
  162. {zou-0.20.22 → zou-0.20.23}/zou/app/models/desktop_login_log.py +0 -0
  163. {zou-0.20.22 → zou-0.20.23}/zou/app/models/entity.py +0 -0
  164. {zou-0.20.22 → zou-0.20.23}/zou/app/models/entity_type.py +0 -0
  165. {zou-0.20.22 → zou-0.20.23}/zou/app/models/event.py +0 -0
  166. {zou-0.20.22 → zou-0.20.23}/zou/app/models/file_status.py +0 -0
  167. {zou-0.20.22 → zou-0.20.23}/zou/app/models/login_log.py +0 -0
  168. {zou-0.20.22 → zou-0.20.23}/zou/app/models/metadata_descriptor.py +0 -0
  169. {zou-0.20.22 → zou-0.20.23}/zou/app/models/milestone.py +0 -0
  170. {zou-0.20.22 → zou-0.20.23}/zou/app/models/news.py +0 -0
  171. {zou-0.20.22 → zou-0.20.23}/zou/app/models/notification.py +0 -0
  172. {zou-0.20.22 → zou-0.20.23}/zou/app/models/organisation.py +0 -0
  173. {zou-0.20.22 → zou-0.20.23}/zou/app/models/output_file.py +0 -0
  174. {zou-0.20.22 → zou-0.20.23}/zou/app/models/output_type.py +0 -0
  175. {zou-0.20.22 → zou-0.20.23}/zou/app/models/person.py +0 -0
  176. {zou-0.20.22 → zou-0.20.23}/zou/app/models/playlist.py +0 -0
  177. {zou-0.20.22 → zou-0.20.23}/zou/app/models/preview_background_file.py +0 -0
  178. {zou-0.20.22 → zou-0.20.23}/zou/app/models/preview_file.py +0 -0
  179. {zou-0.20.22 → zou-0.20.23}/zou/app/models/project_status.py +0 -0
  180. {zou-0.20.22 → zou-0.20.23}/zou/app/models/schedule_item.py +0 -0
  181. {zou-0.20.22 → zou-0.20.23}/zou/app/models/search_filter.py +0 -0
  182. {zou-0.20.22 → zou-0.20.23}/zou/app/models/search_filter_group.py +0 -0
  183. {zou-0.20.22 → zou-0.20.23}/zou/app/models/serializer.py +0 -0
  184. {zou-0.20.22 → zou-0.20.23}/zou/app/models/software.py +0 -0
  185. {zou-0.20.22 → zou-0.20.23}/zou/app/models/status_automation.py +0 -0
  186. {zou-0.20.22 → zou-0.20.23}/zou/app/models/studio.py +0 -0
  187. {zou-0.20.22 → zou-0.20.23}/zou/app/models/subscription.py +0 -0
  188. {zou-0.20.22 → zou-0.20.23}/zou/app/models/task_status.py +0 -0
  189. {zou-0.20.22 → zou-0.20.23}/zou/app/models/task_type.py +0 -0
  190. {zou-0.20.22 → zou-0.20.23}/zou/app/models/time_spent.py +0 -0
  191. {zou-0.20.22 → zou-0.20.23}/zou/app/models/working_file.py +0 -0
  192. {zou-0.20.22 → zou-0.20.23}/zou/app/services/__init__.py +0 -0
  193. {zou-0.20.22 → zou-0.20.23}/zou/app/services/auth_service.py +0 -0
  194. {zou-0.20.22 → zou-0.20.23}/zou/app/services/backup_service.py +0 -0
  195. {zou-0.20.22 → zou-0.20.23}/zou/app/services/base_service.py +0 -0
  196. {zou-0.20.22 → zou-0.20.23}/zou/app/services/breakdown_service.py +0 -0
  197. {zou-0.20.22 → zou-0.20.23}/zou/app/services/chats_service.py +0 -0
  198. {zou-0.20.22 → zou-0.20.23}/zou/app/services/comments_service.py +0 -0
  199. {zou-0.20.22 → zou-0.20.23}/zou/app/services/concepts_service.py +0 -0
  200. {zou-0.20.22 → zou-0.20.23}/zou/app/services/custom_actions_service.py +0 -0
  201. {zou-0.20.22 → zou-0.20.23}/zou/app/services/deletion_service.py +0 -0
  202. {zou-0.20.22 → zou-0.20.23}/zou/app/services/edits_service.py +0 -0
  203. {zou-0.20.22 → zou-0.20.23}/zou/app/services/emails_service.py +0 -0
  204. {zou-0.20.22 → zou-0.20.23}/zou/app/services/entities_service.py +0 -0
  205. {zou-0.20.22 → zou-0.20.23}/zou/app/services/events_service.py +0 -0
  206. {zou-0.20.22 → zou-0.20.23}/zou/app/services/exception.py +0 -0
  207. {zou-0.20.22 → zou-0.20.23}/zou/app/services/file_tree_service.py +0 -0
  208. {zou-0.20.22 → zou-0.20.23}/zou/app/services/files_service.py +0 -0
  209. {zou-0.20.22 → zou-0.20.23}/zou/app/services/index_service.py +0 -0
  210. {zou-0.20.22 → zou-0.20.23}/zou/app/services/names_service.py +0 -0
  211. {zou-0.20.22 → zou-0.20.23}/zou/app/services/news_service.py +0 -0
  212. {zou-0.20.22 → zou-0.20.23}/zou/app/services/notifications_service.py +0 -0
  213. {zou-0.20.22 → zou-0.20.23}/zou/app/services/persons_service.py +0 -0
  214. {zou-0.20.22 → zou-0.20.23}/zou/app/services/playlists_service.py +0 -0
  215. {zou-0.20.22 → zou-0.20.23}/zou/app/services/preview_files_service.py +0 -0
  216. {zou-0.20.22 → zou-0.20.23}/zou/app/services/projects_service.py +0 -0
  217. {zou-0.20.22 → zou-0.20.23}/zou/app/services/scenes_service.py +0 -0
  218. {zou-0.20.22 → zou-0.20.23}/zou/app/services/schedule_service.py +0 -0
  219. {zou-0.20.22 → zou-0.20.23}/zou/app/services/status_automations_service.py +0 -0
  220. {zou-0.20.22 → zou-0.20.23}/zou/app/services/sync_service.py +0 -0
  221. {zou-0.20.22 → zou-0.20.23}/zou/app/services/tasks_service.py +0 -0
  222. {zou-0.20.22 → zou-0.20.23}/zou/app/services/telemetry_services.py +0 -0
  223. {zou-0.20.22 → zou-0.20.23}/zou/app/services/time_spents_service.py +0 -0
  224. {zou-0.20.22 → zou-0.20.23}/zou/app/stores/__init__.py +0 -0
  225. {zou-0.20.22 → zou-0.20.23}/zou/app/stores/auth_tokens_store.py +0 -0
  226. {zou-0.20.22 → zou-0.20.23}/zou/app/stores/file_store.py +0 -0
  227. {zou-0.20.22 → zou-0.20.23}/zou/app/stores/publisher_store.py +0 -0
  228. {zou-0.20.22 → zou-0.20.23}/zou/app/stores/queue_store.py +0 -0
  229. {zou-0.20.22 → zou-0.20.23}/zou/app/swagger.py +0 -0
  230. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/__init__.py +0 -0
  231. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/api.py +0 -0
  232. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/auth.py +0 -0
  233. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/cache.py +0 -0
  234. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/chats.py +0 -0
  235. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/colors.py +0 -0
  236. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/csv_utils.py +0 -0
  237. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/date_helpers.py +0 -0
  238. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/dbhelpers.py +0 -0
  239. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/emails.py +0 -0
  240. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/env.py +0 -0
  241. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/events.py +0 -0
  242. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/fido.py +0 -0
  243. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/fields.py +0 -0
  244. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/flask.py +0 -0
  245. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/fs.py +0 -0
  246. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/git.py +0 -0
  247. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/logs.py +0 -0
  248. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/monitoring.py +0 -0
  249. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/permissions.py +0 -0
  250. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/query.py +0 -0
  251. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/redis.py +0 -0
  252. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/remote_job.py +0 -0
  253. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/saml.py +0 -0
  254. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/shell.py +0 -0
  255. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/string.py +0 -0
  256. {zou-0.20.22 → zou-0.20.23}/zou/app/utils/thumbnail.py +0 -0
  257. {zou-0.20.22 → zou-0.20.23}/zou/cli.py +0 -0
  258. {zou-0.20.22 → zou-0.20.23}/zou/debug.py +0 -0
  259. {zou-0.20.22 → zou-0.20.23}/zou/event_stream.py +0 -0
  260. {zou-0.20.22 → zou-0.20.23}/zou/job_settings.py +0 -0
  261. {zou-0.20.22 → zou-0.20.23}/zou/migrations/README +0 -0
  262. {zou-0.20.22 → zou-0.20.23}/zou/migrations/__init__.py +0 -0
  263. {zou-0.20.22 → zou-0.20.23}/zou/migrations/alembic.ini +0 -0
  264. {zou-0.20.22 → zou-0.20.23}/zou/migrations/env.py +0 -0
  265. {zou-0.20.22 → zou-0.20.23}/zou/migrations/script.py.mako +0 -0
  266. {zou-0.20.22 → zou-0.20.23}/zou/migrations/utils/__init__.py +0 -0
  267. {zou-0.20.22 → zou-0.20.23}/zou/migrations/utils/base.py +0 -0
  268. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/003be8a91001_add_start_and_end_dates_to_projects.py +0 -0
  269. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/0596674df51d_add_department_mentions_to_comments.py +0 -0
  270. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/05ac7e8caa21_remove_unique_constraint_for_taskstatus_.py +0 -0
  271. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/05b7dc79a416_add_archived_fields_to_main_tables.py +0 -0
  272. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/06552e22f9e7_add_comment_updated_by.py +0 -0
  273. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/0cf5e0e035fa_drop_column_tasktype_for_shots.py +0 -0
  274. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/0ec3762a745d_add_attachment_table.py +0 -0
  275. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/0ef6416a507b_.py +0 -0
  276. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/10cf267d95c9_fix_schedule_item.py +0 -0
  277. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/16328eae4b5f_add_new_constraint_for_timespent.py +0 -0
  278. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/16df47d76c64_add_some_indexes.py +0 -0
  279. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/17ef8f7be758_disallow_null_choicetype.py +0 -0
  280. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/1bb55759146f_add_table_studio.py +0 -0
  281. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/1cb44194db49_add_file_size_field_to_preview_file.py +0 -0
  282. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/1e150c2cea4d_add_nb_entities_out.py +0 -0
  283. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/1e2d77a2f0c4_add_hd_by_default_column.py +0 -0
  284. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/1fab8c420678_add_attachments_to_message_chats.py +0 -0
  285. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/20a8ad264659_tasktypeassettypelink_.py +0 -0
  286. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/20dfeb36142b_add_projecttaskstatuslink_roles_for_.py +0 -0
  287. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/23122f290ca2_add_entity_chat_models.py +0 -0
  288. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/269d41bfb73f_add_entity_entity_links.py +0 -0
  289. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/29df910f04a4_create_unique_constraint_project_id_.py +0 -0
  290. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/29fe01a6c9eb_add_status_automation_field.py +0 -0
  291. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/2adc020885fa_.py +0 -0
  292. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/2baede80b111_add_entity_status_field.py +0 -0
  293. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/306266361f4f_.py +0 -0
  294. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/328fd44c6347_add_entity_created_by.py +0 -0
  295. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/32f134ff1201_add_is_shared_flag_to_filters.py +0 -0
  296. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/346250b5304c_add_position_to_preview_files.py +0 -0
  297. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/3476e147e632_add_acks_to_comments.py +0 -0
  298. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/389cfb9de776_.py +0 -0
  299. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/38baa9a23b3d_.py +0 -0
  300. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/398150912a3f_validation_status_preview.py +0 -0
  301. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/3b0d1321079e_.py +0 -0
  302. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/3d5c93bafb9d_.py +0 -0
  303. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/3e0538ddf80f_.py +0 -0
  304. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/3fee3bd10f9d_.py +0 -0
  305. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/4095103c7d01_add_is_clients_isolated_flag_to_projects.py +0 -0
  306. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/40dea9555940_.py +0 -0
  307. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/42ec83db6a01_change_person_preferred_two_factor_.py +0 -0
  308. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/43d0cf0ed5e7_.py +0 -0
  309. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/443d1e78a932_.py +0 -0
  310. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/45c2de366e66_.py +0 -0
  311. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/45dafbb3f4e1_for_person_contract_type_disallow_null.py +0 -0
  312. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/4715c2586036_add_last_preview_file_fields.py +0 -0
  313. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/4e3738cdc34c_.py +0 -0
  314. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/4f2398ebcd49_.py +0 -0
  315. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/523ee9647bee_.py +0 -0
  316. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/539a3a00c417_for_departmentlink_index_person_id_.py +0 -0
  317. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/54ee0d1d60ba_add_build_job_model.py +0 -0
  318. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/556526e47daa_.py +0 -0
  319. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/57222395f2be_add_statusautomation_import_last_revision.py +0 -0
  320. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/5798d2c9020b_change_person_role_to_choicetype.py +0 -0
  321. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/590aa1ffe731_add_notifications_enabled_flag.py +0 -0
  322. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/59a7445a966c_add_entity_is_shared.py +0 -0
  323. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/5a291251823c_add_max_retake_parameter.py +0 -0
  324. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/5ab9d7a75887_.py +0 -0
  325. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/5b0fcbb94f24_.py +0 -0
  326. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/5b7fa3e51701_add_is_client_allowed_flag_to_task_.py +0 -0
  327. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/5b980f0dc365_add_comment_links.py +0 -0
  328. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/5b9fd9ddfe43_add_homepage_and_contract_fields.py +0 -0
  329. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/5c0498e264bc_add_slack_fields.py +0 -0
  330. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/5e2ce62632a6_add_workflow_to_project.py +0 -0
  331. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/680c64565f9d_for_searchfiltergroup_is_shared.py +0 -0
  332. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/693cc511d28d_add_taskstatus_priority.py +0 -0
  333. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/6aa446ee4072_add_is_for_all_flage_to_playlists.py +0 -0
  334. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/6bd3b102d61b_.py +0 -0
  335. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/6c597e842afa_add_task_type_field_to_playlists.py +0 -0
  336. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/6d1b2c60f58b_add_milestone_model.py +0 -0
  337. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/6d7fa5a8e9a5_add_timesheets_locked_field_to_org.py +0 -0
  338. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/6eeaff945706_add_data_field_on_entity_links.py +0 -0
  339. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/6f6049877105_.py +0 -0
  340. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/7417c8eb70d8_add_for_entity_field_to_playlists.py +0 -0
  341. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/772a5e43f05b_.py +0 -0
  342. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/7748d3d22925_add_columns_to_searchfilter_table_to_.py +0 -0
  343. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/77d6820f494f_add_reply_to_notif.py +0 -0
  344. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/7b1f765677d8_.py +0 -0
  345. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/7bc746997e8d_add_slack_token_field_to_organisation.py +0 -0
  346. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/7dc79d4ed7cd_.py +0 -0
  347. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/818f7bda2528_.py +0 -0
  348. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/82e7f7a95e84_add_project_id_to_events.py +0 -0
  349. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/82ee682204ab_add_is_generated_from_ldap_column_to_.py +0 -0
  350. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/8588f254d6b8_add_archived_fields.py +0 -0
  351. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/8739ae9fa28b_add_for_client_field.py +0 -0
  352. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/87efceb6745b_add_ready_for_to_entity.py +0 -0
  353. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/892b264937ec_.py +0 -0
  354. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/8a1b4a1b7f4a_add_totp_columns_for_person.py +0 -0
  355. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/8e4f39e321f4_add_day_off_table.py +0 -0
  356. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/8e67c183bed7_add_preference_fields.py +0 -0
  357. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/8fbd40afbe5f_allow_to_set_float_values_for_.py +0 -0
  358. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/9010a64e5a2d_add_indices.py +0 -0
  359. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/9060dd4f6116_notification_uc.py +0 -0
  360. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/925771029620_.py +0 -0
  361. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/92b40d79ad3f_allow_message_attachments.py +0 -0
  362. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/92bdfe07e5f5_discord_integration.py +0 -0
  363. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/956659992419_add_columns_for_person_to_store_fido_.py +0 -0
  364. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/96c79d31e648_add_mail_otp_columns_for_person.py +0 -0
  365. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/96f58a4a2a58_person_partial_index_for_email_only_.py +0 -0
  366. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/971dbf5a0faf_add_short_name_for_asset_type_entity_.py +0 -0
  367. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/98c90621cf58_add_for_client_flag_to_playlist.py +0 -0
  368. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/99825b9cc778_.py +0 -0
  369. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/9a09467f9b2c_.py +0 -0
  370. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/9b85c14fa8a7_add_day_off_new_columns.py +0 -0
  371. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/9bd17364fc18_.py +0 -0
  372. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/9d3bb33c6fc6_add_department_keys_to_filter_models.py +0 -0
  373. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/9e5b3a9b0cee_add_new_column_metadatadescriptor_data_type_.py +0 -0
  374. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/9f8445f9b42c_add_man_days_fields.py +0 -0
  375. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/a23682ccc1f1_.py +0 -0
  376. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/a252a094e977_add_descriptions_for_entities_tasks_and_.py +0 -0
  377. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/a519c710877c_.py +0 -0
  378. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/a65bdadbae2f_.py +0 -0
  379. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/a66508788c53_add_nb_assets_ready.py +0 -0
  380. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/a6c25eed3ea1_add_login_failed_attemps_and_last_login_.py +0 -0
  381. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/a7c43f3fbc76_add_duration_column_to_the_preview_file.py +0 -0
  382. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/aa0a60033106_feedback_request.py +0 -0
  383. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/addbbefa7028_add_departments_link_to_metadata_.py +0 -0
  384. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/ae0127f2fc56_add_previewfile_width_and_previewfile_.py +0 -0
  385. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/af1790868e2c_.py +0 -0
  386. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/b45cb782bb9c_.py +0 -0
  387. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/b4dd0add5f79_.py +0 -0
  388. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/b8c0a0f9d054_drop_task_status_is_reviewable.py +0 -0
  389. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/b8ed0fb263f8_add_person_jti_and_jti_expiration_date.py +0 -0
  390. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/b97a71306fc8_add_is_casting_standby_column_to_entity.py +0 -0
  391. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/be56dc0fb760_for_is_shared_disallow_nullable.py +0 -0
  392. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/bf1347acdee2_.py +0 -0
  393. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/c49e41f1298b_add_previewbackground.py +0 -0
  394. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/c68c2a62cfac_add_mimetype_column_to_attachment.py +0 -0
  395. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/c726b98be194_.py +0 -0
  396. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/c81f3e83bdb5_.py +0 -0
  397. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/ca28796a2a62_add_is_done_field_to_the_task_model.py +0 -0
  398. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/cf3d365de164_add_entity_version_model.py +0 -0
  399. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/cf6cec6d6bf5_add_status_field_to_preview_file.py +0 -0
  400. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/d80267806131_task_status_new_column_is_default.py +0 -0
  401. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/d8dcd5196d57_add_casting_label.py +0 -0
  402. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/de8a3de227ef_.py +0 -0
  403. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/deeacd38d373_for_projecttaskstatuslink_set_default_.py +0 -0
  404. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/df1834485f57_.py +0 -0
  405. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/df9f8a147e80_change_file_size_to_big_integer.py +0 -0
  406. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/e1ef93f40d3d_.py +0 -0
  407. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/e29638428dfd_add_schedule_item_table.py +0 -0
  408. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/e3f6db74cc1e_.py +0 -0
  409. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/e839d6603c09_add_person_id_to_shot_history.py +0 -0
  410. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/ee2373fbe3a4_.py +0 -0
  411. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/f0567e8d0c62_.py +0 -0
  412. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/f0c6cbb61869_add_production_style_field.py +0 -0
  413. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/f344b867a911_for_description_of_entity_task_working_.py +0 -0
  414. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/f4ff5a73d283_add_person_ldap_uid.py +0 -0
  415. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/f5b113876a49_add_preferred_two_factor_authentication_.py +0 -0
  416. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/f5bdca075cdc_add_preview_download_flag_to_projects.py +0 -0
  417. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/f874ad5e898a_add_link_entity_type_task_type.py +0 -0
  418. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/f995b28fb749_.py +0 -0
  419. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/fb6b6f188497_.py +0 -0
  420. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/fb87feaaa094_add_missing_unique_constraints.py +0 -0
  421. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/fba149993140_add_missing_index.py +0 -0
  422. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/fc322f908695_.py +0 -0
  423. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/fee7c696166e_.py +0 -0
  424. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/feffd3c5b806_introduce_concepts.py +0 -0
  425. {zou-0.20.22 → zou-0.20.23}/zou/migrations/versions/ffeed4956ab1_add_more_details_to_projects.py +0 -0
  426. {zou-0.20.22 → zou-0.20.23}/zou/remote/__init__.py +0 -0
  427. {zou-0.20.22 → zou-0.20.23}/zou/remote/config_payload.py +0 -0
  428. {zou-0.20.22 → zou-0.20.23}/zou/remote/normalize_movie.py +0 -0
  429. {zou-0.20.22 → zou-0.20.23}/zou/remote/playlist.py +0 -0
  430. {zou-0.20.22 → zou-0.20.23}/zou/utils/__init__.py +0 -0
  431. {zou-0.20.22 → zou-0.20.23}/zou/utils/movie.py +0 -0
  432. {zou-0.20.22 → zou-0.20.23}/zou.egg-info/dependency_links.txt +0 -0
  433. {zou-0.20.22 → zou-0.20.23}/zou.egg-info/entry_points.txt +0 -0
  434. {zou-0.20.22 → zou-0.20.23}/zou.egg-info/not-zip-safe +0 -0
  435. {zou-0.20.22 → zou-0.20.23}/zou.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: zou
3
- Version: 0.20.22
3
+ Version: 0.20.23
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
@@ -46,7 +46,7 @@ Requires-Dist: gevent==24.11.1
46
46
  Requires-Dist: gunicorn==23.0.0
47
47
  Requires-Dist: isoweek==1.3.3
48
48
  Requires-Dist: itsdangerous==2.2.0
49
- Requires-Dist: Jinja2==3.1.5
49
+ Requires-Dist: Jinja2==3.1.6
50
50
  Requires-Dist: ldap3==2.9.1
51
51
  Requires-Dist: matterhook==0.2
52
52
  Requires-Dist: meilisearch==0.34.0
@@ -52,7 +52,7 @@ install_requires =
52
52
  gunicorn==23.0.0
53
53
  isoweek==1.3.3
54
54
  itsdangerous==2.2.0
55
- Jinja2==3.1.5
55
+ Jinja2==3.1.6
56
56
  ldap3==2.9.1
57
57
  matterhook==0.2
58
58
  meilisearch==0.34.0
@@ -0,0 +1 @@
1
+ __version__ = "0.20.23"
@@ -491,7 +491,13 @@ class ReplyCommentResource(Resource, ArgsMixin):
491
491
  ]
492
492
  )
493
493
 
494
- user_service.check_task_action_access(task_id)
494
+ comment = tasks_service.get_comment(comment_id)
495
+ current_user = persons_service.get_current_user()
496
+ if comment["person_id"] != current_user["id"]:
497
+ if permissions.has_client_permissions():
498
+ raise permissions.PermissionDenied()
499
+ user_service.check_task_action_access(task_id)
500
+
495
501
  return comments_service.reply_comment(comment_id, args["text"])
496
502
 
497
503
 
@@ -418,11 +418,8 @@ class CreatePreviewFilePictureResource(
418
418
  )
419
419
  raise PreviewFileReuploadNotAllowedException
420
420
 
421
- try:
422
- user_service.check_task_action_access(preview_file["task_id"])
423
- return True
424
- except permissions.PermissionDenied:
425
- return False
421
+ user_service.check_task_action_access(preview_file["task_id"])
422
+ return True
426
423
 
427
424
  def is_exist(self, preview_file_id):
428
425
  """
@@ -42,6 +42,7 @@ from zou.app.blueprints.shots.resources import (
42
42
  EpisodeAssetTasksResource,
43
43
  SequenceShotTasksResource,
44
44
  ProjectQuotasResource,
45
+ ProjectPersonQuotasResource,
45
46
  SetShotsFramesResource,
46
47
  )
47
48
 
@@ -95,6 +96,10 @@ routes = [
95
96
  "/data/projects/<project_id>/quotas/<task_type_id>",
96
97
  ProjectQuotasResource,
97
98
  ),
99
+ (
100
+ "/data/projects/<project_id>/quotas/persons/<person_id>",
101
+ ProjectPersonQuotasResource,
102
+ ),
98
103
  (
99
104
  "/actions/projects/<project_id>/task-types/<task_type_id>/set-shot-nb-frames",
100
105
  SetShotsFramesResource,
@@ -1607,6 +1607,80 @@ class ProjectQuotasResource(Resource, ArgsMixin):
1607
1607
  )
1608
1608
 
1609
1609
 
1610
+ class ProjectPersonQuotasResource(Resource, ArgsMixin):
1611
+
1612
+ @jwt_required()
1613
+ def get(self, project_id, person_id):
1614
+ """
1615
+ Retrieve quotas statistics for shots.
1616
+ ---
1617
+ tags:
1618
+ - Shots
1619
+ parameters:
1620
+ - in: path
1621
+ name: project_id
1622
+ required: True
1623
+ type: string
1624
+ format: UUID
1625
+ x-example: a24a6ea4-ce75-4665-a070-57453082c25
1626
+ - in: path
1627
+ name: person_id
1628
+ required: True
1629
+ type: string
1630
+ format: UUID
1631
+ x-example: a24a6ea4-ce75-4665-a070-57453082c25
1632
+ - in: query
1633
+ name: count_mode
1634
+ required: True
1635
+ type: string
1636
+ enum: [weighted, weigtheddone, feedback, done]
1637
+ x-example: weighted
1638
+ - in: query
1639
+ name: studio_id
1640
+ required: False
1641
+ type: string
1642
+ format: UUID
1643
+ x-example: a24a6ea4-ce75-4665-a070-57453082c25
1644
+ responses:
1645
+ 200:
1646
+ description: Quotas statistics for shots
1647
+ """
1648
+ projects_service.get_project(project_id)
1649
+ user_service.check_project_access(project_id)
1650
+ args = self.get_args(
1651
+ [
1652
+ ("count_mode", "weighted", False, str),
1653
+ ("studio_id", None, False, str),
1654
+ ]
1655
+ )
1656
+ count_mode = args["count_mode"]
1657
+ studio_id = args["studio_id"]
1658
+
1659
+ if count_mode not in ["weighted", "weighteddone", "feedback", "done"]:
1660
+ raise WrongParameterException(
1661
+ "count_mode must be equal to weighted, weigtheddone, feedback"
1662
+ ", or done"
1663
+ )
1664
+
1665
+ feedback = "done" not in count_mode
1666
+ weighted = "weighted" in count_mode
1667
+
1668
+ if weighted:
1669
+ return shots_service.get_weighted_quotas(
1670
+ project_id,
1671
+ person_id=person_id,
1672
+ feedback=feedback,
1673
+ studio_id=studio_id,
1674
+ )
1675
+ else:
1676
+ return shots_service.get_raw_quotas(
1677
+ project_id,
1678
+ person_id=person_id,
1679
+ feedback=feedback,
1680
+ studio_id=studio_id,
1681
+ )
1682
+
1683
+
1610
1684
  class SetShotsFramesResource(Resource, ArgsMixin):
1611
1685
  @jwt_required()
1612
1686
  def post(self, project_id, task_type_id):
@@ -10,6 +10,7 @@ from zou.app.models.person import ROLE_TYPES
10
10
 
11
11
  PROJECT_STYLES = [
12
12
  ("2d", "2D Animation"),
13
+ ("2dpaper", "2D Animation (Paper)"),
13
14
  ("3d", "3D Animation"),
14
15
  ("2d3d", "2D/3D Animation"),
15
16
  ("ar", "Augmented Reality"),
@@ -47,6 +47,8 @@ class Task(db.Model, BaseMixin, SerializerMixin):
47
47
  last_comment_date = db.Column(db.DateTime)
48
48
  nb_assets_ready = db.Column(db.Integer, default=0)
49
49
  data = db.Column(JSONB)
50
+ nb_drawings = db.Column(db.Integer, default=0)
51
+
50
52
  shotgun_id = db.Column(db.Integer)
51
53
  last_preview_file_id = db.Column(UUIDType(binary=False))
52
54
 
@@ -348,7 +348,9 @@ def get_assets_and_tasks(criterions={}, with_episode_ids=False):
348
348
  "last_comment_date": fields.serialize_value(
349
349
  task_last_comment_date
350
350
  ),
351
- "last_preview_file_id": str(task_last_preview_file_id or ""),
351
+ "last_preview_file_id": str(
352
+ task_last_preview_file_id or ""
353
+ ),
352
354
  "priority": task_priority or 0,
353
355
  "real_start_date": fields.serialize_value(
354
356
  task_real_start_date
@@ -256,6 +256,7 @@ def get_shots_and_tasks(criterions={}):
256
256
  Task.last_preview_file_id,
257
257
  Task.nb_assets_ready,
258
258
  Task.difficulty,
259
+ Task.nb_drawings,
259
260
  assignees_table.columns.person,
260
261
  Project.id,
261
262
  Project.name,
@@ -308,6 +309,7 @@ def get_shots_and_tasks(criterions={}):
308
309
  task_last_preview_file_id,
309
310
  task_nb_assets_ready,
310
311
  task_difficulty,
312
+ task_nb_drawings,
311
313
  person_id,
312
314
  project_id,
313
315
  project_name,
@@ -373,6 +375,7 @@ def get_shots_and_tasks(criterions={}):
373
375
  "retake_count": task_retake_count,
374
376
  "start_date": task_start_date,
375
377
  "difficulty": task_difficulty,
378
+ "nb_drawings": task_nb_drawings,
376
379
  "task_status_id": task_status_id,
377
380
  "task_type_id": task_type_id,
378
381
  "assignees": [],
@@ -1117,7 +1120,11 @@ def get_base_entity_type_name(entity_dict):
1117
1120
 
1118
1121
 
1119
1122
  def get_weighted_quotas(
1120
- project_id, task_type_id, studio_id=None, feedback=True
1123
+ project_id,
1124
+ task_type_id=None,
1125
+ person_id=None,
1126
+ studio_id=None,
1127
+ feedback=True,
1121
1128
  ):
1122
1129
  """
1123
1130
  Build quota statistics. It counts the number of frames done for each day.
@@ -1140,7 +1147,6 @@ def get_weighted_quotas(
1140
1147
  query = (
1141
1148
  Task.query.filter(Entity.entity_type_id == shot_type["id"])
1142
1149
  .filter(Task.project_id == project_id)
1143
- .filter(Task.task_type_id == task_type_id)
1144
1150
  .join(Entity, Entity.id == Task.entity_id)
1145
1151
  .join(Project, Project.id == Task.project_id)
1146
1152
  .join(TimeSpent, Task.id == TimeSpent.task_id)
@@ -1152,6 +1158,12 @@ def get_weighted_quotas(
1152
1158
  )
1153
1159
  )
1154
1160
 
1161
+ if task_type_id is not None:
1162
+ query = query.filter(Task.task_type_id == task_type_id)
1163
+
1164
+ if person_id is not None:
1165
+ query = query.filter(TimeSpent.person_id == person_id)
1166
+
1155
1167
  if feedback:
1156
1168
  query = query.filter(Task.end_date != None)
1157
1169
  else:
@@ -1166,11 +1178,21 @@ def get_weighted_quotas(
1166
1178
  )
1167
1179
  result = query.all()
1168
1180
 
1169
- for task, nb_frames, date, duration, person_id in result:
1170
- person_id = str(person_id)
1171
- if task.duration > 0 and nb_frames is not None:
1181
+ for task, nb_frames, date, duration, task_person_id in result:
1182
+ task_person_id = str(task_person_id)
1183
+ nb_drawings = task.nb_drawings or 0
1184
+ nb_frames = nb_frames or 0
1185
+ if task.duration > 0:
1172
1186
  nb_frames = round(nb_frames * (duration / task.duration))
1173
- _add_quota_entry(quotas, person_id, date, timezone, nb_frames, fps)
1187
+ nb_drawings = round(nb_drawings * (duration / task.duration))
1188
+ entry_id = str(task_person_id)
1189
+ # We get quotas for a specific person split by task types
1190
+ if person_id is not None:
1191
+ entry_id = str(task.task_type_id)
1192
+ for entry in [entry_id, "total"]:
1193
+ _add_quota_entry(
1194
+ quotas, entry, date, timezone, nb_frames, nb_drawings, fps
1195
+ )
1174
1196
 
1175
1197
  query = (
1176
1198
  Task.query.filter(Task.project_id == project_id)
@@ -1185,6 +1207,13 @@ def get_weighted_quotas(
1185
1207
  .add_columns(Entity.nb_frames, Person.id)
1186
1208
  )
1187
1209
 
1210
+ if task_type_id is not None:
1211
+ query = query.filter(Task.task_type_id == task_type_id)
1212
+
1213
+ if person_id is not None:
1214
+ person = persons_service.get_person_raw(person_id)
1215
+ query = query.filter(Task.assignees.contains(person))
1216
+
1188
1217
  if feedback:
1189
1218
  query = query.filter(Task.end_date != None)
1190
1219
  else:
@@ -1196,7 +1225,7 @@ def get_weighted_quotas(
1196
1225
  )
1197
1226
  result = query.all()
1198
1227
 
1199
- for task, nb_frames, person_id in result:
1228
+ for task, nb_frames, task_person_id in result:
1200
1229
  date = task.done_date
1201
1230
  if feedback:
1202
1231
  date = task.end_date
@@ -1209,16 +1238,36 @@ def get_weighted_quotas(
1209
1238
  else:
1210
1239
  nb_frames = 0
1211
1240
 
1241
+ nb_drawings = task.nb_drawings or 0
1242
+
1212
1243
  for x in range((date - task.real_start_date).days + 1):
1213
1244
  if date.weekday() < 5:
1214
- _add_quota_entry(
1215
- quotas, str(person_id), date, timezone, nb_frames, fps
1216
- )
1245
+ entry_id = str(task_person_id)
1246
+ # We get quotas for a specific person split by task types
1247
+ if person_id is not None:
1248
+ entry_id = str(task.task_type_id)
1249
+
1250
+ for entry in [entry_id, "total"]:
1251
+ _add_quota_entry(
1252
+ quotas,
1253
+ entry,
1254
+ date,
1255
+ timezone,
1256
+ nb_frames,
1257
+ nb_drawings,
1258
+ fps,
1259
+ )
1217
1260
  date = date + timedelta(1)
1218
1261
  return quotas
1219
1262
 
1220
1263
 
1221
- def get_raw_quotas(project_id, task_type_id, studio_id=None, feedback=True):
1264
+ def get_raw_quotas(
1265
+ project_id,
1266
+ task_type_id=None,
1267
+ person_id=None,
1268
+ studio_id=None,
1269
+ feedback=True,
1270
+ ):
1222
1271
  """
1223
1272
  Build quota statistics in a raw way. It counts the number of frames done
1224
1273
  for each day. A shot is considered done at the first feedback request (end
@@ -1234,13 +1283,19 @@ def get_raw_quotas(project_id, task_type_id, studio_id=None, feedback=True):
1234
1283
  query = (
1235
1284
  Task.query.filter(Task.project_id == project_id)
1236
1285
  .filter(Entity.entity_type_id == shot_type["id"])
1237
- .filter(Task.task_type_id == task_type_id)
1238
1286
  .join(Entity, Entity.id == Task.entity_id)
1239
1287
  .join(Project, Project.id == Task.project_id)
1240
1288
  .join(Task.assignees)
1241
1289
  .add_columns(Entity.nb_frames, Person.id)
1242
1290
  )
1243
1291
 
1292
+ if task_type_id is not None:
1293
+ query = query.filter(Task.task_type_id == task_type_id)
1294
+
1295
+ if person_id is not None:
1296
+ person = persons_service.get_person_raw(person_id)
1297
+ query = query.filter(Task.assignees.contains(person))
1298
+
1244
1299
  if feedback:
1245
1300
  query = query.filter(Task.end_date != None)
1246
1301
  else:
@@ -1256,20 +1311,30 @@ def get_raw_quotas(project_id, task_type_id, studio_id=None, feedback=True):
1256
1311
 
1257
1312
  result = query.all()
1258
1313
 
1259
- for task, nb_frames, person_id in result:
1314
+ for task, nb_frames, task_person_id in result:
1260
1315
  date = task.done_date
1261
1316
  if feedback:
1262
1317
  date = task.end_date
1263
1318
 
1264
1319
  if nb_frames is None:
1265
1320
  nb_frames = 0
1266
- _add_quota_entry(
1267
- quotas, str(person_id), date, timezone, nb_frames, fps
1268
- )
1321
+
1322
+ nb_drawings = task.nb_drawings or 0
1323
+
1324
+ entry_id = str(task_person_id)
1325
+ if person_id is not None:
1326
+ entry_id = str(task.task_type_id)
1327
+
1328
+ for entry in [entry_id, "total"]:
1329
+ _add_quota_entry(
1330
+ quotas, entry, date, timezone, nb_frames, nb_drawings, fps
1331
+ )
1269
1332
  return quotas
1270
1333
 
1271
1334
 
1272
- def _add_quota_entry(quotas, person_id, date, timezone, nb_frames, fps):
1335
+ def _add_quota_entry(
1336
+ quotas, entry_id, date, timezone, nb_frames, nb_drawings, fps
1337
+ ):
1273
1338
  nb_seconds = nb_frames / fps
1274
1339
  date_str = date_helpers.get_simple_string_with_timezone_from_date(
1275
1340
  date, timezone
@@ -1277,59 +1342,84 @@ def _add_quota_entry(quotas, person_id, date, timezone, nb_frames, fps):
1277
1342
  year = date_str[:4]
1278
1343
  week = year + "-" + str(date.isocalendar()[1])
1279
1344
  month = date_str[:7]
1280
- if person_id not in quotas:
1281
- _init_quota_person(quotas, person_id)
1282
- _init_quota_date(quotas, person_id, date_str, week, month)
1283
- quotas[person_id]["day"]["frames"][date_str] += nb_frames
1284
- quotas[person_id]["day"]["seconds"][date_str] += nb_seconds
1285
- quotas[person_id]["day"]["count"][date_str] += 1
1286
- quotas[person_id]["week"]["frames"][week] += nb_frames
1287
- quotas[person_id]["week"]["seconds"][week] += nb_seconds
1288
- quotas[person_id]["week"]["count"][week] += 1
1289
- quotas[person_id]["month"]["frames"][month] += nb_frames
1290
- quotas[person_id]["month"]["seconds"][month] += nb_seconds
1291
- quotas[person_id]["month"]["count"][month] += 1
1292
- quotas[person_id]["year"]["frames"][year] += nb_frames
1293
- quotas[person_id]["year"]["seconds"][year] += nb_seconds
1294
- quotas[person_id]["year"]["count"][year] += 1
1295
-
1296
-
1297
- def _init_quota_date(quotas, person_id, date_str, week, month):
1345
+ if entry_id not in quotas:
1346
+ _init_quota_entry(quotas, entry_id)
1347
+ _init_quota_date(quotas, entry_id, date_str, week, month)
1348
+ quotas[entry_id]["day"]["frames"][date_str] += nb_frames
1349
+ quotas[entry_id]["day"]["seconds"][date_str] += nb_seconds
1350
+ quotas[entry_id]["day"]["drawings"][date_str] += nb_drawings
1351
+ quotas[entry_id]["day"]["count"][date_str] += 1
1352
+ quotas[entry_id]["week"]["frames"][week] += nb_frames
1353
+ quotas[entry_id]["week"]["seconds"][week] += nb_seconds
1354
+ quotas[entry_id]["week"]["drawings"][week] += nb_drawings
1355
+ quotas[entry_id]["week"]["count"][week] += 1
1356
+ quotas[entry_id]["month"]["frames"][month] += nb_frames
1357
+ quotas[entry_id]["month"]["seconds"][month] += nb_seconds
1358
+ quotas[entry_id]["month"]["drawings"][month] += nb_drawings
1359
+ quotas[entry_id]["month"]["count"][month] += 1
1360
+ quotas[entry_id]["year"]["frames"][year] += nb_frames
1361
+ quotas[entry_id]["year"]["drawings"][year] += nb_drawings
1362
+ quotas[entry_id]["year"]["seconds"][year] += nb_seconds
1363
+ quotas[entry_id]["year"]["count"][year] += 1
1364
+
1365
+
1366
+ def _init_quota_date(quotas, entry_id, date_str, week, month):
1298
1367
  year = week[:4]
1299
- if date_str not in quotas[person_id]["day"]["frames"]:
1300
- quotas[person_id]["day"]["frames"][date_str] = 0
1301
- quotas[person_id]["day"]["seconds"][date_str] = 0
1302
- quotas[person_id]["day"]["count"][date_str] = 0
1303
- if month not in quotas[person_id]["day"]["entries"]:
1304
- quotas[person_id]["day"]["entries"][month] = 0
1305
- quotas[person_id]["day"]["entries"][month] += 1
1306
- if week not in quotas[person_id]["week"]["frames"]:
1307
- quotas[person_id]["week"]["frames"][week] = 0
1308
- quotas[person_id]["week"]["seconds"][week] = 0
1309
- quotas[person_id]["week"]["count"][week] = 0
1310
- if year not in quotas[person_id]["week"]["entries"]:
1311
- quotas[person_id]["week"]["entries"][year] = 0
1312
- quotas[person_id]["week"]["entries"][year] += 1
1313
- if month not in quotas[person_id]["month"]["frames"]:
1314
- quotas[person_id]["month"]["frames"][month] = 0
1315
- quotas[person_id]["month"]["seconds"][month] = 0
1316
- quotas[person_id]["month"]["count"][month] = 0
1317
- if year not in quotas[person_id]["month"]["entries"]:
1318
- quotas[person_id]["month"]["entries"][year] = 0
1319
- quotas[person_id]["month"]["entries"][year] += 1
1320
- if year not in quotas[person_id]["year"]["frames"]:
1321
- quotas[person_id]["year"]["frames"][year] = 0
1322
- quotas[person_id]["year"]["seconds"][year] = 0
1323
- quotas[person_id]["year"]["count"][year] = 0
1324
-
1325
-
1326
- def _init_quota_person(quotas, person_id):
1327
- quotas[person_id] = {}
1328
- quotas[person_id] = {
1329
- "day": {"frames": {}, "seconds": {}, "count": {}, "entries": {}},
1330
- "week": {"frames": {}, "seconds": {}, "count": {}, "entries": {}},
1331
- "month": {"frames": {}, "seconds": {}, "count": {}, "entries": {}},
1332
- "year": {"frames": {}, "seconds": {}, "count": {}},
1368
+ if date_str not in quotas[entry_id]["day"]["frames"]:
1369
+ quotas[entry_id]["day"]["frames"][date_str] = 0
1370
+ quotas[entry_id]["day"]["seconds"][date_str] = 0
1371
+ quotas[entry_id]["day"]["count"][date_str] = 0
1372
+ quotas[entry_id]["day"]["drawings"][date_str] = 0
1373
+ if month not in quotas[entry_id]["day"]["entries"]:
1374
+ quotas[entry_id]["day"]["entries"][month] = 0
1375
+ quotas[entry_id]["day"]["entries"][month] += 1
1376
+ if week not in quotas[entry_id]["week"]["frames"]:
1377
+ quotas[entry_id]["week"]["frames"][week] = 0
1378
+ quotas[entry_id]["week"]["seconds"][week] = 0
1379
+ quotas[entry_id]["week"]["count"][week] = 0
1380
+ quotas[entry_id]["week"]["drawings"][week] = 0
1381
+ if year not in quotas[entry_id]["week"]["entries"]:
1382
+ quotas[entry_id]["week"]["entries"][year] = 0
1383
+ quotas[entry_id]["week"]["entries"][year] += 1
1384
+ if month not in quotas[entry_id]["month"]["frames"]:
1385
+ quotas[entry_id]["month"]["frames"][month] = 0
1386
+ quotas[entry_id]["month"]["seconds"][month] = 0
1387
+ quotas[entry_id]["month"]["count"][month] = 0
1388
+ quotas[entry_id]["month"]["drawings"][month] = 0
1389
+ if year not in quotas[entry_id]["month"]["entries"]:
1390
+ quotas[entry_id]["month"]["entries"][year] = 0
1391
+ quotas[entry_id]["month"]["entries"][year] += 1
1392
+ if year not in quotas[entry_id]["year"]["frames"]:
1393
+ quotas[entry_id]["year"]["frames"][year] = 0
1394
+ quotas[entry_id]["year"]["seconds"][year] = 0
1395
+ quotas[entry_id]["year"]["count"][year] = 0
1396
+ quotas[entry_id]["year"]["drawings"][year] = 0
1397
+
1398
+
1399
+ def _init_quota_entry(quotas, entry_id):
1400
+ quotas[entry_id] = {
1401
+ "day": {
1402
+ "frames": {},
1403
+ "seconds": {},
1404
+ "count": {},
1405
+ "entries": {},
1406
+ "drawings": {},
1407
+ },
1408
+ "week": {
1409
+ "frames": {},
1410
+ "seconds": {},
1411
+ "count": {},
1412
+ "entries": {},
1413
+ "drawings": {},
1414
+ },
1415
+ "month": {
1416
+ "frames": {},
1417
+ "seconds": {},
1418
+ "count": {},
1419
+ "entries": {},
1420
+ "drawings": {},
1421
+ },
1422
+ "year": {"frames": {}, "seconds": {}, "count": {}, "drawings": {}},
1333
1423
  }
1334
1424
 
1335
1425
 
@@ -1487,7 +1577,6 @@ def get_weighted_quota_shots_between(
1487
1577
  shot = already_listed[shot["id"]]
1488
1578
  shot["weight"] += round(duration / task_duration, 2)
1489
1579
 
1490
- print(start, end)
1491
1580
  if type(start) is str:
1492
1581
  start = date_helpers.get_datetime_from_string(start)
1493
1582
  if type(end) is str: