Files
Zordon/lib/render_job.py
2022-12-07 14:39:50 -08:00

102 lines
3.7 KiB
Python

import hashlib
import json
import logging
import os
import uuid
from datetime import datetime
from utilities.render_worker import RenderStatus, RenderWorkerFactory
logger = logging.getLogger()
class RenderJob:
def __init__(self, renderer, input_path, output_path, args, priority=2, owner=None, client=None, notify=None,
custom_id=None, name=None):
self.id = custom_id or self.generate_id()
self.owner = owner
self.priority = priority
self.client = client
self.notify = notify
self.date_created = datetime.now()
self.scheduled_start = None
self.renderer = renderer
self.name = name or os.path.basename(input_path) + '_' + self.date_created.strftime("%Y.%m.%d_%H.%M.%S")
self.worker = RenderWorkerFactory.create_worker(renderer, input_path, output_path, args)
self.worker.log_path = os.path.join(os.path.dirname(input_path), self.name + '.log')
def render_status(self):
if self.scheduled_start and self.worker.status == RenderStatus.NOT_STARTED:
return RenderStatus.SCHEDULED
else:
return self.worker.status
def file_hash(self):
if os.path.exists(self.worker.input_path):
return hashlib.md5(open(self.worker.input_path, 'rb').read()).hexdigest()
return None
def json_safe_copy(self):
"""Converts RenderJob into JSON-friendly dict"""
import numbers
job_dict = None
try:
job_dict = self.__dict__.copy()
job_dict['status'] = self.render_status().value
job_dict['file_hash'] = self.file_hash if self.file_hash and isinstance(self.file_hash, str) else self.file_hash()
job_dict['worker'] = self.worker.__dict__.copy()
job_dict['worker']['status'] = job_dict['status']
# remove unwanted keys from dict
keys_to_remove = ['thread', 'process']
for key in job_dict['worker'].keys():
if key.startswith('_'):
keys_to_remove.append(key)
for key in keys_to_remove:
job_dict['worker'].pop(key, None)
# jobs from current_session generate percent completed
# jobs after loading server pull in a saved value. Have to check if callable object or not
percent_complete = self.worker.percent_complete if isinstance(self.worker.percent_complete, numbers.Number) \
else self.worker.percent_complete()
job_dict['worker']['percent_complete'] = percent_complete
# convert to json and back to auto-convert dates to iso format
def date_serializer(o):
if isinstance(o, datetime):
return o.isoformat()
json_convert = json.dumps(job_dict, default=date_serializer)
job_dict = json.loads(json_convert)
except Exception as e:
logger.exception(e)
logger.error("Error converting to JSON: {}".format(e))
return job_dict
def start(self):
self.worker.start()
def stop(self):
self.worker.stop()
def time_elapsed(self):
# calculate elapsed time
elapsed_time = 'Unknown'
start_time = self.worker.start_time
end_time = self.worker.end_time
if start_time:
if end_time:
elapsed_time = str(end_time - start_time)
elif self.render_status() == RenderStatus.RUNNING:
elapsed_time = str(datetime.now() - start_time)
return elapsed_time
def frame_count(self):
return self.worker.total_frames
@classmethod
def generate_id(cls):
return str(uuid.uuid4()).split('-')[0]