zou 0.19.68__py3-none-any.whl → 0.19.70__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 +17 -15
- zou/app/blueprints/breakdown/resources.py +4 -4
- zou/app/blueprints/comments/resources.py +2 -2
- zou/app/blueprints/crud/base.py +11 -20
- zou/app/blueprints/crud/comments.py +4 -40
- 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/crud/person.py +4 -0
- zou/app/blueprints/crud/task.py +4 -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/persons/resources.py +0 -1
- zou/app/blueprints/shots/resources.py +0 -1
- 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/config.py +1 -0
- zou/app/models/organisation.py +11 -19
- zou/app/models/person.py +1 -1
- zou/app/models/serializer.py +17 -17
- zou/app/services/assets_service.py +6 -12
- zou/app/services/breakdown_service.py +1 -1
- zou/app/services/comments_service.py +1 -1
- zou/app/services/concepts_service.py +4 -12
- zou/app/services/edits_service.py +5 -11
- zou/app/services/events_service.py +4 -4
- zou/app/services/news_service.py +8 -8
- zou/app/services/persons_service.py +9 -4
- zou/app/services/preview_files_service.py +12 -4
- zou/app/services/projects_service.py +4 -13
- zou/app/services/shots_service.py +6 -12
- zou/app/services/sync_service.py +4 -4
- zou/app/services/tasks_service.py +12 -29
- zou/app/services/user_service.py +22 -37
- 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.68.dist-info → zou-0.19.70.dist-info}/METADATA +9 -9
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/RECORD +53 -53
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/LICENSE +0 -0
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/WHEEL +0 -0
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/entry_points.txt +0 -0
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/top_level.txt +0 -0
zou/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.19.
|
|
1
|
+
__version__ = "0.19.70"
|
zou/app/__init__.py
CHANGED
|
@@ -78,7 +78,9 @@ class AuthenticatedResource(Resource):
|
|
|
78
78
|
description: Person not found
|
|
79
79
|
"""
|
|
80
80
|
person = persons_service.get_current_user(relations=True)
|
|
81
|
-
organisation = persons_service.get_organisation(
|
|
81
|
+
organisation = persons_service.get_organisation(
|
|
82
|
+
sensitive=permissions.has_admin_permissions()
|
|
83
|
+
)
|
|
82
84
|
return {
|
|
83
85
|
"authenticated": True,
|
|
84
86
|
"user": person,
|
|
@@ -227,15 +229,21 @@ class LoginResource(Resource, ArgsMixin):
|
|
|
227
229
|
"HTTP_X_REAL_IP", request.remote_addr
|
|
228
230
|
)
|
|
229
231
|
|
|
232
|
+
organisation = persons_service.get_organisation(
|
|
233
|
+
sensitive=user["role"] != "admin"
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
response = jsonify(
|
|
237
|
+
{
|
|
238
|
+
"user": user,
|
|
239
|
+
"organisation": organisation,
|
|
240
|
+
"login": True,
|
|
241
|
+
"access_token": access_token,
|
|
242
|
+
"refresh_token": refresh_token,
|
|
243
|
+
}
|
|
244
|
+
)
|
|
245
|
+
|
|
230
246
|
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
247
|
set_access_cookies(response, access_token)
|
|
240
248
|
set_refresh_cookies(response, refresh_token)
|
|
241
249
|
events_service.create_login_log(user["id"], ip_address, "web")
|
|
@@ -243,12 +251,6 @@ class LoginResource(Resource, ArgsMixin):
|
|
|
243
251
|
events_service.create_login_log(
|
|
244
252
|
user["id"], ip_address, "script"
|
|
245
253
|
)
|
|
246
|
-
response = {
|
|
247
|
-
"login": True,
|
|
248
|
-
"user": user,
|
|
249
|
-
"access_token": access_token,
|
|
250
|
-
"refresh_token": refresh_token,
|
|
251
|
-
}
|
|
252
254
|
current_app.logger.info(f"User {email} is logged in.")
|
|
253
255
|
return response
|
|
254
256
|
except WrongUserException:
|
|
@@ -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
|
|
@@ -435,8 +435,8 @@ class CommentManyTasksResource(Resource):
|
|
|
435
435
|
allowed_comments = []
|
|
436
436
|
for comment in comments:
|
|
437
437
|
try:
|
|
438
|
-
task = tasks_service.
|
|
439
|
-
comment["object_id"],
|
|
438
|
+
task = tasks_service.get_task(
|
|
439
|
+
comment["object_id"], relations=True
|
|
440
440
|
)
|
|
441
441
|
if (
|
|
442
442
|
person["role"] == "supervisor"
|
zou/app/blueprints/crud/base.py
CHANGED
|
@@ -13,7 +13,6 @@ from zou.app.mixin import ArgsMixin
|
|
|
13
13
|
from zou.app.utils import events, fields, permissions, query
|
|
14
14
|
from zou.app.services.exception import (
|
|
15
15
|
WrongParameterException,
|
|
16
|
-
WrongParameterException,
|
|
17
16
|
)
|
|
18
17
|
|
|
19
18
|
|
|
@@ -27,7 +26,10 @@ class BaseModelsResource(Resource, ArgsMixin):
|
|
|
27
26
|
if query is None:
|
|
28
27
|
query = self.model.query
|
|
29
28
|
|
|
30
|
-
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)
|
|
31
33
|
|
|
32
34
|
def paginated_entries(self, query, page, limit=None, relations=False):
|
|
33
35
|
total = query.count()
|
|
@@ -259,14 +261,6 @@ class BaseModelsResource(Resource, ArgsMixin):
|
|
|
259
261
|
current_app.logger.error(str(exception), exc_info=1)
|
|
260
262
|
return {"message": str(exception)}, 400
|
|
261
263
|
|
|
262
|
-
except WrongParameterException as exception:
|
|
263
|
-
current_app.logger.error(str(exception), exc_info=1)
|
|
264
|
-
return (
|
|
265
|
-
exception.dict
|
|
266
|
-
if exception.dict is not None
|
|
267
|
-
else {"message": str(exception)}
|
|
268
|
-
), 400
|
|
269
|
-
|
|
270
264
|
def emit_create_event(self, instance_dict):
|
|
271
265
|
return events.emit(
|
|
272
266
|
"%s:new" % self.model.__tablename__.replace("_", "-"),
|
|
@@ -290,6 +284,10 @@ class BaseModelResource(Resource, ArgsMixin):
|
|
|
290
284
|
abort(404)
|
|
291
285
|
return instance
|
|
292
286
|
|
|
287
|
+
def get_serialized_instance(self, instance_id, relations=True):
|
|
288
|
+
instance = self.get_model_or_404(instance_id)
|
|
289
|
+
return self.serialize_instance(instance, relations=relations)
|
|
290
|
+
|
|
293
291
|
def check_read_permissions(self, instance_dict):
|
|
294
292
|
return permissions.check_admin_permissions()
|
|
295
293
|
|
|
@@ -338,8 +336,9 @@ class BaseModelResource(Resource, ArgsMixin):
|
|
|
338
336
|
"""
|
|
339
337
|
relations = self.get_bool_parameter("relations", "true")
|
|
340
338
|
try:
|
|
341
|
-
|
|
342
|
-
|
|
339
|
+
result = self.get_serialized_instance(
|
|
340
|
+
instance_id, relations=relations
|
|
341
|
+
)
|
|
343
342
|
self.check_read_permissions(result)
|
|
344
343
|
result = self.clean_get_result(result)
|
|
345
344
|
|
|
@@ -430,14 +429,6 @@ class BaseModelResource(Resource, ArgsMixin):
|
|
|
430
429
|
current_app.logger.error(str(exception), exc_info=1)
|
|
431
430
|
return {"message": str(exception)}, 400
|
|
432
431
|
|
|
433
|
-
except WrongParameterException as exception:
|
|
434
|
-
current_app.logger.error(str(exception), exc_info=1)
|
|
435
|
-
return (
|
|
436
|
-
exception.dict
|
|
437
|
-
if exception.dict is not None
|
|
438
|
-
else {"message": str(exception)}
|
|
439
|
-
), 400
|
|
440
|
-
|
|
441
432
|
@jwt_required()
|
|
442
433
|
def delete(self, instance_id):
|
|
443
434
|
"""
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from flask_jwt_extended import jwt_required
|
|
2
|
-
from flask import current_app
|
|
3
2
|
|
|
4
|
-
from sqlalchemy.exc import StatementError
|
|
5
3
|
|
|
6
4
|
from zou.app.models.comment import Comment
|
|
7
5
|
from zou.app.models.attachment_file import AttachmentFile
|
|
@@ -19,53 +17,19 @@ from zou.app.utils import events, permissions
|
|
|
19
17
|
|
|
20
18
|
from zou.app.blueprints.crud.base import BaseModelResource, BaseModelsResource
|
|
21
19
|
|
|
22
|
-
from zou.app.services.exception import (
|
|
23
|
-
CommentNotFoundException,
|
|
24
|
-
)
|
|
25
|
-
|
|
26
20
|
|
|
27
21
|
class CommentsResource(BaseModelsResource):
|
|
28
22
|
def __init__(self):
|
|
29
23
|
BaseModelsResource.__init__(self, Comment)
|
|
30
24
|
|
|
31
|
-
def check_read_permissions(self, options=None):
|
|
32
|
-
if options is not None:
|
|
33
|
-
if "project_id" in options:
|
|
34
|
-
user_service.check_project_access(options["project_id"])
|
|
35
|
-
if (
|
|
36
|
-
permissions.has_vendor_permissions()
|
|
37
|
-
or permissions.has_client_permissions()
|
|
38
|
-
):
|
|
39
|
-
raise permissions.PermissionDenied
|
|
40
|
-
else:
|
|
41
|
-
return True
|
|
42
|
-
return permissions.check_admin_permissions()
|
|
43
|
-
|
|
44
25
|
|
|
45
26
|
class CommentResource(BaseModelResource):
|
|
46
27
|
def __init__(self):
|
|
47
28
|
BaseModelResource.__init__(self, Comment)
|
|
48
29
|
self.protected_fields += ["mentions", "department_mentions"]
|
|
49
30
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"""
|
|
53
|
-
Retrieve a model corresponding at given ID and return it as a JSON
|
|
54
|
-
object.
|
|
55
|
-
"""
|
|
56
|
-
try:
|
|
57
|
-
instance = tasks_service.get_comment_with_relations(instance_id)
|
|
58
|
-
self.check_read_permissions(instance)
|
|
59
|
-
result = self.clean_get_result(instance)
|
|
60
|
-
|
|
61
|
-
except StatementError as exception:
|
|
62
|
-
current_app.logger.error(str(exception), exc_info=1)
|
|
63
|
-
return {"message": str(exception)}, 400
|
|
64
|
-
|
|
65
|
-
except ValueError:
|
|
66
|
-
raise CommentNotFoundException
|
|
67
|
-
|
|
68
|
-
return result, 200
|
|
31
|
+
def get_serialized_instance(self, instance_id, relations=True):
|
|
32
|
+
return tasks_service.get_comment(instance_id, relations=relations)
|
|
69
33
|
|
|
70
34
|
def clean_get_result(self, result):
|
|
71
35
|
if permissions.has_client_permissions():
|
|
@@ -123,8 +87,8 @@ class CommentResource(BaseModelResource):
|
|
|
123
87
|
instance["object_id"], relations=True
|
|
124
88
|
)
|
|
125
89
|
task_type = tasks_service.get_task_type(task["task_type_id"])
|
|
126
|
-
project = projects_service.
|
|
127
|
-
task["project_id"]
|
|
90
|
+
project = projects_service.get_project(
|
|
91
|
+
task["project_id"], relations=True
|
|
128
92
|
)
|
|
129
93
|
current_user = persons_service.get_current_user(relations=True)
|
|
130
94
|
if current_user["id"] not in project["team"]:
|
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
|
|
@@ -97,6 +97,8 @@ class PersonsResource(BaseModelsResource):
|
|
|
97
97
|
raise WrongParameterException(
|
|
98
98
|
"Expiration date can't be in the past."
|
|
99
99
|
)
|
|
100
|
+
except WrongParameterException:
|
|
101
|
+
raise
|
|
100
102
|
except:
|
|
101
103
|
raise WrongParameterException("Expiration date is not valid.")
|
|
102
104
|
return data
|
|
@@ -178,6 +180,8 @@ class PersonResource(BaseModelResource, ArgsMixin):
|
|
|
178
180
|
raise WrongParameterException(
|
|
179
181
|
"Expiration date can't be in the past."
|
|
180
182
|
)
|
|
183
|
+
except WrongParameterException:
|
|
184
|
+
raise
|
|
181
185
|
except:
|
|
182
186
|
raise WrongParameterException("Expiration date is not valid.")
|
|
183
187
|
return data
|
zou/app/blueprints/crud/task.py
CHANGED
|
@@ -116,7 +116,10 @@ class TasksResource(BaseModelsResource, ArgsMixin):
|
|
|
116
116
|
instance.save()
|
|
117
117
|
self.emit_create_event(instance.serialize())
|
|
118
118
|
|
|
119
|
-
return
|
|
119
|
+
return (
|
|
120
|
+
tasks_service.get_task(str(instance.id), relations=True),
|
|
121
|
+
201,
|
|
122
|
+
)
|
|
120
123
|
|
|
121
124
|
except TypeError as exception:
|
|
122
125
|
current_app.logger.error(str(exception), exc_info=1)
|
|
@@ -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
|
|
@@ -30,7 +30,6 @@ from zou.app.services.exception import (
|
|
|
30
30
|
UnactiveUserException,
|
|
31
31
|
TwoFactorAuthenticationNotEnabledException,
|
|
32
32
|
PersonInProtectedAccounts,
|
|
33
|
-
WrongParameterException,
|
|
34
33
|
)
|
|
35
34
|
from zou.app.services.auth_service import (
|
|
36
35
|
disable_two_factor_authentication_for_person,
|
|
@@ -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
|