WIP: convert GORM to sqlc, for jobs/tasks #104304

Closed
Sybren A. Stüvel wants to merge 27 commits from sqlc-task into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
28 changed files with 1035 additions and 406 deletions
Showing only changes of commit bfc7c07629 - Show all commits

View File

@ -1,9 +1,9 @@
name: Bug Report name: Bug Report
about: File a bug report about: File a bug report
labels: labels:
- "type::Report" - "Type/Report"
- "status::Needs Triage" - "Status/Needs Triage"
- "priority::Normal" - "Priority/Normal"
body: body:
- type: markdown - type: markdown
attributes: attributes:

View File

@ -1,7 +1,7 @@
name: Design name: Design
about: Create a design task (for developers only) about: Create a design task (for developers only)
labels: labels:
- "type::Design" - "Type/Design"
body: body:
- type: textarea - type: textarea
id: body id: body

View File

@ -0,0 +1,41 @@
name: Custom Job Type
about: Submit your custom job type
labels:
- "Type/Job Type"
body:
- type: markdown
attributes:
value: |
## Thanks for contributing!
With this form you can submit your custom job type for listing on https://flamenco.blender.org/third-party-jobs/
- type: input
id: blender_version
attributes:
label: "Blender Version(s)"
description: "Which version(s) of Blender are known to work with this job type?"
required: true
- type: input
id: flamenco_version
attributes:
label: "Flamenco Version(s)"
description: "Which version(s) of Flamenco are known to work with this job type?"
required: true
- type: textarea
id: description
attributes:
label: "Description"
description: "Please describe what this job type does, what the target audience is, how to use it, etc. Feel free to include images as well."
required: true
- type: markdown
attributes:
value: |
Please understand that both Flamenco and Blender are under constant
development. By their very nature, this means that every once in a while
your job type will need some attention and updating.
- type: checkboxes
id: understanding
attributes:
label: "Will you help to keep things up to date?"
options:
- label: "Yes, I'll check with new versions of Blender and/or Flamenco, and send in a report when updating is necessary"

View File

@ -1,7 +1,7 @@
name: To Do name: To Do
about: Create a to do task (for developers only) about: Create a to do task (for developers only)
labels: labels:
- "type::To Do" - "Type/To Do"
body: body:
- type: textarea - type: textarea
id: body id: body

View File

