mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 08:48:13 +00:00
Remove Old Multi-Client Code / Refactoring (#13)
* Remove a lot of old code from render_queue regarding clients * More code cleanup * More code cleanup * Move everything around * Minor log change
This commit is contained in:
@@ -4,3 +4,4 @@ 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
|
||||||
|
port_number: 8080
|
||||||
@@ -17,7 +17,7 @@ from rich.table import Table
|
|||||||
from rich.text import Text
|
from rich.text import Text
|
||||||
from rich.tree import Tree
|
from rich.tree import Tree
|
||||||
|
|
||||||
from lib.render_workers.base_worker import RenderStatus, string_to_status
|
from lib.workers.base_worker import RenderStatus, string_to_status
|
||||||
from lib.server.server_proxy import RenderServerProxy
|
from lib.server.server_proxy import RenderServerProxy
|
||||||
from lib.utilities.misc_helper import get_time_elapsed
|
from lib.utilities.misc_helper import get_time_elapsed
|
||||||
from start_server import start_server
|
from start_server import start_server
|
||||||
|
|||||||
@@ -11,25 +11,13 @@ from tkinter.ttk import Frame, Label, Entry, Combobox, Progressbar
|
|||||||
import psutil
|
import psutil
|
||||||
import requests
|
import requests
|
||||||
import threading
|
import threading
|
||||||
from lib.render_workers.blender_worker import Blender
|
from lib.workers.blender_worker import Blender
|
||||||
from lib.server.server_proxy import RenderServerProxy
|
from lib.server.server_proxy import RenderServerProxy
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
prefs_name = 'config/.scheduler_prefs'
|
|
||||||
label_width = 9
|
label_width = 9
|
||||||
header_padding = 6
|
header_padding = 6
|
||||||
server_setup_timeout = 5
|
|
||||||
|
|
||||||
|
|
||||||
def request_data(server_ip, payload, server_port=8080, timeout=2):
|
|
||||||
try:
|
|
||||||
req = requests.get(f'http://{server_ip}:{server_port}/api/{payload}', timeout=timeout)
|
|
||||||
if req.ok:
|
|
||||||
return req.json()
|
|
||||||
except Exception as e:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
# CheckListBox source - https://stackoverflow.com/questions/50398649/python-tkinter-tk-support-checklist-box
|
# CheckListBox source - https://stackoverflow.com/questions/50398649/python-tkinter-tk-support-checklist-box
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class Blender(BaseRenderEngine):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_scene_info(cls, project_path, timeout=10):
|
def get_scene_info(cls, project_path, timeout=10):
|
||||||
scene_info = None
|
scene_info = {}
|
||||||
try:
|
try:
|
||||||
results = cls.run_python_script(project_path, os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
results = cls.run_python_script(project_path, os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
||||||
'scripts', 'blender', 'get_file_info.py'), timeout=timeout)
|
'scripts', 'blender', 'get_file_info.py'), timeout=timeout)
|
||||||
@@ -71,6 +71,8 @@ class Blender(BaseRenderEngine):
|
|||||||
raw_data = line.split('SCENE_DATA:')[-1]
|
raw_data = line.split('SCENE_DATA:')[-1]
|
||||||
scene_info = json.loads(raw_data)
|
scene_info = json.loads(raw_data)
|
||||||
break
|
break
|
||||||
|
elif line.startswith('Error'):
|
||||||
|
logger.error(f"get_scene_info error: {line.strip()}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f'Error getting file details for .blend file: {e}')
|
logger.error(f'Error getting file details for .blend file: {e}')
|
||||||
return scene_info
|
return scene_info
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
import logging
|
import logging
|
||||||
import platform
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import psutil
|
from sqlalchemy import create_engine
|
||||||
import requests
|
|
||||||
from sqlalchemy import create_engine, Column, String, Integer
|
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
|
||||||
from .render_workers.base_worker import RenderStatus, BaseRenderWorker, Base
|
from .workers.base_worker import RenderStatus, BaseRenderWorker, Base
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
@@ -18,27 +15,6 @@ class JobNotFoundError(Exception):
|
|||||||
self.job_id = job_id
|
self.job_id = job_id
|
||||||
|
|
||||||
|
|
||||||
class RenderClient(Base):
|
|
||||||
__tablename__ = 'render_clients'
|
|
||||||
id = Column(Integer, primary_key=True)
|
|
||||||
hostname = Column(String)
|
|
||||||
|
|
||||||
def __init__(self, hostname):
|
|
||||||
self.hostname = hostname
|
|
||||||
|
|
||||||
def is_available(self, timeout=3):
|
|
||||||
try:
|
|
||||||
response = requests.get(f"http://{self.hostname}:8080/api/status", timeout=timeout)
|
|
||||||
if response.ok:
|
|
||||||
return True
|
|
||||||
except requests.ConnectionError as e:
|
|
||||||
pass
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "client stuff"
|
|
||||||
|
|
||||||
|
|
||||||
class RenderQueue:
|
class RenderQueue:
|
||||||
engine = create_engine('sqlite:///database.db')
|
engine = create_engine('sqlite:///database.db')
|
||||||
Base.metadata.create_all(engine)
|
Base.metadata.create_all(engine)
|
||||||
@@ -46,30 +22,19 @@ class RenderQueue:
|
|||||||
session = Session()
|
session = Session()
|
||||||
job_queue = []
|
job_queue = []
|
||||||
maximum_renderer_instances = {'blender': 1, 'aerender': 1, 'ffmpeg': 4}
|
maximum_renderer_instances = {'blender': 1, 'aerender': 1, 'ffmpeg': 4}
|
||||||
hostname = None
|
|
||||||
port = 8080
|
|
||||||
client_mode = False
|
|
||||||
server_hostname = None
|
|
||||||
|
|
||||||
last_saved_counts = {}
|
last_saved_counts = {}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_to_render_queue(cls, render_job, force_start=False, client=None):
|
def add_to_render_queue(cls, render_job, force_start=False):
|
||||||
|
logger.debug('Adding priority {} job to render queue: {}'.format(render_job.priority, render_job))
|
||||||
if not client or render_job.client == cls.hostname:
|
cls.job_queue.append(render_job)
|
||||||
logger.debug('Adding priority {} job to render queue: {}'.format(render_job.priority, render_job))
|
if force_start:
|
||||||
render_job.client = cls.hostname
|
cls.start_job(render_job)
|
||||||
cls.job_queue.append(render_job)
|
cls.session.add(render_job)
|
||||||
if force_start:
|
cls.save_state()
|
||||||
cls.start_job(render_job)
|
|
||||||
cls.session.add(render_job)
|
|
||||||
cls.save_state()
|
|
||||||
else:
|
|
||||||
# todo: implement client rendering
|
|
||||||
logger.warning('remote client rendering not implemented yet')
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def all_jobs(cls):
|
def all_jobs(cls):
|
||||||
@@ -169,75 +134,3 @@ class RenderQueue:
|
|||||||
for job_status in RenderStatus:
|
for job_status in RenderStatus:
|
||||||
job_counts[job_status.value] = len(cls.jobs_with_status(job_status))
|
job_counts[job_status.value] = len(cls.jobs_with_status(job_status))
|
||||||
return job_counts
|
return job_counts
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def status(cls):
|
|
||||||
return {"timestamp": datetime.now().isoformat(),
|
|
||||||
"platform": platform.platform(),
|
|
||||||
"cpu_percent": psutil.cpu_percent(percpu=False),
|
|
||||||
"cpu_percent_per_cpu": psutil.cpu_percent(percpu=True),
|
|
||||||
"cpu_count": psutil.cpu_count(),
|
|
||||||
"memory_total": psutil.virtual_memory().total,
|
|
||||||
"memory_available": psutil.virtual_memory().available,
|
|
||||||
"memory_percent": psutil.virtual_memory().percent,
|
|
||||||
"job_counts": cls.job_counts(),
|
|
||||||
"host_name": cls.hostname
|
|
||||||
}
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def render_clients(cls):
|
|
||||||
all_clients = cls.session.query(RenderClient).all()
|
|
||||||
if not all_clients:
|
|
||||||
cls.session.add(RenderClient(hostname=cls.hostname))
|
|
||||||
cls.save_state()
|
|
||||||
all_clients = cls.session.query(RenderClient).all()
|
|
||||||
return all_clients
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def client_with_hostname(cls, hostname):
|
|
||||||
return cls.session.query(RenderClient).filter(RenderClient.hostname == hostname).first()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def register_client(cls, hostname):
|
|
||||||
new_client = None
|
|
||||||
err_msg = None
|
|
||||||
|
|
||||||
if hostname == cls.hostname:
|
|
||||||
err_msg = "Cannot register same hostname as server"
|
|
||||||
elif cls.client_with_hostname(hostname):
|
|
||||||
err_msg = f"Client '{hostname}' already registered"
|
|
||||||
else:
|
|
||||||
new_client = RenderClient(hostname=hostname)
|
|
||||||
if not new_client.is_available():
|
|
||||||
cls.session.add(new_client)
|
|
||||||
logger.info(f"Client '{hostname}' successfully registered")
|
|
||||||
cls.save_state()
|
|
||||||
else:
|
|
||||||
err_msg = f"Cannot connect to client at hostname: {hostname}"
|
|
||||||
|
|
||||||
if err_msg:
|
|
||||||
logger.warning(err_msg)
|
|
||||||
return err_msg, 400
|
|
||||||
else:
|
|
||||||
return new_client.hostname
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def unregister_client(cls, hostname):
|
|
||||||
success = False
|
|
||||||
client = cls.client_with_hostname(hostname)
|
|
||||||
if client and hostname != cls.hostname:
|
|
||||||
cls.session.delete(client)
|
|
||||||
cls.save_state()
|
|
||||||
logger.info(f"Client '{hostname}' successfully unregistered")
|
|
||||||
success = True
|
|
||||||
return str(success)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def is_client_available(client_hostname, timeout=3):
|
|
||||||
try:
|
|
||||||
response = requests.get(f"http://{client_hostname}:8080/api/status", timeout=timeout)
|
|
||||||
if response.ok:
|
|
||||||
return True
|
|
||||||
except requests.ConnectionError as e:
|
|
||||||
pass
|
|
||||||
return False
|
|
||||||
|
|||||||
@@ -3,28 +3,27 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import platform
|
||||||
import shutil
|
import shutil
|
||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import zipfile
|
import zipfile
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from urllib.request import urlretrieve
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
import json2html
|
import json2html
|
||||||
import requests
|
import psutil
|
||||||
import yaml
|
import yaml
|
||||||
from flask import Flask, request, render_template, send_file, after_this_request, Response, redirect, url_for, abort
|
from flask import Flask, request, render_template, send_file, after_this_request, Response, redirect, url_for, abort
|
||||||
from urllib.parse import urlparse
|
|
||||||
from urllib.request import urlretrieve
|
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
from lib.server.zeroconf_server import ZeroconfServer
|
|
||||||
from lib.render_queue import RenderQueue, JobNotFoundError
|
from lib.render_queue import RenderQueue, JobNotFoundError
|
||||||
from lib.render_workers.worker_factory import RenderWorkerFactory
|
from lib.workers.base_worker import string_to_status, RenderStatus
|
||||||
from lib.render_workers.base_worker import string_to_status, RenderStatus
|
from lib.workers.worker_factory import RenderWorkerFactory
|
||||||
|
from lib.server.zeroconf_server import ZeroconfServer
|
||||||
from lib.utilities.server_helper import generate_thumbnail_for_job
|
from lib.utilities.server_helper import generate_thumbnail_for_job
|
||||||
from lib.server.server_proxy import RenderServerProxy
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
server = Flask(__name__, template_folder='templates', static_folder='static')
|
server = Flask(__name__, template_folder='templates', static_folder='static')
|
||||||
@@ -55,8 +54,8 @@ def index():
|
|||||||
presets = yaml.load(f, Loader=yaml.FullLoader)
|
presets = yaml.load(f, Loader=yaml.FullLoader)
|
||||||
|
|
||||||
return render_template('index.html', all_jobs=sorted_jobs(RenderQueue.all_jobs()),
|
return render_template('index.html', all_jobs=sorted_jobs(RenderQueue.all_jobs()),
|
||||||
hostname=RenderQueue.hostname, renderer_info=renderer_info(),
|
hostname=server.config['HOSTNAME'], renderer_info=renderer_info(),
|
||||||
render_clients=render_clients(), preset_list=presets)
|
render_clients=[server.config['HOSTNAME']], preset_list=presets)
|
||||||
|
|
||||||
|
|
||||||
@server.get('/api/jobs')
|
@server.get('/api/jobs')
|
||||||
@@ -85,7 +84,7 @@ def job_detail(job_id):
|
|||||||
media_basename = os.path.basename(found_job.file_list()[0])
|
media_basename = os.path.basename(found_job.file_list()[0])
|
||||||
media_url = f"/api/job/{job_id}/file/{media_basename}"
|
media_url = f"/api/job/{job_id}/file/{media_basename}"
|
||||||
return render_template('details.html', detail_table=table_html, media_url=media_url,
|
return render_template('details.html', detail_table=table_html, media_url=media_url,
|
||||||
hostname=RenderQueue.hostname, job_status=found_job.status.value.title(),
|
hostname=server.config['HOSTNAME'], job_status=found_job.status.value.title(),
|
||||||
job=found_job, renderer_info=renderer_info())
|
job=found_job, renderer_info=renderer_info())
|
||||||
|
|
||||||
|
|
||||||
@@ -210,23 +209,6 @@ def download_all(job_id):
|
|||||||
return f'Cannot find project files for job {job_id}', 500
|
return f'Cannot find project files for job {job_id}', 500
|
||||||
|
|
||||||
|
|
||||||
@server.post('/api/register_client')
|
|
||||||
def register_client():
|
|
||||||
client_hostname = request.values['hostname']
|
|
||||||
return RenderQueue.register_client(client_hostname)
|
|
||||||
|
|
||||||
|
|
||||||
@server.post('/api/unregister_client')
|
|
||||||
def unregister_client():
|
|
||||||
client_hostname = request.values['hostname']
|
|
||||||
return RenderQueue.unregister_client(client_hostname)
|
|
||||||
|
|
||||||
|
|
||||||
@server.get('/api/clients')
|
|
||||||
def render_clients():
|
|
||||||
return [c.hostname for c in RenderQueue.render_clients()]
|
|
||||||
|
|
||||||
|
|
||||||
@server.get('/api/presets')
|
@server.get('/api/presets')
|
||||||
def presets():
|
def presets():
|
||||||
with open('config/presets.yaml') as f:
|
with open('config/presets.yaml') as f:
|
||||||
@@ -239,22 +221,10 @@ def full_status():
|
|||||||
full_results = {'timestamp': datetime.now().isoformat(), 'servers': {}}
|
full_results = {'timestamp': datetime.now().isoformat(), 'servers': {}}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for client_hostname in render_clients():
|
snapshot_results = snapshot()
|
||||||
is_online = False
|
server_data = {'status': snapshot_results.get('status', {}), 'jobs': snapshot_results.get('jobs', {}),
|
||||||
if client_hostname == RenderQueue.hostname:
|
'is_online': True}
|
||||||
snapshot_results = snapshot()
|
full_results['servers'][server.config['HOSTNAME']] = server_data
|
||||||
is_online = True
|
|
||||||
else:
|
|
||||||
snapshot_results = {}
|
|
||||||
try:
|
|
||||||
snapshot_request = requests.get(f'http://{client_hostname}:8080/snapshot', timeout=1)
|
|
||||||
snapshot_results = snapshot_request.json()
|
|
||||||
is_online = snapshot_request.ok
|
|
||||||
except requests.ConnectionError as e:
|
|
||||||
pass
|
|
||||||
server_data = {'status': snapshot_results.get('status', {}), 'jobs': snapshot_results.get('jobs', {}),
|
|
||||||
'is_online': is_online}
|
|
||||||
full_results['servers'][client_hostname] = server_data
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Exception fetching full status: {e}")
|
logger.error(f"Exception fetching full status: {e}")
|
||||||
|
|
||||||
@@ -263,7 +233,7 @@ def full_status():
|
|||||||
|
|
||||||
@server.get('/api/snapshot')
|
@server.get('/api/snapshot')
|
||||||
def snapshot():
|
def snapshot():
|
||||||
server_status = RenderQueue.status()
|
server_status = status()
|
||||||
server_jobs = [x.json() for x in RenderQueue.all_jobs()]
|
server_jobs = [x.json() for x in RenderQueue.all_jobs()]
|
||||||
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
|
||||||
@@ -385,7 +355,7 @@ def add_job_handler():
|
|||||||
input_path=loaded_project_local_path,
|
input_path=loaded_project_local_path,
|
||||||
output_path=job["output_path"],
|
output_path=job["output_path"],
|
||||||
args=job.get('args', {}))
|
args=job.get('args', {}))
|
||||||
render_job.client = job.get('client', None) or RenderQueue.hostname
|
render_job.client = server.config['HOSTNAME']
|
||||||
render_job.owner = job.get("owner", None)
|
render_job.owner = job.get("owner", None)
|
||||||
render_job.name = job.get("name", None)
|
render_job.name = job.get("name", None)
|
||||||
render_job.priority = int(job.get('priority', render_job.priority))
|
render_job.priority = int(job.get('priority', render_job.priority))
|
||||||
@@ -476,7 +446,18 @@ def clear_history():
|
|||||||
|
|
||||||
@server.route('/api/status')
|
@server.route('/api/status')
|
||||||
def status():
|
def status():
|
||||||
return RenderQueue.status()
|
return {"timestamp": datetime.now().isoformat(),
|
||||||
|
"platform": platform.platform(),
|
||||||
|
"cpu_percent": psutil.cpu_percent(percpu=False),
|
||||||
|
"cpu_percent_per_cpu": psutil.cpu_percent(percpu=True),
|
||||||
|
"cpu_count": psutil.cpu_count(),
|
||||||
|
"memory_total": psutil.virtual_memory().total,
|
||||||
|
"memory_available": psutil.virtual_memory().available,
|
||||||
|
"memory_percent": psutil.virtual_memory().percent,
|
||||||
|
"job_counts": RenderQueue.job_counts(),
|
||||||
|
"hostname": server.config['HOSTNAME'],
|
||||||
|
"port": server.config['PORT']
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@server.get('/api/renderer_info')
|
@server.get('/api/renderer_info')
|
||||||
@@ -495,8 +476,7 @@ def renderer_info():
|
|||||||
|
|
||||||
@server.route('/upload')
|
@server.route('/upload')
|
||||||
def upload_file_page():
|
def upload_file_page():
|
||||||
return render_template('upload.html', render_clients=render_clients(),
|
return render_template('upload.html', supported_renderers=RenderWorkerFactory.supported_renderers())
|
||||||
supported_renderers=RenderWorkerFactory.supported_renderers())
|
|
||||||
|
|
||||||
|
|
||||||
def start_server(background_thread=False):
|
def start_server(background_thread=False):
|
||||||
@@ -511,15 +491,17 @@ def start_server(background_thread=False):
|
|||||||
logging.basicConfig(format='%(asctime)s: %(levelname)s: %(module)s: %(message)s', datefmt='%d-%b-%y %H:%M:%S',
|
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())
|
level=config.get('server_log_level', 'INFO').upper())
|
||||||
|
|
||||||
|
# get hostname
|
||||||
|
local_hostname = socket.gethostname()
|
||||||
|
local_hostname = local_hostname + (".local" if not local_hostname.endswith(".local") else "")
|
||||||
|
|
||||||
|
# load flask settings
|
||||||
|
server.config['HOSTNAME'] = local_hostname
|
||||||
|
server.config['PORT'] = int(config.get('port_number', 8080))
|
||||||
server.config['UPLOAD_FOLDER'] = os.path.expanduser(config['upload_folder'])
|
server.config['UPLOAD_FOLDER'] = os.path.expanduser(config['upload_folder'])
|
||||||
server.config['THUMBS_FOLDER'] = os.path.join(os.path.expanduser(config['upload_folder']), 'thumbs')
|
server.config['THUMBS_FOLDER'] = os.path.join(os.path.expanduser(config['upload_folder']), 'thumbs')
|
||||||
server.config['MAX_CONTENT_PATH'] = config['max_content_path']
|
server.config['MAX_CONTENT_PATH'] = config['max_content_path']
|
||||||
|
|
||||||
# Get hostname and render clients
|
|
||||||
local_hostname = socket.gethostname()
|
|
||||||
RenderQueue.hostname = local_hostname + (".local" if not local_hostname.endswith(".local") else "")
|
|
||||||
server.config['HOSTNAME'] = RenderQueue.hostname
|
|
||||||
|
|
||||||
# disable most Flask logging
|
# disable most Flask logging
|
||||||
flask_log = logging.getLogger('werkzeug')
|
flask_log = logging.getLogger('werkzeug')
|
||||||
flask_log.setLevel(config.get('flask_log_level', 'ERROR').upper())
|
flask_log.setLevel(config.get('flask_log_level', 'ERROR').upper())
|
||||||
@@ -530,19 +512,18 @@ def start_server(background_thread=False):
|
|||||||
thread = threading.Thread(target=eval_loop, kwargs={'delay_sec': config.get('queue_eval_seconds', 1)}, daemon=True)
|
thread = threading.Thread(target=eval_loop, kwargs={'delay_sec': config.get('queue_eval_seconds', 1)}, daemon=True)
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
logging.info(f"Starting Zordon Render Server - Hostname: '{RenderQueue.hostname}'")
|
logging.info(f"Starting Zordon Render Server - Hostname: '{server.config['HOSTNAME']}:'")
|
||||||
|
zeroconf_server = ZeroconfServer("_zordon._tcp.local.", server.config['HOSTNAME'], server.config['PORT'])
|
||||||
zeroconf_server = ZeroconfServer("_zordon._tcp.local.", RenderQueue.hostname, RenderQueue.port)
|
|
||||||
zeroconf_server.start()
|
zeroconf_server.start()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if background_thread:
|
if background_thread:
|
||||||
server_thread = threading.Thread(
|
server_thread = threading.Thread(
|
||||||
target=lambda: server.run(host='0.0.0.0', port=RenderQueue.port, debug=False, use_reloader=False))
|
target=lambda: server.run(host='0.0.0.0', port=server.config['PORT'], debug=False, use_reloader=False))
|
||||||
server_thread.start()
|
server_thread.start()
|
||||||
server_thread.join()
|
server_thread.join()
|
||||||
else:
|
else:
|
||||||
server.run(host='0.0.0.0', port=RenderQueue.port, debug=config.get('flask_debug_enable', False),
|
server.run(host='0.0.0.0', port=server.config['PORT'], debug=config.get('flask_debug_enable', False),
|
||||||
use_reloader=False, threaded=True)
|
use_reloader=False, threaded=True)
|
||||||
finally:
|
finally:
|
||||||
zeroconf_server.stop()
|
zeroconf_server.stop()
|
||||||
@@ -4,7 +4,7 @@ import json
|
|||||||
import requests
|
import requests
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
from lib.render_workers.base_worker import RenderStatus
|
from lib.workers.base_worker import RenderStatus
|
||||||
from requests_toolbelt.multipart import MultipartEncoder, MultipartEncoderMonitor
|
from requests_toolbelt.multipart import MultipartEncoder, MultipartEncoderMonitor
|
||||||
|
|
||||||
status_colors = {RenderStatus.ERROR: "red", RenderStatus.CANCELLED: 'orange1', RenderStatus.COMPLETED: 'green',
|
status_colors = {RenderStatus.ERROR: "red", RenderStatus.CANCELLED: 'orange1', RenderStatus.COMPLETED: 'green',
|
||||||
@@ -21,7 +21,7 @@ OFFLINE_MAX = 2
|
|||||||
class RenderServerProxy:
|
class RenderServerProxy:
|
||||||
|
|
||||||
def __init__(self, hostname, server_port="8080"):
|
def __init__(self, hostname, server_port="8080"):
|
||||||
self._hostname = hostname
|
self.hostname = hostname
|
||||||
self.port = server_port
|
self.port = server_port
|
||||||
self.fetched_status_data = None
|
self.fetched_status_data = None
|
||||||
self.__jobs_cache_token = None
|
self.__jobs_cache_token = None
|
||||||
@@ -31,15 +31,6 @@ class RenderServerProxy:
|
|||||||
self.__offline_flags = 0
|
self.__offline_flags = 0
|
||||||
self.update_cadence = 5
|
self.update_cadence = 5
|
||||||
|
|
||||||
@property
|
|
||||||
def hostname(self):
|
|
||||||
return self._hostname
|
|
||||||
|
|
||||||
@hostname.setter
|
|
||||||
def hostname(self, value):
|
|
||||||
self._hostname = value
|
|
||||||
self.__jobs_cache_token = None
|
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
status = self.request_data('status')
|
status = self.request_data('status')
|
||||||
return status
|
return status
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import ffmpeg # todo: remove all references to ffmpeg library and instead use direct subprocesses
|
import ffmpeg # todo: remove all references to ffmpeg library and instead use direct subprocesses
|
||||||
from ..render_engines.ffmpeg_engine import FFMPEG
|
from ..engines.ffmpeg_engine import FFMPEG
|
||||||
|
|
||||||
|
|
||||||
def file_info(path):
|
def file_info(path):
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import threading
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
from .ffmpeg_helper import generate_thumbnail, save_first_frame
|
from .ffmpeg_helper import generate_thumbnail, save_first_frame
|
||||||
from lib.render_workers.base_worker import RenderStatus
|
from lib.workers.base_worker import RenderStatus
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import re
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from .base_worker import *
|
from .base_worker import *
|
||||||
from ..render_engines.aerender_engine import AERender
|
from ..engines.aerender_engine import AERender
|
||||||
|
|
||||||
def aerender_path():
|
def aerender_path():
|
||||||
paths = glob.glob('/Applications/*After Effects*/aerender')
|
paths = glob.glob('/Applications/*After Effects*/aerender')
|
||||||
@@ -6,7 +6,7 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
from base_worker import *
|
from base_worker import *
|
||||||
|
|
||||||
from ..render_engines.blender_engine import Blender
|
from ..engines.blender_engine import Blender
|
||||||
|
|
||||||
|
|
||||||
class BlenderRenderWorker(BaseRenderWorker):
|
class BlenderRenderWorker(BaseRenderWorker):
|
||||||
@@ -30,9 +30,9 @@ class BlenderRenderWorker(BaseRenderWorker):
|
|||||||
|
|
||||||
# Scene Info
|
# Scene Info
|
||||||
self.scene_info = Blender.get_scene_info(input_path)
|
self.scene_info = Blender.get_scene_info(input_path)
|
||||||
self.total_frames = (int(self.scene_info.get('frame_end', 0)) - int(self.scene_info.get('frame_start', 0)) + 1) \
|
self.total_frames = (int(self.scene_info.get('frame_end', 1)) - int(self.scene_info.get('frame_start', 1)) + 1) \
|
||||||
if self.render_all_frames else 1
|
if self.render_all_frames else 1
|
||||||
self.current_frame = int(self.scene_info.get('frame_start', 0))
|
self.current_frame = int(self.scene_info.get('frame_start', 1))
|
||||||
|
|
||||||
def generate_worker_subprocess(self):
|
def generate_worker_subprocess(self):
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ class BlenderRenderWorker(BaseRenderWorker):
|
|||||||
time_elapsed, time_remaining))
|
time_elapsed, time_remaining))
|
||||||
elif "file doesn't exist" in line.lower():
|
elif "file doesn't exist" in line.lower():
|
||||||
self.log_error(line, halt_render=True)
|
self.log_error(line, halt_render=True)
|
||||||
elif 'error' in line.lower():
|
elif line.lower().startswith('error'):
|
||||||
self.log_error(line)
|
self.log_error(line)
|
||||||
elif 'Saved' in line or 'Saving' in line or 'quit' in line:
|
elif 'Saved' in line or 'Saving' in line or 'quit' in line:
|
||||||
match = re.match(r'Time: (.*) \(Saving', line)
|
match = re.match(r'Time: (.*) \(Saving', line)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import re
|
import re
|
||||||
from .base_worker import *
|
from .base_worker import *
|
||||||
from ..render_engines.ffmpeg_engine import FFMPEG
|
from ..engines.ffmpeg_engine import FFMPEG
|
||||||
|
|
||||||
|
|
||||||
class FFMPEGRenderWorker(BaseRenderWorker):
|
class FFMPEGRenderWorker(BaseRenderWorker):
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from lib.server.job_server import start_server
|
from lib.server.api_server import start_server
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
start_server()
|
start_server()
|
||||||
|
|||||||
Reference in New Issue
Block a user