mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 08:48:13 +00:00
Improved how jobs are converted to JSON
This commit is contained in:
@@ -22,13 +22,13 @@ server = Flask(__name__)
|
|||||||
|
|
||||||
@server.get('/jobs')
|
@server.get('/jobs')
|
||||||
def jobs_json():
|
def jobs_json():
|
||||||
return [json.loads(x.json()) for x in RenderQueue.job_queue if not x.archived]
|
return [x.json_safe_copy() for x in RenderQueue.job_queue if not x.archived]
|
||||||
|
|
||||||
|
|
||||||
@server.get('/jobs/<status_val>')
|
@server.get('/jobs/<status_val>')
|
||||||
def filtered_jobs_json(status_val):
|
def filtered_jobs_json(status_val):
|
||||||
state = string_to_status(status_val)
|
state = string_to_status(status_val)
|
||||||
jobs = [json.loads(x.json()) for x in RenderQueue.jobs_with_status(state)]
|
jobs = [x.json_safe_copy() for x in RenderQueue.jobs_with_status(state)]
|
||||||
if jobs:
|
if jobs:
|
||||||
return jobs
|
return jobs
|
||||||
else:
|
else:
|
||||||
@@ -39,7 +39,7 @@ def filtered_jobs_json(status_val):
|
|||||||
def get_job_status(job_id):
|
def get_job_status(job_id):
|
||||||
found_job = RenderQueue.job_with_id(job_id)
|
found_job = RenderQueue.job_with_id(job_id)
|
||||||
if found_job:
|
if found_job:
|
||||||
return found_job.json()
|
return found_job.json_safe_copy()
|
||||||
else:
|
else:
|
||||||
return f'Cannot find job with ID {job_id}', 400
|
return f'Cannot find job with ID {job_id}', 400
|
||||||
|
|
||||||
@@ -130,17 +130,13 @@ def full_status():
|
|||||||
@server.get('/snapshot')
|
@server.get('/snapshot')
|
||||||
def snapshot():
|
def snapshot():
|
||||||
server_status = RenderQueue.status()
|
server_status = RenderQueue.status()
|
||||||
server_jobs = [json.loads(x.json()) for x in RenderQueue.job_queue if not x.archived]
|
server_jobs = [x.json_safe_copy() for x in RenderQueue.job_queue if not x.archived]
|
||||||
server_data = {'status': server_status, 'jobs': server_jobs, 'timestamp': datetime.now().isoformat()}
|
server_data = {'status': server_status, 'jobs': server_jobs, 'timestamp': datetime.now().isoformat()}
|
||||||
return server_data
|
return server_data
|
||||||
|
|
||||||
|
|
||||||
@server.post('/add_job')
|
@server.post('/add_job')
|
||||||
def add_job():
|
def add_job_handler():
|
||||||
def remove_job_dir():
|
|
||||||
if job_dir and os.path.exists(job_dir):
|
|
||||||
logger.debug(f"Removing job dir: {job_dir}")
|
|
||||||
shutil.rmtree(job_dir)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
"""Create new job and add to server render queue"""
|
"""Create new job and add to server render queue"""
|
||||||
@@ -148,25 +144,7 @@ def add_job():
|
|||||||
if not json_string:
|
if not json_string:
|
||||||
return 'missing json data', 400
|
return 'missing json data', 400
|
||||||
|
|
||||||
request_params = json.loads(json_string)
|
print(json_string)
|
||||||
job_owner = request_params.get("owner", None)
|
|
||||||
renderer = request_params.get("renderer", None)
|
|
||||||
input_path = request_params.get("input", None)
|
|
||||||
output_path = request_params.get("output", None)
|
|
||||||
priority = int(request_params.get('priority', 2))
|
|
||||||
args = request_params.get('args', {})
|
|
||||||
client = request_params.get('client', RenderQueue.host_name)
|
|
||||||
force_start = request_params.get('force_start', False)
|
|
||||||
uploaded_file = request.files.get('file', None)
|
|
||||||
html_origin = request_params.get('origin', None) == 'html'
|
|
||||||
custom_id = None
|
|
||||||
job_dir = None
|
|
||||||
|
|
||||||
# check for minimum render requirements
|
|
||||||
if None in [renderer, input_path or (uploaded_file and uploaded_file.filename), output_path]:
|
|
||||||
err_msg = 'Cannot add job: Missing required parameters'
|
|
||||||
logger.error(err_msg)
|
|
||||||
return err_msg, 400
|
|
||||||
|
|
||||||
# handle uploaded files
|
# handle uploaded files
|
||||||
if uploaded_file and uploaded_file.filename:
|
if uploaded_file and uploaded_file.filename:
|
||||||
|
|||||||
@@ -41,37 +41,48 @@ class RenderJob:
|
|||||||
def file_hash(self):
|
def file_hash(self):
|
||||||
return hashlib.md5(open(self.worker.input_path, 'rb').read()).hexdigest()
|
return hashlib.md5(open(self.worker.input_path, 'rb').read()).hexdigest()
|
||||||
|
|
||||||
def json(self):
|
def json_safe_copy(self):
|
||||||
"""Converts RenderJob into JSON format"""
|
"""Converts RenderJob into JSON-friendly dict"""
|
||||||
import numbers
|
import numbers
|
||||||
|
job_dict = None
|
||||||
def date_serializer(o):
|
|
||||||
if isinstance(o, datetime):
|
|
||||||
return o.isoformat()
|
|
||||||
|
|
||||||
json_string = ''
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
d = self.__dict__.copy()
|
job_dict = self.__dict__.copy()
|
||||||
d['status'] = self.render_status().value
|
job_dict['status'] = self.render_status().value
|
||||||
d['file_hash'] = self.file_hash if isinstance(self.file_hash, str) else self.file_hash()
|
job_dict['file_hash'] = self.file_hash if isinstance(self.file_hash, str) else self.file_hash()
|
||||||
d['worker'] = self.worker.__dict__.copy()
|
job_dict['worker'] = self.worker.__dict__.copy()
|
||||||
for key in ['thread', 'process']: # remove unwanted keys from JSON
|
job_dict['worker']['status'] = job_dict['status']
|
||||||
d['worker'].pop(key, None)
|
|
||||||
d['worker']['status'] = d['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 from current_session generate percent completed
|
||||||
# jobs after loading server pull in a saved value. Have to check if callable object or not
|
# 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) \
|
percent_complete = self.worker.percent_complete if isinstance(self.worker.percent_complete, numbers.Number) \
|
||||||
else self.worker.percent_complete()
|
else self.worker.percent_complete()
|
||||||
d['worker']['percent_complete'] = percent_complete
|
job_dict['worker']['percent_complete'] = percent_complete
|
||||||
|
|
||||||
json_string = json.dumps(d, default=date_serializer)
|
# 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:
|
except Exception as e:
|
||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
logger.error("Error converting to JSON: {}".format(e))
|
logger.error("Error converting to JSON: {}".format(e))
|
||||||
return json_string
|
return job_dict
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self.worker.start()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.worker.stop()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_id(cls):
|
def generate_id(cls):
|
||||||
|
|||||||
@@ -165,16 +165,13 @@ class RenderQueue:
|
|||||||
def start_job(cls, job):
|
def start_job(cls, job):
|
||||||
logger.info('Starting {}render: {} - Priority {}'.format('scheduled ' if job.scheduled_start else '', job.name,
|
logger.info('Starting {}render: {} - Priority {}'.format('scheduled ' if job.scheduled_start else '', job.name,
|
||||||
job.priority))
|
job.priority))
|
||||||
job.worker.start()
|
job.start()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def cancel_job(cls, job):
|
def cancel_job(cls, job):
|
||||||
logger.info('Cancelling job ID: {}'.format(job.id))
|
logger.info('Cancelling job ID: {}'.format(job.id))
|
||||||
if job.render_status() in [RenderStatus.NOT_STARTED, RenderStatus.RUNNING, RenderStatus.ERROR]:
|
job.stop()
|
||||||
job.worker.stop()
|
return job.render_status == RenderStatus.CANCELLED
|
||||||
job.worker.status = RenderStatus.CANCELLED
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def renderer_instances(cls):
|
def renderer_instances(cls):
|
||||||
|
|||||||
Reference in New Issue
Block a user