mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 08:48:13 +00:00
Combine add_job and upload_file methods
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
upload_folder: "/Users/brett/Desktop/zordon-uploads/"
|
upload_folder: "/Users/brett/Desktop/zordon-uploads/"
|
||||||
max_content_path: 100000000
|
max_content_path: 100000000
|
||||||
|
server_log_level: info
|
||||||
flask_log_level: error
|
flask_log_level: error
|
||||||
flask_debug_enable: false
|
flask_debug_enable: false
|
||||||
queue_eval_seconds: 1
|
queue_eval_seconds: 1
|
||||||
@@ -18,7 +18,7 @@ from rich.text import Text
|
|||||||
from rich.tree import Tree
|
from rich.tree import Tree
|
||||||
|
|
||||||
from utilities.render_worker import RenderStatus, string_to_status
|
from utilities.render_worker import RenderStatus, string_to_status
|
||||||
from zordon_server import start_server
|
from server import start_server
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The RenderDashboard is designed to be run on a remote machine or on the local server
|
The RenderDashboard is designed to be run on a remote machine or on the local server
|
||||||
|
|||||||
110
server.py
110
server.py
@@ -97,32 +97,67 @@ def snapshot():
|
|||||||
|
|
||||||
@app.post('/add_job')
|
@app.post('/add_job')
|
||||||
def add_job():
|
def add_job():
|
||||||
|
|
||||||
|
try:
|
||||||
"""Create new job and add to server render queue"""
|
"""Create new job and add to server render queue"""
|
||||||
renderer = request.json.get("renderer", None)
|
if request.is_json:
|
||||||
input_path = request.json.get("input", None)
|
request_params = request.get_json()
|
||||||
output_path = request.json.get("output", None)
|
else:
|
||||||
priority = request.json.get('priority', 2)
|
# handle request values from HTML pages - may deprecate if HTML is not used or can pass JSON from HTML
|
||||||
args = request.json.get('args', None)
|
request_params = request.values
|
||||||
client = request.json.get('client', RenderManager.host_name)
|
|
||||||
force_start = request.json.get('force_start', False)
|
|
||||||
|
|
||||||
if None in [renderer, input_path, output_path]:
|
renderer = request_params.get("renderer", None)
|
||||||
return {'error': 'missing required parameters'}, 400
|
input_path = request_params.get("input", None)
|
||||||
|
output_path = request_params.get("output", "test-output.mp4")
|
||||||
|
priority = int(request_params.get('priority', 2))
|
||||||
|
args = request_params.get('args', {})
|
||||||
|
client = request_params.get('client', RenderManager.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
|
||||||
|
|
||||||
|
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 {'error': err_msg}
|
||||||
|
|
||||||
|
# cleanup args from html form and convert them into an args dict
|
||||||
|
for key, val in request_params.items():
|
||||||
|
if key.startswith(renderer):
|
||||||
|
cleaned_key = key.split('+')[-1]
|
||||||
|
args[cleaned_key] = val
|
||||||
|
|
||||||
|
# handle uploaded files
|
||||||
|
if uploaded_file and uploaded_file.filename:
|
||||||
|
logger.info(f"Receiving uploaded file {uploaded_file.filename}")
|
||||||
|
new_id = RenderJob.generate_id()
|
||||||
|
job_dir = os.path.join(app.config['UPLOAD_FOLDER'], new_id + "-" + uploaded_file.filename)
|
||||||
|
if not os.path.exists(job_dir):
|
||||||
|
os.makedirs(job_dir)
|
||||||
|
|
||||||
|
local_path = os.path.join(job_dir, secure_filename(uploaded_file.filename))
|
||||||
|
uploaded_file.save(local_path)
|
||||||
|
input_path = local_path
|
||||||
|
|
||||||
|
# todo: finish output_path - currently placeholder data
|
||||||
|
output_path = os.path.join(job_dir, uploaded_file.filename + "-output.mp4")
|
||||||
|
|
||||||
|
# local renders
|
||||||
if client == RenderManager.host_name:
|
if client == RenderManager.host_name:
|
||||||
logger.info(f"Creating job locally - {input_path}")
|
logger.info(f"Creating job locally - {input_path}")
|
||||||
# Local Renders
|
|
||||||
try:
|
try:
|
||||||
render_job = RenderWorkerFactory.create_worker(renderer, input_path, output_path, args)
|
render_job = RenderWorkerFactory.create_worker(renderer, input_path, output_path, args)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
return {'error': str(e)}, 400
|
return {'error': str(e)}, 400
|
||||||
|
|
||||||
new_job = RenderJob(render_job, priority=priority)
|
new_job = RenderJob(render_job, priority=priority, custom_id=custom_id)
|
||||||
RenderManager.add_to_render_queue(new_job, force_start=force_start)
|
RenderManager.add_to_render_queue(new_job, force_start=force_start)
|
||||||
|
|
||||||
return new_job.json()
|
return new_job.json()
|
||||||
|
|
||||||
|
# client renders
|
||||||
elif client in RenderManager.render_clients:
|
elif client in RenderManager.render_clients:
|
||||||
|
|
||||||
# see if host is available
|
# see if host is available
|
||||||
@@ -145,7 +180,7 @@ def add_job():
|
|||||||
job_data = request.json
|
job_data = request.json
|
||||||
job_data['input'] = input_path
|
job_data['input'] = input_path
|
||||||
logger.info(f"Uploading file {input_path} to client {client}")
|
logger.info(f"Uploading file {input_path} to client {client}")
|
||||||
response = requests.post(f"http://{client}:8080/uploader", files=job_files, data=job_data)
|
response = requests.post(f"http://{client}:8080/add_job", files=job_files, data=job_data)
|
||||||
if response.ok:
|
if response.ok:
|
||||||
logger.info("Job submitted successfully!")
|
logger.info("Job submitted successfully!")
|
||||||
return response.json() if response.json() else "Job ok"
|
return response.json() if response.json() else "Job ok"
|
||||||
@@ -166,6 +201,10 @@ def add_job():
|
|||||||
logger.error(err_msg)
|
logger.error(err_msg)
|
||||||
return {'error', err_msg}, 400
|
return {'error', err_msg}, 400
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"Unknown error adding job: {e}")
|
||||||
|
return {'error', 'cannot add job'}
|
||||||
|
|
||||||
|
|
||||||
@app.get('/cancel_job')
|
@app.get('/cancel_job')
|
||||||
def cancel_job():
|
def cancel_job():
|
||||||
@@ -204,46 +243,7 @@ def default():
|
|||||||
|
|
||||||
@app.route('/upload')
|
@app.route('/upload')
|
||||||
def upload_file_page():
|
def upload_file_page():
|
||||||
return render_template('upload.html')
|
return render_template('upload.html', render_clients=RenderManager.render_clients)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/uploader', methods=['POST'])
|
|
||||||
def upload_file():
|
|
||||||
if request.method == 'POST':
|
|
||||||
try:
|
|
||||||
|
|
||||||
uploaded_file = request.files['file']
|
|
||||||
if not uploaded_file.filename:
|
|
||||||
return {'error': 'no file uploaded'}
|
|
||||||
|
|
||||||
# generate directory to use
|
|
||||||
logger.debug(f"Receiving uploaded file {uploaded_file.filename}")
|
|
||||||
new_id = RenderJob.generate_id()
|
|
||||||
job_dir = os.path.join(app.config['UPLOAD_FOLDER'], new_id + "-" + uploaded_file.filename)
|
|
||||||
if not os.path.exists(job_dir):
|
|
||||||
os.makedirs(job_dir)
|
|
||||||
|
|
||||||
local_path = os.path.join(job_dir, secure_filename(uploaded_file.filename))
|
|
||||||
uploaded_file.save(local_path)
|
|
||||||
renderer = request.values['renderer']
|
|
||||||
|
|
||||||
# todo: finish output_path - currently placeholder data
|
|
||||||
output_path = os.path.join(job_dir, uploaded_file.filename + "-output.mp4")
|
|
||||||
|
|
||||||
try:
|
|
||||||
render_job = RenderWorkerFactory.create_worker(renderer, local_path, output_path,
|
|
||||||
args=request.values.get('args', None))
|
|
||||||
new_job = RenderJob(render_job, custom_id=new_id)
|
|
||||||
RenderManager.add_to_render_queue(new_job)
|
|
||||||
return new_job.json()
|
|
||||||
except ValueError as e:
|
|
||||||
logger.exception(e)
|
|
||||||
return {'error': str(e)}, 400
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.exception(e)
|
|
||||||
|
|
||||||
return {'error': 'unknown error'}
|
|
||||||
|
|
||||||
|
|
||||||
def start_server(background_thread=False):
|
def start_server(background_thread=False):
|
||||||
@@ -253,12 +253,12 @@ def start_server(background_thread=False):
|
|||||||
RenderManager.evaluate_queue()
|
RenderManager.evaluate_queue()
|
||||||
time.sleep(delay_sec)
|
time.sleep(delay_sec)
|
||||||
|
|
||||||
logging.basicConfig(format='%(asctime)s: %(levelname)s: %(module)s: %(message)s', datefmt='%d-%b-%y %H:%M:%S',
|
|
||||||
level=logging.INFO)
|
|
||||||
|
|
||||||
with open('config.yaml') as f:
|
with open('config.yaml') as f:
|
||||||
config = yaml.load(f, Loader=yaml.FullLoader)
|
config = yaml.load(f, Loader=yaml.FullLoader)
|
||||||
|
|
||||||
|
logging.basicConfig(format='%(asctime)s: %(levelname)s: %(module)s: %(message)s', datefmt='%d-%b-%y %H:%M:%S',
|
||||||
|
level=config.get('server_log_level', 'INFO').upper())
|
||||||
|
|
||||||
app.config['UPLOAD_FOLDER'] = config['upload_folder']
|
app.config['UPLOAD_FOLDER'] = config['upload_folder']
|
||||||
app.config['MAX_CONTENT_PATH'] = config['max_content_path']
|
app.config['MAX_CONTENT_PATH'] = config['max_content_path']
|
||||||
# app.config['RESULT_STATIC_PATH'] = 'static'
|
# app.config['RESULT_STATIC_PATH'] = 'static'
|
||||||
|
|||||||
@@ -1,9 +1,52 @@
|
|||||||
<html>
|
<html>
|
||||||
<body>
|
|
||||||
<form action = "http://localhost:5000/uploader" method = "POST"
|
<body>
|
||||||
enctype = "multipart/form-data">
|
<h1>Upload a file</h1>
|
||||||
<input type = "file" name = "file" />
|
|
||||||
<input type = "submit"/>
|
<form action="/add_job" method="POST"
|
||||||
</form>
|
enctype="multipart/form-data">
|
||||||
</body>
|
<div>
|
||||||
|
<input type="file" name="file"/><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="hidden" id="origin" name="origin" value="html">
|
||||||
|
|
||||||
|
<div id="client">
|
||||||
|
Render Client:
|
||||||
|
<select name="client">
|
||||||
|
{% for client in render_clients %}
|
||||||
|
<option value="{{client}}">{{client}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="renderer">Renderer:</label>
|
||||||
|
<select id="renderer" name="renderer" onchange="javascript:rendererCheck();">
|
||||||
|
<option value="aerender">After Effects</option>
|
||||||
|
<option value="blender">Blender</option>
|
||||||
|
<option value="ffmpeg">FFMPEG</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div id="priority">
|
||||||
|
Priority:
|
||||||
|
<select name="priority">
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="2" selected>2</option>
|
||||||
|
<option value="3">3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="show_blender">
|
||||||
|
Engine:
|
||||||
|
<select name="blender+engine">
|
||||||
|
<option value="CYCLES">Cycles</option>
|
||||||
|
<option value="BLENDER_EEVEE">Eevee</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<input type="submit"/>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -35,12 +35,13 @@ class AERenderWorker(BaseRenderWorker):
|
|||||||
render_engine = 'aerender'
|
render_engine = 'aerender'
|
||||||
supported_extensions = ['.aep']
|
supported_extensions = ['.aep']
|
||||||
|
|
||||||
def __init__(self, project, comp, render_settings, omsettings, output):
|
def __init__(self, input_path, output_path, args=None):
|
||||||
super(AERenderWorker, self).__init__(input=project, output=output)
|
super(AERenderWorker, self).__init__(input_path=input_path, output_path=output_path, ignore_extensions=False,
|
||||||
|
args=args)
|
||||||
|
|
||||||
self.comp = comp
|
self.comp = args.get('comp', None)
|
||||||
self.render_settings = render_settings
|
self.render_settings = args.get('render_settings', None)
|
||||||
self.omsettings = omsettings
|
self.omsettings = args.get('omsettings', None)
|
||||||
|
|
||||||
self.progress = 0
|
self.progress = 0
|
||||||
self.progress_history = []
|
self.progress_history = []
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ class BlenderRenderWorker(BaseRenderWorker):
|
|||||||
install_paths = ['/Applications/Blender.app/Contents/MacOS/Blender']
|
install_paths = ['/Applications/Blender.app/Contents/MacOS/Blender']
|
||||||
|
|
||||||
def __init__(self, input_path, output_path, args=None, render_all_frames=False, engine='BLENDER_EEVEE'):
|
def __init__(self, input_path, output_path, args=None, render_all_frames=False, engine='BLENDER_EEVEE'):
|
||||||
super(BlenderRenderWorker, self).__init__(input_path=input_path, output_path=output_path, args=args)
|
super(BlenderRenderWorker, self).__init__(input_path=input_path, output_path=output_path,
|
||||||
|
ignore_extensions=False, args=args)
|
||||||
|
|
||||||
self.engine = engine # or 'CYCLES'
|
self.engine = engine # or 'CYCLES'
|
||||||
self.format = 'JPEG'
|
self.format = 'JPEG'
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ class FFMPEGRenderWorker(BaseRenderWorker):
|
|||||||
render_engine = 'ffmpeg'
|
render_engine = 'ffmpeg'
|
||||||
|
|
||||||
def __init__(self, input_path, output_path, args=None):
|
def __init__(self, input_path, output_path, args=None):
|
||||||
super(FFMPEGRenderWorker, self).__init__(input_path=input_path, output_path=output_path, ignore_extensions=True, args=args)
|
super(FFMPEGRenderWorker, self).__init__(input_path=input_path, output_path=output_path, ignore_extensions=True,
|
||||||
|
args=args)
|
||||||
|
|
||||||
self.total_frames = -1
|
self.total_frames = -1
|
||||||
if os.path.exists(input_path):
|
if os.path.exists(input_path):
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class BaseRenderWorker(object):
|
|||||||
def version():
|
def version():
|
||||||
return 'Unknown'
|
return 'Unknown'
|
||||||
|
|
||||||
def __init__(self, input_path, output_path, args=None, ignore_extensions=False):
|
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.supported_extensions):
|
||||||
|
|||||||
Reference in New Issue
Block a user