zou 0.19.14__py3-none-any.whl → 0.20.11__py3-none-any.whl

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 (165) hide show
  1. zou/__init__.py +1 -1
  2. zou/app/__init__.py +10 -2
  3. zou/app/api.py +2 -0
  4. zou/app/blueprints/assets/__init__.py +22 -0
  5. zou/app/blueprints/assets/resources.py +241 -4
  6. zou/app/blueprints/auth/__init__.py +4 -0
  7. zou/app/blueprints/auth/resources.py +154 -22
  8. zou/app/blueprints/breakdown/resources.py +4 -4
  9. zou/app/blueprints/chats/__init__.py +22 -0
  10. zou/app/blueprints/chats/resources.py +199 -0
  11. zou/app/blueprints/comments/resources.py +36 -19
  12. zou/app/blueprints/crud/__init__.py +12 -0
  13. zou/app/blueprints/crud/attachment_file.py +14 -5
  14. zou/app/blueprints/crud/base.py +29 -28
  15. zou/app/blueprints/crud/chat.py +13 -0
  16. zou/app/blueprints/crud/chat_message.py +13 -0
  17. zou/app/blueprints/crud/comments.py +85 -29
  18. zou/app/blueprints/crud/custom_action.py +1 -1
  19. zou/app/blueprints/crud/day_off.py +47 -9
  20. zou/app/blueprints/crud/department.py +1 -25
  21. zou/app/blueprints/crud/entity.py +46 -5
  22. zou/app/blueprints/crud/entity_type.py +13 -1
  23. zou/app/blueprints/crud/event.py +1 -1
  24. zou/app/blueprints/crud/file_status.py +1 -1
  25. zou/app/blueprints/crud/metadata_descriptor.py +24 -10
  26. zou/app/blueprints/crud/organisation.py +22 -5
  27. zou/app/blueprints/crud/output_file.py +1 -1
  28. zou/app/blueprints/crud/output_type.py +1 -1
  29. zou/app/blueprints/crud/person.py +32 -24
  30. zou/app/blueprints/crud/playlist.py +1 -1
  31. zou/app/blueprints/crud/preview_background_file.py +6 -7
  32. zou/app/blueprints/crud/preview_file.py +1 -1
  33. zou/app/blueprints/crud/project.py +14 -6
  34. zou/app/blueprints/crud/project_status.py +1 -1
  35. zou/app/blueprints/crud/schedule_item.py +4 -2
  36. zou/app/blueprints/crud/software.py +1 -1
  37. zou/app/blueprints/crud/status_automation.py +1 -1
  38. zou/app/blueprints/crud/studio.py +33 -0
  39. zou/app/blueprints/crud/task.py +47 -3
  40. zou/app/blueprints/crud/task_status.py +1 -1
  41. zou/app/blueprints/crud/task_type.py +4 -4
  42. zou/app/blueprints/crud/working_file.py +4 -8
  43. zou/app/blueprints/events/resources.py +13 -12
  44. zou/app/blueprints/export/csv/assets.py +15 -6
  45. zou/app/blueprints/export/csv/edits.py +15 -5
  46. zou/app/blueprints/export/csv/playlists.py +1 -1
  47. zou/app/blueprints/export/csv/shots.py +15 -5
  48. zou/app/blueprints/export/csv/time_spents.py +1 -1
  49. zou/app/blueprints/files/resources.py +22 -23
  50. zou/app/blueprints/index/resources.py +38 -29
  51. zou/app/blueprints/news/resources.py +25 -11
  52. zou/app/blueprints/persons/__init__.py +5 -2
  53. zou/app/blueprints/persons/resources.py +126 -120
  54. zou/app/blueprints/previews/__init__.py +18 -8
  55. zou/app/blueprints/previews/resources.py +569 -328
  56. zou/app/blueprints/projects/resources.py +1 -1
  57. zou/app/blueprints/search/resources.py +18 -6
  58. zou/app/blueprints/shots/__init__.py +5 -0
  59. zou/app/blueprints/shots/resources.py +134 -4
  60. zou/app/blueprints/source/__init__.py +6 -6
  61. zou/app/blueprints/source/csv/assets.py +10 -3
  62. zou/app/blueprints/source/csv/base.py +1 -1
  63. zou/app/blueprints/source/csv/edits.py +10 -3
  64. zou/app/blueprints/source/csv/shots.py +10 -3
  65. zou/app/blueprints/source/{edl.py → otio.py} +84 -41
  66. zou/app/blueprints/tasks/__init__.py +3 -2
  67. zou/app/blueprints/tasks/resources.py +83 -52
  68. zou/app/blueprints/user/__init__.py +9 -0
  69. zou/app/blueprints/user/resources.py +170 -12
  70. zou/app/config.py +10 -0
  71. zou/app/mixin.py +6 -5
  72. zou/app/models/attachment_file.py +10 -4
  73. zou/app/models/base.py +18 -13
  74. zou/app/models/build_job.py +7 -4
  75. zou/app/models/chat.py +44 -0
  76. zou/app/models/chat_message.py +37 -0
  77. zou/app/models/comment.py +1 -0
  78. zou/app/models/day_off.py +3 -0
  79. zou/app/models/entity.py +4 -6
  80. zou/app/models/entity_type.py +2 -0
  81. zou/app/models/organisation.py +14 -15
  82. zou/app/models/person.py +6 -1
  83. zou/app/models/project.py +3 -0
  84. zou/app/models/search_filter.py +11 -0
  85. zou/app/models/search_filter_group.py +10 -0
  86. zou/app/models/serializer.py +17 -17
  87. zou/app/models/status_automation.py +2 -0
  88. zou/app/models/studio.py +13 -0
  89. zou/app/models/subscription.py +2 -2
  90. zou/app/models/task.py +6 -1
  91. zou/app/models/task_status.py +1 -0
  92. zou/app/models/task_type.py +1 -0
  93. zou/app/models/working_file.py +1 -1
  94. zou/app/services/assets_service.py +101 -14
  95. zou/app/services/auth_service.py +17 -44
  96. zou/app/services/breakdown_service.py +37 -5
  97. zou/app/services/chats_service.py +279 -0
  98. zou/app/services/comments_service.py +110 -65
  99. zou/app/services/concepts_service.py +4 -12
  100. zou/app/services/deletion_service.py +43 -30
  101. zou/app/services/edits_service.py +5 -11
  102. zou/app/services/emails_service.py +4 -4
  103. zou/app/services/entities_service.py +17 -2
  104. zou/app/services/events_service.py +12 -4
  105. zou/app/services/exception.py +5 -5
  106. zou/app/services/names_service.py +7 -2
  107. zou/app/services/news_service.py +17 -9
  108. zou/app/services/persons_service.py +38 -21
  109. zou/app/services/playlists_service.py +8 -7
  110. zou/app/services/preview_files_service.py +137 -10
  111. zou/app/services/projects_service.py +5 -14
  112. zou/app/services/shots_service.py +221 -49
  113. zou/app/services/sync_service.py +46 -42
  114. zou/app/services/tasks_service.py +185 -46
  115. zou/app/services/time_spents_service.py +67 -20
  116. zou/app/services/user_service.py +350 -107
  117. zou/app/stores/auth_tokens_store.py +2 -1
  118. zou/app/stores/file_store.py +18 -0
  119. zou/app/stores/publisher_store.py +7 -7
  120. zou/app/stores/queue_store.py +1 -0
  121. zou/app/swagger.py +36 -20
  122. zou/app/utils/cache.py +2 -0
  123. zou/app/utils/commands.py +104 -7
  124. zou/app/utils/csv_utils.py +1 -4
  125. zou/app/utils/date_helpers.py +33 -17
  126. zou/app/utils/dbhelpers.py +14 -1
  127. zou/app/utils/emails.py +2 -2
  128. zou/app/utils/fido.py +22 -0
  129. zou/app/utils/flask.py +1 -0
  130. zou/app/utils/query.py +54 -6
  131. zou/app/utils/redis.py +11 -0
  132. zou/app/utils/saml.py +51 -0
  133. zou/app/utils/string.py +2 -0
  134. zou/app/utils/thumbnail.py +4 -2
  135. zou/cli.py +76 -18
  136. zou/debug.py +4 -2
  137. zou/event_stream.py +122 -165
  138. zou/job_settings.py +1 -0
  139. zou/migrations/env.py +0 -0
  140. zou/migrations/utils/base.py +6 -6
  141. zou/migrations/versions/1bb55759146f_add_table_studio.py +67 -0
  142. zou/migrations/versions/1fab8c420678_add_attachments_to_message_chats.py +56 -0
  143. zou/migrations/versions/23122f290ca2_add_entity_chat_models.py +149 -0
  144. zou/migrations/versions/32f134ff1201_add_is_shared_flag_to_filters.py +33 -0
  145. zou/migrations/versions/57222395f2be_add_statusautomation_import_last_revision.py +41 -0
  146. zou/migrations/versions/59a7445a966c_add_entity_is_shared.py +41 -0
  147. zou/migrations/versions/5b980f0dc365_add_comment_links.py +35 -0
  148. zou/migrations/versions/680c64565f9d_for_searchfiltergroup_is_shared.py +35 -0
  149. zou/migrations/versions/8e67c183bed7_add_preference_fields.py +71 -0
  150. zou/migrations/versions/92b40d79ad3f_allow_message_attachments.py +38 -0
  151. zou/migrations/versions/971dbf5a0faf_add_short_name_for_asset_type_entity_.py +33 -0
  152. zou/migrations/versions/9b85c14fa8a7_add_day_off_new_columns.py +68 -0
  153. zou/migrations/versions/9d3bb33c6fc6_add_department_keys_to_filter_models.py +73 -0
  154. zou/migrations/versions/a252a094e977_add_descriptions_for_entities_tasks_and_.py +40 -0
  155. zou/migrations/versions/be56dc0fb760_for_is_shared_disallow_nullable.py +102 -0
  156. zou/migrations/versions/ca28796a2a62_add_is_done_field_to_the_task_model.py +108 -0
  157. zou/migrations/versions/f344b867a911_for_description_of_entity_task_working_.py +75 -0
  158. zou/remote/config_payload.py +2 -1
  159. zou/utils/movie.py +14 -4
  160. {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/METADATA +75 -69
  161. {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/RECORD +164 -135
  162. {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/WHEEL +1 -1
  163. {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/LICENSE +0 -0
  164. {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/entry_points.txt +0 -0
  165. {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/top_level.txt +0 -0
@@ -61,7 +61,7 @@ class EditsCsvExport(Resource):
61
61
  def build_headers(self, metadata_infos, validation_columns):
62
62
  headers = ["Project", "Episode", "Name", "Description", "Time Spent"]
63
63
 
64
- metadata_headers = [name for (name, _) in metadata_infos]
64
+ metadata_headers = [name for (name, _, _) in metadata_infos]
65
65
 
66
66
  validation_assignations_columns = []
67
67
  for validation_column in validation_columns:
@@ -94,9 +94,15 @@ class EditsCsvExport(Resource):
94
94
  ]
95
95
  )
96
96
 
97
- for _, field_name in metadata_infos:
98
- result_metadata = result.get("data", {}) or {}
99
- row.append(result_metadata.get(field_name, ""))
97
+ result_data = result.get("data", {}) or {}
98
+ for _, field_name, data_type in metadata_infos:
99
+ result_metadata = result_data.get(field_name, "")
100
+ if data_type == "boolean":
101
+ row.append(
102
+ "true" if result_metadata.lower() == "true" else "false"
103
+ )
104
+ else:
105
+ row.append(result_metadata)
100
106
 
101
107
  for column in validation_columns:
102
108
  if column in task_map:
@@ -149,7 +155,11 @@ class EditsCsvExport(Resource):
149
155
  ]
150
156
 
151
157
  columns = [
152
- (descriptor["name"], descriptor["field_name"])
158
+ (
159
+ descriptor["name"],
160
+ descriptor["field_name"],
161
+ descriptor["data_type"],
162
+ )
153
163
  for descriptor in descriptors
154
164
  ]
155
165
 
@@ -100,7 +100,7 @@ class PlaylistCsvExport(Resource):
100
100
 
101
101
  def build_row(self, shot):
102
102
  entity = entities_service.get_entity(shot["entity_id"])
103
- name, _ = names_service.get_full_entity_name(shot["entity_id"])
103
+ name, _, _ = names_service.get_full_entity_name(shot["entity_id"])
104
104
  preview_file = files_service.get_preview_file(shot["preview_file_id"])
105
105
  task = tasks_service.get_task(preview_file["task_id"])
106
106
  task_type = self.task_type_map[task["task_type_id"]]
@@ -76,7 +76,7 @@ class ShotsCsvExport(Resource):
76
76
  "FPS",
77
77
  ]
78
78
 
79
- metadata_headers = [name for (name, _) in metadata_infos]
79
+ metadata_headers = [name for (name, _, _) in metadata_infos]
80
80
 
81
81
  validation_assignations_columns = []
82
82
  for validation_column in validation_columns:
@@ -123,9 +123,15 @@ class ShotsCsvExport(Resource):
123
123
  for person_id in task["assignees"]
124
124
  ]
125
125
  )
