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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/io/netrender')
-rw-r--r--release/scripts/io/netrender/__init__.py42
-rw-r--r--release/scripts/io/netrender/client.py29
-rw-r--r--release/scripts/io/netrender/master.py21
-rw-r--r--release/scripts/io/netrender/master_html.py7
-rw-r--r--release/scripts/io/netrender/operators.py93
-rw-r--r--[-rwxr-xr-x]release/scripts/io/netrender/repath.py25
-rw-r--r--release/scripts/io/netrender/slave.py43
-rw-r--r--release/scripts/io/netrender/ui.py344
-rw-r--r--release/scripts/io/netrender/utils.py17
9 files changed, 330 insertions, 291 deletions
diff --git a/release/scripts/io/netrender/__init__.py b/release/scripts/io/netrender/__init__.py
index f5f104d6d92..5a705e95aa8 100644
--- a/release/scripts/io/netrender/__init__.py
+++ b/release/scripts/io/netrender/__init__.py
@@ -18,16 +18,31 @@
# This directory is a Python package.
-from netrender import model
-from netrender import operators
-from netrender import client
-from netrender import slave
-from netrender import master
-from netrender import master_html
-from netrender import utils
-from netrender import balancing
-from netrender import ui
-from netrender import repath
+# To support reload properly, try to access a package var, if it's there, reload everything
+try:
+ init_data
+
+ reload(model)
+ reload(operators)
+ reload(client)
+ reload(slave)
+ reload(master)
+ reload(master_html)
+ reload(utils)
+ reload(balancing)
+ reload(ui)
+ reload(repath)
+except:
+ from netrender import model
+ from netrender import operators
+ from netrender import client
+ from netrender import slave
+ from netrender import master
+ from netrender import master_html
+ from netrender import utils
+ from netrender import balancing
+ from netrender import ui
+ from netrender import repath
jobs = []
slaves = []
@@ -38,11 +53,10 @@ init_data = True
init_address = True
def register():
- pass # TODO
+ ui.addProperties()
+
def unregister():
import bpy
- bpy.types.unregister(ui.NetRenderJob)
- bpy.types.unregister(ui.NetRenderSettings)
- bpy.types.unregister(ui.NetRenderSlave)
+ bpy.types.Scene.RemoveProperty("network_render")
diff --git a/release/scripts/io/netrender/client.py b/release/scripts/io/netrender/client.py
index 9f6d1a7639e..6f0f6460ae1 100644
--- a/release/scripts/io/netrender/client.py
+++ b/release/scripts/io/netrender/client.py
@@ -41,7 +41,7 @@ def addFluidFiles(job, path):
job.addFile(path + fluid_file, current_frame, current_frame)
def addPointCache(job, ob, point_cache, default_path):
- if not point_cache.disk_cache:
+ if not point_cache.use_disk_cache:
return
@@ -49,7 +49,7 @@ def addPointCache(job, ob, point_cache, default_path):
if name == "":
name = "".join(["%02X" % ord(c) for c in ob.name])
- cache_path = bpy.utils.expandpath(point_cache.filepath) if point_cache.external else default_path
+ cache_path = bpy.path.abspath(point_cache.filepath) if point_cache.use_external else default_path
index = "%02i" % point_cache.index
@@ -113,7 +113,7 @@ def clientSendJob(conn, scene, anim = False):
# LIBRARIES
###########################
for lib in bpy.data.libraries:
- file_path = bpy.utils.expandpath(lib.filepath)
+ file_path = bpy.path.abspath(lib.filepath)
if os.path.exists(file_path):
job.addFile(file_path)
@@ -122,7 +122,7 @@ def clientSendJob(conn, scene, anim = False):
###########################
for image in bpy.data.images:
if image.source == "FILE" and not image.packed_file:
- file_path = bpy.utils.expandpath(image.filepath)
+ file_path = bpy.path.abspath(image.filepath)
if os.path.exists(file_path):
job.addFile(file_path)
@@ -139,17 +139,17 @@ def clientSendJob(conn, scene, anim = False):
for object in bpy.data.objects:
for modifier in object.modifiers:
if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
- addFluidFiles(job, bpy.utils.expandpath(modifier.settings.path))
+ addFluidFiles(job, bpy.path.abspath(modifier.settings.path))
elif modifier.type == "CLOTH":
addPointCache(job, object, modifier.point_cache, default_path)
elif modifier.type == "SOFT_BODY":
addPointCache(job, object, modifier.point_cache, default_path)
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
addPointCache(job, object, modifier.domain_settings.point_cache_low, default_path)
- if modifier.domain_settings.highres:
+ if modifier.domain_settings.use_high_resolution:
addPointCache(job, object, modifier.domain_settings.point_cache_high, default_path)
- elif modifier.type == "MULTIRES" and modifier.external:
- file_path = bpy.utils.expandpath(modifier.filepath)
+ elif modifier.type == "MULTIRES" and modifier.is_external:
+ file_path = bpy.path.abspath(modifier.filepath)
job.addFile(file_path)
# particles modifier are stupid and don't contain data
@@ -171,6 +171,7 @@ def clientSendJob(conn, scene, anim = False):
# try to send path first
conn.request("POST", "/job", repr(job.serialize()))
response = conn.getresponse()
+ response.read()
job_id = response.getheader("job-id")
@@ -181,6 +182,7 @@ def clientSendJob(conn, scene, anim = False):
conn.request("PUT", fileURL(job_id, rfile.index), f)
f.close()
response = conn.getresponse()
+ response.read()
# server will reply with ACCEPTED until all files are found
@@ -189,7 +191,6 @@ def clientSendJob(conn, scene, anim = False):
def requestResult(conn, job_id, frame):
conn.request("GET", renderURL(job_id, frame))
-@rnaType
class NetworkRenderEngine(bpy.types.RenderEngine):
bl_idname = 'NET_RENDER'
bl_label = "Network Render"
@@ -209,7 +210,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
address = "" if netsettings.server_address == "[default]" else netsettings.server_address
- master.runMaster((address, netsettings.server_port), netsettings.master_broadcast, netsettings.master_clear, netsettings.path, self.update_stats, self.test_break)
+ master.runMaster((address, netsettings.server_port), netsettings.master_broadcast, netsettings.use_master_clear, netsettings.path, self.update_stats, self.test_break)
def render_slave(self, scene):
@@ -237,6 +238,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
requestResult(conn, job_id, scene.frame_current)
response = conn.getresponse()
+ response.read()
if response.status == http.client.NO_CONTENT:
new_job = True
@@ -245,16 +247,19 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
requestResult(conn, job_id, scene.frame_current)
response = conn.getresponse()
+ response.read()
while response.status == http.client.ACCEPTED and not self.test_break():
time.sleep(1)
requestResult(conn, job_id, scene.frame_current)
response = conn.getresponse()
+ response.read()
# cancel new jobs (animate on network) on break
if self.test_break() and new_job:
conn.request("POST", cancelURL(job_id))
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
netsettings.job_id = 0
@@ -266,7 +271,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
x= int(r.resolution_x*r.resolution_percentage*0.01)
y= int(r.resolution_y*r.resolution_percentage*0.01)
- f = open(netsettings.path + "output.exr", "wb")
+ f = open(os.path.join(netsettings.path, "output.exr"), "wb")
buf = response.read(1024)
while buf:
@@ -276,7 +281,7 @@ class NetworkRenderEngine(bpy.types.RenderEngine):
f.close()
result = self.begin_result(0, 0, x, y)
- result.load_from_file(netsettings.path + "output.exr")
+ result.load_from_file(os.path.join(netsettings.path, "output.exr"))
self.end_result(result)
conn.close()
diff --git a/release/scripts/io/netrender/master.py b/release/scripts/io/netrender/master.py
index f227f61a536..6deb925420b 100644
--- a/release/scripts/io/netrender/master.py
+++ b/release/scripts/io/netrender/master.py
@@ -89,7 +89,7 @@ class MRenderJob(netrender.model.RenderJob):
def save(self):
if self.save_path:
- f = open(self.save_path + "job.txt", "w")
+ f = open(os.path.join(self.save_path, "job.txt"), "w")
f.write(repr(self.serialize()))
f.close()
@@ -134,8 +134,8 @@ class MRenderJob(netrender.model.RenderJob):
self.status = JOB_QUEUED
def addLog(self, frames):
- log_name = "_".join(("%04d" % f for f in frames)) + ".log"
- log_path = self.save_path + log_name
+ log_name = "_".join(("%06d" % f for f in frames)) + ".log"
+ log_path = os.path.join(self.save_path, log_name)
for number in frames:
frame = self[number]
@@ -260,7 +260,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
elif frame.status == DONE:
self.server.stats("", "Sending result to client")
- filename = job.save_path + "%04d" % frame_number + ".exr"
+ filename = os.path.join(job.save_path, "%06d.exr" % frame_number)
f = open(filename, 'rb')
self.send_head(content = "image/x-exr")
@@ -294,7 +294,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if frame.status in (QUEUED, DISPATCHED):
self.send_head(http.client.ACCEPTED)
elif frame.status == DONE:
- filename = job.save_path + "%04d" % frame_number + ".exr"
+ filename = os.path.join(job.save_path, "%06d.exr" % frame_number)
thumbname = thumbnail(filename)
@@ -716,7 +716,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if file_index > 0:
file_path = prefixPath(job.save_path, render_file.filepath, main_path)
else:
- file_path = job.save_path + main_name
+ file_path = os.path.join(job.save_path, main_name)
buf = self.rfile.read(length)
@@ -772,7 +772,7 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if job_result == DONE:
length = int(self.headers['content-length'])
buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".exr", 'wb')
+ f = open(os.path.join(job.save_path, "%06d.exr" % job_frame), 'wb')
f.write(buf)
f.close()
@@ -822,13 +822,12 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
if job.type == netrender.model.JOB_BLENDER:
length = int(self.headers['content-length'])
buf = self.rfile.read(length)
- f = open(job.save_path + "%04d" % job_frame + ".jpg", 'wb')
+ f = open(os.path.join(job.save_path, "%06d.jpg" % job_frame), 'wb')
f.write(buf)
f.close()
del buf
- self.send_head()
else: # frame not found
self.send_head(http.client.NO_CONTENT)
else: # job not found
@@ -880,7 +879,7 @@ class RenderMasterServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
self.job_id = 0
if subdir:
- self.path = path + "master_" + str(os.getpid()) + os.sep
+ self.path = os.path.join(path, "master_" + str(os.getpid()))
else:
self.path = path
@@ -1007,7 +1006,7 @@ class RenderMasterServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
self.jobs_map[job.id] = job
# create job directory
- job.save_path = self.path + "job_" + job.id + os.sep
+ job.save_path = os.path.join(self.path, "job_" + job.id)
if not os.path.exists(job.save_path):
os.mkdir(job.save_path)
diff --git a/release/scripts/io/netrender/master_html.py b/release/scripts/io/netrender/master_html.py
index c3695cd4f0f..74155f6bd66 100644
--- a/release/scripts/io/netrender/master_html.py
+++ b/release/scripts/io/netrender/master_html.py
@@ -27,9 +27,10 @@ def get(handler):
def output(text):
handler.wfile.write(bytes(text, encoding='utf8'))
- def head(title):
+ def head(title, refresh = False):
output("<html><head>")
- output("<meta http-equiv='refresh' content=5>")
+ if refresh:
+ output("<meta http-equiv='refresh' content=5>")
output("<script src='/html/netrender.js' type='text/javascript'></script>")
# output("<script src='/html/json2.js' type='text/javascript'></script>")
output("<title>")
@@ -104,7 +105,7 @@ def get(handler):
f.close()
elif handler.path == "/html" or handler.path == "/":
handler.send_head(content = "text/html")
- head("NetRender")
+ head("NetRender", refresh = True)
output("<h2>Jobs</h2>")
diff --git a/release/scripts/io/netrender/operators.py b/release/scripts/io/netrender/operators.py
index 858ec800dbc..252b1146b67 100644
--- a/release/scripts/io/netrender/operators.py
+++ b/release/scripts/io/netrender/operators.py
@@ -26,13 +26,13 @@ from netrender.utils import *
import netrender.client as client
import netrender.model
-@rnaType
class RENDER_OT_netslave_bake(bpy.types.Operator):
'''NEED DESCRIPTION'''
bl_idname = "render.netslavebake"
bl_label = "Bake all in file"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -52,27 +52,27 @@ class RENDER_OT_netslave_bake(bpy.types.Operator):
modifier.settings.path = relative_path
bpy.ops.fluid.bake({"active_object": object, "scene": scene})
elif modifier.type == "CLOTH":
- modifier.point_cache.step = 1
- modifier.point_cache.disk_cache = True
- modifier.point_cache.external = False
+ modifier.point_cache.frame_step = 1
+ modifier.point_cache.use_disk_cache = True
+ modifier.point_cache.use_external = False
elif modifier.type == "SOFT_BODY":
- modifier.point_cache.step = 1
- modifier.point_cache.disk_cache = True
- modifier.point_cache.external = False
+ modifier.point_cache.frame_step = 1
+ modifier.point_cache.use_disk_cache = True
+ modifier.point_cache.use_external = False
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
- modifier.domain_settings.point_cache_low.step = 1
- modifier.domain_settings.point_cache_low.disk_cache = True
- modifier.domain_settings.point_cache_low.external = False
- modifier.domain_settings.point_cache_high.step = 1
- modifier.domain_settings.point_cache_high.disk_cache = True
- modifier.domain_settings.point_cache_high.external = False
+ modifier.domain_settings.point_cache_low.use_step = 1
+ modifier.domain_settings.point_cache_low.use_disk_cache = True
+ modifier.domain_settings.point_cache_low.use_external = False
+ modifier.domain_settings.point_cache_high.use_step = 1
+ modifier.domain_settings.point_cache_high.use_disk_cache = True
+ modifier.domain_settings.point_cache_high.use_external = False
# particles modifier are stupid and don't contain data
# we have to go through the object property
for psys in object.particle_systems:
- psys.point_cache.step = 1
- psys.point_cache.disk_cache = True
- psys.point_cache.external = False
+ psys.point_cache.use_step = 1
+ psys.point_cache.use_disk_cache = True
+ psys.point_cache.use_external = False
psys.point_cache.filepath = relative_path
bpy.ops.ptcache.bake_all()
@@ -84,13 +84,13 @@ class RENDER_OT_netslave_bake(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientanim(bpy.types.Operator):
'''Start rendering an animation on network'''
bl_idname = "render.netclientanim"
bl_label = "Animation on network"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -111,13 +111,13 @@ class RENDER_OT_netclientanim(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientrun(bpy.types.Operator):
'''Start network rendering service'''
bl_idname = "render.netclientstart"
bl_label = "Start Service"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -128,13 +128,13 @@ class RENDER_OT_netclientrun(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientsend(bpy.types.Operator):
'''Send Render Job to the Network'''
bl_idname = "render.netclientsend"
bl_label = "Send job"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -158,13 +158,13 @@ class RENDER_OT_netclientsend(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientsendframe(bpy.types.Operator):
'''Send Render Job with current frame to the Network'''
bl_idname = "render.netclientsendframe"
bl_label = "Send current frame job"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -188,13 +188,13 @@ class RENDER_OT_netclientsendframe(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientstatus(bpy.types.Operator):
'''Refresh the status of the current jobs'''
bl_idname = "render.netclientstatus"
bl_label = "Client Status"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -205,6 +205,7 @@ class RENDER_OT_netclientstatus(bpy.types.Operator):
conn.request("GET", "/status")
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8')))
@@ -228,13 +229,13 @@ class RENDER_OT_netclientstatus(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
bl_idname = "render.netclientblacklistslave"
bl_label = "Client Blacklist Slave"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -258,13 +259,13 @@ class RENDER_OT_netclientblacklistslave(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
'''Operator documentation text, will be used for the operator tooltip and python docs.'''
bl_idname = "render.netclientwhitelistslave"
bl_label = "Client Whitelist Slave"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -289,13 +290,13 @@ class RENDER_OT_netclientwhitelistslave(bpy.types.Operator):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientslaves(bpy.types.Operator):
'''Refresh status about available Render slaves'''
bl_idname = "render.netclientslaves"
bl_label = "Client Slaves"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -306,6 +307,7 @@ class RENDER_OT_netclientslaves(bpy.types.Operator):
conn.request("GET", "/slaves")
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8')))
@@ -334,13 +336,13 @@ class RENDER_OT_netclientslaves(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientcancel(bpy.types.Operator):
'''Cancel the selected network rendering job.'''
bl_idname = "render.netclientcancel"
bl_label = "Client Cancel"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
netsettings = context.scene.network_render
return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
@@ -354,6 +356,7 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
conn.request("POST", cancelURL(job.id))
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
netsettings.jobs.remove(netsettings.active_job_index)
@@ -363,13 +366,13 @@ class RENDER_OT_netclientcancel(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class RENDER_OT_netclientcancelall(bpy.types.Operator):
'''Cancel all running network rendering jobs.'''
bl_idname = "render.netclientcancelall"
bl_label = "Client Cancel All"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -380,6 +383,7 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator):
conn.request("POST", "/clear")
response = conn.getresponse()
+ response.read()
print( response.status, response.reason )
while(len(netsettings.jobs) > 0):
@@ -390,13 +394,13 @@ class RENDER_OT_netclientcancelall(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class netclientdownload(bpy.types.Operator):
'''Download render results from the network'''
bl_idname = "render.netclientdownload"
bl_label = "Client Download"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
netsettings = context.scene.network_render
return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
@@ -412,6 +416,7 @@ class netclientdownload(bpy.types.Operator):
for frame in job.frames:
client.requestResult(conn, job.id, frame.number)
response = conn.getresponse()
+ response.read()
if response.status != http.client.OK:
print("missing", frame.number)
@@ -419,7 +424,7 @@ class netclientdownload(bpy.types.Operator):
print("got back", frame.number)
- f = open(netsettings.path + "%06d" % frame.number + ".exr", "wb")
+ f = open(os.path.join(netsettings.path, "%06d.exr" % frame.number), "wb")
buf = response.read(1024)
while buf:
@@ -435,13 +440,13 @@ class netclientdownload(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class netclientscan(bpy.types.Operator):
'''Listen on network for master server broadcasting its address and port.'''
bl_idname = "render.netclientscan"
bl_label = "Client Scan"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
return True
def execute(self, context):
@@ -458,13 +463,13 @@ class netclientscan(bpy.types.Operator):
def invoke(self, context, event):
return self.execute(context)
-@rnaType
class netclientweb(bpy.types.Operator):
'''Open new window with information about running rendering jobs'''
bl_idname = "render.netclientweb"
bl_label = "Open Master Monitor"
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
netsettings = context.scene.network_render
return netsettings.server_address != "[default]"
diff --git a/release/scripts/io/netrender/repath.py b/release/scripts/io/netrender/repath.py
index 7f9befd34fb..3ac9636b628 100755..100644
--- a/release/scripts/io/netrender/repath.py
+++ b/release/scripts/io/netrender/repath.py
@@ -66,10 +66,10 @@ def update(job):
def process(paths):
def processPointCache(point_cache):
- point_cache.external = False
+ point_cache.use_external = False
def processFluid(fluid):
- new_path = path_map.get(fluid.path, None)
+ new_path = path_map.get(fluid.filepath, None)
if new_path:
fluid.path = new_path
@@ -83,14 +83,17 @@ def process(paths):
elif paths[i].endswith(".bobj.gz"):
path_map[os.path.split(paths[i])[0]] = os.path.split(paths[i+1])[0]
else:
- path_map[paths[i]] = paths[i+1]
+ path_map[os.path.split(paths[i])[1]] = paths[i+1]
+
+ # TODO original paths aren't really the orignal path (they are the normalized path
+ # so we repath using the filenames only.
###########################
# LIBRARIES
###########################
for lib in bpy.data.libraries:
- file_path = bpy.utils.expandpath(lib.filepath)
- new_path = path_map.get(file_path, None)
+ file_path = bpy.path.abspath(lib.filepath)
+ new_path = path_map.get(os.path.split(file_path)[1], None)
if new_path:
lib.filepath = new_path
@@ -99,8 +102,8 @@ def process(paths):
###########################
for image in bpy.data.images:
if image.source == "FILE" and not image.packed_file:
- file_path = bpy.utils.expandpath(image.filepath)
- new_path = path_map.get(file_path, None)
+ file_path = bpy.path.abspath(image.filepath)
+ new_path = path_map.get(os.path.split(file_path)[1], None)
if new_path:
image.filepath = new_path
@@ -118,10 +121,10 @@ def process(paths):
processPointCache(modifier.point_cache)
elif modifier.type == "SMOKE" and modifier.smoke_type == "TYPE_DOMAIN":
processPointCache(modifier.domain_settings.point_cache_low)
- if modifier.domain_settings.highres:
+ if modifier.domain_settings.use_high_resolution:
processPointCache(modifier.domain_settings.point_cache_high)
- elif modifier.type == "MULTIRES" and modifier.external:
- file_path = bpy.utils.expandpath(modifier.filepath)
+ elif modifier.type == "MULTIRES" and modifier.is_external:
+ file_path = bpy.path.abspath(modifier.filepath)
new_path = path_map.get(file_path, None)
if new_path:
modifier.filepath = new_path
@@ -144,4 +147,4 @@ if __name__ == "__main__":
process(args)
- bpy.ops.wm.save_as_mainfile(path=new_path, check_existing=False)
+ bpy.ops.wm.save_as_mainfile(filepath=new_path, check_existing=False)
diff --git a/release/scripts/io/netrender/slave.py b/release/scripts/io/netrender/slave.py
index 9fd00152dc1..b383481824b 100644
--- a/release/scripts/io/netrender/slave.py
+++ b/release/scripts/io/netrender/slave.py
@@ -59,8 +59,8 @@ def slave_Info():
def testCancel(conn, job_id, frame_number):
conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(frame_number)})
- # cancelled if job isn't found anymore
- if conn.getresponse().status == http.client.NO_CONTENT:
+ # canceled if job isn't found anymore
+ if responseStatus(conn) == http.client.NO_CONTENT:
return True
else:
return False
@@ -79,7 +79,9 @@ def testFile(conn, job_id, slave_id, rfile, JOB_PREFIX, main_path = None):
job_full_path = prefixPath(JOB_PREFIX, rfile.filepath, main_path, force = True)
if not found:
- temp_path = JOB_PREFIX + "slave.temp"
+ # Force prefix path if not found
+ job_full_path = prefixPath(JOB_PREFIX, rfile.filepath, main_path, force = True)
+ temp_path = os.path.join(JOB_PREFIX, "slave.temp")
conn.request("GET", fileURL(job_id, rfile.index), headers={"slave-id":slave_id})
response = conn.getresponse()
@@ -111,10 +113,11 @@ def render_slave(engine, netsettings, threads):
if conn:
conn.request("POST", "/slave", repr(slave_Info().serialize()))
response = conn.getresponse()
+ response.read()
slave_id = response.getheader("slave-id")
- NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep
+ NODE_PREFIX = os.path.join(netsettings.path, "slave_" + slave_id)
if not os.path.exists(NODE_PREFIX):
os.mkdir(NODE_PREFIX)
@@ -130,7 +133,7 @@ def render_slave(engine, netsettings, threads):
job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8')))
engine.update_stats("", "Network render processing job from master")
- JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep
+ JOB_PREFIX = os.path.join(NODE_PREFIX, "job_" + job.id)
if not os.path.exists(JOB_PREFIX):
os.mkdir(JOB_PREFIX)
@@ -155,6 +158,7 @@ def render_slave(engine, netsettings, threads):
logfile = netrender.model.LogFile(job.id, slave_id, [frame.number for frame in job.frames])
conn.request("POST", "/log", bytes(repr(logfile.serialize()), encoding='utf8'))
response = conn.getresponse()
+ response.read()
first_frame = job.frames[0].number
@@ -170,7 +174,7 @@ def render_slave(engine, netsettings, threads):
frame_args += ["-f", str(frame.number)]
val = SetErrorMode()
- process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-t", str(threads), "-o", JOB_PREFIX + "######", "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-t", str(threads), "-o", os.path.join(JOB_PREFIX, "######"), "-E", "BLENDER_RENDER", "-F", "MULTILAYER"] + frame_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
RestoreErrorMode(val)
elif job.type == netrender.model.JOB_PROCESS:
command = job.frames[0].command
@@ -194,9 +198,10 @@ def render_slave(engine, netsettings, threads):
# (only need to update on one frame, they are linked
conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
response = conn.getresponse()
+ response.read()
# Also output on console
- if netsettings.slave_thumb:
+ if netsettings.use_slave_output_log:
print(str(stdout, encoding='utf8'), end="")
stdout = bytes()
@@ -214,18 +219,21 @@ def render_slave(engine, netsettings, threads):
if cancelled:
# kill process if needed
if process.poll() == None:
- process.terminate()
+ try:
+ process.terminate()
+ except OSError:
+ pass
continue # to next frame
# flush the rest of the logs
if stdout:
# Also output on console
- if netsettings.slave_thumb:
+ if netsettings.use_slave_thumb:
print(str(stdout, encoding='utf8'), end="")
# (only need to update on one frame, they are linked
conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
- if conn.getresponse().status == http.client.NO_CONTENT:
+ if responseStatus(conn) == http.client.NO_CONTENT:
continue
total_t = time.time() - start_t
@@ -246,26 +254,27 @@ def render_slave(engine, netsettings, threads):
if job.type == netrender.model.JOB_BLENDER:
# send image back to server
- filename = JOB_PREFIX + "%06d" % frame.number + ".exr"
+ filename = os.path.join(JOB_PREFIX, "%06d.exr" % frame.number)
# thumbnail first
- if netsettings.slave_thumb:
+ if netsettings.use_slave_thumb:
thumbname = thumbnail(filename)
f = open(thumbname, 'rb')
conn.request("PUT", "/thumb", f, headers=headers)
f.close()
- conn.getresponse()
+ responseStatus(conn)
+
f = open(filename, 'rb')
conn.request("PUT", "/render", f, headers=headers)
f.close()
- if conn.getresponse().status == http.client.NO_CONTENT:
+ if responseStatus(conn) == http.client.NO_CONTENT:
continue
elif job.type == netrender.model.JOB_PROCESS:
conn.request("PUT", "/render", headers=headers)
- if conn.getresponse().status == http.client.NO_CONTENT:
+ if responseStatus(conn) == http.client.NO_CONTENT:
continue
else:
headers["job-result"] = str(ERROR)
@@ -273,7 +282,7 @@ def render_slave(engine, netsettings, threads):
headers["job-frame"] = str(frame.number)
# send error result back to server
conn.request("PUT", "/render", headers=headers)
- if conn.getresponse().status == http.client.NO_CONTENT:
+ if responseStatus(conn) == http.client.NO_CONTENT:
continue
engine.update_stats("", "Network render connected to master, waiting for jobs")
@@ -288,7 +297,7 @@ def render_slave(engine, netsettings, threads):
conn.close()
- if netsettings.slave_clear:
+ if netsettings.use_slave_clear:
clearSlave(NODE_PREFIX)
if __name__ == "__main__":
diff --git a/release/scripts/io/netrender/ui.py b/release/scripts/io/netrender/ui.py
index c60b10c484a..c2d943f63f8 100644
--- a/release/scripts/io/netrender/ui.py
+++ b/release/scripts/io/netrender/ui.py
@@ -36,6 +36,11 @@ DISPATCHED = 1
DONE = 2
ERROR = 3
+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:
netrender.init_file = bpy.data.filepath
@@ -81,17 +86,21 @@ class RenderButtonsPanel():
bl_region_type = "WINDOW"
bl_context = "render"
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
-
- def poll(self, context):
+
+ @classmethod
+ def poll(cls, context):
rd = context.scene.render
- return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
+ return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES)
# Setting panel, use in the scene for now.
-@rnaType
class RENDER_PT_network_settings(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Network Settings"
COMPAT_ENGINES = {'NET_RENDER'}
+ @classmethod
+ def poll(cls, context):
+ return super(RENDER_PT_network_settings, cls).poll(context)
+
def draw(self, context):
layout = self.layout
@@ -122,15 +131,14 @@ class RENDER_PT_network_settings(bpy.types.Panel, RenderButtonsPanel):
layout.operator("render.netclientweb", icon='QUESTION')
-@rnaType
class RENDER_PT_network_slave_settings(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Slave Settings"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
- return (super().poll(context)
- and scene.network_render.mode == "RENDER_SLAVE")
+ return super(RENDER_PT_network_slave_settings, cls).poll(context) and scene.network_render.mode == "RENDER_SLAVE"
def draw(self, context):
layout = self.layout
@@ -139,23 +147,23 @@ class RENDER_PT_network_slave_settings(bpy.types.Panel, RenderButtonsPanel):
rd = scene.render
netsettings = scene.network_render
- layout.prop(netsettings, "slave_clear")
- layout.prop(netsettings, "slave_thumb")
- layout.prop(netsettings, "slave_outputlog")
+ layout.prop(netsettings, "use_slave_clear")
+ layout.prop(netsettings, "use_slave_thumb")
+ layout.prop(netsettings, "use_slave_output_log")
layout.label(text="Threads:")
layout.prop(rd, "threads_mode", expand=True)
sub = layout.column()
sub.enabled = rd.threads_mode == 'FIXED'
sub.prop(rd, "threads")
-@rnaType
+
class RENDER_PT_network_master_settings(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Master Settings"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
- return (super().poll(context)
- and scene.network_render.mode == "RENDER_MASTER")
+ return super(RENDER_PT_network_master_settings, cls).poll(context) and scene.network_render.mode == "RENDER_MASTER"
def draw(self, context):
layout = self.layout
@@ -163,18 +171,17 @@ class RENDER_PT_network_master_settings(bpy.types.Panel, RenderButtonsPanel):
scene = context.scene
netsettings = scene.network_render
- layout.prop(netsettings, "master_broadcast")
- layout.prop(netsettings, "master_clear")
+ layout.prop(netsettings, "use_master_broadcast")
+ layout.prop(netsettings, "use_master_clear")
-@rnaType
class RENDER_PT_network_job(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Job Settings"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
- return (super().poll(context)
- and scene.network_render.mode == "RENDER_CLIENT")
+ return super(RENDER_PT_network_job, cls).poll(context) and scene.network_render.mode == "RENDER_CLIENT"
def draw(self, context):
layout = self.layout
@@ -207,19 +214,18 @@ class RENDER_PT_network_job(bpy.types.Panel, RenderButtonsPanel):
row.prop(netsettings, "priority")
row.prop(netsettings, "chunks")
-@rnaType
class RENDER_PT_network_slaves(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Slaves Status"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
netsettings = scene.network_render
if netsettings.mode != "RENDER_CLIENT":
return False
verify_address(netsettings)
- return (super().poll(context)
- and netsettings.server_address != "[default]")
+ return super(RENDER_PT_network_slaves, cls).poll(context) and netsettings.server_address != "[default]"
def draw(self, context):
layout = self.layout
@@ -246,19 +252,18 @@ class RENDER_PT_network_slaves(bpy.types.Panel, RenderButtonsPanel):
layout.label(text="Seen: " + time.ctime(slave.last_seen))
layout.label(text="Stats: " + slave.stats)
-@rnaType
class RENDER_PT_network_slaves_blacklist(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Slaves Blacklist"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
netsettings = scene.network_render
if netsettings.mode != "RENDER_CLIENT":
return False
verify_address(netsettings)
- return (super().poll(context)
- and netsettings.server_address != "[default]")
+ return super(RENDER_PT_network_slaves_blacklist, cls).poll(context) and netsettings.server_address != "[default]"
def draw(self, context):
layout = self.layout
@@ -284,19 +289,18 @@ class RENDER_PT_network_slaves_blacklist(bpy.types.Panel, RenderButtonsPanel):
layout.label(text="Seen: " + time.ctime(slave.last_seen))
layout.label(text="Stats: " + slave.stats)
-@rnaType
class RENDER_PT_network_jobs(bpy.types.Panel, RenderButtonsPanel):
bl_label = "Jobs"
COMPAT_ENGINES = {'NET_RENDER'}
- def poll(self, context):
+ @classmethod
+ def poll(cls, context):
scene = context.scene
netsettings = scene.network_render
if netsettings.mode != "RENDER_CLIENT":
return False
verify_address(netsettings)
- return (super().poll(context)
- and netsettings.server_address != "[default]")
+ return super(RENDER_PT_network_jobs, cls).poll(context) and netsettings.server_address != "[default]"
def draw(self, context):
layout = self.layout
@@ -325,150 +329,148 @@ class RENDER_PT_network_jobs(bpy.types.Panel, RenderButtonsPanel):
layout.label(text="Done: %04i" % job.results[DONE])
layout.label(text="Error: %04i" % job.results[ERROR])
-@rnaType
class NetRenderSettings(bpy.types.IDPropertyGroup):
pass
-@rnaType
class NetRenderSlave(bpy.types.IDPropertyGroup):
pass
-@rnaType
class NetRenderJob(bpy.types.IDPropertyGroup):
pass
-bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings")
-
-NetRenderSettings.StringProperty( attr="server_address",
- name="Server address",
- description="IP or name of the master render server",
- maxlen = 128,
- default = "[default]")
-
-NetRenderSettings.IntProperty( attr="server_port",
- name="Server port",
- description="port of the master render server",
- default = 8000,
- min=1,
- max=65535)
-
-NetRenderSettings.BoolProperty( attr="master_broadcast",
- name="Broadcast",
- description="broadcast master server address on local network",
- default = True)
-
-NetRenderSettings.BoolProperty( attr="slave_clear",
- name="Clear on exit",
- description="delete downloaded files on exit",
- default = True)
-
-NetRenderSettings.BoolProperty( attr="slave_thumb",
- name="Generate thumbnails",
- description="Generate thumbnails on slaves instead of master",
- default = False)
-
-NetRenderSettings.BoolProperty( attr="slave_outputlog",
- name="Output render log on console",
- description="Output render text log to console as well as sending it to the master",
- default = True)
-
-NetRenderSettings.BoolProperty( attr="master_clear",
- name="Clear on exit",
- description="delete saved files on exit",
- default = False)
-
-default_path = os.environ.get("TEMP")
-
-if not default_path:
- if os.name == 'nt':
- default_path = "c:/tmp/"
- else:
- default_path = "/tmp/"
-elif not default_path.endswith(os.sep):
- default_path += os.sep
-
-NetRenderSettings.StringProperty( attr="path",
- name="Path",
- description="Path for temporary files",
- maxlen = 128,
- default = default_path,
- subtype='FILE_PATH')
-
-NetRenderSettings.StringProperty( attr="job_name",
- name="Job name",
- description="Name of the job",
- maxlen = 128,
- default = "[default]")
-
-NetRenderSettings.StringProperty( attr="job_category",
- name="Job category",
- description="Category of the job",
- maxlen = 128,
- default = "")
-
-NetRenderSettings.IntProperty( attr="chunks",
- name="Chunks",
- description="Number of frame to dispatch to each slave in one chunk",
- default = 5,
- min=1,
- max=65535)
-
-NetRenderSettings.IntProperty( attr="priority",
- name="Priority",
- description="Priority of the job",
- default = 1,
- min=1,
- max=10)
-
-NetRenderSettings.StringProperty( attr="job_id",
- name="Network job id",
- description="id of the last sent render job",
- maxlen = 64,
- default = "")
-
-NetRenderSettings.IntProperty( attr="active_slave_index",
- name="Index of the active slave",
- description="",
- default = -1,
- min= -1,
- max=65535)
-
-NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index",
- name="Index of the active slave",
- description="",
- default = -1,
- min= -1,
- max=65535)
-
-NetRenderSettings.IntProperty( attr="active_job_index",
- name="Index of the active job",
- description="",
- default = -1,
- min= -1,
- max=65535)
-
-NetRenderSettings.EnumProperty(attr="mode",
- items=(
- ("RENDER_CLIENT", "Client", "Act as render client"),
- ("RENDER_MASTER", "Master", "Act as render master"),
- ("RENDER_SLAVE", "Slave", "Act as render slave"),
- ),
- name="Network mode",
- description="Mode of operation of this instance",
- default="RENDER_CLIENT")
-
-NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="")
-NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="")
-NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="")
-
-NetRenderSlave.StringProperty( attr="name",
- name="Name of the slave",
- description="",
- maxlen = 64,
- default = "")
-
-NetRenderJob.StringProperty( attr="name",
- name="Name of the job",
- description="",
- maxlen = 128,
- default = "")
+def addProperties():
+ bpy.types.Scene.PointerProperty(attr="network_render", type=NetRenderSettings, name="Network Render", description="Network Render Settings")
+
+ NetRenderSettings.StringProperty( attr="server_address",
+ name="Server address",
+ description="IP or name of the master render server",
+ maxlen = 128,
+ default = "[default]")
+
+ NetRenderSettings.IntProperty( attr="server_port",
+ name="Server port",
+ description="port of the master render server",
+ default = 8000,
+ min=1,
+ max=65535)
+
+ NetRenderSettings.BoolProperty( attr="use_master_broadcast",
+ name="Broadcast",
+ description="broadcast master server address on local network",
+ default = True)
+
+ NetRenderSettings.BoolProperty( attr="use_slave_clear",
+ name="Clear on exit",
+ description="delete downloaded files on exit",
+ default = True)
+
+ NetRenderSettings.BoolProperty( attr="use_slave_thumb",
+ name="Generate thumbnails",
+ description="Generate thumbnails on slaves instead of master",
+ default = False)
+
+ NetRenderSettings.BoolProperty( attr="use_slave_output_log",
+ name="Output render log on console",
+ description="Output render text log to console as well as sending it to the master",
+ default = True)
+
+ NetRenderSettings.BoolProperty( attr="use_master_clear",
+ name="Clear on exit",
+ description="delete saved files on exit",
+ default = False)
+
+ default_path = os.environ.get("TEMP")
+
+ if not default_path:
+ if os.name == 'nt':
+ default_path = "c:/tmp/"
+ else:
+ default_path = "/tmp/"
+ elif not default_path.endswith(os.sep):
+ default_path += os.sep
+
+ NetRenderSettings.StringProperty( attr="path",
+ name="Path",
+ description="Path for temporary files",
+ maxlen = 128,
+ default = default_path,
+ subtype='FILE_PATH')
+
+ NetRenderSettings.StringProperty( attr="job_name",
+ name="Job name",
+ description="Name of the job",
+ maxlen = 128,
+ default = "[default]")
+
+ NetRenderSettings.StringProperty( attr="job_category",
+ name="Job category",
+ description="Category of the job",
+ maxlen = 128,
+ default = "")
+
+ NetRenderSettings.IntProperty( attr="chunks",
+ name="Chunks",
+ description="Number of frame to dispatch to each slave in one chunk",
+ default = 5,
+ min=1,
+ max=65535)
+
+ NetRenderSettings.IntProperty( attr="priority",
+ name="Priority",
+ description="Priority of the job",
+ default = 1,
+ min=1,
+ max=10)
+
+ NetRenderSettings.StringProperty( attr="job_id",
+ name="Network job id",
+ description="id of the last sent render job",
+ maxlen = 64,
+ default = "")
+
+ NetRenderSettings.IntProperty( attr="active_slave_index",
+ name="Index of the active slave",
+ description="",
+ default = -1,
+ min= -1,
+ max=65535)
+
+ NetRenderSettings.IntProperty( attr="active_blacklisted_slave_index",
+ name="Index of the active slave",
+ description="",
+ default = -1,
+ min= -1,
+ max=65535)
+
+ NetRenderSettings.IntProperty( attr="active_job_index",
+ name="Index of the active job",
+ description="",
+ default = -1,
+ min= -1,
+ max=65535)
+
+ NetRenderSettings.EnumProperty(attr="mode",
+ items=(
+ ("RENDER_CLIENT", "Client", "Act as render client"),
+ ("RENDER_MASTER", "Master", "Act as render master"),
+ ("RENDER_SLAVE", "Slave", "Act as render slave"),
+ ),
+ name="Network mode",
+ description="Mode of operation of this instance",
+ default="RENDER_CLIENT")
+
+ NetRenderSettings.CollectionProperty(attr="slaves", type=NetRenderSlave, name="Slaves", description="")
+ NetRenderSettings.CollectionProperty(attr="slaves_blacklist", type=NetRenderSlave, name="Slaves Blacklist", description="")
+ NetRenderSettings.CollectionProperty(attr="jobs", type=NetRenderJob, name="Job List", description="")
+
+ NetRenderSlave.StringProperty( attr="name",
+ name="Name of the slave",
+ description="",
+ maxlen = 64,
+ default = "")
+
+ NetRenderJob.StringProperty( attr="name",
+ name="Name of the job",
+ description="",
+ maxlen = 128,
+ default = "")
diff --git a/release/scripts/io/netrender/utils.py b/release/scripts/io/netrender/utils.py
index 6288b9747c0..81617ac0d30 100644
--- a/release/scripts/io/netrender/utils.py
+++ b/release/scripts/io/netrender/utils.py
@@ -57,9 +57,10 @@ FRAME_STATUS_TEXT = {
ERROR: "Error"
}
-def rnaType(rna_type):
- if bpy: bpy.types.register(rna_type)
- return rna_type
+def responseStatus(conn):
+ response = conn.getresponse()
+ response.read()
+ return response.status
def reporting(report, message, errorType = None):
if errorType:
@@ -171,20 +172,20 @@ def prefixPath(prefix_directory, file_path, prefix_path, force = False):
# if an absolute path, make sure path exists, if it doesn't, use relative local path
full_path = file_path
if force or not os.path.exists(full_path):
- p, n = os.path.split(full_path)
+ p, n = os.path.split(os.path.normpath(full_path))
if prefix_path and p.startswith(prefix_path):
if len(prefix_path) < len(p):
- directory = prefix_directory + p[len(prefix_path)+1:] + os.sep # +1 to remove separator
+ directory = os.path.join(prefix_directory, p[len(prefix_path)+1:]) # +1 to remove separator
if not os.path.exists(directory):
os.mkdir(directory)
else:
directory = prefix_directory
- full_path = directory + n
+ full_path = os.path.join(directory, n)
else:
- full_path = prefix_directory + n
+ full_path = os.path.join(prefix_directory, n)
else:
- full_path = prefix_directory + file_path
+ full_path = (prefix_directory, file_path)
return full_path