diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-03-19 04:49:03 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-03-19 04:49:18 +0300 |
commit | 57f376e9465c6b79ebd4409bc30e0b5930dd4140 (patch) | |
tree | 8dc6d5940bc8c39d7979d3b35c19d91f4bb83bf0 /netrender | |
parent | 1338695613af08ae912e6507f0fc89d54577e11a (diff) |
Cleanup: trailing space
Diffstat (limited to 'netrender')
-rw-r--r-- | netrender/baking.py | 32 | ||||
-rw-r--r-- | netrender/balancing.py | 4 | ||||
-rw-r--r-- | netrender/client.py | 62 | ||||
-rw-r--r-- | netrender/master.py | 60 | ||||
-rw-r--r-- | netrender/master_html.py | 146 | ||||
-rw-r--r-- | netrender/model.py | 54 | ||||
-rw-r--r-- | netrender/operators.py | 52 | ||||
-rw-r--r-- | netrender/repath.py | 46 | ||||
-rw-r--r-- | netrender/slave.py | 88 | ||||
-rw-r--r-- | netrender/thumbnail.py | 8 | ||||
-rw-r--r-- | netrender/ui.py | 82 | ||||
-rw-r--r-- | netrender/utils.py | 52 | ||||
-rw-r--r-- | netrender/versioning.py | 36 |
13 files changed, 361 insertions, 361 deletions
diff --git a/netrender/baking.py b/netrender/baking.py index f3a759a4..f595a26b 100644 --- a/netrender/baking.py +++ b/netrender/baking.py @@ -26,14 +26,14 @@ def commandToTask(command): i = command.index("|") ri = command.rindex("|") return (command[:i], command[i+1:ri], command[ri+1:]) - + def taskToCommand(task): return "|".join(task) - + def bake(job, tasks): main_file = job.files[0] job_full_path = main_file.filepath - + task_commands = [] for task in tasks: task_commands.extend(task) @@ -61,34 +61,34 @@ def resultsFromOuput(lines): if match: task_id = int(match.groups()[0]) task_filename = match.groups()[1] - + results.append((task_id, task_filename)) - + return results def bake_cache(obj, point_cache, task_index): if point_cache.is_baked: bpy.ops.ptcache.free_bake({"point_cache": point_cache}) - + point_cache.use_disk_cache = True point_cache.use_external = False - + bpy.ops.ptcache.bake({"point_cache": point_cache}, bake=True) - + results = cache_results(obj, point_cache) - + print() - + for filename in results: print("BAKE FILE[", task_index, "]:", filename) - + def cache_results(obj, point_cache): name = cacheName(obj, point_cache) default_path = cachePath(bpy.data.filepath) cache_path = bpy.path.abspath(point_cache.filepath) if point_cache.use_external else default_path - + index = "%02i" % point_cache.index if os.path.exists(cache_path): @@ -103,9 +103,9 @@ def cache_results(obj, point_cache): cache_files.append(os.path.join(cache_path, cache_file)) cache_files.sort() - + return cache_files - + return [] def process_generic(obj, index, task_index): @@ -143,12 +143,12 @@ if __name__ == "__main__": i = sys.argv.index("--") except: i = 0 - + if i: task_args = sys.argv[i+1:] for i in range(0, len(task_args), 3): bake_type = task_args[i] obj = bpy.data.objects[task_args[i+1]] index = int(task_args[i+2]) - + process_funcs.get(bake_type, process_null)(obj, index, i) diff --git a/netrender/balancing.py b/netrender/balancing.py index b6531604..e60165dd 100644 --- a/netrender/balancing.py +++ b/netrender/balancing.py @@ -174,7 +174,7 @@ class NewJobPriority(PriorityRule): "enabled": self.enabled, "editable": self.editable, "descritpiton":str(self), - "limit": self.limit, + "limit": self.limit, "limit_str":self.str_limit(), "id":self.id() } @@ -215,7 +215,7 @@ class ExcludeQueuedEmptyJob(ExclusionRule): def test(self, job): return job.status != netrender.model.JOB_QUEUED or job.countFrames(status = netrender.model.FRAME_QUEUED) == 0 - + def serialize(self): return { "type": "exception", "enabled": self.enabled, diff --git a/netrender/client.py b/netrender/client.py index 0ad9a1e4..8c5499b6 100644 --- a/netrender/client.py +++ b/netrender/client.py @@ -104,10 +104,10 @@ def fillCommonJobSettings(job, job_name, netsettings): job.render = netsettings.job_render_engine_other else: job.render = netsettings.job_render_engine - + if netsettings.job_tags: job.tags.update(netsettings.job_tags.split(";")) - + if netsettings.job_type == "JOB_BLENDER": job.type = netrender.model.JOB_BLENDER elif netsettings.job_type == "JOB_PROCESS": @@ -133,16 +133,16 @@ def sendJobVCS(conn, scene, anim = False): job.addFrame(scene.frame_current) filename = bpy.data.filepath - + if not filename.startswith(netsettings.vcs_wpath): # this is an error, need better way to handle this return filename = filename[len(netsettings.vcs_wpath):] - + if filename[0] in {os.sep, os.altsep}: filename = filename[1:] - + job.addFile(filename, signed=False) job_name = netsettings.job_name @@ -152,14 +152,14 @@ def sendJobVCS(conn, scene, anim = False): fillCommonJobSettings(job, job_name, netsettings) - + # VCS Specific code job.version_info = netrender.model.VersioningInfo() job.version_info.system = netsettings.vcs_system job.version_info.wpath = netsettings.vcs_wpath job.version_info.rpath = netsettings.vcs_rpath job.version_info.revision = netsettings.vcs_revision - + job.tags.add(netrender.model.TAG_RENDER) # try to send path first @@ -169,7 +169,7 @@ def sendJobVCS(conn, scene, anim = False): response.read() job_id = response.getheader("job-id") - + # a VCS job is always good right now, need error handling return job_id @@ -179,20 +179,20 @@ def sendJobBaking(conn, scene, can_save = True): job = netrender.model.RenderJob() filename = bpy.data.filepath - + if not os.path.exists(filename): raise RuntimeError("Current file path not defined\nSave your file before sending a job") if can_save and netsettings.save_before_job: bpy.ops.wm.save_mainfile(filepath=filename, check_existing=False) - + job.addFile(filename) job_name = netsettings.job_name path, name = os.path.split(filename) if job_name == "[default]": job_name = name - + ############################### # LIBRARIES (needed for baking) ############################### @@ -202,7 +202,7 @@ def sendJobBaking(conn, scene, can_save = True): job.addFile(file_path) tasks = set() - + #################################### # FLUID + POINT CACHE (what we bake) #################################### @@ -213,17 +213,17 @@ def sendJobBaking(conn, scene, can_save = True): else: # owner is modifier index = [index for index, data in enumerate(object.modifiers) if data == owner][0] tasks.add((owner.type, object.name, str(index))) - + def fluidFunc(object, modifier, cache_path): pass - + def multiresFunc(object, modifier, cache_path): pass - + processObjectDependencies(pointCacheFunc, fluidFunc, multiresFunc) fillCommonJobSettings(job, job_name, netsettings) - + job.tags.add(netrender.model.TAG_BAKING) job.subtype = netrender.model.JOB_SUB_BAKING job.chunks = 1 # No chunking for baking @@ -231,7 +231,7 @@ def sendJobBaking(conn, scene, can_save = True): for i, task in enumerate(tasks): job.addFrame(i + 1) job.frames[-1].command = netrender.baking.taskToCommand(task) - + # try to send path first with ConnectionContext(): conn.request("POST", "/job", json.dumps(job.serialize())) @@ -253,7 +253,7 @@ def sendJobBaking(conn, scene, can_save = True): # server will reply with ACCEPTED until all files are found return job_id - + def sendJobBlender(conn, scene, anim = False, can_save = True): netsettings = scene.network_render job = netrender.model.RenderJob() @@ -268,7 +268,7 @@ def sendJobBlender(conn, scene, anim = False, can_save = True): if not os.path.exists(filename): raise RuntimeError("Current file path not defined\nSave your file before sending a job") - + if can_save and netsettings.save_before_job: bpy.ops.wm.save_mainfile(filepath=filename, check_existing=False) @@ -295,7 +295,7 @@ def sendJobBlender(conn, scene, anim = False, can_save = True): file_path = bpy.path.abspath(image.filepath) if os.path.exists(file_path): job.addFile(file_path) - + tex_path = os.path.splitext(file_path)[0] + ".tex" if os.path.exists(tex_path): job.addFile(tex_path) @@ -304,22 +304,22 @@ def sendJobBlender(conn, scene, anim = False, can_save = True): # FLUID + POINT CACHE ########################### default_path = cachePath(filename) - + def pointCacheFunc(object, owner, point_cache): addPointCache(job, object, point_cache, default_path) - + def fluidFunc(object, modifier, cache_path): addFluidFiles(job, cache_path) - + def multiresFunc(object, modifier, cache_path): job.addFile(cache_path) - + processObjectDependencies(pointCacheFunc, fluidFunc, multiresFunc) #print(job.files) fillCommonJobSettings(job, job_name, netsettings) - + job.tags.add(netrender.model.TAG_RENDER) # try to send path first @@ -371,7 +371,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine): address = "" if netsettings.server_address == "[default]" else netsettings.server_address - master.runMaster(address = (address, netsettings.server_port), + master.runMaster(address = (address, netsettings.server_port), broadcast = netsettings.use_master_broadcast, clear = netsettings.use_master_clear, force = netsettings.use_master_force_upload, @@ -405,8 +405,8 @@ class NetworkRenderEngine(bpy.types.RenderEngine): # reading back result self.update_stats("", "Network render waiting for results") - - + + requestResult(conn, job_id, scene.frame_current) response = conn.getresponse() buf = response.read() @@ -419,7 +419,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine): requestResult(conn, job_id, scene.frame_current) response = conn.getresponse() buf = response.read() - + while response.status == http.client.ACCEPTED and not self.test_break(): time.sleep(1) requestResult(conn, job_id, scene.frame_current) @@ -442,9 +442,9 @@ class NetworkRenderEngine(bpy.types.RenderEngine): r = scene.render x= int(r.resolution_x*r.resolution_percentage*0.01) y= int(r.resolution_y*r.resolution_percentage*0.01) - + result_path = os.path.join(bpy.path.abspath(netsettings.path), "output.exr") - + folder = os.path.split(result_path)[0] verifyCreateDir(folder) diff --git a/netrender/master.py b/netrender/master.py index 9b7b72a9..456e436d 100644 --- a/netrender/master.py +++ b/netrender/master.py @@ -38,20 +38,20 @@ class MRenderFile(netrender.model.RenderFile): def updateStatus(self): self.found = os.path.exists(self.filepath) - + if self.found and self.signature != None: found_signature = hashFile(self.filepath) self.found = self.signature == found_signature if not self.found: print("Signature mismatch", self.signature, found_signature) - + return self.found def test(self): # don't check when forcing upload and only until found if not self.force and not self.found: self.updateStatus() - + return self.found @@ -60,7 +60,7 @@ class MRenderSlave(netrender.model.RenderSlave): super().__init__(slave_info) self.id = hashlib.md5(bytes(repr(slave_info.name) + repr(slave_info.address), encoding='utf8')).hexdigest() self.last_seen = time.time() - + self.job = None self.job_frames = [] @@ -97,7 +97,7 @@ class MRenderJob(netrender.model.RenderJob): self.last_update = 0 self.save_path = "" self.files = [MRenderFile(rfile.filepath, rfile.index, rfile.start, rfile.end, rfile.signature) for rfile in job_info.files] - + def setForceUpload(self, force): for rfile in self.files: rfile.force = force @@ -154,7 +154,7 @@ class MRenderJob(netrender.model.RenderJob): def start(self): self.status = netrender.model.JOB_QUEUED - + def addLog(self, frames): frames = sorted(frames) @@ -174,7 +174,7 @@ class MRenderJob(netrender.model.RenderJob): def reset(self, all): for f in self.frames: f.reset(all) - + if all: self.status = netrender.model.JOB_QUEUED @@ -188,7 +188,7 @@ class MRenderJob(netrender.model.RenderJob): break return frames - + def getResultPath(self, filename): return os.path.join(self.save_path, filename) @@ -239,7 +239,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): f.write(buf) f.close() del buf - + def log_message(self, format, *args): # override because the original calls self.address_string(), which # is extremely slow due to some timeout.. @@ -256,7 +256,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"): self.send_response(code) - + if code == http.client.OK and content: self.send_header("Content-type", content) @@ -351,10 +351,10 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if frame.status == netrender.model.FRAME_DONE: for filename in frame.results: filepath = job.getResultPath(filename) - + zfile.write(filepath, filename) - - + + f = open(zip_filepath, 'rb') self.send_head(content = "application/x-zip-compressed") shutil.copyfileobj(f, self.wfile) @@ -577,7 +577,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): job_id = self.server.nextJobID() job = MRenderJob(job_id, job_info) - + job.setForceUpload(self.server.force) for frame in job_info.frames: @@ -728,7 +728,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): self.server.stats("", "New slave connected") slave_info = netrender.model.RenderSlave.materialize(json.loads(str(self.rfile.read(length), encoding='utf8')), cache = False) - + slave_info.address = self.client_address slave_id = self.server.addSlave(slave_info) @@ -790,12 +790,12 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): file_path = os.path.join(job.save_path, main_name) # add same temp file + renames as slave - + self.write_file(file_path) - + rfile.filepath = file_path # set the new path found = rfile.updateStatus() # make sure we have the right file - + if not found: # checksum mismatch self.server.stats("", "File upload but checksum mismatch, this shouldn't happen") self.send_head(http.client.CONFLICT) @@ -882,19 +882,19 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if frame: job_result = int(self.headers['job-result']) job_finished = self.headers['job-finished'] == str(True) - + self.send_head(content = None) if job_result == netrender.model.FRAME_DONE: result_filename = self.headers['result-filename'] - + frame.results.append(result_filename) self.write_file(job.getResultPath(result_filename)) - + if job_finished: job_time = float(self.headers['job-time']) slave.finishedFrame(job_frame) - + frame.status = job_result frame.time = job_time @@ -925,7 +925,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler): if frame: self.send_head(content = None) - + if job.hasRenderResult(): self.write_file(os.path.join(os.path.join(job.save_path, "%06d.jpg" % job_frame))) @@ -996,7 +996,7 @@ class RenderMasterServer(socketserver.ThreadingMixIn, http.server.HTTPServer): def restore(self, jobs, slaves, balancer = None): self.jobs = jobs self.jobs_map = {} - + for job in self.jobs: self.jobs_map[job.id] = job self.job_id = max(self.job_id, int(job.id)) @@ -1004,10 +1004,10 @@ class RenderMasterServer(socketserver.ThreadingMixIn, http.server.HTTPServer): self.slaves = slaves for slave in self.slaves: self.slaves_map[slave.id] = slave - + if balancer: self.balancer = balancer - + def nextJobID(self): self.job_id += 1 @@ -1123,7 +1123,7 @@ class RenderMasterServer(socketserver.ThreadingMixIn, http.server.HTTPServer): and slave.id not in job.blacklist # slave is not blacklisted and (not slave.tags or job.tags.issubset(slave.tags)) # slave doesn't use tags or slave has all job tags ): - + return job, job.getFrames() return None, None @@ -1138,17 +1138,17 @@ def createMaster(address, clear, force, path): print("loading saved master:", filepath) with open(filepath, 'rb') as f: path, jobs, slaves = pickle.load(f) - + httpd = RenderMasterServer(address, RenderHandler, path, force=force, subdir=False) httpd.restore(jobs, slaves) - + return httpd return RenderMasterServer(address, RenderHandler, path, force=force) def saveMaster(path, httpd): filepath = os.path.join(path, "blender_master.data") - + with open(filepath, 'wb') as f: pickle.dump((httpd.path, httpd.jobs, httpd.slaves), f, pickle.HIGHEST_PROTOCOL) diff --git a/netrender/master_html.py b/netrender/master_html.py index e358c7e2..128004d2 100644 --- a/netrender/master_html.py +++ b/netrender/master_html.py @@ -46,8 +46,8 @@ def countFiles(job): elif not file == job.files[0]: tot_other += 1 return tot_cache,tot_fluid,tot_other; - - + + def get(handler): def output(text): handler.wfile.write(bytes(text, encoding='utf8')) @@ -112,11 +112,11 @@ def get(handler): def checkbox(title, value, script=""): return """<input type="checkbox" title="%s" %s %s>""" % (title, "checked" if value else "", ("onclick=\"%s\"" % script) if script else "") - + def sendjson(message): - handler.send_head(content = "application/json") + handler.send_head(content = "application/json") output(json.dumps(message,sort_keys=False)) - + def sendFile(filename,content_type): f = open(os.path.join(src_folder,filename), 'rb') @@ -126,9 +126,9 @@ def get(handler): f.close() # return serialized version of job for html interface # job: the base job - # includeFiles: boolean to indicate if we want file to be serialized too into job - # includeFrames; boolean to indicate if we want frame to be serialized too into job - def gethtmlJobInfo(job,includeFiles=True,includeFrames=True): + # includeFiles: boolean to indicate if we want file to be serialized too into job + # includeFrames; boolean to indicate if we want frame to be serialized too into job + def gethtmlJobInfo(job,includeFiles=True,includeFrames=True): if (job): results = job.framesStatus() serializedJob = job.serialize(withFiles=includeFiles, withFrames=includeFrames) @@ -142,27 +142,27 @@ def get(handler): tot_cache, tot_fluid, tot_other = countFiles(job) serializedJob["totcache"] = tot_cache serializedJob["totfluid"] = tot_fluid - serializedJob["totother"] = tot_other - serializedJob["wktime"] = (time.time()-job.start_time ) if job.status != netrender.model.JOB_FINISHED else (job.finish_time-job.start_time) + serializedJob["totother"] = tot_other + serializedJob["wktime"] = (time.time()-job.start_time ) if job.status != netrender.model.JOB_FINISHED else (job.finish_time-job.start_time) else: serializedJob={"name":"invalid job"} - + return serializedJob; - + # return serialized files based on cumulative file_type # job_id: id of the job # message: serialized content # file_type: any combinaison of CACHE_FILE,FLUID_FILES, OTHER_FILES - + def getFiles(job_id,message,file_type): - + job=handler.server.getJobID(job_id) print ("job.files.length="+str(len(job.files))) - + for file in job.files: filedata=file.serialize() filedata["name"] = os.path.split(file.filepath)[1] - + if file.filepath.endswith(".bphys") and (file_type & CACHE_FILES): message.append(filedata); continue @@ -172,104 +172,104 @@ def get(handler): if (not file == job.files[0]) and (file_type & OTHER_FILES) and (not file.filepath.endswith((".bobj.gz", ".bvel.gz"))) and not file.filepath.endswith(".bphys"): message.append(filedata); continue - - - + + + if handler.path == "/html/netrender.js": sendFile("netrender.js","text/javascript") - + elif handler.path == "/html/netrender.css": sendFile("netrender.css","text/css") - + elif handler.path =="/html/newui": sendFile("newui.html","text/html") - + elif handler.path.startswith("/html/js"): path, filename = os.path.split(handler.path) sendFile("js/"+filename,"text/javascript") - - elif handler.path.startswith("/html/css/images"): + + elif handler.path.startswith("/html/css/images"): path, filename = os.path.split(handler.path) sendFile("css/images/"+filename,"image/png") - + elif handler.path.startswith("/html/css"): path, filename = os.path.split(handler.path) sendFile("css/"+filename,"text/css") - # return all master rules information + # return all master rules information elif handler.path == "/html/rules": message = [] for rule in handler.server.balancer.rules: message.append(rule.serialize()) for rule in handler.server.balancer.priorities: - message.append(rule.serialize()) + message.append(rule.serialize()) for rule in handler.server.balancer.exceptions: message.append(rule.serialize()) sendjson(message) - #return all slaves list + #return all slaves list elif handler.path == "/html/slaves": message = [] for slave in handler.server.slaves: serializedSlave = slave.serialize() if slave.job: serializedSlave["job_name"] = slave.job.name - serializedSlave["job_id"] = slave.job.id + serializedSlave["job_id"] = slave.job.id else: serializedSlave["job_name"] = "None" serializedSlave["job_id"] = "0" message.append(serializedSlave) sendjson(message) - # return all job list + # return all job list elif handler.path == "/html/jobs": message = [] for job in handler.server.jobs: if job: message.append(gethtmlJobInfo(job, False, False)) sendjson(message) - #return a job information + #return a job information elif handler.path.startswith("/html/job_"): - + job_id = handler.path[10:] job = handler.server.getJobID(job_id) - + message = [] if job: - + message.append(gethtmlJobInfo(job, includeFiles=False)) sendjson(message) - # return all frames for a job + # return all frames for a job elif handler.path.startswith("/html/frames_"): - + job_id = handler.path[13:] job = handler.server.getJobID(job_id) - + message = [] if job: for f in job.frames: message.append(f.serialize()) - + sendjson(message) - # return physic cache files + # return physic cache files elif handler.path.startswith("/html/cachefiles_"): job_id = handler.path[17:] message = [] getFiles(job_id, message, CACHE_FILES); - sendjson(message) - #return fluid cache files + sendjson(message) + #return fluid cache files elif handler.path.startswith("/html/fluidfiles_"): job_id = handler.path[17:] - + message = [] getFiles(job_id, message, FLUID_FILES); - sendjson(message) - - #return list of other files ( images, sequences ...) + sendjson(message) + + #return list of other files ( images, sequences ...) elif handler.path.startswith("/html/otherfiles_"): job_id = handler.path[17:] - + message = [] getFiles(job_id, message, OTHER_FILES); - sendjson(message) - # return blend file info + sendjson(message) + # return blend file info elif handler.path.startswith("/html/blendfile_"): job_id = handler.path[16:] job = handler.server.getJobID(job_id) @@ -280,10 +280,10 @@ def get(handler): sendjson(message) # return black listed slaves for a job elif handler.path.startswith("/html/blacklist_"): - + job_id = handler.path[16:] job = handler.server.getJobID(job_id) - + message = [] if job: for slave_id in job.blacklist: @@ -291,9 +291,9 @@ def get(handler): message.append(slave.serialize()) sendjson(message) # return all slaves currently assigned to a job - + elif handler.path.startswith("/html/slavesjob_"): - + job_id = handler.path[16:] job = handler.server.getJobID(job_id) message = [] @@ -301,8 +301,8 @@ def get(handler): for slave in handler.server.slaves: if slave.job and slave.job == job: message.append(slave.serialize()) - sendjson(message) - # here begin code for simple ui + sendjson(message) + # here begin code for simple ui elif handler.path == "/html" or handler.path == "/": handler.send_head(content = "text/html") head("NetRender", refresh = True) @@ -336,10 +336,10 @@ def get(handler): for job in handler.server.jobs: results = job.framesStatus() - + time_finished = job.time_finished time_started = job.time_started - + rowTable( """<button title="cancel job" onclick="cancel_job('%s');">X</button>""" % job.id + """<button title="pause job" onclick="request('/pause_%s', null);">P</button>""" % job.id + @@ -370,7 +370,7 @@ def get(handler): ) endTable() - + output("<h2>Slaves</h2>") startTable() @@ -383,7 +383,7 @@ def get(handler): output("<h2>Configuration</h2>") output("""<button title="remove all jobs" onclick="clear_jobs();">CLEAR JOB LIST</button>""") - + output("<br />") output(link("new interface", "/html/newui")) @@ -427,7 +427,7 @@ def get(handler): job_id = handler.path[9:] head("NetRender") - + output(link("Back to Main Page", "/html")) job = handler.server.getJobID(job_id) @@ -442,7 +442,7 @@ def get(handler): rowTable("resolution", "%ix%i at %i%%" % job.resolution) rowTable("tags", ";".join(sorted(job.tags)) if job.tags else "<i>None</i>") - + rowTable("results", link("download all", resultURL(job_id))) endTable() @@ -450,29 +450,29 @@ def get(handler): if job.type == netrender.model.JOB_BLENDER: output("<h2>Files</h2>") - + startTable() headerTable("path") - + tot_cache = 0 tot_fluid = 0 tot_other = 0 - + rowTable(job.files[0].original_path) - tot_cache, tot_fluid, tot_other = countFiles(job) - + tot_cache, tot_fluid, tot_other = countFiles(job) + if tot_cache > 0: rowTable("%i physic cache files" % tot_cache, class_style = "toggle", extra = "onclick='toggleDisplay(".cache", "none", "table-row")'") for file in job.files: if file.filepath.endswith(".bphys"): rowTable(os.path.split(file.filepath)[1], class_style = "cache") - + if tot_fluid > 0: rowTable("%i fluid bake files" % tot_fluid, class_style = "toggle", extra = "onclick='toggleDisplay(".fluid", "none", "table-row")'") for file in job.files: if file.filepath.endswith((".bobj.gz", ".bvel.gz")): rowTable(os.path.split(file.filepath)[1], class_style = "fluid") - + if tot_other > 0: rowTable("%i other files" % tot_other, class_style = "toggle", extra = "onclick='toggleDisplay(".other", "none", "table-row")'") for file in job.files: @@ -487,15 +487,15 @@ def get(handler): endTable() elif job.type == netrender.model.JOB_VCS: output("<h2>Versioning</h2>") - + startTable() - + rowTable("System", job.version_info.system.name) rowTable("Remote Path", job.version_info.rpath) rowTable("Working Path", job.version_info.wpath) rowTable("Revision", job.version_info.revision) rowTable("Render File", job.files[0].filepath) - + endTable() if job.blacklist: @@ -524,10 +524,10 @@ def get(handler): output("<h2>Frames</h2>") startTable() - + if job.hasRenderResult(): headerTable("no", "status", "render time", "slave", "log", "result", "") - + for frame in job.frames: rowTable( frame.number, @@ -541,7 +541,7 @@ def get(handler): ) else: headerTable("no", "status", "process time", "slave", "log") - + for frame in job.frames: rowTable( frame.number, diff --git a/netrender/model.py b/netrender/model.py index 4153f936..62623da9 100644 --- a/netrender/model.py +++ b/netrender/model.py @@ -121,7 +121,7 @@ class RenderSlave: self.total_done = 0 self.total_error = 0 self.last_seen = 0.0 - + if info: self.name = info.name self.address = info.address @@ -176,7 +176,7 @@ class VersioningInfo: self.wpath = "" self.rpath = "" self.revision = "" - + @property def system(self): return self._system @@ -187,7 +187,7 @@ class VersioningInfo: def update(self): self.system.update(self) - + def serialize(self): return { "wpath": self.wpath, @@ -195,7 +195,7 @@ class VersioningInfo: "revision": self.revision, "system": self.system.name } - + @staticmethod def generate(system, path): vs = VersioningInfo() @@ -204,23 +204,23 @@ class VersioningInfo: vs.rpath = vs.system.path(path) vs.revision = vs.system.revision(path) - + return vs - - + + @staticmethod def materialize(data): if not data: return None - + vs = VersioningInfo() vs.wpath = data["wpath"] vs.rpath = data["rpath"] vs.revision = data["revision"] vs.system = data["system"] - + return vs - + class RenderFile: def __init__(self, filepath = "", index = 0, start = -1, end = -1, signature = 0): @@ -231,7 +231,7 @@ class RenderFile: self.start = start self.end = end self.force = False - + def serialize(self): return { @@ -242,7 +242,7 @@ class RenderFile: "end": self.end, "signature": self.signature, "force": self.force - + } @staticmethod @@ -259,16 +259,16 @@ class RenderFile: class RenderJob: def __init__(self, info = None): self.id = "" - + self.resolution = None self.usage = 0.0 self.last_dispatched = 0.0 self.frames = [] self.transitions = [] - + self._status = None - + if info: self.type = info.type self.subtype = info.subtype @@ -300,13 +300,13 @@ class RenderJob: def status(self): """Status of the job (waiting, paused, finished or queued)""" return self._status - + @status.setter def status(self, value): transition = JOB_TRANSITIONS.get((self.status, value), None) if transition: self.transitions.append((transition, time.time())) - + self._status = value @property @@ -316,7 +316,7 @@ class RenderJob: if transition == JOB_TRANSITION_STARTED: started_time = time_value break - + return started_time @property @@ -326,7 +326,7 @@ class RenderJob: for transition, time_value in self.transitions: if transition == JOB_TRANSITION_FINISHED: finished_time = time_value - + return finished_time def hasRenderResult(self): @@ -339,15 +339,15 @@ class RenderJob: def isFileInFrames(): if start == end == -1: return True - + for rframe in self.frames: if start <= rframe.number<= end: return True - + return False - - - if isFileInFrames(): + + + if isFileInFrames(): if signed: signature = hashFile(file_path) else: @@ -426,10 +426,10 @@ class RenderJob: } if (withFiles): data["files"]=[f.serialize() for f in self.files if f.start == -1 or not frames or (f.start <= max_frame and f.end >= min_frame)] - + if (withFrames): data["frames"]=[f.serialize() for f in self.frames if not frames or f in frames] - + return data @staticmethod def materialize(data): @@ -454,7 +454,7 @@ class RenderJob: job.last_dispatched = data["last_dispatched"] job.resolution = data["resolution"] job.render=data["render"] - + version_info = data.get("version_info", None) if version_info: job.version_info = VersioningInfo.materialize(version_info) diff --git a/netrender/operators.py b/netrender/operators.py index bf0dfd61..c7012b39 100644 --- a/netrender/operators.py +++ b/netrender/operators.py @@ -51,7 +51,7 @@ class RENDER_OT_netclientsendbake(bpy.types.Operator): self.report({'INFO'}, "Job sent to master") except Exception as err: self.report({'ERROR'}, str(err)) - + return {'FINISHED'} def invoke(self, context, event): @@ -389,26 +389,26 @@ class netclientdownload(bpy.types.Operator): if conn: job_id = netrender.jobs[netsettings.active_job_index].id - + with ConnectionContext(): conn.request("GET", "/status", headers={"job-id":job_id}) response = conn.getresponse() - + if response.status != http.client.OK: self.report({'ERROR'}, "Job ID %i not defined on master" % job_id) return {'ERROR'} - + content = response.read() - + job = netrender.model.RenderJob.materialize(json.loads(str(content, encoding='utf8'))) - - conn.close() - + + conn.close() + finished_frames = [] - + nb_error = 0 nb_missing = 0 - + for frame in job.frames: if frame.status == netrender.model.FRAME_DONE: finished_frames.append(frame.number) @@ -416,36 +416,36 @@ class netclientdownload(bpy.types.Operator): nb_error += 1 else: nb_missing += 1 - + if not finished_frames: self.report({'ERROR'}, "Job doesn't have any finished frames") return {'ERROR'} - + frame_ranges = [] - + first = None last = None - + for i in range(len(finished_frames)): current = finished_frames[i] - + if not first: first = current last = current elif last + 1 == current: last = current - + if last + 1 < current or i + 1 == len(finished_frames): if first < last: frame_ranges.append((first, last)) else: frame_ranges.append((first,)) - + first = current last = current - + getResults(netsettings.server_address, netsettings.server_port, job_id, job.resolution[0], job.resolution[1], job.resolution[2], frame_ranges) - + if nb_error and nb_missing: self.report({'ERROR'}, "Results downloaded but skipped %i frames with errors and %i unfinished frames" % (nb_error, nb_missing)) elif nb_error: @@ -495,20 +495,20 @@ class netclientvcsguess(bpy.types.Operator): def execute(self, context): netsettings = context.scene.network_render - + system = versioning.SYSTEMS.get(netsettings.vcs_system, None) - + if system: wpath, name = os.path.split(os.path.abspath(bpy.data.filepath)) - + rpath = system.path(wpath) revision = system.revision(wpath) - + netsettings.vcs_wpath = wpath netsettings.vcs_rpath = rpath netsettings.vcs_revision = revision - - + + return {'FINISHED'} @@ -538,7 +538,7 @@ class netclientweb(bpy.types.Operator): if netsettings.use_ssl: webbrowser.open("https://%s:%i" % (netsettings.server_address, netsettings.server_port)) else: - webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port)) + webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port)) return {'FINISHED'} def invoke(self, context, event): diff --git a/netrender/repath.py b/netrender/repath.py index e39929b4..348f7426 100644 --- a/netrender/repath.py +++ b/netrender/repath.py @@ -28,7 +28,7 @@ from netrender.utils import * def reset(job): main_file = job.files[0] - + job_full_path = main_file.filepath if os.path.exists(job_full_path + ".bak"): @@ -37,27 +37,27 @@ def reset(job): def update(job): paths = [] - + main_file = job.files[0] - + job_full_path = main_file.filepath - + path, ext = os.path.splitext(job_full_path) - + new_path = path + ".remap" + ext - - original_path = main_file.original_path - + + original_path = main_file.original_path + # Disable for now. Partial repath should work anyway #all = main_file.filepath != main_file.original_path - all = False - + all = False + for rfile in job.files[1:]: if all or rfile.original_path != rfile.filepath: paths.append(rfile.original_path) paths.append(rfile.filepath) - + # Only update if needed if paths: process = subprocess.Popen( @@ -75,7 +75,7 @@ def update(job): stderr=subprocess.STDOUT, ) process.wait() - + os.renames(job_full_path, job_full_path + ".bak") os.renames(new_path, job_full_path) @@ -97,12 +97,12 @@ def process(original_path, paths): else: if DEBUG: print(paths[i], paths[i+1]) path_map[paths[i]] = paths[i+1] - + if DEBUG: print("----------------------------------------------------------") # TODO original paths aren't really the original path, they are the normalized path - # so we repath using the filenames only. - + # so we repath using the filenames only. + ########################### # LIBRARIES ########################### @@ -123,7 +123,7 @@ def process(original_path, paths): if DEBUG: print(file_path, new_path) if new_path: image.filepath = new_path - + ########################### # FLUID + POINT CACHE @@ -139,31 +139,31 @@ def process(original_path, paths): point_cache.use_external = True point_cache.filepath = new_path point_cache.name = cache_name - + def fluidFunc(object, modifier, cache_path): fluid = modifier.settings new_path = path_map.get(cache_path, None) if new_path: fluid.path = new_path - + def multiresFunc(object, modifier, cache_path): new_path = path_map.get(cache_path, None) if new_path: modifier.filepath = new_path - + processObjectDependencies(pointCacheFunc, fluidFunc, multiresFunc) if DEBUG: print("==========================================================") - + if __name__ == "__main__": try: i = sys.argv.index("--") except: i = 0 - + if i: new_path, original_path, *args = sys.argv[i+1:] - + process(original_path, args) - + bpy.ops.wm.save_as_mainfile(filepath=new_path, check_existing=False) diff --git a/netrender/slave.py b/netrender/slave.py index c20906a5..a5d97172 100644 --- a/netrender/slave.py +++ b/netrender/slave.py @@ -45,13 +45,13 @@ def slave_Info(netsettings): slave.stats = sysname + " " + release + " " + machine + " " + processor if netsettings.slave_tags: slave.tags = set(netsettings.slave_tags.split(";")) - + if netsettings.slave_bake: slave.tags.add(netrender.model.TAG_BAKING) - + if netsettings.slave_render: slave.tags.add(netrender.model.TAG_RENDER) - + return slave def testCancel(conn, job_id, frame_number): @@ -66,13 +66,13 @@ def testCancel(conn, job_id, frame_number): def testFile(conn, job_id, slave_id, rfile, job_prefix, main_path=None): job_full_path = createLocalPath(rfile, job_prefix, main_path, rfile.force) - + found = os.path.exists(job_full_path) - + if found and rfile.signature != None: found_signature = hashFile(job_full_path) found = found_signature == rfile.signature - + if not found: print("Found file %s at %s but signature mismatch!" % (rfile.filepath, job_full_path)) os.remove(job_full_path) @@ -99,7 +99,7 @@ def testFile(conn, job_id, slave_id, rfile, job_prefix, main_path=None): f.close() os.renames(temp_path, job_full_path) - + rfile.filepath = job_full_path return job_full_path @@ -114,7 +114,7 @@ def render_slave(engine, netsettings, threads): bisleep = BreakableIncrementedSleep(INCREMENT_TIMEOUT, 1, MAX_TIMEOUT, engine.test_break) engine.update_stats("", "Network render node initiation") - + slave_path = bpy.path.abspath(netsettings.path) if not os.path.exists(slave_path): @@ -124,23 +124,23 @@ def render_slave(engine, netsettings, threads): if not os.access(slave_path, os.W_OK): print("Slave working path ( %s ) is not writable" % netsettings.path) return - + conn = clientConnection(netsettings) - + if not conn: print("Connection failed, will try connecting again at most %i times" % MAX_CONNECT_TRY) bisleep.reset() - + for i in range(MAX_CONNECT_TRY): bisleep.sleep() - + conn = clientConnection(netsettings) - + if conn or engine.test_break(): break - + print("Retry %i failed, waiting %is before retrying" % (i + 1, bisleep.current)) - + if conn: with ConnectionContext(): conn.request("POST", "/slave", json.dumps(slave_Info(netsettings).serialize())) @@ -184,7 +184,7 @@ def render_slave(engine, netsettings, threads): for rfile in job.files[1:]: testFile(conn, job.id, slave_id, rfile, job_prefix, main_path) print("\t", rfile.filepath) - + netrender.repath.update(job) engine.update_stats("", "Render File " + main_file + " for job " + job.id) @@ -192,15 +192,15 @@ def render_slave(engine, netsettings, threads): if not job.version_info: # Need to return an error to server, incorrect job type pass - + job_path = job.files[0].filepath # path of main file main_path, main_file = os.path.split(job_path) - + job.version_info.update() - + # For VCS jobs, file path is relative to the working copy path job_full_path = os.path.join(job.version_info.wpath, job_path) - + engine.update_stats("", "Render File " + main_file + " for job " + job.id) # announce log to master @@ -238,26 +238,26 @@ def render_slave(engine, netsettings, threads): stdout=subprocess.PIPE, stderr=subprocess.STDOUT, ) - + elif job.subtype == netrender.model.JOB_SUB_BAKING: tasks = [] for frame in job.frames: tasks.append(netrender.baking.commandToTask(frame.command)) - + with NoErrorDialogContext(): process = netrender.baking.bake(job, tasks) - + elif job.type == netrender.model.JOB_PROCESS: command = job.frames[0].command with NoErrorDialogContext(): process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) headers = {"slave-id":slave_id} - + results = [] line = "" - + class ProcessData: def __init__(self): self.lock = threading.Lock() @@ -265,21 +265,21 @@ def render_slave(engine, netsettings, threads): self.cancelled = False self.start_time = time.time() self.last_time = time.time() - + data = ProcessData() - + def run_process(process, data): while not data.cancelled and process.poll() is None: buf = process.stdout.read(1024) - + data.lock.acquire() data.stdout += buf data.lock.release() - + process_thread = threading.Thread(target=run_process, args=(process, data)) - + process_thread.start() - + while not data.cancelled and process_thread.is_alive(): time.sleep(CANCEL_POLL_SPEED / 2) current_time = time.time() @@ -294,13 +294,13 @@ def render_slave(engine, netsettings, threads): with ConnectionContext(): conn.request("PUT", logURL(job.id, first_frame), data.stdout, headers=headers) responseStatus(conn) - + stdout_text = str(data.stdout, encoding='utf8') - + # Also output on console if netsettings.use_slave_output_log: print(stdout_text, end="") - + lines = stdout_text.split("\n") lines[0] = line + lines[0] line = lines.pop() @@ -308,14 +308,14 @@ def render_slave(engine, netsettings, threads): results.extend(netrender.baking.resultsFromOuput(lines)) data.stdout = bytes() - + data.lock.release() data.last_time = current_time if testCancel(conn, job.id, first_frame): engine.update_stats("", "Job canceled by Master") data.cancelled = True - + process_thread.join() del process_thread @@ -337,11 +337,11 @@ def render_slave(engine, netsettings, threads): # flush the rest of the logs if data.stdout: stdout_text = str(data.stdout, encoding='utf8') - + # Also output on console if netsettings.use_slave_output_log: print(stdout_text, end="") - + lines = stdout_text.split("\n") lines[0] = line + lines[0] if job.subtype == netrender.model.JOB_SUB_BAKING: @@ -350,7 +350,7 @@ def render_slave(engine, netsettings, threads): # (only need to update on one frame, they are linked with ConnectionContext(): conn.request("PUT", logURL(job.id, first_frame), data.stdout, headers=headers) - + if responseStatus(conn) == http.client.NO_CONTENT: continue @@ -377,7 +377,7 @@ def render_slave(engine, netsettings, threads): # thumbnail first if netsettings.use_slave_thumb: thumbname = thumbnail.generate(filename) - + if thumbname: f = open(thumbname, 'rb') with ConnectionContext(): @@ -394,21 +394,21 @@ def render_slave(engine, netsettings, threads): elif job.subtype == netrender.model.JOB_SUB_BAKING: index = job.frames.index(frame) - + frame_results = [result_filepath for task_index, result_filepath in results if task_index == index] - + for result_filepath in frame_results: result_path, result_filename = os.path.split(result_filepath) headers["result-filename"] = result_filename headers["job-finished"] = str(result_filepath == frame_results[-1]) - + f = open(result_filepath, 'rb') with ConnectionContext(): conn.request("PUT", "/result", f, headers=headers) f.close() if responseStatus(conn) == http.client.NO_CONTENT: continue - + elif job.type == netrender.model.JOB_PROCESS: with ConnectionContext(): conn.request("PUT", "/render", headers=headers) diff --git a/netrender/thumbnail.py b/netrender/thumbnail.py index 4408599e..0c72356d 100644 --- a/netrender/thumbnail.py +++ b/netrender/thumbnail.py @@ -38,7 +38,7 @@ def generate(filename, external=True): while process.poll() is None: process.stdout.read(1024) # empty buffer to be sure process.stdout.read() - + return _thumbname(filename) else: return _internal(filename) @@ -58,7 +58,7 @@ def _internal(filename): scene = bpy.data.scenes[0] # FIXME, this is dodgy! scene.render.image_settings.file_format = "JPEG" scene.render.image_settings.quality = 90 - + # remove existing image, if there's a leftover (otherwise open changes the name) if imagename in bpy.data.images: img = bpy.data.images[imagename] @@ -66,9 +66,9 @@ def _internal(filename): bpy.ops.image.open(filepath=filename) img = bpy.data.images[imagename] - + img.save_render(thumbname, scene=scene) - + img.user_clear() bpy.data.images.remove(img) diff --git a/netrender/ui.py b/netrender/ui.py index 2b352a5e..7f65163f 100644 --- a/netrender/ui.py +++ b/netrender/ui.py @@ -36,7 +36,7 @@ ADDRESS_TEST_TIMEOUT = 30 def base_poll(cls, context): rd = context.scene.render return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES) - + def init_file(): if netrender.init_file != bpy.data.filepath: @@ -79,7 +79,7 @@ def verify_address(netsettings, force=False): conn.close() else: netrender.valid_address = False - + return netrender.valid_address class NeedValidAddress(): @@ -92,11 +92,11 @@ class NetRenderButtonsPanel(): bl_region_type = "WINDOW" bl_context = "render" # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here - + @classmethod def poll(cls, context): rd = context.scene.render - return rd.engine == 'NET_RENDER' and rd.use_game_engine == False + return rd.engine == 'NET_RENDER' and rd.use_game_engine == False # Setting panel, use in the scene for now. class RENDER_PT_network_settings(NetRenderButtonsPanel, bpy.types.Panel): @@ -120,7 +120,7 @@ class RENDER_PT_network_settings(NetRenderButtonsPanel, bpy.types.Panel): layout.operator("render.netclientstart", icon='PLAY') layout.prop(netsettings, "path") - + row = layout.row() split = layout.split(percentage=0.5) @@ -135,19 +135,19 @@ class RENDER_PT_network_settings(NetRenderButtonsPanel, bpy.types.Panel): if netsettings.mode != "RENDER_MASTER": layout.operator("render.netclientscan", icon='FILE_REFRESH', text="") - + if not netrender.valid_address: layout.label(text="No master at specified address") - - + + if netsettings.use_ssl and netsettings.mode == "RENDER_MASTER": layout.prop(netsettings, "cert_path", text="Certificate") layout.prop(netsettings, "key_path", text="Key") layout.operator("render.netclientweb", icon='QUESTION') - - + + class RENDER_PT_network_slave_settings(NetRenderButtonsPanel, bpy.types.Panel): bl_label = "Slave Settings" COMPAT_ENGINES = {'NET_RENDER'} @@ -171,7 +171,7 @@ class RENDER_PT_network_slave_settings(NetRenderButtonsPanel, bpy.types.Panel): layout.prop(netsettings, "use_slave_output_log") layout.label(text="Threads:") layout.prop(rd, "threads_mode", expand=True) - + col = layout.column() col.enabled = rd.threads_mode == 'FIXED' col.prop(rd, "threads") @@ -225,18 +225,18 @@ class RENDER_PT_network_job(NetRenderButtonsPanel, bpy.types.Panel): layout.prop(netsettings, "job_category", text="Category") layout.prop(netsettings, "job_tags", text="Tags") layout.prop(netsettings, "job_render_engine", text="Engine") - + if netsettings.job_render_engine == "OTHER": layout.prop(netsettings, "job_render_engine_other", text="Other Engine") row = layout.row() row.prop(netsettings, "priority") row.prop(netsettings, "chunks") - + if netsettings.job_type == "JOB_BLENDER": layout.prop(netsettings, "save_before_job") - - + + class RENDER_PT_network_job_vcs(NetRenderButtonsPanel, bpy.types.Panel): bl_label = "VCS Job Settings" @@ -366,7 +366,7 @@ class RENDER_PT_network_output(NeedValidAddress, NetRenderButtonsPanel, bpy.type def poll(cls, context): netsettings = context.scene.network_render return super().poll(context) and netsettings.mode == "RENDER_CLIENT" - + draw = properties_render.RENDER_PT_output.draw @@ -404,14 +404,14 @@ class NetRenderSettings(bpy.types.PropertyGroup): maxlen = 128, default = "[default]", update = address_update_callback) - + NetRenderSettings.server_port = IntProperty( name="Server port", description="port of the master render server", default = 8000, min=1, max=65535) - + NetRenderSettings.use_master_broadcast = BoolProperty( name="Broadcast", description="broadcast master server address on local network", @@ -432,17 +432,17 @@ class NetRenderSettings(bpy.types.PropertyGroup): maxlen = 128, default = "", subtype='FILE_PATH') - + NetRenderSettings.use_slave_clear = BoolProperty( name="Clear on exit", description="delete downloaded files on exit", default = True) - + NetRenderSettings.use_slave_thumb = BoolProperty( name="Generate thumbnails", description="Generate thumbnails on slaves instead of master", default = False) - + NetRenderSettings.slave_tags = StringProperty( name="Tags", description="Tags to associate with the slave (semi-colon separated)", @@ -453,7 +453,7 @@ class NetRenderSettings(bpy.types.PropertyGroup): name="Output render log on console", description="Output render text log to console as well as sending it to the master", default = True) - + NetRenderSettings.slave_render = BoolProperty( name="Render on slave", description="Use slave for render jobs", @@ -473,9 +473,9 @@ class NetRenderSettings(bpy.types.PropertyGroup): name="Force Dependency Upload", description="Force client to upload dependency files to master", default = False) - + default_path = os.environ.get("TEMP") - + if not default_path: if os.name == 'nt': default_path = "c:/tmp/" @@ -483,14 +483,14 @@ class NetRenderSettings(bpy.types.PropertyGroup): default_path = "/tmp/" elif not default_path.endswith(os.sep): default_path += os.sep - + NetRenderSettings.path = StringProperty( name="Path", description="Path for temporary files", maxlen = 128, default = default_path, subtype='FILE_PATH') - + NetRenderSettings.job_type = EnumProperty( items=( ("JOB_BLENDER", "Blender", "Standard Blender Job"), @@ -500,13 +500,13 @@ class NetRenderSettings(bpy.types.PropertyGroup): name="Job Type", description="Type of render job", default="JOB_BLENDER") - + NetRenderSettings.job_name = StringProperty( name="Job name", description="Name of the job", maxlen = 128, default = "[default]") - + NetRenderSettings.job_category = StringProperty( name="Job category", description="Category of the job", @@ -534,7 +534,7 @@ class NetRenderSettings(bpy.types.PropertyGroup): description="Render engine other than the builtin defaults (POVRAY_RENDER, ...)", maxlen = 128, default = "") - + NetRenderSettings.save_before_job = BoolProperty( name="Save Before Job", description="Save current file before sending a job", @@ -546,65 +546,65 @@ class NetRenderSettings(bpy.types.PropertyGroup): default = 5, min=1, max=65535) - + NetRenderSettings.priority = IntProperty( name="Priority", description="Priority of the job", default = 1, min=1, max=10) - + NetRenderSettings.vcs_wpath = StringProperty( name="Working Copy", description="Path of the local working copy", maxlen = 1024, default = "") - + NetRenderSettings.vcs_rpath = StringProperty( name="Remote Path", description="Path of the server copy (protocol specific)", maxlen = 1024, default = "") - + NetRenderSettings.vcs_revision = StringProperty( name="Revision", description="Revision for this job", maxlen = 256, default = "") - + NetRenderSettings.vcs_system = EnumProperty( items= netrender.versioning.ITEMS, name="VCS mode", description="Version Control System", default=netrender.versioning.ITEMS[0][0]) - + NetRenderSettings.job_id = StringProperty( name="Network job id", description="id of the last sent render job", maxlen = 64, default = "") - + NetRenderSettings.active_slave_index = IntProperty( name="Index of the active slave", description="", default = -1, min= -1, max=65535) - + NetRenderSettings.active_blacklisted_slave_index = IntProperty( name="Index of the active slave", description="", default = -1, min= -1, max=65535) - + NetRenderSettings.active_job_index = IntProperty( name="Index of the active job", description="", default = -1, min= -1, max=65535) - + NetRenderSettings.mode = EnumProperty( items=( ("RENDER_CLIENT", "Client", "Act as render client"), @@ -614,11 +614,11 @@ class NetRenderSettings(bpy.types.PropertyGroup): name="Network mode", description="Mode of operation of this instance", default="RENDER_CLIENT") - + NetRenderSettings.slaves = CollectionProperty(type=NetRenderSlave, name="Slaves", description="") NetRenderSettings.slaves_blacklist = CollectionProperty(type=NetRenderSlave, name="Slaves Blacklist", description="") NetRenderSettings.jobs = CollectionProperty(type=NetRenderJob, name="Job List", description="") - + bpy.types.Scene.network_render = PointerProperty(type=NetRenderSettings, name="Network Render", description="Network Render Settings") @classmethod diff --git a/netrender/utils.py b/netrender/utils.py index edade26f..78d57487 100644 --- a/netrender/utils.py +++ b/netrender/utils.py @@ -42,7 +42,7 @@ if system == "Darwin": def __init__(self, timeout = None): self.old_timeout = socket.getdefaulttimeout() self.timeout = timeout - + def __enter__(self): if self.old_timeout != self.timeout: socket.setdefaulttimeout(self.timeout) @@ -54,7 +54,7 @@ else: class ConnectionContext: def __init__(self, timeout = None): pass - + def __enter__(self): pass @@ -66,7 +66,7 @@ if system in {"Windows", "win32"}: class NoErrorDialogContext: def __init__(self): self.val = 0 - + def __enter__(self): self.val = ctypes.windll.kernel32.SetErrorMode(0x0002) ctypes.windll.kernel32.SetErrorMode(self.val | 0x0002) @@ -77,7 +77,7 @@ else: class NoErrorDialogContext: def __init__(self): pass - + def __enter__(self): pass @@ -87,7 +87,7 @@ else: class DirectoryContext: def __init__(self, path): self.path = path - + def __enter__(self): self.curdir = os.path.abspath(os.curdir) os.chdir(self.path) @@ -102,19 +102,19 @@ class BreakableIncrementedSleep: self.max = max_timeout self.current = self.default self.break_fct = break_fct - + def reset(self): self.current = self.default def increase(self): self.current = min(self.current + self.increment, self.max) - + def sleep(self): for i in range(self.current): time.sleep(1) if self.break_fct(): break - + self.increase() def responseStatus(conn): @@ -163,7 +163,7 @@ def clientConnection(netsettings, report = None, scan = True, timeout = 50): address = netsettings.server_address port = netsettings.server_port use_ssl = netsettings.use_ssl - + if address== "[default]": # calling operator from python is fucked, scene isn't in context # if bpy: @@ -236,7 +236,7 @@ def hashFile(path): value = hashData(f.read()) f.close() return value - + def hashData(data): m = hashlib.md5() m.update(data) @@ -257,13 +257,13 @@ def verifyCreateDir(directory_path): if original_path != directory_path: print("Expanded from the following path:", original_path) raise - + def cacheName(ob, point_cache): name = point_cache.name if name == "": name = "".join(["%02X" % ord(c) for c in ob.name]) - + return name def cachePath(file_path): @@ -291,12 +291,12 @@ def processObjectDependencies(pointCacheFunction, fluidFunction, multiresFunctio elif modifier.type == "DYNAMIC_PAINT" and modifier.canvas_settings: for surface in modifier.canvas_settings.canvas_surfaces: pointCacheFunction(object, modifier, surface.point_cache) - + # particles modifier are stupid and don't contain data # we have to go through the object property for psys in object.particle_systems: pointCacheFunction(object, psys, psys.point_cache) - + def createLocalPath(rfile, prefixdirectory, prefixpath, forcelocal): filepath = rfile.original_path @@ -309,12 +309,12 @@ def createLocalPath(rfile, prefixdirectory, prefixpath, forcelocal): finalpath = filepath if forcelocal or not os.path.exists(finalpath): path, name = os.path.split(os.path.normpath(finalpath)) - + # Don't add signatures to cache files, relink fails otherwise if not name.endswith(".bphys") and not name.endswith(".bobj.gz"): name, ext = os.path.splitext(name) name = name + "_" + rfile.signature + ext - + if prefixpath and path.startswith(prefixpath): suffix = "" while path != prefixpath: @@ -334,7 +334,7 @@ def createLocalPath(rfile, prefixdirectory, prefixpath, forcelocal): if not name.endswith(".bphys") and not name.endswith(".bobj.gz"): name, ext = os.path.splitext(name) name = name + "_" + rfile.signature + ext - + directory = directory.replace("../") directory = os.path.join(prefixdirectory, directory) @@ -355,7 +355,7 @@ def getResults(server_address, server_port, job_id, resolution_x, resolution_y, frame_arguments.extend(["-s", str(r[0]), "-e", str(r[1]), "-a"]) else: frame_arguments.extend(["-f", str(r[0])]) - + filepath = os.path.join(bpy.app.tempdir, "netrender_temp.blend") bpy.ops.wm.save_as_mainfile(filepath=filepath, copy=True, check_existing=False) @@ -387,22 +387,22 @@ def getResults(server_address, server_port, job_id, resolution_x, resolution_y, stdout = process.stdout.read(1024) if bpy.app.debug: print(str(stdout, encoding='utf-8'), end="") - + # read leftovers if needed stdout = process.stdout.read() if bpy.app.debug: print(str(stdout, encoding='utf-8')) - + os.remove(filepath) - + if bpy.app.debug: print("=============================================") return def _getResults(server_address, server_port, job_id, resolution_x, resolution_y, resolution_percentage): render = bpy.context.scene.render - + netsettings = bpy.context.scene.network_render netsettings.server_address = server_address @@ -417,7 +417,7 @@ def _getResults(server_address, server_port, job_id, resolution_x, resolution_y, render.use_full_sample = False render.use_compositing = False render.use_border = False - + def getFileInfo(filepath, infos): process = subprocess.Popen( @@ -445,7 +445,7 @@ def getFileInfo(filepath, infos): values = [eval(v[1:].strip()) for v in stdout.split("\n") if v.startswith("$")] return values - + if __name__ == "__main__": try: @@ -453,8 +453,8 @@ if __name__ == "__main__": except ValueError: start = 0 action, *args = sys.argv[start:] - - if action == "FileInfo": + + if action == "FileInfo": for info in args: print("$", eval(info)) elif action == "GetResults": diff --git a/netrender/versioning.py b/netrender/versioning.py index e88416cd..871fe687 100644 --- a/netrender/versioning.py +++ b/netrender/versioning.py @@ -23,34 +23,34 @@ import subprocess from netrender.utils import * class AbstractVCS: - name = "ABSTRACT VCS" + name = "ABSTRACT VCS" def __init__(self): pass - + def update(self, info): """update(info) Update a working copy to the specified revision. If working copy doesn't exist, do a full get from server to create it. [info] model.VersioningInfo instance, specifies the working path, remote path and version number.""" pass - + def revision(self, path): """revision(path) return the current revision of the specified working copy path""" pass - + def path(self, path): """path(path) return the remote path of the specified working copy path""" pass - + class Subversion(AbstractVCS): name = "Subversion" description = "Use the Subversion version control system" def __init__(self): super().__init__() - self.version_exp = re.compile("([0-9]*)") - self.path_exp = re.compile("URL: (.*)") + self.version_exp = re.compile("([0-9]*)") + self.path_exp = re.compile("URL: (.*)") def update(self, info): if not os.path.exists(info.wpath): @@ -61,28 +61,28 @@ class Subversion(AbstractVCS): else: with DirectoryContext(info.wpath): subprocess.call(["svn", "up", "--accept", "theirs-full", "-r", str(info.revision)]) - + def revision(self, path): if not os.path.exists(path): return with DirectoryContext(path): stdout = subprocess.check_output(["svnversion"]) - + match = self.version_exp.match(str(stdout, encoding="utf-8")) - + if match: return match.group(1) - + def path(self, path): if not os.path.exists(path): return with DirectoryContext(path): stdout = subprocess.check_output(["svn", "info"]) - + match = self.path_exp.search(str(stdout, encoding="utf-8")) - + if match: return match.group(1) @@ -91,7 +91,7 @@ class Git(AbstractVCS): description = "Use the Git distributed version control system" def __init__(self): super().__init__() - self.version_exp = re.compile("^commit (.*)") + self.version_exp = re.compile("^commit (.*)") def update(self, info): if not os.path.exists(info.wpath): @@ -102,19 +102,19 @@ class Git(AbstractVCS): with DirectoryContext(info.wpath): subprocess.call(["git", "checkout", str(info.revision)]) - + def revision(self, path): if not os.path.exists(path): return with DirectoryContext(path): stdout = subprocess.check_output(["git", "show"]) - + match = self.version_exp.search(str(stdout, encoding="utf-8")) - + if match: return match.group(1) - + def path(self, path): if not os.path.exists(path): return |