zou 0.19.68__py3-none-any.whl → 0.19.70__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zou/__init__.py +1 -1
- zou/app/__init__.py +1 -1
- zou/app/blueprints/auth/resources.py +17 -15
- zou/app/blueprints/breakdown/resources.py +4 -4
- zou/app/blueprints/comments/resources.py +2 -2
- zou/app/blueprints/crud/base.py +11 -20
- zou/app/blueprints/crud/comments.py +4 -40
- zou/app/blueprints/crud/event.py +1 -1
- zou/app/blueprints/crud/metadata_descriptor.py +9 -9
- zou/app/blueprints/crud/organisation.py +16 -1
- zou/app/blueprints/crud/person.py +4 -0
- zou/app/blueprints/crud/task.py +4 -1
- zou/app/blueprints/events/resources.py +8 -8
- zou/app/blueprints/export/csv/assets.py +15 -6
- zou/app/blueprints/export/csv/edits.py +15 -5
- zou/app/blueprints/export/csv/shots.py +15 -5
- zou/app/blueprints/index/resources.py +2 -0
- zou/app/blueprints/news/resources.py +6 -6
- zou/app/blueprints/persons/resources.py +0 -1
- zou/app/blueprints/shots/resources.py +0 -1
- zou/app/blueprints/source/csv/assets.py +10 -3
- zou/app/blueprints/source/csv/base.py +1 -1
- zou/app/blueprints/source/csv/edits.py +10 -3
- zou/app/blueprints/source/csv/shots.py +10 -3
- zou/app/blueprints/tasks/resources.py +7 -1
- zou/app/config.py +1 -0
- zou/app/models/organisation.py +11 -19
- zou/app/models/person.py +1 -1
- zou/app/models/serializer.py +17 -17
- zou/app/services/assets_service.py +6 -12
- zou/app/services/breakdown_service.py +1 -1
- zou/app/services/comments_service.py +1 -1
- zou/app/services/concepts_service.py +4 -12
- zou/app/services/edits_service.py +5 -11
- zou/app/services/events_service.py +4 -4
- zou/app/services/news_service.py +8 -8
- zou/app/services/persons_service.py +9 -4
- zou/app/services/preview_files_service.py +12 -4
- zou/app/services/projects_service.py +4 -13
- zou/app/services/shots_service.py +6 -12
- zou/app/services/sync_service.py +4 -4
- zou/app/services/tasks_service.py +12 -29
- zou/app/services/user_service.py +22 -37
- zou/app/utils/commands.py +4 -4
- zou/app/utils/csv_utils.py +1 -4
- zou/cli.py +4 -4
- zou/remote/config_payload.py +2 -1
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/METADATA +9 -9
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/RECORD +53 -53
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/LICENSE +0 -0
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/WHEEL +0 -0
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/entry_points.txt +0 -0
- {zou-0.19.68.dist-info → zou-0.19.70.dist-info}/top_level.txt +0 -0
|
@@ -21,7 +21,7 @@ from zou.app.services.tasks_service import (
|
|
|
21
21
|
)
|
|
22
22
|
from zou.app.services.comments_service import create_comment
|
|
23
23
|
from zou.app.services.exception import WrongParameterException
|
|
24
|
-
from zou.app.utils import events
|
|
24
|
+
from zou.app.utils import events, string
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class EditsCsvImportResource(BaseCsvProjectImportResource):
|
|
@@ -192,9 +192,16 @@ class EditsCsvImportResource(BaseCsvProjectImportResource):
|
|
|
192
192
|
else:
|
|
193
193
|
edit_new_values["data"] = entity.data.copy()
|
|
194
194
|
|
|
195
|
-
for name,
|
|
195
|
+
for name, descriptor in self.descriptor_fields.items():
|
|
196
196
|
if name in row:
|
|
197
|
-
|
|
197
|
+
if descriptor["data_type"] == "boolean":
|
|
198
|
+
edit_new_values["data"][descriptor["field_name"]] = (
|
|
199
|
+
"true" if string.strtobool(row[name]) else "false"
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
edit_new_values["data"][descriptor["field_name"]] = row[
|
|
203
|
+
name
|
|
204
|
+
]
|
|
198
205
|
|
|
199
206
|
tasks_update = self.get_tasks_update(row)
|
|
200
207
|
|
|
@@ -21,7 +21,7 @@ from zou.app.services.tasks_service import (
|
|
|
21
21
|
)
|
|
22
22
|
from zou.app.services.comments_service import create_comment
|
|
23
23
|
from zou.app.services.exception import WrongParameterException
|
|
24
|
-
from zou.app.utils import events
|
|
24
|
+
from zou.app.utils import events, string
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class ShotsCsvImportResource(BaseCsvProjectImportResource):
|
|
@@ -229,9 +229,16 @@ class ShotsCsvImportResource(BaseCsvProjectImportResource):
|
|
|
229
229
|
if fps is not None:
|
|
230
230
|
shot_new_values["data"]["fps"] = fps
|
|
231
231
|
|
|
232
|
-
for name,
|
|
232
|
+
for name, descriptor in self.descriptor_fields.items():
|
|
233
233
|
if name in row:
|
|
234
|
-
|
|
234
|
+
if descriptor["data_type"] == "boolean":
|
|
235
|
+
shot_new_values["data"][descriptor["field_name"]] = (
|
|
236
|
+
"true" if string.strtobool(row[name]) else "false"
|
|
237
|
+
)
|
|
238
|
+
else:
|
|
239
|
+
shot_new_values["data"][descriptor["field_name"]] = row[
|
|
240
|
+
name
|
|
241
|
+
]
|
|
235
242
|
|
|
236
243
|
tasks_update = self.get_tasks_update(row)
|
|
237
244
|
|
|
@@ -1532,6 +1532,11 @@ class ProjectCommentsResource(Resource, ArgsMixin):
|
|
|
1532
1532
|
type: string
|
|
1533
1533
|
format: UUID
|
|
1534
1534
|
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
1535
|
+
- in: query
|
|
1536
|
+
name: limit
|
|
1537
|
+
type: integer
|
|
1538
|
+
default: 100
|
|
1539
|
+
x-example: 100
|
|
1535
1540
|
responses:
|
|
1536
1541
|
200:
|
|
1537
1542
|
description: All comments to tasks related to given project
|
|
@@ -1544,7 +1549,8 @@ class ProjectCommentsResource(Resource, ArgsMixin):
|
|
|
1544
1549
|
):
|
|
1545
1550
|
raise permissions.PermissionDenied
|
|
1546
1551
|
page = self.get_page()
|
|
1547
|
-
|
|
1552
|
+
limit = self.get_limit()
|
|
1553
|
+
return tasks_service.get_comments_for_project(project_id, page, limit)
|
|
1548
1554
|
|
|
1549
1555
|
|
|
1550
1556
|
class ProjectPreviewFilesResource(Resource, ArgsMixin):
|
zou/app/config.py
CHANGED
|
@@ -158,6 +158,7 @@ CRISP_TOKEN = os.getenv("CRISP_TOKEN", "")
|
|
|
158
158
|
IS_SELF_HOSTED = envtobool("IS_SELF_HOSTED", True)
|
|
159
159
|
|
|
160
160
|
DEFAULT_TIMEZONE = os.getenv("DEFAULT_TIMEZONE", "Europe/Paris")
|
|
161
|
+
DEFAULT_LOCALE = os.getenv("DEFAULT_LOCALE", "en_US")
|
|
161
162
|
|
|
162
163
|
USER_LIMIT = int(os.getenv("USER_LIMIT", "100"))
|
|
163
164
|
MIN_PASSWORD_LENGTH = int(os.getenv("MIN_PASSWORD_LENGTH", 8))
|
zou/app/models/organisation.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from zou.app import db
|
|
2
2
|
from zou.app.models.serializer import SerializerMixin
|
|
3
3
|
from zou.app.models.base import BaseMixin
|
|
4
|
-
from zou.app.utils import fields
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
class Organisation(db.Model, BaseMixin, SerializerMixin):
|
|
@@ -22,22 +21,15 @@ class Organisation(db.Model, BaseMixin, SerializerMixin):
|
|
|
22
21
|
dark_theme_by_default = db.Column(db.Boolean(), default=False)
|
|
23
22
|
format_duration_in_hours = db.Column(db.Boolean(), default=False)
|
|
24
23
|
|
|
25
|
-
def present(self):
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"use_original_file_name": self.use_original_file_name,
|
|
37
|
-
"timesheets_locked": self.timesheets_locked,
|
|
38
|
-
"dark_theme_by_default": self.dark_theme_by_default,
|
|
39
|
-
"format_duration_in_hours": self.format_duration_in_hours,
|
|
40
|
-
"updated_at": self.updated_at,
|
|
41
|
-
"created_at": self.created_at,
|
|
42
|
-
}
|
|
24
|
+
def present(self, sensitive=False):
|
|
25
|
+
return self.serialize(
|
|
26
|
+
ignored_attrs=(
|
|
27
|
+
[]
|
|
28
|
+
if sensitive
|
|
29
|
+
else [
|
|
30
|
+
"chat_token_slack",
|
|
31
|
+
"chat_webhook_mattermost",
|
|
32
|
+
"chat_token_discord",
|
|
33
|
+
]
|
|
34
|
+
)
|
|
43
35
|
)
|
zou/app/models/person.py
CHANGED
|
@@ -94,7 +94,7 @@ class Person(db.Model, BaseMixin, SerializerMixin):
|
|
|
94
94
|
TimezoneType(backend="pytz"),
|
|
95
95
|
default=pytz_timezone(config.DEFAULT_TIMEZONE),
|
|
96
96
|
)
|
|
97
|
-
locale = db.Column(LocaleType, default=Locale(
|
|
97
|
+
locale = db.Column(LocaleType, default=Locale(config.DEFAULT_LOCALE))
|
|
98
98
|
data = db.Column(JSONB)
|
|
99
99
|
role = db.Column(ChoiceType(ROLE_TYPES), default="user", nullable=False)
|
|
100
100
|
has_avatar = db.Column(db.Boolean(), default=False)
|
zou/app/models/serializer.py
CHANGED
|
@@ -14,35 +14,35 @@ class SerializerMixin(object):
|
|
|
14
14
|
orm.attributes.CollectionAttributeImpl,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
-
def serialize(
|
|
17
|
+
def serialize(
|
|
18
|
+
self,
|
|
19
|
+
obj_type=None,
|
|
20
|
+
relations=False,
|
|
21
|
+
milliseconds=False,
|
|
22
|
+
ignored_attrs=[],
|
|
23
|
+
):
|
|
18
24
|
attrs = inspect(self.__class__).all_orm_descriptors.keys()
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
attr
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
obj_dict = {
|
|
28
|
-
attr: serialize_value(
|
|
29
|
-
getattr(self, attr), milliseconds=milliseconds
|
|
30
|
-
)
|
|
31
|
-
for attr in attrs
|
|
32
|
-
if not self.is_join(attr)
|
|
33
|
-
}
|
|
25
|
+
obj_dict = {
|
|
26
|
+
attr: serialize_value(
|
|
27
|
+
getattr(self, attr), milliseconds=milliseconds
|
|
28
|
+
)
|
|
29
|
+
for attr in attrs
|
|
30
|
+
if attr not in ignored_attrs
|
|
31
|
+
and (relations or not self.is_join(attr))
|
|
32
|
+
}
|
|
34
33
|
obj_dict["type"] = obj_type or type(self).__name__
|
|
35
34
|
return obj_dict
|
|
36
35
|
|
|
37
36
|
@staticmethod
|
|
38
37
|
def serialize_list(
|
|
39
|
-
models, obj_type=None, relations=False, milliseconds=False
|
|
38
|
+
models, obj_type=None, relations=False, milliseconds=False, **kwargs
|
|
40
39
|
):
|
|
41
40
|
return [
|
|
42
41
|
model.serialize(
|
|
43
42
|
obj_type=obj_type,
|
|
44
43
|
relations=relations,
|
|
45
44
|
milliseconds=milliseconds,
|
|
45
|
+
**kwargs
|
|
46
46
|
)
|
|
47
47
|
for model in models
|
|
48
48
|
]
|
|
@@ -40,7 +40,7 @@ from zou.app.services.exception import (
|
|
|
40
40
|
|
|
41
41
|
def clear_asset_cache(asset_id):
|
|
42
42
|
cache.cache.delete_memoized(get_asset, asset_id)
|
|
43
|
-
cache.cache.delete_memoized(
|
|
43
|
+
cache.cache.delete_memoized(get_asset, asset_id, True)
|
|
44
44
|
cache.cache.delete_memoized(get_full_asset, asset_id)
|
|
45
45
|
|
|
46
46
|
|
|
@@ -416,19 +416,13 @@ def get_asset_raw(entity_id):
|
|
|
416
416
|
|
|
417
417
|
|
|
418
418
|
@cache.memoize_function(120)
|
|
419
|
-
def get_asset(entity_id):
|
|
419
|
+
def get_asset(entity_id, relations=False):
|
|
420
420
|
"""
|
|
421
421
|
Return a given asset as a dict.
|
|
422
422
|
"""
|
|
423
|
-
return get_asset_raw(entity_id).serialize(
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
@cache.memoize_function(120)
|
|
427
|
-
def get_asset_with_relations(entity_id):
|
|
428
|
-
"""
|
|
429
|
-
Return a given asset as a dict.
|
|
430
|
-
"""
|
|
431
|
-
return get_asset_raw(entity_id).serialize(obj_type="Asset", relations=True)
|
|
423
|
+
return get_asset_raw(entity_id).serialize(
|
|
424
|
+
obj_type="Asset", relations=relations
|
|
425
|
+
)
|
|
432
426
|
|
|
433
427
|
|
|
434
428
|
def get_asset_by_shotgun_id(shotgun_id):
|
|
@@ -458,7 +452,7 @@ def get_full_asset(asset_id):
|
|
|
458
452
|
"""
|
|
459
453
|
assets = get_assets_and_tasks({"id": asset_id}, with_episode_ids=True)
|
|
460
454
|
if len(assets) > 0:
|
|
461
|
-
asset =
|
|
455
|
+
asset = get_asset(asset_id, relations=True)
|
|
462
456
|
asset_type_id = asset["entity_type_id"]
|
|
463
457
|
asset_type = get_asset_type(asset_type_id)
|
|
464
458
|
project = Project.get(asset["project_id"])
|
|
@@ -414,7 +414,7 @@ def _create_episode_casting_link(entity, asset_id, nb_occurences=1, label=""):
|
|
|
414
414
|
link = EntityLink.create(
|
|
415
415
|
entity_in_id=sequence["parent_id"],
|
|
416
416
|
entity_out_id=asset_id,
|
|
417
|
-
nb_occurences=
|
|
417
|
+
nb_occurences=nb_occurences,
|
|
418
418
|
label=label,
|
|
419
419
|
)
|
|
420
420
|
events.emit(
|
|
@@ -82,7 +82,7 @@ def create_comment(
|
|
|
82
82
|
"""
|
|
83
83
|
Create a new comment and related: news, notifications and events.
|
|
84
84
|
"""
|
|
85
|
-
task = tasks_service.
|
|
85
|
+
task = tasks_service.get_task(task_id, relations=True)
|
|
86
86
|
task_status = tasks_service.get_task_status(task_status_id)
|
|
87
87
|
author = _get_comment_author(person_id)
|
|
88
88
|
_check_retake_capping(task_status, task)
|
|
@@ -33,7 +33,7 @@ from zou.app.services.exception import (
|
|
|
33
33
|
|
|
34
34
|
def clear_concept_cache(concept_id):
|
|
35
35
|
cache.cache.delete_memoized(get_concept, concept_id)
|
|
36
|
-
cache.cache.delete_memoized(
|
|
36
|
+
cache.cache.delete_memoized(get_concept, concept_id, True)
|
|
37
37
|
cache.cache.delete_memoized(get_full_concept, concept_id)
|
|
38
38
|
|
|
39
39
|
|
|
@@ -61,23 +61,15 @@ def get_concept_raw(concept_id):
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
@cache.memoize_function(120)
|
|
64
|
-
def
|
|
64
|
+
def get_concept(concept_id, relations=False):
|
|
65
65
|
"""
|
|
66
66
|
Return given concept as a dictionary.
|
|
67
67
|
"""
|
|
68
68
|
return get_concept_raw(concept_id).serialize(
|
|
69
|
-
obj_type="Concept", relations=
|
|
69
|
+
obj_type="Concept", relations=relations
|
|
70
70
|
)
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
@cache.memoize_function(120)
|
|
74
|
-
def get_concept(concept_id):
|
|
75
|
-
"""
|
|
76
|
-
Return given concept as a dictionary.
|
|
77
|
-
"""
|
|
78
|
-
return get_concept_raw(concept_id).serialize(obj_type="Concept")
|
|
79
|
-
|
|
80
|
-
|
|
81
73
|
@cache.memoize_function(120)
|
|
82
74
|
def get_full_concept(concept_id):
|
|
83
75
|
"""
|
|
@@ -86,7 +78,7 @@ def get_full_concept(concept_id):
|
|
|
86
78
|
concepts = get_concepts_and_tasks({"id": concept_id})
|
|
87
79
|
if len(concepts) > 0:
|
|
88
80
|
concept = concepts[0]
|
|
89
|
-
concept.update(
|
|
81
|
+
concept.update(get_concept(concept_id, relations=True))
|
|
90
82
|
return concept
|
|
91
83
|
else:
|
|
92
84
|
raise ConceptNotFoundException
|
|
@@ -33,7 +33,7 @@ from zou.app.services.exception import (
|
|
|
33
33
|
|
|
34
34
|
def clear_edit_cache(edit_id):
|
|
35
35
|
cache.cache.delete_memoized(get_edit, edit_id)
|
|
36
|
-
cache.cache.delete_memoized(
|
|
36
|
+
cache.cache.delete_memoized(get_edit, edit_id, True)
|
|
37
37
|
cache.cache.delete_memoized(get_full_edit, edit_id)
|
|
38
38
|
|
|
39
39
|
|
|
@@ -241,19 +241,13 @@ def get_edit_raw(edit_id):
|
|
|
241
241
|
|
|
242
242
|
|
|
243
243
|
@cache.memoize_function(120)
|
|
244
|
-
def get_edit(edit_id):
|
|
244
|
+
def get_edit(edit_id, relations=False):
|
|
245
245
|
"""
|
|
246
246
|
Return given edit as a dictionary.
|
|
247
247
|
"""
|
|
248
|
-
return get_edit_raw(edit_id).serialize(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
@cache.memoize_function(120)
|
|
252
|
-
def get_edit_with_relations(edit_id):
|
|
253
|
-
"""
|
|
254
|
-
Return given edit as a dictionary.
|
|
255
|
-
"""
|
|
256
|
-
return get_edit_raw(edit_id).serialize(obj_type="Edit", relations=True)
|
|
248
|
+
return get_edit_raw(edit_id).serialize(
|
|
249
|
+
obj_type="Edit", relations=relations
|
|
250
|
+
)
|
|
257
251
|
|
|
258
252
|
|
|
259
253
|
@cache.memoize_function(120)
|
|
@@ -7,7 +7,7 @@ from sqlalchemy import func
|
|
|
7
7
|
def get_last_events(
|
|
8
8
|
after=None,
|
|
9
9
|
before=None,
|
|
10
|
-
|
|
10
|
+
limit=100,
|
|
11
11
|
only_files=False,
|
|
12
12
|
project_id=None,
|
|
13
13
|
name=None,
|
|
@@ -46,7 +46,7 @@ def get_last_events(
|
|
|
46
46
|
if name is not None:
|
|
47
47
|
query = query.filter(ApiEvent.name == name)
|
|
48
48
|
|
|
49
|
-
events = query.limit(
|
|
49
|
+
events = query.limit(limit).all()
|
|
50
50
|
return [
|
|
51
51
|
fields.serialize_dict(
|
|
52
52
|
{
|
|
@@ -71,7 +71,7 @@ def create_login_log(person_id, ip_address, origin):
|
|
|
71
71
|
return login_log.serialize()
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
def get_last_login_logs(before=None,
|
|
74
|
+
def get_last_login_logs(before=None, limit=100):
|
|
75
75
|
"""
|
|
76
76
|
Return last 100 login logs published. If before parameter is set, it returns
|
|
77
77
|
last 100 login logs before this date.
|
|
@@ -85,7 +85,7 @@ def get_last_login_logs(before=None, page_size=100):
|
|
|
85
85
|
LoginLog.created_at < func.cast(before, LoginLog.created_at.type)
|
|
86
86
|
)
|
|
87
87
|
|
|
88
|
-
login_logs = query.limit(
|
|
88
|
+
login_logs = query.limit(limit).all()
|
|
89
89
|
return [
|
|
90
90
|
{
|
|
91
91
|
"created_at": fields.serialize_value(created_at),
|
zou/app/services/news_service.py
CHANGED
|
@@ -92,7 +92,7 @@ def get_last_news_for_project(
|
|
|
92
92
|
task_status_id=None,
|
|
93
93
|
author_id=None,
|
|
94
94
|
page=1,
|
|
95
|
-
|
|
95
|
+
limit=50,
|
|
96
96
|
before=None,
|
|
97
97
|
after=None,
|
|
98
98
|
episode_id=None,
|
|
@@ -102,7 +102,7 @@ def get_last_news_for_project(
|
|
|
102
102
|
Return last 50 news for given project. Add related information to make it
|
|
103
103
|
displayable.
|
|
104
104
|
"""
|
|
105
|
-
offset = (page - 1) *
|
|
105
|
+
offset = (page - 1) * limit
|
|
106
106
|
|
|
107
107
|
query = (
|
|
108
108
|
News.query.order_by(News.created_at.desc())
|
|
@@ -158,7 +158,7 @@ def get_last_news_for_project(
|
|
|
158
158
|
News.created_at < func.cast(before, News.created_at.type)
|
|
159
159
|
)
|
|
160
160
|
|
|
161
|
-
(total, nb_pages) = _get_news_total(query,
|
|
161
|
+
(total, nb_pages) = _get_news_total(query, limit)
|
|
162
162
|
|
|
163
163
|
query = query.add_columns(
|
|
164
164
|
Project.id,
|
|
@@ -172,7 +172,7 @@ def get_last_news_for_project(
|
|
|
172
172
|
Entity.preview_file_id,
|
|
173
173
|
)
|
|
174
174
|
|
|
175
|
-
query = query.limit(
|
|
175
|
+
query = query.limit(limit)
|
|
176
176
|
query = query.offset(offset)
|
|
177
177
|
news_list = query.all()
|
|
178
178
|
result = []
|
|
@@ -221,15 +221,15 @@ def get_last_news_for_project(
|
|
|
221
221
|
"data": result,
|
|
222
222
|
"total": total,
|
|
223
223
|
"nb_pages": nb_pages,
|
|
224
|
-
"limit":
|
|
224
|
+
"limit": limit,
|
|
225
225
|
"offset": offset,
|
|
226
226
|
"page": page,
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
|
|
230
|
-
def _get_news_total(query,
|
|
230
|
+
def _get_news_total(query, limit):
|
|
231
231
|
total = query.count()
|
|
232
|
-
nb_pages = int(math.ceil(total / float(
|
|
232
|
+
nb_pages = int(math.ceil(total / float(limit)))
|
|
233
233
|
return total, nb_pages
|
|
234
234
|
|
|
235
235
|
|
|
@@ -314,4 +314,4 @@ def get_news_for_entity(entity_id):
|
|
|
314
314
|
"""
|
|
315
315
|
Get all news related to a given entity.
|
|
316
316
|
"""
|
|
317
|
-
return get_last_news_for_project(entity_id=entity_id,
|
|
317
|
+
return get_last_news_for_project(entity_id=entity_id, limit=2000)
|
|
@@ -36,8 +36,9 @@ def clear_person_cache():
|
|
|
36
36
|
cache.cache.delete_memoized(get_persons)
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
def
|
|
39
|
+
def clear_organisation_cache():
|
|
40
40
|
cache.cache.delete_memoized(get_organisation)
|
|
41
|
+
cache.cache.delete_memoized(get_organisation, True)
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
@cache.memoize_function(120)
|
|
@@ -230,6 +231,8 @@ def create_person(
|
|
|
230
231
|
raise WrongParameterException(
|
|
231
232
|
"Expiration date can't be in the past."
|
|
232
233
|
)
|
|
234
|
+
except WrongParameterException:
|
|
235
|
+
raise
|
|
233
236
|
except:
|
|
234
237
|
raise WrongParameterException("Expiration date is not valid.")
|
|
235
238
|
|
|
@@ -310,6 +313,8 @@ def update_person(person_id, data, bypass_protected_accounts=False):
|
|
|
310
313
|
raise WrongParameterException(
|
|
311
314
|
"Expiration date can't be in the past."
|
|
312
315
|
)
|
|
316
|
+
except WrongParameterException:
|
|
317
|
+
raise
|
|
313
318
|
except:
|
|
314
319
|
raise WrongParameterException("Expiration date is not valid.")
|
|
315
320
|
|
|
@@ -480,14 +485,14 @@ Thank you and see you soon on Kitsu,
|
|
|
480
485
|
|
|
481
486
|
|
|
482
487
|
@cache.memoize_function(120)
|
|
483
|
-
def get_organisation():
|
|
488
|
+
def get_organisation(sensitive=False):
|
|
484
489
|
"""
|
|
485
490
|
Return organisation set up on this instance. It creates it if none exists.
|
|
486
491
|
"""
|
|
487
492
|
organisation = Organisation.query.first()
|
|
488
493
|
if organisation is None:
|
|
489
494
|
organisation = Organisation.create(name="Kitsu")
|
|
490
|
-
return organisation.present()
|
|
495
|
+
return organisation.present(sensitive=sensitive)
|
|
491
496
|
|
|
492
497
|
|
|
493
498
|
def update_organisation(organisation_id, data):
|
|
@@ -497,7 +502,7 @@ def update_organisation(organisation_id, data):
|
|
|
497
502
|
organisation = Organisation.get(organisation_id)
|
|
498
503
|
organisation.update(data)
|
|
499
504
|
events.emit("organisation:update", {"organisation_id": organisation_id})
|
|
500
|
-
|
|
505
|
+
clear_organisation_cache()
|
|
501
506
|
return organisation.present()
|
|
502
507
|
|
|
503
508
|
|
|
@@ -89,7 +89,7 @@ def _is_valid_partial_resolution(resolution):
|
|
|
89
89
|
return resolution is not None and bool(re.match(r"x\d{3,4}", resolution))
|
|
90
90
|
|
|
91
91
|
|
|
92
|
-
def get_preview_file_fps(project):
|
|
92
|
+
def get_preview_file_fps(project, entity=None):
|
|
93
93
|
"""
|
|
94
94
|
Return fps set at project level or default fps if the dimensions are not
|
|
95
95
|
set.
|
|
@@ -97,6 +97,12 @@ def get_preview_file_fps(project):
|
|
|
97
97
|
fps = "25.00"
|
|
98
98
|
if project.get("fps", None) is not None:
|
|
99
99
|
fps = project["fps"].replace(",", ".")
|
|
100
|
+
|
|
101
|
+
if entity is not None:
|
|
102
|
+
entity_data = entity.get("data", {}) or {}
|
|
103
|
+
if entity_data.get("fps", None) is not None:
|
|
104
|
+
fps = entity_data["fps"].replace(",", ".")
|
|
105
|
+
|
|
100
106
|
return "%.3f" % float(fps)
|
|
101
107
|
|
|
102
108
|
|
|
@@ -193,7 +199,7 @@ def prepare_and_store_movie(
|
|
|
193
199
|
preview_file = set_preview_file_as_broken(preview_file_id)
|
|
194
200
|
return preview_file
|
|
195
201
|
|
|
196
|
-
fps = get_preview_file_fps(project)
|
|
202
|
+
fps = get_preview_file_fps(project, entity)
|
|
197
203
|
(width, height) = get_preview_file_dimensions(project, entity)
|
|
198
204
|
|
|
199
205
|
if normalize:
|
|
@@ -619,7 +625,9 @@ def extract_frame_from_preview_file(preview_file, frame_number):
|
|
|
619
625
|
else:
|
|
620
626
|
raise PreviewFileNotFoundException
|
|
621
627
|
|
|
622
|
-
fps = get_preview_file_fps(
|
|
628
|
+
fps = get_preview_file_fps(
|
|
629
|
+
project, get_entity_from_preview_file(preview_file["id"])
|
|
630
|
+
)
|
|
623
631
|
extracted_frame_path = movie.extract_frame_from_movie(
|
|
624
632
|
preview_file_path, frame_number, fps
|
|
625
633
|
)
|
|
@@ -650,7 +658,7 @@ def extract_tile_from_preview_file(preview_file):
|
|
|
650
658
|
extracted_tile_path = movie.generate_tile(preview_file_path)
|
|
651
659
|
return extracted_tile_path
|
|
652
660
|
else:
|
|
653
|
-
|
|
661
|
+
raise WrongParameterException("Preview file is not a movie")
|
|
654
662
|
|
|
655
663
|
|
|
656
664
|
def reset_movie_files_metadata():
|
|
@@ -38,7 +38,7 @@ from sqlalchemy import or_
|
|
|
38
38
|
|
|
39
39
|
def clear_project_cache(project_id):
|
|
40
40
|
cache.cache.delete_memoized(get_project, project_id)
|
|
41
|
-
cache.cache.delete_memoized(
|
|
41
|
+
cache.cache.delete_memoized(get_project, project_id, True)
|
|
42
42
|
cache.cache.delete_memoized(get_project_by_name)
|
|
43
43
|
cache.cache.delete_memoized(open_projects)
|
|
44
44
|
|
|
@@ -259,21 +259,12 @@ def get_project_raw(project_id):
|
|
|
259
259
|
|
|
260
260
|
|
|
261
261
|
@cache.memoize_function(240)
|
|
262
|
-
def get_project(project_id):
|
|
262
|
+
def get_project(project_id, relations=False):
|
|
263
263
|
"""
|
|
264
264
|
Get project matching given id, as a dict. Raises an exception if project is
|
|
265
265
|
not found.
|
|
266
266
|
"""
|
|
267
|
-
return get_project_raw(project_id).serialize()
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
@cache.memoize_function(240)
|
|
271
|
-
def get_project_with_relations(project_id):
|
|
272
|
-
"""
|
|
273
|
-
Get project matching given id, as a dict. Raises an exception if project is
|
|
274
|
-
not found.
|
|
275
|
-
"""
|
|
276
|
-
return get_project_raw(project_id).serialize(relations=True)
|
|
267
|
+
return get_project_raw(project_id).serialize(relations=relations)
|
|
277
268
|
|
|
278
269
|
|
|
279
270
|
@cache.memoize_function(120)
|
|
@@ -487,7 +478,7 @@ def add_metadata_descriptor(
|
|
|
487
478
|
field_name=slugify.slugify(name, separator="_"),
|
|
488
479
|
)
|
|
489
480
|
except Exception:
|
|
490
|
-
raise WrongParameterException
|
|
481
|
+
raise WrongParameterException("Metadata descriptor already exists.")
|
|
491
482
|
events.emit(
|
|
492
483
|
"metadata-descriptor:new",
|
|
493
484
|
{"metadata_descriptor_id": str(descriptor.id)},
|
|
@@ -50,7 +50,7 @@ from zou.app.services.exception import (
|
|
|
50
50
|
|
|
51
51
|
def clear_shot_cache(shot_id):
|
|
52
52
|
cache.cache.delete_memoized(get_shot, shot_id)
|
|
53
|
-
cache.cache.delete_memoized(
|
|
53
|
+
cache.cache.delete_memoized(get_shot, shot_id, True)
|
|
54
54
|
cache.cache.delete_memoized(get_full_shot, shot_id)
|
|
55
55
|
|
|
56
56
|
|
|
@@ -402,19 +402,13 @@ def get_shot_raw(shot_id):
|
|
|
402
402
|
|
|
403
403
|
|
|
404
404
|
@cache.memoize_function(120)
|
|
405
|
-
def get_shot(shot_id):
|
|
405
|
+
def get_shot(shot_id, relations=False):
|
|
406
406
|
"""
|
|
407
407
|
Return given shot as a dictionary.
|
|
408
408
|
"""
|
|
409
|
-
return get_shot_raw(shot_id).serialize(
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
@cache.memoize_function(120)
|
|
413
|
-
def get_shot_with_relations(shot_id):
|
|
414
|
-
"""
|
|
415
|
-
Return given shot as a dictionary.
|
|
416
|
-
"""
|
|
417
|
-
return get_shot_raw(shot_id).serialize(obj_type="Shot", relations=True)
|
|
409
|
+
return get_shot_raw(shot_id).serialize(
|
|
410
|
+
obj_type="Shot", relations=relations
|
|
411
|
+
)
|
|
418
412
|
|
|
419
413
|
|
|
420
414
|
@cache.memoize_function(120)
|
|
@@ -426,7 +420,7 @@ def get_full_shot(shot_id):
|
|
|
426
420
|
shots = get_shots_and_tasks({"id": shot_id})
|
|
427
421
|
if len(shots) > 0:
|
|
428
422
|
shot = shots[0]
|
|
429
|
-
shot.update(
|
|
423
|
+
shot.update(get_shot(shot_id, relations=True))
|
|
430
424
|
return shot
|
|
431
425
|
else:
|
|
432
426
|
raise ShotNotFoundException
|
zou/app/services/sync_service.py
CHANGED
|
@@ -323,12 +323,12 @@ def run_other_sync(project=None, with_events=False):
|
|
|
323
323
|
sync_entries("events", ApiEvent, project=project)
|
|
324
324
|
|
|
325
325
|
|
|
326
|
-
def run_last_events_sync(minutes=0,
|
|
326
|
+
def run_last_events_sync(minutes=0, limit=300):
|
|
327
327
|
"""
|
|
328
328
|
Retrieve last events from source instance and import related data and
|
|
329
329
|
action.
|
|
330
330
|
"""
|
|
331
|
-
path = "events/last?
|
|
331
|
+
path = "events/last?limit=%s" % limit
|
|
332
332
|
if minutes > 0:
|
|
333
333
|
now = date_helpers.get_utc_now_datetime()
|
|
334
334
|
min_before = now - datetime.timedelta(minutes=minutes)
|
|
@@ -346,12 +346,12 @@ def run_last_events_sync(minutes=0, page_size=300):
|
|
|
346
346
|
pass
|
|
347
347
|
|
|
348
348
|
|
|
349
|
-
def run_last_events_files(minutes=0,
|
|
349
|
+
def run_last_events_files(minutes=0, limit=50):
|
|
350
350
|
"""
|
|
351
351
|
Retrieve last events from source instance and import related data and
|
|
352
352
|
action.
|
|
353
353
|
"""
|
|
354
|
-
path = "events/last?only_files=true&
|
|
354
|
+
path = "events/last?only_files=true&limit=%s" % limit
|
|
355
355
|
if minutes > 0:
|
|
356
356
|
now = date_helpers.get_utc_now_datetime()
|
|
357
357
|
min_before = now - datetime.timedelta(minutes=minutes)
|