Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-03-19 04:49:03 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-03-19 04:49:18 +0300
commit57f376e9465c6b79ebd4409bc30e0b5930dd4140 (patch)
tree8dc6d5940bc8c39d7979d3b35c19d91f4bb83bf0 /netrender
parent1338695613af08ae912e6507f0fc89d54577e11a (diff)
Cleanup: trailing space
Diffstat (limited to 'netrender')
-rw-r--r--netrender/baking.py32
-rw-r--r--netrender/balancing.py4
-rw-r--r--netrender/client.py62
-rw-r--r--netrender/master.py60
-rw-r--r--netrender/master_html.py146
-rw-r--r--netrender/model.py54
-rw-r--r--netrender/operators.py52
-rw-r--r--netrender/repath.py46
-rw-r--r--netrender/slave.py88
-rw-r--r--netrender/thumbnail.py8
-rw-r--r--netrender/ui.py82
-rw-r--r--netrender/utils.py52
-rw-r--r--netrender/versioning.py36
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(&quot;.cache&quot;, &quot;none&quot;, &quot;table-row&quot;)'")
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(&quot;.fluid&quot;, &quot;none&quot;, &quot;table-row&quot;)'")
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(&quot;.other&quot;, &quot;none&quot;, &quot;table-row&quot;)'")
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