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
|
@@ -15,120 +15,27 @@ from zou.app.services import (
|
|
|
15
15
|
shots_service,
|
|
16
16
|
user_service,
|
|
17
17
|
)
|
|
18
|
-
from zou.app.utils import
|
|
18
|
+
from zou.app.utils import (
|
|
19
|
+
permissions,
|
|
20
|
+
csv_utils,
|
|
21
|
+
auth,
|
|
22
|
+
emails,
|
|
23
|
+
fields,
|
|
24
|
+
date_helpers,
|
|
25
|
+
)
|
|
19
26
|
from zou.app.services.exception import (
|
|
20
27
|
DepartmentNotFoundException,
|
|
21
28
|
WrongDateFormatException,
|
|
22
29
|
WrongParameterException,
|
|
23
30
|
UnactiveUserException,
|
|
24
31
|
TwoFactorAuthenticationNotEnabledException,
|
|
32
|
+
PersonInProtectedAccounts,
|
|
25
33
|
)
|
|
26
34
|
from zou.app.services.auth_service import (
|
|
27
35
|
disable_two_factor_authentication_for_person,
|
|
28
36
|
)
|
|
29
37
|
|
|
30
38
|
|
|
31
|
-
class NewPersonResource(Resource, ArgsMixin):
|
|
32
|
-
"""
|
|
33
|
-
Create a new user in the database.
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
# TODO: Remove this route in the future.
|
|
37
|
-
@jwt_required()
|
|
38
|
-
@permissions.require_admin
|
|
39
|
-
def post(self):
|
|
40
|
-
"""
|
|
41
|
-
Create a new user in the database.
|
|
42
|
-
This route will be removed in the future.
|
|
43
|
-
Please use POST /data/persons instead.
|
|
44
|
-
---
|
|
45
|
-
tags:
|
|
46
|
-
- Persons
|
|
47
|
-
description: Set password to None if not provided.
|
|
48
|
-
User role can be set but only admins can create admin users.
|
|
49
|
-
parameters:
|
|
50
|
-
- in: formData
|
|
51
|
-
name: email
|
|
52
|
-
required: True
|
|
53
|
-
type: string
|
|
54
|
-
format: email
|
|
55
|
-
x-example: admin@example.com
|
|
56
|
-
- in: formData
|
|
57
|
-
name: phone
|
|
58
|
-
required: False
|
|
59
|
-
type: integer
|
|
60
|
-
x-example: 06 12 34 56 78
|
|
61
|
-
- in: formData
|
|
62
|
-
name: role
|
|
63
|
-
required: False
|
|
64
|
-
type: string
|
|
65
|
-
x-example: user
|
|
66
|
-
- in: formData
|
|
67
|
-
name: first_name
|
|
68
|
-
required: True
|
|
69
|
-
type: string
|
|
70
|
-
- in: formData
|
|
71
|
-
name: last_name
|
|
72
|
-
required: False
|
|
73
|
-
type: string
|
|
74
|
-
responses:
|
|
75
|
-
201:
|
|
76
|
-
description: User created
|
|
77
|
-
"""
|
|
78
|
-
data = self.get_arguments()
|
|
79
|
-
|
|
80
|
-
if not data["is_bot"] and persons_service.is_user_limit_reached():
|
|
81
|
-
return {
|
|
82
|
-
"error": True,
|
|
83
|
-
"message": "User limit reached.",
|
|
84
|
-
"limit": config.USER_LIMIT,
|
|
85
|
-
}, 400
|
|
86
|
-
else:
|
|
87
|
-
if data["password"] is not None:
|
|
88
|
-
data["password"] = auth.encrypt_password(data["password"])
|
|
89
|
-
person = persons_service.create_person(
|
|
90
|
-
data["email"],
|
|
91
|
-
data["password"],
|
|
92
|
-
data["first_name"],
|
|
93
|
-
data["last_name"],
|
|
94
|
-
data["phone"],
|
|
95
|
-
role=data["role"],
|
|
96
|
-
desktop_login=data["desktop_login"],
|
|
97
|
-
departments=data["departments"],
|
|
98
|
-
is_bot=data["is_bot"],
|
|
99
|
-
expiration_date=data["expiration_date"],
|
|
100
|
-
active=data["active"],
|
|
101
|
-
)
|
|
102
|
-
return person, 201
|
|
103
|
-
|
|
104
|
-
def get_arguments(self):
|
|
105
|
-
args = self.get_args(
|
|
106
|
-
[
|
|
107
|
-
{
|
|
108
|
-
"name": "email",
|
|
109
|
-
"help": "The email is required.",
|
|
110
|
-
"required": True,
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
"name": "first_name",
|
|
114
|
-
"help": "The first name is required.",
|
|
115
|
-
"required": True,
|
|
116
|
-
},
|
|
117
|
-
("last_name", ""),
|
|
118
|
-
("phone", ""),
|
|
119
|
-
("role", "user"),
|
|
120
|
-
("desktop_login", ""),
|
|
121
|
-
{"name": "departments", "action": "append"},
|
|
122
|
-
"password",
|
|
123
|
-
{"name": "is_bot", "default": False, "type": bool},
|
|
124
|
-
{"name": "expiration_date", "default": None, "type": str},
|
|
125
|
-
{"name": "active", "default": True, "type": bool},
|
|
126
|
-
]
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
return args
|
|
130
|
-
|
|
131
|
-
|
|
132
39
|
class DesktopLoginsResource(Resource, ArgsMixin):
|
|
133
40
|
"""
|
|
134
41
|
Allow to create and retrieve desktop login logs. Desktop login logs can only
|
|
@@ -189,7 +96,7 @@ class DesktopLoginsResource(Resource, ArgsMixin):
|
|
|
189
96
|
201:
|
|
190
97
|
description: Desktop login log entry created.
|
|
191
98
|
"""
|
|
192
|
-
args = self.get_args([("date",
|
|
99
|
+
args = self.get_args([("date", date_helpers.get_utc_now_datetime())])
|
|
193
100
|
|
|
194
101
|
current_user = persons_service.get_current_user()
|
|
195
102
|
if (
|
|
@@ -400,7 +307,7 @@ class PersonDurationTimeSpentsResource(Resource, ArgsMixin):
|
|
|
400
307
|
raise permissions.PermissionDenied
|
|
401
308
|
if permissions.has_supervisor_permissions():
|
|
402
309
|
department_ids = persons_service.get_current_user(
|
|
403
|
-
True
|
|
310
|
+
relations=True
|
|
404
311
|
)["departments"]
|
|
405
312
|
else:
|
|
406
313
|
raise permissions.PermissionDenied
|
|
@@ -625,7 +532,24 @@ class PersonDayTimeSpentsResource(PersonDurationTimeSpentsResource):
|
|
|
625
532
|
abort(404)
|
|
626
533
|
|
|
627
534
|
|
|
628
|
-
class
|
|
535
|
+
class PersonQuotaMixin:
|
|
536
|
+
|
|
537
|
+
def get_quota_arguments(self):
|
|
538
|
+
project_id = self.get_project_id()
|
|
539
|
+
task_type_id = self.get_task_type_id()
|
|
540
|
+
count_mode = self.get_text_parameter("count_mode", default="weigthed")
|
|
541
|
+
if count_mode not in ["weighted", "weighteddone", "feedback", "done"]:
|
|
542
|
+
raise WrongParameterException(
|
|
543
|
+
"count_mode must be equal to weighted, weigtheddone, feedback"
|
|
544
|
+
", or done"
|
|
545
|
+
)
|
|
546
|
+
feedback = "done" not in count_mode
|
|
547
|
+
weighted = "weighted" in count_mode
|
|
548
|
+
|
|
549
|
+
return (project_id, task_type_id, count_mode, feedback, weighted)
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
class PersonMonthQuotaShotsResource(Resource, ArgsMixin, PersonQuotaMixin):
|
|
629
553
|
"""
|
|
630
554
|
Get ended shots used for quota calculation of this month.
|
|
631
555
|
"""
|
|
@@ -656,6 +580,12 @@ class PersonMonthQuotaShotsResource(Resource, ArgsMixin):
|
|
|
656
580
|
x-example: 07
|
|
657
581
|
minimum: 1
|
|
658
582
|
maximum: 12
|
|
583
|
+
- in: query
|
|
584
|
+
name: count_mode
|
|
585
|
+
required: True
|
|
586
|
+
type: string
|
|
587
|
+
enum: [weighted, weigtheddone, feedback, done]
|
|
588
|
+
x-example: weighted
|
|
659
589
|
responses:
|
|
660
590
|
200:
|
|
661
591
|
description: Ended shots used for quota calculation of this month
|
|
@@ -663,10 +593,11 @@ class PersonMonthQuotaShotsResource(Resource, ArgsMixin):
|
|
|
663
593
|
description: Wrong date format
|
|
664
594
|
"""
|
|
665
595
|
user_service.check_person_is_not_bot(person_id)
|
|
666
|
-
project_id = self.get_project_id()
|
|
667
|
-
task_type_id = self.get_task_type_id()
|
|
668
596
|
user_service.check_person_access(person_id)
|
|
669
|
-
weighted =
|
|
597
|
+
(project_id, task_type_id, count_mode, feedback, weighted) = (
|
|
598
|
+
self.get_quota_arguments()
|
|
599
|
+
)
|
|
600
|
+
|
|
670
601
|
try:
|
|
671
602
|
return shots_service.get_month_quota_shots(
|
|
672
603
|
person_id,
|
|
@@ -675,12 +606,13 @@ class PersonMonthQuotaShotsResource(Resource, ArgsMixin):
|
|
|
675
606
|
project_id=project_id,
|
|
676
607
|
task_type_id=task_type_id,
|
|
677
608
|
weighted=weighted,
|
|
609
|
+
feedback=feedback,
|
|
678
610
|
)
|
|
679
611
|
except WrongDateFormatException:
|
|
680
612
|
abort(404)
|
|
681
613
|
|
|
682
614
|
|
|
683
|
-
class PersonWeekQuotaShotsResource(Resource, ArgsMixin):
|
|
615
|
+
class PersonWeekQuotaShotsResource(Resource, ArgsMixin, PersonQuotaMixin):
|
|
684
616
|
"""
|
|
685
617
|
Get ended shots used for quota calculation of this week.
|
|
686
618
|
"""
|
|
@@ -711,6 +643,12 @@ class PersonWeekQuotaShotsResource(Resource, ArgsMixin):
|
|
|
711
643
|
x-example: 35
|
|
712
644
|
minimum: 1
|
|
713
645
|
maximum: 52
|
|
646
|
+
- in: query
|
|
647
|
+
name: count_mode
|
|
648
|
+
required: True
|
|
649
|
+
type: string
|
|
650
|
+
enum: [weighted, weigtheddone, feedback, done]
|
|
651
|
+
x-example: weighted
|
|
714
652
|
responses:
|
|
715
653
|
200:
|
|
716
654
|
description: Ended shots used for quota calculation of this week
|
|
@@ -718,10 +656,11 @@ class PersonWeekQuotaShotsResource(Resource, ArgsMixin):
|
|
|
718
656
|
description: Wrong date format
|
|
719
657
|
"""
|
|
720
658
|
user_service.check_person_is_not_bot(person_id)
|
|
721
|
-
project_id = self.get_project_id()
|
|
722
|
-
task_type_id = self.get_task_type_id()
|
|
723
659
|
user_service.check_person_access(person_id)
|
|
724
|
-
weighted =
|
|
660
|
+
(project_id, task_type_id, count_mode, feedback, weighted) = (
|
|
661
|
+
self.get_quota_arguments()
|
|
662
|
+
)
|
|
663
|
+
|
|
725
664
|
try:
|
|
726
665
|
return shots_service.get_week_quota_shots(
|
|
727
666
|
person_id,
|
|
@@ -730,12 +669,13 @@ class PersonWeekQuotaShotsResource(Resource, ArgsMixin):
|
|
|
730
669
|
project_id=project_id,
|
|
731
670
|
task_type_id=task_type_id,
|
|
732
671
|
weighted=weighted,
|
|
672
|
+
feedback=feedback,
|
|
733
673
|
)
|
|
734
674
|
except WrongDateFormatException:
|
|
735
675
|
abort(404)
|
|
736
676
|
|
|
737
677
|
|
|
738
|
-
class PersonDayQuotaShotsResource(Resource, ArgsMixin):
|
|
678
|
+
class PersonDayQuotaShotsResource(Resource, ArgsMixin, PersonQuotaMixin):
|
|
739
679
|
"""
|
|
740
680
|
Get ended shots used for quota calculation of this day.
|
|
741
681
|
"""
|
|
@@ -773,6 +713,12 @@ class PersonDayQuotaShotsResource(Resource, ArgsMixin):
|
|
|
773
713
|
x-example: 12
|
|
774
714
|
minimum: 1
|
|
775
715
|
maximum: 31
|
|
716
|
+
- in: query
|
|
717
|
+
name: count_mode
|
|
718
|
+
required: True
|
|
719
|
+
type: string
|
|
720
|
+
enum: [weighted, weigtheddone, feedback, done]
|
|
721
|
+
x-example: weighted
|
|
776
722
|
responses:
|
|
777
723
|
200:
|
|
778
724
|
description: Ended shots used for quota calculation of this day
|
|
@@ -780,10 +726,11 @@ class PersonDayQuotaShotsResource(Resource, ArgsMixin):
|
|
|
780
726
|
description: Wrong date format
|
|
781
727
|
"""
|
|
782
728
|
user_service.check_person_is_not_bot(person_id)
|
|
783
|
-
project_id = self.get_project_id()
|
|
784
|
-
task_type_id = self.get_task_type_id()
|
|
785
729
|
user_service.check_person_access(person_id)
|
|
786
|
-
weighted =
|
|
730
|
+
(project_id, task_type_id, count_mode, feedback, weighted) = (
|
|
731
|
+
self.get_quota_arguments()
|
|
732
|
+
)
|
|
733
|
+
|
|
787
734
|
try:
|
|
788
735
|
return shots_service.get_day_quota_shots(
|
|
789
736
|
person_id,
|
|
@@ -793,6 +740,7 @@ class PersonDayQuotaShotsResource(Resource, ArgsMixin):
|
|
|
793
740
|
project_id=project_id,
|
|
794
741
|
task_type_id=task_type_id,
|
|
795
742
|
weighted=weighted,
|
|
743
|
+
feedback=feedback,
|
|
796
744
|
)
|
|
797
745
|
except WrongDateFormatException:
|
|
798
746
|
abort(404)
|
|
@@ -806,7 +754,12 @@ class TimeSpentDurationResource(Resource, ArgsMixin):
|
|
|
806
754
|
def get_person_project_department_arguments(self):
|
|
807
755
|
project_id = self.get_project_id()
|
|
808
756
|
person_id = None
|
|
809
|
-
|
|
757
|
+
department_id = self.get_text_parameter("department_id")
|
|
758
|
+
if department_id is not None:
|
|
759
|
+
department_ids = [department_id]
|
|
760
|
+
else:
|
|
761
|
+
department_ids = None
|
|
762
|
+
studio_id = self.get_text_parameter("studio_id")
|
|
810
763
|
if not permissions.has_admin_permissions():
|
|
811
764
|
if (
|
|
812
765
|
permissions.has_manager_permissions()
|
|
@@ -820,9 +773,16 @@ class TimeSpentDurationResource(Resource, ArgsMixin):
|
|
|
820
773
|
elif project_id not in project_ids:
|
|
821
774
|
raise permissions.PermissionDenied
|
|
822
775
|
if permissions.has_supervisor_permissions():
|
|
823
|
-
|
|
776
|
+
persons_departments = persons_service.get_current_user(
|
|
824
777
|
relations=True
|
|
825
778
|
)["departments"]
|
|
779
|
+
if department_id is not None:
|
|
780
|
+
if department_id not in persons_departments:
|
|
781
|
+
raise WrongParameterException(
|
|
782
|
+
"Supervisor not allowed to access this department"
|
|
783
|
+
)
|
|
784
|
+
else:
|
|
785
|
+
department_ids = persons_departments
|
|
826
786
|
else:
|
|
827
787
|
person_id = persons_service.get_current_user()["id"]
|
|
828
788
|
|
|
@@ -830,6 +790,7 @@ class TimeSpentDurationResource(Resource, ArgsMixin):
|
|
|
830
790
|
"person_id": person_id,
|
|
831
791
|
"project_id": project_id,
|
|
832
792
|
"department_ids": department_ids,
|
|
793
|
+
"studio_id": studio_id,
|
|
833
794
|
}
|
|
834
795
|
|
|
835
796
|
|
|
@@ -1136,6 +1097,38 @@ class PersonYearDayOffResource(Resource, ArgsMixin):
|
|
|
1136
1097
|
)
|
|
1137
1098
|
|
|
1138
1099
|
|
|
1100
|
+
class PersonDayOffResource(Resource, ArgsMixin):
|
|
1101
|
+
"""
|
|
1102
|
+
Return all day offs recorded for given and person.
|
|
1103
|
+
"""
|
|
1104
|
+
|
|
1105
|
+
@jwt_required()
|
|
1106
|
+
def get(self, person_id):
|
|
1107
|
+
"""
|
|
1108
|
+
Return all day offs recorded for given and person.
|
|
1109
|
+
---
|
|
1110
|
+
tags:
|
|
1111
|
+
- Persons
|
|
1112
|
+
parameters:
|
|
1113
|
+
- in: path
|
|
1114
|
+
name: person_id
|
|
1115
|
+
required: True
|
|
1116
|
+
type: string
|
|
1117
|
+
format: UUID
|
|
1118
|
+
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
1119
|
+
responses:
|
|
1120
|
+
200:
|
|
1121
|
+
description: All day off recorded for given person.
|
|
1122
|
+
"""
|
|
1123
|
+
user_service.check_person_is_not_bot(person_id)
|
|
1124
|
+
user_id = persons_service.get_current_user()["id"]
|
|
1125
|
+
if person_id != user_id:
|
|
1126
|
+
permissions.check_admin_permissions()
|
|
1127
|
+
return time_spents_service.get_day_offs_between(
|
|
1128
|
+
person_id=person_id,
|
|
1129
|
+
)
|
|
1130
|
+
|
|
1131
|
+
|
|
1139
1132
|
class AddToDepartmentResource(Resource, ArgsMixin):
|
|
1140
1133
|
"""
|
|
1141
1134
|
Add a user to given department.
|
|
@@ -1261,6 +1254,11 @@ class ChangePasswordForPersonResource(Resource, ArgsMixin):
|
|
|
1261
1254
|
permissions.check_admin_permissions()
|
|
1262
1255
|
try:
|
|
1263
1256
|
person = persons_service.get_person(person_id)
|
|
1257
|
+
if (
|
|
1258
|
+
person["email"] in config.PROTECTED_ACCOUNTS
|
|
1259
|
+
and person["id"] != persons_service.get_current_user()["id"]
|
|
1260
|
+
):
|
|
1261
|
+
raise PersonInProtectedAccounts()
|
|
1264
1262
|
current_user = persons_service.get_current_user()
|
|
1265
1263
|
auth.validate_password(password, password_2)
|
|
1266
1264
|
password = auth.encrypt_password(password)
|
|
@@ -1271,7 +1269,7 @@ class ChangePasswordForPersonResource(Resource, ArgsMixin):
|
|
|
1271
1269
|
)
|
|
1272
1270
|
organisation = persons_service.get_organisation()
|
|
1273
1271
|
time_string = format_datetime(
|
|
1274
|
-
|
|
1272
|
+
date_helpers.get_utc_now_datetime(),
|
|
1275
1273
|
tzinfo=person["timezone"],
|
|
1276
1274
|
locale=person["locale"],
|
|
1277
1275
|
)
|
|
@@ -1304,6 +1302,14 @@ Thank you and see you soon on Kitsu,
|
|
|
1304
1302
|
return {"error": True, "message": "Password is too short."}, 400
|
|
1305
1303
|
except UnactiveUserException:
|
|
1306
1304
|
return {"error": True, "message": "User is unactive."}, 400
|
|
1305
|
+
except PersonInProtectedAccounts:
|
|
1306
|
+
return (
|
|
1307
|
+
{
|
|
1308
|
+
"error": True,
|
|
1309
|
+
"message": "This user is in protected accounts.",
|
|
1310
|
+
},
|
|
1311
|
+
400,
|
|
1312
|
+
)
|
|
1307
1313
|
|
|
1308
1314
|
def get_arguments(self):
|
|
1309
1315
|
args = self.get_args(
|
|
@@ -1365,7 +1371,7 @@ class DisableTwoFactorAuthenticationPersonResource(Resource, ArgsMixin):
|
|
|
1365
1371
|
)
|
|
1366
1372
|
organisation = persons_service.get_organisation()
|
|
1367
1373
|
time_string = format_datetime(
|
|
1368
|
-
|
|
1374
|
+
date_helpers.get_utc_now_datetime(),
|
|
1369
1375
|
tzinfo=person["timezone"],
|
|
1370
1376
|
locale=person["locale"],
|
|
1371
1377
|
)
|
|
@@ -2,6 +2,9 @@ from flask import Blueprint
|
|
|
2
2
|
from zou.app.utils.api import configure_api_from_blueprint
|
|
3
3
|
|
|
4
4
|
from zou.app.blueprints.previews.resources import (
|
|
5
|
+
AddTaskBatchCommentResource,
|
|
6
|
+
AddTasksBatchCommentResource,
|
|
7
|
+
AttachmentThumbnailResource,
|
|
5
8
|
CreatePreviewFilePictureResource,
|
|
6
9
|
PreviewFileLowMovieResource,
|
|
7
10
|
PreviewFileMovieResource,
|
|
@@ -13,14 +16,13 @@ from zou.app.blueprints.previews.resources import (
|
|
|
13
16
|
PreviewFilePreviewResource,
|
|
14
17
|
PreviewFileOriginalResource,
|
|
15
18
|
PreviewFileTileResource,
|
|
16
|
-
CreateOrganisationThumbnailResource,
|
|
17
19
|
OrganisationThumbnailResource,
|
|
18
|
-
|
|
20
|
+
CreateOrganisationThumbnailResource,
|
|
19
21
|
ProjectThumbnailResource,
|
|
20
|
-
|
|
22
|
+
CreateProjectThumbnailResource,
|
|
21
23
|
PersonThumbnailResource,
|
|
24
|
+
CreatePersonThumbnailResource,
|
|
22
25
|
RunningPreviewFiles,
|
|
23
|
-
LegacySetMainPreviewResource,
|
|
24
26
|
SetMainPreviewResource,
|
|
25
27
|
UpdateAnnotationsResource,
|
|
26
28
|
UpdatePreviewPositionResource,
|
|
@@ -37,6 +39,14 @@ routes = [
|
|
|
37
39
|
"/pictures/preview-files/<instance_id>",
|
|
38
40
|
CreatePreviewFilePictureResource,
|
|
39
41
|
),
|
|
42
|
+
(
|
|
43
|
+
"/actions/tasks/<task_id>/batch-comment",
|
|
44
|
+
AddTaskBatchCommentResource,
|
|
45
|
+
),
|
|
46
|
+
(
|
|
47
|
+
"/actions/tasks/batch-comment",
|
|
48
|
+
AddTasksBatchCommentResource,
|
|
49
|
+
),
|
|
40
50
|
(
|
|
41
51
|
"/movies/originals/preview-files/<instance_id>.mp4",
|
|
42
52
|
PreviewFileMovieResource,
|
|
@@ -53,6 +63,10 @@ routes = [
|
|
|
53
63
|
"/pictures/thumbnails/preview-files/<instance_id>.png",
|
|
54
64
|
PreviewFileThumbnailResource,
|
|
55
65
|
),
|
|
66
|
+
(
|
|
67
|
+
"/pictures/thumbnails/attachment-files/<attachment_file_id>.png",
|
|
68
|
+
AttachmentThumbnailResource,
|
|
69
|
+
),
|
|
56
70
|
(
|
|
57
71
|
"/pictures/thumbnails-square/preview-files/<instance_id>.png",
|
|
58
72
|
PreviewFileThumbnailSquareResource,
|
|
@@ -113,10 +127,6 @@ routes = [
|
|
|
113
127
|
"/pictures/preview-background-files/<instance_id>.<extension>",
|
|
114
128
|
PreviewBackgroundFileResource,
|
|
115
129
|
),
|
|
116
|
-
(
|
|
117
|
-
"/actions/entities/<entity_id>/set-main-preview/<preview_file_id>",
|
|
118
|
-
LegacySetMainPreviewResource,
|
|
119
|
-
),
|
|
120
130
|
(
|
|
121
131
|
"/actions/preview-files/<preview_file_id>/set-main-preview",
|
|
122
132
|
SetMainPreviewResource,
|