126
-
127
- for _, field_name in metadata_infos:
128
- row.append(result.get("data", {}).get(field_name, ""))
126
+ result_data = result.get("data", {}) or {}
127
+ for _, field_name, data_type in metadata_infos:
128
+ result_metadata = result_data.get(field_name, "")
129
+ if data_type == "boolean":
130
+ row.append(
131
+ "true" if result_metadata.lower() == "true" else "false"
132
+ )
133
+ else:
134
+ row.append(result_metadata)
129
135
 
130
136
  for column in validation_columns:
131
137
  if column in task_map:
@@ -171,7 +177,11 @@ class ShotsCsvExport(Resource):
171
177
  ]
172
178
 
173
179
  columns = [
174
- (descriptor["name"], descriptor["field_name"])
180
+ (
181
+ descriptor["name"],
182
+ descriptor["field_name"],
183
+ descriptor["data_type"],
184
+ )
175
185
  for descriptor in descriptors
176
186
  ]
177
187
 
@@ -72,7 +72,7 @@ class TimeSpentsCsvExport(BaseCsvExport):
72
72
  person_last_name,
73
73
  ) = time_spent_row
74
74
  if entity_type_name == "Shot":
75
- entity_name, _ = names_service.get_full_entity_name(entity_id)
75
+ entity_name, _, _ = names_service.get_full_entity_name(entity_id)
76
76
 
