diff options
Diffstat (limited to 'release/io/netrender')
-rw-r--r-- | release/io/netrender/__init__.py | 17 | ||||
-rw-r--r-- | release/io/netrender/client.py | 204 | ||||
-rw-r--r-- | release/io/netrender/master.py | 615 | ||||
-rw-r--r-- | release/io/netrender/model.py | 162 | ||||
-rw-r--r-- | release/io/netrender/operators.py | 236 | ||||
-rw-r--r-- | release/io/netrender/slave.py | 169 | ||||
-rw-r--r-- | release/io/netrender/ui.py | 283 | ||||
-rw-r--r-- | release/io/netrender/utils.py | 61 |
8 files changed, 0 insertions, 1747 deletions
diff --git a/release/io/netrender/__init__.py b/release/io/netrender/__init__.py deleted file mode 100644 index 1eb91abb938..00000000000 --- a/release/io/netrender/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# This directory is a Python package. - -import model -import operators -import client -import slave -import master -import utils -import ui - -# store temp data in bpy module - -import bpy - -bpy.data.netrender_jobs = [] -bpy.data.netrender_slaves = [] -bpy.data.netrender_blacklist = []
\ No newline at end of file diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py deleted file mode 100644 index 0c60bd1603c..00000000000 --- a/release/io/netrender/client.py +++ /dev/null @@ -1,204 +0,0 @@ -import bpy -import sys, os -import http, http.client, http.server, urllib -import subprocess, shutil, time, hashlib - -import netrender.slave as slave -import netrender.master as master -from netrender.utils import * - - -def clientSendJob(conn, scene, anim = False, chunks = 5): - netsettings = scene.network_render - job = netrender.model.RenderJob() - - if anim: - for f in range(scene.start_frame, scene.end_frame + 1): - job.addFrame(f) - else: - job.addFrame(scene.current_frame) - - filename = bpy.data.filename - job.addFile(filename) - - job_name = netsettings.job_name - path, name = os.path.split(filename) - if job_name == "[default]": - job_name = name - - ########################### - # LIBRARIES - ########################### - for lib in bpy.data.libraries: - lib_path = lib.filename - - if lib_path.startswith("//"): - lib_path = path + os.sep + lib_path[2:] - - job.addFile(lib_path) - - ########################### - # POINT CACHES - ########################### - - root, ext = os.path.splitext(name) - cache_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that - - if os.path.exists(cache_path): - caches = {} - pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)_[0-9]+\.bphys") - for cache_file in sorted(os.listdir(cache_path)): - match = pattern.match(cache_file) - - if match: - cache_id = match.groups()[0] - cache_frame = int(match.groups()[1]) - - cache_files = caches.get(cache_id, []) - cache_files.append((cache_frame, cache_file)) - caches[cache_id] = cache_files - - for cache in caches.values(): - cache.sort() - - if len(cache) == 1: - cache_frame, cache_file = cache[0] - job.addFile(cache_path + cache_file, cache_frame, cache_frame) - else: - for i in range(len(cache)): - current_item = cache[i] - next_item = cache[i+1] if i + 1 < len(cache) else None - previous_item = cache[i - 1] if i > 0 else None - - current_frame, current_file = current_item - - if not next_item and not previous_item: - job.addFile(cache_path + current_file, current_frame, current_frame) - elif next_item and not previous_item: - next_frame = next_item[0] - job.addFile(cache_path + current_file, current_frame, next_frame - 1) - elif not next_item and previous_item: - previous_frame = previous_item[0] - job.addFile(cache_path + current_file, previous_frame + 1, current_frame) - else: - next_frame = next_item[0] - previous_frame = previous_item[0] - job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1) - - ########################### - # IMAGES - ########################### - for image in bpy.data.images: - if image.source == "FILE" and not image.packed_file: - job.addFile(image.filename) - - # print(job.files) - - job.name = job_name - - for slave in scene.network_render.slaves_blacklist: - job.blacklist.append(slave.id) - - job.chunks = netsettings.chunks - job.priority = netsettings.priority - - # try to send path first - conn.request("POST", "job", repr(job.serialize())) - response = conn.getresponse() - - job_id = response.getheader("job-id") - - # if not ACCEPTED (but not processed), send files - if response.status == http.client.ACCEPTED: - for filepath in job.files: - f = open(filepath, "rb") - conn.request("PUT", "file", f, headers={"job-id": job_id, "job-file": filepath}) - f.close() - response = conn.getresponse() - - # server will reply with NOT_FOUD until all files are found - - return job_id - -def clientRequestResult(conn, scene, job_id): - conn.request("GET", "render", headers={"job-id": job_id, "job-frame":str(scene.current_frame)}) - -class NetworkRenderEngine(bpy.types.RenderEngine): - __idname__ = 'NET_RENDER' - __label__ = "Network Render" - def render(self, scene): - if scene.network_render.mode == "RENDER_CLIENT": - self.render_client(scene) - elif scene.network_render.mode == "RENDER_SLAVE": - self.render_slave(scene) - elif scene.network_render.mode == "RENDER_MASTER": - self.render_master(scene) - else: - print("UNKNOWN OPERATION MODE") - - def render_master(self, scene): - server_address = (scene.network_render.server_address, scene.network_render.server_port) - httpd = master.RenderMasterServer(server_address, master.RenderHandler, scene.network_render.path) - httpd.timeout = 1 - httpd.stats = self.update_stats - while not self.test_break(): - httpd.handle_request() - - def render_slave(self, scene): - slave.render_slave(self, scene) - - def render_client(self, scene): - netsettings = scene.network_render - self.update_stats("", "Network render client initiation") - - conn = clientConnection(scene) - - if conn: - # Sending file - - self.update_stats("", "Network render exporting") - - job_id = netsettings.job_id - - # reading back result - - self.update_stats("", "Network render waiting for results") - - clientRequestResult(conn, scene, job_id) - response = conn.getresponse() - - if response.status == http.client.NO_CONTENT: - netsettings.job_id = clientSendJob(conn, scene) - clientRequestResult(conn, scene, job_id) - - while response.status == http.client.ACCEPTED and not self.test_break(): - print("waiting") - time.sleep(1) - clientRequestResult(conn, scene, job_id) - response = conn.getresponse() - - if response.status != http.client.OK: - conn.close() - return - - r = scene.render_data - x= int(r.resolution_x*r.resolution_percentage*0.01) - y= int(r.resolution_y*r.resolution_percentage*0.01) - - f = open(netsettings.path + "output.exr", "wb") - buf = response.read(1024) - - while buf: - f.write(buf) - buf = response.read(1024) - - f.close() - - result = self.begin_result(0, 0, x, y) - result.load_from_file(netsettings.path + "output.exr", 0, 0) - self.end_result(result) - - conn.close() - -bpy.types.register(NetworkRenderEngine) - diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py deleted file mode 100644 index 78e9243bc9d..00000000000 --- a/release/io/netrender/master.py +++ /dev/null @@ -1,615 +0,0 @@ -import sys, os -import http, http.client, http.server, urllib -import subprocess, shutil, time, hashlib - -from netrender.utils import * -import netrender.model - -JOB_WAITING = 0 # before all data has been entered -JOB_PAUSED = 1 # paused by user -JOB_QUEUED = 2 # ready to be dispatched - -class MRenderFile: - def __init__(self, filepath, start, end): - self.filepath = filepath - self.start = start - self.end = end - self.found = False - - def test(self): - self.found = os.path.exists(self.filepath) - return self.found - - -class MRenderSlave(netrender.model.RenderSlave): - def __init__(self, name, address, stats): - super().__init__() - self.id = hashlib.md5(bytes(repr(name) + repr(address), encoding='utf8')).hexdigest() - self.name = name - self.address = address - self.stats = stats - self.last_seen = time.time() - - self.job = None - self.frame = None - - netrender.model.RenderSlave._slave_map[self.id] = self - - def seen(self): - self.last_seen = time.time() - -# sorting key for jobs -def groupKey(job): - return (job.status, job.framesLeft() > 0, job.priority, job.credits) - -class MRenderJob(netrender.model.RenderJob): - def __init__(self, job_id, name, files, chunks = 1, priority = 1, credits = 100.0, blacklist = []): - super().__init__() - self.id = job_id - self.name = name - self.files = files - self.frames = [] - self.chunks = chunks - self.priority = priority - self.credits = credits - self.blacklist = blacklist - self.last_dispatched = time.time() - - # special server properties - self.save_path = "" - self.files_map = {path: MRenderFile(path, start, end) for path, start, end in files} - self.status = JOB_WAITING - - def save(self): - if self.save_path: - f = open(self.save_path + "job.txt", "w") - f.write(repr(self.serialize())) - f.close() - - def testStart(self): - for f in self.files_map.values(): - if not f.test(): - return False - - self.start() - return True - - def start(self): - self.status = JOB_QUEUED - - def update(self): - self.credits -= 5 # cost of one frame - self.credits += (time.time() - self.last_dispatched) / 60 - self.last_dispatched = time.time() - - def addFrame(self, frame_number): - frame = MRenderFrame(frame_number) - self.frames.append(frame) - return frame - - def framesLeft(self): - total = 0 - for j in self.frames: - if j.status == QUEUED: - total += 1 - - return total - - def reset(self, all): - for f in self.frames: - f.reset(all) - - def getFrames(self): - frames = [] - for f in self.frames: - if f.status == QUEUED: - self.update() - frames.append(f) - if len(frames) >= self.chunks: - break - - return frames - -class MRenderFrame(netrender.model.RenderFrame): - def __init__(self, frame): - super().__init__() - self.number = frame - self.slave = None - self.time = 0 - self.status = QUEUED - - def reset(self, all): - if all or self.status == ERROR: - self.slave = None - self.time = 0 - self.status = QUEUED - - -# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - -class RenderHandler(http.server.BaseHTTPRequestHandler): - def send_head(self, code = http.client.OK, headers = {}): - self.send_response(code) - self.send_header("Content-type", "application/octet-stream") - - for key, value in headers.items(): - self.send_header(key, value) - - self.end_headers() - - def do_HEAD(self): - print(self.path) - - if self.path == "status": - job_id = self.headers.get('job-id', "") - job_frame = int(self.headers.get('job-frame', -1)) - - if job_id: - print("status:", job_id, "\n") - - job = self.server.getJobByID(job_id) - if job: - if job_frame != -1: - frame = job[frame] - - if not frame: - # no such frame - self.send_heat(http.client.NO_CONTENT) - return - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - return - - self.send_head() - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - - def do_GET(self): - print(self.path) - - if self.path == "version": - self.send_head() - self.server.stats("", "New client connection") - self.wfile.write(VERSION) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "render": - job_id = self.headers['job-id'] - job_frame = int(self.headers['job-frame']) - print("render:", job_id, job_frame) - - job = self.server.getJobByID(job_id) - - if job: - frame = job[job_frame] - - if frame: - if frame.status in (QUEUED, DISPATCHED): - self.send_head(http.client.ACCEPTED) - elif frame.status == DONE: - self.server.stats("", "Sending result back to client") - f = open(job.save_path + "%04d" % job_frame + ".exr", 'rb') - - self.send_head() - - shutil.copyfileobj(f, self.wfile) - - f.close() - elif frame.status == ERROR: - self.send_head(http.client.PARTIAL_CONTENT) - else: - # no such frame - self.send_head(http.client.NO_CONTENT) - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "log": - job_id = self.headers['job-id'] - job_frame = int(self.headers['job-frame']) - print("log:", job_id, job_frame) - - job = self.server.getJobByID(job_id) - - if job: - frame = job[job_frame] - - if frame: - if frame.status in (QUEUED, DISPATCHED): - self.send_head(http.client.PROCESSING) - else: - self.server.stats("", "Sending log back to client") - f = open(job.save_path + "%04d" % job_frame + ".log", 'rb') - - self.send_head() - - shutil.copyfileobj(f, self.wfile) - - f.close() - else: - # no such frame - self.send_head(http.client.NO_CONTENT) - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "status": - job_id = self.headers.get('job-id', "") - job_frame = int(self.headers.get('job-frame', -1)) - - if job_id: - print("status:", job_id, "\n") - - job = self.server.getJobByID(job_id) - if job: - if job_frame != -1: - frame = job[frame] - - if frame: - message = frame.serialize() - else: - # no such frame - self.send_heat(http.client.NO_CONTENT) - return - else: - message = job.serialize() - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - return - else: # status of all jobs - message = [] - - for job in self.server: - message.append(job.serialize()) - - self.send_head() - self.wfile.write(bytes(repr(message), encoding='utf8')) - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "job": - self.server.update() - - slave_id = self.headers['slave-id'] - - print("slave-id", slave_id) - - slave = self.server.updateSlave(slave_id) - - if slave: # only if slave id is valid - job, frames = self.server.getNewJob(slave_id) - - if job and frames: - for f in frames: - print("dispatch", f.number) - f.status = DISPATCHED - f.slave = slave - - self.send_head(headers={"job-id": job.id}) - - message = job.serialize(frames) - - self.wfile.write(bytes(repr(message), encoding='utf8')) - - self.server.stats("", "Sending job frame to render node") - else: - # no job available, return error code - self.send_head(http.client.ACCEPTED) - else: # invalid slave id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "file": - slave_id = self.headers['slave-id'] - - slave = self.server.updateSlave(slave_id) - - if slave: # only if slave id is valid - job_id = self.headers['job-id'] - job_file = self.headers['job-file'] - print("job:", job_id, "\n") - print("file:", job_file, "\n") - - job = self.server.getJobByID(job_id) - - if job: - render_file = job.files_map.get(job_file, None) - - if render_file: - self.server.stats("", "Sending file to render node") - f = open(render_file.path, 'rb') - - shutil.copyfileobj(f, self.wfile) - - f.close() - else: - # no such file - self.send_head(http.client.NO_CONTENT) - else: - # no such job id - self.send_head(http.client.NO_CONTENT) - else: # invalid slave id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "slave": - message = [] - - for slave in self.server.slaves: - message.append(slave.serialize()) - - self.send_head() - - self.wfile.write(bytes(repr(message), encoding='utf8')) - - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - def do_POST(self): - print(self.path) - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - if self.path == "job": - print("posting job info") - self.server.stats("", "Receiving job") - - length = int(self.headers['content-length']) - - job_info = netrender.model.RenderJob.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) - - job_id = self.server.nextJobID() - - print(job_info.files) - - job = MRenderJob(job_id, job_info.name, job_info.files, chunks = job_info.chunks, priority = job_info.priority, blacklist = job_info.blacklist) - - for frame in job_info.frames: - frame = job.addFrame(frame.number) - - self.server.addJob(job) - - headers={"job-id": job_id} - - if job.testStart(): - self.send_head(headers=headers) - else: - self.send_head(http.client.ACCEPTED, headers=headers) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "cancel": - job_id = self.headers.get('job-id', "") - if job_id: - print("cancel:", job_id, "\n") - self.server.removeJob(job_id) - else: # cancel all jobs - self.server.clear() - - self.send_head() - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "reset": - job_id = self.headers.get('job-id', "") - job_frame = int(self.headers.get('job-frame', "-1")) - all = bool(self.headers.get('reset-all', "False")) - - job = self.server.getJobByID(job_id) - - if job: - if job_frame != -1: - job[job_frame].reset(all) - else: - job.reset(all) - - self.send_head() - else: # job not found - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "slave": - length = int(self.headers['content-length']) - job_frame_string = self.headers['job-frame'] - - slave_info = netrender.model.RenderSlave.materialize(eval(str(self.rfile.read(length), encoding='utf8'))) - - slave_id = self.server.addSlave(slave_info.name, self.client_address, slave_info.stats) - - self.send_head(headers = {"slave-id": slave_id}) - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - def do_PUT(self): - print(self.path) - - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - if self.path == "file": - print("writing blend file") - self.server.stats("", "Receiving job") - - length = int(self.headers['content-length']) - job_id = self.headers['job-id'] - job_file = self.headers['job-file'] - - job = self.server.getJobByID(job_id) - - if job: - - render_file = job.files_map.get(job_file, None) - - if render_file: - main_file = job.files[0] - - main_path, main_name = os.path.split(main_file) - - if job_file != main_file: - file_path = prefixPath(job.save_path, job_file, main_path) - else: - file_path = job.save_path + main_name - - buf = self.rfile.read(length) - - # add same temp file + renames as slave - - f = open(file_path, "wb") - f.write(buf) - f.close() - del buf - - render_file.path = file_path # set the new path - - if job.testStart(): - self.send_head(headers=headers) - else: - self.send_head(http.client.ACCEPTED, headers=headers) - else: # invalid file - self.send_head(http.client.NO_CONTENT) - else: # job not found - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "render": - print("writing result file") - self.server.stats("", "Receiving render result") - - slave_id = self.headers['slave-id'] - - slave = self.server.updateSlave(slave_id) - - if slave: # only if slave id is valid - job_id = self.headers['job-id'] - - job = self.server.getJobByID(job_id) - - if job: - job_frame = int(self.headers['job-frame']) - job_result = int(self.headers['job-result']) - job_time = float(self.headers['job-time']) - - frame = job[job_frame] - - if job_result == DONE: - length = int(self.headers['content-length']) - buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb') - f.write(buf) - f.close() - - del buf - elif job_result == ERROR: - # blacklist slave on this job on error - job.blacklist.append(slave.id) - - frame.status = job_result - frame.time = job_time - - self.server.updateSlave(self.headers['slave-id']) - - self.send_head() - else: # job not found - self.send_head(http.client.NO_CONTENT) - else: # invalid slave id - self.send_head(http.client.NO_CONTENT) - # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - elif self.path == "log": - print("writing log file") - self.server.stats("", "Receiving log file") - - job_id = self.headers['job-id'] - - job = self.server.getJobByID(job_id) - - if job: - length = int(self.headers['content-length']) - job_frame = int(self.headers['job-frame']) - - buf = self.rfile.read(length) - f = open(job.save_path + "%04d" % job_frame + ".log", 'wb') - f.write(buf) - f.close() - - del buf - - self.server.updateSlave(self.headers['slave-id']) - - self.send_head() - else: # job not found - self.send_head(http.client.NO_CONTENT) - -class RenderMasterServer(http.server.HTTPServer): - def __init__(self, address, handler_class, path): - super().__init__(address, handler_class) - self.jobs = [] - self.jobs_map = {} - self.slaves = [] - self.slaves_map = {} - self.job_id = 0 - self.path = path + "master_" + str(os.getpid()) + os.sep - - if not os.path.exists(self.path): - os.mkdir(self.path) - - def nextJobID(self): - self.job_id += 1 - return str(self.job_id) - - def addSlave(self, name, address, stats): - slave = MRenderSlave(name, address, stats) - self.slaves.append(slave) - self.slaves_map[slave.id] = slave - - return slave.id - - def getSlave(self, slave_id): - return self.slaves_map.get(slave_id, None) - - def updateSlave(self, slave_id): - slave = self.getSlave(slave_id) - if slave: - slave.seen() - - return slave - - def clear(self): - self.jobs_map = {} - self.jobs = [] - - def update(self): - self.jobs.sort(key = groupKey) - - def removeJob(self, id): - job = self.jobs_map.pop(id) - - if job: - self.jobs.remove(job) - - def addJob(self, job): - self.jobs.append(job) - self.jobs_map[job.id] = job - - # create job directory - job.save_path = self.path + "job_" + job.id + os.sep - if not os.path.exists(job.save_path): - os.mkdir(job.save_path) - - job.save() - - def getJobByID(self, id): - return self.jobs_map.get(id, None) - - def __iter__(self): - for job in self.jobs: - yield job - - def getNewJob(self, slave_id): - if self.jobs: - for job in reversed(self.jobs): - if job.status == JOB_QUEUED and job.framesLeft() > 0 and slave_id not in job.blacklist: - return job, job.getFrames() - - return None, None diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py deleted file mode 100644 index 7803ad034a7..00000000000 --- a/release/io/netrender/model.py +++ /dev/null @@ -1,162 +0,0 @@ -import sys, os -import http, http.client, http.server, urllib -import subprocess, shutil, time, hashlib - -from netrender.utils import * - -class RenderSlave: - _slave_map = {} - - def __init__(self): - self.id = "" - self.name = "" - self.address = (0,0) - self.stats = "" - self.total_done = 0 - self.total_error = 0 - self.last_seen = 0.0 - - def serialize(self): - return { - "id": self.id, - "name": self.name, - "address": self.address, - "stats": self.stats, - "total_done": self.total_done, - "total_error": self.total_error, - "last_seen": self.last_seen - } - - @staticmethod - def materialize(data): - if not data: - return None - - slave_id = data["id"] - - if slave_id in RenderSlave._slave_map: - return RenderSlave._slave_map[slave_id] - else: - slave = RenderSlave() - slave.id = slave_id - slave.name = data["name"] - slave.address = data["address"] - slave.stats = data["stats"] - slave.total_done = data["total_done"] - slave.total_error = data["total_error"] - slave.last_seen = data["last_seen"] - - RenderSlave._slave_map[slave_id] = slave - - return slave - -class RenderJob: - def __init__(self): - self.id = "" - self.name = "" - self.files = [] - self.frames = [] - self.chunks = 0 - self.priority = 0 - self.credits = 0 - self.blacklist = [] - self.last_dispatched = 0.0 - - def addFile(self, file_path, start=-1, end=-1): - self.files.append((file_path, start, end)) - - def addFrame(self, frame_number): - frame = RenderFrame(frame_number) - self.frames.append(frame) - return frame - - def __len__(self): - return len(self.frames) - - def framesStatus(self): - results = { - QUEUED: 0, - DISPATCHED: 0, - DONE: 0, - ERROR: 0 - } - - for frame in self.frames: - results[frame.status] += 1 - - return results - - def __contains__(self, frame_number): - for f in self.frames: - if f.number == frame_number: - return True - else: - return False - - def __getitem__(self, frame_number): - for f in self.frames: - if f.number == frame_number: - return f - else: - return None - - def serialize(self, frames = None): - min_frame = min((f.number for f in frames)) if frames else -1 - max_frame = max((f.number for f in frames)) if frames else -1 - return { - "id": self.id, - "name": self.name, - "files": [f for f in self.files if f[1] == -1 or not frames or (f[1] <= min_frame <= f[2] or f[1] <= max_frame <= f[2])], - "frames": [f.serialize() for f in self.frames if not frames or f in frames], - "chunks": self.chunks, - "priority": self.priority, - "credits": self.credits, - "blacklist": self.blacklist, - "last_dispatched": self.last_dispatched - } - - @staticmethod - def materialize(data): - if not data: - return None - - job = RenderJob() - job.id = data["id"] - job.name = data["name"] - job.files = data["files"] - job.frames = [RenderFrame.materialize(f) for f in data["frames"]] - job.chunks = data["chunks"] - job.priority = data["priority"] - job.credits = data["credits"] - job.blacklist = data["blacklist"] - job.last_dispatched = data["last_dispatched"] - - return job - -class RenderFrame: - def __init__(self, number = 0): - self.number = number - self.time = 0 - self.status = QUEUED - self.slave = None - - def serialize(self): - return { - "number": self.number, - "time": self.time, - "status": self.status, - "slave": None if not self.slave else self.slave.serialize() - } - - @staticmethod - def materialize(data): - if not data: - return None - - frame = RenderFrame() - frame.number = data["number"] - frame.time = data["time"] - frame.status = data["status"] - frame.slave = RenderSlave.materialize(data["slave"]) - - return frame diff --git a/release/io/netrender/operators.py b/release/io/netrender/operators.py deleted file mode 100644 index 1c6d89c0043..00000000000 --- a/release/io/netrender/operators.py +++ /dev/null @@ -1,236 +0,0 @@ -import bpy -import sys, os -import http, http.client, http.server, urllib - -from netrender.utils import * -import netrender.client as client -import netrender.model - -class RENDER_OT_netclientsend(bpy.types.Operator): - ''' - Operator documentation text, will be used for the operator tooltip and python docs. - ''' - __idname__ = "render.netclientsend" - __label__ = "Net Render Client Send" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - scene = context.scene - - conn = clientConnection(scene) - - if conn: - # Sending file - scene.network_render.job_id = client.clientSendJob(conn, scene, True) - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -class RENDER_OT_netclientstatus(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientstatus" - __label__ = "Net Render Client Status" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - conn = clientConnection(context.scene) - - if conn: - conn.request("GET", "status") - - response = conn.getresponse() - print( response.status, response.reason ) - - jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8'))) - - while(len(netsettings.jobs) > 0): - netsettings.jobs.remove(0) - - bpy.data.netrender_jobs = [] - - for j in jobs: - bpy.data.netrender_jobs.append(j) - netsettings.jobs.add() - job = netsettings.jobs[-1] - - j.results = j.framesStatus() # cache frame status - - job.name = j.name - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -class RENDER_OT_netclientblacklistslave(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientblacklistslave" - __label__ = "Net Render Client Blacklist Slave" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - - if netsettings.active_slave_index >= 0: - - # deal with data - slave = bpy.data.netrender_slaves.pop(netsettings.active_slave_index) - bpy.data.netrender_blacklist.append(slave) - - # deal with rna - netsettings.slaves_blacklist.add() - netsettings.slaves_blacklist[-1].name = slave.name - - netsettings.slaves.remove(netsettings.active_slave_index) - netsettings.active_slave_index = -1 - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -class RENDER_OT_netclientwhitelistslave(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientwhitelistslave" - __label__ = "Net Render Client Whitelist Slave" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - - if netsettings.active_blacklisted_slave_index >= 0: - - # deal with data - slave = bpy.data.netrender_blacklist.pop(netsettings.active_blacklisted_slave_index) - bpy.data.netrender_slaves.append(slave) - - # deal with rna - netsettings.slaves.add() - netsettings.slaves[-1].name = slave.name - - netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index) - netsettings.active_blacklisted_slave_index = -1 - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - - -class RENDER_OT_netclientslaves(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientslaves" - __label__ = "Net Render Client Slaves" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - return True - - def execute(self, context): - netsettings = context.scene.network_render - conn = clientConnection(context.scene) - - if conn: - conn.request("GET", "slave") - - response = conn.getresponse() - print( response.status, response.reason ) - - slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8'))) - - while(len(netsettings.slaves) > 0): - netsettings.slaves.remove(0) - - bpy.data.netrender_slaves = [] - - for s in slaves: - for i in range(len(bpy.data.netrender_blacklist)): - slave = bpy.data.netrender_blacklist[i] - if slave.id == s.id: - bpy.data.netrender_blacklist[i] = s - netsettings.slaves_blacklist[i].name = s.name - break - else: - bpy.data.netrender_slaves.append(s) - - netsettings.slaves.add() - slave = netsettings.slaves[-1] - slave.name = s.name - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -class RENDER_OT_netclientcancel(bpy.types.Operator): - '''Operator documentation text, will be used for the operator tooltip and python docs.''' - __idname__ = "render.netclientcancel" - __label__ = "Net Render Client Cancel" - - # List of operator properties, the attributes will be assigned - # to the class instance from the operator settings before calling. - - __props__ = [] - - def poll(self, context): - netsettings = context.scene.network_render - return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0 - - def execute(self, context): - netsettings = context.scene.network_render - conn = clientConnection(context.scene) - - if conn: - job = bpy.data.netrender_jobs[netsettings.active_job_index] - - conn.request("POST", "cancel", headers={"job-id":job.id}) - - response = conn.getresponse() - print( response.status, response.reason ) - - return ('FINISHED',) - - def invoke(self, context, event): - return self.execute(context) - -bpy.ops.add(RENDER_OT_netclientsend) -bpy.ops.add(RENDER_OT_netclientstatus) -bpy.ops.add(RENDER_OT_netclientslaves) -bpy.ops.add(RENDER_OT_netclientblacklistslave) -bpy.ops.add(RENDER_OT_netclientwhitelistslave) -bpy.ops.add(RENDER_OT_netclientcancel)
\ No newline at end of file diff --git a/release/io/netrender/slave.py b/release/io/netrender/slave.py deleted file mode 100644 index c12c846231d..00000000000 --- a/release/io/netrender/slave.py +++ /dev/null @@ -1,169 +0,0 @@ -import sys, os -import http, http.client, http.server, urllib -import subprocess, time - -from netrender.utils import * -import netrender.model - -CANCEL_POLL_SPEED = 2 -MAX_TIMEOUT = 10 -INCREMENT_TIMEOUT = 1 - -def slave_Info(): - sysname, nodename, release, version, machine = os.uname() - slave = netrender.model.RenderSlave() - slave.name = nodename - slave.stats = sysname + " " + release + " " + machine - return slave - -def testCancel(conn, job_id): - conn.request("HEAD", "status", headers={"job-id":job_id}) - response = conn.getresponse() - - # cancelled if job isn't found anymore - if response.status == http.client.NO_CONTENT: - return True - else: - return False - -def testFile(conn, JOB_PREFIX, file_path, main_path = None): - job_full_path = prefixPath(JOB_PREFIX, file_path, main_path) - - if not os.path.exists(job_full_path): - temp_path = JOB_PREFIX + "slave.temp.blend" - conn.request("GET", "file", headers={"job-id": job.id, "slave-id":slave_id, "job-file":file_path}) - response = conn.getresponse() - - if response.status != http.client.OK: - return None # file for job not returned by server, need to return an error code to server - - f = open(temp_path, "wb") - buf = response.read(1024) - - while buf: - f.write(buf) - buf = response.read(1024) - - f.close() - - os.renames(temp_path, job_full_path) - - return job_full_path - - -def render_slave(engine, scene): - netsettings = scene.network_render - timeout = 1 - - engine.update_stats("", "Network render node initiation") - - conn = clientConnection(scene) - - if conn: - conn.request("POST", "slave", repr(slave_Info().serialize())) - response = conn.getresponse() - - slave_id = response.getheader("slave-id") - - NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep - if not os.path.exists(NODE_PREFIX): - os.mkdir(NODE_PREFIX) - - while not engine.test_break(): - - conn.request("GET", "job", headers={"slave-id":slave_id}) - response = conn.getresponse() - - if response.status == http.client.OK: - timeout = 1 # reset timeout on new job - - job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8'))) - - JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep - if not os.path.exists(JOB_PREFIX): - os.mkdir(JOB_PREFIX) - - job_path = job.files[0][0] # data in files have format (path, start, end) - main_path, main_file = os.path.split(job_path) - - job_full_path = testFile(conn, JOB_PREFIX, job_path) - print("Fullpath", job_full_path) - print("File:", main_file, "and %i other files" % (len(job.files) - 1,)) - engine.update_stats("", "Render File", main_file, "for job", job.id) - - for file_path, start, end in job.files[1:]: - print("\t", file_path) - testFile(conn, JOB_PREFIX, file_path, main_path) - - frame_args = [] - - for frame in job.frames: - print("frame", frame.number) - frame_args += ["-f", str(frame.number)] - - start_t = time.time() - - process = subprocess.Popen([sys.argv[0], "-b", job_full_path, "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - cancelled = False - stdout = bytes() - run_t = time.time() - while process.poll() == None and not cancelled: - stdout += process.stdout.read(32) - current_t = time.time() - cancelled = engine.test_break() - if current_t - run_t > CANCEL_POLL_SPEED: - if testCancel(conn, job.id): - cancelled = True - else: - run_t = current_t - - if cancelled: - # kill process if needed - if process.poll() == None: - process.terminate() - continue # to next frame - - total_t = time.time() - start_t - - avg_t = total_t / len(job.frames) - - status = process.returncode - - print("status", status) - - headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)} - - if status == 0: # non zero status is error - headers["job-result"] = str(DONE) - for frame in job.frames: - headers["job-frame"] = str(frame.number) - # send result back to server - f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb') - conn.request("PUT", "render", f, headers=headers) - f.close() - response = conn.getresponse() - else: - headers["job-result"] = str(ERROR) - for frame in job.frames: - headers["job-frame"] = str(frame.number) - # send error result back to server - conn.request("PUT", "render", headers=headers) - response = conn.getresponse() - - for frame in job.frames: - headers["job-frame"] = str(frame.number) - # send log in any case - conn.request("PUT", "log", stdout, headers=headers) - response = conn.getresponse() - else: - if timeout < MAX_TIMEOUT: - timeout += INCREMENT_TIMEOUT - - for i in range(timeout): - time.sleep(1) - if engine.test_break(): - conn.close() - return - - conn.close() diff --git a/release/io/netrender/ui.py b/release/io/netrender/ui.py deleted file mode 100644 index 8faabe6ff2d..00000000000 --- a/release/io/netrender/ui.py +++ /dev/null @@ -1,283 +0,0 @@ -import bpy -import sys, os -import http, http.client, http.server, urllib -import subprocess, shutil, time, hashlib - -import netrender.slave as slave -import netrender.master as master - -from netrender.utils import * - -VERSION = b"0.3" - -PATH_PREFIX = "/tmp/" - -QUEUED = 0 -DISPATCHED = 1 -DONE = 2 -ERROR = 3 - -class RenderButtonsPanel(bpy.types.Panel): - __space_type__ = "PROPERTIES" - __region_type__ = "WINDOW" - __context__ = "scene" - # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here - - def poll(self, context): - rd = context.scene.render_data - return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES) - -# Setting panel, use in the scene for now. -class SCENE_PT_network_settings(RenderButtonsPanel): - __label__ = "Network Settings" - COMPAT_ENGINES = set(['NET_RENDER']) - - def draw_header(self, context): - layout = self.layout - scene = context.scene - - def draw(self, context): - layout = self.layout - scene = context.scene - rd = scene.render_data - - layout.active = True - - split = layout.split() - - col = split.column() - - col.itemR(scene.network_render, "mode") - col.itemR(scene.network_render, "server_address") - col.itemR(scene.network_render, "server_port") - col.itemR(scene.network_render, "path") - - if scene.network_render.mode == "RENDER_CLIENT": - col.itemR(scene.network_render, "chunks") - col.itemR(scene.network_render, "priority") - col.itemR(scene.network_render, "job_name") - col.itemO("render.netclientsend", text="send job to server") -bpy.types.register(SCENE_PT_network_settings) - -class SCENE_PT_network_slaves(RenderButtonsPanel): - __label__ = "Slaves Status" - COMPAT_ENGINES = set(['NET_RENDER']) - - def poll(self, context): - scene = context.scene - return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" - - def draw(self, context): - layout = self.layout - - scene = context.scene - netsettings = scene.network_render - - row = layout.row() - row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2) - - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientslaves", icon="ICON_FILE_REFRESH", text="") - subcol.itemO("render.netclientblacklistslave", icon="ICON_ZOOMOUT", text="") - - if len(bpy.data.netrender_slaves) == 0 and len(netsettings.slaves) > 0: - while(len(netsettings.slaves) > 0): - netsettings.slaves.remove(0) - - if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0: - layout.itemS() - - slave = bpy.data.netrender_slaves[netsettings.active_slave_index] - - layout.itemL(text="Name: " + slave.name) - layout.itemL(text="Address: " + slave.address[0]) - layout.itemL(text="Seen: " + time.ctime(slave.last_seen)) - layout.itemL(text="Stats: " + slave.stats) - -bpy.types.register(SCENE_PT_network_slaves) - -class SCENE_PT_network_slaves_blacklist(RenderButtonsPanel): - __label__ = "Slaves Blacklist" - COMPAT_ENGINES = set(['NET_RENDER']) - - def poll(self, context): - scene = context.scene - return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" - - def draw(self, context): - layout = self.layout - - scene = context.scene - netsettings = scene.network_render - - row = layout.row() - row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2) - - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientwhitelistslave", icon="ICON_ZOOMOUT", text="") - - if len(bpy.data.netrender_blacklist) == 0 and len(netsettings.slaves_blacklist) > 0: - while(len(netsettings.slaves_blacklist) > 0): - netsettings.slaves_blacklist.remove(0) - - if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0: - layout.itemS() - - slave = bpy.data.netrender_blacklist[netsettings.active_blacklisted_slave_index] - - layout.itemL(text="Name: " + slave.name) - layout.itemL(text="Address: " + slave.address[0]) - layout.itemL(text="Seen: " + slave.last_seen) - layout.itemL(text="Stats: " + time.ctime(slave.stats)) - -bpy.types.register(SCENE_PT_network_slaves_blacklist) - -class SCENE_PT_network_jobs(RenderButtonsPanel): - __label__ = "Jobs" - COMPAT_ENGINES = set(['NET_RENDER']) - - def poll(self, context): - scene = context.scene - return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT" - - def draw(self, context): - layout = self.layout - - scene = context.scene - netsettings = scene.network_render - - row = layout.row() - row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2) - - col = row.column() - - subcol = col.column(align=True) - subcol.itemO("render.netclientstatus", icon="ICON_FILE_REFRESH", text="") - subcol.itemO("render.netclientcancel", icon="ICON_ZOOMOUT", text="") - - if len(bpy.data.netrender_jobs) == 0 and len(netsettings.jobs) > 0: - while(len(netsettings.jobs) > 0): - netsettings.jobs.remove(0) - - if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0: - layout.itemS() - - job = bpy.data.netrender_jobs[netsettings.active_job_index] - - layout.itemL(text="Name: %s" % job.name) - layout.itemL(text="Length: %04i" % len(job)) - layout.itemL(text="Done: %04i" % job.results[DONE]) - layout.itemL(text="Error: %04i" % job.results[ERROR]) - -bpy.types.register(SCENE_PT_network_jobs) - -class NetRenderSettings(bpy.types.IDPropertyGroup): - pass - -class NetRenderSlave(bpy.types.IDPropertyGroup): - pass - -class NetRenderJob(bpy.types.IDPropertyGroup): - pass - -bpy.types.register(NetRenderSettings) -bpy.types.register(NetRenderSlave) -bpy.types.register(NetRenderJob) - -bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings") - -NetRenderSettings.StringProperty( attr="server_address", - name="Server address", - description="IP or name of the master render server", - maxlen = 128, - default = "127.0.0.1") - -NetRenderSettings.IntProperty( attr="server_port", - name="Server port", - description="port of the master render server", - default = 8000, - min=1, - max=65535) - -NetRenderSettings.StringProperty( attr="path", - name="Path", - description="Path for temporary files", - maxlen = 128, - default = "/tmp/") - -NetRenderSettings.StringProperty( attr="job_name", - name="Job name", - description="Name of the job", - maxlen = 128, - default = "[default]") - -NetRenderSettings.IntProperty( attr="chunks", - name="Chunks", - description="Number of frame to dispatch to each slave in one chunk", - default = 5, - min=1, - max=65535) - -NetRenderSettings.IntProperty( attr="priority", - name="Priority", - description="Priority of the job", - default = 1, - min=1, - max=10) - -NetRenderSettings.StringProperty( attr="job_id", - name="Network job id", - description="id of the last sent render job", - maxlen = 64, - default = "") - -NetRenderSettings.IntProperty( attr="active_slave_index", - name="Index of the active slave", - description="", - default = -1, - min= -1, - max=65535) - -NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index", - name="Index of the active slave", - description="", - default = -1, - min= -1, - max=65535) - -NetRenderSettings.IntProperty( attr="active_job_index", - name="Index of the active job", - description="", - default = -1, - min= -1, - max=65535) - -NetRenderSettings.EnumProperty(attr="mode", - items=( - ("RENDER_CLIENT", "Client", "Act as render client"), - ("RENDER_MASTER", "Master", "Act as render master"), - ("RENDER_SLAVE", "Slave", "Act as render slave"), - ), - name="network mode", - description="mode of operation of this instance", - default="RENDER_CLIENT") - -NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="") -NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="") -NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="") - -NetRenderSlave.StringProperty( attr="name", - name="Name of the slave", - description="", - maxlen = 64, - default = "") - -NetRenderJob.StringProperty( attr="name", - name="Name of the job", - description="", - maxlen = 128, - default = "") diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py deleted file mode 100644 index d1b383f7a97..00000000000 --- a/release/io/netrender/utils.py +++ /dev/null @@ -1,61 +0,0 @@ -import bpy -import sys, os -import re -import http, http.client, http.server, urllib -import subprocess, shutil, time, hashlib - -import netrender.model - -VERSION = b"0.5" - -QUEUED = 0 -DISPATCHED = 1 -DONE = 2 -ERROR = 3 - -def clientConnection(scene): - netrender = scene.network_render - - conn = http.client.HTTPConnection(netrender.server_address, netrender.server_port) - - if clientVerifyVersion(conn): - return conn - else: - conn.close() - return None - -def clientVerifyVersion(conn): - conn.request("GET", "version") - response = conn.getresponse() - - if response.status != http.client.OK: - conn.close() - return False - - server_version = response.read() - - if server_version != VERSION: - print("Incorrect server version!") - print("expected", VERSION, "received", server_version) - return False - - return True - -def prefixPath(prefix_directory, file_path, prefix_path): - if os.path.isabs(file_path): - # if an absolute path, make sure path exists, if it doesn't, use relative local path - full_path = file_path - if not os.path.exists(full_path): - p, n = os.path.split(full_path) - - if main_path and p.startswith(main_path): - directory = prefix_directory + p[len(main_path):] - full_path = directory + n - if not os.path.exists(directory): - os.mkdir(directory) - else: - full_path = prefix_directory + n - else: - full_path = prefix_directory + file_path - - return full_path
\ No newline at end of file |