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.
- zou/__init__.py +1 -1
- zou/app/__init__.py +10 -2
- zou/app/api.py +2 -0
- zou/app/blueprints/assets/__init__.py +22 -0
- zou/app/blueprints/assets/resources.py +241 -4
- zou/app/blueprints/auth/__init__.py +4 -0
- zou/app/blueprints/auth/resources.py +154 -22
- zou/app/blueprints/breakdown/resources.py +4 -4
- zou/app/blueprints/chats/__init__.py +22 -0
- zou/app/blueprints/chats/resources.py +199 -0
- zou/app/blueprints/comments/resources.py +36 -19
- zou/app/blueprints/crud/__init__.py +12 -0
- zou/app/blueprints/crud/attachment_file.py +14 -5
- zou/app/blueprints/crud/base.py +29 -28
- zou/app/blueprints/crud/chat.py +13 -0
- zou/app/blueprints/crud/chat_message.py +13 -0
- zou/app/blueprints/crud/comments.py +85 -29
- zou/app/blueprints/crud/custom_action.py +1 -1
- zou/app/blueprints/crud/day_off.py +47 -9
- zou/app/blueprints/crud/department.py +1 -25
- zou/app/blueprints/crud/entity.py +46 -5
- zou/app/blueprints/crud/entity_type.py +13 -1
- zou/app/blueprints/crud/event.py +1 -1
- zou/app/blueprints/crud/file_status.py +1 -1
- zou/app/blueprints/crud/metadata_descriptor.py +24 -10
- zou/app/blueprints/crud/organisation.py +22 -5
- zou/app/blueprints/crud/output_file.py +1 -1
- zou/app/blueprints/crud/output_type.py +1 -1
- zou/app/blueprints/crud/person.py +32 -24
- zou/app/blueprints/crud/playlist.py +1 -1
- zou/app/blueprints/crud/preview_background_file.py +6 -7
- zou/app/blueprints/crud/preview_file.py +1 -1
- zou/app/blueprints/crud/project.py +14 -6
- zou/app/blueprints/crud/project_status.py +1 -1
- zou/app/blueprints/crud/schedule_item.py +4 -2
- zou/app/blueprints/crud/software.py +1 -1
- zou/app/blueprints/crud/status_automation.py +1 -1
- zou/app/blueprints/crud/studio.py +33 -0
- zou/app/blueprints/crud/task.py +47 -3
- zou/app/blueprints/crud/task_status.py +1 -1
- zou/app/blueprints/crud/task_type.py +4 -4
- zou/app/blueprints/crud/working_file.py +4 -8
- zou/app/blueprints/events/resources.py +13 -12
- zou/app/blueprints/export/csv/assets.py +15 -6
- zou/app/blueprints/export/csv/edits.py +15 -5
- zou/app/blueprints/export/csv/playlists.py +1 -1
- zou/app/blueprints/export/csv/shots.py +15 -5
- zou/app/blueprints/export/csv/time_spents.py +1 -1
- zou/app/blueprints/files/resources.py +22 -23
- zou/app/blueprints/index/resources.py +38 -29
- zou/app/blueprints/news/resources.py +25 -11
- zou/app/blueprints/persons/__init__.py +5 -2
- zou/app/blueprints/persons/resources.py +126 -120
- zou/app/blueprints/previews/__init__.py +18 -8
- zou/app/blueprints/previews/resources.py +569 -328
- zou/app/blueprints/projects/resources.py +1 -1
- zou/app/blueprints/search/resources.py +18 -6
- zou/app/blueprints/shots/__init__.py +5 -0
- zou/app/blueprints/shots/resources.py +134 -4
- zou/app/blueprints/source/__init__.py +6 -6
- zou/app/blueprints/source/csv/assets.py +10 -3
- zou/app/blueprints/source/csv/base.py +1 -1
- zou/app/blueprints/source/csv/edits.py +10 -3
- zou/app/blueprints/source/csv/shots.py +10 -3
- zou/app/blueprints/source/{edl.py → otio.py} +84 -41
- zou/app/blueprints/tasks/__init__.py +3 -2
- zou/app/blueprints/tasks/resources.py +83 -52
- zou/app/blueprints/user/__init__.py +9 -0
- zou/app/blueprints/user/resources.py +170 -12
- zou/app/config.py +10 -0
- zou/app/mixin.py +6 -5
- zou/app/models/attachment_file.py +10 -4
- zou/app/models/base.py +18 -13
- zou/app/models/build_job.py +7 -4
- zou/app/models/chat.py +44 -0
- zou/app/models/chat_message.py +37 -0
- zou/app/models/comment.py +1 -0
- zou/app/models/day_off.py +3 -0
- zou/app/models/entity.py +4 -6
- zou/app/models/entity_type.py +2 -0
- zou/app/models/organisation.py +14 -15
- zou/app/models/person.py +6 -1
- zou/app/models/project.py +3 -0
- zou/app/models/search_filter.py +11 -0
- zou/app/models/search_filter_group.py +10 -0
- zou/app/models/serializer.py +17 -17
- zou/app/models/status_automation.py +2 -0
- zou/app/models/studio.py +13 -0
- zou/app/models/subscription.py +2 -2
- zou/app/models/task.py +6 -1
- zou/app/models/task_status.py +1 -0
- zou/app/models/task_type.py +1 -0
- zou/app/models/working_file.py +1 -1
- zou/app/services/assets_service.py +101 -14
- zou/app/services/auth_service.py +17 -44
- zou/app/services/breakdown_service.py +37 -5
- zou/app/services/chats_service.py +279 -0
- zou/app/services/comments_service.py +110 -65
- zou/app/services/concepts_service.py +4 -12
- zou/app/services/deletion_service.py +43 -30
- zou/app/services/edits_service.py +5 -11
- zou/app/services/emails_service.py +4 -4
- zou/app/services/entities_service.py +17 -2
- zou/app/services/events_service.py +12 -4
- zou/app/services/exception.py +5 -5
- zou/app/services/names_service.py +7 -2
- zou/app/services/news_service.py +17 -9
- zou/app/services/persons_service.py +38 -21
- zou/app/services/playlists_service.py +8 -7
- zou/app/services/preview_files_service.py +137 -10
- zou/app/services/projects_service.py +5 -14
- zou/app/services/shots_service.py +221 -49
- zou/app/services/sync_service.py +46 -42
- zou/app/services/tasks_service.py +185 -46
- zou/app/services/time_spents_service.py +67 -20
- zou/app/services/user_service.py +350 -107
- zou/app/stores/auth_tokens_store.py +2 -1
- zou/app/stores/file_store.py +18 -0
- zou/app/stores/publisher_store.py +7 -7
- zou/app/stores/queue_store.py +1 -0
- zou/app/swagger.py +36 -20
- zou/app/utils/cache.py +2 -0
- zou/app/utils/commands.py +104 -7
- zou/app/utils/csv_utils.py +1 -4
- zou/app/utils/date_helpers.py +33 -17
- zou/app/utils/dbhelpers.py +14 -1
- zou/app/utils/emails.py +2 -2
- zou/app/utils/fido.py +22 -0
- zou/app/utils/flask.py +1 -0
- zou/app/utils/query.py +54 -6
- zou/app/utils/redis.py +11 -0
- zou/app/utils/saml.py +51 -0
- zou/app/utils/string.py +2 -0
- zou/app/utils/thumbnail.py +4 -2
- zou/cli.py +76 -18
- zou/debug.py +4 -2
- zou/event_stream.py +122 -165
- zou/job_settings.py +1 -0
- zou/migrations/env.py +0 -0
- zou/migrations/utils/base.py +6 -6
- zou/migrations/versions/1bb55759146f_add_table_studio.py +67 -0
- zou/migrations/versions/1fab8c420678_add_attachments_to_message_chats.py +56 -0
- zou/migrations/versions/23122f290ca2_add_entity_chat_models.py +149 -0
- zou/migrations/versions/32f134ff1201_add_is_shared_flag_to_filters.py +33 -0
- zou/migrations/versions/57222395f2be_add_statusautomation_import_last_revision.py +41 -0
- zou/migrations/versions/59a7445a966c_add_entity_is_shared.py +41 -0
- zou/migrations/versions/5b980f0dc365_add_comment_links.py +35 -0
- zou/migrations/versions/680c64565f9d_for_searchfiltergroup_is_shared.py +35 -0
- zou/migrations/versions/8e67c183bed7_add_preference_fields.py +71 -0
- zou/migrations/versions/92b40d79ad3f_allow_message_attachments.py +38 -0
- zou/migrations/versions/971dbf5a0faf_add_short_name_for_asset_type_entity_.py +33 -0
- zou/migrations/versions/9b85c14fa8a7_add_day_off_new_columns.py +68 -0
- zou/migrations/versions/9d3bb33c6fc6_add_department_keys_to_filter_models.py +73 -0
- zou/migrations/versions/a252a094e977_add_descriptions_for_entities_tasks_and_.py +40 -0
- zou/migrations/versions/be56dc0fb760_for_is_shared_disallow_nullable.py +102 -0
- zou/migrations/versions/ca28796a2a62_add_is_done_field_to_the_task_model.py +108 -0
- zou/migrations/versions/f344b867a911_for_description_of_entity_task_working_.py +75 -0
- zou/remote/config_payload.py +2 -1
- zou/utils/movie.py +14 -4
- {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/METADATA +75 -69
- {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/RECORD +164 -135
- {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/WHEEL +1 -1
- {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/LICENSE +0 -0
- {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/entry_points.txt +0 -0
- {zou-0.19.14.dist-info → zou-0.20.11.dist-info}/top_level.txt +0 -0
|
@@ -13,14 +13,14 @@ from zou.app.services import (
|
|
|
13
13
|
index_service,
|
|
14
14
|
persons_service,
|
|
15
15
|
)
|
|
16
|
-
from zou.app.utils import permissions, auth
|
|
16
|
+
from zou.app.utils import permissions, auth, date_helpers
|
|
17
17
|
|
|
18
18
|
from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
|
|
19
19
|
|
|
20
20
|
from zou.app.mixin import ArgsMixin
|
|
21
21
|
|
|
22
22
|
from zou.app.services.exception import (
|
|
23
|
-
|
|
23
|
+
WrongParameterException,
|
|
24
24
|
PersonInProtectedAccounts,
|
|
25
25
|
)
|
|
26
26
|
|
|
@@ -52,7 +52,7 @@ class PersonsResource(BaseModelsResource):
|
|
|
52
52
|
for person in query.all()
|
|
53
53
|
]
|
|
54
54
|
|
|
55
|
-
def check_read_permissions(self):
|
|
55
|
+
def check_read_permissions(self, options=None):
|
|
56
56
|
return True
|
|
57
57
|
|
|
58
58
|
def check_create_permissions(self, data):
|
|
@@ -61,11 +61,9 @@ class PersonsResource(BaseModelsResource):
|
|
|
61
61
|
and data.get("active", True)
|
|
62
62
|
and persons_service.is_user_limit_reached()
|
|
63
63
|
):
|
|
64
|
-
raise
|
|
64
|
+
raise WrongParameterException(
|
|
65
65
|
"User limit reached.",
|
|
66
66
|
{
|
|
67
|
-
"error": True,
|
|
68
|
-
"message": "User limit reached.",
|
|
69
67
|
"limit": config.USER_LIMIT,
|
|
70
68
|
},
|
|
71
69
|
)
|
|
@@ -75,32 +73,34 @@ class PersonsResource(BaseModelsResource):
|
|
|
75
73
|
if "role" in data and data["role"] not in [
|
|
76
74
|
role for role, _ in ROLE_TYPES
|
|
77
75
|
]:
|
|
78
|
-
raise
|
|
76
|
+
raise WrongParameterException("Invalid role")
|
|
79
77
|
if "contract_type" in data and data["contract_type"] not in [
|
|
80
78
|
contract_type for contract_type, _ in CONTRACT_TYPES
|
|
81
79
|
]:
|
|
82
|
-
raise
|
|
80
|
+
raise WrongParameterException("Invalid contract_type")
|
|
83
81
|
if "two_factor_authentication" in data and data[
|
|
84
82
|
"two_factor_authentication"
|
|
85
83
|
] not in [
|
|
86
84
|
two_factor_authentication
|
|
87
85
|
for two_factor_authentication, _ in TWO_FACTOR_AUTHENTICATION_TYPES
|
|
88
86
|
]:
|
|
89
|
-
raise
|
|
87
|
+
raise WrongParameterException("Invalid two_factor_authentication")
|
|
90
88
|
|
|
91
89
|
if "expiration_date" in data and data["expiration_date"] is not None:
|
|
92
90
|
try:
|
|
93
91
|
if (
|
|
94
|
-
|
|
95
|
-
data["expiration_date"]
|
|
92
|
+
date_helpers.get_date_from_string(
|
|
93
|
+
data["expiration_date"]
|
|
96
94
|
).date()
|
|
97
95
|
< datetime.date.today()
|
|
98
96
|
):
|
|
99
|
-
raise
|
|
97
|
+
raise WrongParameterException(
|
|
100
98
|
"Expiration date can't be in the past."
|
|
101
99
|
)
|
|
100
|
+
except WrongParameterException:
|
|
101
|
+
raise
|
|
102
102
|
except:
|
|
103
|
-
raise
|
|
103
|
+
raise WrongParameterException("Expiration date is not valid.")
|
|
104
104
|
return data
|
|
105
105
|
|
|
106
106
|
def update_data(self, data):
|
|
@@ -151,22 +151,23 @@ class PersonResource(BaseModelResource, ArgsMixin):
|
|
|
151
151
|
data.pop("is_generated_from_ldap", None)
|
|
152
152
|
data.pop("ldap_uid", None)
|
|
153
153
|
data.pop("last_presence", None)
|
|
154
|
+
data.pop("studio_id", None)
|
|
154
155
|
|
|
155
156
|
if "role" in data and data["role"] not in [
|
|
156
157
|
role for role, _ in ROLE_TYPES
|
|
157
158
|
]:
|
|
158
|
-
raise
|
|
159
|
+
raise WrongParameterException("Invalid role")
|
|
159
160
|
if "contract_type" in data and data["contract_type"] not in [
|
|
160
161
|
contract_type for contract_type, _ in CONTRACT_TYPES
|
|
161
162
|
]:
|
|
162
|
-
raise
|
|
163
|
+
raise WrongParameterException("Invalid contract_type")
|
|
163
164
|
if "two_factor_authentication" in data and data[
|
|
164
165
|
"two_factor_authentication"
|
|
165
166
|
] not in [
|
|
166
167
|
two_factor_authentication
|
|
167
168
|
for two_factor_authentication, _ in TWO_FACTOR_AUTHENTICATION_TYPES
|
|
168
169
|
]:
|
|
169
|
-
raise
|
|
170
|
+
raise WrongParameterException("Invalid two_factor_authentication")
|
|
170
171
|
|
|
171
172
|
if "expiration_date" in data and data["expiration_date"] is not None:
|
|
172
173
|
try:
|
|
@@ -176,11 +177,13 @@ class PersonResource(BaseModelResource, ArgsMixin):
|
|
|
176
177
|
).date()
|
|
177
178
|
< datetime.date.today()
|
|
178
179
|
):
|
|
179
|
-
raise
|
|
180
|
+
raise WrongParameterException(
|
|
180
181
|
"Expiration date can't be in the past."
|
|
181
182
|
)
|
|
183
|
+
except WrongParameterException:
|
|
184
|
+
raise
|
|
182
185
|
except:
|
|
183
|
-
raise
|
|
186
|
+
raise WrongParameterException("Expiration date is not valid.")
|
|
184
187
|
return data
|
|
185
188
|
|
|
186
189
|
def check_delete_permissions(self, instance_dict):
|
|
@@ -203,14 +206,19 @@ class PersonResource(BaseModelResource, ArgsMixin):
|
|
|
203
206
|
and not data.get("is_bot", False)
|
|
204
207
|
and persons_service.is_user_limit_reached()
|
|
205
208
|
):
|
|
206
|
-
raise
|
|
209
|
+
raise WrongParameterException("User limit reached.")
|
|
207
210
|
if (
|
|
208
|
-
|
|
209
|
-
and instance_dict["
|
|
211
|
+
instance_dict["email"] in config.PROTECTED_ACCOUNTS
|
|
212
|
+
and instance_dict["id"] != persons_service.get_current_user()["id"]
|
|
210
213
|
):
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
+
message = None
|
|
215
|
+
if data.get("active") is False:
|
|
216
|
+
message = "Can't set this person as inactive it's a protected account."
|
|
217
|
+
elif data.get("role") is not None:
|
|
218
|
+
message = "Can't change the role of this person it's a protected account."
|
|
219
|
+
|
|
220
|
+
if message is not None:
|
|
221
|
+
raise PersonInProtectedAccounts(message)
|
|
214
222
|
return data
|
|
215
223
|
|
|
216
224
|
def post_update(self, instance_dict, data):
|
|
@@ -9,7 +9,7 @@ class PlaylistsResource(BaseModelsResource):
|
|
|
9
9
|
def __init__(self):
|
|
10
10
|
BaseModelsResource.__init__(self, Playlist)
|
|
11
11
|
|
|
12
|
-
def check_read_permissions(self):
|
|
12
|
+
def check_read_permissions(self, options=None):
|
|
13
13
|
return True
|
|
14
14
|
|
|
15
15
|
def check_create_permissions(self, playlist):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from zou.app.models.preview_background_file import PreviewBackgroundFile
|
|
2
|
-
from zou.app.services.exception import
|
|
3
|
-
from zou.app.services import files_service
|
|
2
|
+
from zou.app.services.exception import WrongParameterException
|
|
3
|
+
from zou.app.services import files_service, deletion_service
|
|
4
4
|
|
|
5
5
|
from zou.app.blueprints.crud.base import BaseModelResource, BaseModelsResource
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ class PreviewBackgroundFilesResource(BaseModelsResource):
|
|
|
9
9
|
def __init__(self):
|
|
10
10
|
BaseModelsResource.__init__(self, PreviewBackgroundFile)
|
|
11
11
|
|
|
12
|
-
def check_read_permissions(self):
|
|
12
|
+
def check_read_permissions(self, options=None):
|
|
13
13
|
return True
|
|
14
14
|
|
|
15
15
|
def update_data(self, data):
|
|
@@ -17,7 +17,7 @@ class PreviewBackgroundFilesResource(BaseModelsResource):
|
|
|
17
17
|
name = data.get("name", None)
|
|
18
18
|
preview_background_file = PreviewBackgroundFile.get_by(name=name)
|
|
19
19
|
if preview_background_file is not None:
|
|
20
|
-
raise
|
|
20
|
+
raise WrongParameterException(
|
|
21
21
|
"A preview background file with similar name already exists"
|
|
22
22
|
)
|
|
23
23
|
return data
|
|
@@ -44,7 +44,7 @@ class PreviewBackgroundFileResource(BaseModelResource):
|
|
|
44
44
|
if preview_background_file is not None and instance_id != str(
|
|
45
45
|
preview_background_file.id
|
|
46
46
|
):
|
|
47
|
-
raise
|
|
47
|
+
raise WrongParameterException(
|
|
48
48
|
"A preview background file with similar name already exists"
|
|
49
49
|
)
|
|
50
50
|
return data
|
|
@@ -58,7 +58,6 @@ class PreviewBackgroundFileResource(BaseModelResource):
|
|
|
58
58
|
return instance_dict
|
|
59
59
|
|
|
60
60
|
def post_delete(self, instance_dict):
|
|
61
|
-
|
|
62
|
-
# deletion_service.clear_preview_background_files(instance_dict["id"])
|
|
61
|
+
deletion_service.clear_preview_background_files(instance_dict["id"])
|
|
63
62
|
files_service.clear_preview_background_file_cache(instance_dict["id"])
|
|
64
63
|
return instance_dict
|
|
@@ -18,7 +18,7 @@ from zou.app.utils import events, permissions, fields
|
|
|
18
18
|
|
|
19
19
|
from zou.app.blueprints.crud.base import BaseModelResource, BaseModelsResource
|
|
20
20
|
|
|
21
|
-
from zou.app.services.exception import
|
|
21
|
+
from zou.app.services.exception import WrongParameterException
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class ProjectsResource(BaseModelsResource):
|
|
@@ -31,7 +31,7 @@ class ProjectsResource(BaseModelsResource):
|
|
|
31
31
|
else:
|
|
32
32
|
return query.filter(user_service.build_related_projects_filter())
|
|
33
33
|
|
|
34
|
-
def check_read_permissions(self):
|
|
34
|
+
def check_read_permissions(self, options=None):
|
|
35
35
|
return True
|
|
36
36
|
|
|
37
37
|
def check_creation_integrity(self, data):
|
|
@@ -44,7 +44,7 @@ class ProjectsResource(BaseModelsResource):
|
|
|
44
44
|
if data["production_style"] not in [
|
|
45
45
|
type_name for type_name, _ in PROJECT_STYLES
|
|
46
46
|
]:
|
|
47
|
-
raise
|
|
47
|
+
raise WrongParameterException("Invalid production_style")
|
|
48
48
|
return True
|
|
49
49
|
|
|
50
50
|
def update_data(self, data):
|
|
@@ -71,7 +71,9 @@ class ProjectsResource(BaseModelsResource):
|
|
|
71
71
|
or data["preview_background_file_id"]
|
|
72
72
|
not in data["preview_background_files_ids"]
|
|
73
73
|
):
|
|
74
|
-
raise
|
|
74
|
+
raise WrongParameterException(
|
|
75
|
+
"Invalid preview_background_file_id"
|
|
76
|
+
)
|
|
75
77
|
return data
|
|
76
78
|
|
|
77
79
|
def post_creation(self, project):
|
|
@@ -131,7 +133,9 @@ class ProjectResource(BaseModelResource, ArgsMixin):
|
|
|
131
133
|
data["preview_background_file_id"]
|
|
132
134
|
not in preview_background_files_ids
|
|
133
135
|
):
|
|
134
|
-
raise
|
|
136
|
+
raise WrongParameterException(
|
|
137
|
+
"Invalid preview_background_file_id"
|
|
138
|
+
)
|
|
135
139
|
|
|
136
140
|
return data
|
|
137
141
|
|
|
@@ -167,7 +171,7 @@ class ProjectResource(BaseModelResource, ArgsMixin):
|
|
|
167
171
|
if data["production_style"] not in [
|
|
168
172
|
type_name for type_name, _ in PROJECT_STYLES
|
|
169
173
|
]:
|
|
170
|
-
raise
|
|
174
|
+
raise WrongParameterException("Invalid production_style")
|
|
171
175
|
return data
|
|
172
176
|
|
|
173
177
|
@jwt_required()
|
|
@@ -203,6 +207,8 @@ class ProjectTaskTypeLinksResource(Resource, ArgsMixin):
|
|
|
203
207
|
]
|
|
204
208
|
)
|
|
205
209
|
|
|
210
|
+
user_service.check_manager_project_access(args["project_id"])
|
|
211
|
+
|
|
206
212
|
task_type_link = projects_service.create_project_task_type_link(
|
|
207
213
|
args["project_id"],
|
|
208
214
|
args["task_type_id"],
|
|
@@ -230,6 +236,8 @@ class ProjectTaskStatusLinksResource(Resource, ArgsMixin):
|
|
|
230
236
|
]
|
|
231
237
|
)
|
|
232
238
|
|
|
239
|
+
user_service.check_manager_project_access(args["project_id"])
|
|
240
|
+
|
|
233
241
|
task_status_link = projects_service.create_project_task_status_link(
|
|
234
242
|
args["project_id"],
|
|
235
243
|
args["task_status_id"],
|
|
@@ -3,7 +3,7 @@ from zou.app.models.schedule_item import ScheduleItem
|
|
|
3
3
|
from zou.app.blueprints.crud.base import BaseModelResource, BaseModelsResource
|
|
4
4
|
|
|
5
5
|
from zou.app.services import user_service
|
|
6
|
-
from zou.app.services.exception import
|
|
6
|
+
from zou.app.services.exception import WrongParameterException
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class ScheduleItemsResource(BaseModelsResource):
|
|
@@ -17,7 +17,9 @@ class ScheduleItemsResource(BaseModelsResource):
|
|
|
17
17
|
object_id=data.get("object_id", None),
|
|
18
18
|
)
|
|
19
19
|
if schedule_item is not None:
|
|
20
|
-
raise
|
|
20
|
+
raise WrongParameterException(
|
|
21
|
+
"A similar schedule item already exists"
|
|
22
|
+
)
|
|
21
23
|
return schedule_item
|
|
22
24
|
|
|
23
25
|
|
|
@@ -13,7 +13,7 @@ class StatusAutomationsResource(BaseModelsResource):
|
|
|
13
13
|
def __init__(self):
|
|
14
14
|
BaseModelsResource.__init__(self, StatusAutomation)
|
|
15
15
|
|
|
16
|
-
def check_read_permissions(self):
|
|
16
|
+
def check_read_permissions(self, options=None):
|
|
17
17
|
user_service.block_access_to_vendor()
|
|
18
18
|
return True
|
|
19
19
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from zou.app.models.studio import Studio
|
|
2
|
+
|
|
3
|
+
from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
|
|
4
|
+
|
|
5
|
+
from zou.app.services import tasks_service
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class StudiosResource(BaseModelsResource):
|
|
9
|
+
def __init__(self):
|
|
10
|
+
BaseModelsResource.__init__(self, Studio)
|
|
11
|
+
|
|
12
|
+
def check_read_permissions(self, options=None):
|
|
13
|
+
return True
|
|
14
|
+
|
|
15
|
+
def post_creation(self, instance):
|
|
16
|
+
tasks_service.clear_studio_cache(str(instance.id))
|
|
17
|
+
return instance.serialize()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class StudioResource(BaseModelResource):
|
|
21
|
+
def __init__(self):
|
|
22
|
+
BaseModelResource.__init__(self, Studio)
|
|
23
|
+
|
|
24
|
+
def check_read_permissions(self, instance):
|
|
25
|
+
return True
|
|
26
|
+
|
|
27
|
+
def post_update(self, instance_dict, data):
|
|
28
|
+
tasks_service.clear_studio_cache(instance_dict["id"])
|
|
29
|
+
return instance_dict
|
|
30
|
+
|
|
31
|
+
def post_delete(self, instance_dict):
|
|
32
|
+
tasks_service.clear_studio_cache(instance_dict["id"])
|
|
33
|
+
return instance_dict
|
zou/app/blueprints/crud/task.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
from flask import request, current_app
|
|
2
2
|
from flask_jwt_extended import jwt_required
|
|
3
3
|
|
|
4
|
+
from sqlalchemy.orm import aliased
|
|
4
5
|
from sqlalchemy.exc import IntegrityError
|
|
6
|
+
|
|
5
7
|
from zou.app.mixin import ArgsMixin
|
|
8
|
+
from zou.app.models.entity import Entity
|
|
6
9
|
from zou.app.models.person import Person
|
|
7
10
|
from zou.app.models.project import Project
|
|
8
11
|
from zou.app.models.task import Task
|
|
@@ -21,11 +24,11 @@ from zou.app.services.exception import WrongTaskTypeForEntityException
|
|
|
21
24
|
from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
|
|
22
25
|
|
|
23
26
|
|
|
24
|
-
class TasksResource(BaseModelsResource):
|
|
27
|
+
class TasksResource(BaseModelsResource, ArgsMixin):
|
|
25
28
|
def __init__(self):
|
|
26
29
|
BaseModelsResource.__init__(self, Task)
|
|
27
30
|
|
|
28
|
-
def check_read_permissions(self):
|
|
31
|
+
def check_read_permissions(self, options=None):
|
|
29
32
|
return True
|
|
30
33
|
|
|
31
34
|
def add_project_permission_filter(self, query):
|
|
@@ -37,6 +40,43 @@ class TasksResource(BaseModelsResource):
|
|
|
37
40
|
)
|
|
38
41
|
return query
|
|
39
42
|
|
|
43
|
+
def build_filters(self, options):
|
|
44
|
+
(
|
|
45
|
+
many_join_filter,
|
|
46
|
+
in_filter,
|
|
47
|
+
name_filter,
|
|
48
|
+
criterions,
|
|
49
|
+
) = super().build_filters(options)
|
|
50
|
+
if "project_id" in criterions:
|
|
51
|
+
del criterions["project_id"]
|
|
52
|
+
if "episode_id" in criterions:
|
|
53
|
+
del criterions["episode_id"]
|
|
54
|
+
return (
|
|
55
|
+
many_join_filter,
|
|
56
|
+
in_filter,
|
|
57
|
+
name_filter,
|
|
58
|
+
criterions,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def apply_filters(self, query, options):
|
|
62
|
+
query = super().apply_filters(query, options)
|
|
63
|
+
|
|
64
|
+
project_id = options.get("project_id", None)
|
|
65
|
+
episode_id = options.get("episode_id", None)
|
|
66
|
+
if episode_id is not None:
|
|
67
|
+
Sequence = aliased(Entity)
|
|
68
|
+
query = (
|
|
69
|
+
query.join(Entity, Task.entity_id == Entity.id)
|
|
70
|
+
.join(Sequence, Entity.parent_id == Sequence.id)
|
|
71
|
+
.filter(Sequence.parent_id == episode_id)
|
|
72
|
+
)
|
|
73
|
+
elif project_id is not None:
|
|
74
|
+
query = query.join(Entity, Task.entity_id == Entity.id).filter(
|
|
75
|
+
Entity.project_id == project_id
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return query
|
|
79
|
+
|
|
40
80
|
def post(self):
|
|
41
81
|
"""
|
|
42
82
|
Create a task with data given in the request body. JSON format is
|
|
@@ -74,8 +114,12 @@ class TasksResource(BaseModelsResource):
|
|
|
74
114
|
if assignees is not None:
|
|
75
115
|
instance.assignees = persons
|
|
76
116
|
instance.save()
|
|
117
|
+
self.emit_create_event(instance.serialize())
|
|
77
118
|
|
|
78
|
-
return
|
|
119
|
+
return (
|
|
120
|
+
tasks_service.get_task(str(instance.id), relations=True),
|
|
121
|
+
201,
|
|
122
|
+
)
|
|
79
123
|
|
|
80
124
|
except TypeError as exception:
|
|
81
125
|
current_app.logger.error(str(exception), exc_info=1)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from zou.app.models.task_type import TaskType
|
|
2
|
-
from zou.app.services.exception import
|
|
2
|
+
from zou.app.services.exception import WrongParameterException
|
|
3
3
|
from zou.app.services import tasks_service
|
|
4
4
|
|
|
5
5
|
from zou.app.blueprints.crud.base import BaseModelResource, BaseModelsResource
|
|
@@ -9,7 +9,7 @@ class TaskTypesResource(BaseModelsResource):
|
|
|
9
9
|
def __init__(self):
|
|
10
10
|
BaseModelsResource.__init__(self, TaskType)
|
|
11
11
|
|
|
12
|
-
def check_read_permissions(self):
|
|
12
|
+
def check_read_permissions(self, options=None):
|
|
13
13
|
return True
|
|
14
14
|
|
|
15
15
|
def update_data(self, data):
|
|
@@ -17,7 +17,7 @@ class TaskTypesResource(BaseModelsResource):
|
|
|
17
17
|
name = data.get("name", None)
|
|
18
18
|
task_type = TaskType.get_by(name=name)
|
|
19
19
|
if task_type is not None:
|
|
20
|
-
raise
|
|
20
|
+
raise WrongParameterException(
|
|
21
21
|
"A task type with similar name already exists"
|
|
22
22
|
)
|
|
23
23
|
return data
|
|
@@ -40,7 +40,7 @@ class TaskTypeResource(BaseModelResource):
|
|
|
40
40
|
if name is not None:
|
|
41
41
|
task_type = TaskType.get_by(name=name)
|
|
42
42
|
if task_type is not None and instance_id != str(task_type.id):
|
|
43
|
-
raise
|
|
43
|
+
raise WrongParameterException(
|
|
44
44
|
"A task type with similar name already exists"
|
|
45
45
|
)
|
|
46
46
|
return data
|
|
@@ -8,7 +8,7 @@ from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
|
|
|
8
8
|
from zou.app.models.entity import Entity
|
|
9
9
|
from zou.app.models.project import Project
|
|
10
10
|
from zou.app.models.working_file import WorkingFile
|
|
11
|
-
from zou.app.services import user_service,
|
|
11
|
+
from zou.app.services import user_service, files_service
|
|
12
12
|
from zou.app.utils import permissions
|
|
13
13
|
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@ class WorkingFilesResource(BaseModelsResource):
|
|
|
16
16
|
def __init__(self):
|
|
17
17
|
BaseModelsResource.__init__(self, WorkingFile)
|
|
18
18
|
|
|
19
|
-
def check_read_permissions(self):
|
|
19
|
+
def check_read_permissions(self, options=None):
|
|
20
20
|
"""
|
|
21
21
|
Overriding so that people without admin credentials can still access
|
|
22
22
|
this resource.
|
|
@@ -46,16 +46,12 @@ class WorkingFileResource(BaseModelResource):
|
|
|
46
46
|
|
|
47
47
|
def check_read_permissions(self, instance):
|
|
48
48
|
working_file = files_service.get_working_file(instance["id"])
|
|
49
|
-
|
|
50
|
-
user_service.check_project_access(task["project_id"])
|
|
51
|
-
user_service.check_entity_access(task["entity_id"])
|
|
49
|
+
user_service.check_task_access(working_file["task_id"])
|
|
52
50
|
return True
|
|
53
51
|
|
|
54
52
|
def check_update_permissions(self, instance, data):
|
|
55
53
|
working_file = files_service.get_working_file(instance["id"])
|
|
56
|
-
|
|
57
|
-
user_service.check_project_access(task["project_id"])
|
|
58
|
-
user_service.check_entity_access(task["entity_id"])
|
|
54
|
+
user_service.check_task_access(working_file["task_id"])
|
|
59
55
|
return True
|
|
60
56
|
|
|
61
57
|
@jwt_required()
|
|
@@ -2,7 +2,7 @@ from flask_restful import Resource
|
|
|
2
2
|
from flask_jwt_extended import jwt_required
|
|
3
3
|
|
|
4
4
|
from zou.app.mixin import ArgsMixin
|
|
5
|
-
from zou.app.utils import fields, permissions
|
|
5
|
+
from zou.app.utils import fields, permissions, date_helpers
|
|
6
6
|
|
|
7
7
|
from zou.app.services import events_service
|
|
8
8
|
from zou.app.services.exception import WrongParameterException
|
|
@@ -32,7 +32,7 @@ class EventsResource(Resource, ArgsMixin):
|
|
|
32
32
|
type: boolean
|
|
33
33
|
default: False
|
|
34
34
|
- in: query
|
|
35
|
-
name:
|
|
35
|
+
name: limit
|
|
36
36
|
type: integer
|
|
37
37
|
default: 100
|
|
38
38
|
x-example: 100
|
|
@@ -50,17 +50,19 @@ class EventsResource(Resource, ArgsMixin):
|
|
|
50
50
|
("after", None, False),
|
|
51
51
|
("before", None, False),
|
|
52
52
|
("only_files", False, False),
|
|
53
|
-
("
|
|
53
|
+
("limit", 100, False),
|
|
54
54
|
("project_id", None, False),
|
|
55
|
+
("name", None, False),
|
|
55
56
|
],
|
|
56
57
|
)
|
|
57
58
|
|
|
58
59
|
permissions.check_manager_permissions()
|
|
59
60
|
before = self.parse_date_parameter(args["before"])
|
|
60
61
|
after = self.parse_date_parameter(args["after"])
|
|
61
|
-
|
|
62
|
+
limit = args["limit"]
|
|
62
63
|
only_files = args["only_files"] == "true"
|
|
63
64
|
project_id = args.get("project_id", None)
|
|
65
|
+
name = args["name"]
|
|
64
66
|
if project_id is not None and not fields.is_valid_id(project_id):
|
|
65
67
|
raise WrongParameterException(
|
|
66
68
|
"The project_id parameter is not a valid id"
|
|
@@ -69,9 +71,10 @@ class EventsResource(Resource, ArgsMixin):
|
|
|
69
71
|
return events_service.get_last_events(
|
|
70
72
|
after=after,
|
|
71
73
|
before=before,
|
|
72
|
-
|
|
74
|
+
limit=limit,
|
|
73
75
|
only_files=only_files,
|
|
74
76
|
project_id=project_id,
|
|
77
|
+
name=name,
|
|
75
78
|
)
|
|
76
79
|
|
|
77
80
|
|
|
@@ -90,20 +93,18 @@ class LoginLogsResource(Resource, ArgsMixin):
|
|
|
90
93
|
format: date
|
|
91
94
|
x-example: "2022-07-12T00:00:00"
|
|
92
95
|
- in: query
|
|
93
|
-
name:
|
|
96
|
+
name: limit
|
|
94
97
|
type: integer
|
|
95
98
|
x-example: 100
|
|
96
99
|
responses:
|
|
97
100
|
200:
|
|
98
101
|
description: All login logs
|
|
99
102
|
"""
|
|
100
|
-
args = self.get_args(["before", ("
|
|
103
|
+
args = self.get_args(["before", ("limit", 100)])
|
|
101
104
|
|
|
102
105
|
permissions.check_manager_permissions()
|
|
103
106
|
before = None
|
|
104
107
|
if args["before"] is not None:
|
|
105
|
-
before =
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
page_size = args["page_size"]
|
|
109
|
-
return events_service.get_last_login_logs(before, page_size)
|
|
108
|
+
before = date_helpers.get_datetime_from_string(args["before"])
|
|
109
|
+
limit = args["limit"]
|
|
110
|
+
return events_service.get_last_login_logs(before, limit)
|
|
@@ -65,7 +65,7 @@ class AssetsCsvExport(Resource):
|
|
|
65
65
|
def build_headers(self, metadata_infos, validation_columns):
|
|
66
66
|
headers = ["Project", "Type", "Name", "Description", "Time Spent"]
|
|
67
67
|
|
|
68
|
-
metadata_headers = [name for (name, _) in metadata_infos]
|
|
68
|
+
metadata_headers = [name for (name, _, _) in metadata_infos]
|
|
69
69
|
|
|
70
70
|
validation_assignations_columns = []
|
|
71
71
|
for validation_column in validation_columns:
|
|
@@ -97,10 +97,15 @@ class AssetsCsvExport(Resource):
|
|
|
97
97
|
for person_id in task["assignees"]
|
|
98
98
|
]
|
|
99
99
|
)
|
|
100
|
-
|
|
101
|
-
for _, field_name in metadata_infos:
|
|
102
|
-
result_metadata =
|
|
103
|
-
|
|
100
|
+
result_data = result.get("data", {}) or {}
|
|
101
|
+
for _, field_name, data_type in metadata_infos:
|
|
102
|
+
result_metadata = result_data.get(field_name, "")
|
|
103
|
+
if data_type == "boolean":
|
|
104
|
+
row.append(
|
|
105
|
+
"true" if result_metadata.lower() == "true" else "false"
|
|
106
|
+
)
|
|
107
|
+
else:
|
|
108
|
+
row.append(result_metadata)
|
|
104
109
|
|
|
105
110
|
for column in validation_columns:
|
|
106
111
|
if column in task_map:
|
|
@@ -153,7 +158,11 @@ class AssetsCsvExport(Resource):
|
|
|
153
158
|
]
|
|
154
159
|
|
|
155
160
|
columns = [
|
|
156
|
-
(
|
|
161
|
+
(
|
|
162
|
+
descriptor["name"],
|
|
163
|
+
descriptor["field_name"],
|
|
164
|
+
descriptor["data_type"],
|
|
165
|
+
)
|
|
157
166
|
for descriptor in descriptors
|
|
158
167
|
]
|
|
159
168
|
|