@ -6,6 +6,9 @@ bugs in actually-released versions.
## 3.6 - in development ## 3.6 - in development
- Add `label` to job settings, to have full control over how they are presented in Blender's job submission GUI. If a job setting does not define a label, its `key` is used to generate one (like Flamenco 3.5 and older).
- Add `shellSplit(someString)` function to the job compiler scripts. This splits a string into an array of strings using shell/CLI semantics.
## 3.5 - released 2024-04-16 ## 3.5 - released 2024-04-16
- Add MQTT support ([docs](https://flamenco.blender.org/usage/manager-configuration/mqtt/)). Flamenco Manager can now send internal events to an MQTT broker. - Add MQTT support ([docs](https://flamenco.blender.org/usage/manager-configuration/mqtt/)). Flamenco Manager can now send internal events to an MQTT broker.

View File

@ -304,8 +304,8 @@ def _create_property(job_type: _AvailableJobType, setting: _AvailableJobSetting)
if not setting.get("editable", True): if not setting.get("editable", True):
prop_kwargs["get"] = _create_prop_getter(job_type, setting) prop_kwargs["get"] = _create_prop_getter(job_type, setting)
prop_name = _job_setting_key_to_label(setting.key) prop_label = _job_setting_label(setting)
prop = prop_type(name=prop_name, **prop_kwargs) prop = prop_type(name=prop_label, **prop_kwargs)
return prop return prop
@ -316,10 +316,10 @@ def _create_autoeval_property(
assert isinstance(setting, AvailableJobSetting) assert isinstance(setting, AvailableJobSetting)
setting_name = _job_setting_key_to_label(setting.key) setting_label = _job_setting_label(setting)
prop_descr = ( prop_descr = (
"Automatically determine the value for %r when the job gets submitted" "Automatically determine the value for %r when the job gets submitted"
% setting_name % setting_label
) )
prop = bpy.props.BoolProperty( prop = bpy.props.BoolProperty(
@ -379,13 +379,13 @@ def _job_type_to_class_name(job_type_name: str) -> str:
return job_type_name.title().replace("-", "") return job_type_name.title().replace("-", "")
def _job_setting_key_to_label(setting_key: str) -> str: def _job_setting_label(setting: _AvailableJobSetting) -> str:
"""Change 'some_setting_key' to 'Some Setting Key'. """Return a suitable label for this job setting."""
>>> _job_setting_key_to_label('some_setting_key') label = setting.get("label", default="")
'Some Setting Key' if label:
""" return label
return setting_key.title().replace("_", " ") return setting.key.title().replace("_", " ")
def _set_if_available( def _set_if_available(

View File

@ -11,6 +11,7 @@ Name | Type | Description | Notes
**choices** | **[str]** | When given, limit the valid values to these choices. Only usable with string type. | [optional] **choices** | **[str]** | When given, limit the valid values to these choices. Only usable with string type. | [optional]
**propargs** | **{str: (bool, date, datetime, dict, float, int, list, str, none_type)}** | Any extra arguments to the bpy.props.SomeProperty() call used to create this property. | [optional] **propargs** | **{str: (bool, date, datetime, dict, float, int, list, str, none_type)}** | Any extra arguments to the bpy.props.SomeProperty() call used to create this property. | [optional]
**description** | **bool, date, datetime, dict, float, int, list, str, none_type** | The description/tooltip shown in the user interface. | [optional] **description** | **bool, date, datetime, dict, float, int, list, str, none_type** | The description/tooltip shown in the user interface. | [optional]
**label** | **bool, date, datetime, dict, float, int, list, str, none_type** | Label for displaying this setting. If not specified, the key is used to generate a reasonable label. | [optional]
**default** | **bool, date, datetime, dict, float, int, list, str, none_type** | The default value shown to the user when determining this setting. | [optional] **default** | **bool, date, datetime, dict, float, int, list, str, none_type** | The default value shown to the user when determining this setting. | [optional]
**eval** | **str** | Python expression to be evaluated in order to determine the default value for this setting. | [optional] **eval** | **str** | Python expression to be evaluated in order to determine the default value for this setting. | [optional]
**eval_info** | [**AvailableJobSettingEvalInfo**](AvailableJobSettingEvalInfo.md) | | [optional] **eval_info** | [**AvailableJobSettingEvalInfo**](AvailableJobSettingEvalInfo.md) | | [optional]

View File

@ -99,6 +99,7 @@ class AvailableJobSetting(ModelNormal):
'choices': ([str],), # noqa: E501 'choices': ([str],), # noqa: E501
'propargs': ({str: (bool, date, datetime, dict, float, int, list, str, none_type)},), # noqa: E501 'propargs': ({str: (bool, date, datetime, dict, float, int, list, str, none_type)},), # noqa: E501
'description': (bool, date, datetime, dict, float, int, list, str, none_type,), # noqa: E501 'description': (bool, date, datetime, dict, float, int, list, str, none_type,), # noqa: E501
'label': (bool, date, datetime, dict, float, int, list, str, none_type,), # noqa: E501
'default': (bool, date, datetime, dict, float, int, list, str, none_type,), # noqa: E501 'default': (bool, date, datetime, dict, float, int, list, str, none_type,), # noqa: E501
'eval': (str,), # noqa: E501 'eval': (str,), # noqa: E501
'eval_info': (AvailableJobSettingEvalInfo,), # noqa: E501 'eval_info': (AvailableJobSettingEvalInfo,), # noqa: E501
@ -119,6 +120,7 @@ class AvailableJobSetting(ModelNormal):
'choices': 'choices', # noqa: E501 'choices': 'choices', # noqa: E501
'propargs': 'propargs', # noqa: E501 'propargs': 'propargs', # noqa: E501
'description': 'description', # noqa: E501 'description': 'description', # noqa: E501
'label': 'label', # noqa: E501
'default': 'default', # noqa: E501 'default': 'default', # noqa: E501
'eval': 'eval', # noqa: E501 'eval': 'eval', # noqa: E501
'eval_info': 'evalInfo', # noqa: E501 'eval_info': 'evalInfo', # noqa: E501
@ -176,6 +178,7 @@ class AvailableJobSetting(ModelNormal):
choices ([str]): When given, limit the valid values to these choices. Only usable with string type.. [optional] # noqa: E501 choices ([str]): When given, limit the valid values to these choices. Only usable with string type.. [optional] # noqa: E501
propargs ({str: (bool, date, datetime, dict, float, int, list, str, none_type)}): Any extra arguments to the bpy.props.SomeProperty() call used to create this property.. [optional] # noqa: E501 propargs ({str: (bool, date, datetime, dict, float, int, list, str, none_type)}): Any extra arguments to the bpy.props.SomeProperty() call used to create this property.. [optional] # noqa: E501
description (bool, date, datetime, dict, float, int, list, str, none_type): The description/tooltip shown in the user interface.. [optional] # noqa: E501 description (bool, date, datetime, dict, float, int, list, str, none_type): The description/tooltip shown in the user interface.. [optional] # noqa: E501
label (bool, date, datetime, dict, float, int, list, str, none_type): Label for displaying this setting. If not specified, the key is used to generate a reasonable label.. [optional] # noqa: E501
default (bool, date, datetime, dict, float, int, list, str, none_type): The default value shown to the user when determining this setting.. [optional] # noqa: E501 default (bool, date, datetime, dict, float, int, list, str, none_type): The default value shown to the user when determining this setting.. [optional] # noqa: E501
eval (str): Python expression to be evaluated in order to determine the default value for this setting.. [optional] # noqa: E501 eval (str): Python expression to be evaluated in order to determine the default value for this setting.. [optional] # noqa: E501
eval_info (AvailableJobSettingEvalInfo): [optional] # noqa: E501 eval_info (AvailableJobSettingEvalInfo): [optional] # noqa: E501
@ -273,6 +276,7 @@ class AvailableJobSetting(ModelNormal):
choices ([str]): When given, limit the valid values to these choices. Only usable with string type.. [optional] # noqa: E501 choices ([str]): When given, limit the valid values to these choices. Only usable with string type.. [optional] # noqa: E501
propargs ({str: (bool, date, datetime, dict, float, int, list, str, none_type)}): Any extra arguments to the bpy.props.SomeProperty() call used to create this property.. [optional] # noqa: E501 propargs ({str: (bool, date, datetime, dict, float, int, list, str, none_type)}): Any extra arguments to the bpy.props.SomeProperty() call used to create this property.. [optional] # noqa: E501
description (bool, date, datetime, dict, float, int, list, str, none_type): The description/tooltip shown in the user interface.. [optional] # noqa: E501 description (bool, date, datetime, dict, float, int, list, str, none_type): The description/tooltip shown in the user interface.. [optional] # noqa: E501
label (bool, date, datetime, dict, float, int, list, str, none_type): Label for displaying this setting. If not specified, the key is used to generate a reasonable label.. [optional] # noqa: E501
default (bool, date, datetime, dict, float, int, list, str, none_type): The default value shown to the user when determining this setting.. [optional] # noqa: E501 default (bool, date, datetime, dict, float, int, list, str, none_type): The default value shown to the user when determining this setting.. [optional] # noqa: E501
eval (str): Python expression to be evaluated in order to determine the default value for this setting.. [optional] # noqa: E501 eval (str): Python expression to be evaluated in order to determine the default value for this setting.. [optional] # noqa: E501
eval_info (AvailableJobSettingEvalInfo): [optional] # noqa: E501 eval_info (AvailableJobSettingEvalInfo): [optional] # noqa: E501

View File

@ -76,152 +76,152 @@ All URIs are relative to *http://localhost*
Class | Method | HTTP request | Description Class | Method | HTTP request | Description
------------ | ------------- | ------------- | ------------- ------------ | ------------- | ------------- | -------------
*JobsApi* | [**delete_job**](flamenco\manager\docs/JobsApi.md#delete_job) | **DELETE** /api/v3/jobs/{job_id} | Request deletion this job, including its tasks and any log files. The actual deletion may happen in the background. No job files will be deleted (yet). *JobsApi* | [**delete_job**](flamenco/manager/docs/JobsApi.md#delete_job) | **DELETE** /api/v3/jobs/{job_id} | Request deletion this job, including its tasks and any log files. The actual deletion may happen in the background. No job files will be deleted (yet).
*JobsApi* | [**delete_job_mass**](flamenco\manager\docs/JobsApi.md#delete_job_mass) | **DELETE** /api/v3/jobs/mass-delete | Mark jobs for deletion, based on certain criteria. *JobsApi* | [**delete_job_mass**](flamenco/manager/docs/JobsApi.md#delete_job_mass) | **DELETE** /api/v3/jobs/mass-delete | Mark jobs for deletion, based on certain criteria.
*JobsApi* | [**delete_job_what_would_it_do**](flamenco\manager\docs/JobsApi.md#delete_job_what_would_it_do) | **GET** /api/v3/jobs/{job_id}/what-would-delete-do | Get info about what would be deleted when deleting this job. The job itself, its logs, and the last-rendered images will always be deleted. The job files are only deleted conditionally, and this operation can be used to figure that out. *JobsApi* | [**delete_job_what_would_it_do**](flamenco/manager/docs/JobsApi.md#delete_job_what_would_it_do) | **GET** /api/v3/jobs/{job_id}/what-would-delete-do | Get info about what would be deleted when deleting this job. The job itself, its logs, and the last-rendered images will always be deleted. The job files are only deleted conditionally, and this operation can be used to figure that out.
*JobsApi* | [**fetch_global_last_rendered_info**](flamenco\manager\docs/JobsApi.md#fetch_global_last_rendered_info) | **GET** /api/v3/jobs/last-rendered | Get the URL that serves the last-rendered images. *JobsApi* | [**fetch_global_last_rendered_info**](flamenco/manager/docs/JobsApi.md#fetch_global_last_rendered_info) | **GET** /api/v3/jobs/last-rendered | Get the URL that serves the last-rendered images.
*JobsApi* | [**fetch_job**](flamenco\manager\docs/JobsApi.md#fetch_job) | **GET** /api/v3/jobs/{job_id} | Fetch info about the job. *JobsApi* | [**fetch_job**](flamenco/manager/docs/JobsApi.md#fetch_job) | **GET** /api/v3/jobs/{job_id} | Fetch info about the job.
*JobsApi* | [**fetch_job_blocklist**](flamenco\manager\docs/JobsApi.md#fetch_job_blocklist) | **GET** /api/v3/jobs/{job_id}/blocklist | Fetch the list of workers that are blocked from doing certain task types on this job. *JobsApi* | [**fetch_job_blocklist**](flamenco/manager/docs/JobsApi.md#fetch_job_blocklist) | **GET** /api/v3/jobs/{job_id}/blocklist | Fetch the list of workers that are blocked from doing certain task types on this job.
*JobsApi* | [**fetch_job_last_rendered_info**](flamenco\manager\docs/JobsApi.md#fetch_job_last_rendered_info) | **GET** /api/v3/jobs/{job_id}/last-rendered | Get the URL that serves the last-rendered images of this job. *JobsApi* | [**fetch_job_last_rendered_info**](flamenco/manager/docs/JobsApi.md#fetch_job_last_rendered_info) | **GET** /api/v3/jobs/{job_id}/last-rendered | Get the URL that serves the last-rendered images of this job.
*JobsApi* | [**fetch_job_tasks**](flamenco\manager\docs/JobsApi.md#fetch_job_tasks) | **GET** /api/v3/jobs/{job_id}/tasks | Fetch a summary of all tasks of the given job. *JobsApi* | [**fetch_job_tasks**](flamenco/manager/docs/JobsApi.md#fetch_job_tasks) | **GET** /api/v3/jobs/{job_id}/tasks | Fetch a summary of all tasks of the given job.
*JobsApi* | [**fetch_task**](flamenco\manager\docs/JobsApi.md#fetch_task) | **GET** /api/v3/tasks/{task_id} | Fetch a single task. *JobsApi* | [**fetch_task**](flamenco/manager/docs/JobsApi.md#fetch_task) | **GET** /api/v3/tasks/{task_id} | Fetch a single task.
*JobsApi* | [**fetch_task_log_info**](flamenco\manager\docs/JobsApi.md#fetch_task_log_info) | **GET** /api/v3/tasks/{task_id}/log | Get the URL of the task log, and some more info. *JobsApi* | [**fetch_task_log_info**](flamenco/manager/docs/JobsApi.md#fetch_task_log_info) | **GET** /api/v3/tasks/{task_id}/log | Get the URL of the task log, and some more info.
*JobsApi* | [**fetch_task_log_tail**](flamenco\manager\docs/JobsApi.md#fetch_task_log_tail) | **GET** /api/v3/tasks/{task_id}/logtail | Fetch the last few lines of the task's log. *JobsApi* | [**fetch_task_log_tail**](flamenco/manager/docs/JobsApi.md#fetch_task_log_tail) | **GET** /api/v3/tasks/{task_id}/logtail | Fetch the last few lines of the task's log.
*JobsApi* | [**get_job_type**](flamenco\manager\docs/JobsApi.md#get_job_type) | **GET** /api/v3/jobs/type/{typeName} | Get single job type and its parameters. *JobsApi* | [**get_job_type**](flamenco/manager/docs/JobsApi.md#get_job_type) | **GET** /api/v3/jobs/type/{typeName} | Get single job type and its parameters.
*JobsApi* | [**get_job_types**](flamenco\manager\docs/JobsApi.md#get_job_types) | **GET** /api/v3/jobs/types | Get list of job types and their parameters. *JobsApi* | [**get_job_types**](flamenco/manager/docs/JobsApi.md#get_job_types) | **GET** /api/v3/jobs/types | Get list of job types and their parameters.
*JobsApi* | [**query_jobs**](flamenco\manager\docs/JobsApi.md#query_jobs) | **POST** /api/v3/jobs/query | Fetch list of jobs. *JobsApi* | [**query_jobs**](flamenco/manager/docs/JobsApi.md#query_jobs) | **POST** /api/v3/jobs/query | Fetch list of jobs.
*JobsApi* | [**remove_job_blocklist**](flamenco\manager\docs/JobsApi.md#remove_job_blocklist) | **DELETE** /api/v3/jobs/{job_id}/blocklist | Remove entries from a job blocklist. *JobsApi* | [**remove_job_blocklist**](flamenco/manager/docs/JobsApi.md#remove_job_blocklist) | **DELETE** /api/v3/jobs/{job_id}/blocklist | Remove entries from a job blocklist.
*JobsApi* | [**set_job_priority**](flamenco\manager\docs/JobsApi.md#set_job_priority) | **POST** /api/v3/jobs/{job_id}/setpriority | *JobsApi* | [**set_job_priority**](flamenco/manager/docs/JobsApi.md#set_job_priority) | **POST** /api/v3/jobs/{job_id}/setpriority |
*JobsApi* | [**set_job_status**](flamenco\manager\docs/JobsApi.md#set_job_status) | **POST** /api/v3/jobs/{job_id}/setstatus | *JobsApi* | [**set_job_status**](flamenco/manager/docs/JobsApi.md#set_job_status) | **POST** /api/v3/jobs/{job_id}/setstatus |
*JobsApi* | [**set_task_status**](flamenco\manager\docs/JobsApi.md#set_task_status) | **POST** /api/v3/tasks/{task_id}/setstatus | *JobsApi* | [**set_task_status**](flamenco/manager/docs/JobsApi.md#set_task_status) | **POST** /api/v3/tasks/{task_id}/setstatus |
*JobsApi* | [**submit_job**](flamenco\manager\docs/JobsApi.md#submit_job) | **POST** /api/v3/jobs | Submit a new job for Flamenco Manager to execute. *JobsApi* | [**submit_job**](flamenco/manager/docs/JobsApi.md#submit_job) | **POST** /api/v3/jobs | Submit a new job for Flamenco Manager to execute.
*JobsApi* | [**submit_job_check**](flamenco\manager\docs/JobsApi.md#submit_job_check) | **POST** /api/v3/jobs/check | Submit a new job for Flamenco Manager to check. *JobsApi* | [**submit_job_check**](flamenco/manager/docs/JobsApi.md#submit_job_check) | **POST** /api/v3/jobs/check | Submit a new job for Flamenco Manager to check.
*MetaApi* | [**check_blender_exe_path**](flamenco\manager\docs/MetaApi.md#check_blender_exe_path) | **POST** /api/v3/configuration/check/blender | Validate a CLI command for use as way to start Blender *MetaApi* | [**check_blender_exe_path**](flamenco/manager/docs/MetaApi.md#check_blender_exe_path) | **POST** /api/v3/configuration/check/blender | Validate a CLI command for use as way to start Blender
*MetaApi* | [**check_shared_storage_path**](flamenco\manager\docs/MetaApi.md#check_shared_storage_path) | **POST** /api/v3/configuration/check/shared-storage | Validate a path for use as shared storage. *MetaApi* | [**check_shared_storage_path**](flamenco/manager/docs/MetaApi.md#check_shared_storage_path) | **POST** /api/v3/configuration/check/shared-storage | Validate a path for use as shared storage.
*MetaApi* | [**find_blender_exe_path**](flamenco\manager\docs/MetaApi.md#find_blender_exe_path) | **GET** /api/v3/configuration/check/blender | Find one or more CLI commands for use as way to start Blender *MetaApi* | [**find_blender_exe_path**](flamenco/manager/docs/MetaApi.md#find_blender_exe_path) | **GET** /api/v3/configuration/check/blender | Find one or more CLI commands for use as way to start Blender
*MetaApi* | [**get_configuration**](flamenco\manager\docs/MetaApi.md#get_configuration) | **GET** /api/v3/configuration | Get the configuration of this Manager. *MetaApi* | [**get_configuration**](flamenco/manager/docs/MetaApi.md#get_configuration) | **GET** /api/v3/configuration | Get the configuration of this Manager.
*MetaApi* | [**get_configuration_file**](flamenco\manager\docs/MetaApi.md#get_configuration_file) | **GET** /api/v3/configuration/file | Retrieve the configuration of Flamenco Manager. *MetaApi* | [**get_configuration_file**](flamenco/manager/docs/MetaApi.md#get_configuration_file) | **GET** /api/v3/configuration/file | Retrieve the configuration of Flamenco Manager.
*MetaApi* | [**get_farm_status**](flamenco\manager\docs/MetaApi.md#get_farm_status) | **GET** /api/v3/status | Get the status of this Flamenco farm. *MetaApi* | [**get_farm_status**](flamenco/manager/docs/MetaApi.md#get_farm_status) | **GET** /api/v3/status | Get the status of this Flamenco farm.
*MetaApi* | [**get_shared_storage**](flamenco\manager\docs/MetaApi.md#get_shared_storage) | **GET** /api/v3/configuration/shared-storage/{audience}/{platform} | Get the shared storage location of this Manager, adjusted for the given audience and platform. *MetaApi* | [**get_shared_storage**](flamenco/manager/docs/MetaApi.md#get_shared_storage) | **GET** /api/v3/configuration/shared-storage/{audience}/{platform} | Get the shared storage location of this Manager, adjusted for the given audience and platform.
*MetaApi* | [**get_variables**](flamenco\manager\docs/MetaApi.md#get_variables) | **GET** /api/v3/configuration/variables/{audience}/{platform} | Get the variables of this Manager. Used by the Blender add-on to recognise two-way variables, and for the web interface to do variable replacement based on the browser's platform. *MetaApi* | [**get_variables**](flamenco/manager/docs/MetaApi.md#get_variables) | **GET** /api/v3/configuration/variables/{audience}/{platform} | Get the variables of this Manager. Used by the Blender add-on to recognise two-way variables, and for the web interface to do variable replacement based on the browser's platform.
*MetaApi* | [**get_version**](flamenco\manager\docs/MetaApi.md#get_version) | **GET** /api/v3/version | Get the Flamenco version of this Manager *MetaApi* | [**get_version**](flamenco/manager/docs/MetaApi.md#get_version) | **GET** /api/v3/version | Get the Flamenco version of this Manager
*MetaApi* | [**save_setup_assistant_config**](flamenco\manager\docs/MetaApi.md#save_setup_assistant_config) | **POST** /api/v3/configuration/setup-assistant | Update the Manager's configuration, and restart it in fully functional mode. *MetaApi* | [**save_setup_assistant_config**](flamenco/manager/docs/MetaApi.md#save_setup_assistant_config) | **POST** /api/v3/configuration/setup-assistant | Update the Manager's configuration, and restart it in fully functional mode.
*ShamanApi* | [**shaman_checkout**](flamenco\manager\docs/ShamanApi.md#shaman_checkout) | **POST** /api/v3/shaman/checkout/create | Create a directory, and symlink the required files into it. The files must all have been uploaded to Shaman before calling this endpoint. *ShamanApi* | [**shaman_checkout**](flamenco/manager/docs/ShamanApi.md#shaman_checkout) | **POST** /api/v3/shaman/checkout/create | Create a directory, and symlink the required files into it. The files must all have been uploaded to Shaman before calling this endpoint.
*ShamanApi* | [**shaman_checkout_requirements**](flamenco\manager\docs/ShamanApi.md#shaman_checkout_requirements) | **POST** /api/v3/shaman/checkout/requirements | Checks a Shaman Requirements file, and reports which files are unknown. *ShamanApi* | [**shaman_checkout_requirements**](flamenco/manager/docs/ShamanApi.md#shaman_checkout_requirements) | **POST** /api/v3/shaman/checkout/requirements | Checks a Shaman Requirements file, and reports which files are unknown.
*ShamanApi* | [**shaman_file_store**](flamenco\manager\docs/ShamanApi.md#shaman_file_store) | **POST** /api/v3/shaman/files/{checksum}/{filesize} | Store a new file on the Shaman server. Note that the Shaman server can forcibly close the HTTP connection when another client finishes uploading the exact same file, to prevent double uploads. The file's contents should be sent in the request body. *ShamanApi* | [**shaman_file_store**](flamenco/manager/docs/ShamanApi.md#shaman_file_store) | **POST** /api/v3/shaman/files/{checksum}/{filesize} | Store a new file on the Shaman server. Note that the Shaman server can forcibly close the HTTP connection when another client finishes uploading the exact same file, to prevent double uploads. The file's contents should be sent in the request body.
*ShamanApi* | [**shaman_file_store_check**](flamenco\manager\docs/ShamanApi.md#shaman_file_store_check) | **GET** /api/v3/shaman/files/{checksum}/{filesize} | Check the status of a file on the Shaman server. *ShamanApi* | [**shaman_file_store_check**](flamenco/manager/docs/ShamanApi.md#shaman_file_store_check) | **GET** /api/v3/shaman/files/{checksum}/{filesize} | Check the status of a file on the Shaman server.
*WorkerApi* | [**may_worker_run**](flamenco\manager\docs/WorkerApi.md#may_worker_run) | **GET** /api/v3/worker/task/{task_id}/may-i-run | The response indicates whether the worker is allowed to run / keep running the task. Optionally contains a queued worker status change. *WorkerApi* | [**may_worker_run**](flamenco/manager/docs/WorkerApi.md#may_worker_run) | **GET** /api/v3/worker/task/{task_id}/may-i-run | The response indicates whether the worker is allowed to run / keep running the task. Optionally contains a queued worker status change.
*WorkerApi* | [**register_worker**](flamenco\manager\docs/WorkerApi.md#register_worker) | **POST** /api/v3/worker/register-worker | Register a new worker *WorkerApi* | [**register_worker**](flamenco/manager/docs/WorkerApi.md#register_worker) | **POST** /api/v3/worker/register-worker | Register a new worker
*WorkerApi* | [**schedule_task**](flamenco\manager\docs/WorkerApi.md#schedule_task) | **POST** /api/v3/worker/task | Obtain a new task to execute *WorkerApi* | [**schedule_task**](flamenco/manager/docs/WorkerApi.md#schedule_task) | **POST** /api/v3/worker/task | Obtain a new task to execute
*WorkerApi* | [**sign_off**](flamenco\manager\docs/WorkerApi.md#sign_off) | **POST** /api/v3/worker/sign-off | Mark the worker as offline *WorkerApi* | [**sign_off**](flamenco/manager/docs/WorkerApi.md#sign_off) | **POST** /api/v3/worker/sign-off | Mark the worker as offline
*WorkerApi* | [**sign_on**](flamenco\manager\docs/WorkerApi.md#sign_on) | **POST** /api/v3/worker/sign-on | Authenticate & sign in the worker. *WorkerApi* | [**sign_on**](flamenco/manager/docs/WorkerApi.md#sign_on) | **POST** /api/v3/worker/sign-on | Authenticate & sign in the worker.
*WorkerApi* | [**task_output_produced**](flamenco\manager\docs/WorkerApi.md#task_output_produced) | **POST** /api/v3/worker/task/{task_id}/output-produced | Store the most recently rendered frame here. Note that it is up to the Worker to ensure this is in a format that's digestable by the Manager. Currently only PNG and JPEG support is planned. *WorkerApi* | [**task_output_produced**](flamenco/manager/docs/WorkerApi.md#task_output_produced) | **POST** /api/v3/worker/task/{task_id}/output-produced | Store the most recently rendered frame here. Note that it is up to the Worker to ensure this is in a format that's digestable by the Manager. Currently only PNG and JPEG support is planned.
*WorkerApi* | [**task_update**](flamenco\manager\docs/WorkerApi.md#task_update) | **POST** /api/v3/worker/task/{task_id} | Update the task, typically to indicate progress, completion, or failure. *WorkerApi* | [**task_update**](flamenco/manager/docs/WorkerApi.md#task_update) | **POST** /api/v3/worker/task/{task_id} | Update the task, typically to indicate progress, completion, or failure.
*WorkerApi* | [**worker_state**](flamenco\manager\docs/WorkerApi.md#worker_state) | **GET** /api/v3/worker/state | *WorkerApi* | [**worker_state**](flamenco/manager/docs/WorkerApi.md#worker_state) | **GET** /api/v3/worker/state |
*WorkerApi* | [**worker_state_changed**](flamenco\manager\docs/WorkerApi.md#worker_state_changed) | **POST** /api/v3/worker/state-changed | Worker changed state. This could be as acknowledgement of a Manager-requested state change, or in response to worker-local signals. *WorkerApi* | [**worker_state_changed**](flamenco/manager/docs/WorkerApi.md#worker_state_changed) | **POST** /api/v3/worker/state-changed | Worker changed state. This could be as acknowledgement of a Manager-requested state change, or in response to worker-local signals.
*WorkerMgtApi* | [**create_worker_tag**](flamenco\manager\docs/WorkerMgtApi.md#create_worker_tag) | **POST** /api/v3/worker-mgt/tags | Create a new worker tag. *WorkerMgtApi* | [**create_worker_tag**](flamenco/manager/docs/WorkerMgtApi.md#create_worker_tag) | **POST** /api/v3/worker-mgt/tags | Create a new worker tag.
*WorkerMgtApi* | [**delete_worker**](flamenco\manager\docs/WorkerMgtApi.md#delete_worker) | **DELETE** /api/v3/worker-mgt/workers/{worker_id} | Remove the given worker. It is recommended to only call this function when the worker is in `offline` state. If the worker is still running, stop it first. Any task still assigned to the worker will be requeued. *WorkerMgtApi* | [**delete_worker**](flamenco/manager/docs/WorkerMgtApi.md#delete_worker) | **DELETE** /api/v3/worker-mgt/workers/{worker_id} | Remove the given worker. It is recommended to only call this function when the worker is in `offline` state. If the worker is still running, stop it first. Any task still assigned to the worker will be requeued.
*WorkerMgtApi* | [**delete_worker_tag**](flamenco\manager\docs/WorkerMgtApi.md#delete_worker_tag) | **DELETE** /api/v3/worker-mgt/tag/{tag_id} | Remove this worker tag. This unassigns all workers from the tag and removes it. *WorkerMgtApi* | [**delete_worker_tag**](flamenco/manager/docs/WorkerMgtApi.md#delete_worker_tag) | **DELETE** /api/v3/worker-mgt/tag/{tag_id} | Remove this worker tag. This unassigns all workers from the tag and removes it.
*WorkerMgtApi* | [**fetch_worker**](flamenco\manager\docs/WorkerMgtApi.md#fetch_worker) | **GET** /api/v3/worker-mgt/workers/{worker_id} | Fetch info about the worker. *WorkerMgtApi* | [**fetch_worker**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker) | **GET** /api/v3/worker-mgt/workers/{worker_id} | Fetch info about the worker.
*WorkerMgtApi* | [**fetch_worker_sleep_schedule**](flamenco\manager\docs/WorkerMgtApi.md#fetch_worker_sleep_schedule) | **GET** /api/v3/worker-mgt/workers/{worker_id}/sleep-schedule | *WorkerMgtApi* | [**fetch_worker_sleep_schedule**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker_sleep_schedule) | **GET** /api/v3/worker-mgt/workers/{worker_id}/sleep-schedule |
*WorkerMgtApi* | [**fetch_worker_tag**](flamenco\manager\docs/WorkerMgtApi.md#fetch_worker_tag) | **GET** /api/v3/worker-mgt/tag/{tag_id} | Get a single worker tag. *WorkerMgtApi* | [**fetch_worker_tag**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker_tag) | **GET** /api/v3/worker-mgt/tag/{tag_id} | Get a single worker tag.
*WorkerMgtApi* | [**fetch_worker_tags**](flamenco\manager\docs/WorkerMgtApi.md#fetch_worker_tags) | **GET** /api/v3/worker-mgt/tags | Get list of worker tags. *WorkerMgtApi* | [**fetch_worker_tags**](flamenco/manager/docs/WorkerMgtApi.md#fetch_worker_tags) | **GET** /api/v3/worker-mgt/tags | Get list of worker tags.
*WorkerMgtApi* | [**fetch_workers**](flamenco\manager\docs/WorkerMgtApi.md#fetch_workers) | **GET** /api/v3/worker-mgt/workers | Get list of workers. *WorkerMgtApi* | [**fetch_workers**](flamenco/manager/docs/WorkerMgtApi.md#fetch_workers) | **GET** /api/v3/worker-mgt/workers | Get list of workers.
*WorkerMgtApi* | [**request_worker_status_change**](flamenco\manager\docs/WorkerMgtApi.md#request_worker_status_change) | **POST** /api/v3/worker-mgt/workers/{worker_id}/setstatus | *WorkerMgtApi* | [**request_worker_status_change**](flamenco/manager/docs/WorkerMgtApi.md#request_worker_status_change) | **POST** /api/v3/worker-mgt/workers/{worker_id}/setstatus |
*WorkerMgtApi* | [**set_worker_sleep_schedule**](flamenco\manager\docs/WorkerMgtApi.md#set_worker_sleep_schedule) | **POST** /api/v3/worker-mgt/workers/{worker_id}/sleep-schedule | *WorkerMgtApi* | [**set_worker_sleep_schedule**](flamenco/manager/docs/WorkerMgtApi.md#set_worker_sleep_schedule) | **POST** /api/v3/worker-mgt/workers/{worker_id}/sleep-schedule |
*WorkerMgtApi* | [**set_worker_tags**](flamenco\manager\docs/WorkerMgtApi.md#set_worker_tags) | **POST** /api/v3/worker-mgt/workers/{worker_id}/settags | *WorkerMgtApi* | [**set_worker_tags**](flamenco/manager/docs/WorkerMgtApi.md#set_worker_tags) | **POST** /api/v3/worker-mgt/workers/{worker_id}/settags |
*WorkerMgtApi* | [**update_worker_tag**](flamenco\manager\docs/WorkerMgtApi.md#update_worker_tag) | **PUT** /api/v3/worker-mgt/tag/{tag_id} | Update an existing worker tag. *WorkerMgtApi* | [**update_worker_tag**](flamenco/manager/docs/WorkerMgtApi.md#update_worker_tag) | **PUT** /api/v3/worker-mgt/tag/{tag_id} | Update an existing worker tag.
## Documentation For Models ## Documentation For Models
- [AssignedTask](flamenco\manager\docs/AssignedTask.md) - [AssignedTask](flamenco/manager/docs/AssignedTask.md)
- [AvailableJobSetting](flamenco\manager\docs/AvailableJobSetting.md) - [AvailableJobSetting](flamenco/manager/docs/AvailableJobSetting.md)
- [AvailableJobSettingEvalInfo](flamenco\manager\docs/AvailableJobSettingEvalInfo.md) - [AvailableJobSettingEvalInfo](flamenco/manager/docs/AvailableJobSettingEvalInfo.md)
- [AvailableJobSettingSubtype](flamenco\manager\docs/AvailableJobSettingSubtype.md) - [AvailableJobSettingSubtype](flamenco/manager/docs/AvailableJobSettingSubtype.md)
- [AvailableJobSettingType](flamenco\manager\docs/AvailableJobSettingType.md) - [AvailableJobSettingType](flamenco/manager/docs/AvailableJobSettingType.md)
- [AvailableJobSettingVisibility](flamenco\manager\docs/AvailableJobSettingVisibility.md) - [AvailableJobSettingVisibility](flamenco/manager/docs/AvailableJobSettingVisibility.md)
- [AvailableJobType](flamenco\manager\docs/AvailableJobType.md) - [AvailableJobType](flamenco/manager/docs/AvailableJobType.md)
- [AvailableJobTypes](flamenco\manager\docs/AvailableJobTypes.md) - [AvailableJobTypes](flamenco/manager/docs/AvailableJobTypes.md)
- [BlenderPathCheckResult](flamenco\manager\docs/BlenderPathCheckResult.md) - [BlenderPathCheckResult](flamenco/manager/docs/BlenderPathCheckResult.md)
- [BlenderPathFindResult](flamenco\manager\docs/BlenderPathFindResult.md) - [BlenderPathFindResult](flamenco/manager/docs/BlenderPathFindResult.md)
- [BlenderPathSource](flamenco\manager\docs/BlenderPathSource.md) - [BlenderPathSource](flamenco/manager/docs/BlenderPathSource.md)
- [Command](flamenco\manager\docs/Command.md) - [Command](flamenco/manager/docs/Command.md)
- [Error](flamenco\manager\docs/Error.md) - [Error](flamenco/manager/docs/Error.md)
- [EventFarmStatus](flamenco\manager\docs/EventFarmStatus.md) - [EventFarmStatus](flamenco/manager/docs/EventFarmStatus.md)
- [EventJobUpdate](flamenco\manager\docs/EventJobUpdate.md) - [EventJobUpdate](flamenco/manager/docs/EventJobUpdate.md)
- [EventLastRenderedUpdate](flamenco\manager\docs/EventLastRenderedUpdate.md) - [EventLastRenderedUpdate](flamenco/manager/docs/EventLastRenderedUpdate.md)
- [EventLifeCycle](flamenco\manager\docs/EventLifeCycle.md) - [EventLifeCycle](flamenco/manager/docs/EventLifeCycle.md)
- [EventTaskLogUpdate](flamenco\manager\docs/EventTaskLogUpdate.md) - [EventTaskLogUpdate](flamenco/manager/docs/EventTaskLogUpdate.md)
- [EventTaskUpdate](flamenco\manager\docs/EventTaskUpdate.md) - [EventTaskUpdate](flamenco/manager/docs/EventTaskUpdate.md)
- [EventWorkerTagUpdate](flamenco\manager\docs/EventWorkerTagUpdate.md) - [EventWorkerTagUpdate](flamenco/manager/docs/EventWorkerTagUpdate.md)
- [EventWorkerUpdate](flamenco\manager\docs/EventWorkerUpdate.md) - [EventWorkerUpdate](flamenco/manager/docs/EventWorkerUpdate.md)
- [FarmStatus](flamenco\manager\docs/FarmStatus.md) - [FarmStatus](flamenco/manager/docs/FarmStatus.md)
- [FarmStatusReport](flamenco\manager\docs/FarmStatusReport.md) - [FarmStatusReport](flamenco/manager/docs/FarmStatusReport.md)
- [FlamencoVersion](flamenco\manager\docs/FlamencoVersion.md) - [FlamencoVersion](flamenco/manager/docs/FlamencoVersion.md)
- [Job](flamenco\manager\docs/Job.md) - [Job](flamenco/manager/docs/Job.md)
- [JobAllOf](flamenco\manager\docs/JobAllOf.md) - [JobAllOf](flamenco/manager/docs/JobAllOf.md)
- [JobBlocklist](flamenco\manager\docs/JobBlocklist.md) - [JobBlocklist](flamenco/manager/docs/JobBlocklist.md)
- [JobBlocklistEntry](flamenco\manager\docs/JobBlocklistEntry.md) - [JobBlocklistEntry](flamenco/manager/docs/JobBlocklistEntry.md)
- [JobDeletionInfo](flamenco\manager\docs/JobDeletionInfo.md) - [JobDeletionInfo](flamenco/manager/docs/JobDeletionInfo.md)
- [JobLastRenderedImageInfo](flamenco\manager\docs/JobLastRenderedImageInfo.md) - [JobLastRenderedImageInfo](flamenco/manager/docs/JobLastRenderedImageInfo.md)
- [JobMassDeletionSelection](flamenco\manager\docs/JobMassDeletionSelection.md) - [JobMassDeletionSelection](flamenco/manager/docs/JobMassDeletionSelection.md)
- [JobMetadata](flamenco\manager\docs/JobMetadata.md) - [JobMetadata](flamenco/manager/docs/JobMetadata.md)
- [JobPriorityChange](flamenco\manager\docs/JobPriorityChange.md) - [JobPriorityChange](flamenco/manager/docs/JobPriorityChange.md)
- [JobSettings](flamenco\manager\docs/JobSettings.md) - [JobSettings](flamenco/manager/docs/JobSettings.md)
- [JobStatus](flamenco\manager\docs/JobStatus.md) - [JobStatus](flamenco/manager/docs/JobStatus.md)
- [JobStatusChange](flamenco\manager\docs/JobStatusChange.md) - [JobStatusChange](flamenco/manager/docs/JobStatusChange.md)
- [JobStorageInfo](flamenco\manager\docs/JobStorageInfo.md) - [JobStorageInfo](flamenco/manager/docs/JobStorageInfo.md)
- [JobTasksSummary](flamenco\manager\docs/JobTasksSummary.md) - [JobTasksSummary](flamenco/manager/docs/JobTasksSummary.md)
- [JobsQuery](flamenco\manager\docs/JobsQuery.md) - [JobsQuery](flamenco/manager/docs/JobsQuery.md)
- [JobsQueryResult](flamenco\manager\docs/JobsQueryResult.md) - [JobsQueryResult](flamenco/manager/docs/JobsQueryResult.md)
- [LifeCycleEventType](flamenco\manager\docs/LifeCycleEventType.md) - [LifeCycleEventType](flamenco/manager/docs/LifeCycleEventType.md)
- [ManagerConfiguration](flamenco\manager\docs/ManagerConfiguration.md) - [ManagerConfiguration](flamenco/manager/docs/ManagerConfiguration.md)
- [ManagerVariable](flamenco\manager\docs/ManagerVariable.md) - [ManagerVariable](flamenco/manager/docs/ManagerVariable.md)
- [ManagerVariableAudience](flamenco\manager\docs/ManagerVariableAudience.md) - [ManagerVariableAudience](flamenco/manager/docs/ManagerVariableAudience.md)
- [ManagerVariables](flamenco\manager\docs/ManagerVariables.md) - [ManagerVariables](flamenco/manager/docs/ManagerVariables.md)
- [MayKeepRunning](flamenco\manager\docs/MayKeepRunning.md) - [MayKeepRunning](flamenco/manager/docs/MayKeepRunning.md)
- [PathCheckInput](flamenco\manager\docs/PathCheckInput.md) - [PathCheckInput](flamenco/manager/docs/PathCheckInput.md)
- [PathCheckResult](flamenco\manager\docs/PathCheckResult.md) - [PathCheckResult](flamenco/manager/docs/PathCheckResult.md)
- [RegisteredWorker](flamenco\manager\docs/RegisteredWorker.md) - [RegisteredWorker](flamenco/manager/docs/RegisteredWorker.md)
- [SecurityError](flamenco\manager\docs/SecurityError.md) - [SecurityError](flamenco/manager/docs/SecurityError.md)
- [SetupAssistantConfig](flamenco\manager\docs/SetupAssistantConfig.md) - [SetupAssistantConfig](flamenco/manager/docs/SetupAssistantConfig.md)
- [ShamanCheckout](flamenco\manager\docs/ShamanCheckout.md) - [ShamanCheckout](flamenco/manager/docs/ShamanCheckout.md)
- [ShamanCheckoutResult](flamenco\manager\docs/ShamanCheckoutResult.md) - [ShamanCheckoutResult](flamenco/manager/docs/ShamanCheckoutResult.md)
- [ShamanFileSpec](flamenco\manager\docs/ShamanFileSpec.md) - [ShamanFileSpec](flamenco/manager/docs/ShamanFileSpec.md)
- [ShamanFileSpecWithStatus](flamenco\manager\docs/ShamanFileSpecWithStatus.md) - [ShamanFileSpecWithStatus](flamenco/manager/docs/ShamanFileSpecWithStatus.md)
- [ShamanFileStatus](flamenco\manager\docs/ShamanFileStatus.md) - [ShamanFileStatus](flamenco/manager/docs/ShamanFileStatus.md)
- [ShamanRequirementsRequest](flamenco\manager\docs/ShamanRequirementsRequest.md) - [ShamanRequirementsRequest](flamenco/manager/docs/ShamanRequirementsRequest.md)
- [ShamanRequirementsResponse](flamenco\manager\docs/ShamanRequirementsResponse.md) - [ShamanRequirementsResponse](flamenco/manager/docs/ShamanRequirementsResponse.md)
- [ShamanSingleFileStatus](flamenco\manager\docs/ShamanSingleFileStatus.md) - [ShamanSingleFileStatus](flamenco/manager/docs/ShamanSingleFileStatus.md)
- [SharedStorageLocation](flamenco\manager\docs/SharedStorageLocation.md) - [SharedStorageLocation](flamenco/manager/docs/SharedStorageLocation.md)
- [SocketIOSubscription](flamenco\manager\docs/SocketIOSubscription.md) - [SocketIOSubscription](flamenco/manager/docs/SocketIOSubscription.md)
- [SocketIOSubscriptionOperation](flamenco\manager\docs/SocketIOSubscriptionOperation.md) - [SocketIOSubscriptionOperation](flamenco/manager/docs/SocketIOSubscriptionOperation.md)
- [SocketIOSubscriptionType](flamenco\manager\docs/SocketIOSubscriptionType.md) - [SocketIOSubscriptionType](flamenco/manager/docs/SocketIOSubscriptionType.md)
- [SubmittedJob](flamenco\manager\docs/SubmittedJob.md) - [SubmittedJob](flamenco/manager/docs/SubmittedJob.md)
- [Task](flamenco\manager\docs/Task.md) - [Task](flamenco/manager/docs/Task.md)
- [TaskLogInfo](flamenco\manager\docs/TaskLogInfo.md) - [TaskLogInfo](flamenco/manager/docs/TaskLogInfo.md)
- [TaskStatus](flamenco\manager\docs/TaskStatus.md) - [TaskStatus](flamenco/manager/docs/TaskStatus.md)
- [TaskStatusChange](flamenco\manager\docs/TaskStatusChange.md) - [TaskStatusChange](flamenco/manager/docs/TaskStatusChange.md)
- [TaskSummary](flamenco\manager\docs/TaskSummary.md) - [TaskSummary](flamenco/manager/docs/TaskSummary.md)
- [TaskUpdate](flamenco\manager\docs/TaskUpdate.md) - [TaskUpdate](flamenco/manager/docs/TaskUpdate.md)
- [TaskWorker](flamenco\manager\docs/TaskWorker.md) - [TaskWorker](flamenco/manager/docs/TaskWorker.md)
- [Worker](flamenco\manager\docs/Worker.md) - [Worker](flamenco/manager/docs/Worker.md)
- [WorkerAllOf](flamenco\manager\docs/WorkerAllOf.md) - [WorkerAllOf](flamenco/manager/docs/WorkerAllOf.md)
- [WorkerList](flamenco\manager\docs/WorkerList.md) - [WorkerList](flamenco/manager/docs/WorkerList.md)
- [WorkerRegistration](flamenco\manager\docs/WorkerRegistration.md) - [WorkerRegistration](flamenco/manager/docs/WorkerRegistration.md)
- [WorkerSignOn](flamenco\manager\docs/WorkerSignOn.md) - [WorkerSignOn](flamenco/manager/docs/WorkerSignOn.md)
- [WorkerSleepSchedule](flamenco\manager\docs/WorkerSleepSchedule.md) - [WorkerSleepSchedule](flamenco/manager/docs/WorkerSleepSchedule.md)
- [WorkerStateChange](flamenco\manager\docs/WorkerStateChange.md) - [WorkerStateChange](flamenco/manager/docs/WorkerStateChange.md)
- [WorkerStateChanged](flamenco\manager\docs/WorkerStateChanged.md) - [WorkerStateChanged](flamenco/manager/docs/WorkerStateChanged.md)
- [WorkerStatus](flamenco\manager\docs/WorkerStatus.md) - [WorkerStatus](flamenco/manager/docs/WorkerStatus.md)
- [WorkerStatusChangeRequest](flamenco\manager\docs/WorkerStatusChangeRequest.md) - [WorkerStatusChangeRequest](flamenco/manager/docs/WorkerStatusChangeRequest.md)
- [WorkerSummary](flamenco\manager\docs/WorkerSummary.md) - [WorkerSummary](flamenco/manager/docs/WorkerSummary.md)
- [WorkerTag](flamenco\manager\docs/WorkerTag.md) - [WorkerTag](flamenco/manager/docs/WorkerTag.md)
- [WorkerTagChangeRequest](flamenco\manager\docs/WorkerTagChangeRequest.md) - [WorkerTagChangeRequest](flamenco/manager/docs/WorkerTagChangeRequest.md)
- [WorkerTagList](flamenco\manager\docs/WorkerTagList.md) - [WorkerTagList](flamenco/manager/docs/WorkerTagList.md)
- [WorkerTask](flamenco\manager\docs/WorkerTask.md) - [WorkerTask](flamenco/manager/docs/WorkerTask.md)
- [WorkerTaskAllOf](flamenco\manager\docs/WorkerTaskAllOf.md) - [WorkerTaskAllOf](flamenco/manager/docs/WorkerTaskAllOf.md)
## Documentation For Authorization ## Documentation For Authorization

View File

@ -10,6 +10,7 @@ import (
"time" "time"
"github.com/dop251/goja" "github.com/dop251/goja"
"github.com/google/shlex"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
@ -33,6 +34,19 @@ func jsFormatTimestampLocal(timestamp time.Time) string {
return timestamp.Local().Format("2006-01-02_150405") return timestamp.Local().Format("2006-01-02_150405")
} }
// jsShellSplit splits a string into its parts, using CLI/shell semantics.
func jsShellSplit(vm *goja.Runtime, someCLIArgs string) []string {
split, err := shlex.Split(someCLIArgs)
if err != nil {
// Generate a JS exception by panicing with a Goja Value.
exception := vm.ToValue(err)
panic(exception)
}
return split
}
type ErrInvalidRange struct { type ErrInvalidRange struct {
Range string // The frame range that was invalid. Range string // The frame range that was invalid.
Message string // The error message Message string // The error message

View File

@ -5,10 +5,28 @@ package job_compilers
import ( import (
"testing" "testing"
"github.com/dop251/goja"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestShellSplitHappy(t *testing.T) {
expect := []string{"--python-expr", "print(1 + 1)"}
actual := jsShellSplit(nil, "--python-expr 'print(1 + 1)'")
assert.Equal(t, expect, actual)
}
func TestShellSplitFailure(t *testing.T) {
vm := goja.New()
testFunc := func() {
jsShellSplit(vm, "--python-expr invalid_quoting(1 + 1)'")
}
// Testing that a goja.Value is used for the panic is a bit tricky, so just
// test that the function panics.
assert.Panics(t, testFunc)
}
func TestFrameChunkerHappyBlenderStyle(t *testing.T) { func TestFrameChunkerHappyBlenderStyle(t *testing.T) {
chunks, err := jsFrameChunker("1..10,20..25,40,3..8", 4) chunks, err := jsFrameChunker("1..10,20..25,40,3..8", 4)
require.NoError(t, err) require.NoError(t, err)

View File

@ -140,6 +140,9 @@ func newGojaVM(registry *require.Registry) *goja.Runtime {
mustSet("alert", jsAlert) mustSet("alert", jsAlert)
mustSet("frameChunker", jsFrameChunker) mustSet("frameChunker", jsFrameChunker)
mustSet("formatTimestampLocal", jsFormatTimestampLocal) mustSet("formatTimestampLocal", jsFormatTimestampLocal)
mustSet("shellSplit", func(cliArgs string) []string {
return jsShellSplit(vm, cliArgs)
})
// Pre-import some useful modules. // Pre-import some useful modules.
registry.Enable(vm) registry.Enable(vm)

View File

@ -121,6 +121,30 @@ func TestSaveJobStorageInfo(t *testing.T) {
assert.Equal(t, startTime, updatedJob.UpdatedAt, "SaveJobStorageInfo should not touch UpdatedAt") assert.Equal(t, startTime, updatedJob.UpdatedAt, "SaveJobStorageInfo should not touch UpdatedAt")
} }
func TestSaveJobPriority(t *testing.T) {
ctx, cancel, db := persistenceTestFixtures(t, 1*time.Second)
defer cancel()
// Create test job.
authoredJob := createTestAuthoredJobWithTasks()
err := db.StoreAuthoredJob(ctx, authoredJob)
require.NoError(t, err)
// Set a new priority.
newPriority := 47
dbJob, err := db.FetchJob(ctx, authoredJob.JobID)
require.NoError(t, err)
require.NotEqual(t, newPriority, dbJob.Priority,
"Initial priority should not be the same as what this test changes it to")
dbJob.Priority = newPriority
require.NoError(t, db.SaveJobPriority(ctx, dbJob))
// Check the result.
dbJob, err = db.FetchJob(ctx, authoredJob.JobID)
require.NoError(t, err)
assert.EqualValues(t, newPriority, dbJob.Priority)
}
func TestDeleteJob(t *testing.T) { func TestDeleteJob(t *testing.T) {
ctx, cancel, db := persistenceTestFixtures(t, 1*time.Second) ctx, cancel, db := persistenceTestFixtures(t, 1*time.Second)
defer cancel() defer cancel()
@ -506,6 +530,79 @@ func TestFetchTasksOfWorkerInStatus(t *testing.T) {
assert.Empty(t, tasks, "worker should have no task in status %q", w) assert.Empty(t, tasks, "worker should have no task in status %q", w)
} }
func TestFetchTasksOfWorkerInStatusOfJob(t *testing.T) {
ctx, close, db, dbJob, authoredJob := jobTasksTestFixtures(t)
defer close()
// Create multiple Workers, to test the function doesn't return tasks from
// other Workers.
worker := createWorker(ctx, t, db, func(worker *Worker) {
worker.UUID = "43300628-5f3b-4724-ab30-9821af8bda86"
})
otherWorker := createWorker(ctx, t, db, func(worker *Worker) {
worker.UUID = "2327350f-75ec-4b0e-bd28-31a7b045c85c"
})
// Create another job, to make sure the function under test doesn't return
// tasks from other jobs.
otherJob := duplicateJobAndTasks(authoredJob)
otherJob.Name = "The other job"
persistAuthoredJob(t, ctx, db, otherJob)
// Assign a task from each job to each Worker.
// Also double-check the test precondition that all tasks have the same status.
{ // Job / Worker.
task1, err := db.FetchTask(ctx, authoredJob.Tasks[1].UUID)
require.NoError(t, err)
require.NoError(t, db.TaskAssignToWorker(ctx, task1, worker))
require.Equal(t, task1.Status, api.TaskStatusQueued)
task2, err := db.FetchTask(ctx, authoredJob.Tasks[0].UUID)
require.NoError(t, err)
require.NoError(t, db.TaskAssignToWorker(ctx, task2, worker))
require.Equal(t, task2.Status, api.TaskStatusQueued)
}
{ // Job / Other Worker.
task, err := db.FetchTask(ctx, authoredJob.Tasks[2].UUID)
require.NoError(t, err)
require.NoError(t, db.TaskAssignToWorker(ctx, task, otherWorker))
require.Equal(t, task.Status, api.TaskStatusQueued)
}
{ // Other Job / Worker.
task, err := db.FetchTask(ctx, otherJob.Tasks[1].UUID)
require.NoError(t, err)
require.NoError(t, db.TaskAssignToWorker(ctx, task, worker))
require.Equal(t, task.Status, api.TaskStatusQueued)
}
{ // Other Job / Other Worker.
task, err := db.FetchTask(ctx, otherJob.Tasks[2].UUID)
require.NoError(t, err)
require.NoError(t, db.TaskAssignToWorker(ctx, task, otherWorker))
require.Equal(t, task.Status, api.TaskStatusQueued)
}
{ // Test active tasks, should be none.
tasks, err := db.FetchTasksOfWorkerInStatusOfJob(ctx, worker, api.TaskStatusActive, dbJob)
require.NoError(t, err)
require.Len(t, tasks, 0)
}
{ // Test queued tasks, should be two.
tasks, err := db.FetchTasksOfWorkerInStatusOfJob(ctx, worker, api.TaskStatusQueued, dbJob)
require.NoError(t, err)
require.Len(t, tasks, 2)
assert.Equal(t, authoredJob.Tasks[0].UUID, tasks[0].UUID)
assert.Equal(t, authoredJob.Tasks[1].UUID, tasks[1].UUID)
}
{ // Test queued tasks for worker without tasks, should be none.
worker := createWorker(ctx, t, db, func(worker *Worker) {
worker.UUID = "6534a1d4-f58e-4f2c-8925-4b2cd6caac22"
})
tasks, err := db.FetchTasksOfWorkerInStatusOfJob(ctx, worker, api.TaskStatusQueued, dbJob)
require.NoError(t, err)
require.Len(t, tasks, 0)
}
}
func TestTaskTouchedByWorker(t *testing.T) { func TestTaskTouchedByWorker(t *testing.T) {
ctx, close, db, _, authoredJob := jobTasksTestFixtures(t) ctx, close, db, _, authoredJob := jobTasksTestFixtures(t)
defer close() defer close()

View File

@ -1751,6 +1751,8 @@ components:
type: object type: object
"description": "description":
description: The description/tooltip shown in the user interface. description: The description/tooltip shown in the user interface.
"label":
description: Label for displaying this setting. If not specified, the key is used to generate a reasonable label.
"default": "default":
description: The default value shown to the user when determining this setting. description: The default value shown to the user when determining this setting.
"eval": "eval":

View File

@ -19,233 +19,233 @@ import (
var swaggerSpec = []string{ var swaggerSpec = []string{
"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",
"Qwu3RhEBAA==", "TsdIqRwsP+BnAT5R106wEPQ9K9/Lqa8IF85hyx18+u3T/wkAAP//PbRANsURAQA=",
} }
// GetSwagger returns the content of the embedded swagger specification file // GetSwagger returns the content of the embedded swagger specification file

View File

@ -215,6 +215,9 @@ type AvailableJobSetting struct {
// Identifier for the setting, must be unique within the job type. // Identifier for the setting, must be unique within the job type.
Key string `json:"key"` Key string `json:"key"`
// Label for displaying this setting. If not specified, the key is used to generate a reasonable label.
Label *interface{} `json:"label,omitempty"`
// Any extra arguments to the bpy.props.SomeProperty() call used to create this property. // Any extra arguments to the bpy.props.SomeProperty() call used to create this property.
Propargs *map[string]interface{} `json:"propargs,omitempty"` Propargs *map[string]interface{} `json:"propargs,omitempty"`

View File

@ -74,6 +74,9 @@ class AvailableJobSetting {
if (data.hasOwnProperty('description')) { if (data.hasOwnProperty('description')) {
obj['description'] = ApiClient.convertToType(data['description'], Object); obj['description'] = ApiClient.convertToType(data['description'], Object);
} }
if (data.hasOwnProperty('label')) {
obj['label'] = ApiClient.convertToType(data['label'], Object);
}
if (data.hasOwnProperty('default')) { if (data.hasOwnProperty('default')) {
obj['default'] = ApiClient.convertToType(data['default'], Object); obj['default'] = ApiClient.convertToType(data['default'], Object);
} }
@ -133,6 +136,12 @@ AvailableJobSetting.prototype['propargs'] = undefined;
*/ */
AvailableJobSetting.prototype['description'] = undefined; AvailableJobSetting.prototype['description'] = undefined;
/**
* Label for displaying this setting. If not specified, the key is used to generate a reasonable label.
* @member {Object} label
*/
AvailableJobSetting.prototype['label'] = undefined;
/** /**
* The default value shown to the user when determining this setting. * The default value shown to the user when determining this setting.
* @member {Object} default * @member {Object} default

View File

@ -101,7 +101,7 @@
v-show="currentSetupStep == 3" v-show="currentSetupStep == 3"
@next-clicked="nextStepAfterCheckBlenderExePath" @next-clicked="nextStepAfterCheckBlenderExePath"
@back-clicked="prevStep" @back-clicked="prevStep"
:is-next-clickable="selectedBlender != null || customBlenderExe != (null || '')" :is-next-clickable="selectedBlender != null || customBlenderExe != ''"
title="Blender"> title="Blender">
<div v-if="isBlenderExeFinding" class="is-in-progress">Looking for Blender installs...</div> <div v-if="isBlenderExeFinding" class="is-in-progress">Looking for Blender installs...</div>

View File

@ -13,8 +13,8 @@ in this process.
## SQLC ## SQLC
Flamenco mostly uses [GORM][gorm] for interfacing with its SQLite database. This Flamenco mostly uses [GORM](https://gorm.io/) for interfacing with its SQLite database. This
is gradually being phased out, to be replaced with [SQLC][sqlc]. is gradually being phased out, to be replaced with [SQLC](https://sqlc.dev/).
To generate the SQLC schema file: To generate the SQLC schema file:
```sh ```sh

View File

@ -134,17 +134,17 @@ Storage Services][cloud-storage].
### My Worker cannot find my Manager, what do I do? ### My Worker cannot find my Manager, what do I do?
First check the Manager output on the terminal, to see if it shows any messages There can be a few causes for this, each with their own solution.
about "auto-discovery" or "UPnP/SSDP". Most of the time it's actually Spotify
getting in the way, so make sure to close that before you start the Manager.
If that doesn't help, you'll have to tell the Worker where it can find the 1. **Check the Manager output on the terminal** for any messages related to "auto-discovery" or "UPnP/SSDP". Older versions of Spotify can interfere, so make sure to close that before you start the Manager.
Manager. This can be done on the commandline, by running it like
`flamenco-worker -manager http://192.168.0.1:8080/` (adjust the address to your ![Screenshot of Flamenco Manager's log output on the terminal](ssdp-port-already-in-use.webp)
situation) or more permanently by [editing the worker configuration
file][workercfg]. 2. Ensure that the **Manager port is open** in your firewall. On Windows, the system will prompt you for this during the initial setup. If you're using a third-party firewall (sometimes presenting itself as anti-virus software), you may need to create a custom rule manually. The default port is `8080`, which can be changed in [the Manager configuration file][managercfg].
3. If that doesn't help, you'll have to **tell the Worker where it can find the Manager**. This can be done on the commandline, by running it like `flamenco-worker -manager http://192.168.0.1:8080/` (adjust the address to your situation) or more permanently by editing [the worker configuration file][workercfg].
[workercfg]: {{< ref "usage/worker-configuration" >}} [workercfg]: {{< ref "usage/worker-configuration" >}}
[managercfg]: {{< ref "usage/manager-configuration" >}}
### My Worker cannot find Blender, what do I do? ### My Worker cannot find Blender, what do I do?

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -4,14 +4,25 @@ weight: 30
--- ---
This section contains third-party job types for Flamenco. These have been This section contains third-party job types for Flamenco. These have been
submitted by the community. If you wish to contribute, consider joining the submitted by the community. If you wish to contribute your custom job type,
[Blender Chat channel][flamencochannel] and chime-in there. either
- join the [#flamenco Blender Chat channel][flamencochannel] and poke `@dr.sybren`, or
- write an [issue in the tracker][tracker] with your proposal.
## How can I create my own Job Type? ## How can I create my own Job Type?
This is described [Job Types][jobtypes]. It is recommended to use the This is described [Job Types][jobtypes]. It is recommended to use the
[built-in scripts][built-in-scripts] as examples and adjust them from there. [built-in scripts][built-in-scripts] as examples and adjust them from there.
## Installation
Each job type consists of a `.js` file. After downloading, place those in the
`scripts` directory next to the Flamenco Manager executable. Create the
directory if necessary. Then restart Flamenco Manager and in Blender press the
"Refresh from Manager" button.
## Third-Party Job Types ## Third-Party Job Types
{{< flamenco/toc-children >}} {{< flamenco/toc-children >}}
@ -19,3 +30,4 @@ This is described [Job Types][jobtypes]. It is recommended to use the
[jobtypes]: {{< ref "usage/job-types" >}} [jobtypes]: {{< ref "usage/job-types" >}}
[built-in-scripts]: https://projects.blender.org/studio/flamenco/src/branch/main/internal/manager/job_compilers/scripts [built-in-scripts]: https://projects.blender.org/studio/flamenco/src/branch/main/internal/manager/job_compilers/scripts
[flamencochannel]: https://blender.chat/channel/flamenco [flamencochannel]: https://blender.chat/channel/flamenco
[tracker]: https://projects.blender.org/studio/flamenco/issues/new?template=.gitea%2fissue_template%2fjobtype.yaml

View File

@ -3,18 +3,13 @@ title: Compositor Nodes
weight: 10 weight: 10
--- ---
*Job type documented and maintained by: [Dylan Blanqué][author]. Please report any issues at [the script's Github project][github].* {{< flamenco/thirdPartyCompatibility blender="v4.0" flamenco="v3.5" >}}
Documented and maintained by [Dylan Blanqué][author].
Please report any issues at [the script's Github][github].
[author]: https://projects.blender.org/Dylan-Blanque [author]: https://projects.blender.org/Dylan-Blanque
[github]: https://github.com/dblanque/flamenco-compositor-script/issues [github]: https://github.com/dblanque/flamenco-compositor-script/issues
{{< /flamenco/thirdPartyCompatibility >}}
{{< hint >}}
This is a community-made job type. It may not reflect the same design as the
rest of Flamenco, as it was made for a specific person to solve a specific need.
{{< /hint >}}
This job type updates Blender's compositor nodes to work with Flamenco. This job type updates Blender's compositor nodes to work with Flamenco.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 122 KiB

View File

@ -0,0 +1,317 @@
// SPDX-License-Identifier: GPL-3.0-or-later
const JOB_TYPE = {
label: 'Cycles OPTIX GPU',
description:
'OPTIX GPU rendering + extra checkboxes for some experimental features + extra CLI args for Blender',
settings: [
// Settings for artists to determine:
{
key: 'frames',
type: 'string',
required: true,
eval: "f'{C.scene.frame_start}-{C.scene.frame_end}'",
evalInfo: {
showLinkButton: true,
description: 'Scene frame range',
},
description: "Frame range to render. Examples: '47', '1-30', '3, 5-10, 47-327'",
},
{
key: 'chunk_size',
type: 'int32',
default: 1,
description: 'Number of frames to render in one Blender render task',
visible: 'submission',
},
// render_output_root + add_path_components determine the value of render_output_path.
{
key: 'render_output_root',
type: 'string',
subtype: 'dir_path',
required: true,
visible: 'submission',
description:
'Base directory of where render output is stored. Will have some job-specific parts appended to it',
},
{
key: 'add_path_components',
type: 'int32',
required: true,
default: 0,
propargs: { min: 0, max: 32 },
visible: 'submission',
description:
'Number of path components of the current blend file to use in the render output path',
},
{
key: 'render_output_path',
type: 'string',
subtype: 'file_path',
editable: false,
eval: "str(Path(abspath(settings.render_output_root), last_n_dir_parts(settings.add_path_components), jobname, '{timestamp}', '######'))",
description: 'Final file path of where render output will be saved',
},
{
key: 'experimental_gp3',
label: 'Experimental: GPv3',
description: 'Experimental Flag: Grease Pencil 3',
type: 'bool',
required: false,
},
{
key: 'experimental_new_anim',
label: 'Experimental: Baklava',
description: 'Experimental Flag: New Animation Data-block',
type: 'bool',
required: false,
},
// Extra CLI arguments for Blender, for debugging purposes.
{
key: 'blender_args_before',
label: 'Blender CLI args: Before',
description: 'CLI arguments for Blender, placed before the .blend filename',
type: 'string',
required: false,
},
{
key: 'blender_args_after',
label: 'After',
description: 'CLI arguments for Blender, placed after the .blend filename',
type: 'string',
required: false,
},
// Automatically evaluated settings:
{
key: 'blendfile',
type: 'string',
required: true,
description: 'Path of the Blend file to render',
visible: 'web',
},
{
key: 'fps',
type: 'float',
eval: 'C.scene.render.fps / C.scene.render.fps_base',
visible: 'hidden',
},
{
key: 'format',
type: 'string',
required: true,
eval: 'C.scene.render.image_settings.file_format',
visible: 'web',
},
{
key: 'image_file_extension',
type: 'string',
required: true,
eval: 'C.scene.render.file_extension',
visible: 'hidden',
description: 'File extension used when rendering images',
},
{
key: 'has_previews',
type: 'bool',
required: false,
eval: 'C.scene.render.image_settings.use_preview',
visible: 'hidden',
description: 'Whether Blender will render preview images.',
},
],
};
// Set of scene.render.image_settings.file_format values that produce
// files which FFmpeg is known not to handle as input.
const ffmpegIncompatibleImageFormats = new Set([
'EXR',
'MULTILAYER', // Old CLI-style format indicators
'OPEN_EXR',
'OPEN_EXR_MULTILAYER', // DNA values for these formats.
]);
// File formats that would cause rendering to video.
// This is not supported by this job type.
const videoFormats = ['FFMPEG', 'AVI_RAW', 'AVI_JPEG'];
function compileJob(job) {
print('Blender Render job submitted');
print('job: ', job);
const settings = job.settings;
if (videoFormats.indexOf(settings.format) >= 0) {
throw `This job type only renders images, and not "${settings.format}"`;
}
const renderOutput = renderOutputPath(job);
// Make sure that when the job is investigated later, it shows the
// actually-used render output:
settings.render_output_path = renderOutput;
const renderDir = path.dirname(renderOutput);
const renderTasks = authorRenderTasks(settings, renderDir, renderOutput);
const videoTask = authorCreateVideoTask(settings, renderDir);
for (const rt of renderTasks) {
job.addTask(rt);
}
if (videoTask) {
// If there is a video task, all other tasks have to be done first.
for (const rt of renderTasks) {
videoTask.addDependency(rt);
}
job.addTask(videoTask);
}
cleanupJobSettings(job.settings);
}
// Do field replacement on the render output path.
function renderOutputPath(job) {
let path = job.settings.render_output_path;
if (!path) {
throw 'no render_output_path setting!';
}
return path.replace(/{([^}]+)}/g, (match, group0) => {
switch (group0) {
case 'timestamp':
return formatTimestampLocal(job.created);
default:
return match;
}
});
}
const enable_all_optix = `
import bpy
cycles_prefs = bpy.context.preferences.addons['cycles'].preferences
cycles_prefs.compute_device_type = 'OPTIX'
for dev in cycles_prefs.get_devices_for_type('OPTIX'):
dev.use = (dev.type != 'CPU')
`;
const enable_experimental_common = `
import bpy
exp_prefs = bpy.context.preferences.experimental
`;
function authorRenderTasks(settings, renderDir, renderOutput) {
print('authorRenderTasks(', renderDir, renderOutput, ')');
// Extra arguments for Blender.
const blender_args_before = shellSplit(settings.blender_args_before);
const blender_args_after = shellSplit(settings.blender_args_after);
// More arguments for Blender, which will be the same for each task.
const task_invariant_args = [
'--python-expr',
enable_all_optix,
'--python-expr',
"import bpy; bpy.context.scene.cycles.device = 'GPU'",
'--render-output',
path.join(renderDir, path.basename(renderOutput)),
'--render-format',
settings.format,
].concat(blender_args_after);
// Add any experimental flags.
{
let py_code_to_join = [enable_experimental_common];
if (settings.experimental_gp3) {
py_code_to_join.push('exp_prefs.use_grease_pencil_version3 = True');
}
if (settings.experimental_new_anim) {
py_code_to_join.push('exp_prefs.use_animation_baklava = True');
}
// If it's not just the common code, at least one flag was enabled.
if (py_code_to_join.length > 1) {
task_invariant_args.push('--python-expr');
task_invariant_args.push(py_code_to_join.join('\n'));
}
}
// Construct a task for each chunk.
let renderTasks = [];
let chunks = frameChunker(settings.frames, settings.chunk_size);
for (let chunk of chunks) {
const task = author.Task(`render-${chunk}`, 'blender');
const command = author.Command('blender-render', {
exe: '{blender}',
exeArgs: '{blenderArgs}',
argsBefore: blender_args_before,
blendfile: settings.blendfile,
args: task_invariant_args.concat([
'--render-frame',
chunk.replaceAll('-', '..'), // Convert to Blender frame range notation.
]),
});
task.addCommand(command);
renderTasks.push(task);
}
return renderTasks;
}
function authorCreateVideoTask(settings, renderDir) {
const needsPreviews = ffmpegIncompatibleImageFormats.has(settings.format);
if (needsPreviews && !settings.has_previews) {
print('Not authoring video task, FFmpeg-incompatible render output');
return;
}
if (!settings.fps) {
print('Not authoring video task, no FPS known:', settings);
return;
}
const stem = path.stem(settings.blendfile).replace('.flamenco', '');
const outfile = path.join(renderDir, `${stem}-${settings.frames}.mp4`);
const outfileExt = needsPreviews ? '.jpg' : settings.image_file_extension;
const task = author.Task('preview-video', 'ffmpeg');
const command = author.Command('frames-to-video', {
exe: 'ffmpeg',
fps: settings.fps,
inputGlob: path.join(renderDir, `*${outfileExt}`),
outputFile: outfile,
args: [
'-c:v',
'h264',
'-crf',
'20',
'-g',
'18',
'-vf',
'pad=ceil(iw/2)*2:ceil(ih/2)*2',
'-pix_fmt',
'yuv420p',
'-r',
settings.fps,
'-y', // Be sure to always pass either "-n" or "-y".
],
});
task.addCommand(command);
print(`Creating output video for ${settings.format}`);
return task;
}
// Clean up empty job settings so that they're no longer shown in the web UI.
function cleanupJobSettings(settings) {
const settings_to_check = [
'blender_args_before',
'blender_args_after',
'experimental_gp3',
'experimental_new_anim',
];
for (let setting_name of settings_to_check) {
if (!settings[setting_name]) delete settings[setting_name];
}
}

View File

@ -0,0 +1,36 @@
---
title: Cycles/OPTIX + Experimental
weight: 20
resources:
- name: screenshot
src: cycles-optix-gpu.png
title: Screenshot of the Flamenco job submission panel in Blender
---
{{< flamenco/thirdPartyCompatibility blender="v4.2-alpha+" flamenco="v3.6-alpha+" >}}
Documented and maintained by [Sybren Stüvel][author].
Please report any issues at [Flamenco's tracker][tracker].
[author]: https://projects.blender.org/dr.sybren
[tracker]: https://projects.blender.org/studio/flamenco/issues
{{< /flamenco/thirdPartyCompatibility >}}
This job type is the most-used one at [Blender Studio](https://studio.blender.org/). It includes a few features:
- Always enable GPU rendering with OPTIX.
- Checkboxes to enable specific experimental flags.
- Extra input fields for arbitrary commandline arguments for Blender.
To use, download [cycles_optix_gpu.js](cycles_optix_gpu.js) and place it in the
`scripts` directory next to the Flamenco Manager executable. Create the
directory if necessary. Then restart Flamenco Manager and in Blender press the
"Refresh from Manager" button.
<style>
figure {
width: 30em;
}
</style>
{{< img name="screenshot" size="medium" >}}

View File

@ -0,0 +1,39 @@
{{/*
This is an adjusted copy of themes/hugo-geekdoc/layouts/shortcodes/hint.html
- Add a CSS class.
- Different the default title.
*/}}
{{ $type := default "note" (.Get "type") }}
{{ $icon := .Get "icon" }}
{{ $title := default "Compatibility Information" (.Get "title") }}
{{ $blender := default "unknown" (.Get "blender" ) }}
{{ $flamenco := default "unknown" (.Get "flamenco" ) }}
<blockquote class="gdoc-hint {{ $type | lower }} compatibility-box">
<div class="gdoc-hint__title flex align-center">
{{- with $icon -}}
<svg class="gdoc-icon {{ . }}">
<use xlink:href="#{{ . }}"></use>
</svg>
<span>{{ $title }}</span>
{{- else -}}
<i class="fa {{ $type | lower }}" title="{{ $title }}"></i>
{{- end -}}
</div>
<div class="gdoc-hint__text">
<div class="infobox">
<dl class="versions">
<dt>Blender</dt>
<dd>{{ $blender }}</dd>
<dt>Flamenco</dt>
<dd>{{ $flamenco }}</dd>
</dl>
<p class="disclaimer">This is a community-made job type. It may not reflect the same design as the
rest of Flamenco, as it was made for a specific person to solve a specific need.</p>
</div>
{{ .Inner | $.Page.RenderString }}
</div>
</blockquote>

View File

@ -208,3 +208,38 @@ article p {
table tbody td { table tbody td {
vertical-align: top; vertical-align: top;
} }
/* 3rd party job types compatibility notes. */
.compatibility-box .infobox {
display: flex;
justify-content: space-around;
align-items: flex-start;
}
.compatibility-box p.disclaimer {
font-style: italic;
flex-basis: 70%;
text-align: justify;
}
.compatibility-box .infobox dl, .compatibility-box .infobox p.disclaimer {
margin: 0.6ex;
}
.compatibility-box dl {
flex-basis: 30%;
display: flex;
flex-flow: row wrap;
}
.compatibility-box dl dt {
margin: 0;
flex-basis: 55%;
padding: 0.2em 0.4em;
text-align: right;
}
.compatibility-box dl dt::after {
content: ":";
}
.compatibility-box dl dd {
flex-basis: 45%;
flex-grow: 1;
margin: 0;
padding: 0.2em 0.4em;
}