zou 0.19.15__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} +82 -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/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.15.dist-info → zou-0.20.11.dist-info}/METADATA +75 -69
- {zou-0.19.15.dist-info → zou-0.20.11.dist-info}/RECORD +163 -134
- {zou-0.19.15.dist-info → zou-0.20.11.dist-info}/WHEEL +1 -1
- {zou-0.19.15.dist-info → zou-0.20.11.dist-info}/LICENSE +0 -0
- {zou-0.19.15.dist-info → zou-0.20.11.dist-info}/entry_points.txt +0 -0
- {zou-0.19.15.dist-info → zou-0.20.11.dist-info}/top_level.txt +0 -0
|
@@ -61,7 +61,7 @@ class EditsCsvExport(Resource):
|
|
|
61
61
|
def build_headers(self, metadata_infos, validation_columns):
|
|
62
62
|
headers = ["Project", "Episode", "Name", "Description", "Time Spent"]
|
|
63
63
|
|
|
64
|
-
metadata_headers = [name for (name, _) in metadata_infos]
|
|
64
|
+
metadata_headers = [name for (name, _, _) in metadata_infos]
|
|
65
65
|
|
|
66
66
|
validation_assignations_columns = []
|
|
67
67
|
for validation_column in validation_columns:
|
|
@@ -94,9 +94,15 @@ class EditsCsvExport(Resource):
|
|
|
94
94
|
]
|
|
95
95
|
)
|
|
96
96
|
|
|
97
|
-
|
|
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
|
|
|
@@ -100,7 +100,7 @@ class PlaylistCsvExport(Resource):
|
|
|
100
100
|
|
|
101
101
|
def build_row(self, shot):
|
|
102
102
|
entity = entities_service.get_entity(shot["entity_id"])
|
|
103
|
-
name, _ = names_service.get_full_entity_name(shot["entity_id"])
|
|
103
|
+
name, _, _ = names_service.get_full_entity_name(shot["entity_id"])
|
|
104
104
|
preview_file = files_service.get_preview_file(shot["preview_file_id"])
|
|
105
105
|
task = tasks_service.get_task(preview_file["task_id"])
|
|
106
106
|
task_type = self.task_type_map[task["task_type_id"]]
|
|
@@ -76,7 +76,7 @@ class ShotsCsvExport(Resource):
|
|
|
76
76
|
"FPS",
|
|
77
77
|
]
|
|
78
78
|
|
|
79
|
-
metadata_headers = [name for (name, _) in metadata_infos]
|
|
79
|
+
metadata_headers = [name for (name, _, _) in metadata_infos]
|
|
80
80
|
|
|
81
81
|
validation_assignations_columns = []
|
|
82
82
|
for validation_column in validation_columns:
|
|
@@ -123,9 +123,15 @@ class ShotsCsvExport(Resource):
|
|
|
123
123
|
for person_id in task["assignees"]
|
|
124
124
|
]
|
|
125
125
|
)
|
|
126
|
-
|
|
127
|
-
for _, field_name in metadata_infos:
|
|
128
|
-
|
|
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
|
|
|
@@ -72,7 +72,7 @@ class TimeSpentsCsvExport(BaseCsvExport):
|
|
|
72
72
|
person_last_name,
|
|
73
73
|
) = time_spent_row
|
|
74
74
|
if entity_type_name == "Shot":
|
|
75
|
-
entity_name, _ = names_service.get_full_entity_name(entity_id)
|
|
75
|
+
entity_name, _, _ = names_service.get_full_entity_name(entity_id)
|
|
76
76
|
|
|
77
77
|
date = ""
|
|
78
78
|
if time_spent.date is not None:
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import datetime
|
|
2
1
|
import os
|
|
3
2
|
|
|
4
3
|
from flask import request, abort, current_app
|
|
@@ -9,7 +8,7 @@ from flask_fs.errors import FileNotFound
|
|
|
9
8
|
from zou.app import config
|
|
10
9
|
|
|
11
10
|
from zou.app.mixin import ArgsMixin
|
|
12
|
-
from zou.app.utils import fs
|
|
11
|
+
from zou.app.utils import fs, date_helpers
|
|
13
12
|
from zou.app.stores import file_store
|
|
14
13
|
from zou.app.services import (
|
|
15
14
|
file_tree_service,
|
|
@@ -33,7 +32,10 @@ from zou.app.services.exception import (
|
|
|
33
32
|
|
|
34
33
|
|
|
35
34
|
def send_storage_file(
|
|
36
|
-
working_file_id,
|
|
35
|
+
working_file_id,
|
|
36
|
+
as_attachment=False,
|
|
37
|
+
max_age=config.CLIENT_CACHE_MAX_AGE,
|
|
38
|
+
last_modified=None,
|
|
37
39
|
):
|
|
38
40
|
"""
|
|
39
41
|
Send file from storage. If it's not a local storage, cache the file in
|
|
@@ -61,6 +63,7 @@ def send_storage_file(
|
|
|
61
63
|
as_attachment=as_attachment,
|
|
62
64
|
download_name=download_name,
|
|
63
65
|
max_age=max_age,
|
|
66
|
+
last_modified=last_modified,
|
|
64
67
|
)
|
|
65
68
|
except IOError as e:
|
|
66
69
|
current_app.logger.error(e)
|
|
@@ -88,9 +91,7 @@ class WorkingFileFileResource(Resource):
|
|
|
88
91
|
|
|
89
92
|
def check_access(self, working_file_id):
|
|
90
93
|
working_file = files_service.get_working_file(working_file_id)
|
|
91
|
-
|
|
92
|
-
user_service.check_project_access(task["project_id"])
|
|
93
|
-
user_service.check_entity_access(task["entity_id"])
|
|
94
|
+
user_service.check_task_access(working_file["task_id"])
|
|
94
95
|
return working_file
|
|
95
96
|
|
|
96
97
|
def save_uploaded_file_in_temporary_folder(self, working_file_id):
|
|
@@ -126,8 +127,13 @@ class WorkingFileFileResource(Resource):
|
|
|
126
127
|
schema:
|
|
127
128
|
type: file
|
|
128
129
|
"""
|
|
129
|
-
self.check_access(working_file_id)
|
|
130
|
-
return send_storage_file(
|
|
130
|
+
working_file = self.check_access(working_file_id)
|
|
131
|
+
return send_storage_file(
|
|
132
|
+
working_file_id,
|
|
133
|
+
last_modified=date_helpers.get_datetime_from_string(
|
|
134
|
+
working_file["updated_at"]
|
|
135
|
+
),
|
|
136
|
+
)
|
|
131
137
|
|
|
132
138
|
@jwt_required()
|
|
133
139
|
def post(self, working_file_id):
|
|
@@ -548,10 +554,8 @@ class LastWorkingFilesResource(Resource):
|
|
|
548
554
|
description: Last working files revision for each file name for given task
|
|
549
555
|
"""
|
|
550
556
|
result = {}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
user_service.check_entity_access(task["entity_id"])
|
|
554
|
-
result = files_service.get_last_working_files_for_task(task["id"])
|
|
557
|
+
user_service.check_task_access(task_id)
|
|
558
|
+
result = files_service.get_last_working_files_for_task(task_id)
|
|
555
559
|
|
|
556
560
|
return result
|
|
557
561
|
|
|
@@ -580,10 +584,8 @@ class TaskWorkingFilesResource(Resource):
|
|
|
580
584
|
description: Last working files revision for each file name for given task
|
|
581
585
|
"""
|
|
582
586
|
result = {}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
user_service.check_entity_access(task["entity_id"])
|
|
586
|
-
result = files_service.get_working_files_for_task(task["id"])
|
|
587
|
+
user_service.check_task_access(task_id)
|
|
588
|
+
result = files_service.get_working_files_for_task(task_id)
|
|
587
589
|
|
|
588
590
|
return result
|
|
589
591
|
|
|
@@ -766,11 +768,10 @@ class ModifiedFileResource(Resource):
|
|
|
766
768
|
description: Working file modification date updated
|
|
767
769
|
"""
|
|
768
770
|
working_file = files_service.get_working_file(working_file_id)
|
|
769
|
-
|
|
770
|
-
user_service.check_project_access(task["project_id"])
|
|
771
|
-
user_service.check_entity_access(task["entity_id"])
|
|
771
|
+
user_service.check_task_access(working_file["task_id"])
|
|
772
772
|
working_file = files_service.update_working_file(
|
|
773
|
-
working_file_id,
|
|
773
|
+
working_file_id,
|
|
774
|
+
{"updated_at": date_helpers.get_utc_now_datetime()},
|
|
774
775
|
)
|
|
775
776
|
return working_file
|
|
776
777
|
|
|
@@ -818,9 +819,7 @@ class CommentWorkingFileResource(Resource, ArgsMixin):
|
|
|
818
819
|
)
|
|
819
820
|
|
|
820
821
|
working_file = files_service.get_working_file(working_file_id)
|
|
821
|
-
|
|
822
|
-
user_service.check_project_access(task["project_id"])
|
|
823
|
-
user_service.check_entity_access(task["entity_id"])
|
|
822
|
+
user_service.check_task_access(working_file["task_id"])
|
|
824
823
|
working_file = self.update_comment(working_file_id, args["comment"])
|
|
825
824
|
return working_file
|
|
826
825
|
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import psutil
|
|
2
2
|
import redis
|
|
3
3
|
import requests
|
|
4
|
-
|
|
5
|
-
from datetime import datetime
|
|
4
|
+
import datetime
|
|
6
5
|
|
|
7
6
|
from flask import Response, abort
|
|
8
7
|
from flask_restful import Resource
|
|
9
8
|
from zou import __version__
|
|
10
9
|
|
|
11
10
|
from zou.app import app, config
|
|
12
|
-
from zou.app.utils import permissions, shell
|
|
13
|
-
from zou.app.services import projects_service, stats_service
|
|
14
|
-
|
|
11
|
+
from zou.app.utils import permissions, shell, date_helpers
|
|
12
|
+
from zou.app.services import projects_service, stats_service, persons_service
|
|
15
13
|
from flask_jwt_extended import jwt_required
|
|
14
|
+
from zou.app.utils.redis import get_redis_url
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
class IndexResource(Resource):
|
|
@@ -26,7 +25,7 @@ class IndexResource(Resource):
|
|
|
26
25
|
200:
|
|
27
26
|
description: API name and version
|
|
28
27
|
"""
|
|
29
|
-
return {"api":
|
|
28
|
+
return {"api": config.APP_NAME, "version": __version__}
|
|
30
29
|
|
|
31
30
|
|
|
32
31
|
class BaseStatusResource(Resource):
|
|
@@ -43,6 +42,7 @@ class BaseStatusResource(Resource):
|
|
|
43
42
|
host=config.KEY_VALUE_STORE["host"],
|
|
44
43
|
port=config.KEY_VALUE_STORE["port"],
|
|
45
44
|
db=config.AUTH_TOKEN_BLACKLIST_KV_INDEX,
|
|
45
|
+
password=config.KEY_VALUE_STORE["password"],
|
|
46
46
|
decode_responses=True,
|
|
47
47
|
)
|
|
48
48
|
store.get("test")
|
|
@@ -62,11 +62,12 @@ class BaseStatusResource(Resource):
|
|
|
62
62
|
|
|
63
63
|
is_jq_up = True
|
|
64
64
|
try:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
args = [
|
|
66
|
+
"rq",
|
|
67
|
+
"info",
|
|
68
|
+
"--url",
|
|
69
|
+
get_redis_url(config.KV_JOB_DB_INDEX),
|
|
70
|
+
]
|
|
70
71
|
out = shell.run_command(args)
|
|
71
72
|
is_jq_up = b"0 workers" not in out
|
|
72
73
|
except Exception:
|
|
@@ -87,10 +88,8 @@ class BaseStatusResource(Resource):
|
|
|
87
88
|
|
|
88
89
|
version = __version__
|
|
89
90
|
|
|
90
|
-
api_name = app.config["APP_NAME"]
|
|
91
|
-
|
|
92
91
|
return (
|
|
93
|
-
|
|
92
|
+
config.APP_NAME,
|
|
94
93
|
version,
|
|
95
94
|
is_db_up,
|
|
96
95
|
is_kv_up,
|
|
@@ -231,8 +230,8 @@ class InfluxStatusResource(BaseStatusResource):
|
|
|
231
230
|
description: Status of database, key value, event stream, job queue and time
|
|
232
231
|
"""
|
|
233
232
|
(
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
_,
|
|
234
|
+
_,
|
|
236
235
|
is_db_up,
|
|
237
236
|
is_kv_up,
|
|
238
237
|
is_es_up,
|
|
@@ -246,7 +245,9 @@ class InfluxStatusResource(BaseStatusResource):
|
|
|
246
245
|
"event-stream-up": int(is_es_up),
|
|
247
246
|
"job-queue-up": int(is_jq_up),
|
|
248
247
|
"indexer-up": int(is_indexer_up),
|
|
249
|
-
"time": datetime.
|
|
248
|
+
"time": datetime.datetime.timestamp(
|
|
249
|
+
date_helpers.get_utc_now_datetime()
|
|
250
|
+
),
|
|
250
251
|
}
|
|
251
252
|
|
|
252
253
|
|
|
@@ -272,28 +273,36 @@ class StatsResource(Resource):
|
|
|
272
273
|
class ConfigResource(Resource):
|
|
273
274
|
def get(self):
|
|
274
275
|
"""
|
|
275
|
-
Get
|
|
276
|
+
Get basic configuration for the current instance.
|
|
276
277
|
---
|
|
277
278
|
tags:
|
|
278
279
|
- Index
|
|
279
280
|
responses:
|
|
280
281
|
200:
|
|
281
|
-
description:
|
|
282
|
+
description: Configuration object including self-hosted status,
|
|
283
|
+
Crisp token, indexer configuration, SAML status, and dark
|
|
284
|
+
theme status.
|
|
282
285
|
"""
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
"
|
|
286
|
+
organisation = persons_service.get_organisation()
|
|
287
|
+
conf = {
|
|
288
|
+
"is_self_hosted": config.IS_SELF_HOSTED,
|
|
289
|
+
"crisp_token": config.CRISP_TOKEN,
|
|
290
|
+
"dark_theme_by_default": organisation["dark_theme_by_default"],
|
|
286
291
|
"indexer_configured": (
|
|
287
|
-
len(
|
|
288
|
-
and
|
|
292
|
+
len(config.INDEXER["key"]) > 0
|
|
293
|
+
and config.INDEXER["key"] != "masterkey"
|
|
289
294
|
),
|
|
295
|
+
"saml_enabled": config.SAML_ENABLED,
|
|
296
|
+
"saml_idp_name": config.SAML_IDP_NAME,
|
|
297
|
+
"default_locale": config.DEFAULT_LOCALE,
|
|
298
|
+
"default_timezone": config.DEFAULT_TIMEZONE,
|
|
290
299
|
}
|
|
291
|
-
if
|
|
292
|
-
|
|
293
|
-
"dsn":
|
|
294
|
-
"sampleRate":
|
|
300
|
+
if config.SENTRY_KITSU_ENABLED:
|
|
301
|
+
conf["sentry"] = {
|
|
302
|
+
"dsn": config.SENTRY_KITSU_DSN,
|
|
303
|
+
"sampleRate": config.SENTRY_KITSU_SR,
|
|
295
304
|
}
|
|
296
|
-
return
|
|
305
|
+
return conf
|
|
297
306
|
|
|
298
307
|
|
|
299
308
|
class TestEventsResource(Resource):
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
from flask_restful import Resource
|
|
1
|
+
from flask_restful import Resource, inputs
|
|
2
2
|
from flask_jwt_extended import jwt_required
|
|
3
3
|
|
|
4
4
|
from zou.app.mixin import ArgsMixin
|
|
5
|
-
from zou.app.services import
|
|
5
|
+
from zou.app.services import (
|
|
6
|
+
news_service,
|
|
7
|
+
projects_service,
|
|
8
|
+
user_service,
|
|
9
|
+
persons_service,
|
|
10
|
+
)
|
|
6
11
|
from zou.app.services.exception import NewsNotFoundException
|
|
7
12
|
from zou.app.utils import permissions
|
|
8
13
|
|
|
9
14
|
|
|
10
|
-
class NewsMixin:
|
|
15
|
+
class NewsMixin(ArgsMixin):
|
|
11
16
|
def get_news(self, project_ids=[]):
|
|
12
17
|
(
|
|
13
18
|
only_preview,
|
|
@@ -16,12 +21,13 @@ class NewsMixin:
|
|
|
16
21
|
episode_id,
|
|
17
22
|
person_id,
|
|
18
23
|
page,
|
|
19
|
-
|
|
24
|
+
limit,
|
|
20
25
|
after,
|
|
21
26
|
before,
|
|
22
27
|
) = self.get_arguments()
|
|
23
28
|
|
|
24
|
-
|
|
29
|
+
current_user = persons_service.get_current_user_raw()
|
|
30
|
+
|
|
25
31
|
after = self.parse_date_parameter(after)
|
|
26
32
|
before = self.parse_date_parameter(before)
|
|
27
33
|
result = news_service.get_last_news_for_project(
|
|
@@ -32,18 +38,21 @@ class NewsMixin:
|
|
|
32
38
|
episode_id=episode_id,
|
|
33
39
|
author_id=person_id,
|
|
34
40
|
page=page,
|
|
35
|
-
|
|
41
|
+
limit=limit,
|
|
36
42
|
after=after,
|
|
37
43
|
before=before,
|
|
44
|
+
current_user=current_user,
|
|
38
45
|
)
|
|
39
46
|
stats = news_service.get_news_stats_for_project(
|
|
40
47
|
project_ids=project_ids,
|
|
48
|
+
only_preview=only_preview,
|
|
41
49
|
task_type_id=task_type_id,
|
|
42
50
|
task_status_id=task_status_id,
|
|
43
51
|
episode_id=episode_id,
|
|
44
52
|
author_id=person_id,
|
|
45
53
|
after=after,
|
|
46
54
|
before=before,
|
|
55
|
+
current_user=current_user,
|
|
47
56
|
)
|
|
48
57
|
result["stats"] = stats
|
|
49
58
|
return result
|
|
@@ -51,14 +60,19 @@ class NewsMixin:
|
|
|
51
60
|
def get_arguments(self):
|
|
52
61
|
args = self.get_args(
|
|
53
62
|
[
|
|
54
|
-
|
|
63
|
+
(
|
|
64
|
+
"only_preview",
|
|
65
|
+
False,
|
|
66
|
+
False,
|
|
67
|
+
inputs.boolean,
|
|
68
|
+
),
|
|
55
69
|
"task_type_id",
|
|
56
70
|
"task_status_id",
|
|
57
71
|
"person_id",
|
|
58
72
|
"project_id",
|
|
59
73
|
"episode_id",
|
|
60
74
|
{"name": "page", "default": 1, "type": int},
|
|
61
|
-
{"name": "
|
|
75
|
+
{"name": "limit", "default": 50, "type": int},
|
|
62
76
|
"after",
|
|
63
77
|
"before",
|
|
64
78
|
],
|
|
@@ -70,7 +84,7 @@ class NewsMixin:
|
|
|
70
84
|
args["episode_id"],
|
|
71
85
|
args["person_id"],
|
|
72
86
|
args["page"],
|
|
73
|
-
args["
|
|
87
|
+
args["limit"],
|
|
74
88
|
args["after"],
|
|
75
89
|
args["before"],
|
|
76
90
|
)
|
|
@@ -106,7 +120,7 @@ class ProjectNewsResource(Resource, NewsMixin, ArgsMixin):
|
|
|
106
120
|
type: integer
|
|
107
121
|
x-example: 1
|
|
108
122
|
- in: query
|
|
109
|
-
name:
|
|
123
|
+
name: limit
|
|
110
124
|
type: integer
|
|
111
125
|
x-example: 50
|
|
112
126
|
- in: query
|
|
@@ -169,7 +183,7 @@ class NewsResource(Resource, NewsMixin, ArgsMixin):
|
|
|
169
183
|
type: integer
|
|
170
184
|
x-example: 1
|
|
171
185
|
- in: query
|
|
172
|
-
name:
|
|
186
|
+
name: limit
|
|
173
187
|
type: integer
|
|
174
188
|
x-example: 50
|
|
175
189
|
- in: query
|
|
@@ -7,7 +7,6 @@ from zou.app.blueprints.persons.resources import (
|
|
|
7
7
|
DayOffForMonthResource,
|
|
8
8
|
DesktopLoginsResource,
|
|
9
9
|
InvitePersonResource,
|
|
10
|
-
NewPersonResource,
|
|
11
10
|
PersonMonthQuotaShotsResource,
|
|
12
11
|
PersonWeekQuotaShotsResource,
|
|
13
12
|
PersonDayQuotaShotsResource,
|
|
@@ -17,6 +16,7 @@ from zou.app.blueprints.persons.resources import (
|
|
|
17
16
|
PersonDayTimeSpentsResource,
|
|
18
17
|
PersonWeekDayOffResource,
|
|
19
18
|
PersonYearDayOffResource,
|
|
19
|
+
PersonDayOffResource,
|
|
20
20
|
PersonMonthDayOffResource,
|
|
21
21
|
PresenceLogsResource,
|
|
22
22
|
TimeSpentsResource,
|
|
@@ -33,7 +33,6 @@ from zou.app.blueprints.persons.resources import (
|
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
routes = [
|
|
36
|
-
("/data/persons/new", NewPersonResource),
|
|
37
36
|
("/data/persons/<person_id>/desktop-login-logs", DesktopLoginsResource),
|
|
38
37
|
("/data/persons/presence-logs/<month_date>", PresenceLogsResource),
|
|
39
38
|
("/data/persons/<person_id>/time-spents", TimeSpentsResource),
|
|
@@ -91,6 +90,10 @@ routes = [
|
|
|
91
90
|
"/data/persons/<person_id>/day-offs/year/<year>",
|
|
92
91
|
PersonYearDayOffResource,
|
|
93
92
|
),
|
|
93
|
+
(
|
|
94
|
+
"/data/persons/<person_id>/day-offs",
|
|
95
|
+
PersonDayOffResource,
|
|
96
|
+
),
|
|
94
97
|
("/actions/persons/<person_id>/invite", InvitePersonResource),
|
|
95
98
|
("/actions/persons/<person_id>/departments/add", AddToDepartmentResource),
|
|
96
99
|
(
|