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/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.20.
|
|
1
|
+
__version__ = "0.20.40"
|
zou/app/api.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import sys
|
|
3
|
+
import importlib
|
|
4
|
+
import traceback
|
|
3
5
|
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
from flask import Blueprint
|
|
6
|
+
from pathlib import Path
|
|
7
7
|
|
|
8
8
|
from zou.app.blueprints.assets import blueprint as assets_blueprint
|
|
9
9
|
from zou.app.blueprints.auth import blueprint as auth_blueprint
|
|
@@ -29,6 +29,9 @@ from zou.app.blueprints.user import blueprint as user_blueprint
|
|
|
29
29
|
from zou.app.blueprints.edits import blueprint as edits_blueprint
|
|
30
30
|
from zou.app.blueprints.concepts import blueprint as concepts_blueprint
|
|
31
31
|
|
|
32
|
+
from zou.app.utils.plugins import PluginManifest
|
|
33
|
+
from zou.app.utils import events
|
|
34
|
+
|
|
32
35
|
|
|
33
36
|
def configure(app):
|
|
34
37
|
"""
|
|
@@ -93,44 +96,36 @@ def register_event_handlers(app):
|
|
|
93
96
|
|
|
94
97
|
def load_plugins(app):
|
|
95
98
|
"""
|
|
96
|
-
Load
|
|
97
|
-
"""
|
|
98
|
-
if os.path.exists(app.config["PLUGIN_FOLDER"]):
|
|
99
|
-
plugins = load_plugin_modules(app.config["PLUGIN_FOLDER"])
|
|
100
|
-
for plugin in plugins:
|
|
101
|
-
load_plugin(app, plugin)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def load_plugin_modules(plugin_folder):
|
|
105
|
-
"""
|
|
106
|
-
Run Python import on all plugin listed in plugin folder. It returns the
|
|
107
|
-
imported module.
|
|
108
|
-
"""
|
|
109
|
-
sys.path.insert(0, plugin_folder)
|
|
110
|
-
return [
|
|
111
|
-
__import__(file_name)
|
|
112
|
-
for file_name in os.listdir(plugin_folder)
|
|
113
|
-
if os.path.isdir(os.path.join(plugin_folder, file_name))
|
|
114
|
-
and file_name != "__pycache__"
|
|
115
|
-
]
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def load_plugin(app, plugin):
|
|
119
|
-
"""
|
|
120
|
-
Load a given plugin as an API plugin: add configured routes to the API. It
|
|
121
|
-
assumes that the plugin is already loaded in memory has a blueprint
|
|
122
|
-
structure.
|
|
99
|
+
Load plugins from the plugin folder.
|
|
123
100
|
"""
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
101
|
+
plugin_folder = app.config["PLUGIN_FOLDER"]
|
|
102
|
+
abs_plugin_path = os.path.abspath(plugin_folder)
|
|
103
|
+
if abs_plugin_path not in sys.path:
|
|
104
|
+
sys.path.insert(0, abs_plugin_path)
|
|
105
|
+
|
|
106
|
+
if os.path.exists(plugin_folder):
|
|
107
|
+
for plugin_id in os.listdir(plugin_folder):
|
|
108
|
+
try:
|
|
109
|
+
load_plugin(app, plugin_id)
|
|
110
|
+
app.logger.info(f"Plugin {plugin_id} loaded.")
|
|
111
|
+
except ImportError as e:
|
|
112
|
+
app.logger.error(f"Plugin {plugin_id} failed to import: {e}")
|
|
113
|
+
except Exception as e:
|
|
114
|
+
app.logger.error(
|
|
115
|
+
f"Plugin {plugin_id} failed to initialize: {e}"
|
|
116
|
+
)
|
|
117
|
+
app.logger.debug(traceback.format_exc())
|
|
118
|
+
|
|
119
|
+
if abs_plugin_path in sys.path:
|
|
120
|
+
sys.path.remove(abs_plugin_path)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def load_plugin(app, plugin_id):
|
|
124
|
+
plugin_path = Path(app.config["PLUGIN_FOLDER"]) / plugin_id
|
|
125
|
+
manifest = PluginManifest.from_file(plugin_path / "manifest.toml")
|
|
126
|
+
|
|
127
|
+
plugin_module = importlib.import_module(plugin_id)
|
|
128
|
+
if hasattr(plugin_module, "init_plugin"):
|
|
129
|
+
plugin_module.init_plugin(app, manifest)
|
|
130
|
+
|
|
131
|
+
return plugin_module
|
|
@@ -129,6 +129,12 @@ from zou.app.blueprints.crud.chat_message import (
|
|
|
129
129
|
ChatMessagesResource,
|
|
130
130
|
)
|
|
131
131
|
from zou.app.blueprints.crud.studio import StudioResource, StudiosResource
|
|
132
|
+
from zou.app.blueprints.crud.salary_scale import (
|
|
133
|
+
SalaryScalesResource,
|
|
134
|
+
SalaryScaleResource,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
from zou.app.blueprints.crud.plugin import PluginResource, PluginsResource
|
|
132
138
|
|
|
133
139
|
routes = [
|
|
134
140
|
("/data/persons", PersonsResource),
|
|
@@ -212,6 +218,10 @@ routes = [
|
|
|
212
218
|
),
|
|
213
219
|
("/data/studios", StudiosResource),
|
|
214
220
|
("/data/studios/<instance_id>", StudioResource),
|
|
221
|
+
("/data/salary-scales", SalaryScalesResource),
|
|
222
|
+
("/data/salary-scales/<instance_id>", SalaryScaleResource),
|
|
223
|
+
("/data/plugins/<instance_id>", PluginResource),
|
|
224
|
+
("/data/plugins", PluginsResource),
|
|
215
225
|
]
|
|
216
226
|
|
|
217
227
|
blueprint = Blueprint("/data", "data")
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
|
|
2
|
+
|
|
3
|
+
from zou.app.models.salary_scale import Budget
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BudgetsResource(BaseModelsResource):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
BaseModelsResource.__init__(self, Budget)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BudgetResource(BaseModelResource):
|
|
12
|
+
protected_fields = [
|
|
13
|
+
"id",
|
|
14
|
+
"created_at",
|
|
15
|
+
"updated_at",
|
|
16
|
+
"project_id",
|
|
17
|
+
"revision",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
def __init__(self):
|
|
21
|
+
BaseModelResource.__init__(self, Budget)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
|
|
2
|
+
|
|
3
|
+
from zou.app.models.salary_scale import BudgetEntry
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BudgetEntriesResource(BaseModelsResource):
|
|
7
|
+
|
|
8
|
+
def __init__(self):
|
|
9
|
+
BaseModelsResource.__init__(self, BudgetEntry)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BudgetEntryResource(BaseModelResource):
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
BaseModelResource.__init__(self, BudgetEntry)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from zou.app.models.plugin import Plugin
|
|
2
|
+
|
|
3
|
+
from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PluginsResource(BaseModelsResource):
|
|
7
|
+
def __init__(self):
|
|
8
|
+
BaseModelsResource.__init__(self, Plugin)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PluginResource(BaseModelResource):
|
|
12
|
+
def __init__(self):
|
|
13
|
+
BaseModelResource.__init__(self, Plugin)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from flask_jwt_extended import jwt_required
|
|
2
|
+
|
|
3
|
+
from zou.app.blueprints.crud.base import BaseModelsResource, BaseModelResource
|
|
4
|
+
|
|
5
|
+
from zou.app.services.exception import WrongParameterException
|
|
6
|
+
|
|
7
|
+
from zou.app.models.department import Department
|
|
8
|
+
from zou.app.models.salary_scale import SalaryScale
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from zou.app.models.person import POSITION_TYPES, SENIORITY_TYPES
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SalaryScalesResource(BaseModelsResource):
|
|
15
|
+
def __init__(self):
|
|
16
|
+
BaseModelsResource.__init__(self, SalaryScale)
|
|
17
|
+
|
|
18
|
+
def check_creation_integrity(self, data):
|
|
19
|
+
raise WrongParameterException("Salary scales cannot be created")
|
|
20
|
+
|
|
21
|
+
@jwt_required()
|
|
22
|
+
def get(self):
|
|
23
|
+
"""
|
|
24
|
+
Retrieve all salary scale entries.
|
|
25
|
+
---
|
|
26
|
+
tags:
|
|
27
|
+
- Crud
|
|
28
|
+
description: Retrieve all salary scale entries.
|
|
29
|
+
responses:
|
|
30
|
+
200:
|
|
31
|
+
description: All salary scale entries
|
|
32
|
+
403:
|
|
33
|
+
description: Permission denied
|
|
34
|
+
"""
|
|
35
|
+
self.check_read_permissions()
|
|
36
|
+
query = self.model.query
|
|
37
|
+
|
|
38
|
+
position_types = [position for position, _ in POSITION_TYPES]
|
|
39
|
+
seniority_types = [seniority for seniority, _ in SENIORITY_TYPES]
|
|
40
|
+
|
|
41
|
+
departments = Department.query.all()
|
|
42
|
+
salary_scales = SalaryScale.query.all()
|
|
43
|
+
salary_scale_map = {}
|
|
44
|
+
for salary_scale in salary_scales:
|
|
45
|
+
key = (
|
|
46
|
+
f"{salary_scale.department_id}-"
|
|
47
|
+
+ f"{salary_scale.position.value.lower()}-"
|
|
48
|
+
+ f"{salary_scale.seniority.value.lower()}"
|
|
49
|
+
)
|
|
50
|
+
salary_scale_map[key] = True
|
|
51
|
+
|
|
52
|
+
for department in departments:
|
|
53
|
+
for position in position_types:
|
|
54
|
+
for seniority in seniority_types:
|
|
55
|
+
key = (
|
|
56
|
+
f"{department.id}-"
|
|
57
|
+
+ f"{position.lower()}-"
|
|
58
|
+
+ f"{seniority.lower()}"
|
|
59
|
+
)
|
|
60
|
+
if key not in salary_scale_map:
|
|
61
|
+
SalaryScale.create(
|
|
62
|
+
department_id=department.id,
|
|
63
|
+
position=position,
|
|
64
|
+
seniority=seniority,
|
|
65
|
+
)
|
|
66
|
+
return self.all_entries(query)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class SalaryScaleResource(BaseModelResource):
|
|
70
|
+
protected_fields = ["id", "created_at", "updated_at", "department_id"]
|
|
71
|
+
|
|
72
|
+
def __init__(self):
|
|
73
|
+
BaseModelResource.__init__(self, SalaryScale)
|
|
@@ -42,6 +42,21 @@ class ProjectPlaylistsResource(Resource, ArgsMixin):
|
|
|
42
42
|
type: string
|
|
43
43
|
format: UUID
|
|
44
44
|
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
45
|
+
- in: query
|
|
46
|
+
name: page
|
|
47
|
+
required: False
|
|
48
|
+
type: integer
|
|
49
|
+
x-example: 1
|
|
50
|
+
- in: query
|
|
51
|
+
name: sort_by
|
|
52
|
+
required: False
|
|
53
|
+
type: string
|
|
54
|
+
x-example: udpdated_at
|
|
55
|
+
- in: query
|
|
56
|
+
name: task_type_id
|
|
57
|
+
required: False
|
|
58
|
+
type: string
|
|
59
|
+
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
45
60
|
responses:
|
|
46
61
|
200:
|
|
47
62
|
description: All playlists related to given project
|
|
@@ -26,6 +26,10 @@ from zou.app.blueprints.projects.resources import (
|
|
|
26
26
|
ProductionEpisodesScheduleItemsResource,
|
|
27
27
|
ProductionSequencesScheduleItemsResource,
|
|
28
28
|
ProductionTimeSpentsResource,
|
|
29
|
+
ProductionBudgetsResource,
|
|
30
|
+
ProductionBudgetResource,
|
|
31
|
+
ProductionBudgetEntriesResource,
|
|
32
|
+
ProductionBudgetEntryResource,
|
|
29
33
|
)
|
|
30
34
|
|
|
31
35
|
routes = [
|
|
@@ -110,6 +114,19 @@ routes = [
|
|
|
110
114
|
ProductionSequencesScheduleItemsResource,
|
|
111
115
|
),
|
|
112
116
|
("/data/projects/<project_id>/time-spents", ProductionTimeSpentsResource),
|
|
117
|
+
("/data/projects/<project_id>/budgets", ProductionBudgetsResource),
|
|
118
|
+
(
|
|
119
|
+
"/data/projects/<project_id>/budgets/<budget_id>",
|
|
120
|
+
ProductionBudgetResource,
|
|
121
|
+
),
|
|
122
|
+
(
|
|
123
|
+
"/data/projects/<project_id>/budgets/<budget_id>/entries",
|
|
124
|
+
ProductionBudgetEntriesResource,
|
|
125
|
+
),
|
|
126
|
+
(
|
|
127
|
+
"/data/projects/<project_id>/budgets/<budget_id>/entries/<entry_id>",
|
|
128
|
+
ProductionBudgetEntryResource,
|
|
129
|
+
),
|
|
113
130
|
]
|
|
114
131
|
|
|
115
132
|
blueprint = Blueprint("projects", "projects")
|