Addon: submit job to Manager after packing the files
This commit is contained in:
parent
7352b0950b
commit
b5053734dd
29
addon/flamenco/job_submission.py
Normal file
29
addon/flamenco/job_submission.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .manager import ApiClient as _ApiClient
|
||||||
|
from .manager.models import (
|
||||||
|
Job as _Job,
|
||||||
|
SubmittedJob as _SubmittedJob,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_ApiClient = object
|
||||||
|
_Job = object
|
||||||
|
_SubmittedJob = object
|
||||||
|
|
||||||
|
|
||||||
|
def submit_job(job: _SubmittedJob, api_client: _ApiClient) -> _Job:
|
||||||
|
"""Send the given job to Flamenco Manager."""
|
||||||
|
from flamenco.manager import ApiClient
|
||||||
|
from flamenco.manager.api import jobs_api
|
||||||
|
from flamenco.manager.models import SubmittedJob, Job
|
||||||
|
|
||||||
|
assert isinstance(job, SubmittedJob), "got %s" % type(job)
|
||||||
|
assert isinstance(api_client, ApiClient), "got %s" % type(api_client)
|
||||||
|
|
||||||
|
job_api_instance = jobs_api.JobsApi(api_client)
|
||||||
|
response: Job = job_api_instance.submit_job(job)
|
||||||
|
print("Job submitted: %s (%s)" % (response.name, response.id))
|
||||||
|
|
||||||
|
return response
|
@ -12,6 +12,7 @@ from . import job_types_propgroup
|
|||||||
_log = logging.getLogger(__name__)
|
_log = logging.getLogger(__name__)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from flamenco.manager import ApiClient as _ApiClient
|
||||||
from flamenco.manager.models import (
|
from flamenco.manager.models import (
|
||||||
AvailableJobType as _AvailableJobType,
|
AvailableJobType as _AvailableJobType,
|
||||||
AvailableJobTypes as _AvailableJobTypes,
|
AvailableJobTypes as _AvailableJobTypes,
|
||||||
@ -19,6 +20,7 @@ if TYPE_CHECKING:
|
|||||||
JobSettings as _JobSettings,
|
JobSettings as _JobSettings,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
_ApiClient = object
|
||||||
_AvailableJobTypes = object
|
_AvailableJobTypes = object
|
||||||
_AvailableJobType = object
|
_AvailableJobType = object
|
||||||
_SubmittedJob = object
|
_SubmittedJob = object
|
||||||
@ -131,35 +133,20 @@ def update_job_type_properties(scene: bpy.types.Scene) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_job_settings(scene: bpy.types.Scene) -> Optional[_JobSettings]:
|
|
||||||
from flamenco.manager.models import JobSettings
|
|
||||||
|
|
||||||
job_settings = getattr(scene, "flamenco_job_settings", None)
|
|
||||||
if job_settings is None:
|
|
||||||
return None
|
|
||||||
assert isinstance(job_settings, JobSettings), "expected JobSettings, got %s" % (
|
|
||||||
type(job_settings)
|
|
||||||
)
|
|
||||||
return job_settings
|
|
||||||
|
|
||||||
|
|
||||||
def job_for_scene(scene: bpy.types.Scene) -> Optional[_SubmittedJob]:
|
def job_for_scene(scene: bpy.types.Scene) -> Optional[_SubmittedJob]:
|
||||||
from flamenco.manager.models import SubmittedJob, JobSettings, JobMetadata
|
from flamenco.manager.models import SubmittedJob, JobMetadata
|
||||||
|
|
||||||
settings_propgroup = get_job_settings(scene)
|
propgroup = getattr(scene, "flamenco_job_settings", None)
|
||||||
if settings_propgroup is None:
|
assert isinstance(
|
||||||
return None
|
propgroup, job_types_propgroup.JobTypePropertyGroup
|
||||||
|
), "did not expect %s" % (type(propgroup))
|
||||||
|
|
||||||
# TODO: convert settings_propgroup to JobSettings.
|
settings = propgroup.as_jobsettings()
|
||||||
# dict(settings_propgroup) only includes the user-modified items, which
|
|
||||||
# isn't enough; the JobSettings() object should also have explicit values
|
|
||||||
# for the still-default ones.
|
|
||||||
settings = JobSettings()
|
|
||||||
metadata = JobMetadata()
|
metadata = JobMetadata()
|
||||||
|
|
||||||
job: SubmittedJob = SubmittedJob(
|
job: SubmittedJob = SubmittedJob(
|
||||||
name=scene.flamenco_job_name,
|
name=scene.flamenco_job_name,
|
||||||
type=settings_propgroup.job_type.name,
|
type=propgroup.job_type.name,
|
||||||
priority=50,
|
priority=50,
|
||||||
id=str(uuid.uuid4()),
|
id=str(uuid.uuid4()),
|
||||||
settings=settings,
|
settings=settings,
|
||||||
|
@ -38,6 +38,15 @@ class JobTypePropertyGroup:
|
|||||||
def unregister_property_group(cls):
|
def unregister_property_group(cls):
|
||||||
bpy.utils.unregister_class(cls)
|
bpy.utils.unregister_class(cls)
|
||||||
|
|
||||||
|
def as_jobsettings(self) -> _JobSettings:
|
||||||
|
from flamenco.manager.models import JobSettings
|
||||||
|
|
||||||
|
js: JobSettings = JobSettings()
|
||||||
|
for setting in self.job_type.settings:
|
||||||
|
js[setting.key] = getattr(self, setting.key)
|
||||||
|
|
||||||
|
return js
|
||||||
|
|
||||||
|
|
||||||
# Mapping from AvailableJobType.setting.type to a callable that converts a value
|
# Mapping from AvailableJobType.setting.type to a callable that converts a value
|
||||||
# to the appropriate type. This is necessary due to the ambiguity between floats
|
# to the appropriate type. This is necessary due to the ambiguity between floats
|
||||||
|
@ -7,16 +7,18 @@ from typing import Optional, TYPE_CHECKING
|
|||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
from . import preferences
|
from . import job_submission
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .bat_interface import (
|
from .bat_interface import (
|
||||||
PackThread as _PackThread,
|
PackThread as _PackThread,
|
||||||
Message as _Message,
|
Message as _Message,
|
||||||
)
|
)
|
||||||
|
from .manager.models import SubmittedJob as _SubmittedJob
|
||||||
else:
|
else:
|
||||||
_PackThread = object
|
_PackThread = object
|
||||||
_Message = object
|
_Message = object
|
||||||
|
_SubmittedJob = object
|
||||||
|
|
||||||
_log = logging.getLogger(__name__)
|
_log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -110,6 +112,7 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER"} # No UNDO.
|
bl_options = {"REGISTER"} # No UNDO.
|
||||||
|
|
||||||
job_name: bpy.props.StringProperty(name="Job Name") # type: ignore
|
job_name: bpy.props.StringProperty(name="Job Name") # type: ignore
|
||||||
|
job: Optional[_SubmittedJob] = None
|
||||||
|
|
||||||
timer: Optional[bpy.types.Timer] = None
|
timer: Optional[bpy.types.Timer] = None
|
||||||
packthread: Optional[_PackThread] = None
|
packthread: Optional[_PackThread] = None
|
||||||
@ -118,6 +121,15 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
|
|
||||||
def invoke(self, context: bpy.types.Context, event: bpy.types.Event) -> set[str]:
|
def invoke(self, context: bpy.types.Context, event: bpy.types.Event) -> set[str]:
|
||||||
filepath = self._save_blendfile(context)
|
filepath = self._save_blendfile(context)
|
||||||
|
|
||||||
|
# Construct the Job locally before trying to pack. If any validations fail, better fail early.
|
||||||
|
from . import job_types
|
||||||
|
|
||||||
|
self.job = job_types.job_for_scene(context.scene)
|
||||||
|
if self.job is None:
|
||||||
|
self.report({"ERROR"}, "Unable to create job")
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
return self._bat_pack(context, filepath)
|
return self._bat_pack(context, filepath)
|
||||||
|
|
||||||
def modal(self, context: bpy.types.Context, event: bpy.types.Event) -> set[str]:
|
def modal(self, context: bpy.types.Context, event: bpy.types.Event) -> set[str]:
|
||||||
@ -212,7 +224,7 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
|
|
||||||
if isinstance(msg, bat_interface.MsgDone):
|
if isinstance(msg, bat_interface.MsgDone):
|
||||||
self.report({"INFO"}, "BAT pack is done")
|
self.report({"INFO"}, "BAT pack is done")
|
||||||
# TODO: actually send the job to Flamenco!
|
self._submit_job(context)
|
||||||
return self._quit(context)
|
return self._quit(context)
|
||||||
|
|
||||||
if isinstance(msg, bat_interface.MsgException):
|
if isinstance(msg, bat_interface.MsgException):
|
||||||
@ -229,6 +241,15 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator):
|
|||||||
|
|
||||||
return {"RUNNING_MODAL"}
|
return {"RUNNING_MODAL"}
|
||||||
|
|
||||||
|
def _submit_job(self, context: bpy.types.Context) -> None:
|
||||||
|
"""Use the Flamenco API to submit the new Job."""
|
||||||
|
assert self.job is not None
|
||||||
|
|
||||||
|
api_client = self.get_api_client(context)
|
||||||
|
job = job_submission.submit_job(self.job, api_client)
|
||||||
|
|
||||||
|
self.report({"INFO"}, "Job submitted")
|
||||||
|
|
||||||
def _quit(self, context: bpy.types.Context) -> set[str]:
|
def _quit(self, context: bpy.types.Context) -> set[str]:
|
||||||
"""Stop any timer and return a 'FINISHED' status.
|
"""Stop any timer and return a 'FINISHED' status.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user