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() @classmethod def generate_id(cls): return str(uuid.uuid4()).split('-')[0]