mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 08:48:13 +00:00
BaseRenderWorker split into BaseRenderWorker & BaseRenderEngine
This commit is contained in:
@@ -30,27 +30,24 @@ def string_to_status(string):
|
|||||||
|
|
||||||
class BaseRenderWorker(object):
|
class BaseRenderWorker(object):
|
||||||
|
|
||||||
renderer = 'BaseRenderWorker'
|
engine = None
|
||||||
render_engine = None
|
|
||||||
render_engine_version = None
|
|
||||||
supported_extensions = []
|
|
||||||
install_paths = []
|
|
||||||
supported_export_formats = []
|
|
||||||
|
|
||||||
def __init__(self, input_path, output_path, args=None, ignore_extensions=True):
|
def __init__(self, input_path, output_path, args=None, ignore_extensions=True):
|
||||||
|
|
||||||
if not ignore_extensions:
|
if not ignore_extensions:
|
||||||
if not any(ext in input_path for ext in self.supported_extensions):
|
if not any(ext in input_path for ext in self.engine.supported_extensions):
|
||||||
err_meg = f'Cannot find valid project with supported file extension for {self.renderer} renderer'
|
err_meg = f'Cannot find valid project with supported file extension for {self.engine.name} renderer'
|
||||||
logger.error(err_meg)
|
logger.error(err_meg)
|
||||||
raise ValueError(err_meg)
|
raise ValueError(err_meg)
|
||||||
|
if not self.engine:
|
||||||
|
raise NotImplementedError("Engine not defined")
|
||||||
|
|
||||||
# Essential Info
|
# Essential Info
|
||||||
self.input_path = input_path
|
self.input_path = input_path
|
||||||
self.output_path = output_path
|
self.output_path = output_path
|
||||||
self.args = args or {}
|
self.args = args or {}
|
||||||
self.date_created = datetime.now()
|
self.date_created = datetime.now()
|
||||||
self.renderer_version = self.version()
|
self.renderer_version = self.engine.version()
|
||||||
|
|
||||||
# Frame Ranges
|
# Frame Ranges
|
||||||
self.total_frames = 0
|
self.total_frames = 0
|
||||||
@@ -75,23 +72,6 @@ class BaseRenderWorker(object):
|
|||||||
self.is_finished = False
|
self.is_finished = False
|
||||||
self.last_output = None
|
self.last_output = None
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def version(cls):
|
|
||||||
raise NotImplementedError("Unknown version")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def renderer_path(cls):
|
|
||||||
path = None
|
|
||||||
try:
|
|
||||||
path = subprocess.check_output(['which', cls.render_engine]).decode('utf-8').strip()
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
for p in cls.install_paths:
|
|
||||||
if os.path.exists(p):
|
|
||||||
path = p
|
|
||||||
except Exception as e:
|
|
||||||
logging.exception(e)
|
|
||||||
return path
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
if not os.path.exists(self.input_path):
|
if not os.path.exists(self.input_path):
|
||||||
raise FileNotFoundError(f"Cannot find input path: {self.input_path}")
|
raise FileNotFoundError(f"Cannot find input path: {self.input_path}")
|
||||||
@@ -128,9 +108,9 @@ class BaseRenderWorker(object):
|
|||||||
self.errors.append(msg)
|
self.errors.append(msg)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.renderer_path():
|
if not self.engine.renderer_path():
|
||||||
self.status = RenderStatus.ERROR
|
self.status = RenderStatus.ERROR
|
||||||
msg = 'Cannot find render engine path for {}'.format(self.render_engine)
|
msg = 'Cannot find render engine path for {}'.format(self.engine.name())
|
||||||
logger.error(msg)
|
logger.error(msg)
|
||||||
self.errors.append(msg)
|
self.errors.append(msg)
|
||||||
return
|
return
|
||||||
@@ -166,12 +146,12 @@ class BaseRenderWorker(object):
|
|||||||
|
|
||||||
with open(self.log_path, "a") as f:
|
with open(self.log_path, "a") as f:
|
||||||
|
|
||||||
f.write("{3} - Starting {0} {1} Render for {2}\n".format(self.renderer, self.version(), self.input_path,
|
f.write(f"{self.start_time.isoformat()} - Starting {self.engine.name()} {self.engine.version()} "
|
||||||
self.start_time.isoformat()))
|
f"Render for {self.input_path}")
|
||||||
f.write(f"Running command: {' '.join(subprocess_cmds)}\n")
|
f.write(f"Running command: {' '.join(subprocess_cmds)}\n")
|
||||||
for c in io.TextIOWrapper(self.__process.stdout, encoding="utf-8"): # or another encoding
|
for c in io.TextIOWrapper(self.__process.stdout, encoding="utf-8"): # or another encoding
|
||||||
f.write(c)
|
f.write(c)
|
||||||
logger.debug(f"{self.renderer}Worker: {c.strip()}")
|
logger.debug(f"{self.engine.name()}Worker: {c.strip()}")
|
||||||
self.last_output = c.strip()
|
self.last_output = c.strip()
|
||||||
self._parse_stdout(c.strip())
|
self._parse_stdout(c.strip())
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
@@ -187,18 +167,19 @@ class BaseRenderWorker(object):
|
|||||||
duration = self.end_time - self.start_time
|
duration = self.end_time - self.start_time
|
||||||
|
|
||||||
if return_code:
|
if return_code:
|
||||||
message = f"{self.renderer} render failed with return_code {return_code} after {duration}"
|
message = f"{self.engine.name()} render failed with return_code {return_code} after {duration}"
|
||||||
logger.error(message)
|
logger.error(message)
|
||||||
self.failed_attempts = self.failed_attempts + 1
|
self.failed_attempts = self.failed_attempts + 1
|
||||||
else:
|
else:
|
||||||
message = f"{self.renderer} render completed successfully in {duration}"
|
message = f"{self.engine.name()} render completed successfully in {duration}"
|
||||||
logger.info(message)
|
logger.info(message)
|
||||||
self.status = RenderStatus.COMPLETED
|
self.status = RenderStatus.COMPLETED
|
||||||
|
|
||||||
f.write(message)
|
f.write(message)
|
||||||
|
|
||||||
if self.failed_attempts >= self.maximum_attempts and self.status is not RenderStatus.CANCELLED:
|
if self.failed_attempts >= self.maximum_attempts and self.status is not RenderStatus.CANCELLED:
|
||||||
logger.error('{} Render of {} failed after {} attempts'.format(self.renderer, self.input_path, self.failed_attempts))
|
logger.error('{} Render of {} failed after {} attempts'.format(self.engine.name(), self.input_path,
|
||||||
|
self.failed_attempts))
|
||||||
self.status = RenderStatus.ERROR
|
self.status = RenderStatus.ERROR
|
||||||
if not self.errors:
|
if not self.errors:
|
||||||
self.errors = [self.last_output]
|
self.errors = [self.last_output]
|
||||||
@@ -237,6 +218,45 @@ class BaseRenderWorker(object):
|
|||||||
return elapsed
|
return elapsed
|
||||||
|
|
||||||
|
|
||||||
|
class BaseRenderEngine(object):
|
||||||
|
|
||||||
|
install_paths = []
|
||||||
|
supported_extensions = []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def name(cls):
|
||||||
|
return cls.__name__.lower()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def renderer_path(cls):
|
||||||
|
path = None
|
||||||
|
try:
|
||||||
|
path = subprocess.check_output(['which', cls.name()]).decode('utf-8').strip()
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
for p in cls.install_paths:
|
||||||
|
if os.path.exists(p):
|
||||||
|
path = p
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(e)
|
||||||
|
return path
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def version(cls):
|
||||||
|
raise NotImplementedError("version not implemented")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_help(cls):
|
||||||
|
path = cls.renderer_path()
|
||||||
|
if not path:
|
||||||
|
raise FileNotFoundError("renderer path not found")
|
||||||
|
help_doc = subprocess.check_output([path, '-h'], stderr=subprocess.STDOUT).decode('utf-8')
|
||||||
|
return help_doc
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_formats(cls):
|
||||||
|
raise NotImplementedError("get_formats not implemented")
|
||||||
|
|
||||||
|
|
||||||
class RenderWorkerFactory:
|
class RenderWorkerFactory:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -255,15 +275,14 @@ class RenderWorkerFactory:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def supported_renderers():
|
def supported_renderers():
|
||||||
return [x.render_engine for x in RenderWorkerFactory.supported_classes()]
|
return [x.engine.name() for x in RenderWorkerFactory.supported_classes()]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def class_for_name(name):
|
def class_for_name(name):
|
||||||
name = name.lower()
|
name = name.lower()
|
||||||
for render_class in RenderWorkerFactory.supported_classes():
|
for render_class in RenderWorkerFactory.supported_classes():
|
||||||
if render_class.render_engine == name:
|
if render_class.engine.name() == name:
|
||||||
return render_class
|
return render_class
|
||||||
|
|
||||||
raise LookupError(f'Cannot find class for name: {name}')
|
raise LookupError(f'Cannot find class for name: {name}')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user