zou 0.19.69__py3-none-any.whl → 0.19.71__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 +1 -1
- zou/app/blueprints/auth/resources.py +19 -15
- zou/app/blueprints/breakdown/resources.py +4 -4
- zou/app/blueprints/crud/base.py +4 -1
- zou/app/blueprints/crud/comments.py +0 -13
- zou/app/blueprints/crud/event.py +1 -1
- zou/app/blueprints/crud/metadata_descriptor.py +9 -9
- zou/app/blueprints/crud/organisation.py +16 -1
- zou/app/blueprints/events/resources.py +8 -8
- zou/app/blueprints/export/csv/assets.py +15 -6
- zou/app/blueprints/export/csv/edits.py +15 -5
- zou/app/blueprints/export/csv/shots.py +15 -5
- zou/app/blueprints/index/resources.py +2 -0
- zou/app/blueprints/news/resources.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/tasks/resources.py +7 -1
- zou/app/models/organisation.py +11 -19
- zou/app/models/serializer.py +17 -17
- zou/app/services/events_service.py +4 -4
- zou/app/services/news_service.py +8 -8
- zou/app/services/persons_service.py +5 -4
- zou/app/services/projects_service.py +1 -1
- zou/app/services/shots_service.py +1 -1
- zou/app/services/sync_service.py +4 -4
- zou/app/services/tasks_service.py +4 -2
- zou/app/services/user_service.py +21 -36
- zou/app/utils/commands.py +4 -4
- zou/app/utils/csv_utils.py +1 -4
- zou/cli.py +4 -4
- zou/remote/config_payload.py +2 -1
- {zou-0.19.69.dist-info → zou-0.19.71.dist-info}/METADATA +6 -6
- {zou-0.19.69.dist-info → zou-0.19.71.dist-info}/RECORD +40 -40
- {zou-0.19.69.dist-info → zou-0.19.71.dist-info}/LICENSE +0 -0
- {zou-0.19.69.dist-info → zou-0.19.71.dist-info}/WHEEL +0 -0
- {zou-0.19.69.dist-info → zou-0.19.71.dist-info}/entry_points.txt +0 -0
- {zou-0.19.69.dist-info → zou-0.19.71.dist-info}/top_level.txt +0 -0
zou/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.19.
|
|
1
|
+
__version__ = "0.19.71"
|
zou/app/__init__.py
CHANGED
|
@@ -14,6 +14,7 @@ from flask_jwt_extended import (
|
|
|
14
14
|
set_access_cookies,
|
|
15
15
|
set_refresh_cookies,
|
|
16
16
|
unset_jwt_cookies,
|
|
17
|
+
unset_refresh_cookies,
|
|
17
18
|
get_jwt,
|
|
18
19
|
)
|
|
19
20
|
|
|
@@ -78,7 +79,9 @@ class AuthenticatedResource(Resource):
|
|
|
78
79
|
description: Person not found
|
|
79
80
|
"""
|
|
80
81
|
person = persons_service.get_current_user(relations=True)
|
|
81
|
-
organisation = persons_service.get_organisation(
|
|
82
|
+
organisation = persons_service.get_organisation(
|
|
83
|
+
sensitive=permissions.has_admin_permissions()
|
|
84
|
+
)
|
|
82
85
|
return {
|
|
83
86
|
"authenticated": True,
|
|
84
87
|
"user": person,
|
|
@@ -227,15 +230,21 @@ class LoginResource(Resource, ArgsMixin):
|
|
|
227
230
|
"HTTP_X_REAL_IP", request.remote_addr
|
|
228
231
|
)
|
|
229
232
|
|
|
233
|
+
organisation = persons_service.get_organisation(
|
|
234
|
+
sensitive=user["role"] != "admin"
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
response = jsonify(
|
|
238
|
+
{
|
|
239
|
+
"user": user,
|
|
240
|
+
"organisation": organisation,
|
|
241
|
+
"login": True,
|
|
242
|
+
"access_token": access_token,
|
|
243
|
+
"refresh_token": refresh_token,
|
|
244
|
+
}
|
|
245
|
+
)
|
|
246
|
+
|
|
230
247
|
if is_from_browser(request.user_agent):
|
|
231
|
-
organisation = persons_service.get_organisation()
|
|
232
|
-
response = jsonify(
|
|
233
|
-
{
|
|
234
|
-
"user": user,
|
|
235
|
-
"organisation": organisation,
|
|
236
|
-
"login": True,
|
|
237
|
-
}
|
|
238
|
-
)
|
|
239
248
|
set_access_cookies(response, access_token)
|
|
240
249
|
set_refresh_cookies(response, refresh_token)
|
|
241
250
|
events_service.create_login_log(user["id"], ip_address, "web")
|
|
@@ -243,12 +252,6 @@ class LoginResource(Resource, ArgsMixin):
|
|
|
243
252
|
events_service.create_login_log(
|
|
244
253
|
user["id"], ip_address, "script"
|
|
245
254
|
)
|
|
246
|
-
response = {
|
|
247
|
-
"login": True,
|
|
248
|
-
"user": user,
|
|
249
|
-
"access_token": access_token,
|
|
250
|
-
"refresh_token": refresh_token,
|
|
251
|
-
}
|
|
252
255
|
current_app.logger.info(f"User {email} is logged in.")
|
|
253
256
|
return response
|
|
254
257
|
except WrongUserException:
|
|
@@ -386,6 +389,7 @@ class RefreshTokenResource(Resource):
|
|
|
386
389
|
if is_from_browser(request.user_agent):
|
|
387
390
|
response = jsonify({"refresh": True})
|
|
388
391
|
set_access_cookies(response, access_token)
|
|
392
|
+
unset_refresh_cookies(response)
|
|
389
393
|
else:
|
|
390
394
|
return {"access_token": access_token}
|
|
391
395
|
|
|
@@ -398,14 +398,14 @@ class ProjectEntityLinksResource(Resource, ArgsMixin):
|
|
|
398
398
|
type: string
|
|
399
399
|
format: Number
|
|
400
400
|
x-example: 2
|
|
401
|
-
- in:
|
|
402
|
-
name:
|
|
401
|
+
- in: query
|
|
402
|
+
name: limit
|
|
403
403
|
required: False
|
|
404
404
|
type: string
|
|
405
405
|
format: Number
|
|
406
406
|
x-example: 100
|
|
407
|
-
- in:
|
|
408
|
-
name:
|
|
407
|
+
- in: query
|
|
408
|
+
name: cursor_created_at
|
|
409
409
|
required: False
|
|
410
410
|
type: string
|
|
411
411
|
format: Datetime
|
zou/app/blueprints/crud/base.py
CHANGED
|
@@ -26,7 +26,10 @@ class BaseModelsResource(Resource, ArgsMixin):
|
|
|
26
26
|
if query is None:
|
|
27
27
|
query = self.model.query
|
|
28
28
|
|
|
29
|
-
return self.
|
|
29
|
+
return self.serialize_list(query.all(), relations=relations)
|
|
30
|
+
|
|
31
|
+
def serialize_list(self, entries, relations=False):
|
|
32
|
+
return self.model.serialize_list(entries, relations=relations)
|
|
30
33
|
|
|
31
34
|
def paginated_entries(self, query, page, limit=None, relations=False):
|
|
32
35
|
total = query.count()
|
|
@@ -22,19 +22,6 @@ class CommentsResource(BaseModelsResource):
|
|
|
22
22
|
def __init__(self):
|
|
23
23
|
BaseModelsResource.__init__(self, Comment)
|
|
24
24
|
|
|
25
|
-
def check_read_permissions(self, options=None):
|
|
26
|
-
if options is not None:
|
|
27
|
-
if "project_id" in options:
|
|
28
|
-
user_service.check_project_access(options["project_id"])
|
|
29
|
-
if (
|
|
30
|
-
permissions.has_vendor_permissions()
|
|
31
|
-
or permissions.has_client_permissions()
|
|
32
|
-
):
|
|
33
|
-
raise permissions.PermissionDenied
|
|
34
|
-
else:
|
|
35
|
-
return True
|
|
36
|
-
return permissions.check_admin_permissions()
|
|
37
|
-
|
|
38
25
|
|
|
39
26
|
class CommentResource(BaseModelResource):
|
|
40
27
|
def __init__(self):
|
zou/app/blueprints/crud/event.py
CHANGED
|
@@ -27,15 +27,6 @@ class MetadataDescriptorsResource(BaseModelsResource):
|
|
|
27
27
|
)
|
|
28
28
|
return query
|
|
29
29
|
|
|
30
|
-
def all_entries(self, query=None, relations=True):
|
|
31
|
-
if query is None:
|
|
32
|
-
query = self.model.query
|
|
33
|
-
|
|
34
|
-
return [
|
|
35
|
-
metadata_descriptor.serialize(relations=relations)
|
|
36
|
-
for metadata_descriptor in query.all()
|
|
37
|
-
]
|
|
38
|
-
|
|
39
30
|
def check_creation_integrity(self, data):
|
|
40
31
|
"""
|
|
41
32
|
Check if the data descriptor has a valid data_type.
|
|
@@ -46,6 +37,15 @@ class MetadataDescriptorsResource(BaseModelsResource):
|
|
|
46
37
|
raise WrongParameterException("Invalid data_type")
|
|
47
38
|
return True
|
|
48
39
|
|
|
40
|
+
def all_entries(self, query=None, relations=True):
|
|
41
|
+
if query is None:
|
|
42
|
+
query = self.model.query
|
|
43
|
+
|
|
44
|
+
return [
|
|
45
|
+
metadata_descriptor.serialize(relations=relations)
|
|
46
|
+
for metadata_descriptor in query.all()
|
|
47
|
+
]
|
|
48
|
+
|
|
49
49
|
|
|
50
50
|
class MetadataDescriptorResource(BaseModelResource):
|
|
51
51
|
|
|
@@ -2,6 +2,7 @@ from zou.app.models.organisation import Organisation
|
|
|
2
2
|
from zou.app.blueprints.crud.base import BaseModelResource, BaseModelsResource
|
|
3
3
|
|
|
4
4
|
from zou.app.services import persons_service
|
|
5
|
+
from zou.app.utils.permissions import has_admin_permissions
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class OrganisationsResource(BaseModelsResource):
|
|
@@ -24,6 +25,20 @@ class OrganisationResource(BaseModelResource):
|
|
|
24
25
|
data["hours_by_day"] = float(data["hours_by_day"])
|
|
25
26
|
return data
|
|
26
27
|
|
|
28
|
+
def serialize_instance(self, data, relations=True):
|
|
29
|
+
return data.serialize(
|
|
30
|
+
relations=relations,
|
|
31
|
+
ignored_attrs=(
|
|
32
|
+
[]
|
|
33
|
+
if has_admin_permissions()
|
|
34
|
+
else [
|
|
35
|
+
"chat_token_slack",
|
|
36
|
+
"chat_webhook_mattermost",
|
|
37
|
+
"chat_token_discord",
|
|
38
|
+
]
|
|
39
|
+
),
|
|
40
|
+
)
|
|
41
|
+
|
|
27
42
|
def post_update(self, instance_dict, data):
|
|
28
|
-
persons_service.
|
|
43
|
+
persons_service.clear_organisation_cache()
|
|
29
44
|
return instance_dict
|
|
@@ -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,7 +50,7 @@ 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
55
|
("name", None, False),
|
|
56
56
|
],
|
|
@@ -59,7 +59,7 @@ class EventsResource(Resource, ArgsMixin):
|
|
|
59
59
|
permissions.check_manager_permissions()
|
|
60
60
|
before = self.parse_date_parameter(args["before"])
|
|
61
61
|
after = self.parse_date_parameter(args["after"])
|
|
62
|
-
|
|
62
|
+
limit = args["limit"]
|
|
63
63
|
only_files = args["only_files"] == "true"
|
|
64
64
|
project_id = args.get("project_id", None)
|
|
65
65
|
name = args["name"]
|
|
@@ -71,7 +71,7 @@ class EventsResource(Resource, ArgsMixin):
|
|
|
71
71
|
return events_service.get_last_events(
|
|
72
72
|
after=after,
|
|
73
73
|
before=before,
|
|
74
|
-
|
|
74
|
+
limit=limit,
|
|
75
75
|
only_files=only_files,
|
|
76
76
|
project_id=project_id,
|
|
77
77
|
name=name,
|
|
@@ -93,18 +93,18 @@ class LoginLogsResource(Resource, ArgsMixin):
|
|
|
93
93
|
format: date
|
|
94
94
|
x-example: "2022-07-12T00:00:00"
|
|
95
95
|
- in: query
|
|
96
|
-
name:
|
|
96
|
+
name: limit
|
|
97
97
|
type: integer
|
|
98
98
|
x-example: 100
|
|
99
99
|
responses:
|
|
100
100
|
200:
|
|
101
101
|
description: All login logs
|
|
102
102
|
"""
|
|
103
|
-
args = self.get_args(["before", ("
|
|
103
|
+
args = self.get_args(["before", ("limit", 100)])
|
|
104
104
|
|
|
105
105
|
permissions.check_manager_permissions()
|
|
106
106
|
before = None
|
|
107
107
|
if args["before"] is not None:
|
|
108
108
|
before = date_helpers.get_datetime_from_string(args["before"])
|
|
109
|
-
|
|
110
|
-
return events_service.get_last_login_logs(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
|
|
|
@@ -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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
(
|
|
158
|
+
(
|
|
159
|
+
descriptor["name"],
|
|
160
|
+
descriptor["field_name"],
|
|
161
|
+
descriptor["data_type"],
|
|
162
|
+
)
|
|
153
163
|
for descriptor in descriptors
|
|
154
164
|
]
|
|
155
165
|
|
|
@@ -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
|
-
|
|
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
|
-
(
|
|
180
|
+
(
|
|
181
|
+
descriptor["name"],
|
|
182
|
+
descriptor["field_name"],
|
|
183
|
+
descriptor["data_type"],
|
|
184
|
+
)
|
|
175
185
|
for descriptor in descriptors
|
|
176
186
|
]
|
|
177
187
|
|
|
@@ -297,6 +297,8 @@ class ConfigResource(Resource):
|
|
|
297
297
|
),
|
|
298
298
|
"saml_enabled": config.SAML_ENABLED,
|
|
299
299
|
"saml_idp_name": config.SAML_IDP_NAME,
|
|
300
|
+
"default_locale": config.DEFAULT_LOCALE,
|
|
301
|
+
"default_timezone": config.DEFAULT_TIMEZONE,
|
|
300
302
|
}
|
|
301
303
|
if config.SENTRY_KITSU_ENABLED:
|
|
302
304
|
conf["sentry"] = {
|
|
@@ -21,7 +21,7 @@ class NewsMixin(ArgsMixin):
|
|
|
21
21
|
episode_id,
|
|
22
22
|
person_id,
|
|
23
23
|
page,
|
|
24
|
-
|
|
24
|
+
limit,
|
|
25
25
|
after,
|
|
26
26
|
before,
|
|
27
27
|
) = self.get_arguments()
|
|
@@ -38,7 +38,7 @@ class NewsMixin(ArgsMixin):
|
|
|
38
38
|
episode_id=episode_id,
|
|
39
39
|
author_id=person_id,
|
|
40
40
|
page=page,
|
|
41
|
-
|
|
41
|
+
limit=limit,
|
|
42
42
|
after=after,
|
|
43
43
|
before=before,
|
|
44
44
|
current_user=current_user,
|
|
@@ -72,7 +72,7 @@ class NewsMixin(ArgsMixin):
|
|
|
72
72
|
"project_id",
|
|
73
73
|
"episode_id",
|
|
74
74
|
{"name": "page", "default": 1, "type": int},
|
|
75
|
-
{"name": "
|
|
75
|
+
{"name": "limit", "default": 50, "type": int},
|
|
76
76
|
"after",
|
|
77
77
|
"before",
|
|
78
78
|
],
|
|
@@ -84,7 +84,7 @@ class NewsMixin(ArgsMixin):
|
|
|
84
84
|
args["episode_id"],
|
|
85
85
|
args["person_id"],
|
|
86
86
|
args["page"],
|
|
87
|
-
args["
|
|
87
|
+
args["limit"],
|
|
88
88
|
args["after"],
|
|
89
89
|
args["before"],
|
|
90
90
|
)
|
|
@@ -120,7 +120,7 @@ class ProjectNewsResource(Resource, NewsMixin, ArgsMixin):
|
|
|
120
120
|
type: integer
|
|
121
121
|
x-example: 1
|
|
122
122
|
- in: query
|
|
123
|
-
name:
|
|
123
|
+
name: limit
|
|
124
124
|
type: integer
|
|
125
125
|
x-example: 50
|
|
126
126
|
- in: query
|
|
@@ -183,7 +183,7 @@ class NewsResource(Resource, NewsMixin, ArgsMixin):
|
|
|
183
183
|
type: integer
|
|
184
184
|
x-example: 1
|
|
185
185
|
- in: query
|
|
186
|
-
name:
|
|
186
|
+
name: limit
|
|
187
187
|
type: integer
|
|
188
188
|
x-example: 50
|
|
189
189
|
- in: query
|
|
@@ -16,7 +16,7 @@ from zou.app.services import (
|
|
|
16
16
|
)
|
|
17
17
|
from zou.app.models.entity import Entity
|
|
18
18
|
from zou.app.services.exception import WrongParameterException
|
|
19
|
-
from zou.app.utils import events, cache
|
|
19
|
+
from zou.app.utils import events, cache, string
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class AssetsCsvImportResource(BaseCsvProjectImportResource):
|
|
@@ -209,9 +209,16 @@ class AssetsCsvImportResource(BaseCsvProjectImportResource):
|
|
|
209
209
|
else:
|
|
210
210
|
asset_new_values["data"] = entity.data.copy()
|
|
211
211
|
|
|
212
|
-
for name,
|
|
212
|
+
for name, descriptor in self.descriptor_fields.items():
|
|
213
213
|
if name in row:
|
|
214
|
-
|
|
214
|
+
if descriptor["data_type"] == "boolean":
|
|
215
|
+
asset_new_values["data"][descriptor["field_name"]] = (
|
|
216
|
+
"true" if string.strtobool(row[name]) else "false"
|
|
217
|
+
)
|
|
218
|
+
else:
|
|
219
|
+
asset_new_values["data"][descriptor["field_name"]] = row[
|
|
220
|
+
name
|
|
221
|
+
]
|
|
215
222
|
|
|
216
223
|
ready_for = row.get("Ready for", None)
|
|
217
224
|
if ready_for is not None:
|
|
@@ -131,5 +131,5 @@ class BaseCsvProjectImportResource(BaseCsvImportResource, ArgsMixin):
|
|
|
131
131
|
descriptors = projects_service.get_metadata_descriptors(project_id)
|
|
132
132
|
for descriptor in descriptors:
|
|
133
133
|
if descriptor["entity_type"] == entity_type:
|
|
134
|
-
descriptor_map[descriptor["name"]] = descriptor
|
|
134
|
+
descriptor_map[descriptor["name"]] = descriptor
|
|
135
135
|
return descriptor_map
|
|
@@ -21,7 +21,7 @@ from zou.app.services.tasks_service import (
|
|
|
21
21
|
)
|
|
22
22
|
from zou.app.services.comments_service import create_comment
|
|
23
23
|
from zou.app.services.exception import WrongParameterException
|
|
24
|
-
from zou.app.utils import events
|
|
24
|
+
from zou.app.utils import events, string
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class EditsCsvImportResource(BaseCsvProjectImportResource):
|
|
@@ -192,9 +192,16 @@ class EditsCsvImportResource(BaseCsvProjectImportResource):
|
|
|
192
192
|
else:
|
|
193
193
|
edit_new_values["data"] = entity.data.copy()
|
|
194
194
|
|
|
195
|
-
for name,
|
|
195
|
+
for name, descriptor in self.descriptor_fields.items():
|
|
196
196
|
if name in row:
|
|
197
|
-
|
|
197
|
+
if descriptor["data_type"] == "boolean":
|
|
198
|
+
edit_new_values["data"][descriptor["field_name"]] = (
|
|
199
|
+
"true" if string.strtobool(row[name]) else "false"
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
edit_new_values["data"][descriptor["field_name"]] = row[
|
|
203
|
+
name
|
|
204
|
+
]
|
|
198
205
|
|
|
199
206
|
tasks_update = self.get_tasks_update(row)
|
|
200
207
|
|
|
@@ -21,7 +21,7 @@ from zou.app.services.tasks_service import (
|
|
|
21
21
|
)
|
|
22
22
|
from zou.app.services.comments_service import create_comment
|
|
23
23
|
from zou.app.services.exception import WrongParameterException
|
|
24
|
-
from zou.app.utils import events
|
|
24
|
+
from zou.app.utils import events, string
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class ShotsCsvImportResource(BaseCsvProjectImportResource):
|
|
@@ -229,9 +229,16 @@ class ShotsCsvImportResource(BaseCsvProjectImportResource):
|
|
|
229
229
|
if fps is not None:
|
|
230
230
|
shot_new_values["data"]["fps"] = fps
|
|
231
231
|
|
|
232
|
-
for name,
|
|
232
|
+
for name, descriptor in self.descriptor_fields.items():
|
|
233
233
|
if name in row:
|
|
234
|
-
|
|
234
|
+
if descriptor["data_type"] == "boolean":
|
|
235
|
+
shot_new_values["data"][descriptor["field_name"]] = (
|
|
236
|
+
"true" if string.strtobool(row[name]) else "false"
|
|
237
|
+
)
|
|
238
|
+
else:
|
|
239
|
+
shot_new_values["data"][descriptor["field_name"]] = row[
|
|
240
|
+
name
|
|
241
|
+
]
|
|
235
242
|
|
|
236
243
|
tasks_update = self.get_tasks_update(row)
|
|
237
244
|
|
|
@@ -1532,6 +1532,11 @@ class ProjectCommentsResource(Resource, ArgsMixin):
|
|
|
1532
1532
|
type: string
|
|
1533
1533
|
format: UUID
|
|
1534
1534
|
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
1535
|
+
- in: query
|
|
1536
|
+
name: limit
|
|
1537
|
+
type: integer
|
|
1538
|
+
default: 100
|
|
1539
|
+
x-example: 100
|
|
1535
1540
|
responses:
|
|
1536
1541
|
200:
|
|
1537
1542
|
description: All comments to tasks related to given project
|
|
@@ -1544,7 +1549,8 @@ class ProjectCommentsResource(Resource, ArgsMixin):
|
|
|
1544
1549
|
):
|
|
1545
1550
|
raise permissions.PermissionDenied
|
|
1546
1551
|
page = self.get_page()
|
|
1547
|
-
|
|
1552
|
+
limit = self.get_limit()
|
|
1553
|
+
return tasks_service.get_comments_for_project(project_id, page, limit)
|
|
1548
1554
|
|
|
1549
1555
|
|
|
1550
1556
|
class ProjectPreviewFilesResource(Resource, ArgsMixin):
|
zou/app/models/organisation.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from zou.app import db
|
|
2
2
|
from zou.app.models.serializer import SerializerMixin
|
|
3
3
|
from zou.app.models.base import BaseMixin
|
|
4
|
-
from zou.app.utils import fields
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
class Organisation(db.Model, BaseMixin, SerializerMixin):
|
|
@@ -22,22 +21,15 @@ class Organisation(db.Model, BaseMixin, SerializerMixin):
|
|
|
22
21
|
dark_theme_by_default = db.Column(db.Boolean(), default=False)
|
|
23
22
|
format_duration_in_hours = db.Column(db.Boolean(), default=False)
|
|
24
23
|
|
|
25
|
-
def present(self):
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"use_original_file_name": self.use_original_file_name,
|
|
37
|
-
"timesheets_locked": self.timesheets_locked,
|
|
38
|
-
"dark_theme_by_default": self.dark_theme_by_default,
|
|
39
|
-
"format_duration_in_hours": self.format_duration_in_hours,
|
|
40
|
-
"updated_at": self.updated_at,
|
|
41
|
-
"created_at": self.created_at,
|
|
42
|
-
}
|
|
24
|
+
def present(self, sensitive=False):
|
|
25
|
+
return self.serialize(
|
|
26
|
+
ignored_attrs=(
|
|
27
|
+
[]
|
|
28
|
+
if sensitive
|
|
29
|
+
else [
|
|
30
|
+
"chat_token_slack",
|
|
31
|
+
"chat_webhook_mattermost",
|
|
32
|
+
"chat_token_discord",
|
|
33
|
+
]
|
|
34
|
+
)
|
|
43
35
|
)
|
zou/app/models/serializer.py
CHANGED
|
@@ -14,35 +14,35 @@ class SerializerMixin(object):
|
|
|
14
14
|
orm.attributes.CollectionAttributeImpl,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
-
def serialize(
|
|
17
|
+
def serialize(
|
|
18
|
+
self,
|
|
19
|
+
obj_type=None,
|
|
20
|
+
relations=False,
|
|
21
|
+
milliseconds=False,
|
|
22
|
+
ignored_attrs=[],
|
|
23
|
+
):
|
|
18
24
|
attrs = inspect(self.__class__).all_orm_descriptors.keys()
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
attr
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
obj_dict = {
|
|
28
|
-
attr: serialize_value(
|
|
29
|
-
getattr(self, attr), milliseconds=milliseconds
|
|
30
|
-
)
|
|
31
|
-
for attr in attrs
|
|
32
|
-
if not self.is_join(attr)
|
|
33
|
-
}
|
|
25
|
+
obj_dict = {
|
|
26
|
+
attr: serialize_value(
|
|
27
|
+
getattr(self, attr), milliseconds=milliseconds
|
|
28
|
+
)
|
|
29
|
+
for attr in attrs
|
|
30
|
+
if attr not in ignored_attrs
|
|
31
|
+
and (relations or not self.is_join(attr))
|
|
32
|
+
}
|
|
34
33
|
obj_dict["type"] = obj_type or type(self).__name__
|
|
35
34
|
return obj_dict
|
|
36
35
|
|
|
37
36
|
@staticmethod
|
|
38
37
|
def serialize_list(
|
|
39
|
-
models, obj_type=None, relations=False, milliseconds=False
|
|
38
|
+
models, obj_type=None, relations=False, milliseconds=False, **kwargs
|
|
40
39
|
):
|
|
41
40
|
return [
|
|
42
41
|
model.serialize(
|
|
43
42
|
obj_type=obj_type,
|
|
44
43
|
relations=relations,
|
|
45
44
|
milliseconds=milliseconds,
|
|
45
|
+
**kwargs
|
|
46
46
|
)
|
|
47
47
|
for model in models
|
|
48
48
|
]
|