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
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""add department keys to filter models
|
|
2
|
+
|
|
3
|
+
Revision ID: 9d3bb33c6fc6
|
|
4
|
+
Revises: 8e67c183bed7
|
|
5
|
+
Create Date: 2024-10-11 15:52:29.740222
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
import sqlalchemy_utils
|
|
12
|
+
import sqlalchemy_utils
|
|
13
|
+
import uuid
|
|
14
|
+
|
|
15
|
+
# revision identifiers, used by Alembic.
|
|
16
|
+
revision = "9d3bb33c6fc6"
|
|
17
|
+
down_revision = "8e67c183bed7"
|
|
18
|
+
branch_labels = None
|
|
19
|
+
depends_on = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def upgrade():
|
|
23
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
24
|
+
with op.batch_alter_table("search_filter", schema=None) as batch_op:
|
|
25
|
+
batch_op.add_column(
|
|
26
|
+
sa.Column(
|
|
27
|
+
"department_id",
|
|
28
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
29
|
+
default=uuid.uuid4,
|
|
30
|
+
nullable=True,
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
batch_op.create_foreign_key(
|
|
34
|
+
"search_filter_department_id_fkey",
|
|
35
|
+
"department",
|
|
36
|
+
["department_id"],
|
|
37
|
+
["id"],
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
with op.batch_alter_table("search_filter_group", schema=None) as batch_op:
|
|
41
|
+
batch_op.add_column(
|
|
42
|
+
sa.Column(
|
|
43
|
+
"department_id",
|
|
44
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
45
|
+
default=uuid.uuid4,
|
|
46
|
+
nullable=True,
|
|
47
|
+
)
|
|
48
|
+
)
|
|
49
|
+
batch_op.create_foreign_key(
|
|
50
|
+
"search_filter_group_department_id_fkey",
|
|
51
|
+
"department",
|
|
52
|
+
["department_id"],
|
|
53
|
+
["id"],
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# ### end Alembic commands ###
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def downgrade():
|
|
60
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
61
|
+
with op.batch_alter_table("search_filter_group", schema=None) as batch_op:
|
|
62
|
+
batch_op.drop_constraint(
|
|
63
|
+
"search_filter_group_department_id_fkey", type_="foreignkey"
|
|
64
|
+
)
|
|
65
|
+
batch_op.drop_column("department_id")
|
|
66
|
+
|
|
67
|
+
with op.batch_alter_table("search_filter", schema=None) as batch_op:
|
|
68
|
+
batch_op.drop_constraint(
|
|
69
|
+
"search_filter_department_id_fkey", type_="foreignkey"
|
|
70
|
+
)
|
|
71
|
+
batch_op.drop_column("department_id")
|
|
72
|
+
|
|
73
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Add descriptions for entities tasks and statuses
|
|
2
|
+
|
|
3
|
+
Revision ID: a252a094e977
|
|
4
|
+
Revises: 1bb55759146f
|
|
5
|
+
Create Date: 2024-06-20 20:37:21.885953
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "a252a094e977"
|
|
15
|
+
down_revision = "1bb55759146f"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
op.add_column(
|
|
23
|
+
"task_type", sa.Column("description", sa.Text(), nullable=True)
|
|
24
|
+
)
|
|
25
|
+
op.add_column(
|
|
26
|
+
"task_status", sa.Column("description", sa.Text(), nullable=True)
|
|
27
|
+
)
|
|
28
|
+
op.add_column(
|
|
29
|
+
"entity_type", sa.Column("description", sa.Text(), nullable=True)
|
|
30
|
+
)
|
|
31
|
+
# ### end Alembic commands ###
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def downgrade():
|
|
35
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
36
|
+
op.drop_column("task_type", "description")
|
|
37
|
+
op.drop_column("task_status", "description")
|
|
38
|
+
op.drop_column("entity_type", "description")
|
|
39
|
+
|
|
40
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""For is_shared disallow nullable
|
|
2
|
+
|
|
3
|
+
Revision ID: be56dc0fb760
|
|
4
|
+
Revises: 680c64565f9d
|
|
5
|
+
Create Date: 2024-05-31 17:44:17.975779
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
from sqlalchemy import orm
|
|
12
|
+
from sqlalchemy.ext.declarative import declarative_base
|
|
13
|
+
from zou.migrations.utils.base import BaseMixin
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# revision identifiers, used by Alembic.
|
|
17
|
+
revision = "be56dc0fb760"
|
|
18
|
+
down_revision = "680c64565f9d"
|
|
19
|
+
branch_labels = None
|
|
20
|
+
depends_on = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def upgrade():
|
|
24
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
25
|
+
|
|
26
|
+
base = declarative_base()
|
|
27
|
+
|
|
28
|
+
class SearchFilter(base, BaseMixin):
|
|
29
|
+
"""
|
|
30
|
+
Filters allow to store quick search on a list: asset list, shot list,
|
|
31
|
+
sequence list, todo-list...
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
__tablename__ = "search_filter"
|
|
35
|
+
list_type = sa.Column(sa.String(80), nullable=False, index=True)
|
|
36
|
+
entity_type = sa.Column(sa.String(80))
|
|
37
|
+
name = sa.Column(sa.String(200), nullable=False, default="")
|
|
38
|
+
search_query = sa.Column(sa.String(500), nullable=False, default="")
|
|
39
|
+
is_shared = sa.Column(
|
|
40
|
+
sa.Boolean,
|
|
41
|
+
default=False,
|
|
42
|
+
nullable=True,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
class SearchFilterGroup(base, BaseMixin):
|
|
46
|
+
"""
|
|
47
|
+
Groups are used to store search filters into sections.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
__tablename__ = "search_filter_group"
|
|
51
|
+
list_type = sa.Column(sa.String(80), nullable=False, index=True)
|
|
52
|
+
entity_type = sa.Column(sa.String(80))
|
|
53
|
+
name = sa.Column(sa.String(200), nullable=False, default="")
|
|
54
|
+
color = sa.Column(sa.String(8), nullable=False, default="")
|
|
55
|
+
is_shared = sa.Column(
|
|
56
|
+
sa.Boolean,
|
|
57
|
+
default=False,
|
|
58
|
+
nullable=True,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
bind = op.get_bind()
|
|
62
|
+
session = orm.Session(bind=bind)
|
|
63
|
+
session.query(SearchFilter).where(SearchFilter.is_shared == None).update(
|
|
64
|
+
{SearchFilter.is_shared: False}
|
|
65
|
+
)
|
|
66
|
+
session.query(SearchFilterGroup).where(
|
|
67
|
+
SearchFilterGroup.is_shared == None
|
|
68
|
+
).update({SearchFilterGroup.is_shared: False})
|
|
69
|
+
session.commit()
|
|
70
|
+
|
|
71
|
+
with op.batch_alter_table("search_filter", schema=None) as batch_op:
|
|
72
|
+
batch_op.alter_column(
|
|
73
|
+
"is_shared",
|
|
74
|
+
existing_type=sa.BOOLEAN(),
|
|
75
|
+
server_default=sa.sql.expression.false(),
|
|
76
|
+
nullable=False,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
with op.batch_alter_table("search_filter_group", schema=None) as batch_op:
|
|
80
|
+
batch_op.alter_column(
|
|
81
|
+
"is_shared",
|
|
82
|
+
existing_type=sa.BOOLEAN(),
|
|
83
|
+
server_default=sa.sql.expression.false(),
|
|
84
|
+
nullable=False,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# ### end Alembic commands ###
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def downgrade():
|
|
91
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
92
|
+
with op.batch_alter_table("search_filter_group", schema=None) as batch_op:
|
|
93
|
+
batch_op.alter_column(
|
|
94
|
+
"is_shared", existing_type=sa.BOOLEAN(), nullable=True
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
with op.batch_alter_table("search_filter", schema=None) as batch_op:
|
|
98
|
+
batch_op.alter_column(
|
|
99
|
+
"is_shared", existing_type=sa.BOOLEAN(), nullable=True
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""add is_done field to the task model
|
|
2
|
+
|
|
3
|
+
Revision ID: ca28796a2a62
|
|
4
|
+
Revises: 971dbf5a0faf
|
|
5
|
+
Create Date: 2024-07-19 15:24:21.064991
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
from sqlalchemy import orm
|
|
12
|
+
from sqlalchemy.ext.declarative import declarative_base
|
|
13
|
+
from zou.migrations.utils.base import BaseMixin
|
|
14
|
+
from sqlalchemy_utils import UUIDType, ChoiceType
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# revision identifiers, used by Alembic.
|
|
18
|
+
revision = "ca28796a2a62"
|
|
19
|
+
down_revision = "971dbf5a0faf"
|
|
20
|
+
branch_labels = None
|
|
21
|
+
depends_on = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def upgrade():
|
|
25
|
+
base = declarative_base()
|
|
26
|
+
|
|
27
|
+
TYPES = [
|
|
28
|
+
("comment", "Comment"),
|
|
29
|
+
("mention", "Mention"),
|
|
30
|
+
("assignation", "Assignation"),
|
|
31
|
+
("reply", "Reply"),
|
|
32
|
+
("reply-mention", "Reply Mention"),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
class Notification(base, BaseMixin):
|
|
36
|
+
"""
|
|
37
|
+
A notification is stored each time a comment is posted.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
__tablename__ = "notification"
|
|
41
|
+
read = sa.Column(sa.Boolean, nullable=False, default=False)
|
|
42
|
+
change = sa.Column(sa.Boolean, nullable=False, default=False)
|
|
43
|
+
type = sa.Column(ChoiceType(TYPES), nullable=False)
|
|
44
|
+
person_id = sa.Column(
|
|
45
|
+
UUIDType(binary=False),
|
|
46
|
+
nullable=False,
|
|
47
|
+
index=True,
|
|
48
|
+
)
|
|
49
|
+
author_id = sa.Column(
|
|
50
|
+
UUIDType(binary=False),
|
|
51
|
+
nullable=False,
|
|
52
|
+
index=True,
|
|
53
|
+
)
|
|
54
|
+
comment_id = sa.Column(
|
|
55
|
+
UUIDType(binary=False),
|
|
56
|
+
nullable=True,
|
|
57
|
+
index=True,
|
|
58
|
+
)
|
|
59
|
+
task_id = sa.Column(
|
|
60
|
+
UUIDType(binary=False),
|
|
61
|
+
nullable=False,
|
|
62
|
+
index=True,
|
|
63
|
+
)
|
|
64
|
+
reply_id = sa.Column(UUIDType(binary=False), nullable=True, index=True)
|
|
65
|
+
|
|
66
|
+
__table_args__ = (
|
|
67
|
+
sa.UniqueConstraint(
|
|
68
|
+
"person_id",
|
|
69
|
+
"author_id",
|
|
70
|
+
"comment_id",
|
|
71
|
+
"reply_id",
|
|
72
|
+
"type",
|
|
73
|
+
name="notification_uc",
|
|
74
|
+
),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
bind = op.get_bind()
|
|
78
|
+
session = orm.Session(bind=bind)
|
|
79
|
+
session.query(Notification).where(Notification.type == None).update(
|
|
80
|
+
{Notification.type: "comment"}
|
|
81
|
+
)
|
|
82
|
+
session.commit()
|
|
83
|
+
|
|
84
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
85
|
+
with op.batch_alter_table("notification", schema=None) as batch_op:
|
|
86
|
+
batch_op.alter_column(
|
|
87
|
+
"type", existing_type=sa.VARCHAR(length=255), nullable=False
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
with op.batch_alter_table("task", schema=None) as batch_op:
|
|
91
|
+
batch_op.add_column(
|
|
92
|
+
sa.Column("done_date", sa.DateTime(), nullable=True)
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
# ### end Alembic commands ###
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def downgrade():
|
|
99
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
100
|
+
with op.batch_alter_table("task", schema=None) as batch_op:
|
|
101
|
+
batch_op.drop_column("done_date")
|
|
102
|
+
|
|
103
|
+
with op.batch_alter_table("notification", schema=None) as batch_op:
|
|
104
|
+
batch_op.alter_column(
|
|
105
|
+
"type", existing_type=sa.VARCHAR(length=255), nullable=True
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""For description of entity, task, working_file don't set any length
|
|
2
|
+
|
|
3
|
+
Revision ID: f344b867a911
|
|
4
|
+
Revises: 32f134ff1201
|
|
5
|
+
Create Date: 2024-05-22 15:46:07.855818
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "f344b867a911"
|
|
15
|
+
down_revision = "32f134ff1201"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
with op.batch_alter_table("entity", schema=None) as batch_op:
|
|
23
|
+
batch_op.alter_column(
|
|
24
|
+
"description",
|
|
25
|
+
existing_type=sa.VARCHAR(length=1200),
|
|
26
|
+
type_=sa.Text(),
|
|
27
|
+
existing_nullable=True,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
with op.batch_alter_table("task", schema=None) as batch_op:
|
|
31
|
+
batch_op.alter_column(
|
|
32
|
+
"description",
|
|
33
|
+
existing_type=sa.VARCHAR(length=200),
|
|
34
|
+
type_=sa.Text(),
|
|
35
|
+
existing_nullable=True,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
with op.batch_alter_table("working_file", schema=None) as batch_op:
|
|
39
|
+
batch_op.alter_column(
|
|
40
|
+
"description",
|
|
41
|
+
existing_type=sa.VARCHAR(length=200),
|
|
42
|
+
type_=sa.Text(),
|
|
43
|
+
existing_nullable=True,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# ### end Alembic commands ###
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def downgrade():
|
|
50
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
51
|
+
with op.batch_alter_table("working_file", schema=None) as batch_op:
|
|
52
|
+
batch_op.alter_column(
|
|
53
|
+
"description",
|
|
54
|
+
existing_type=sa.Text(),
|
|
55
|
+
type_=sa.VARCHAR(length=200),
|
|
56
|
+
existing_nullable=True,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
with op.batch_alter_table("task", schema=None) as batch_op:
|
|
60
|
+
batch_op.alter_column(
|
|
61
|
+
"description",
|
|
62
|
+
existing_type=sa.Text(),
|
|
63
|
+
type_=sa.VARCHAR(length=200),
|
|
64
|
+
existing_nullable=True,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
with op.batch_alter_table("entity", schema=None) as batch_op:
|
|
68
|
+
batch_op.alter_column(
|
|
69
|
+
"description",
|
|
70
|
+
existing_type=sa.Text(),
|
|
71
|
+
type_=sa.VARCHAR(length=1200),
|
|
72
|
+
existing_nullable=True,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# ### end Alembic commands ###
|
zou/remote/config_payload.py
CHANGED
|
@@ -67,7 +67,8 @@ def get_file_from_storage(storage, output_file_path, filename):
|
|
|
67
67
|
or os.path.getsize(output_file_path) == 0
|
|
68
68
|
):
|
|
69
69
|
with open(output_file_path, "wb") as output_file:
|
|
70
|
-
|
|
70
|
+
for chunk in storage.read_chunks(filename):
|
|
71
|
+
output_file.write(chunk)
|
|
71
72
|
return output_file_path
|
|
72
73
|
|
|
73
74
|
|
zou/utils/movie.py
CHANGED
|
@@ -103,14 +103,20 @@ def generate_tile(movie_path):
|
|
|
103
103
|
duration = get_movie_duration(video_track=video_track)
|
|
104
104
|
fps = get_movie_fps(video_track=video_track)
|
|
105
105
|
duration_in_frames = int(duration * fps)
|
|
106
|
-
rows = min(math.ceil(duration_in_frames / 8),
|
|
106
|
+
rows = min(math.ceil(duration_in_frames / 8), 480)
|
|
107
107
|
ratio = get_movie_display_aspect_ratio(video_track=video_track)
|
|
108
108
|
height = 100
|
|
109
109
|
width = math.ceil(height * ratio)
|
|
110
|
-
|
|
110
|
+
if rows == 480:
|
|
111
|
+
select = (
|
|
112
|
+
rf"select='not(mod(n\,{math.ceil(duration_in_frames/3840)}))',"
|
|
113
|
+
)
|
|
114
|
+
else:
|
|
115
|
+
select = ""
|
|
111
116
|
try:
|
|
112
117
|
ffmpeg.input(movie_path).output(
|
|
113
|
-
file_target_path,
|
|
118
|
+
file_target_path,
|
|
119
|
+
vf=f"{select}scale={width}:{height},tile=8x{rows}",
|
|
114
120
|
).overwrite_output().run(quiet=True)
|
|
115
121
|
except ffmpeg._run.Error as e:
|
|
116
122
|
log_ffmpeg_error(e, "An error occured while generating the tile.")
|
|
@@ -489,7 +495,11 @@ def concat_demuxer(in_files, output_path, *args):
|
|
|
489
495
|
|
|
490
496
|
stream = ffmpeg.input(temp.name, format="concat", safe=0)
|
|
491
497
|
stream = ffmpeg.output(
|
|
492
|
-
stream.video,
|
|
498
|
+
stream.video,
|
|
499
|
+
stream.audio,
|
|
500
|
+
output_path,
|
|
501
|
+
vf="select=concatdec_select",
|
|
502
|
+
af="aselect=concatdec_select,aresample=async=1",
|
|
493
503
|
)
|
|
494
504
|
return run_ffmpeg(stream, "-xerror")
|
|
495
505
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: zou
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.11
|
|
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
|
|
@@ -11,82 +11,88 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
11
11
|
Classifier: Environment :: Web Environment
|
|
12
12
|
Classifier: Framework :: Flask
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.9
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
19
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
19
20
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
20
21
|
Classifier: Topic :: Multimedia :: Graphics
|
|
21
|
-
Requires-Python: >=3.
|
|
22
|
+
Requires-Python: >=3.9, <3.14
|
|
22
23
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
36
|
-
Requires-Dist:
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist: flask-
|
|
39
|
-
Requires-Dist: flask-
|
|
40
|
-
Requires-Dist: flask-
|
|
41
|
-
Requires-Dist: flask
|
|
42
|
-
Requires-Dist:
|
|
43
|
-
Requires-Dist:
|
|
44
|
-
Requires-Dist: gevent
|
|
45
|
-
Requires-Dist:
|
|
46
|
-
Requires-Dist:
|
|
47
|
-
Requires-Dist:
|
|
48
|
-
Requires-Dist:
|
|
49
|
-
Requires-Dist:
|
|
50
|
-
Requires-Dist:
|
|
51
|
-
Requires-Dist:
|
|
52
|
-
Requires-Dist:
|
|
53
|
-
Requires-Dist:
|
|
54
|
-
Requires-Dist:
|
|
55
|
-
Requires-Dist:
|
|
56
|
-
Requires-Dist:
|
|
57
|
-
Requires-Dist:
|
|
58
|
-
Requires-Dist:
|
|
59
|
-
Requires-Dist:
|
|
60
|
-
Requires-Dist:
|
|
61
|
-
Requires-Dist:
|
|
62
|
-
Requires-Dist:
|
|
63
|
-
Requires-Dist:
|
|
64
|
-
Requires-Dist:
|
|
65
|
-
Requires-Dist:
|
|
66
|
-
Requires-Dist:
|
|
67
|
-
Requires-Dist:
|
|
68
|
-
Requires-Dist:
|
|
69
|
-
Requires-Dist:
|
|
70
|
-
Requires-Dist:
|
|
71
|
-
Requires-Dist:
|
|
72
|
-
|
|
73
|
-
Requires-Dist:
|
|
74
|
-
|
|
75
|
-
Requires-Dist:
|
|
76
|
-
Requires-Dist: black ==24.2.0 ; extra == 'lint'
|
|
77
|
-
Requires-Dist: pre-commit ==3.6.2 ; (python_version >= "3.9") and extra == 'lint'
|
|
78
|
-
Provides-Extra: monitoring
|
|
79
|
-
Requires-Dist: prometheus-flask-exporter ==0.23.0 ; extra == 'monitoring'
|
|
80
|
-
Requires-Dist: pygelf ==0.4.2 ; extra == 'monitoring'
|
|
81
|
-
Requires-Dist: sentry-sdk ==1.41.0 ; extra == 'monitoring'
|
|
24
|
+
Requires-Dist: audioop-lts==0.2.1; python_version >= "3.13"
|
|
25
|
+
Requires-Dist: babel==2.16.0
|
|
26
|
+
Requires-Dist: click==8.1.8
|
|
27
|
+
Requires-Dist: discord.py==2.4.0
|
|
28
|
+
Requires-Dist: email-validator==2.2.0
|
|
29
|
+
Requires-Dist: ffmpeg-python==0.2.0
|
|
30
|
+
Requires-Dist: fido2==1.2.0
|
|
31
|
+
Requires-Dist: flasgger==0.9.7.1
|
|
32
|
+
Requires-Dist: flask_bcrypt==1.0.1
|
|
33
|
+
Requires-Dist: flask_caching==2.3.0
|
|
34
|
+
Requires-Dist: flask_fixtures==0.3.8
|
|
35
|
+
Requires-Dist: flask_mail==0.10.0
|
|
36
|
+
Requires-Dist: flask_principal==0.4.0
|
|
37
|
+
Requires-Dist: flask_restful==0.3.10
|
|
38
|
+
Requires-Dist: flask_sqlalchemy==3.1.1
|
|
39
|
+
Requires-Dist: flask-fs2[s3,swift]==0.7.28
|
|
40
|
+
Requires-Dist: flask-jwt-extended==4.7.1
|
|
41
|
+
Requires-Dist: flask-migrate==4.1.0
|
|
42
|
+
Requires-Dist: flask-socketio==5.5.1
|
|
43
|
+
Requires-Dist: flask==3.1.0
|
|
44
|
+
Requires-Dist: gazu==0.10.22
|
|
45
|
+
Requires-Dist: gevent-websocket==0.10.1
|
|
46
|
+
Requires-Dist: gevent==24.11.1
|
|
47
|
+
Requires-Dist: gunicorn==23.0.0
|
|
48
|
+
Requires-Dist: isoweek==1.3.3
|
|
49
|
+
Requires-Dist: itsdangerous==2.2.0
|
|
50
|
+
Requires-Dist: Jinja2==3.1.5
|
|
51
|
+
Requires-Dist: ldap3==2.9.1
|
|
52
|
+
Requires-Dist: matterhook==0.2
|
|
53
|
+
Requires-Dist: meilisearch==0.33.1
|
|
54
|
+
Requires-Dist: numpy==2.0.1; python_version == "3.9"
|
|
55
|
+
Requires-Dist: numpy==2.2.1; python_version >= "3.10"
|
|
56
|
+
Requires-Dist: opencv-python==4.10.0.84
|
|
57
|
+
Requires-Dist: OpenTimelineIO==0.17.0
|
|
58
|
+
Requires-Dist: OpenTimelineIO-Plugins==0.17.0
|
|
59
|
+
Requires-Dist: orjson==3.10.14
|
|
60
|
+
Requires-Dist: pillow==11.1.0
|
|
61
|
+
Requires-Dist: psutil==6.1.1
|
|
62
|
+
Requires-Dist: psycopg[binary]==3.2.3
|
|
63
|
+
Requires-Dist: pyotp==2.9.0
|
|
64
|
+
Requires-Dist: pysaml2==7.5.0
|
|
65
|
+
Requires-Dist: python-nomad==2.0.1
|
|
66
|
+
Requires-Dist: python-slugify==8.0.4
|
|
67
|
+
Requires-Dist: python-socketio==5.12.1
|
|
68
|
+
Requires-Dist: pytz==2024.2
|
|
69
|
+
Requires-Dist: redis==5.2.1
|
|
70
|
+
Requires-Dist: requests==2.32.3
|
|
71
|
+
Requires-Dist: rq==2.1.0
|
|
72
|
+
Requires-Dist: slackclient==2.9.4
|
|
73
|
+
Requires-Dist: sqlalchemy_utils==0.41.2
|
|
74
|
+
Requires-Dist: sqlalchemy==2.0.37
|
|
75
|
+
Requires-Dist: ua-parser==1.0.0
|
|
76
|
+
Requires-Dist: werkzeug==3.1.3
|
|
82
77
|
Provides-Extra: prod
|
|
83
|
-
Requires-Dist: gunicorn
|
|
84
|
-
Requires-Dist: gevent
|
|
78
|
+
Requires-Dist: gunicorn; extra == "prod"
|
|
79
|
+
Requires-Dist: gevent; extra == "prod"
|
|
80
|
+
Provides-Extra: dev
|
|
81
|
+
Requires-Dist: wheel; extra == "dev"
|
|
85
82
|
Provides-Extra: test
|
|
86
|
-
Requires-Dist: fakeredis
|
|
87
|
-
Requires-Dist: mixer
|
|
88
|
-
Requires-Dist: pytest-cov
|
|
89
|
-
Requires-Dist: pytest
|
|
83
|
+
Requires-Dist: fakeredis==2.26.2; extra == "test"
|
|
84
|
+
Requires-Dist: mixer==7.2.2; extra == "test"
|
|
85
|
+
Requires-Dist: pytest-cov==6.0.0; extra == "test"
|
|
86
|
+
Requires-Dist: pytest==8.3.4; extra == "test"
|
|
87
|
+
Provides-Extra: monitoring
|
|
88
|
+
Requires-Dist: prometheus-flask-exporter==0.23.1; extra == "monitoring"
|
|
89
|
+
Requires-Dist: pygelf==0.4.2; extra == "monitoring"
|
|
90
|
+
Requires-Dist: sentry-sdk==2.19.2; extra == "monitoring"
|
|
91
|
+
Provides-Extra: lint
|
|
92
|
+
Requires-Dist: autoflake==2.3.1; extra == "lint"
|
|
93
|
+
Requires-Dist: black==24.10.0; extra == "lint"
|
|
94
|
+
Requires-Dist: pre-commit==4.0.1; extra == "lint"
|
|
95
|
+
Dynamic: requires-python
|
|
90
96
|
|
|
91
97
|
.. figure:: https://zou.cg-wire.com/kitsu.png
|
|
92
98
|
:alt: Kitsu Logo
|