zou 0.19.45__py3-none-any.whl → 0.19.47__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/blueprints/auth/resources.py +0 -2
- zou/app/blueprints/comments/resources.py +4 -1
- zou/app/blueprints/crud/entity.py +5 -5
- zou/app/blueprints/crud/organisation.py +6 -0
- zou/app/blueprints/events/resources.py +2 -4
- zou/app/blueprints/files/resources.py +12 -3
- zou/app/blueprints/previews/__init__.py +3 -8
- zou/app/blueprints/previews/resources.py +192 -224
- zou/app/blueprints/shots/__init__.py +1 -1
- zou/app/blueprints/shots/resources.py +4 -5
- zou/app/mixin.py +3 -3
- zou/app/models/organisation.py +2 -0
- zou/app/services/auth_service.py +0 -19
- zou/app/services/comments_service.py +2 -2
- zou/app/services/shots_service.py +15 -14
- zou/app/stores/auth_tokens_store.py +1 -1
- {zou-0.19.45.dist-info → zou-0.19.47.dist-info}/METADATA +7 -6
- {zou-0.19.45.dist-info → zou-0.19.47.dist-info}/RECORD +23 -23
- {zou-0.19.45.dist-info → zou-0.19.47.dist-info}/WHEEL +1 -1
- {zou-0.19.45.dist-info → zou-0.19.47.dist-info}/LICENSE +0 -0
- {zou-0.19.45.dist-info → zou-0.19.47.dist-info}/entry_points.txt +0 -0
- {zou-0.19.45.dist-info → zou-0.19.47.dist-info}/top_level.txt +0 -0
zou/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.19.
|
|
1
|
+
__version__ = "0.19.47"
|
|
@@ -217,7 +217,6 @@ class LoginResource(Resource, ArgsMixin):
|
|
|
217
217
|
"identity_type": "person",
|
|
218
218
|
},
|
|
219
219
|
)
|
|
220
|
-
auth_service.register_tokens(app, access_token, refresh_token)
|
|
221
220
|
identity_changed.send(
|
|
222
221
|
current_app._get_current_object(),
|
|
223
222
|
identity=Identity(user["id"], "person"),
|
|
@@ -383,7 +382,6 @@ class RefreshTokenResource(Resource):
|
|
|
383
382
|
"identity_type": "person",
|
|
384
383
|
},
|
|
385
384
|
)
|
|
386
|
-
auth_service.register_tokens(app, access_token)
|
|
387
385
|
if is_from_browser(request.user_agent):
|
|
388
386
|
response = jsonify({"refresh": True})
|
|
389
387
|
set_access_cookies(response, access_token)
|
|
@@ -5,7 +5,7 @@ from flask_restful import Resource, reqparse
|
|
|
5
5
|
from flask_jwt_extended import jwt_required
|
|
6
6
|
|
|
7
7
|
from zou.app.mixin import ArgsMixin
|
|
8
|
-
from zou.app.utils import permissions
|
|
8
|
+
from zou.app.utils import permissions, date_helpers
|
|
9
9
|
|
|
10
10
|
from zou.app.services import (
|
|
11
11
|
chats_service,
|
|
@@ -80,6 +80,9 @@ class DownloadAttachmentResource(Resource):
|
|
|
80
80
|
as_attachment=False,
|
|
81
81
|
download_name=attachment_file["name"],
|
|
82
82
|
max_age=config.CLIENT_CACHE_MAX_AGE,
|
|
83
|
+
last_modified=date_helpers.get_datetime_from_string(
|
|
84
|
+
attachment_file["updated_at"]
|
|
85
|
+
),
|
|
83
86
|
)
|
|
84
87
|
except Exception:
|
|
85
88
|
current_app.logger.error(
|
|
@@ -23,7 +23,7 @@ from zou.app.services import (
|
|
|
23
23
|
user_service,
|
|
24
24
|
concepts_service,
|
|
25
25
|
)
|
|
26
|
-
from zou.app.utils import events,
|
|
26
|
+
from zou.app.utils import events, date_helpers
|
|
27
27
|
|
|
28
28
|
from werkzeug.exceptions import NotFound
|
|
29
29
|
|
|
@@ -187,11 +187,11 @@ class EntityResource(BaseModelResource, EntityEventMixin):
|
|
|
187
187
|
version = None
|
|
188
188
|
if frame_in != pframe_in or frame_out != pframe_out or name != pname:
|
|
189
189
|
current_user_id = persons_service.get_current_user()["id"]
|
|
190
|
-
previous_updated_at =
|
|
191
|
-
previous_shot["updated_at"]
|
|
190
|
+
previous_updated_at = date_helpers.get_datetime_from_string(
|
|
191
|
+
previous_shot["updated_at"]
|
|
192
192
|
)
|
|
193
|
-
updated_at =
|
|
194
|
-
shot["updated_at"]
|
|
193
|
+
updated_at = date_helpers.get_datetime_from_string(
|
|
194
|
+
shot["updated_at"]
|
|
195
195
|
)
|
|
196
196
|
if (
|
|
197
197
|
date_helpers.get_date_diff(previous_updated_at, updated_at)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from zou.app.models.organisation import Organisation
|
|
2
2
|
from zou.app.blueprints.crud.base import BaseModelResource, BaseModelsResource
|
|
3
3
|
|
|
4
|
+
from zou.app.services import persons_service
|
|
5
|
+
|
|
4
6
|
|
|
5
7
|
class OrganisationsResource(BaseModelsResource):
|
|
6
8
|
def __init__(self):
|
|
@@ -21,3 +23,7 @@ class OrganisationResource(BaseModelResource):
|
|
|
21
23
|
if "hours_by_day" in data:
|
|
22
24
|
data["hours_by_day"] = float(data["hours_by_day"])
|
|
23
25
|
return data
|
|
26
|
+
|
|
27
|
+
def post_update(self, instance_dict, data):
|
|
28
|
+
persons_service.clear_oranisation_cache()
|
|
29
|
+
return instance_dict
|
|
@@ -2,7 +2,7 @@ from flask_restful import Resource
|
|
|
2
2
|
from flask_jwt_extended import jwt_required
|
|
3
3
|
|
|
4
4
|
from zou.app.mixin import ArgsMixin
|
|
5
|
-
from zou.app.utils import fields, permissions
|
|
5
|
+
from zou.app.utils import fields, permissions, date_helpers
|
|
6
6
|
|
|
7
7
|
from zou.app.services import events_service
|
|
8
8
|
from zou.app.services.exception import WrongParameterException
|
|
@@ -105,8 +105,6 @@ class LoginLogsResource(Resource, ArgsMixin):
|
|
|
105
105
|
permissions.check_manager_permissions()
|
|
106
106
|
before = None
|
|
107
107
|
if args["before"] is not None:
|
|
108
|
-
before =
|
|
109
|
-
args["before"], "%Y-%m-%dT%H:%M:%S"
|
|
110
|
-
)
|
|
108
|
+
before = date_helpers.get_datetime_from_string(args["before"])
|
|
111
109
|
page_size = args["page_size"]
|
|
112
110
|
return events_service.get_last_login_logs(before, page_size)
|
|
@@ -32,7 +32,10 @@ from zou.app.services.exception import (
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def send_storage_file(
|
|
35
|
-
working_file_id,
|
|
35
|
+
working_file_id,
|
|
36
|
+
as_attachment=False,
|
|
37
|
+
max_age=config.CLIENT_CACHE_MAX_AGE,
|
|
38
|
+
last_modified=None,
|
|
36
39
|
):
|
|
37
40
|
"""
|
|
38
41
|
Send file from storage. If it's not a local storage, cache the file in
|
|
@@ -60,6 +63,7 @@ def send_storage_file(
|
|
|
60
63
|
as_attachment=as_attachment,
|
|
61
64
|
download_name=download_name,
|
|
62
65
|
max_age=max_age,
|
|
66
|
+
last_modified=last_modified,
|
|
63
67
|
)
|
|
64
68
|
except IOError as e:
|
|
65
69
|
current_app.logger.error(e)
|
|
@@ -125,8 +129,13 @@ class WorkingFileFileResource(Resource):
|
|
|
125
129
|
schema:
|
|
126
130
|
type: file
|
|
127
131
|
"""
|
|
128
|
-
self.check_access(working_file_id)
|
|
129
|
-
return send_storage_file(
|
|
132
|
+
working_file = self.check_access(working_file_id)
|
|
133
|
+
return send_storage_file(
|
|
134
|
+
working_file_id,
|
|
135
|
+
last_modified=date_helpers.get_datetime_from_string(
|
|
136
|
+
working_file["updated_at"]
|
|
137
|
+
),
|
|
138
|
+
)
|
|
130
139
|
|
|
131
140
|
@jwt_required()
|
|
132
141
|
def post(self, working_file_id):
|
|
@@ -14,14 +14,13 @@ from zou.app.blueprints.previews.resources import (
|
|
|
14
14
|
PreviewFilePreviewResource,
|
|
15
15
|
PreviewFileOriginalResource,
|
|
16
16
|
PreviewFileTileResource,
|
|
17
|
-
CreateOrganisationThumbnailResource,
|
|
18
17
|
OrganisationThumbnailResource,
|
|
19
|
-
|
|
18
|
+
CreateOrganisationThumbnailResource,
|
|
20
19
|
ProjectThumbnailResource,
|
|
21
|
-
|
|
20
|
+
CreateProjectThumbnailResource,
|
|
22
21
|
PersonThumbnailResource,
|
|
22
|
+
CreatePersonThumbnailResource,
|
|
23
23
|
RunningPreviewFiles,
|
|
24
|
-
LegacySetMainPreviewResource,
|
|
25
24
|
SetMainPreviewResource,
|
|
26
25
|
UpdateAnnotationsResource,
|
|
27
26
|
UpdatePreviewPositionResource,
|
|
@@ -118,10 +117,6 @@ routes = [
|
|
|
118
117
|
"/pictures/preview-background-files/<instance_id>.<extension>",
|
|
119
118
|
PreviewBackgroundFileResource,
|
|
120
119
|
),
|
|
121
|
-
(
|
|
122
|
-
"/actions/entities/<entity_id>/set-main-preview/<preview_file_id>",
|
|
123
|
-
LegacySetMainPreviewResource,
|
|
124
|
-
),
|
|
125
120
|
(
|
|
126
121
|
"/actions/preview-files/<preview_file_id>/set-main-preview",
|
|
127
122
|
SetMainPreviewResource,
|
|
@@ -32,6 +32,7 @@ from zou.app.utils import (
|
|
|
32
32
|
events,
|
|
33
33
|
permissions,
|
|
34
34
|
thumbnail as thumbnail_utils,
|
|
35
|
+
date_helpers,
|
|
35
36
|
)
|
|
36
37
|
from zou.app.services.exception import (
|
|
37
38
|
ArgumentsException,
|
|
@@ -86,6 +87,7 @@ def send_standard_file(
|
|
|
86
87
|
extension,
|
|
87
88
|
mimetype="application/octet-stream",
|
|
88
89
|
as_attachment=False,
|
|
90
|
+
last_modified=None,
|
|
89
91
|
):
|
|
90
92
|
return send_storage_file(
|
|
91
93
|
file_store.get_local_file_path,
|
|
@@ -95,10 +97,13 @@ def send_standard_file(
|
|
|
95
97
|
extension,
|
|
96
98
|
mimetype=mimetype,
|
|
97
99
|
as_attachment=as_attachment,
|
|
100
|
+
last_modified=last_modified,
|
|
98
101
|
)
|
|
99
102
|
|
|
100
103
|
|
|
101
|
-
def send_movie_file(
|
|
104
|
+
def send_movie_file(
|
|
105
|
+
preview_file_id, as_attachment=False, lowdef=False, last_modified=None
|
|
106
|
+
):
|
|
102
107
|
folder = "previews"
|
|
103
108
|
if lowdef:
|
|
104
109
|
folder = "lowdef"
|
|
@@ -110,6 +115,7 @@ def send_movie_file(preview_file_id, as_attachment=False, lowdef=False):
|
|
|
110
115
|
"mp4",
|
|
111
116
|
mimetype="video/mp4",
|
|
112
117
|
as_attachment=as_attachment,
|
|
118
|
+
last_modified=last_modified,
|
|
113
119
|
)
|
|
114
120
|
|
|
115
121
|
|
|
@@ -119,6 +125,7 @@ def send_picture_file(
|
|
|
119
125
|
as_attachment=False,
|
|
120
126
|
extension="png",
|
|
121
127
|
download_name="",
|
|
128
|
+
last_modified=None,
|
|
122
129
|
):
|
|
123
130
|
if extension == "png":
|
|
124
131
|
mimetype = "image/png"
|
|
@@ -133,6 +140,7 @@ def send_picture_file(
|
|
|
133
140
|
mimetype=mimetype,
|
|
134
141
|
as_attachment=as_attachment,
|
|
135
142
|
download_name=download_name,
|
|
143
|
+
last_modified=last_modified,
|
|
136
144
|
)
|
|
137
145
|
|
|
138
146
|
|
|
@@ -146,6 +154,7 @@ def send_storage_file(
|
|
|
146
154
|
as_attachment=False,
|
|
147
155
|
max_age=config.CLIENT_CACHE_MAX_AGE,
|
|
148
156
|
download_name="",
|
|
157
|
+
last_modified=None,
|
|
149
158
|
):
|
|
150
159
|
"""
|
|
151
160
|
Send file from storage. If it's not a local storage, cache the file in
|
|
@@ -189,6 +198,7 @@ def send_storage_file(
|
|
|
189
198
|
as_attachment=as_attachment,
|
|
190
199
|
download_name=download_name,
|
|
191
200
|
max_age=max_age,
|
|
201
|
+
last_modified=last_modified,
|
|
192
202
|
)
|
|
193
203
|
except IOError as e:
|
|
194
204
|
current_app.logger.error(e)
|
|
@@ -410,26 +420,30 @@ class CreatePreviewFilePictureResource(Resource, ArgsMixin):
|
|
|
410
420
|
return files_service.get_preview_file(preview_file_id) is not None
|
|
411
421
|
|
|
412
422
|
|
|
413
|
-
class
|
|
423
|
+
class BasePreviewFileResource(Resource):
|
|
414
424
|
"""
|
|
415
|
-
|
|
425
|
+
Base class to download a preview file.
|
|
416
426
|
"""
|
|
417
427
|
|
|
418
428
|
def __init__(self):
|
|
419
429
|
Resource.__init__(self)
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
return files_service.get_preview_file(preview_file_id) is not None
|
|
430
|
+
self.preview_file = None
|
|
431
|
+
self.last_modified = None
|
|
423
432
|
|
|
424
433
|
def is_allowed(self, preview_file_id):
|
|
425
|
-
preview_file = files_service.get_preview_file(preview_file_id)
|
|
426
|
-
task = tasks_service.get_task(preview_file["task_id"])
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
434
|
+
self.preview_file = files_service.get_preview_file(preview_file_id)
|
|
435
|
+
task = tasks_service.get_task(self.preview_file["task_id"])
|
|
436
|
+
user_service.check_project_access(task["project_id"])
|
|
437
|
+
user_service.check_entity_access(task["entity_id"])
|
|
438
|
+
self.last_modified = date_helpers.get_datetime_from_string(
|
|
439
|
+
self.preview_file["updated_at"]
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
class PreviewFileMovieResource(BasePreviewFileResource):
|
|
444
|
+
"""
|
|
445
|
+
Allow to download a movie preview.
|
|
446
|
+
"""
|
|
433
447
|
|
|
434
448
|
@jwt_required()
|
|
435
449
|
def get(self, instance_id):
|
|
@@ -454,14 +468,12 @@ class PreviewFileMovieResource(Resource):
|
|
|
454
468
|
404:
|
|
455
469
|
description: File not found
|
|
456
470
|
"""
|
|
457
|
-
|
|
458
|
-
abort(404)
|
|
459
|
-
|
|
460
|
-
if not self.is_allowed(instance_id):
|
|
461
|
-
abort(403)
|
|
471
|
+
self.is_allowed(instance_id)
|
|
462
472
|
|
|
463
473
|
try:
|
|
464
|
-
return send_movie_file(
|
|
474
|
+
return send_movie_file(
|
|
475
|
+
instance_id, last_modified=self.last_modified
|
|
476
|
+
)
|
|
465
477
|
except FileNotFound:
|
|
466
478
|
current_app.logger.error(
|
|
467
479
|
"Movie file was not found for: %s" % instance_id
|
|
@@ -469,7 +481,7 @@ class PreviewFileMovieResource(Resource):
|
|
|
469
481
|
abort(404)
|
|
470
482
|
|
|
471
483
|
|
|
472
|
-
class PreviewFileLowMovieResource(
|
|
484
|
+
class PreviewFileLowMovieResource(BasePreviewFileResource):
|
|
473
485
|
"""
|
|
474
486
|
Allow to download a lowdef movie preview.
|
|
475
487
|
"""
|
|
@@ -496,14 +508,17 @@ class PreviewFileLowMovieResource(PreviewFileMovieResource):
|
|
|
496
508
|
404:
|
|
497
509
|
description: File not found
|
|
498
510
|
"""
|
|
499
|
-
|
|
500
|
-
abort(403)
|
|
511
|
+
self.is_allowed(instance_id)
|
|
501
512
|
|
|
502
513
|
try:
|
|
503
|
-
return send_movie_file(
|
|
514
|
+
return send_movie_file(
|
|
515
|
+
instance_id, lowdef=True, last_modified=self.last_modified
|
|
516
|
+
)
|
|
504
517
|
except Exception:
|
|
505
518
|
try:
|
|
506
|
-
return send_movie_file(
|
|
519
|
+
return send_movie_file(
|
|
520
|
+
instance_id, last_modified=self.last_modified
|
|
521
|
+
)
|
|
507
522
|
except FileNotFound:
|
|
508
523
|
current_app.logger.error(
|
|
509
524
|
"Movie file was not found for: %s" % instance_id
|
|
@@ -511,7 +526,7 @@ class PreviewFileLowMovieResource(PreviewFileMovieResource):
|
|
|
511
526
|
abort(404)
|
|
512
527
|
|
|
513
528
|
|
|
514
|
-
class PreviewFileMovieDownloadResource(
|
|
529
|
+
class PreviewFileMovieDownloadResource(BasePreviewFileResource):
|
|
515
530
|
"""
|
|
516
531
|
Allow to download a movie preview.
|
|
517
532
|
"""
|
|
@@ -538,11 +553,14 @@ class PreviewFileMovieDownloadResource(PreviewFileMovieResource):
|
|
|
538
553
|
404:
|
|
539
554
|
description: File not found
|
|
540
555
|
"""
|
|
541
|
-
|
|
542
|
-
abort(403)
|
|
556
|
+
self.is_allowed(instance_id)
|
|
543
557
|
|
|
544
558
|
try:
|
|
545
|
-
return send_movie_file(
|
|
559
|
+
return send_movie_file(
|
|
560
|
+
instance_id,
|
|
561
|
+
as_attachment=True,
|
|
562
|
+
last_modified=self.last_modified,
|
|
563
|
+
)
|
|
546
564
|
except FileNotFound:
|
|
547
565
|
current_app.logger.error(
|
|
548
566
|
"Movie file was not found for: %s" % instance_id
|
|
@@ -550,30 +568,11 @@ class PreviewFileMovieDownloadResource(PreviewFileMovieResource):
|
|
|
550
568
|
abort(404)
|
|
551
569
|
|
|
552
570
|
|
|
553
|
-
class PreviewFileResource(
|
|
571
|
+
class PreviewFileResource(BasePreviewFileResource):
|
|
554
572
|
"""
|
|
555
573
|
Allow to download a generic file preview.
|
|
556
574
|
"""
|
|
557
575
|
|
|
558
|
-
def __init__(self):
|
|
559
|
-
Resource.__init__(self)
|
|
560
|
-
|
|
561
|
-
def is_exist(self, preview_file_id):
|
|
562
|
-
return files_service.get_preview_file(preview_file_id) is not None
|
|
563
|
-
|
|
564
|
-
def is_allowed(self, preview_file_id):
|
|
565
|
-
if permissions.has_manager_permissions():
|
|
566
|
-
return True
|
|
567
|
-
else:
|
|
568
|
-
preview_file = files_service.get_preview_file(preview_file_id)
|
|
569
|
-
task = tasks_service.get_task(preview_file["task_id"])
|
|
570
|
-
try:
|
|
571
|
-
user_service.check_project_access(task["project_id"])
|
|
572
|
-
user_service.check_entity_access(task["entity_id"])
|
|
573
|
-
return True
|
|
574
|
-
except permissions.PermissionDenied:
|
|
575
|
-
return False
|
|
576
|
-
|
|
577
576
|
@jwt_required()
|
|
578
577
|
def get(self, instance_id, extension):
|
|
579
578
|
"""
|
|
@@ -601,21 +600,26 @@ class PreviewFileResource(Resource):
|
|
|
601
600
|
404:
|
|
602
601
|
description: Non-movie file not found
|
|
603
602
|
"""
|
|
604
|
-
|
|
605
|
-
abort(404)
|
|
606
|
-
|
|
607
|
-
if not self.is_allowed(instance_id):
|
|
608
|
-
abort(403)
|
|
603
|
+
self.is_allowed(instance_id)
|
|
609
604
|
|
|
610
605
|
try:
|
|
611
606
|
extension = extension.lower()
|
|
612
607
|
if extension == "png":
|
|
613
|
-
return send_picture_file(
|
|
608
|
+
return send_picture_file(
|
|
609
|
+
"original", instance_id, last_modified=self.last_modified
|
|
610
|
+
)
|
|
614
611
|
elif extension == "pdf":
|
|
615
612
|
mimetype = "application/pdf"
|
|
616
|
-
return send_standard_file(
|
|
613
|
+
return send_standard_file(
|
|
614
|
+
instance_id,
|
|
615
|
+
extension,
|
|
616
|
+
mimetype,
|
|
617
|
+
last_modified=self.last_modified,
|
|
618
|
+
)
|
|
617
619
|
else:
|
|
618
|
-
return send_standard_file(
|
|
620
|
+
return send_standard_file(
|
|
621
|
+
instance_id, extension, last_modified=self.last_modified
|
|
622
|
+
)
|
|
619
623
|
|
|
620
624
|
except FileNotFound:
|
|
621
625
|
current_app.logger.error(
|
|
@@ -624,14 +628,11 @@ class PreviewFileResource(Resource):
|
|
|
624
628
|
abort(404)
|
|
625
629
|
|
|
626
630
|
|
|
627
|
-
class PreviewFileDownloadResource(
|
|
631
|
+
class PreviewFileDownloadResource(BasePreviewFileResource):
|
|
628
632
|
"""
|
|
629
633
|
Allow to download a generic file preview as attachment.
|
|
630
634
|
"""
|
|
631
635
|
|
|
632
|
-
def __init__(self):
|
|
633
|
-
PreviewFileResource.__init__(self)
|
|
634
|
-
|
|
635
636
|
@jwt_required()
|
|
636
637
|
def get(self, instance_id):
|
|
637
638
|
"""
|
|
@@ -654,29 +655,40 @@ class PreviewFileDownloadResource(PreviewFileResource):
|
|
|
654
655
|
404:
|
|
655
656
|
description: Standard file not found
|
|
656
657
|
"""
|
|
657
|
-
|
|
658
|
-
abort(403)
|
|
658
|
+
self.is_allowed(instance_id)
|
|
659
659
|
|
|
660
|
-
|
|
661
|
-
extension = preview_file["extension"]
|
|
660
|
+
extension = self.preview_file["extension"]
|
|
662
661
|
|
|
663
662
|
try:
|
|
664
663
|
if extension == "png":
|
|
665
664
|
return send_picture_file(
|
|
666
|
-
"original",
|
|
665
|
+
"original",
|
|
666
|
+
instance_id,
|
|
667
|
+
as_attachment=True,
|
|
668
|
+
last_modified=self.last_modified,
|
|
667
669
|
)
|
|
668
670
|
elif extension == "pdf":
|
|
669
671
|
mimetype = "application/pdf"
|
|
670
672
|
return send_standard_file(
|
|
671
|
-
instance_id,
|
|
673
|
+
instance_id,
|
|
674
|
+
extension,
|
|
675
|
+
mimetype,
|
|
676
|
+
as_attachment=True,
|
|
677
|
+
last_modified=self.last_modified,
|
|
672
678
|
)
|
|
673
679
|
if extension == "mp4":
|
|
674
680
|
return send_picture_file(
|
|
675
|
-
"original",
|
|
681
|
+
"original",
|
|
682
|
+
instance_id,
|
|
683
|
+
as_attachment=True,
|
|
684
|
+
last_modified=self.last_modified,
|
|
676
685
|
)
|
|
677
686
|
else:
|
|
678
687
|
return send_standard_file(
|
|
679
|
-
instance_id,
|
|
688
|
+
instance_id,
|
|
689
|
+
extension,
|
|
690
|
+
as_attachment=True,
|
|
691
|
+
last_modified=self.last_modified,
|
|
680
692
|
)
|
|
681
693
|
except FileNotFound:
|
|
682
694
|
current_app.logger.error(
|
|
@@ -687,26 +699,31 @@ class PreviewFileDownloadResource(PreviewFileResource):
|
|
|
687
699
|
|
|
688
700
|
class AttachmentThumbnailResource(Resource):
|
|
689
701
|
|
|
690
|
-
def
|
|
691
|
-
|
|
702
|
+
def __init__(self):
|
|
703
|
+
Resource.__init__(self)
|
|
704
|
+
self.attachment_file = None
|
|
692
705
|
|
|
693
706
|
def is_allowed(self, attachment_id):
|
|
694
|
-
attachment_file = comments_service.get_attachment_file(
|
|
695
|
-
|
|
696
|
-
|
|
707
|
+
self.attachment_file = comments_service.get_attachment_file(
|
|
708
|
+
attachment_id
|
|
709
|
+
)
|
|
710
|
+
if self.attachment_file["comment_id"] is not None:
|
|
711
|
+
comment = tasks_service.get_comment(
|
|
712
|
+
self.attachment_file["comment_id"]
|
|
713
|
+
)
|
|
697
714
|
task = tasks_service.get_task(comment["object_id"])
|
|
698
715
|
user_service.check_project_access(task["project_id"])
|
|
699
716
|
user_service.check_entity_access(task["entity_id"])
|
|
700
|
-
elif attachment_file["chat_message_id"] is not None:
|
|
717
|
+
elif self.attachment_file["chat_message_id"] is not None:
|
|
701
718
|
message = chats_service.get_chat_message(
|
|
702
|
-
attachment_file["chat_message_id"]
|
|
719
|
+
self.attachment_file["chat_message_id"]
|
|
703
720
|
)
|
|
704
721
|
chat = chats_service.get_chat_by_id(message["chat_id"])
|
|
705
722
|
entity = entities_service.get_entity(chat["object_id"])
|
|
706
723
|
user_service.check_project_access(entity["project_id"])
|
|
707
724
|
user_service.check_entity_access(chat["object_id"])
|
|
708
725
|
else:
|
|
709
|
-
|
|
726
|
+
raise permissions.PermissionDenied
|
|
710
727
|
return True
|
|
711
728
|
|
|
712
729
|
@jwt_required()
|
|
@@ -731,14 +748,16 @@ class AttachmentThumbnailResource(Resource):
|
|
|
731
748
|
404:
|
|
732
749
|
description: Picture file not found
|
|
733
750
|
"""
|
|
734
|
-
|
|
735
|
-
abort(404)
|
|
736
|
-
|
|
737
|
-
if not self.is_allowed(attachment_file_id):
|
|
738
|
-
abort(403)
|
|
751
|
+
self.is_allowed(attachment_file_id)
|
|
739
752
|
|
|
740
753
|
try:
|
|
741
|
-
return send_picture_file(
|
|
754
|
+
return send_picture_file(
|
|
755
|
+
"thumbnails",
|
|
756
|
+
attachment_file_id,
|
|
757
|
+
last_modified=date_helpers.get_datetime_from_string(
|
|
758
|
+
self.attachment_file["updated_at"]
|
|
759
|
+
),
|
|
760
|
+
)
|
|
742
761
|
except FileNotFound:
|
|
743
762
|
current_app.logger.error(
|
|
744
763
|
"Picture file was not found for attachment: %s"
|
|
@@ -747,31 +766,15 @@ class AttachmentThumbnailResource(Resource):
|
|
|
747
766
|
abort(404)
|
|
748
767
|
|
|
749
768
|
|
|
750
|
-
class BasePreviewPictureResource(
|
|
769
|
+
class BasePreviewPictureResource(BasePreviewFileResource):
|
|
751
770
|
"""
|
|
752
771
|
Base class to download a thumbnail.
|
|
753
772
|
"""
|
|
754
773
|
|
|
755
774
|
def __init__(self, picture_type):
|
|
756
|
-
|
|
775
|
+
BasePreviewFileResource.__init__(self)
|
|
757
776
|
self.picture_type = picture_type
|
|
758
777
|
|
|
759
|
-
def is_exist(self, preview_file_id):
|
|
760
|
-
return files_service.get_preview_file(preview_file_id) is not None
|
|
761
|
-
|
|
762
|
-
def is_allowed(self, preview_file_id):
|
|
763
|
-
if permissions.has_manager_permissions():
|
|
764
|
-
return True
|
|
765
|
-
else:
|
|
766
|
-
preview_file = files_service.get_preview_file(preview_file_id)
|
|
767
|
-
task = tasks_service.get_task(preview_file["task_id"])
|
|
768
|
-
try:
|
|
769
|
-
user_service.check_project_access(task["project_id"])
|
|
770
|
-
user_service.check_entity_access(task["entity_id"])
|
|
771
|
-
return True
|
|
772
|
-
except permissions.PermissionDenied:
|
|
773
|
-
return False
|
|
774
|
-
|
|
775
778
|
@jwt_required()
|
|
776
779
|
def get(self, instance_id):
|
|
777
780
|
"""
|
|
@@ -794,14 +797,14 @@ class BasePreviewPictureResource(Resource):
|
|
|
794
797
|
404:
|
|
795
798
|
description: Picture file not found
|
|
796
799
|
"""
|
|
797
|
-
|
|
798
|
-
abort(404)
|
|
799
|
-
|
|
800
|
-
if not self.is_allowed(instance_id):
|
|
801
|
-
abort(403)
|
|
800
|
+
self.is_allowed(instance_id)
|
|
802
801
|
|
|
803
802
|
try:
|
|
804
|
-
return send_picture_file(
|
|
803
|
+
return send_picture_file(
|
|
804
|
+
self.picture_type,
|
|
805
|
+
instance_id,
|
|
806
|
+
last_modified=self.last_modified,
|
|
807
|
+
)
|
|
805
808
|
except FileNotFound:
|
|
806
809
|
current_app.logger.error(
|
|
807
810
|
"Picture file was not found for: %s" % instance_id
|
|
@@ -838,21 +841,38 @@ class PreviewFileOriginalResource(BasePreviewPictureResource):
|
|
|
838
841
|
BasePreviewPictureResource.__init__(self, "original")
|
|
839
842
|
|
|
840
843
|
|
|
841
|
-
class
|
|
844
|
+
class BaseThumbnailResource(Resource):
|
|
842
845
|
"""
|
|
843
|
-
Base class to
|
|
846
|
+
Base class to post and get a thumbnail.
|
|
844
847
|
"""
|
|
845
848
|
|
|
846
|
-
def __init__(
|
|
849
|
+
def __init__(
|
|
850
|
+
self,
|
|
851
|
+
data_type,
|
|
852
|
+
get_model_func,
|
|
853
|
+
update_model_func,
|
|
854
|
+
size=thumbnail_utils.RECTANGLE_SIZE,
|
|
855
|
+
):
|
|
847
856
|
Resource.__init__(self)
|
|
848
857
|
self.data_type = data_type
|
|
858
|
+
self.get_model_func = get_model_func
|
|
859
|
+
self.update_model_func = update_model_func
|
|
849
860
|
self.size = size
|
|
861
|
+
self.model = None
|
|
862
|
+
self.last_modified = None
|
|
850
863
|
|
|
851
|
-
def
|
|
864
|
+
def is_exist(self, instance_id):
|
|
865
|
+
self.model = self.get_model_func(instance_id)
|
|
866
|
+
|
|
867
|
+
def check_allowed_to_post(self, instance_id):
|
|
852
868
|
permissions.check_admin_permissions()
|
|
853
869
|
|
|
870
|
+
def check_allowed_to_get(self, instance_id):
|
|
871
|
+
if not self.model["has_avatar"]:
|
|
872
|
+
raise NotFound
|
|
873
|
+
|
|
854
874
|
def prepare_creation(self, instance_id):
|
|
855
|
-
|
|
875
|
+
self.model = self.update_model_func(instance_id, {"has_avatar": True})
|
|
856
876
|
|
|
857
877
|
def emit_event(self, instance_id):
|
|
858
878
|
model_name = self.data_type[:-1]
|
|
@@ -889,10 +909,9 @@ class BaseCreatePictureResource(Resource):
|
|
|
889
909
|
404:
|
|
890
910
|
description: Cannot found related object.
|
|
891
911
|
"""
|
|
892
|
-
|
|
893
|
-
|
|
912
|
+
self.is_exist(instance_id)
|
|
913
|
+
self.check_allowed_to_post(instance_id)
|
|
894
914
|
|
|
895
|
-
self.check_permissions(instance_id)
|
|
896
915
|
self.prepare_creation(instance_id)
|
|
897
916
|
|
|
898
917
|
tmp_folder = config.TMP_DIR
|
|
@@ -915,18 +934,6 @@ class BaseCreatePictureResource(Resource):
|
|
|
915
934
|
self.emit_event(instance_id)
|
|
916
935
|
return {"thumbnail_path": thumbnail_url_path}, 201
|
|
917
936
|
|
|
918
|
-
|
|
919
|
-
class BasePictureResource(Resource):
|
|
920
|
-
"""
|
|
921
|
-
Base resource to download a thumbnail.
|
|
922
|
-
"""
|
|
923
|
-
|
|
924
|
-
def is_exist(self, instance_id):
|
|
925
|
-
return False
|
|
926
|
-
|
|
927
|
-
def is_allowed(self, instance_id):
|
|
928
|
-
return True
|
|
929
|
-
|
|
930
937
|
@jwt_required()
|
|
931
938
|
def get(self, instance_id):
|
|
932
939
|
"""
|
|
@@ -949,14 +956,17 @@ class BasePictureResource(Resource):
|
|
|
949
956
|
404:
|
|
950
957
|
description: Object instance not found
|
|
951
958
|
"""
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
if not self.is_allowed(instance_id):
|
|
956
|
-
abort(403)
|
|
959
|
+
self.is_exist(instance_id)
|
|
960
|
+
self.check_allowed_to_get(instance_id)
|
|
957
961
|
|
|
958
962
|
try:
|
|
959
|
-
return send_picture_file(
|
|
963
|
+
return send_picture_file(
|
|
964
|
+
"thumbnails",
|
|
965
|
+
instance_id,
|
|
966
|
+
last_modified=date_helpers.get_datetime_from_string(
|
|
967
|
+
self.model["updated_at"]
|
|
968
|
+
),
|
|
969
|
+
)
|
|
960
970
|
except FileNotFound:
|
|
961
971
|
current_app.logger.error(
|
|
962
972
|
"Thumbnail file was not found for: %s" % instance_id
|
|
@@ -969,114 +979,63 @@ class BasePictureResource(Resource):
|
|
|
969
979
|
abort(404)
|
|
970
980
|
|
|
971
981
|
|
|
972
|
-
class
|
|
982
|
+
class PersonThumbnailResource(BaseThumbnailResource):
|
|
973
983
|
def __init__(self):
|
|
974
|
-
|
|
975
|
-
self,
|
|
984
|
+
BaseThumbnailResource.__init__(
|
|
985
|
+
self,
|
|
986
|
+
"persons",
|
|
987
|
+
persons_service.get_person,
|
|
988
|
+
persons_service.update_person,
|
|
989
|
+
thumbnail_utils.BIG_SQUARE_SIZE,
|
|
976
990
|
)
|
|
977
991
|
|
|
978
|
-
def
|
|
979
|
-
return persons_service.get_person(person_id) is not None
|
|
980
|
-
|
|
981
|
-
def check_permissions(self, instance_id):
|
|
992
|
+
def check_allowed_to_post(self, instance_id):
|
|
982
993
|
is_current_user = (
|
|
983
|
-
persons_service.get_current_user()["id"]
|
|
994
|
+
persons_service.get_current_user()["id"] == instance_id
|
|
984
995
|
)
|
|
985
|
-
if is_current_user and not permissions.has_admin_permissions():
|
|
996
|
+
if not is_current_user and not permissions.has_admin_permissions():
|
|
986
997
|
raise permissions.PermissionDenied
|
|
987
998
|
|
|
988
|
-
def prepare_creation(self, instance_id):
|
|
989
|
-
return persons_service.update_person(instance_id, {"has_avatar": True})
|
|
990
999
|
|
|
1000
|
+
class CreatePersonThumbnailResource(PersonThumbnailResource):
|
|
1001
|
+
pass
|
|
991
1002
|
|
|
992
|
-
class PersonThumbnailResource(BasePictureResource):
|
|
993
|
-
def is_exist(self, person_id):
|
|
994
|
-
person = persons_service.get_person(person_id)
|
|
995
|
-
return person is not None and person["has_avatar"]
|
|
996
1003
|
|
|
1004
|
+
class OrganisationThumbnailResource(BaseThumbnailResource):
|
|
997
1005
|
|
|
998
|
-
class CreateOrganisationThumbnailResource(BaseCreatePictureResource):
|
|
999
1006
|
def __init__(self):
|
|
1000
|
-
|
|
1001
|
-
self,
|
|
1007
|
+
BaseThumbnailResource.__init__(
|
|
1008
|
+
self,
|
|
1009
|
+
"organisations",
|
|
1010
|
+
persons_service.get_organisation,
|
|
1011
|
+
persons_service.update_organisation,
|
|
1012
|
+
thumbnail_utils.BIG_SQUARE_SIZE,
|
|
1002
1013
|
)
|
|
1003
1014
|
|
|
1004
1015
|
def is_exist(self, organisation_id):
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
def check_permissions(self, organisation_id):
|
|
1008
|
-
if not permissions.has_admin_permissions():
|
|
1009
|
-
raise permissions.PermissionDenied
|
|
1010
|
-
|
|
1011
|
-
def prepare_creation(self, organisation_id):
|
|
1012
|
-
return persons_service.update_organisation(
|
|
1013
|
-
organisation_id, {"has_avatar": True}
|
|
1014
|
-
)
|
|
1016
|
+
self.model = persons_service.get_organisation()
|
|
1015
1017
|
|
|
1016
1018
|
|
|
1017
|
-
class OrganisationThumbnailResource
|
|
1018
|
-
|
|
1019
|
-
return True
|
|
1019
|
+
class CreateOrganisationThumbnailResource(OrganisationThumbnailResource):
|
|
1020
|
+
pass
|
|
1020
1021
|
|
|
1021
1022
|
|
|
1022
|
-
class
|
|
1023
|
+
class ProjectThumbnailResource(BaseThumbnailResource):
|
|
1023
1024
|
def __init__(self):
|
|
1024
|
-
|
|
1025
|
-
self,
|
|
1025
|
+
BaseThumbnailResource.__init__(
|
|
1026
|
+
self,
|
|
1027
|
+
"projects",
|
|
1028
|
+
projects_service.get_project,
|
|
1029
|
+
projects_service.update_project,
|
|
1026
1030
|
)
|
|
1027
1031
|
|
|
1028
|
-
def
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
def prepare_creation(self, instance_id):
|
|
1032
|
-
return projects_service.update_project(
|
|
1033
|
-
instance_id, {"has_avatar": True}
|
|
1034
|
-
)
|
|
1032
|
+
def check_allowed_to_get(self, instance_id):
|
|
1033
|
+
super().check_allowed_to_get(instance_id)
|
|
1034
|
+
user_service.check_project_access(instance_id)
|
|
1035
1035
|
|
|
1036
1036
|
|
|
1037
|
-
class ProjectThumbnailResource
|
|
1038
|
-
|
|
1039
|
-
return projects_service.get_project(project_id) is not None
|
|
1040
|
-
|
|
1041
|
-
def is_allowed(self, project_id):
|
|
1042
|
-
try:
|
|
1043
|
-
user_service.check_project_access(project_id)
|
|
1044
|
-
return True
|
|
1045
|
-
except permissions.PermissionDenied:
|
|
1046
|
-
return False
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
class LegacySetMainPreviewResource(Resource):
|
|
1050
|
-
@jwt_required()
|
|
1051
|
-
def put(self, entity_id, preview_file_id):
|
|
1052
|
-
"""
|
|
1053
|
-
Set main preview to given file.
|
|
1054
|
-
---
|
|
1055
|
-
tags:
|
|
1056
|
-
- Previews
|
|
1057
|
-
parameters:
|
|
1058
|
-
- in: path
|
|
1059
|
-
name: entity_id
|
|
1060
|
-
required: True
|
|
1061
|
-
type: string
|
|
1062
|
-
format: UUID
|
|
1063
|
-
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
1064
|
-
- in: path
|
|
1065
|
-
name: preview_file_id
|
|
1066
|
-
required: True
|
|
1067
|
-
type: string
|
|
1068
|
-
format: UUID
|
|
1069
|
-
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
1070
|
-
responses:
|
|
1071
|
-
200:
|
|
1072
|
-
description: Main preview set
|
|
1073
|
-
"""
|
|
1074
|
-
preview_file = files_service.get_preview_file(preview_file_id)
|
|
1075
|
-
task = tasks_service.get_task(preview_file["task_id"])
|
|
1076
|
-
user_service.check_project_access(task["project_id"])
|
|
1077
|
-
return entities_service.update_entity_preview(
|
|
1078
|
-
entity_id, preview_file_id
|
|
1079
|
-
)
|
|
1037
|
+
class CreateProjectThumbnailResource(ProjectThumbnailResource):
|
|
1038
|
+
pass
|
|
1080
1039
|
|
|
1081
1040
|
|
|
1082
1041
|
class SetMainPreviewResource(Resource, ArgsMixin):
|
|
@@ -1516,6 +1475,9 @@ class PreviewBackgroundFileResource(Resource):
|
|
|
1516
1475
|
instance_id,
|
|
1517
1476
|
extension=extension,
|
|
1518
1477
|
download_name=f"{preview_background_file['original_name']}.{extension}",
|
|
1478
|
+
last_modified=date_helpers.get_datetime_from_string(
|
|
1479
|
+
preview_background_file["updated_at"]
|
|
1480
|
+
),
|
|
1519
1481
|
)
|
|
1520
1482
|
except FileNotFound:
|
|
1521
1483
|
current_app.logger.error(
|
|
@@ -1524,11 +1486,17 @@ class PreviewBackgroundFileResource(Resource):
|
|
|
1524
1486
|
raise PreviewBackgroundFileNotFoundException
|
|
1525
1487
|
|
|
1526
1488
|
|
|
1527
|
-
class PreviewBackgroundFileThumbnailResource(
|
|
1528
|
-
def
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1489
|
+
class PreviewBackgroundFileThumbnailResource(BaseThumbnailResource):
|
|
1490
|
+
def __init__(self):
|
|
1491
|
+
BaseThumbnailResource.__init__(
|
|
1492
|
+
self,
|
|
1493
|
+
"preview-backgrounds",
|
|
1494
|
+
files_service.get_preview_background_file,
|
|
1495
|
+
files_service.update_preview_background_file,
|
|
1534
1496
|
)
|
|
1497
|
+
|
|
1498
|
+
def check_allowed_to_get(self, preview_background_file_id):
|
|
1499
|
+
return True
|
|
1500
|
+
|
|
1501
|
+
def post(self, preview_background_file_id):
|
|
1502
|
+
raise AttributeError("Method not allowed")
|
|
@@ -1529,7 +1529,6 @@ class ProjectQuotasResource(Resource, ArgsMixin):
|
|
|
1529
1529
|
)
|
|
1530
1530
|
|
|
1531
1531
|
|
|
1532
|
-
|
|
1533
1532
|
class SetShotsFramesResource(Resource, ArgsMixin):
|
|
1534
1533
|
@jwt_required()
|
|
1535
1534
|
def post(self, project_id, task_type_id):
|
|
@@ -1558,13 +1557,13 @@ class SetShotsFramesResource(Resource, ArgsMixin):
|
|
|
1558
1557
|
description: Frames set for given shots
|
|
1559
1558
|
"""
|
|
1560
1559
|
user_service.check_manager_project_access(project_id)
|
|
1561
|
-
if not fields.is_valid_id(task_type_id) or
|
|
1562
|
-
|
|
1560
|
+
if not fields.is_valid_id(task_type_id) or not fields.is_valid_id(
|
|
1561
|
+
project_id
|
|
1562
|
+
):
|
|
1563
1563
|
raise WrongParameterException("Invalid project or task type id")
|
|
1564
1564
|
|
|
1565
1565
|
episode_id = self.get_episode_id()
|
|
1566
|
-
if not episode_id in ["", None] and
|
|
1567
|
-
not fields.is_valid_id(episode_id):
|
|
1566
|
+
if not episode_id in ["", None] and not fields.is_valid_id(episode_id):
|
|
1568
1567
|
raise WrongParameterException("Invalid episode id")
|
|
1569
1568
|
|
|
1570
1569
|
if episode_id == "":
|
zou/app/mixin.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from flask_restful import reqparse
|
|
2
2
|
from flask import request
|
|
3
3
|
|
|
4
|
-
from zou.app.utils import
|
|
4
|
+
from zou.app.utils import date_helpers
|
|
5
5
|
from zou.app.services.exception import WrongParameterException
|
|
6
6
|
|
|
7
7
|
|
|
@@ -146,10 +146,10 @@ class ArgsMixin(object):
|
|
|
146
146
|
if param is None:
|
|
147
147
|
return date
|
|
148
148
|
try:
|
|
149
|
-
date =
|
|
149
|
+
date = date_helpers.get_datetime_from_string(param)
|
|
150
150
|
except Exception:
|
|
151
151
|
try:
|
|
152
|
-
date =
|
|
152
|
+
date = date_helpers.get_date_from_string(param)
|
|
153
153
|
except Exception:
|
|
154
154
|
raise WrongParameterException(
|
|
155
155
|
"Wrong date format for before argument."
|
zou/app/models/organisation.py
CHANGED
|
@@ -32,5 +32,7 @@ class Organisation(db.Model, BaseMixin, SerializerMixin):
|
|
|
32
32
|
"hd_by_default": self.hd_by_default,
|
|
33
33
|
"use_original_file_name": self.use_original_file_name,
|
|
34
34
|
"timesheets_locked": self.timesheets_locked,
|
|
35
|
+
"updated_at": self.updated_at,
|
|
36
|
+
"created_at": self.created_at,
|
|
35
37
|
}
|
|
36
38
|
)
|
zou/app/services/auth_service.py
CHANGED
|
@@ -9,7 +9,6 @@ from datetime import timedelta
|
|
|
9
9
|
from flask import request, session, current_app
|
|
10
10
|
from babel.dates import format_datetime
|
|
11
11
|
|
|
12
|
-
from flask_jwt_extended import get_jti
|
|
13
12
|
from ldap3 import Server, Connection, ALL, NTLM, SIMPLE
|
|
14
13
|
from ldap3.core.exceptions import (
|
|
15
14
|
LDAPSocketOpenError,
|
|
@@ -678,24 +677,6 @@ def generate_new_recovery_codes(person_id):
|
|
|
678
677
|
return otp_recovery_codes
|
|
679
678
|
|
|
680
679
|
|
|
681
|
-
def register_tokens(app, access_token, refresh_token=None):
|
|
682
|
-
"""
|
|
683
|
-
Register access and refresh tokens to auth token store. That way they
|
|
684
|
-
can be used like a session.
|
|
685
|
-
"""
|
|
686
|
-
access_jti = get_jti(encoded_token=access_token)
|
|
687
|
-
|
|
688
|
-
auth_tokens_store.add(
|
|
689
|
-
access_jti, "false", app.config["JWT_ACCESS_TOKEN_EXPIRES"]
|
|
690
|
-
)
|
|
691
|
-
|
|
692
|
-
if refresh_token is not None:
|
|
693
|
-
refresh_jti = get_jti(encoded_token=refresh_token)
|
|
694
|
-
auth_tokens_store.add(
|
|
695
|
-
refresh_jti, "false", app.config["JWT_REFRESH_TOKEN_EXPIRES"]
|
|
696
|
-
)
|
|
697
|
-
|
|
698
|
-
|
|
699
680
|
def revoke_tokens(app, jti):
|
|
700
681
|
"""
|
|
701
682
|
Remove access and refresh tokens from auth token store.
|
|
@@ -306,8 +306,8 @@ def new_comment(
|
|
|
306
306
|
)
|
|
307
307
|
except ValueError:
|
|
308
308
|
try:
|
|
309
|
-
created_at_date =
|
|
310
|
-
created_at
|
|
309
|
+
created_at_date = date_helpers.get_datetime_from_string(
|
|
310
|
+
created_at
|
|
311
311
|
)
|
|
312
312
|
except ValueError:
|
|
313
313
|
pass
|
|
@@ -1543,7 +1543,7 @@ def set_frames_from_task_type_preview_files(
|
|
|
1543
1543
|
subquery = (
|
|
1544
1544
|
db.session.query(
|
|
1545
1545
|
Shot.id.label("entity_id"),
|
|
1546
|
-
func.max(PreviewFile.created_at).label("max_created_at")
|
|
1546
|
+
func.max(PreviewFile.created_at).label("max_created_at"),
|
|
1547
1547
|
)
|
|
1548
1548
|
.join(Task, PreviewFile.task_id == Task.id)
|
|
1549
1549
|
.join(Shot, Task.entity_id == Shot.id)
|
|
@@ -1559,7 +1559,7 @@ def set_frames_from_task_type_preview_files(
|
|
|
1559
1559
|
subquery = (
|
|
1560
1560
|
db.session.query(
|
|
1561
1561
|
Shot.id.label("entity_id"),
|
|
1562
|
-
func.max(PreviewFile.created_at).label("max_created_at")
|
|
1562
|
+
func.max(PreviewFile.created_at).label("max_created_at"),
|
|
1563
1563
|
)
|
|
1564
1564
|
.join(Task, PreviewFile.task_id == Task.id)
|
|
1565
1565
|
.join(Shot, Task.entity_id == Shot.id)
|
|
@@ -1571,15 +1571,14 @@ def set_frames_from_task_type_preview_files(
|
|
|
1571
1571
|
)
|
|
1572
1572
|
|
|
1573
1573
|
query = (
|
|
1574
|
-
db.session.query(
|
|
1575
|
-
Shot,
|
|
1576
|
-
PreviewFile.duration
|
|
1577
|
-
)
|
|
1574
|
+
db.session.query(Shot, PreviewFile.duration)
|
|
1578
1575
|
.join(Task, Task.entity_id == Shot.id)
|
|
1579
1576
|
.join(subquery, (Shot.id == subquery.c.entity_id))
|
|
1580
|
-
.join(
|
|
1581
|
-
|
|
1582
|
-
|
|
1577
|
+
.join(
|
|
1578
|
+
PreviewFile,
|
|
1579
|
+
(PreviewFile.task_id == Task.id)
|
|
1580
|
+
& (PreviewFile.created_at == subquery.c.max_created_at),
|
|
1581
|
+
)
|
|
1583
1582
|
.filter(Task.task_type_id == task_type_id)
|
|
1584
1583
|
.filter(Shot.project_id == project_id)
|
|
1585
1584
|
)
|
|
@@ -1587,12 +1586,14 @@ def set_frames_from_task_type_preview_files(
|
|
|
1587
1586
|
results = query.all()
|
|
1588
1587
|
project = projects_service.get_project(project_id)
|
|
1589
1588
|
updates = []
|
|
1590
|
-
for
|
|
1589
|
+
for shot, preview_duration in results:
|
|
1591
1590
|
nb_frames = round(preview_duration * int(project["fps"]))
|
|
1592
|
-
updates.append(
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1591
|
+
updates.append(
|
|
1592
|
+
{
|
|
1593
|
+
"id": shot.id,
|
|
1594
|
+
"nb_frames": nb_frames,
|
|
1595
|
+
}
|
|
1596
|
+
)
|
|
1596
1597
|
clear_shot_cache(str(shot.id))
|
|
1597
1598
|
|
|
1598
1599
|
db.session.bulk_update_mappings(Shot, updates)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: zou
|
|
3
|
-
Version: 0.19.
|
|
3
|
+
Version: 0.19.47
|
|
4
4
|
Summary: API to store and manage the data of your animation production
|
|
5
5
|
Home-page: https://zou.cg-wire.com
|
|
6
6
|
Author: CG Wire
|
|
@@ -35,12 +35,12 @@ Requires-Dist: flask-mail ==0.10.0
|
|
|
35
35
|
Requires-Dist: flask-principal ==0.4.0
|
|
36
36
|
Requires-Dist: flask-restful ==0.3.10
|
|
37
37
|
Requires-Dist: flask-sqlalchemy ==3.1.1
|
|
38
|
-
Requires-Dist: flask-fs2[s3,swift] ==0.7.
|
|
38
|
+
Requires-Dist: flask-fs2[s3,swift] ==0.7.27
|
|
39
39
|
Requires-Dist: flask-jwt-extended ==4.6.0
|
|
40
40
|
Requires-Dist: flask-migrate ==4.0.7
|
|
41
41
|
Requires-Dist: flask-socketio ==5.3.6
|
|
42
42
|
Requires-Dist: flask ==3.0.3
|
|
43
|
-
Requires-Dist: gazu ==0.10.
|
|
43
|
+
Requires-Dist: gazu ==0.10.11
|
|
44
44
|
Requires-Dist: gevent-websocket ==0.10.1
|
|
45
45
|
Requires-Dist: gevent ==24.2.1
|
|
46
46
|
Requires-Dist: gunicorn ==22.0.0
|
|
@@ -49,9 +49,10 @@ Requires-Dist: itsdangerous ==2.2.0
|
|
|
49
49
|
Requires-Dist: Jinja2 ==3.1.4
|
|
50
50
|
Requires-Dist: ldap3 ==2.9.1
|
|
51
51
|
Requires-Dist: matterhook ==0.2
|
|
52
|
-
Requires-Dist: meilisearch ==0.31.
|
|
52
|
+
Requires-Dist: meilisearch ==0.31.4
|
|
53
53
|
Requires-Dist: opencv-python ==4.10.0.84
|
|
54
54
|
Requires-Dist: OpenTimelineIO ==0.17.0
|
|
55
|
+
Requires-Dist: OpenTimelineIO-Plugins ==0.17.0
|
|
55
56
|
Requires-Dist: orjson ==3.10.6
|
|
56
57
|
Requires-Dist: pillow ==10.4.0
|
|
57
58
|
Requires-Dist: psutil ==6.0.0
|
|
@@ -78,9 +79,9 @@ Requires-Dist: autoflake ==2.3.1 ; extra == 'lint'
|
|
|
78
79
|
Requires-Dist: black ==24.4.2 ; extra == 'lint'
|
|
79
80
|
Requires-Dist: pre-commit ==3.7.1 ; (python_version >= "3.9") and extra == 'lint'
|
|
80
81
|
Provides-Extra: monitoring
|
|
81
|
-
Requires-Dist: prometheus-flask-exporter ==0.23.
|
|
82
|
+
Requires-Dist: prometheus-flask-exporter ==0.23.1 ; extra == 'monitoring'
|
|
82
83
|
Requires-Dist: pygelf ==0.4.2 ; extra == 'monitoring'
|
|
83
|
-
Requires-Dist: sentry-sdk ==2.
|
|
84
|
+
Requires-Dist: sentry-sdk ==2.10.0 ; extra == 'monitoring'
|
|
84
85
|
Provides-Extra: prod
|
|
85
86
|
Requires-Dist: gunicorn ; extra == 'prod'
|
|
86
87
|
Requires-Dist: gevent ; extra == 'prod'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
zou/__init__.py,sha256=
|
|
1
|
+
zou/__init__.py,sha256=63wiU79B4fTMnEP5X5faQDDk5_7C1AbAa4PkU1j3tGg,24
|
|
2
2
|
zou/cli.py,sha256=2cDkbEOqp_m9hzBQf5wpxc_h0WjoH8KtxQQMNuREYlc,18201
|
|
3
3
|
zou/debug.py,sha256=1fawPbkD4wn0Y9Gk0BiBFSa-CQe5agFi8R9uJYl2Uyk,520
|
|
4
4
|
zou/event_stream.py,sha256=zgob2dZKray2lxPa11hdRNmOg8XRlKDdRcGdF80ylwg,8245
|
|
@@ -6,19 +6,19 @@ zou/job_settings.py,sha256=WB_RkYxmh4ffQHqg63_wsUDiS0zP3yxiwrxK7DhHG0g,150
|
|
|
6
6
|
zou/app/__init__.py,sha256=aWh9K5n63TpXdLDxpfFtNNoCYZVE6OV3YLCXLuygWQg,6700
|
|
7
7
|
zou/app/api.py,sha256=JTB_IMVO8EOoyqx9KdRkiIix0chOLi0yGDY-verUJXA,5127
|
|
8
8
|
zou/app/config.py,sha256=J0jmGmyvk8JqcMPAEW8KfvwP8GwEoC9BxQG8AQV9aiY,6393
|
|
9
|
-
zou/app/mixin.py,sha256=
|
|
9
|
+
zou/app/mixin.py,sha256=A4iIOwpkfYmRKXvF2Ykdc8BUQgufB0r_I4RdZYTiS3E,4896
|
|
10
10
|
zou/app/swagger.py,sha256=UW9DSik3a8GuH1_-7F5P7EYgjZ9DA_kFjukO-6n4kgk,54682
|
|
11
11
|
zou/app/blueprints/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
zou/app/blueprints/assets/__init__.py,sha256=tSRvVrnPj732F4k_lkxoTJBJNmIUAqKXPLJDHvOtAA4,2178
|
|
13
13
|
zou/app/blueprints/assets/resources.py,sha256=qY4K890kTTRWUVnNomilEuJY7qBy4RWHG2XiTuWPfBA,18988
|
|
14
14
|
zou/app/blueprints/auth/__init__.py,sha256=b8Syg8DHJn5s3avMZo5ukNQCzpX_2z9fmBSG3EIt5Yg,998
|
|
15
|
-
zou/app/blueprints/auth/resources.py,sha256=
|
|
15
|
+
zou/app/blueprints/auth/resources.py,sha256=b6zPYiBE_a1gE2ei3FFswy1Iml2r6TtMB5i48f9mPKk,41760
|
|
16
16
|
zou/app/blueprints/breakdown/__init__.py,sha256=Dp6GWSGxxWIedpyzTTEKpCRUYEo8oVNVyQhwNvTMmQM,1888
|
|
17
17
|
zou/app/blueprints/breakdown/resources.py,sha256=JY3j17kv7xPKV9S-XoOxNYivpGHlfZkXI5WuGtx3_Yk,13591
|
|
18
18
|
zou/app/blueprints/chats/__init__.py,sha256=YGmwGvddg3MgSYVIh-hmkX8t2em9_LblxBeJzFqFJD4,558
|
|
19
19
|
zou/app/blueprints/chats/resources.py,sha256=1THB-UNgMcedspNfB9-3-Tsr6rJ_PUl6Y2s_y0Ww0jk,5910
|
|
20
20
|
zou/app/blueprints/comments/__init__.py,sha256=WqpJ7-_dK1cInGTFJAxQ7syZtPCotwq2oO20UEnk1h4,1532
|
|
21
|
-
zou/app/blueprints/comments/resources.py,sha256=
|
|
21
|
+
zou/app/blueprints/comments/resources.py,sha256=_WoAnnv2uRLbc_fzg6XCeXF06_KNFS08r84YVN858Mc,19423
|
|
22
22
|
zou/app/blueprints/concepts/__init__.py,sha256=sP_P4mfYvfMcgeE6MHZYP3eD0Lz0Lwit5-CFuVnA-Jg,894
|
|
23
23
|
zou/app/blueprints/concepts/resources.py,sha256=maJNrBAWX0bKbDKtOZc3YFp4nTVtIdkkAA4H9WA9n1Y,10140
|
|
24
24
|
zou/app/blueprints/crud/__init__.py,sha256=qn7xkEh2EG0mPS_RBmm0GgYr0O1jnmI8ymXZnFWZCz8,8361
|
|
@@ -31,7 +31,7 @@ zou/app/blueprints/crud/comments.py,sha256=YH4cllfGloPMcIq1tgpT5pSvKTwNJ1zpkUssr
|
|
|
31
31
|
zou/app/blueprints/crud/custom_action.py,sha256=Nf6S6YBxePg4-nfaPTroIYZGWt9fJEHC719DOKJ8R98,978
|
|
32
32
|
zou/app/blueprints/crud/day_off.py,sha256=y0vahwLa7F9u6K5KUQ_6vt7XxHWQ_9vBdzDxvEMGIKg,2496
|
|
33
33
|
zou/app/blueprints/crud/department.py,sha256=AAN_qxZDQGS-mR1kRS_2qGx1D7PKT3h_Ke3IXtJ_F90,973
|
|
34
|
-
zou/app/blueprints/crud/entity.py,sha256=
|
|
34
|
+
zou/app/blueprints/crud/entity.py,sha256=Vsa3PFTT8L2x-FP9JXo4fYecWx-dRCzd8049V3g865w,8313
|
|
35
35
|
zou/app/blueprints/crud/entity_link.py,sha256=PlHGy3RPDUVdwWtOpQegz-wZCcxe9FZw_80nUVBy1Ac,819
|
|
36
36
|
zou/app/blueprints/crud/entity_type.py,sha256=eiOwyoxwA2r857vX6Nni1ukXnNnV-6GnpjIGuTrRqrI,1927
|
|
37
37
|
zou/app/blueprints/crud/event.py,sha256=bay2ggg5Oa69lOxNYGkHVQdSKuMxGhk2wqWP7QApKUg,589
|
|
@@ -40,7 +40,7 @@ zou/app/blueprints/crud/metadata_descriptor.py,sha256=6sNsebjbXnUnlflG4biB0M-C2n
|
|
|
40
40
|
zou/app/blueprints/crud/milestone.py,sha256=UIMsyCNS7ZRePjo08yyzubLEo6fcK-RAsVvrfjXoclA,839
|
|
41
41
|
zou/app/blueprints/crud/news.py,sha256=0baKn4OLEVY7ljWgpJEypo2Pgzhlp8GJxjim78oqLtg,344
|
|
42
42
|
zou/app/blueprints/crud/notification.py,sha256=A-KNH0IDNCXlE4AddNxvmsD_7a9HqHGo_rI-Z_pdzus,530
|
|
43
|
-
zou/app/blueprints/crud/organisation.py,sha256=
|
|
43
|
+
zou/app/blueprints/crud/organisation.py,sha256=bNGo3Dtir2o_cHk0vDPs4cJw7mRWlSwPf2oA4lDQUyU,859
|
|
44
44
|
zou/app/blueprints/crud/output_file.py,sha256=jWSagq4LxwtFQH0XL_LjXaiW9FRn8T4k0tv1EbmPfg0,3954
|
|
45
45
|
zou/app/blueprints/crud/output_type.py,sha256=eYJXLPkUCRj9-v5mc3rxqEHM3yycmf6rVAoaOfbnAcU,1998
|
|
46
46
|
zou/app/blueprints/crud/person.py,sha256=7masu1UxnSJT7KZ4zVUvUA7B2_zdY8ZtcEtqEiSIEfc,9201
|
|
@@ -66,7 +66,7 @@ zou/app/blueprints/edits/resources.py,sha256=IvgqEhIvjF6OO7VNK6i5w6NKEoFQyKfuZJ7
|
|
|
66
66
|
zou/app/blueprints/entities/__init__.py,sha256=v-qt2dl3s3tmK_ur-cpDHNPmcL0A6xCybczyuidjUCo,713
|
|
67
67
|
zou/app/blueprints/entities/resources.py,sha256=vyEs5ODyRqP9ICf_2KPVnwrGRCJQxZTgO5qFld0F3lg,3166
|
|
68
68
|
zou/app/blueprints/events/__init__.py,sha256=Vb0gO7Bpj_2Dpx9hhKd2SZW2qqnJrFVoDpJjFOmoMZw,394
|
|
69
|
-
zou/app/blueprints/events/resources.py,sha256=
|
|
69
|
+
zou/app/blueprints/events/resources.py,sha256=SSrfq5TioZj217Qzv8wxFTUzs3_3DP8yGDYUrkttMIs,3238
|
|
70
70
|
zou/app/blueprints/export/__init__.py,sha256=W3U93VD-dHlozFVSt_RDvP7h7K_FqgHPLA__W5H1DkE,1574
|
|
71
71
|
zou/app/blueprints/export/csv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
72
72
|
zou/app/blueprints/export/csv/assets.py,sha256=QafmkM1BphI6wzbcqK6Hc1XBtisjgGTGYejOwJWwWW4,5561
|
|
@@ -81,7 +81,7 @@ zou/app/blueprints/export/csv/task_types.py,sha256=PCEEhOQcdOJv_38i-KNxbkGeNzmQ8
|
|
|
81
81
|
zou/app/blueprints/export/csv/tasks.py,sha256=CHFcs9S3eLIz6psE6Q6mZ-OSur_GrpBeLn98Nh9NNcA,4121
|
|
82
82
|
zou/app/blueprints/export/csv/time_spents.py,sha256=WHdy9Wf2e-kvviYbNyUFr7xgg49h9f-Di12KIZx5ssk,2981
|
|
83
83
|
zou/app/blueprints/files/__init__.py,sha256=7Wty30JW2OXIn-tBFXOWWmPuHnsnxPpH3jNtHvvr9tY,3987
|
|
84
|
-
zou/app/blueprints/files/resources.py,sha256=
|
|
84
|
+
zou/app/blueprints/files/resources.py,sha256=8SIV8kaqv3dxyL8nyqG3QiZmk5ZYIvUxw6k1ic-jhBs,69786
|
|
85
85
|
zou/app/blueprints/index/__init__.py,sha256=Dh3oQiirpg8RCkfVOuk3irIjSvUvuRf0jPxE6oGubz0,828
|
|
86
86
|
zou/app/blueprints/index/resources.py,sha256=DsYpNSO_wCAxyjWOaB9QmEqOBcjn1miLiGnfY-ii1z8,8165
|
|
87
87
|
zou/app/blueprints/news/__init__.py,sha256=HxBXjC15dVbotNAZ0CLf02iwUjxJr20kgf8_kT_9nwM,505
|
|
@@ -90,14 +90,14 @@ zou/app/blueprints/persons/__init__.py,sha256=0cnHHw3K_8OEMm0qOi3wKVomSAg9IJSnVj
|
|
|
90
90
|
zou/app/blueprints/persons/resources.py,sha256=-5J8ZswusYEBTNmX4I7fLFDZVMKyO0qhO_dkMs9SkXA,41406
|
|
91
91
|
zou/app/blueprints/playlists/__init__.py,sha256=vuEk1F3hFHsmuKWhdepMoLyOzmNKDn1YrjjfcaIz0lQ,1596
|
|
92
92
|
zou/app/blueprints/playlists/resources.py,sha256=alRlMHypUFErXLsEYxpFK84cdjFJ3YWwamZtW0KcwLY,17211
|
|
93
|
-
zou/app/blueprints/previews/__init__.py,sha256=
|
|
94
|
-
zou/app/blueprints/previews/resources.py,sha256=
|
|
93
|
+
zou/app/blueprints/previews/__init__.py,sha256=qGohO6LRNZKXBAegINcUXuZlrtxobJKQg84-rQ1L3AU,4202
|
|
94
|
+
zou/app/blueprints/previews/resources.py,sha256=SrbAcsHizZZiWOjnDGurYmuQlxkj1KDyXKE85x_Wz5M,47062
|
|
95
95
|
zou/app/blueprints/projects/__init__.py,sha256=Pn3fA5bpNFEPBzxTKJ2foV6osZFflXXSM2l2uZh3ktM,3927
|
|
96
96
|
zou/app/blueprints/projects/resources.py,sha256=v9_TLh3mujL-p7QcGkfSOJnNojzoJA15jhqAHz5kEIc,31552
|
|
97
97
|
zou/app/blueprints/search/__init__.py,sha256=QCjQIY_85l_orhdEiqav_GifjReuwsjZggN3V0GeUVY,356
|
|
98
98
|
zou/app/blueprints/search/resources.py,sha256=ni-dX8Xfib_0FonLttoXgntXBR957-xhifPSQHHnOnY,2696
|
|
99
|
-
zou/app/blueprints/shots/__init__.py,sha256=
|
|
100
|
-
zou/app/blueprints/shots/resources.py,sha256=
|
|
99
|
+
zou/app/blueprints/shots/__init__.py,sha256=HfgLneZBYUMa2OGwIgEZTz8zrIEYFRiYmRbreBPYeYw,4076
|
|
100
|
+
zou/app/blueprints/shots/resources.py,sha256=NiuRZG2ltSn6KgaZvr_W7bHXJOQkBTFPUDYisShWZ6M,47738
|
|
101
101
|
zou/app/blueprints/source/__init__.py,sha256=H7K-4TDs4pc5EJvcYTYMJBHesxyqsE5-xq7J8ckOS2g,6093
|
|
102
102
|
zou/app/blueprints/source/kitsu.py,sha256=4lWdqxaKDzwx-5POAIHIgZ6ODbDMOOVRxaSb_FOLcCk,5012
|
|
103
103
|
zou/app/blueprints/source/otio.py,sha256=WkzpKylVkNlbY_jwf6uV5-HPylrktQznOcbCs_p8TDQ,13391
|
|
@@ -156,7 +156,7 @@ zou/app/models/metadata_descriptor.py,sha256=LRCJ7NKsy771kMSLeZDrCON7jRk76J-JTFW
|
|
|
156
156
|
zou/app/models/milestone.py,sha256=ZwJ7_PbXT_LeUZKv3l5DLPM7ByFQEccpEeWFq4-IM-Q,927
|
|
157
157
|
zou/app/models/news.py,sha256=UPX0ojWF-leAGZNKqlo7KL0s0lp2tbKMJl4N5lGbouo,1583
|
|
158
158
|
zou/app/models/notification.py,sha256=1ODOymGPeB4oxgX_3WhOgIL_Lsz-JR7miDkBS6W8t_s,2563
|
|
159
|
-
zou/app/models/organisation.py,sha256=
|
|
159
|
+
zou/app/models/organisation.py,sha256=3nUJq9TBJsBs1t3h4OHFBUrvn_FGOnBsiofcdH3tdzk,1587
|
|
160
160
|
zou/app/models/output_file.py,sha256=hyLGrpsgrk0aisDXppRQrB7ItCwyuyw-X0ZwVAHabsA,2569
|
|
161
161
|
zou/app/models/output_type.py,sha256=us_lCUCEvuP4vi_XmmOcEl1J2MtZhMX5ZheBqEFCgWA,381
|
|
162
162
|
zou/app/models/person.py,sha256=-JpYBpzqZ3LDD6HW1YgjrD7szhWSxQ0ti4GrrGvja2w,7466
|
|
@@ -180,12 +180,12 @@ zou/app/models/time_spent.py,sha256=n7i3FO9g1eE_zATkItoCgrGVqq3iMSfdlKSveEZPloc,
|
|
|
180
180
|
zou/app/models/working_file.py,sha256=q0LM3s1ziw_9AmmPDCkwyf1-TJkWTBMgo2LdHyVRwxg,1509
|
|
181
181
|
zou/app/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
182
182
|
zou/app/services/assets_service.py,sha256=Vea-Ra69-Zi0Q2S-Apb5fsZv5E9f_6XYVn2HxaGQBE8,21339
|
|
183
|
-
zou/app/services/auth_service.py,sha256=
|
|
183
|
+
zou/app/services/auth_service.py,sha256=AxKN_THkjN2tmOHTSyFspwwFHqGBnslXuidfbav8Rxk,23224
|
|
184
184
|
zou/app/services/backup_service.py,sha256=_ZtZp6wkcVYnHxBosziwLGdrTvsUttXGphiydq53iy8,4840
|
|
185
185
|
zou/app/services/base_service.py,sha256=OZd0STFh-DyBBdwsmA7DMMnrwv4C8wJUbShvZ1isndU,1383
|
|
186
186
|
zou/app/services/breakdown_service.py,sha256=p93HncjC36qbmvZiB259QGRtciS37N-s_7IWVAQx5eE,26727
|
|
187
187
|
zou/app/services/chats_service.py,sha256=V1RmQeQnsH1xvtbs6wcjEpudQS547eJBM7bgJr9-qYM,8270
|
|
188
|
-
zou/app/services/comments_service.py,sha256=
|
|
188
|
+
zou/app/services/comments_service.py,sha256=CUr0CZGkR95OrHDRJnhAZAikBLtWhM-5uLIoxI4gNtA,18589
|
|
189
189
|
zou/app/services/concepts_service.py,sha256=KGvk6lF5udj3SWn40X9KE8OAigrLCZUKEz9_CW7EMgQ,11440
|
|
190
190
|
zou/app/services/custom_actions_service.py,sha256=fWISEOOdthadrxeHuacEel5Xj6msn0yWXJQDG1gzvsY,297
|
|
191
191
|
zou/app/services/deletion_service.py,sha256=ddaup7i_CTugcJDrynczNcfhjSKgDeGhPQjQ68We_l8,17255
|
|
@@ -206,7 +206,7 @@ zou/app/services/preview_files_service.py,sha256=SIZ_SB1bWNRE_Zm7SuEpvFWqVpHKOgf
|
|
|
206
206
|
zou/app/services/projects_service.py,sha256=_J8hIHy3MX5MsdEMRIKNfbyewwhxtMEcc_ymeHBsF38,21434
|
|
207
207
|
zou/app/services/scenes_service.py,sha256=iXN19HU4njPF5VtZXuUrVJ-W23ZQuQNPC3ADXltbWtU,992
|
|
208
208
|
zou/app/services/schedule_service.py,sha256=E99HKYsXgnK2sw58fw-NNHXWBgVJiA60upztjkNSCaM,6989
|
|
209
|
-
zou/app/services/shots_service.py,sha256=
|
|
209
|
+
zou/app/services/shots_service.py,sha256=w96EbNyXZNKmZg1eUMbaQPAEng3WkfJaPkqEr39F2ug,50310
|
|
210
210
|
zou/app/services/stats_service.py,sha256=cAlc92i9d6eYtsuwe3hYHYwdytg8KEMi1-TADfysJwM,11733
|
|
211
211
|
zou/app/services/status_automations_service.py,sha256=tVio7Sj7inhvKS4UOyRhcdpwr_KNP96hT1o0X7XcGF4,715
|
|
212
212
|
zou/app/services/sync_service.py,sha256=EunfXlma_IIb7011A_xLQLVQGAi-MteKgm2Y2NAxvMs,41586
|
|
@@ -215,7 +215,7 @@ zou/app/services/telemetry_services.py,sha256=xQm1h1t_JxSFW59zQGf4NuNdUi1UfMa_6p
|
|
|
215
215
|
zou/app/services/time_spents_service.py,sha256=TBLC1O9Dg_UbciG5Nw-dejqX2-5n6q44lACeN6OnUkQ,15206
|
|
216
216
|
zou/app/services/user_service.py,sha256=BiOhPV7O-vowet7jOksjXk2V4yxZkdqsIyNboJ-Oz_A,46595
|
|
217
217
|
zou/app/stores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
218
|
-
zou/app/stores/auth_tokens_store.py,sha256=
|
|
218
|
+
zou/app/stores/auth_tokens_store.py,sha256=adcGe3SxfY4y_tP57HIR2SZbnu_Amqk-dAGVZIcJQ9c,1237
|
|
219
219
|
zou/app/stores/file_store.py,sha256=yLQDM6mNbj9oe0vsWdBqun7D8Dw-eSjD1yHCCftX0OI,4045
|
|
220
220
|
zou/app/stores/publisher_store.py,sha256=0cD9bwDdF2rOEeumLrxJx7xNPR_xvf_IAAk5JttDsO4,1006
|
|
221
221
|
zou/app/stores/queue_store.py,sha256=Nyh8_nXilC1FHtJvj6nVVm4sNCEtmJcRRVK2cj2G22c,612
|
|
@@ -407,9 +407,9 @@ zou/remote/normalize_movie.py,sha256=zNfEY3N1UbAHZfddGONTg2Sff3ieLVWd4dfZa1dpnes
|
|
|
407
407
|
zou/remote/playlist.py,sha256=AsDo0bgYhDcd6DfNRV6r6Jj3URWwavE2ZN3VkKRPbLU,3293
|
|
408
408
|
zou/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
409
409
|
zou/utils/movie.py,sha256=u9LCEOvmkxwm-KiZ6jKNdB9LSC6XXUDwJpVx8LkDwJg,16416
|
|
410
|
-
zou-0.19.
|
|
411
|
-
zou-0.19.
|
|
412
|
-
zou-0.19.
|
|
413
|
-
zou-0.19.
|
|
414
|
-
zou-0.19.
|
|
415
|
-
zou-0.19.
|
|
410
|
+
zou-0.19.47.dist-info/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
|
|
411
|
+
zou-0.19.47.dist-info/METADATA,sha256=SATF4GA5kYKo1-waJHtsylYRNspz_qCFLxX3R3E5MqA,6725
|
|
412
|
+
zou-0.19.47.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
|
413
|
+
zou-0.19.47.dist-info/entry_points.txt,sha256=PelQoIx3qhQ_Tmne7wrLY-1m2izuzgpwokoURwSohy4,130
|
|
414
|
+
zou-0.19.47.dist-info/top_level.txt,sha256=4S7G_jk4MzpToeDItHGjPhHx_fRdX52zJZWTD4SL54g,4
|
|
415
|
+
zou-0.19.47.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|