zou 0.20.38__py3-none-any.whl → 0.20.40__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/api.py +38 -43
- zou/app/blueprints/crud/__init__.py +10 -0
- zou/app/blueprints/crud/budget.py +21 -0
- zou/app/blueprints/crud/budget_entry.py +15 -0
- zou/app/blueprints/crud/plugin.py +13 -0
- zou/app/blueprints/crud/salary_scale.py +73 -0
- zou/app/blueprints/playlists/resources.py +15 -0
- zou/app/blueprints/projects/__init__.py +17 -0
- zou/app/blueprints/projects/resources.py +402 -7
- zou/app/blueprints/shots/resources.py +1 -0
- zou/app/mixin.py +12 -1
- zou/app/models/budget.py +39 -0
- zou/app/models/budget_entry.py +65 -0
- zou/app/models/person.py +17 -1
- zou/app/models/plugin.py +21 -0
- zou/app/models/salary_scale.py +28 -0
- zou/app/services/budget_service.py +195 -0
- zou/app/services/comments_service.py +1 -1
- zou/app/services/exception.py +8 -0
- zou/app/services/plugins_service.py +169 -0
- zou/app/services/user_service.py +1 -3
- zou/app/utils/commands.py +51 -1
- zou/app/utils/fields.py +10 -0
- zou/app/utils/plugins.py +88 -0
- zou/cli.py +169 -1
- zou/event_stream.py +23 -5
- zou/migrations/versions/2762a797f1f9_add_people_salary_information.py +52 -0
- zou/migrations/versions/45f739ef962a_add_people_salary_scale_table.py +70 -0
- zou/migrations/versions/4aab1f84ad72_introduce_plugin_table.py +68 -0
- zou/migrations/versions/7a16258f2fab_add_currency_field_to_budgets.py +33 -0
- zou/migrations/versions/83e2f33a9b14_add_project_bugdet_table.py +57 -0
- zou/migrations/versions/8ab98c178903_add_budget_entry_table.py +123 -0
- zou/migrations/versions/d25118cddcaa_modify_salary_scale_model.py +133 -0
- zou/plugin_template/__init__.py +39 -0
- zou/plugin_template/routes.py +6 -0
- {zou-0.20.38.dist-info → zou-0.20.40.dist-info}/METADATA +7 -3
- {zou-0.20.38.dist-info → zou-0.20.40.dist-info}/RECORD +42 -22
- {zou-0.20.38.dist-info → zou-0.20.40.dist-info}/WHEEL +1 -1
- {zou-0.20.38.dist-info → zou-0.20.40.dist-info}/entry_points.txt +0 -0
- {zou-0.20.38.dist-info → zou-0.20.40.dist-info}/licenses/LICENSE +0 -0
- {zou-0.20.38.dist-info → zou-0.20.40.dist-info}/top_level.txt +0 -0
zou/cli.py
CHANGED
|
@@ -9,12 +9,13 @@ import traceback
|
|
|
9
9
|
from sqlalchemy.exc import IntegrityError
|
|
10
10
|
|
|
11
11
|
from zou.app.utils import dbhelpers, auth, commands
|
|
12
|
-
from zou.app.services import persons_service, auth_service
|
|
12
|
+
from zou.app.services import persons_service, auth_service, plugins_service
|
|
13
13
|
from zou.app.services.exception import (
|
|
14
14
|
IsUserLimitReachedException,
|
|
15
15
|
PersonNotFoundException,
|
|
16
16
|
TwoFactorAuthenticationNotEnabledException,
|
|
17
17
|
)
|
|
18
|
+
|
|
18
19
|
from zou.app import app, config
|
|
19
20
|
|
|
20
21
|
from zou import __file__ as root_path
|
|
@@ -643,5 +644,172 @@ def renormalize_movie_preview_files(
|
|
|
643
644
|
)
|
|
644
645
|
|
|
645
646
|
|
|
647
|
+
@cli.command()
|
|
648
|
+
@click.option(
|
|
649
|
+
"--path",
|
|
650
|
+
required=True,
|
|
651
|
+
)
|
|
652
|
+
@click.option(
|
|
653
|
+
"--force",
|
|
654
|
+
is_flag=True,
|
|
655
|
+
default=False,
|
|
656
|
+
show_default=True,
|
|
657
|
+
)
|
|
658
|
+
def install_plugin(path, force=False):
|
|
659
|
+
"""
|
|
660
|
+
Install a plugin.
|
|
661
|
+
"""
|
|
662
|
+
with app.app_context():
|
|
663
|
+
plugins_service.install_plugin(path, force)
|
|
664
|
+
print(f"Plugin {path} installed. Restart the server to apply changes.")
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
@cli.command()
|
|
668
|
+
@click.option(
|
|
669
|
+
"--id",
|
|
670
|
+
required=True,
|
|
671
|
+
)
|
|
672
|
+
def uninstall_plugin(id):
|
|
673
|
+
"""
|
|
674
|
+
Uninstall a plugin.
|
|
675
|
+
"""
|
|
676
|
+
with app.app_context():
|
|
677
|
+
plugins_service.uninstall_plugin(id)
|
|
678
|
+
print(f"Plugin {id} uninstalled.")
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
@cli.command()
|
|
682
|
+
@click.option(
|
|
683
|
+
"--path",
|
|
684
|
+
required=True,
|
|
685
|
+
)
|
|
686
|
+
@click.option(
|
|
687
|
+
"--id",
|
|
688
|
+
help="Plugin ID (must be unique).",
|
|
689
|
+
required=True,
|
|
690
|
+
)
|
|
691
|
+
@click.option(
|
|
692
|
+
"--name", help="Plugin name.", default="MyPlugin", show_default=True
|
|
693
|
+
)
|
|
694
|
+
@click.option(
|
|
695
|
+
"--description",
|
|
696
|
+
help="Plugin description.",
|
|
697
|
+
default="My plugin description.",
|
|
698
|
+
show_default=True,
|
|
699
|
+
)
|
|
700
|
+
@click.option(
|
|
701
|
+
"--version", help="Plugin version.", default="0.1.0", show_default=True
|
|
702
|
+
)
|
|
703
|
+
@click.option(
|
|
704
|
+
"--maintainer",
|
|
705
|
+
help="Plugin maintainer.",
|
|
706
|
+
default="Author <author@author.com>",
|
|
707
|
+
show_default=True,
|
|
708
|
+
)
|
|
709
|
+
@click.option(
|
|
710
|
+
"--website",
|
|
711
|
+
help="Plugin website.",
|
|
712
|
+
default="mywebsite.com",
|
|
713
|
+
show_default=True,
|
|
714
|
+
)
|
|
715
|
+
@click.option(
|
|
716
|
+
"--license",
|
|
717
|
+
help="Plugin license.",
|
|
718
|
+
default="GPL-3.0-only",
|
|
719
|
+
show_default=True,
|
|
720
|
+
)
|
|
721
|
+
@click.option(
|
|
722
|
+
"--force",
|
|
723
|
+
is_flag=True,
|
|
724
|
+
default=False,
|
|
725
|
+
show_default=True,
|
|
726
|
+
)
|
|
727
|
+
def create_plugin_skeleton(
|
|
728
|
+
path,
|
|
729
|
+
id,
|
|
730
|
+
name,
|
|
731
|
+
description,
|
|
732
|
+
version,
|
|
733
|
+
maintainer,
|
|
734
|
+
website,
|
|
735
|
+
license,
|
|
736
|
+
force=False,
|
|
737
|
+
):
|
|
738
|
+
"""
|
|
739
|
+
Create a plugin skeleton.
|
|
740
|
+
"""
|
|
741
|
+
plugin_path = plugins_service.create_plugin_skeleton(
|
|
742
|
+
path,
|
|
743
|
+
id,
|
|
744
|
+
name,
|
|
745
|
+
description,
|
|
746
|
+
version,
|
|
747
|
+
maintainer,
|
|
748
|
+
website,
|
|
749
|
+
license,
|
|
750
|
+
force,
|
|
751
|
+
)
|
|
752
|
+
print(f"Plugin skeleton created in '{plugin_path}'.")
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
@cli.command()
|
|
756
|
+
@click.option(
|
|
757
|
+
"--path",
|
|
758
|
+
required=True,
|
|
759
|
+
)
|
|
760
|
+
@click.option(
|
|
761
|
+
"--output-path",
|
|
762
|
+
required=True,
|
|
763
|
+
)
|
|
764
|
+
@click.option(
|
|
765
|
+
"--force",
|
|
766
|
+
is_flag=True,
|
|
767
|
+
default=False,
|
|
768
|
+
show_default=True,
|
|
769
|
+
)
|
|
770
|
+
def create_plugin_package(
|
|
771
|
+
path,
|
|
772
|
+
output_path,
|
|
773
|
+
force=False,
|
|
774
|
+
):
|
|
775
|
+
"""
|
|
776
|
+
Create a plugin package.
|
|
777
|
+
"""
|
|
778
|
+
plugin_path = plugins_service.create_plugin_package(
|
|
779
|
+
path, output_path, force
|
|
780
|
+
)
|
|
781
|
+
print(f"Plugin package created in '{plugin_path}'.")
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
@cli.command()
|
|
785
|
+
@click.option(
|
|
786
|
+
"--format",
|
|
787
|
+
"output_format",
|
|
788
|
+
type=click.Choice(["table", "json"], case_sensitive=False),
|
|
789
|
+
default="table",
|
|
790
|
+
show_default=True,
|
|
791
|
+
help="Output format: table or json.",
|
|
792
|
+
)
|
|
793
|
+
@click.option(
|
|
794
|
+
"--verbose",
|
|
795
|
+
is_flag=True,
|
|
796
|
+
default=False,
|
|
797
|
+
help="Show more plugin information.",
|
|
798
|
+
)
|
|
799
|
+
@click.option(
|
|
800
|
+
"--filter-field",
|
|
801
|
+
type=click.Choice(
|
|
802
|
+
["plugin_id", "name", "maintainer", "license"], case_sensitive=False
|
|
803
|
+
),
|
|
804
|
+
help="Field to filter by.",
|
|
805
|
+
)
|
|
806
|
+
@click.option("--filter-value", type=str, help="Value to search in the field.")
|
|
807
|
+
def list_plugins(output_format, verbose, filter_field, filter_value):
|
|
808
|
+
"""
|
|
809
|
+
List installed plugins.
|
|
810
|
+
"""
|
|
811
|
+
commands.list_plugins(output_format, verbose, filter_field, filter_value)
|
|
812
|
+
|
|
813
|
+
|
|
646
814
|
if __name__ == "__main__":
|
|
647
815
|
cli()
|
zou/event_stream.py
CHANGED
|
@@ -35,6 +35,9 @@ def _get_empty_room(current_frame=0):
|
|
|
35
35
|
"current_preview_file_index": None,
|
|
36
36
|
"current_frame": current_frame,
|
|
37
37
|
"is_repeating": None,
|
|
38
|
+
"is_annotations_displayed": False,
|
|
39
|
+
"is_zoom_enabled": False,
|
|
40
|
+
"is_waveform_displayed": False,
|
|
38
41
|
"is_laser_mode": None,
|
|
39
42
|
"handle_in": None,
|
|
40
43
|
"handle_out": None,
|
|
@@ -59,7 +62,7 @@ def _leave_room(room_id, user_id):
|
|
|
59
62
|
room["people"] = list(set(room["people"]) - {user_id})
|
|
60
63
|
if len(room["people"]) > 0:
|
|
61
64
|
rooms_data[room_id] = room
|
|
62
|
-
|
|
65
|
+
elif room_id in rooms_data:
|
|
63
66
|
del rooms_data[room_id]
|
|
64
67
|
_emit_people_updated(room_id, room["people"])
|
|
65
68
|
return room
|
|
@@ -81,10 +84,17 @@ def _update_room_playing_status(data, room):
|
|
|
81
84
|
room["is_playing"] = data.get("is_playing", False)
|
|
82
85
|
room["is_repeating"] = data.get("is_repeating", False)
|
|
83
86
|
room["is_laser_mode"] = data.get("is_laser_mode", False)
|
|
87
|
+
room["is_annotations_displayed"] = data.get(
|
|
88
|
+
"is_annotations_displayed", False
|
|
89
|
+
)
|
|
90
|
+
room["is_zoom_enabled"] = data.get("is_zoom_enabled", False)
|
|
91
|
+
room["is_waveform_displayed"] = data.get("is_waveform_displayed", False)
|
|
84
92
|
room["current_entity_id"] = data.get("current_entity_id", None)
|
|
85
93
|
room["current_entity_index"] = data.get("current_entity_index", None)
|
|
86
94
|
room["current_preview_file_id"] = data.get("current_preview_file_id", None)
|
|
87
|
-
room["current_preview_file_index"] = data.get(
|
|
95
|
+
room["current_preview_file_index"] = data.get(
|
|
96
|
+
"current_preview_file_index", None
|
|
97
|
+
)
|
|
88
98
|
room["handle_in"] = data.get("handle_in", None)
|
|
89
99
|
room["handle_out"] = data.get("handle_out", None)
|
|
90
100
|
if "current_frame" in data:
|
|
@@ -193,19 +203,20 @@ def on_join(data):
|
|
|
193
203
|
room["playlist_id"] = room_id
|
|
194
204
|
rooms_data[room_id] = room
|
|
195
205
|
_emit_people_updated(room_id, room["people"])
|
|
206
|
+
emit("preview-room:room-updated", room, room=room_id)
|
|
196
207
|
|
|
197
208
|
|
|
198
209
|
@socketio.on("preview-room:leave", namespace="/events")
|
|
199
210
|
@jwt_required()
|
|
200
211
|
def on_leave(data):
|
|
201
212
|
user_id = get_jwt_identity()
|
|
202
|
-
room_id = data
|
|
213
|
+
room_id = data.get("playlist_id", "")
|
|
203
214
|
_leave_room(room_id, user_id)
|
|
204
215
|
|
|
205
216
|
|
|
206
|
-
@socketio.on("preview-room:
|
|
217
|
+
@socketio.on("preview-room:room-updated", namespace="/events")
|
|
207
218
|
@jwt_required()
|
|
208
|
-
def
|
|
219
|
+
def on_room_updated(data, only_newcomer=False):
|
|
209
220
|
room, room_id = _get_room_from_data(data)
|
|
210
221
|
rooms_data[room_id] = _update_room_playing_status(data, room)
|
|
211
222
|
event_data = {"only_newcomer": only_newcomer, **rooms_data[room_id]}
|
|
@@ -240,6 +251,13 @@ def on_change_version(data):
|
|
|
240
251
|
emit("preview-room:change-version", data, room=room_id)
|
|
241
252
|
|
|
242
253
|
|
|
254
|
+
@socketio.on("preview-room:panzoom-changed", namespace="/events")
|
|
255
|
+
@jwt_required()
|
|
256
|
+
def on_change_version(data):
|
|
257
|
+
room_id = data["playlist_id"]
|
|
258
|
+
emit("preview-room:panzoom-changed", data, room=room_id)
|
|
259
|
+
|
|
260
|
+
|
|
243
261
|
if __name__ == "__main__":
|
|
244
262
|
socketio.run(
|
|
245
263
|
app,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""add people salary information
|
|
2
|
+
|
|
3
|
+
Revision ID: 2762a797f1f9
|
|
4
|
+
Revises: 307edd8c639d
|
|
5
|
+
Create Date: 2025-04-01 18:02:39.343857
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
import sqlalchemy_utils
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# revision identifiers, used by Alembic.
|
|
15
|
+
revision = "2762a797f1f9"
|
|
16
|
+
down_revision = "307edd8c639d"
|
|
17
|
+
branch_labels = None
|
|
18
|
+
depends_on = None
|
|
19
|
+
|
|
20
|
+
from zou.app.models.person import POSITION_TYPES, SENIORITY_TYPES
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def upgrade():
|
|
24
|
+
with op.batch_alter_table("person", schema=None) as batch_op:
|
|
25
|
+
batch_op.add_column(
|
|
26
|
+
sa.Column(
|
|
27
|
+
"position",
|
|
28
|
+
sqlalchemy_utils.types.choice.ChoiceType(POSITION_TYPES),
|
|
29
|
+
nullable=True,
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
batch_op.add_column(
|
|
33
|
+
sa.Column(
|
|
34
|
+
"seniority",
|
|
35
|
+
sqlalchemy_utils.types.choice.ChoiceType(SENIORITY_TYPES),
|
|
36
|
+
nullable=True,
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
batch_op.add_column(
|
|
40
|
+
sa.Column("daily_salary", sa.Integer(), nullable=True)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# ### end Alembic commands ###
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def downgrade():
|
|
47
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
48
|
+
with op.batch_alter_table("person", schema=None) as batch_op:
|
|
49
|
+
batch_op.drop_column("daily_salary")
|
|
50
|
+
batch_op.drop_column("seniority")
|
|
51
|
+
batch_op.drop_column("position")
|
|
52
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""add people salary scale table
|
|
2
|
+
|
|
3
|
+
Revision ID: 45f739ef962a
|
|
4
|
+
Revises: 2762a797f1f9
|
|
5
|
+
Create Date: 2025-04-02 10:11:12.544243
|
|
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 = "45f739ef962a"
|
|
17
|
+
down_revision = "2762a797f1f9"
|
|
18
|
+
branch_labels = None
|
|
19
|
+
depends_on = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def upgrade():
|
|
23
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
24
|
+
op.create_table(
|
|
25
|
+
"salary_scale",
|
|
26
|
+
sa.Column(
|
|
27
|
+
"department_id",
|
|
28
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
29
|
+
default=uuid.uuid4,
|
|
30
|
+
nullable=False,
|
|
31
|
+
),
|
|
32
|
+
sa.Column("senior_supervisor_salary", sa.Integer(), nullable=False),
|
|
33
|
+
sa.Column("mid_supervisor_salary", sa.Integer(), nullable=False),
|
|
34
|
+
sa.Column("junior_supervisor_salary", sa.Integer(), nullable=False),
|
|
35
|
+
sa.Column("senior_lead_salary", sa.Integer(), nullable=False),
|
|
36
|
+
sa.Column("mid_lead_salary", sa.Integer(), nullable=False),
|
|
37
|
+
sa.Column("junior_lead_salary", sa.Integer(), nullable=False),
|
|
38
|
+
sa.Column("senior_artist_salary", sa.Integer(), nullable=False),
|
|
39
|
+
sa.Column("mid_artist_salary", sa.Integer(), nullable=False),
|
|
40
|
+
sa.Column("junior_artist_salary", sa.Integer(), nullable=False),
|
|
41
|
+
sa.Column(
|
|
42
|
+
"id",
|
|
43
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
44
|
+
default=uuid.uuid4,
|
|
45
|
+
nullable=False,
|
|
46
|
+
),
|
|
47
|
+
sa.Column("created_at", sa.DateTime(), nullable=True),
|
|
48
|
+
sa.Column("updated_at", sa.DateTime(), nullable=True),
|
|
49
|
+
sa.ForeignKeyConstraint(
|
|
50
|
+
["department_id"],
|
|
51
|
+
["department.id"],
|
|
52
|
+
),
|
|
53
|
+
sa.PrimaryKeyConstraint("id"),
|
|
54
|
+
)
|
|
55
|
+
with op.batch_alter_table("salary_scale", schema=None) as batch_op:
|
|
56
|
+
batch_op.create_index(
|
|
57
|
+
batch_op.f("ix_salary_scale_department_id"),
|
|
58
|
+
["department_id"],
|
|
59
|
+
unique=False,
|
|
60
|
+
)
|
|
61
|
+
# ### end Alembic commands ###
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def downgrade():
|
|
65
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
66
|
+
with op.batch_alter_table("salary_scale", schema=None) as batch_op:
|
|
67
|
+
batch_op.drop_index(batch_op.f("ix_salary_scale_department_id"))
|
|
68
|
+
|
|
69
|
+
op.drop_table("salary_scale")
|
|
70
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Introduce Plugin table
|
|
2
|
+
|
|
3
|
+
Revision ID: 4aab1f84ad72
|
|
4
|
+
Revises: d25118cddcaa
|
|
5
|
+
Create Date: 2025-04-14 15:18:29.346896
|
|
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 = "4aab1f84ad72"
|
|
17
|
+
down_revision = "d25118cddcaa"
|
|
18
|
+
branch_labels = None
|
|
19
|
+
depends_on = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def upgrade():
|
|
23
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
24
|
+
op.create_table(
|
|
25
|
+
"plugin",
|
|
26
|
+
sa.Column("plugin_id", sa.String(length=80), nullable=False),
|
|
27
|
+
sa.Column("name", sa.String(length=80), nullable=False),
|
|
28
|
+
sa.Column("description", sa.Text(), nullable=True),
|
|
29
|
+
sa.Column("version", sa.String(length=50), nullable=False),
|
|
30
|
+
sa.Column("maintainer_name", sa.String(length=200), nullable=False),
|
|
31
|
+
sa.Column(
|
|
32
|
+
"maintainer_email",
|
|
33
|
+
sqlalchemy_utils.types.email.EmailType(length=255),
|
|
34
|
+
nullable=True,
|
|
35
|
+
),
|
|
36
|
+
sa.Column(
|
|
37
|
+
"website", sqlalchemy_utils.types.url.URLType(), nullable=True
|
|
38
|
+
),
|
|
39
|
+
sa.Column("license", sa.String(length=80), nullable=False),
|
|
40
|
+
sa.Column(
|
|
41
|
+
"id",
|
|
42
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
43
|
+
default=uuid.uuid4,
|
|
44
|
+
nullable=False,
|
|
45
|
+
),
|
|
46
|
+
sa.Column("created_at", sa.DateTime(), nullable=True),
|
|
47
|
+
sa.Column("updated_at", sa.DateTime(), nullable=True),
|
|
48
|
+
sa.PrimaryKeyConstraint("id"),
|
|
49
|
+
)
|
|
50
|
+
with op.batch_alter_table("plugin", schema=None) as batch_op:
|
|
51
|
+
batch_op.create_index(
|
|
52
|
+
batch_op.f("ix_plugin_name"), ["name"], unique=False
|
|
53
|
+
)
|
|
54
|
+
batch_op.create_index(
|
|
55
|
+
batch_op.f("ix_plugin_plugin_id"), ["plugin_id"], unique=True
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# ### end Alembic commands ###
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def downgrade():
|
|
62
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
63
|
+
with op.batch_alter_table("plugin", schema=None) as batch_op:
|
|
64
|
+
batch_op.drop_index(batch_op.f("ix_plugin_plugin_id"))
|
|
65
|
+
batch_op.drop_index(batch_op.f("ix_plugin_name"))
|
|
66
|
+
|
|
67
|
+
op.drop_table("plugin")
|
|
68
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""add currency field to budgets
|
|
2
|
+
|
|
3
|
+
Revision ID: 7a16258f2fab
|
|
4
|
+
Revises: 8ab98c178903
|
|
5
|
+
Create Date: 2025-04-21 22:27:22.703525
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "7a16258f2fab"
|
|
15
|
+
down_revision = "8ab98c178903"
|
|
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("budget", schema=None) as batch_op:
|
|
23
|
+
batch_op.add_column(sa.Column("currency", sa.String(length=3)))
|
|
24
|
+
# ### end Alembic commands ###
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def downgrade():
|
|
28
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
29
|
+
with op.batch_alter_table("task", schema=None) as batch_op:
|
|
30
|
+
batch_op.alter_column(
|
|
31
|
+
"difficulty", existing_type=sa.INTEGER(), nullable=True
|
|
32
|
+
)
|
|
33
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""add project bugdet table
|
|
2
|
+
|
|
3
|
+
Revision ID: 83e2f33a9b14
|
|
4
|
+
Revises: 45f739ef962a
|
|
5
|
+
Create Date: 2025-04-09 20:17:08.331320
|
|
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 = "83e2f33a9b14"
|
|
17
|
+
down_revision = "45f739ef962a"
|
|
18
|
+
branch_labels = None
|
|
19
|
+
depends_on = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def upgrade():
|
|
23
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
24
|
+
op.create_table(
|
|
25
|
+
"budget",
|
|
26
|
+
sa.Column(
|
|
27
|
+
"project_id",
|
|
28
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
29
|
+
default=uuid.uuid4,
|
|
30
|
+
nullable=False,
|
|
31
|
+
),
|
|
32
|
+
sa.Column("revision", sa.Integer(), nullable=False),
|
|
33
|
+
sa.Column("name", sa.String(length=255), nullable=False),
|
|
34
|
+
sa.Column(
|
|
35
|
+
"id",
|
|
36
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
37
|
+
default=uuid.uuid4,
|
|
38
|
+
nullable=False,
|
|
39
|
+
),
|
|
40
|
+
sa.Column("created_at", sa.DateTime(), nullable=True),
|
|
41
|
+
sa.Column("updated_at", sa.DateTime(), nullable=True),
|
|
42
|
+
sa.PrimaryKeyConstraint("id"),
|
|
43
|
+
)
|
|
44
|
+
with op.batch_alter_table("budget", schema=None) as batch_op:
|
|
45
|
+
batch_op.create_index(
|
|
46
|
+
batch_op.f("ix_budget_project_id"), ["project_id"], unique=False
|
|
47
|
+
)
|
|
48
|
+
# ### end Alembic commands ###
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def downgrade():
|
|
52
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
53
|
+
with op.batch_alter_table("budget", schema=None) as batch_op:
|
|
54
|
+
batch_op.drop_index(batch_op.f("ix_budget_project_id"))
|
|
55
|
+
|
|
56
|
+
op.drop_table("budget")
|
|
57
|
+
# ### end Alembic commands ###
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""add budget entry table
|
|
2
|
+
|
|
3
|
+
Revision ID: 8ab98c178903
|
|
4
|
+
Revises: 83e2f33a9b14
|
|
5
|
+
Create Date: 2025-04-15 16:56:25.451489
|
|
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 = "8ab98c178903"
|
|
17
|
+
down_revision = "83e2f33a9b14"
|
|
18
|
+
branch_labels = None
|
|
19
|
+
depends_on = None
|
|
20
|
+
|
|
21
|
+
from zou.app.models.person import POSITION_TYPES, SENIORITY_TYPES
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def upgrade():
|
|
25
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
26
|
+
op.create_table(
|
|
27
|
+
"budget_entry",
|
|
28
|
+
sa.Column(
|
|
29
|
+
"budget_id",
|
|
30
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
31
|
+
default=uuid.uuid4,
|
|
32
|
+
nullable=False,
|
|
33
|
+
),
|
|
34
|
+
sa.Column(
|
|
35
|
+
"department_id",
|
|
36
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
37
|
+
default=uuid.uuid4,
|
|
38
|
+
nullable=False,
|
|
39
|
+
),
|
|
40
|
+
sa.Column(
|
|
41
|
+
"person_id",
|
|
42
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
43
|
+
default=uuid.uuid4,
|
|
44
|
+
nullable=True,
|
|
45
|
+
),
|
|
46
|
+
sa.Column("start_date", sa.Date(), nullable=False),
|
|
47
|
+
sa.Column("months_duration", sa.Integer(), nullable=False),
|
|
48
|
+
sa.Column("daily_salary", sa.Float(), nullable=False),
|
|
49
|
+
sa.Column(
|
|
50
|
+
"position",
|
|
51
|
+
sqlalchemy_utils.types.choice.ChoiceType(POSITION_TYPES),
|
|
52
|
+
nullable=True,
|
|
53
|
+
),
|
|
54
|
+
sa.Column(
|
|
55
|
+
"seniority",
|
|
56
|
+
sqlalchemy_utils.types.choice.ChoiceType(SENIORITY_TYPES),
|
|
57
|
+
nullable=True,
|
|
58
|
+
),
|
|
59
|
+
sa.Column(
|
|
60
|
+
"id",
|
|
61
|
+
sqlalchemy_utils.types.uuid.UUIDType(binary=False),
|
|
62
|
+
default=uuid.uuid4,
|
|
63
|
+
nullable=False,
|
|
64
|
+
),
|
|
65
|
+
sa.Column("created_at", sa.DateTime(), nullable=True),
|
|
66
|
+
sa.Column("updated_at", sa.DateTime(), nullable=True),
|
|
67
|
+
sa.ForeignKeyConstraint(
|
|
68
|
+
["budget_id"],
|
|
69
|
+
["budget.id"],
|
|
70
|
+
),
|
|
71
|
+
sa.ForeignKeyConstraint(
|
|
72
|
+
["department_id"],
|
|
73
|
+
["department.id"],
|
|
74
|
+
),
|
|
75
|
+
sa.ForeignKeyConstraint(
|
|
76
|
+
["person_id"],
|
|
77
|
+
["person.id"],
|
|
78
|
+
),
|
|
79
|
+
sa.PrimaryKeyConstraint("id"),
|
|
80
|
+
)
|
|
81
|
+
with op.batch_alter_table("budget_entry", schema=None) as batch_op:
|
|
82
|
+
batch_op.create_index(
|
|
83
|
+
batch_op.f("ix_budget_entry_budget_id"),
|
|
84
|
+
["budget_id"],
|
|
85
|
+
unique=False,
|
|
86
|
+
)
|
|
87
|
+
batch_op.create_index(
|
|
88
|
+
batch_op.f("ix_budget_entry_department_id"),
|
|
89
|
+
["department_id"],
|
|
90
|
+
unique=False,
|
|
91
|
+
)
|
|
92
|
+
batch_op.create_index(
|
|
93
|
+
batch_op.f("ix_budget_entry_person_id"),
|
|
94
|
+
["person_id"],
|
|
95
|
+
unique=False,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
with op.batch_alter_table("budget", schema=None) as batch_op:
|
|
99
|
+
batch_op.alter_column(
|
|
100
|
+
"project_id", existing_type=sa.UUID(), nullable=True
|
|
101
|
+
)
|
|
102
|
+
batch_op.create_foreign_key(
|
|
103
|
+
"budget_project_id_fkey", "project", ["project_id"], ["id"]
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# ### end Alembic commands ###
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def downgrade():
|
|
110
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
111
|
+
with op.batch_alter_table("budget", schema=None) as batch_op:
|
|
112
|
+
batch_op.drop_constraint("budget_project_id_fkey", type_="foreignkey")
|
|
113
|
+
batch_op.alter_column(
|
|
114
|
+
"project_id", existing_type=sa.UUID(), nullable=False
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
with op.batch_alter_table("budget_entry", schema=None) as batch_op:
|
|
118
|
+
batch_op.drop_index(batch_op.f("ix_budget_entry_person_id"))
|
|
119
|
+
batch_op.drop_index(batch_op.f("ix_budget_entry_department_id"))
|
|
120
|
+
batch_op.drop_index(batch_op.f("ix_budget_entry_budget_id"))
|
|
121
|
+
|
|
122
|
+
op.drop_table("budget_entry")
|
|
123
|
+
# ### end Alembic commands ###
|