77
77
  date = ""
78
78
  if time_spent.date is not None:
@@ -1,4 +1,3 @@
1
- import datetime
2
1
  import os
3
2
 
4
3
  from flask import request, abort, current_app
@@ -9,7 +8,7 @@ from flask_fs.errors import FileNotFound
9
8
  from zou.app import config
10
9
 
11
10
  from zou.app.mixin import ArgsMixin
12
- from zou.app.utils import fs
11
+ from zou.app.utils import fs, date_helpers
13
12
  from zou.app.stores import file_store
14
13
  from zou.app.services import (
15
14
  file_tree_service,
@@ -33,7 +32,10 @@ from zou.app.services.exception import (
33
32
 
34
33
 
35
34
  def send_storage_file(
36
- working_file_id, as_attachment=False, max_age=config.CLIENT_CACHE_MAX_AGE
35
+ working_file_id,
36
+ as_attachment=False,
37
+ max_age=config.CLIENT_CACHE_MAX_AGE,
38
+ last_modified=None,
37
39
  ):
38
40
  """
39
41
  Send file from storage. If it's not a local storage, cache the file in
@@ -61,6 +63,7 @@ def send_storage_file(
61
63
  as_attachment=as_attachment,
62
64
  download_name=download_name,
63
65
  max_age=max_age,
66
+ last_modified=last_modified,
64
67
  )
65
68
  except IOError as e:
66
69
  current_app.logger.error(e)
@@ -88,9 +91,7 @@ class WorkingFileFileResource(Resource):
88
91
 
89
92
  def check_access(self, working_file_id):
90
93
  working_file = files_service.get_working_file(working_file_id)
91
- task = tasks_service.get_task(working_file["task_id"])
92
- user_service.check_project_access(task["project_id"])
93
- user_service.check_entity_access(task["entity_id"])
94
+ user_service.check_task_access(working_file["task_id"])
94
95
  return working_file
95
96
 
96
97
  def save_uploaded_file_in_temporary_folder(self, working_file_id):
@@ -126,8 +127,13 @@ class WorkingFileFileResource(Resource):
126
127
  schema:
127
128
  type: file
128
129
  """
129
- self.check_access(working_file_id)
130
- return send_storage_file(working_file_id)
130
+ working_file = self.check_access(working_file_id)
131
+ return send_storage_file(
132
+ working_file_id,
133
+ last_modified=date_helpers.get_datetime_from_string(
134
+ working_file["updated_at"]
135
+ ),
136
+ )
131
137
 
132
138
  @jwt_required()
133
139
  def post(self, working_file_id):
@@ -548,10 +554,8 @@ class LastWorkingFilesResource(Resource):
548
554
  description: Last working files revision for each file name for given task
549
555
  """
550
556
  result = {}
551
- task = tasks_service.get_task(task_id)
552
- user_service.check_project_access(task["project_id"])
553
- user_service.check_entity_access(task["entity_id"])
554
- result = files_service.get_last_working_files_for_task(task["id"])
557
+ user_service.check_task_access(task_id)
558
+ result = files_service.get_last_working_files_for_task(task_id)
555
559
 
556
560
  return result
557
561
 
@@ -580,10 +584,8 @@ class TaskWorkingFilesResource(Resource):
580
584
  description: Last working files revision for each file name for given task
581
585
  """
582
586
  result = {}
583
- task = tasks_service.get_task(task_id)
584
- user_service.check_project_access(task["project_id"])
585
- user_service.check_entity_access(task["entity_id"])
586
- result = files_service.get_working_files_for_task(task["id"])
587
+ user_service.check_task_access(task_id)
588
+ result = files_service.get_working_files_for_task(task_id)
587
589
 
588
590
  return result
589
591
 
@@ -766,11 +768,10 @@ class ModifiedFileResource(Resource):
766
768
  description: Working file modification date updated
767
769
  """
768
770
  working_file = files_service.get_working_file(working_file_id)
769
- task = tasks_service.get_task(working_file["task_id"])
770
- user_service.check_project_access(task["project_id"])
771
- user_service.check_entity_access(task["entity_id"])
771
+ user_service.check_task_access(working_file["task_id"])
772
772
  working_file = files_service.update_working_file(
773
- working_file_id, {"updated_at": datetime.datetime.utcnow()}
773
+ working_file_id,
774
+ {"updated_at": date_helpers.get_utc_now_datetime()},
774
775
  )
775
776
  return working_file
776
777
 
@@ -818,9 +819,7 @@ class CommentWorkingFileResource(Resource, ArgsMixin):
818
819
  )
819
820
 
820
821
  working_file = files_service.get_working_file(working_file_id)
821
- task = tasks_service.get_task(working_file["task_id"])
822
- user_service.check_project_access(task["project_id"])
823
- user_service.check_entity_access(task["entity_id"])
822
+ user_service.check_task_access(working_file["task_id"])
824
823
  working_file = self.update_comment(working_file_id, args["comment"])
825
824
  return working_file
826
825
 
@@ -1,18 +1,17 @@
1
1
  import psutil
2
2
  import redis
3
3
  import requests
4
-
5
- from datetime import datetime
4
+ import datetime
6
5
 
7
6
  from flask import Response, abort
8
7
  from flask_restful import Resource
9
8
  from zou import __version__
10
9
 
11
10
  from zou.app import app, config
12
- from zou.app.utils import permissions, shell
13
- from zou.app.services import projects_service, stats_service
14
-
11
+ from zou.app.utils import permissions, shell, date_helpers
12
+ from zou.app.services import projects_service, stats_service, persons_service
15
13
  from flask_jwt_extended import jwt_required
14
+ from zou.app.utils.redis import get_redis_url
16
15
 
17
16
 
18
17
  class IndexResource(Resource):
@@ -26,7 +25,7 @@ class IndexResource(Resource):
26
25
  200:
27
26
  description: API name and version
28
27
  """
29
- return {"api": app.config["APP_NAME"], "version": __version__}
28
+ return {"api": config.APP_NAME, "version": __version__}
30
29
 
31
30
 
32
31
  class BaseStatusResource(Resource):
@@ -43,6 +42,7 @@ class BaseStatusResource(Resource):
43
42
  host=config.KEY_VALUE_STORE["host"],
44
43
  port=config.KEY_VALUE_STORE["port"],
45
44
  db=config.AUTH_TOKEN_BLACKLIST_KV_INDEX,
45
+ password=config.KEY_VALUE_STORE["password"],
46
46
  decode_responses=True,
47
47
  )
48
48
  store.get("test")
@@ -62,11 +62,12 @@ class BaseStatusResource(Resource):
62
62
 
63
63
  is_jq_up = True
64
64
  try:
65
- host = config.KEY_VALUE_STORE["host"]
66
- port = config.KEY_VALUE_STORE["port"]
67
- db = config.KV_JOB_DB_INDEX
68
- url = "redis://%s:%s/%s" % (host, port, db)
69
- args = ["rq", "info", "--url", url]
65
+ args = [
66
+ "rq",
67
+ "info",
68
+ "--url",
69
+ get_redis_url(config.KV_JOB_DB_INDEX),
70
+ ]
70
71
  out = shell.run_command(args)
71
72
  is_jq_up = b"0 workers" not in out
72
73
  except Exception:
@@ -87,10 +88,8 @@ class BaseStatusResource(Resource):
87
88
 
88
89
  version = __version__
89
90
 
90
- api_name = app.config["APP_NAME"]
91
-
92
91
  return (
93
- api_name,
92
+ config.APP_NAME,
94
93
  version,
95
94
  is_db_up,
96
95
  is_kv_up,
@@ -231,8 +230,8 @@ class InfluxStatusResource(BaseStatusResource):
231
230
  description: Status of database, key value, event stream, job queue and time
232
231
  """
233
232
  (
234
- api_name,
235
- version,
233
+ _,
234
+ _,
236
235
  is_db_up,
237
236
  is_kv_up,
238
237
  is_es_up,
@@ -246,7 +245,9 @@ class InfluxStatusResource(BaseStatusResource):
246
245
  "event-stream-up": int(is_es_up),
247
246
  "job-queue-up": int(is_jq_up),
248
247
  "indexer-up": int(is_indexer_up),
249
- "time": datetime.timestamp(datetime.utcnow()),
248
+ "time": datetime.datetime.timestamp(
249
+ date_helpers.get_utc_now_datetime()
250
+ ),
250
251
  }
251
252
 
252
253
 
@@ -272,28 +273,36 @@ class StatsResource(Resource):
272
273
  class ConfigResource(Resource):
273
274
  def get(self):
274
275
  """
275
- Get crisp token.
276
+ Get basic configuration for the current instance.
276
277
  ---
277
278
  tags:
278
279
  - Index
279
280
  responses:
280
281
  200:
281
- description: Crisp token
282
+ description: Configuration object including self-hosted status,
283
+ Crisp token, indexer configuration, SAML status, and dark
284
+ theme status.
282
285
  """
283
- config = {
284
- "is_self_hosted": app.config["IS_SELF_HOSTED"],
285
- "crisp_token": app.config["CRISP_TOKEN"],
286
+ organisation = persons_service.get_organisation()
287
+ conf = {
288
+ "is_self_hosted": config.IS_SELF_HOSTED,
289
+ "crisp_token": config.CRISP_TOKEN,
290
+ "dark_theme_by_default": organisation["dark_theme_by_default"],
286
291
  "indexer_configured": (
287
- len(app.config["INDEXER"]["key"]) > 0
288
- and app.config["INDEXER"]["key"] != "masterkey"
292
+ len(config.INDEXER["key"]) > 0
293
+ and config.INDEXER["key"] != "masterkey"
289
294
  ),
295
+ "saml_enabled": config.SAML_ENABLED,
296
+ "saml_idp_name": config.SAML_IDP_NAME,
297
+ "default_locale": config.DEFAULT_LOCALE,
298
+ "default_timezone": config.DEFAULT_TIMEZONE,
290
299
  }
291
- if app.config["SENTRY_KITSU_ENABLED"]:
292
- config["sentry"] = {
293
- "dsn": app.config["SENTRY_KITSU_DSN"],
294
- "sampleRate": app.config["SENTRY_KITSU_SR"],
300
+ if config.SENTRY_KITSU_ENABLED:
301
+ conf["sentry"] = {
302
+ "dsn": config.SENTRY_KITSU_DSN,
303
+ "sampleRate": config.SENTRY_KITSU_SR,
295
304
  }
296
- return config
305
+ return conf
297
306
 
298
307
 
299
308
  class TestEventsResource(Resource):
@@ -1,13 +1,18 @@
1
- from flask_restful import Resource
1
+ from flask_restful import Resource, inputs
2
2
  from flask_jwt_extended import jwt_required
3
3
 
4
4
  from zou.app.mixin import ArgsMixin
5
- from zou.app.services import news_service, projects_service, user_service
5
+ from zou.app.services import (
6
+ news_service,
7
+ projects_service,
8
+ user_service,
9
+ persons_service,
10
+ )
6
11
  from zou.app.services.exception import NewsNotFoundException
7
12
  from zou.app.utils import permissions
8
13
 
9
14
 
10
- class NewsMixin:
15
+ class NewsMixin(ArgsMixin):
11
16
  def get_news(self, project_ids=[]):
12
17
  (
13
18
  only_preview,
@@ -16,12 +21,13 @@ class NewsMixin:
16
21
  episode_id,
17
22
  person_id,
18
23
  page,
19
- page_size,
24
+ limit,
20
25
  after,
21
26
  before,
22
27
  ) = self.get_arguments()
23
28
 
24
- user_service
29
+ current_user = persons_service.get_current_user_raw()
30
+
25
31
  after = self.parse_date_parameter(after)
26
32
  before = self.parse_date_parameter(before)
27
33
  result = news_service.get_last_news_for_project(
@@ -32,18 +38,21 @@ class NewsMixin:
32
38
  episode_id=episode_id,
33
39
  author_id=person_id,
34
40
  page=page,
35
- page_size=page_size,
41
+ limit=limit,
36
42
  after=after,
37
43
  before=before,
44
+ current_user=current_user,
38
45
  )
39
46
  stats = news_service.get_news_stats_for_project(
40
47
  project_ids=project_ids,
48
+ only_preview=only_preview,
41
49
  task_type_id=task_type_id,
42
50
  task_status_id=task_status_id,
43
51
  episode_id=episode_id,
44
52
  author_id=person_id,
45
53
  after=after,
46
54
  before=before,
55
+ current_user=current_user,
47
56
  )
48
57
  result["stats"] = stats
49
58
  return result
@@ -51,14 +60,19 @@ class NewsMixin:
51
60
  def get_arguments(self):
52
61
  args = self.get_args(
53
62
  [
54
- {"name": "only_preview", "default": False, "type": bool},
63
+ (
64
+ "only_preview",
65
+ False,
66
+ False,
67
+ inputs.boolean,
68
+ ),
55
69
  "task_type_id",
56
70
  "task_status_id",
57
71
  "person_id",
58
72
  "project_id",
59
73
  "episode_id",
60
74
  {"name": "page", "default": 1, "type": int},
61
- {"name": "page_size", "default": 50, "type": int},
75
+ {"name": "limit", "default": 50, "type": int},
62
76
  "after",
63
77
  "before",
64
78
  ],
@@ -70,7 +84,7 @@ class NewsMixin:
70
84
  args["episode_id"],
71
85
  args["person_id"],
72
86
  args["page"],
73
- args["page_size"],
87
+ args["limit"],
74
88
  args["after"],
75
89
  args["before"],
76
90
  )
@@ -106,7 +120,7 @@ class ProjectNewsResource(Resource, NewsMixin, ArgsMixin):
106
120
  type: integer
107
121
  x-example: 1
108
122
  - in: query
109
- name: page_size
123
+ name: limit
110
124
  type: integer
111
125
  x-example: 50
112
126
  - in: query
@@ -169,7 +183,7 @@ class NewsResource(Resource, NewsMixin, ArgsMixin):
169
183
  type: integer
170
184
  x-example: 1
171
185
  - in: query
172
- name: page_size
186
+ name: limit
173
187
  type: integer
174
188
  x-example: 50
175
189
  - in: query
@@ -7,7 +7,6 @@ from zou.app.blueprints.persons.resources import (
7
7
  DayOffForMonthResource,
8
8
  DesktopLoginsResource,
9
9
  InvitePersonResource,
10
- NewPersonResource,
11
10
  PersonMonthQuotaShotsResource,
12
11
  PersonWeekQuotaShotsResource,
13
12
  PersonDayQuotaShotsResource,
@@ -17,6 +16,7 @@ from zou.app.blueprints.persons.resources import (
17
16
  PersonDayTimeSpentsResource,
18
17
  PersonWeekDayOffResource,
19
18
  PersonYearDayOffResource,
19
+ PersonDayOffResource,
20
20
  PersonMonthDayOffResource,
21
21
  PresenceLogsResource,
22
22
  TimeSpentsResource,
@@ -33,7 +33,6 @@ from zou.app.blueprints.persons.resources import (
33
33
  )
34
34
 
35
35
  routes = [
36
- ("/data/persons/new", NewPersonResource),
37
36
  ("/data/persons/<person_id>/desktop-login-logs", DesktopLoginsResource),
38
37
  ("/data/persons/presence-logs/<month_date>", PresenceLogsResource),
39
38
  ("/data/persons/<person_id>/time-spents", TimeSpentsResource),
@@ -91,6 +90,10 @@ routes = [
91
90
  "/data/persons/<person_id>/day-offs/year/<year>",
92
91
  PersonYearDayOffResource,
93
92
  ),
93
+ (
94
+ "/data/persons/<person_id>/day-offs",
95
+ PersonDayOffResource,
96
+ ),
94
97
  ("/actions/persons/<person_id>/invite", InvitePersonResource),
95
98
  ("/actions/persons/<person_id>/departments/add", AddToDepartmentResource),
96
99
  (