netrender tab to spaces
This commit is contained in:
		@@ -22,129 +22,129 @@ from netrender.utils import *
 | 
			
		||||
import netrender.model
 | 
			
		||||
 | 
			
		||||
class RatingRule:
 | 
			
		||||
	def rate(self, job):
 | 
			
		||||
		return 0
 | 
			
		||||
    def rate(self, job):
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
class ExclusionRule:
 | 
			
		||||
	def test(self, job):
 | 
			
		||||
		return False
 | 
			
		||||
    def test(self, job):
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
class PriorityRule:
 | 
			
		||||
	def test(self, job):
 | 
			
		||||
		return False
 | 
			
		||||
    def test(self, job):
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
class Balancer:
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		self.rules = []
 | 
			
		||||
		self.priorities = []
 | 
			
		||||
		self.exceptions = []
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.rules = []
 | 
			
		||||
        self.priorities = []
 | 
			
		||||
        self.exceptions = []
 | 
			
		||||
 | 
			
		||||
	def addRule(self, rule):
 | 
			
		||||
		self.rules.append(rule)
 | 
			
		||||
    def addRule(self, rule):
 | 
			
		||||
        self.rules.append(rule)
 | 
			
		||||
 | 
			
		||||
	def addPriority(self, priority):
 | 
			
		||||
		self.priorities.append(priority)
 | 
			
		||||
    def addPriority(self, priority):
 | 
			
		||||
        self.priorities.append(priority)
 | 
			
		||||
 | 
			
		||||
	def addException(self, exception):
 | 
			
		||||
		self.exceptions.append(exception)
 | 
			
		||||
    def addException(self, exception):
 | 
			
		||||
        self.exceptions.append(exception)
 | 
			
		||||
 | 
			
		||||
	def applyRules(self, job):
 | 
			
		||||
		return sum((rule.rate(job) for rule in self.rules))
 | 
			
		||||
    def applyRules(self, job):
 | 
			
		||||
        return sum((rule.rate(job) for rule in self.rules))
 | 
			
		||||
 | 
			
		||||
	def applyPriorities(self, job):
 | 
			
		||||
		for priority in self.priorities:
 | 
			
		||||
			if priority.test(job):
 | 
			
		||||
				return True # priorities are first
 | 
			
		||||
    def applyPriorities(self, job):
 | 
			
		||||
        for priority in self.priorities:
 | 
			
		||||
            if priority.test(job):
 | 
			
		||||
                return True # priorities are first
 | 
			
		||||
 | 
			
		||||
		return False
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
	def applyExceptions(self, job):
 | 
			
		||||
		for exception in self.exceptions:
 | 
			
		||||
			if exception.test(job):
 | 
			
		||||
				return True # exceptions are last
 | 
			
		||||
    def applyExceptions(self, job):
 | 
			
		||||
        for exception in self.exceptions:
 | 
			
		||||
            if exception.test(job):
 | 
			
		||||
                return True # exceptions are last
 | 
			
		||||
 | 
			
		||||
		return False
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
	def sortKey(self, job):
 | 
			
		||||
		return (1 if self.applyExceptions(job) else 0, # exceptions after
 | 
			
		||||
						0 if self.applyPriorities(job) else 1, # priorities first
 | 
			
		||||
						self.applyRules(job))
 | 
			
		||||
    def sortKey(self, job):
 | 
			
		||||
        return (1 if self.applyExceptions(job) else 0, # exceptions after
 | 
			
		||||
                        0 if self.applyPriorities(job) else 1, # priorities first
 | 
			
		||||
                        self.applyRules(job))
 | 
			
		||||
 | 
			
		||||
	def balance(self, jobs):
 | 
			
		||||
		if jobs:
 | 
			
		||||
			# use inline copy to make sure the list is still accessible while sorting
 | 
			
		||||
			jobs[:] = sorted(jobs, key=self.sortKey)
 | 
			
		||||
			return jobs[0]
 | 
			
		||||
		else:
 | 
			
		||||
			return None
 | 
			
		||||
    def balance(self, jobs):
 | 
			
		||||
        if jobs:
 | 
			
		||||
            # use inline copy to make sure the list is still accessible while sorting
 | 
			
		||||
            jobs[:] = sorted(jobs, key=self.sortKey)
 | 
			
		||||
            return jobs[0]
 | 
			
		||||
        else:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
# ==========================
 | 
			
		||||
 | 
			
		||||
class RatingUsage(RatingRule):
 | 
			
		||||
	def __str__(self):
 | 
			
		||||
		return "Usage rating"
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return "Usage rating"
 | 
			
		||||
 | 
			
		||||
	def rate(self, job):
 | 
			
		||||
		# less usage is better
 | 
			
		||||
		return job.usage / job.priority
 | 
			
		||||
    def rate(self, job):
 | 
			
		||||
        # less usage is better
 | 
			
		||||
        return job.usage / job.priority
 | 
			
		||||
 | 
			
		||||
class RatingUsageByCategory(RatingRule):
 | 
			
		||||
	def __str__(self):
 | 
			
		||||
		return "Usage per category rating"
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return "Usage per category rating"
 | 
			
		||||
 | 
			
		||||
	def __init__(self, get_jobs):
 | 
			
		||||
		self.getJobs = get_jobs
 | 
			
		||||
	def rate(self, job):
 | 
			
		||||
		total_category_usage = sum([j.usage for j in self.getJobs() if j.category == job.category])
 | 
			
		||||
		maximum_priority = max([j.priority for j in self.getJobs() if j.category == job.category])
 | 
			
		||||
    def __init__(self, get_jobs):
 | 
			
		||||
        self.getJobs = get_jobs
 | 
			
		||||
    def rate(self, job):
 | 
			
		||||
        total_category_usage = sum([j.usage for j in self.getJobs() if j.category == job.category])
 | 
			
		||||
        maximum_priority = max([j.priority for j in self.getJobs() if j.category == job.category])
 | 
			
		||||
 | 
			
		||||
		# less usage is better
 | 
			
		||||
		return total_category_usage / maximum_priority
 | 
			
		||||
        # less usage is better
 | 
			
		||||
        return total_category_usage / maximum_priority
 | 
			
		||||
 | 
			
		||||
class NewJobPriority(PriorityRule):
 | 
			
		||||
	def str_limit(self):
 | 
			
		||||
		return "less than %i frame%s done" % (self.limit, "s" if self.limit > 1 else "")
 | 
			
		||||
    def str_limit(self):
 | 
			
		||||
        return "less than %i frame%s done" % (self.limit, "s" if self.limit > 1 else "")
 | 
			
		||||
 | 
			
		||||
	def __str__(self):
 | 
			
		||||
		return "Priority to new jobs"
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return "Priority to new jobs"
 | 
			
		||||
 | 
			
		||||
	def __init__(self, limit = 1):
 | 
			
		||||
		self.limit = limit
 | 
			
		||||
    def __init__(self, limit = 1):
 | 
			
		||||
        self.limit = limit
 | 
			
		||||
 | 
			
		||||
	def test(self, job):
 | 
			
		||||
		return job.countFrames(status = DONE) < self.limit
 | 
			
		||||
    def test(self, job):
 | 
			
		||||
        return job.countFrames(status = DONE) < self.limit
 | 
			
		||||
 | 
			
		||||
class MinimumTimeBetweenDispatchPriority(PriorityRule):
 | 
			
		||||
	def str_limit(self):
 | 
			
		||||
		return "more than %i minute%s since last" % (self.limit, "s" if self.limit > 1 else "")
 | 
			
		||||
    def str_limit(self):
 | 
			
		||||
        return "more than %i minute%s since last" % (self.limit, "s" if self.limit > 1 else "")
 | 
			
		||||
 | 
			
		||||
	def __str__(self):
 | 
			
		||||
		return "Priority to jobs that haven't been dispatched recently"
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return "Priority to jobs that haven't been dispatched recently"
 | 
			
		||||
 | 
			
		||||
	def __init__(self, limit = 10):
 | 
			
		||||
		self.limit = limit
 | 
			
		||||
    def __init__(self, limit = 10):
 | 
			
		||||
        self.limit = limit
 | 
			
		||||
 | 
			
		||||
	def test(self, job):
 | 
			
		||||
		return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit
 | 
			
		||||
    def test(self, job):
 | 
			
		||||
        return job.countFrames(status = DISPATCHED) == 0 and (time.time() - job.last_dispatched) / 60 > self.limit
 | 
			
		||||
 | 
			
		||||
class ExcludeQueuedEmptyJob(ExclusionRule):
 | 
			
		||||
	def __str__(self):
 | 
			
		||||
		return "Exclude queued and empty jobs"
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return "Exclude queued and empty jobs"
 | 
			
		||||
 | 
			
		||||
	def test(self, job):
 | 
			
		||||
		return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0
 | 
			
		||||
    def test(self, job):
 | 
			
		||||
        return job.status != JOB_QUEUED or job.countFrames(status = QUEUED) == 0
 | 
			
		||||
 | 
			
		||||
class ExcludeSlavesLimit(ExclusionRule):
 | 
			
		||||
	def str_limit(self):
 | 
			
		||||
		return "more than %.0f%% of all slaves" % (self.limit * 100)
 | 
			
		||||
    def str_limit(self):
 | 
			
		||||
        return "more than %.0f%% of all slaves" % (self.limit * 100)
 | 
			
		||||
 | 
			
		||||
	def __str__(self):
 | 
			
		||||
		return "Exclude jobs that would use too many slaves"
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return "Exclude jobs that would use too many slaves"
 | 
			
		||||
 | 
			
		||||
	def __init__(self, count_jobs, count_slaves, limit = 0.75):
 | 
			
		||||
		self.count_jobs = count_jobs
 | 
			
		||||
		self.count_slaves = count_slaves
 | 
			
		||||
		self.limit = limit
 | 
			
		||||
    def __init__(self, count_jobs, count_slaves, limit = 0.75):
 | 
			
		||||
        self.count_jobs = count_jobs
 | 
			
		||||
        self.count_slaves = count_slaves
 | 
			
		||||
        self.limit = limit
 | 
			
		||||
 | 
			
		||||
	def test(self, job):
 | 
			
		||||
		return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit )
 | 
			
		||||
    def test(self, job):
 | 
			
		||||
        return not ( self.count_jobs() == 1 or self.count_slaves() <= 1 or float(job.countSlaves() + 1) / self.count_slaves() <= self.limit )
 | 
			
		||||
 
 | 
			
		||||
@@ -28,253 +28,253 @@ import netrender.master as master
 | 
			
		||||
from netrender.utils import *
 | 
			
		||||
 | 
			
		||||
def addFluidFiles(job, path):
 | 
			
		||||
	if os.path.exists(path):
 | 
			
		||||
		pattern = re.compile("fluidsurface_(final|preview)_([0-9]+)\.(bobj|bvel)\.gz")
 | 
			
		||||
    if os.path.exists(path):
 | 
			
		||||
        pattern = re.compile("fluidsurface_(final|preview)_([0-9]+)\.(bobj|bvel)\.gz")
 | 
			
		||||
 | 
			
		||||
		for fluid_file in sorted(os.listdir(path)):
 | 
			
		||||
			match = pattern.match(fluid_file)
 | 
			
		||||
        for fluid_file in sorted(os.listdir(path)):
 | 
			
		||||
            match = pattern.match(fluid_file)
 | 
			
		||||
 | 
			
		||||
			if match:
 | 
			
		||||
				# fluid frames starts at 0, which explains the +1
 | 
			
		||||
				# This is stupid
 | 
			
		||||
				current_frame = int(match.groups()[1]) + 1 
 | 
			
		||||
				job.addFile(path + fluid_file, current_frame, current_frame)
 | 
			
		||||
            if match:
 | 
			
		||||
                # fluid frames starts at 0, which explains the +1
 | 
			
		||||
                # This is stupid
 | 
			
		||||
                current_frame = int(match.groups()[1]) + 1
 | 
			
		||||
                job.addFile(path + fluid_file, current_frame, current_frame)
 | 
			
		||||
 | 
			
		||||
def addPointCache(job, ob, point_cache, default_path):
 | 
			
		||||
	if not point_cache.disk_cache:
 | 
			
		||||
		return
 | 
			
		||||
    if not point_cache.disk_cache:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	name = point_cache.name
 | 
			
		||||
	if name == "":
 | 
			
		||||
		name = "".join(["%02X" % ord(c) for c in ob.name])
 | 
			
		||||
    name = point_cache.name
 | 
			
		||||
    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.utils.expandpath(point_cache.filepath) if point_cache.external else default_path
 | 
			
		||||
 | 
			
		||||
	index = "%02i" % point_cache.index
 | 
			
		||||
    index = "%02i" % point_cache.index
 | 
			
		||||
 | 
			
		||||
	if os.path.exists(cache_path):
 | 
			
		||||
		pattern = re.compile(name + "_([0-9]+)_" + index + "\.bphys")
 | 
			
		||||
    if os.path.exists(cache_path):
 | 
			
		||||
        pattern = re.compile(name + "_([0-9]+)_" + index + "\.bphys")
 | 
			
		||||
 | 
			
		||||
		cache_files = []
 | 
			
		||||
        cache_files = []
 | 
			
		||||
 | 
			
		||||
		for cache_file in sorted(os.listdir(cache_path)):
 | 
			
		||||
			match = pattern.match(cache_file)
 | 
			
		||||
        for cache_file in sorted(os.listdir(cache_path)):
 | 
			
		||||
            match = pattern.match(cache_file)
 | 
			
		||||
 | 
			
		||||
			if match:
 | 
			
		||||
				cache_frame = int(match.groups()[0])
 | 
			
		||||
				cache_files.append((cache_frame, cache_file))
 | 
			
		||||
            if match:
 | 
			
		||||
                cache_frame = int(match.groups()[0])
 | 
			
		||||
                cache_files.append((cache_frame, cache_file))
 | 
			
		||||
 | 
			
		||||
		cache_files.sort()
 | 
			
		||||
        cache_files.sort()
 | 
			
		||||
 | 
			
		||||
		if len(cache_files) == 1:
 | 
			
		||||
			cache_frame, cache_file = cache_files[0]
 | 
			
		||||
			job.addFile(cache_path + cache_file, cache_frame, cache_frame)
 | 
			
		||||
		else:
 | 
			
		||||
			for i in range(len(cache_files)):
 | 
			
		||||
				current_item = cache_files[i]
 | 
			
		||||
				next_item = cache_files[i+1] if i + 1 < len(cache_files) else None
 | 
			
		||||
				previous_item = cache_files[i - 1] if i > 0 else None
 | 
			
		||||
        if len(cache_files) == 1:
 | 
			
		||||
            cache_frame, cache_file = cache_files[0]
 | 
			
		||||
            job.addFile(cache_path + cache_file, cache_frame, cache_frame)
 | 
			
		||||
        else:
 | 
			
		||||
            for i in range(len(cache_files)):
 | 
			
		||||
                current_item = cache_files[i]
 | 
			
		||||
                next_item = cache_files[i+1] if i + 1 < len(cache_files) else None
 | 
			
		||||
                previous_item = cache_files[i - 1] if i > 0 else None
 | 
			
		||||
 | 
			
		||||
				current_frame, current_file = current_item
 | 
			
		||||
                current_frame, current_file = current_item
 | 
			
		||||
 | 
			
		||||
				if  not next_item and not previous_item:
 | 
			
		||||
					job.addFile(cache_path + current_file, current_frame, current_frame)
 | 
			
		||||
				elif next_item and not previous_item:
 | 
			
		||||
					next_frame = next_item[0]
 | 
			
		||||
					job.addFile(cache_path + current_file, current_frame, next_frame - 1)
 | 
			
		||||
				elif not next_item and previous_item:
 | 
			
		||||
					previous_frame = previous_item[0]
 | 
			
		||||
					job.addFile(cache_path + current_file, previous_frame + 1, current_frame)
 | 
			
		||||
				else:
 | 
			
		||||
					next_frame = next_item[0]
 | 
			
		||||
					previous_frame = previous_item[0]
 | 
			
		||||
					job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1)
 | 
			
		||||
                if  not next_item and not previous_item:
 | 
			
		||||
                    job.addFile(cache_path + current_file, current_frame, current_frame)
 | 
			
		||||
                elif next_item and not previous_item:
 | 
			
		||||
                    next_frame = next_item[0]
 | 
			
		||||
                    job.addFile(cache_path + current_file, current_frame, next_frame - 1)
 | 
			
		||||
                elif not next_item and previous_item:
 | 
			
		||||
                    previous_frame = previous_item[0]
 | 
			
		||||
                    job.addFile(cache_path + current_file, previous_frame + 1, current_frame)
 | 
			
		||||
                else:
 | 
			
		||||
                    next_frame = next_item[0]
 | 
			
		||||
                    previous_frame = previous_item[0]
 | 
			
		||||
                    job.addFile(cache_path + current_file, previous_frame + 1, next_frame - 1)
 | 
			
		||||
 | 
			
		||||
def clientSendJob(conn, scene, anim = False):
 | 
			
		||||
	netsettings = scene.network_render
 | 
			
		||||
	job = netrender.model.RenderJob()
 | 
			
		||||
    netsettings = scene.network_render
 | 
			
		||||
    job = netrender.model.RenderJob()
 | 
			
		||||
 | 
			
		||||
	if anim:
 | 
			
		||||
		for f in range(scene.start_frame, scene.end_frame + 1):
 | 
			
		||||
			job.addFrame(f)
 | 
			
		||||
	else:
 | 
			
		||||
		job.addFrame(scene.current_frame)
 | 
			
		||||
    if anim:
 | 
			
		||||
        for f in range(scene.start_frame, scene.end_frame + 1):
 | 
			
		||||
            job.addFrame(f)
 | 
			
		||||
    else:
 | 
			
		||||
        job.addFrame(scene.current_frame)
 | 
			
		||||
 | 
			
		||||
	filename = bpy.data.filename
 | 
			
		||||
	job.addFile(filename)
 | 
			
		||||
    filename = bpy.data.filename
 | 
			
		||||
    job.addFile(filename)
 | 
			
		||||
 | 
			
		||||
	job_name = netsettings.job_name
 | 
			
		||||
	path, name = os.path.split(filename)
 | 
			
		||||
	if job_name == "[default]":
 | 
			
		||||
		job_name = name
 | 
			
		||||
    job_name = netsettings.job_name
 | 
			
		||||
    path, name = os.path.split(filename)
 | 
			
		||||
    if job_name == "[default]":
 | 
			
		||||
        job_name = name
 | 
			
		||||
 | 
			
		||||
	###########################
 | 
			
		||||
	# LIBRARIES
 | 
			
		||||
	###########################
 | 
			
		||||
	for lib in bpy.data.libraries:
 | 
			
		||||
		job.addFile(bpy.utils.expandpath(lib.filename))
 | 
			
		||||
    ###########################
 | 
			
		||||
    # LIBRARIES
 | 
			
		||||
    ###########################
 | 
			
		||||
    for lib in bpy.data.libraries:
 | 
			
		||||
        job.addFile(bpy.utils.expandpath(lib.filename))
 | 
			
		||||
 | 
			
		||||
	###########################
 | 
			
		||||
	# IMAGES
 | 
			
		||||
	###########################
 | 
			
		||||
	for image in bpy.data.images:
 | 
			
		||||
		if image.source == "FILE" and not image.packed_file:
 | 
			
		||||
			job.addFile(bpy.utils.expandpath(image.filename))
 | 
			
		||||
    ###########################
 | 
			
		||||
    # IMAGES
 | 
			
		||||
    ###########################
 | 
			
		||||
    for image in bpy.data.images:
 | 
			
		||||
        if image.source == "FILE" and not image.packed_file:
 | 
			
		||||
            job.addFile(bpy.utils.expandpath(image.filename))
 | 
			
		||||
 | 
			
		||||
	###########################
 | 
			
		||||
	# FLUID + POINT CACHE
 | 
			
		||||
	###########################
 | 
			
		||||
	root, ext = os.path.splitext(name)
 | 
			
		||||
	default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
 | 
			
		||||
    ###########################
 | 
			
		||||
    # FLUID + POINT CACHE
 | 
			
		||||
    ###########################
 | 
			
		||||
    root, ext = os.path.splitext(name)
 | 
			
		||||
    default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
 | 
			
		||||
 | 
			
		||||
	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))
 | 
			
		||||
			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:
 | 
			
		||||
					addPointCache(job, object, modifier.domain_settings.point_cache_high, default_path)
 | 
			
		||||
    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))
 | 
			
		||||
            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:
 | 
			
		||||
                    addPointCache(job, object, modifier.domain_settings.point_cache_high, default_path)
 | 
			
		||||
 | 
			
		||||
		# particles modifier are stupid and don't contain data
 | 
			
		||||
		# we have to go through the object property
 | 
			
		||||
		for psys in object.particle_systems:
 | 
			
		||||
			addPointCache(job, object, psys.point_cache, default_path)
 | 
			
		||||
        # particles modifier are stupid and don't contain data
 | 
			
		||||
        # we have to go through the object property
 | 
			
		||||
        for psys in object.particle_systems:
 | 
			
		||||
            addPointCache(job, object, psys.point_cache, default_path)
 | 
			
		||||
 | 
			
		||||
	#print(job.files)
 | 
			
		||||
    #print(job.files)
 | 
			
		||||
 | 
			
		||||
	job.name = job_name
 | 
			
		||||
	job.category = netsettings.job_category
 | 
			
		||||
    job.name = job_name
 | 
			
		||||
    job.category = netsettings.job_category
 | 
			
		||||
 | 
			
		||||
	for slave in netrender.blacklist:
 | 
			
		||||
		job.blacklist.append(slave.id)
 | 
			
		||||
    for slave in netrender.blacklist:
 | 
			
		||||
        job.blacklist.append(slave.id)
 | 
			
		||||
 | 
			
		||||
	job.chunks = netsettings.chunks
 | 
			
		||||
	job.priority = netsettings.priority
 | 
			
		||||
    job.chunks = netsettings.chunks
 | 
			
		||||
    job.priority = netsettings.priority
 | 
			
		||||
 | 
			
		||||
	# try to send path first
 | 
			
		||||
	conn.request("POST", "/job", repr(job.serialize()))
 | 
			
		||||
	response = conn.getresponse()
 | 
			
		||||
    # try to send path first
 | 
			
		||||
    conn.request("POST", "/job", repr(job.serialize()))
 | 
			
		||||
    response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
	job_id = response.getheader("job-id")
 | 
			
		||||
    job_id = response.getheader("job-id")
 | 
			
		||||
 | 
			
		||||
	# if not ACCEPTED (but not processed), send files
 | 
			
		||||
	if response.status == http.client.ACCEPTED:
 | 
			
		||||
		for rfile in job.files:
 | 
			
		||||
			f = open(rfile.filepath, "rb")
 | 
			
		||||
			conn.request("PUT", fileURL(job_id, rfile.index), f)
 | 
			
		||||
			f.close()
 | 
			
		||||
			response = conn.getresponse()
 | 
			
		||||
    # if not ACCEPTED (but not processed), send files
 | 
			
		||||
    if response.status == http.client.ACCEPTED:
 | 
			
		||||
        for rfile in job.files:
 | 
			
		||||
            f = open(rfile.filepath, "rb")
 | 
			
		||||
            conn.request("PUT", fileURL(job_id, rfile.index), f)
 | 
			
		||||
            f.close()
 | 
			
		||||
            response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
	# server will reply with ACCEPTED until all files are found
 | 
			
		||||
    # server will reply with ACCEPTED until all files are found
 | 
			
		||||
 | 
			
		||||
	return job_id
 | 
			
		||||
    return job_id
 | 
			
		||||
 | 
			
		||||
def requestResult(conn, job_id, frame):
 | 
			
		||||
	conn.request("GET", renderURL(job_id, frame))
 | 
			
		||||
    conn.request("GET", renderURL(job_id, frame))
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class NetworkRenderEngine(bpy.types.RenderEngine):
 | 
			
		||||
	bl_idname = 'NET_RENDER'
 | 
			
		||||
	bl_label = "Network Render"
 | 
			
		||||
	def render(self, scene):
 | 
			
		||||
		if scene.network_render.mode == "RENDER_CLIENT":
 | 
			
		||||
			self.render_client(scene)
 | 
			
		||||
		elif scene.network_render.mode == "RENDER_SLAVE":
 | 
			
		||||
			self.render_slave(scene)
 | 
			
		||||
		elif scene.network_render.mode == "RENDER_MASTER":
 | 
			
		||||
			self.render_master(scene)
 | 
			
		||||
		else:
 | 
			
		||||
			print("UNKNOWN OPERATION MODE")
 | 
			
		||||
    bl_idname = 'NET_RENDER'
 | 
			
		||||
    bl_label = "Network Render"
 | 
			
		||||
    def render(self, scene):
 | 
			
		||||
        if scene.network_render.mode == "RENDER_CLIENT":
 | 
			
		||||
            self.render_client(scene)
 | 
			
		||||
        elif scene.network_render.mode == "RENDER_SLAVE":
 | 
			
		||||
            self.render_slave(scene)
 | 
			
		||||
        elif scene.network_render.mode == "RENDER_MASTER":
 | 
			
		||||
            self.render_master(scene)
 | 
			
		||||
        else:
 | 
			
		||||
            print("UNKNOWN OPERATION MODE")
 | 
			
		||||
 | 
			
		||||
	def render_master(self, scene):
 | 
			
		||||
		netsettings = scene.network_render
 | 
			
		||||
    def render_master(self, scene):
 | 
			
		||||
        netsettings = scene.network_render
 | 
			
		||||
 | 
			
		||||
		address = "" if netsettings.server_address == "[default]" else netsettings.server_address
 | 
			
		||||
        address = "" if netsettings.server_address == "[default]" else netsettings.server_address
 | 
			
		||||
 | 
			
		||||
		master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break)
 | 
			
		||||
        master.runMaster((address, netsettings.server_port), netsettings.server_broadcast, netsettings.path, self.update_stats, self.test_break)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	def render_slave(self, scene):
 | 
			
		||||
		slave.render_slave(self, scene.network_render)
 | 
			
		||||
    def render_slave(self, scene):
 | 
			
		||||
        slave.render_slave(self, scene.network_render)
 | 
			
		||||
 | 
			
		||||
	def render_client(self, scene):
 | 
			
		||||
		netsettings = scene.network_render
 | 
			
		||||
		self.update_stats("", "Network render client initiation")
 | 
			
		||||
    def render_client(self, scene):
 | 
			
		||||
        netsettings = scene.network_render
 | 
			
		||||
        self.update_stats("", "Network render client initiation")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		conn = clientConnection(netsettings.server_address, netsettings.server_port)
 | 
			
		||||
        conn = clientConnection(netsettings.server_address, netsettings.server_port)
 | 
			
		||||
 | 
			
		||||
		if conn:
 | 
			
		||||
			# Sending file
 | 
			
		||||
        if conn:
 | 
			
		||||
            # Sending file
 | 
			
		||||
 | 
			
		||||
			self.update_stats("", "Network render exporting")
 | 
			
		||||
            self.update_stats("", "Network render exporting")
 | 
			
		||||
 | 
			
		||||
			new_job = False
 | 
			
		||||
            new_job = False
 | 
			
		||||
 | 
			
		||||
			job_id = netsettings.job_id
 | 
			
		||||
            job_id = netsettings.job_id
 | 
			
		||||
 | 
			
		||||
			# reading back result
 | 
			
		||||
            # reading back result
 | 
			
		||||
 | 
			
		||||
			self.update_stats("", "Network render waiting for results")
 | 
			
		||||
            self.update_stats("", "Network render waiting for results")
 | 
			
		||||
 | 
			
		||||
			requestResult(conn, job_id, scene.current_frame)
 | 
			
		||||
			response = conn.getresponse()
 | 
			
		||||
            requestResult(conn, job_id, scene.current_frame)
 | 
			
		||||
            response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
			if response.status == http.client.NO_CONTENT:
 | 
			
		||||
				new_job = True
 | 
			
		||||
				netsettings.job_id = clientSendJob(conn, scene)
 | 
			
		||||
				job_id = netsettings.job_id 
 | 
			
		||||
            if response.status == http.client.NO_CONTENT:
 | 
			
		||||
                new_job = True
 | 
			
		||||
                netsettings.job_id = clientSendJob(conn, scene)
 | 
			
		||||
                job_id = netsettings.job_id
 | 
			
		||||
 | 
			
		||||
				requestResult(conn, job_id, scene.current_frame)
 | 
			
		||||
				response = conn.getresponse()
 | 
			
		||||
                requestResult(conn, job_id, scene.current_frame)
 | 
			
		||||
                response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
			while response.status == http.client.ACCEPTED and not self.test_break():
 | 
			
		||||
				time.sleep(1)
 | 
			
		||||
				requestResult(conn, job_id, scene.current_frame)
 | 
			
		||||
				response = conn.getresponse()
 | 
			
		||||
            while response.status == http.client.ACCEPTED and not self.test_break():
 | 
			
		||||
                time.sleep(1)
 | 
			
		||||
                requestResult(conn, job_id, scene.current_frame)
 | 
			
		||||
                response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
			# cancel new jobs (animate on network) on break
 | 
			
		||||
			if self.test_break() and new_job:
 | 
			
		||||
				conn.request("POST", cancelURL(job_id))
 | 
			
		||||
				response = conn.getresponse()
 | 
			
		||||
				print( response.status, response.reason )
 | 
			
		||||
				netsettings.job_id = 0
 | 
			
		||||
            # cancel new jobs (animate on network) on break
 | 
			
		||||
            if self.test_break() and new_job:
 | 
			
		||||
                conn.request("POST", cancelURL(job_id))
 | 
			
		||||
                response = conn.getresponse()
 | 
			
		||||
                print( response.status, response.reason )
 | 
			
		||||
                netsettings.job_id = 0
 | 
			
		||||
 | 
			
		||||
			if response.status != http.client.OK:
 | 
			
		||||
				conn.close()
 | 
			
		||||
				return
 | 
			
		||||
            if response.status != http.client.OK:
 | 
			
		||||
                conn.close()
 | 
			
		||||
                return
 | 
			
		||||
 | 
			
		||||
			r = scene.render_data
 | 
			
		||||
			x= int(r.resolution_x*r.resolution_percentage*0.01)
 | 
			
		||||
			y= int(r.resolution_y*r.resolution_percentage*0.01)
 | 
			
		||||
            r = scene.render_data
 | 
			
		||||
            x= int(r.resolution_x*r.resolution_percentage*0.01)
 | 
			
		||||
            y= int(r.resolution_y*r.resolution_percentage*0.01)
 | 
			
		||||
 | 
			
		||||
			f = open(netsettings.path + "output.exr", "wb")
 | 
			
		||||
			buf = response.read(1024)
 | 
			
		||||
            f = open(netsettings.path + "output.exr", "wb")
 | 
			
		||||
            buf = response.read(1024)
 | 
			
		||||
 | 
			
		||||
			while buf:
 | 
			
		||||
				f.write(buf)
 | 
			
		||||
				buf = response.read(1024)
 | 
			
		||||
            while buf:
 | 
			
		||||
                f.write(buf)
 | 
			
		||||
                buf = response.read(1024)
 | 
			
		||||
 | 
			
		||||
			f.close()
 | 
			
		||||
            f.close()
 | 
			
		||||
 | 
			
		||||
			result = self.begin_result(0, 0, x, y)
 | 
			
		||||
			result.load_from_file(netsettings.path + "output.exr", 0, 0)
 | 
			
		||||
			self.end_result(result)
 | 
			
		||||
            result = self.begin_result(0, 0, x, y)
 | 
			
		||||
            result.load_from_file(netsettings.path + "output.exr", 0, 0)
 | 
			
		||||
            self.end_result(result)
 | 
			
		||||
 | 
			
		||||
			conn.close()
 | 
			
		||||
            conn.close()
 | 
			
		||||
 | 
			
		||||
def compatible(module):
 | 
			
		||||
	module = __import__(module)
 | 
			
		||||
	for subclass in module.__dict__.values():
 | 
			
		||||
		try:		subclass.COMPAT_ENGINES.add('NET_RENDER')
 | 
			
		||||
		except:	pass
 | 
			
		||||
	del module
 | 
			
		||||
    module = __import__(module)
 | 
			
		||||
    for subclass in module.__dict__.values():
 | 
			
		||||
        try:		subclass.COMPAT_ENGINES.add('NET_RENDER')
 | 
			
		||||
        except:	pass
 | 
			
		||||
    del module
 | 
			
		||||
 | 
			
		||||
compatible("properties_render")
 | 
			
		||||
compatible("properties_world")
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -24,226 +24,226 @@ from netrender.utils import *
 | 
			
		||||
src_folder = os.path.split(__file__)[0]
 | 
			
		||||
 | 
			
		||||
def get(handler):
 | 
			
		||||
	def output(text):
 | 
			
		||||
		handler.wfile.write(bytes(text, encoding='utf8'))
 | 
			
		||||
    def output(text):
 | 
			
		||||
        handler.wfile.write(bytes(text, encoding='utf8'))
 | 
			
		||||
 | 
			
		||||
	def head(title):
 | 
			
		||||
		output("<html><head>")
 | 
			
		||||
		output("<script src='/html/netrender.js' type='text/javascript'></script>")
 | 
			
		||||
    def head(title):
 | 
			
		||||
        output("<html><head>")
 | 
			
		||||
        output("<script src='/html/netrender.js' type='text/javascript'></script>")
 | 
			
		||||
#		output("<script src='/html/json2.js' type='text/javascript'></script>")
 | 
			
		||||
		output("<title>")
 | 
			
		||||
		output(title)
 | 
			
		||||
		output("</title></head><body>")
 | 
			
		||||
		output("<link rel='stylesheet' href='/html/netrender.css' type='text/css'>")
 | 
			
		||||
        output("<title>")
 | 
			
		||||
        output(title)
 | 
			
		||||
        output("</title></head><body>")
 | 
			
		||||
        output("<link rel='stylesheet' href='/html/netrender.css' type='text/css'>")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	def link(text, url):
 | 
			
		||||
		return "<a href='%s'>%s</a>" % (url, text)
 | 
			
		||||
    def link(text, url):
 | 
			
		||||
        return "<a href='%s'>%s</a>" % (url, text)
 | 
			
		||||
 | 
			
		||||
	def startTable(border=1, class_style = None, caption = None):
 | 
			
		||||
		output("<table border='%i'" % border)
 | 
			
		||||
    def startTable(border=1, class_style = None, caption = None):
 | 
			
		||||
        output("<table border='%i'" % border)
 | 
			
		||||
 | 
			
		||||
		if class_style:
 | 
			
		||||
			output(" class='%s'" % class_style)
 | 
			
		||||
        if class_style:
 | 
			
		||||
            output(" class='%s'" % class_style)
 | 
			
		||||
 | 
			
		||||
		output(">")
 | 
			
		||||
        output(">")
 | 
			
		||||
 | 
			
		||||
		if caption:
 | 
			
		||||
			output("<caption>%s</caption>" % caption)
 | 
			
		||||
        if caption:
 | 
			
		||||
            output("<caption>%s</caption>" % caption)
 | 
			
		||||
 | 
			
		||||
	def headerTable(*headers):
 | 
			
		||||
		output("<thead><tr>")
 | 
			
		||||
    def headerTable(*headers):
 | 
			
		||||
        output("<thead><tr>")
 | 
			
		||||
 | 
			
		||||
		for c in headers:
 | 
			
		||||
			output("<td>" + c + "</td>")
 | 
			
		||||
        for c in headers:
 | 
			
		||||
            output("<td>" + c + "</td>")
 | 
			
		||||
 | 
			
		||||
		output("</tr></thead>")
 | 
			
		||||
        output("</tr></thead>")
 | 
			
		||||
 | 
			
		||||
	def rowTable(*data, id = None, class_style = None, extra = None):
 | 
			
		||||
		output("<tr")
 | 
			
		||||
    def rowTable(*data, id = None, class_style = None, extra = None):
 | 
			
		||||
        output("<tr")
 | 
			
		||||
 | 
			
		||||
		if id:
 | 
			
		||||
			output(" id='%s'" % id)
 | 
			
		||||
        if id:
 | 
			
		||||
            output(" id='%s'" % id)
 | 
			
		||||
 | 
			
		||||
		if class_style:
 | 
			
		||||
			output(" class='%s'" % class_style)
 | 
			
		||||
        if class_style:
 | 
			
		||||
            output(" class='%s'" % class_style)
 | 
			
		||||
 | 
			
		||||
		if extra:
 | 
			
		||||
			output(" %s" % extra)
 | 
			
		||||
        if extra:
 | 
			
		||||
            output(" %s" % extra)
 | 
			
		||||
 | 
			
		||||
		output(">")
 | 
			
		||||
        output(">")
 | 
			
		||||
 | 
			
		||||
		for c in data:
 | 
			
		||||
			output("<td>" + str(c) + "</td>")
 | 
			
		||||
        for c in data:
 | 
			
		||||
            output("<td>" + str(c) + "</td>")
 | 
			
		||||
 | 
			
		||||
		output("</tr>")
 | 
			
		||||
        output("</tr>")
 | 
			
		||||
 | 
			
		||||
	def endTable():
 | 
			
		||||
		output("</table>")
 | 
			
		||||
    def endTable():
 | 
			
		||||
        output("</table>")
 | 
			
		||||
 | 
			
		||||
	if handler.path == "/html/netrender.js":
 | 
			
		||||
		f = open(os.path.join(src_folder, "netrender.js"), 'rb')
 | 
			
		||||
    if handler.path == "/html/netrender.js":
 | 
			
		||||
        f = open(os.path.join(src_folder, "netrender.js"), 'rb')
 | 
			
		||||
 | 
			
		||||
		handler.send_head(content = "text/javascript")
 | 
			
		||||
		shutil.copyfileobj(f, handler.wfile)
 | 
			
		||||
        handler.send_head(content = "text/javascript")
 | 
			
		||||
        shutil.copyfileobj(f, handler.wfile)
 | 
			
		||||
 | 
			
		||||
		f.close()		
 | 
			
		||||
	elif handler.path == "/html/netrender.css":
 | 
			
		||||
		f = open(os.path.join(src_folder, "netrender.css"), 'rb')
 | 
			
		||||
        f.close()
 | 
			
		||||
    elif handler.path == "/html/netrender.css":
 | 
			
		||||
        f = open(os.path.join(src_folder, "netrender.css"), 'rb')
 | 
			
		||||
 | 
			
		||||
		handler.send_head(content = "text/css")
 | 
			
		||||
		shutil.copyfileobj(f, handler.wfile)
 | 
			
		||||
        handler.send_head(content = "text/css")
 | 
			
		||||
        shutil.copyfileobj(f, handler.wfile)
 | 
			
		||||
 | 
			
		||||
		f.close()
 | 
			
		||||
	elif handler.path == "/html" or handler.path == "/":
 | 
			
		||||
		handler.send_head(content = "text/html")
 | 
			
		||||
		head("NetRender")
 | 
			
		||||
        f.close()
 | 
			
		||||
    elif handler.path == "/html" or handler.path == "/":
 | 
			
		||||
        handler.send_head(content = "text/html")
 | 
			
		||||
        head("NetRender")
 | 
			
		||||
 | 
			
		||||
		output("<h2>Master</h2>")
 | 
			
		||||
        output("<h2>Master</h2>")
 | 
			
		||||
 | 
			
		||||
		output("""<button title="remove all jobs" onclick="request('/clear', null);">CLEAR JOB LIST</button>""")
 | 
			
		||||
        output("""<button title="remove all jobs" onclick="request('/clear', null);">CLEAR JOB LIST</button>""")
 | 
			
		||||
 | 
			
		||||
		startTable(caption = "Rules", class_style = "rules")
 | 
			
		||||
        startTable(caption = "Rules", class_style = "rules")
 | 
			
		||||
 | 
			
		||||
		headerTable("type", "description", "limit")
 | 
			
		||||
        headerTable("type", "description", "limit")
 | 
			
		||||
 | 
			
		||||
		for rule in handler.server.balancer.rules:
 | 
			
		||||
			rowTable("rating", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
 | 
			
		||||
        for rule in handler.server.balancer.rules:
 | 
			
		||||
            rowTable("rating", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
 | 
			
		||||
 | 
			
		||||
		for rule in handler.server.balancer.priorities:
 | 
			
		||||
			rowTable("priority", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
 | 
			
		||||
        for rule in handler.server.balancer.priorities:
 | 
			
		||||
            rowTable("priority", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
 | 
			
		||||
 | 
			
		||||
		for rule in handler.server.balancer.exceptions:
 | 
			
		||||
			rowTable("exception", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
 | 
			
		||||
        for rule in handler.server.balancer.exceptions:
 | 
			
		||||
            rowTable("exception", rule, rule.str_limit() if hasattr(rule, "limit") else " ")
 | 
			
		||||
 | 
			
		||||
		endTable()
 | 
			
		||||
        endTable()
 | 
			
		||||
 | 
			
		||||
		output("<h2>Slaves</h2>")
 | 
			
		||||
        output("<h2>Slaves</h2>")
 | 
			
		||||
 | 
			
		||||
		startTable()
 | 
			
		||||
		headerTable("name", "address", "last seen", "stats", "job")
 | 
			
		||||
        startTable()
 | 
			
		||||
        headerTable("name", "address", "last seen", "stats", "job")
 | 
			
		||||
 | 
			
		||||
		for slave in handler.server.slaves:
 | 
			
		||||
			rowTable(slave.name, slave.address[0], time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None")
 | 
			
		||||
        for slave in handler.server.slaves:
 | 
			
		||||
            rowTable(slave.name, slave.address[0], time.ctime(slave.last_seen), slave.stats, link(slave.job.name, "/html/job" + slave.job.id) if slave.job else "None")
 | 
			
		||||
 | 
			
		||||
		endTable()
 | 
			
		||||
        endTable()
 | 
			
		||||
 | 
			
		||||
		output("<h2>Jobs</h2>")
 | 
			
		||||
        output("<h2>Jobs</h2>")
 | 
			
		||||
 | 
			
		||||
		startTable()
 | 
			
		||||
		headerTable(	
 | 
			
		||||
				                    " ",
 | 
			
		||||
				                    "id",
 | 
			
		||||
									"name",
 | 
			
		||||
									"category",
 | 
			
		||||
									"chunks",
 | 
			
		||||
									"priority",
 | 
			
		||||
									"usage",
 | 
			
		||||
									"wait",
 | 
			
		||||
				                    "status",
 | 
			
		||||
									"length",
 | 
			
		||||
									"done",
 | 
			
		||||
									"dispatched",
 | 
			
		||||
									"error",
 | 
			
		||||
									"first",
 | 
			
		||||
									"exception"
 | 
			
		||||
								)
 | 
			
		||||
        startTable()
 | 
			
		||||
        headerTable(
 | 
			
		||||
                                    " ",
 | 
			
		||||
                                    "id",
 | 
			
		||||
                                    "name",
 | 
			
		||||
                                    "category",
 | 
			
		||||
                                    "chunks",
 | 
			
		||||
                                    "priority",
 | 
			
		||||
                                    "usage",
 | 
			
		||||
                                    "wait",
 | 
			
		||||
                                    "status",
 | 
			
		||||
                                    "length",
 | 
			
		||||
                                    "done",
 | 
			
		||||
                                    "dispatched",
 | 
			
		||||
                                    "error",
 | 
			
		||||
                                    "first",
 | 
			
		||||
                                    "exception"
 | 
			
		||||
                                )
 | 
			
		||||
 | 
			
		||||
		handler.server.balance()
 | 
			
		||||
        handler.server.balance()
 | 
			
		||||
 | 
			
		||||
		for job in handler.server.jobs:
 | 
			
		||||
			results = job.framesStatus()
 | 
			
		||||
			rowTable(	
 | 
			
		||||
								"""<button title="cancel job" onclick="request('/cancel_%s', null);">X</button>""" % job.id +
 | 
			
		||||
								"""<button title="reset all frames" onclick="request('/resetall_%s_0', null);">R</button>""" % job.id,
 | 
			
		||||
								job.id,
 | 
			
		||||
								link(job.name, "/html/job" + job.id),
 | 
			
		||||
								job.category if job.category else "<i>None</i>",
 | 
			
		||||
								str(job.chunks) +
 | 
			
		||||
								"""<button title="increase priority" onclick="request('/edit_%s', "{'chunks': %i}");">+</button>""" % (job.id, job.chunks + 1) +								
 | 
			
		||||
								"""<button title="decrease priority" onclick="request('/edit_%s', "{'chunks': %i}");" %s>-</button>""" % (job.id, job.chunks - 1, "disabled=True" if job.chunks == 1 else ""),								
 | 
			
		||||
								str(job.priority) +
 | 
			
		||||
								"""<button title="increase chunks size" onclick="request('/edit_%s', "{'priority': %i}");">+</button>""" % (job.id, job.priority + 1) +								
 | 
			
		||||
								"""<button title="decrease chunks size" onclick="request('/edit_%s', "{'priority': %i}");" %s>-</button>""" % (job.id, job.priority - 1, "disabled=True" if job.priority == 1 else ""),								
 | 
			
		||||
								"%0.1f%%" % (job.usage * 100),
 | 
			
		||||
								"%is" % int(time.time() - job.last_dispatched),
 | 
			
		||||
								job.statusText(),
 | 
			
		||||
								len(job),
 | 
			
		||||
								results[DONE],
 | 
			
		||||
								results[DISPATCHED],
 | 
			
		||||
								str(results[ERROR]) +
 | 
			
		||||
								"""<button title="reset error frames" onclick="request('/reset_%s_0', null);" %s>R</button>""" % (job.id, "disabled=True" if not results[ERROR] else ""),
 | 
			
		||||
								handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job)
 | 
			
		||||
							)
 | 
			
		||||
        for job in handler.server.jobs:
 | 
			
		||||
            results = job.framesStatus()
 | 
			
		||||
            rowTable(
 | 
			
		||||
                                """<button title="cancel job" onclick="request('/cancel_%s', null);">X</button>""" % job.id +
 | 
			
		||||
                                """<button title="reset all frames" onclick="request('/resetall_%s_0', null);">R</button>""" % job.id,
 | 
			
		||||
                                job.id,
 | 
			
		||||
                                link(job.name, "/html/job" + job.id),
 | 
			
		||||
                                job.category if job.category else "<i>None</i>",
 | 
			
		||||
                                str(job.chunks) +
 | 
			
		||||
                                """<button title="increase priority" onclick="request('/edit_%s', "{'chunks': %i}");">+</button>""" % (job.id, job.chunks + 1) +
 | 
			
		||||
                                """<button title="decrease priority" onclick="request('/edit_%s', "{'chunks': %i}");" %s>-</button>""" % (job.id, job.chunks - 1, "disabled=True" if job.chunks == 1 else ""),
 | 
			
		||||
                                str(job.priority) +
 | 
			
		||||
                                """<button title="increase chunks size" onclick="request('/edit_%s', "{'priority': %i}");">+</button>""" % (job.id, job.priority + 1) +
 | 
			
		||||
                                """<button title="decrease chunks size" onclick="request('/edit_%s', "{'priority': %i}");" %s>-</button>""" % (job.id, job.priority - 1, "disabled=True" if job.priority == 1 else ""),
 | 
			
		||||
                                "%0.1f%%" % (job.usage * 100),
 | 
			
		||||
                                "%is" % int(time.time() - job.last_dispatched),
 | 
			
		||||
                                job.statusText(),
 | 
			
		||||
                                len(job),
 | 
			
		||||
                                results[DONE],
 | 
			
		||||
                                results[DISPATCHED],
 | 
			
		||||
                                str(results[ERROR]) +
 | 
			
		||||
                                """<button title="reset error frames" onclick="request('/reset_%s_0', null);" %s>R</button>""" % (job.id, "disabled=True" if not results[ERROR] else ""),
 | 
			
		||||
                                handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job)
 | 
			
		||||
                            )
 | 
			
		||||
 | 
			
		||||
		endTable()
 | 
			
		||||
        endTable()
 | 
			
		||||
 | 
			
		||||
		output("</body></html>")
 | 
			
		||||
        output("</body></html>")
 | 
			
		||||
 | 
			
		||||
	elif handler.path.startswith("/html/job"):
 | 
			
		||||
		handler.send_head(content = "text/html")
 | 
			
		||||
		job_id = handler.path[9:]
 | 
			
		||||
    elif handler.path.startswith("/html/job"):
 | 
			
		||||
        handler.send_head(content = "text/html")
 | 
			
		||||
        job_id = handler.path[9:]
 | 
			
		||||
 | 
			
		||||
		head("NetRender")
 | 
			
		||||
        head("NetRender")
 | 
			
		||||
 | 
			
		||||
		job = handler.server.getJobID(job_id)
 | 
			
		||||
        job = handler.server.getJobID(job_id)
 | 
			
		||||
 | 
			
		||||
		if job:
 | 
			
		||||
			output("<h2>Files</h2>")
 | 
			
		||||
        if job:
 | 
			
		||||
            output("<h2>Files</h2>")
 | 
			
		||||
 | 
			
		||||
			startTable()
 | 
			
		||||
			headerTable("path")
 | 
			
		||||
            startTable()
 | 
			
		||||
            headerTable("path")
 | 
			
		||||
 | 
			
		||||
			tot_cache = 0
 | 
			
		||||
			tot_fluid = 0
 | 
			
		||||
            tot_cache = 0
 | 
			
		||||
            tot_fluid = 0
 | 
			
		||||
 | 
			
		||||
			for file in job.files:
 | 
			
		||||
				if file.filepath.endswith(".bphys"):
 | 
			
		||||
					tot_cache += 1
 | 
			
		||||
				elif file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"):
 | 
			
		||||
					tot_fluid += 1
 | 
			
		||||
				else:
 | 
			
		||||
					rowTable(file.filepath)
 | 
			
		||||
            for file in job.files:
 | 
			
		||||
                if file.filepath.endswith(".bphys"):
 | 
			
		||||
                    tot_cache += 1
 | 
			
		||||
                elif file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"):
 | 
			
		||||
                    tot_fluid += 1
 | 
			
		||||
                else:
 | 
			
		||||
                    rowTable(file.filepath)
 | 
			
		||||
 | 
			
		||||
			if tot_cache > 0:
 | 
			
		||||
				rowTable("%i physic cache files" % tot_cache, class_style = "toggle", extra = "onclick='toggleDisplay(".cache", "none", "table-row")'")
 | 
			
		||||
				for file in job.files:
 | 
			
		||||
					if file.filepath.endswith(".bphys"):
 | 
			
		||||
						rowTable(os.path.split(file.filepath)[1], class_style = "cache")
 | 
			
		||||
            if tot_cache > 0:
 | 
			
		||||
                rowTable("%i physic cache files" % tot_cache, class_style = "toggle", extra = "onclick='toggleDisplay(".cache", "none", "table-row")'")
 | 
			
		||||
                for file in job.files:
 | 
			
		||||
                    if file.filepath.endswith(".bphys"):
 | 
			
		||||
                        rowTable(os.path.split(file.filepath)[1], class_style = "cache")
 | 
			
		||||
 | 
			
		||||
			if tot_fluid > 0:
 | 
			
		||||
				rowTable("%i fluid bake files" % tot_fluid, class_style = "toggle", extra = "onclick='toggleDisplay(".fluid", "none", "table-row")'")
 | 
			
		||||
				for file in job.files:
 | 
			
		||||
					if file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"):
 | 
			
		||||
						rowTable(os.path.split(file.filepath)[1], class_style = "fluid")
 | 
			
		||||
            if tot_fluid > 0:
 | 
			
		||||
                rowTable("%i fluid bake files" % tot_fluid, class_style = "toggle", extra = "onclick='toggleDisplay(".fluid", "none", "table-row")'")
 | 
			
		||||
                for file in job.files:
 | 
			
		||||
                    if file.filepath.endswith(".bobj.gz") or file.filepath.endswith(".bvel.gz"):
 | 
			
		||||
                        rowTable(os.path.split(file.filepath)[1], class_style = "fluid")
 | 
			
		||||
 | 
			
		||||
			endTable()
 | 
			
		||||
            endTable()
 | 
			
		||||
 | 
			
		||||
			output("<h2>Blacklist</h2>")
 | 
			
		||||
            output("<h2>Blacklist</h2>")
 | 
			
		||||
 | 
			
		||||
			if job.blacklist:
 | 
			
		||||
				startTable()
 | 
			
		||||
				headerTable("name", "address")
 | 
			
		||||
            if job.blacklist:
 | 
			
		||||
                startTable()
 | 
			
		||||
                headerTable("name", "address")
 | 
			
		||||
 | 
			
		||||
				for slave_id in job.blacklist:
 | 
			
		||||
					slave = handler.server.slaves_map[slave_id]
 | 
			
		||||
					rowTable(slave.name, slave.address[0])
 | 
			
		||||
                for slave_id in job.blacklist:
 | 
			
		||||
                    slave = handler.server.slaves_map[slave_id]
 | 
			
		||||
                    rowTable(slave.name, slave.address[0])
 | 
			
		||||
 | 
			
		||||
				endTable()
 | 
			
		||||
			else:
 | 
			
		||||
				output("<i>Empty</i>")
 | 
			
		||||
                endTable()
 | 
			
		||||
            else:
 | 
			
		||||
                output("<i>Empty</i>")
 | 
			
		||||
 | 
			
		||||
			output("<h2>Frames</h2>")
 | 
			
		||||
            output("<h2>Frames</h2>")
 | 
			
		||||
 | 
			
		||||
			startTable()
 | 
			
		||||
			headerTable("no", "status", "render time", "slave", "log", "result")
 | 
			
		||||
            startTable()
 | 
			
		||||
            headerTable("no", "status", "render time", "slave", "log", "result")
 | 
			
		||||
 | 
			
		||||
			for frame in job.frames:
 | 
			
		||||
				rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else " ", link("view log", logURL(job_id, frame.number)) if frame.log_path else " ", link("view result", renderURL(job_id, frame.number)) if frame.status == DONE else " ")
 | 
			
		||||
            for frame in job.frames:
 | 
			
		||||
                rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else " ", link("view log", logURL(job_id, frame.number)) if frame.log_path else " ", link("view result", renderURL(job_id, frame.number)) if frame.status == DONE else " ")
 | 
			
		||||
 | 
			
		||||
			endTable()
 | 
			
		||||
		else:
 | 
			
		||||
			output("no such job")
 | 
			
		||||
            endTable()
 | 
			
		||||
        else:
 | 
			
		||||
            output("no such job")
 | 
			
		||||
 | 
			
		||||
		output("</body></html>")
 | 
			
		||||
        output("</body></html>")
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,256 +23,256 @@ import subprocess, shutil, time, hashlib
 | 
			
		||||
from netrender.utils import *
 | 
			
		||||
 | 
			
		||||
class LogFile:
 | 
			
		||||
	def __init__(self, job_id = 0, slave_id = 0, frames = []):
 | 
			
		||||
		self.job_id = job_id
 | 
			
		||||
		self.slave_id = slave_id
 | 
			
		||||
		self.frames = frames
 | 
			
		||||
    def __init__(self, job_id = 0, slave_id = 0, frames = []):
 | 
			
		||||
        self.job_id = job_id
 | 
			
		||||
        self.slave_id = slave_id
 | 
			
		||||
        self.frames = frames
 | 
			
		||||
 | 
			
		||||
	def serialize(self):
 | 
			
		||||
		return 	{
 | 
			
		||||
							"job_id": self.job_id,
 | 
			
		||||
							"slave_id": self.slave_id,
 | 
			
		||||
							"frames": self.frames
 | 
			
		||||
						}
 | 
			
		||||
    def serialize(self):
 | 
			
		||||
        return 	{
 | 
			
		||||
                            "job_id": self.job_id,
 | 
			
		||||
                            "slave_id": self.slave_id,
 | 
			
		||||
                            "frames": self.frames
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
	@staticmethod
 | 
			
		||||
	def materialize(data):
 | 
			
		||||
		if not data:
 | 
			
		||||
			return None
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def materialize(data):
 | 
			
		||||
        if not data:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
		logfile = LogFile()
 | 
			
		||||
		logfile.job_id = data["job_id"]
 | 
			
		||||
		logfile.slave_id = data["slave_id"]
 | 
			
		||||
		logfile.frames = data["frames"]
 | 
			
		||||
        logfile = LogFile()
 | 
			
		||||
        logfile.job_id = data["job_id"]
 | 
			
		||||
        logfile.slave_id = data["slave_id"]
 | 
			
		||||
        logfile.frames = data["frames"]
 | 
			
		||||
 | 
			
		||||
		return logfile
 | 
			
		||||
        return logfile
 | 
			
		||||
 | 
			
		||||
class RenderSlave:
 | 
			
		||||
	_slave_map = {}
 | 
			
		||||
    _slave_map = {}
 | 
			
		||||
 | 
			
		||||
	def __init__(self):
 | 
			
		||||
		self.id = ""
 | 
			
		||||
		self.name = ""
 | 
			
		||||
		self.address = ("",0)
 | 
			
		||||
		self.stats = ""
 | 
			
		||||
		self.total_done = 0
 | 
			
		||||
		self.total_error = 0
 | 
			
		||||
		self.last_seen = 0.0
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.id = ""
 | 
			
		||||
        self.name = ""
 | 
			
		||||
        self.address = ("",0)
 | 
			
		||||
        self.stats = ""
 | 
			
		||||
        self.total_done = 0
 | 
			
		||||
        self.total_error = 0
 | 
			
		||||
        self.last_seen = 0.0
 | 
			
		||||
 | 
			
		||||
	def serialize(self):
 | 
			
		||||
		return 	{
 | 
			
		||||
							"id": self.id,
 | 
			
		||||
							"name": self.name,
 | 
			
		||||
							"address": self.address,
 | 
			
		||||
							"stats": self.stats,
 | 
			
		||||
							"total_done": self.total_done,
 | 
			
		||||
							"total_error": self.total_error,
 | 
			
		||||
							"last_seen": self.last_seen
 | 
			
		||||
						}
 | 
			
		||||
    def serialize(self):
 | 
			
		||||
        return 	{
 | 
			
		||||
                            "id": self.id,
 | 
			
		||||
                            "name": self.name,
 | 
			
		||||
                            "address": self.address,
 | 
			
		||||
                            "stats": self.stats,
 | 
			
		||||
                            "total_done": self.total_done,
 | 
			
		||||
                            "total_error": self.total_error,
 | 
			
		||||
                            "last_seen": self.last_seen
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
	@staticmethod
 | 
			
		||||
	def materialize(data, cache = True):
 | 
			
		||||
		if not data:
 | 
			
		||||
			return None
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def materialize(data, cache = True):
 | 
			
		||||
        if not data:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
		slave_id = data["id"]
 | 
			
		||||
        slave_id = data["id"]
 | 
			
		||||
 | 
			
		||||
		if cache and slave_id in RenderSlave._slave_map:
 | 
			
		||||
			return RenderSlave._slave_map[slave_id]
 | 
			
		||||
        if cache and slave_id in RenderSlave._slave_map:
 | 
			
		||||
            return RenderSlave._slave_map[slave_id]
 | 
			
		||||
 | 
			
		||||
		slave = RenderSlave()
 | 
			
		||||
		slave.id = slave_id
 | 
			
		||||
		slave.name = data["name"]
 | 
			
		||||
		slave.address = data["address"]
 | 
			
		||||
		slave.stats = data["stats"]
 | 
			
		||||
		slave.total_done = data["total_done"]
 | 
			
		||||
		slave.total_error = data["total_error"]
 | 
			
		||||
		slave.last_seen = data["last_seen"]
 | 
			
		||||
        slave = RenderSlave()
 | 
			
		||||
        slave.id = slave_id
 | 
			
		||||
        slave.name = data["name"]
 | 
			
		||||
        slave.address = data["address"]
 | 
			
		||||
        slave.stats = data["stats"]
 | 
			
		||||
        slave.total_done = data["total_done"]
 | 
			
		||||
        slave.total_error = data["total_error"]
 | 
			
		||||
        slave.last_seen = data["last_seen"]
 | 
			
		||||
 | 
			
		||||
		if cache:
 | 
			
		||||
			RenderSlave._slave_map[slave_id] = slave
 | 
			
		||||
        if cache:
 | 
			
		||||
            RenderSlave._slave_map[slave_id] = slave
 | 
			
		||||
 | 
			
		||||
		return slave
 | 
			
		||||
        return slave
 | 
			
		||||
 | 
			
		||||
JOB_BLENDER = 1
 | 
			
		||||
JOB_PROCESS = 2
 | 
			
		||||
 | 
			
		||||
JOB_TYPES = {
 | 
			
		||||
							JOB_BLENDER: "Blender",
 | 
			
		||||
							JOB_PROCESS: "Process"
 | 
			
		||||
						}
 | 
			
		||||
                            JOB_BLENDER: "Blender",
 | 
			
		||||
                            JOB_PROCESS: "Process"
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
class RenderFile:
 | 
			
		||||
	def __init__(self, filepath = "", index = 0, start = -1, end = -1):
 | 
			
		||||
		self.filepath = filepath
 | 
			
		||||
		self.index = index
 | 
			
		||||
		self.start = start
 | 
			
		||||
		self.end = end
 | 
			
		||||
    def __init__(self, filepath = "", index = 0, start = -1, end = -1):
 | 
			
		||||
        self.filepath = filepath
 | 
			
		||||
        self.index = index
 | 
			
		||||
        self.start = start
 | 
			
		||||
        self.end = end
 | 
			
		||||
 | 
			
		||||
	def serialize(self):
 | 
			
		||||
		return 	{
 | 
			
		||||
				    "filepath": self.filepath,
 | 
			
		||||
				    "index": self.index,
 | 
			
		||||
				    "start": self.start,
 | 
			
		||||
				    "end": self.end
 | 
			
		||||
				}
 | 
			
		||||
    def serialize(self):
 | 
			
		||||
        return 	{
 | 
			
		||||
                    "filepath": self.filepath,
 | 
			
		||||
                    "index": self.index,
 | 
			
		||||
                    "start": self.start,
 | 
			
		||||
                    "end": self.end
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
	@staticmethod
 | 
			
		||||
	def materialize(data):
 | 
			
		||||
		if not data:
 | 
			
		||||
			return None
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def materialize(data):
 | 
			
		||||
        if not data:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
		rfile = RenderFile(data["filepath"], data["index"], data["start"], data["end"])
 | 
			
		||||
        rfile = RenderFile(data["filepath"], data["index"], data["start"], data["end"])
 | 
			
		||||
 | 
			
		||||
		return rfile	
 | 
			
		||||
        return rfile
 | 
			
		||||
 | 
			
		||||
class RenderJob:
 | 
			
		||||
	def __init__(self, job_info = None):
 | 
			
		||||
		self.id = ""
 | 
			
		||||
		self.type = JOB_BLENDER
 | 
			
		||||
		self.name = ""
 | 
			
		||||
		self.category = "None"
 | 
			
		||||
		self.status = JOB_WAITING
 | 
			
		||||
		self.files = []
 | 
			
		||||
		self.chunks = 0
 | 
			
		||||
		self.priority = 0
 | 
			
		||||
		self.blacklist = []
 | 
			
		||||
    def __init__(self, job_info = None):
 | 
			
		||||
        self.id = ""
 | 
			
		||||
        self.type = JOB_BLENDER
 | 
			
		||||
        self.name = ""
 | 
			
		||||
        self.category = "None"
 | 
			
		||||
        self.status = JOB_WAITING
 | 
			
		||||
        self.files = []
 | 
			
		||||
        self.chunks = 0
 | 
			
		||||
        self.priority = 0
 | 
			
		||||
        self.blacklist = []
 | 
			
		||||
 | 
			
		||||
		self.usage = 0.0
 | 
			
		||||
		self.last_dispatched = 0.0
 | 
			
		||||
		self.frames = []
 | 
			
		||||
        self.usage = 0.0
 | 
			
		||||
        self.last_dispatched = 0.0
 | 
			
		||||
        self.frames = []
 | 
			
		||||
 | 
			
		||||
		if job_info:
 | 
			
		||||
			self.type = job_info.type
 | 
			
		||||
			self.name = job_info.name
 | 
			
		||||
			self.category = job_info.category
 | 
			
		||||
			self.status = job_info.status
 | 
			
		||||
			self.files = job_info.files
 | 
			
		||||
			self.chunks = job_info.chunks
 | 
			
		||||
			self.priority = job_info.priority
 | 
			
		||||
			self.blacklist = job_info.blacklist
 | 
			
		||||
        if job_info:
 | 
			
		||||
            self.type = job_info.type
 | 
			
		||||
            self.name = job_info.name
 | 
			
		||||
            self.category = job_info.category
 | 
			
		||||
            self.status = job_info.status
 | 
			
		||||
            self.files = job_info.files
 | 
			
		||||
            self.chunks = job_info.chunks
 | 
			
		||||
            self.priority = job_info.priority
 | 
			
		||||
            self.blacklist = job_info.blacklist
 | 
			
		||||
 | 
			
		||||
	def addFile(self, file_path, start=-1, end=-1):
 | 
			
		||||
		self.files.append(RenderFile(file_path, len(self.files), start, end))
 | 
			
		||||
    def addFile(self, file_path, start=-1, end=-1):
 | 
			
		||||
        self.files.append(RenderFile(file_path, len(self.files), start, end))
 | 
			
		||||
 | 
			
		||||
	def addFrame(self, frame_number, command = ""):
 | 
			
		||||
		frame = RenderFrame(frame_number, command)
 | 
			
		||||
		self.frames.append(frame)
 | 
			
		||||
		return frame
 | 
			
		||||
    def addFrame(self, frame_number, command = ""):
 | 
			
		||||
        frame = RenderFrame(frame_number, command)
 | 
			
		||||
        self.frames.append(frame)
 | 
			
		||||
        return frame
 | 
			
		||||
 | 
			
		||||
	def __len__(self):
 | 
			
		||||
		return len(self.frames)
 | 
			
		||||
    def __len__(self):
 | 
			
		||||
        return len(self.frames)
 | 
			
		||||
 | 
			
		||||
	def countFrames(self, status=QUEUED):
 | 
			
		||||
		total = 0
 | 
			
		||||
		for f in self.frames:
 | 
			
		||||
			if f.status == status:
 | 
			
		||||
				total += 1
 | 
			
		||||
    def countFrames(self, status=QUEUED):
 | 
			
		||||
        total = 0
 | 
			
		||||
        for f in self.frames:
 | 
			
		||||
            if f.status == status:
 | 
			
		||||
                total += 1
 | 
			
		||||
 | 
			
		||||
		return total
 | 
			
		||||
        return total
 | 
			
		||||
 | 
			
		||||
	def countSlaves(self):
 | 
			
		||||
		return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED)))
 | 
			
		||||
    def countSlaves(self):
 | 
			
		||||
        return len(set((frame.slave for frame in self.frames if frame.status == DISPATCHED)))
 | 
			
		||||
 | 
			
		||||
	def statusText(self):
 | 
			
		||||
		return JOB_STATUS_TEXT[self.status]
 | 
			
		||||
    def statusText(self):
 | 
			
		||||
        return JOB_STATUS_TEXT[self.status]
 | 
			
		||||
 | 
			
		||||
	def framesStatus(self):
 | 
			
		||||
		results = {
 | 
			
		||||
								QUEUED: 0,
 | 
			
		||||
								DISPATCHED: 0,
 | 
			
		||||
								DONE: 0,
 | 
			
		||||
								ERROR: 0
 | 
			
		||||
							}
 | 
			
		||||
    def framesStatus(self):
 | 
			
		||||
        results = {
 | 
			
		||||
                                QUEUED: 0,
 | 
			
		||||
                                DISPATCHED: 0,
 | 
			
		||||
                                DONE: 0,
 | 
			
		||||
                                ERROR: 0
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
		for frame in self.frames:
 | 
			
		||||
			results[frame.status] += 1
 | 
			
		||||
        for frame in self.frames:
 | 
			
		||||
            results[frame.status] += 1
 | 
			
		||||
 | 
			
		||||
		return results
 | 
			
		||||
        return results
 | 
			
		||||
 | 
			
		||||
	def __contains__(self, frame_number):
 | 
			
		||||
		for f in self.frames:
 | 
			
		||||
			if f.number == frame_number:
 | 
			
		||||
				return True
 | 
			
		||||
		else:
 | 
			
		||||
			return False
 | 
			
		||||
    def __contains__(self, frame_number):
 | 
			
		||||
        for f in self.frames:
 | 
			
		||||
            if f.number == frame_number:
 | 
			
		||||
                return True
 | 
			
		||||
        else:
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
	def __getitem__(self, frame_number):
 | 
			
		||||
		for f in self.frames:
 | 
			
		||||
			if f.number == frame_number:
 | 
			
		||||
				return f
 | 
			
		||||
		else:
 | 
			
		||||
			return None
 | 
			
		||||
    def __getitem__(self, frame_number):
 | 
			
		||||
        for f in self.frames:
 | 
			
		||||
            if f.number == frame_number:
 | 
			
		||||
                return f
 | 
			
		||||
        else:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
	def serialize(self, frames = None):
 | 
			
		||||
		min_frame = min((f.number for f in frames)) if frames else -1
 | 
			
		||||
		max_frame = max((f.number for f in frames)) if frames else -1
 | 
			
		||||
		return 	{
 | 
			
		||||
							"id": self.id,
 | 
			
		||||
							"type": self.type,
 | 
			
		||||
							"name": self.name,
 | 
			
		||||
							"category": self.category,
 | 
			
		||||
							"status": self.status,
 | 
			
		||||
							"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)],
 | 
			
		||||
							"frames": [f.serialize() for f in self.frames if not frames or f in frames],
 | 
			
		||||
							"chunks": self.chunks,
 | 
			
		||||
							"priority": self.priority,
 | 
			
		||||
							"usage": self.usage,
 | 
			
		||||
							"blacklist": self.blacklist,
 | 
			
		||||
							"last_dispatched": self.last_dispatched
 | 
			
		||||
						}
 | 
			
		||||
    def serialize(self, frames = None):
 | 
			
		||||
        min_frame = min((f.number for f in frames)) if frames else -1
 | 
			
		||||
        max_frame = max((f.number for f in frames)) if frames else -1
 | 
			
		||||
        return 	{
 | 
			
		||||
                            "id": self.id,
 | 
			
		||||
                            "type": self.type,
 | 
			
		||||
                            "name": self.name,
 | 
			
		||||
                            "category": self.category,
 | 
			
		||||
                            "status": self.status,
 | 
			
		||||
                            "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)],
 | 
			
		||||
                            "frames": [f.serialize() for f in self.frames if not frames or f in frames],
 | 
			
		||||
                            "chunks": self.chunks,
 | 
			
		||||
                            "priority": self.priority,
 | 
			
		||||
                            "usage": self.usage,
 | 
			
		||||
                            "blacklist": self.blacklist,
 | 
			
		||||
                            "last_dispatched": self.last_dispatched
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
	@staticmethod
 | 
			
		||||
	def materialize(data):
 | 
			
		||||
		if not data:
 | 
			
		||||
			return None
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def materialize(data):
 | 
			
		||||
        if not data:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
		job = RenderJob()
 | 
			
		||||
		job.id = data["id"]
 | 
			
		||||
		job.type = data["type"]
 | 
			
		||||
		job.name = data["name"]
 | 
			
		||||
		job.category = data["category"]
 | 
			
		||||
		job.status = data["status"]
 | 
			
		||||
		job.files = [RenderFile.materialize(f) for f in data["files"]]
 | 
			
		||||
		job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
 | 
			
		||||
		job.chunks = data["chunks"]
 | 
			
		||||
		job.priority = data["priority"]
 | 
			
		||||
		job.usage = data["usage"]
 | 
			
		||||
		job.blacklist = data["blacklist"]
 | 
			
		||||
		job.last_dispatched = data["last_dispatched"]
 | 
			
		||||
        job = RenderJob()
 | 
			
		||||
        job.id = data["id"]
 | 
			
		||||
        job.type = data["type"]
 | 
			
		||||
        job.name = data["name"]
 | 
			
		||||
        job.category = data["category"]
 | 
			
		||||
        job.status = data["status"]
 | 
			
		||||
        job.files = [RenderFile.materialize(f) for f in data["files"]]
 | 
			
		||||
        job.frames = [RenderFrame.materialize(f) for f in data["frames"]]
 | 
			
		||||
        job.chunks = data["chunks"]
 | 
			
		||||
        job.priority = data["priority"]
 | 
			
		||||
        job.usage = data["usage"]
 | 
			
		||||
        job.blacklist = data["blacklist"]
 | 
			
		||||
        job.last_dispatched = data["last_dispatched"]
 | 
			
		||||
 | 
			
		||||
		return job
 | 
			
		||||
        return job
 | 
			
		||||
 | 
			
		||||
class RenderFrame:
 | 
			
		||||
	def __init__(self, number = 0, command = ""):
 | 
			
		||||
		self.number = number
 | 
			
		||||
		self.time = 0
 | 
			
		||||
		self.status = QUEUED
 | 
			
		||||
		self.slave = None
 | 
			
		||||
		self.command = command
 | 
			
		||||
    def __init__(self, number = 0, command = ""):
 | 
			
		||||
        self.number = number
 | 
			
		||||
        self.time = 0
 | 
			
		||||
        self.status = QUEUED
 | 
			
		||||
        self.slave = None
 | 
			
		||||
        self.command = command
 | 
			
		||||
 | 
			
		||||
	def statusText(self):
 | 
			
		||||
		return FRAME_STATUS_TEXT[self.status]
 | 
			
		||||
    def statusText(self):
 | 
			
		||||
        return FRAME_STATUS_TEXT[self.status]
 | 
			
		||||
 | 
			
		||||
	def serialize(self):
 | 
			
		||||
		return 	{
 | 
			
		||||
							"number": self.number,
 | 
			
		||||
							"time": self.time,
 | 
			
		||||
							"status": self.status,
 | 
			
		||||
							"slave": None if not self.slave else self.slave.serialize(),
 | 
			
		||||
							"command": self.command
 | 
			
		||||
						}
 | 
			
		||||
    def serialize(self):
 | 
			
		||||
        return 	{
 | 
			
		||||
                            "number": self.number,
 | 
			
		||||
                            "time": self.time,
 | 
			
		||||
                            "status": self.status,
 | 
			
		||||
                            "slave": None if not self.slave else self.slave.serialize(),
 | 
			
		||||
                            "command": self.command
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
	@staticmethod
 | 
			
		||||
	def materialize(data):
 | 
			
		||||
		if not data:
 | 
			
		||||
			return None
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def materialize(data):
 | 
			
		||||
        if not data:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
		frame = RenderFrame()
 | 
			
		||||
		frame.number = data["number"]
 | 
			
		||||
		frame.time = data["time"]
 | 
			
		||||
		frame.status = data["status"]
 | 
			
		||||
		frame.slave = RenderSlave.materialize(data["slave"])
 | 
			
		||||
		frame.command = data["command"]
 | 
			
		||||
        frame = RenderFrame()
 | 
			
		||||
        frame.number = data["number"]
 | 
			
		||||
        frame.time = data["time"]
 | 
			
		||||
        frame.status = data["status"]
 | 
			
		||||
        frame.slave = RenderSlave.materialize(data["slave"])
 | 
			
		||||
        frame.command = data["command"]
 | 
			
		||||
 | 
			
		||||
		return frame
 | 
			
		||||
        return frame
 | 
			
		||||
 
 | 
			
		||||
@@ -28,414 +28,414 @@ import netrender.model
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class RENDER_OT_netslave_bake(bpy.types.Operator):
 | 
			
		||||
	'''NEED DESCRIPTION'''
 | 
			
		||||
	bl_idname = "render.netslavebake"
 | 
			
		||||
	bl_label = "Bake all in file"
 | 
			
		||||
    '''NEED DESCRIPTION'''
 | 
			
		||||
    bl_idname = "render.netslavebake"
 | 
			
		||||
    bl_label = "Bake all in file"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return True
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		netsettings = scene.network_render
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        netsettings = scene.network_render
 | 
			
		||||
 | 
			
		||||
		filename = bpy.data.filename
 | 
			
		||||
		path, name = os.path.split(filename)
 | 
			
		||||
		root, ext = os.path.splitext(name)
 | 
			
		||||
		default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
 | 
			
		||||
		relative_path = os.sep + os.sep + "blendcache_" + root + os.sep
 | 
			
		||||
        filename = bpy.data.filename
 | 
			
		||||
        path, name = os.path.split(filename)
 | 
			
		||||
        root, ext = os.path.splitext(name)
 | 
			
		||||
        default_path = path + os.sep + "blendcache_" + root + os.sep # need an API call for that
 | 
			
		||||
        relative_path = os.sep + os.sep + "blendcache_" + root + os.sep
 | 
			
		||||
 | 
			
		||||
		# Force all point cache next to the blend file
 | 
			
		||||
		for object in bpy.data.objects:
 | 
			
		||||
			for modifier in object.modifiers:
 | 
			
		||||
				if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
 | 
			
		||||
					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
 | 
			
		||||
				elif modifier.type == "SOFT_BODY":
 | 
			
		||||
					modifier.point_cache.step = 1
 | 
			
		||||
					modifier.point_cache.disk_cache = True
 | 
			
		||||
					modifier.point_cache.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
 | 
			
		||||
        # Force all point cache next to the blend file
 | 
			
		||||
        for object in bpy.data.objects:
 | 
			
		||||
            for modifier in object.modifiers:
 | 
			
		||||
                if modifier.type == 'FLUID_SIMULATION' and modifier.settings.type == "DOMAIN":
 | 
			
		||||
                    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
 | 
			
		||||
                elif modifier.type == "SOFT_BODY":
 | 
			
		||||
                    modifier.point_cache.step = 1
 | 
			
		||||
                    modifier.point_cache.disk_cache = True
 | 
			
		||||
                    modifier.point_cache.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
 | 
			
		||||
 | 
			
		||||
			# 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.filepath = relative_path
 | 
			
		||||
            # 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.filepath = relative_path
 | 
			
		||||
 | 
			
		||||
		bpy.ops.ptcache.bake_all()
 | 
			
		||||
        bpy.ops.ptcache.bake_all()
 | 
			
		||||
 | 
			
		||||
		#bpy.ops.wm.save_mainfile(path = path + os.sep + root + "_baked.blend")
 | 
			
		||||
        #bpy.ops.wm.save_mainfile(path = path + os.sep + root + "_baked.blend")
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    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"
 | 
			
		||||
    '''Start rendering an animation on network'''
 | 
			
		||||
    bl_idname = "render.netclientanim"
 | 
			
		||||
    bl_label = "Animation on network"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return True
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		netsettings = scene.network_render
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        netsettings = scene.network_render
 | 
			
		||||
 | 
			
		||||
		conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
        conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
 | 
			
		||||
		if conn:
 | 
			
		||||
			# Sending file
 | 
			
		||||
			scene.network_render.job_id = client.clientSendJob(conn, scene, True)
 | 
			
		||||
			conn.close()
 | 
			
		||||
        if conn:
 | 
			
		||||
            # Sending file
 | 
			
		||||
            scene.network_render.job_id = client.clientSendJob(conn, scene, True)
 | 
			
		||||
            conn.close()
 | 
			
		||||
 | 
			
		||||
		bpy.ops.screen.render('INVOKE_AREA', animation=True)
 | 
			
		||||
        bpy.ops.screen.render('INVOKE_AREA', animation=True)
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    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"
 | 
			
		||||
    '''Send Render Job to the Network'''
 | 
			
		||||
    bl_idname = "render.netclientsend"
 | 
			
		||||
    bl_label = "Send job"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return True
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		netsettings = scene.network_render
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        netsettings = scene.network_render
 | 
			
		||||
 | 
			
		||||
		try:
 | 
			
		||||
			conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
        try:
 | 
			
		||||
            conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
 | 
			
		||||
			if conn:
 | 
			
		||||
				# Sending file
 | 
			
		||||
				scene.network_render.job_id = client.clientSendJob(conn, scene, True)
 | 
			
		||||
				conn.close()
 | 
			
		||||
				self.report('INFO', "Job sent to master")
 | 
			
		||||
		except Exception as err:
 | 
			
		||||
			self.report('ERROR', str(err))
 | 
			
		||||
            if conn:
 | 
			
		||||
                # Sending file
 | 
			
		||||
                scene.network_render.job_id = client.clientSendJob(conn, scene, True)
 | 
			
		||||
                conn.close()
 | 
			
		||||
                self.report('INFO', "Job sent to master")
 | 
			
		||||
        except Exception as err:
 | 
			
		||||
            self.report('ERROR', str(err))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    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"
 | 
			
		||||
    '''Refresh the status of the current jobs'''
 | 
			
		||||
    bl_idname = "render.netclientstatus"
 | 
			
		||||
    bl_label = "Client Status"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return True
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
		conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
        conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
 | 
			
		||||
		if conn:
 | 
			
		||||
			conn.request("GET", "/status")
 | 
			
		||||
        if conn:
 | 
			
		||||
            conn.request("GET", "/status")
 | 
			
		||||
 | 
			
		||||
			response = conn.getresponse()
 | 
			
		||||
			print( response.status, response.reason )
 | 
			
		||||
            response = conn.getresponse()
 | 
			
		||||
            print( response.status, response.reason )
 | 
			
		||||
 | 
			
		||||
			jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8')))
 | 
			
		||||
            jobs = (netrender.model.RenderJob.materialize(j) for j in eval(str(response.read(), encoding='utf8')))
 | 
			
		||||
 | 
			
		||||
			while(len(netsettings.jobs) > 0):
 | 
			
		||||
				netsettings.jobs.remove(0)
 | 
			
		||||
            while(len(netsettings.jobs) > 0):
 | 
			
		||||
                netsettings.jobs.remove(0)
 | 
			
		||||
 | 
			
		||||
			netrender.jobs = []
 | 
			
		||||
            netrender.jobs = []
 | 
			
		||||
 | 
			
		||||
			for j in jobs:
 | 
			
		||||
				netrender.jobs.append(j)
 | 
			
		||||
				netsettings.jobs.add()
 | 
			
		||||
				job = netsettings.jobs[-1]
 | 
			
		||||
            for j in jobs:
 | 
			
		||||
                netrender.jobs.append(j)
 | 
			
		||||
                netsettings.jobs.add()
 | 
			
		||||
                job = netsettings.jobs[-1]
 | 
			
		||||
 | 
			
		||||
				j.results = j.framesStatus() # cache frame status
 | 
			
		||||
                j.results = j.framesStatus() # cache frame status
 | 
			
		||||
 | 
			
		||||
				job.name = j.name
 | 
			
		||||
                job.name = j.name
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    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"
 | 
			
		||||
    '''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):
 | 
			
		||||
		return True
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
 | 
			
		||||
		if netsettings.active_slave_index >= 0:
 | 
			
		||||
        if netsettings.active_slave_index >= 0:
 | 
			
		||||
 | 
			
		||||
			# deal with data
 | 
			
		||||
			slave = netrender.slaves.pop(netsettings.active_slave_index)
 | 
			
		||||
			netrender.blacklist.append(slave)
 | 
			
		||||
            # deal with data
 | 
			
		||||
            slave = netrender.slaves.pop(netsettings.active_slave_index)
 | 
			
		||||
            netrender.blacklist.append(slave)
 | 
			
		||||
 | 
			
		||||
			# deal with rna
 | 
			
		||||
			netsettings.slaves_blacklist.add()
 | 
			
		||||
			netsettings.slaves_blacklist[-1].name = slave.name
 | 
			
		||||
            # deal with rna
 | 
			
		||||
            netsettings.slaves_blacklist.add()
 | 
			
		||||
            netsettings.slaves_blacklist[-1].name = slave.name
 | 
			
		||||
 | 
			
		||||
			netsettings.slaves.remove(netsettings.active_slave_index)
 | 
			
		||||
			netsettings.active_slave_index = -1
 | 
			
		||||
            netsettings.slaves.remove(netsettings.active_slave_index)
 | 
			
		||||
            netsettings.active_slave_index = -1
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    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"
 | 
			
		||||
    '''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):
 | 
			
		||||
		return True
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
 | 
			
		||||
		if netsettings.active_blacklisted_slave_index >= 0:
 | 
			
		||||
        if netsettings.active_blacklisted_slave_index >= 0:
 | 
			
		||||
 | 
			
		||||
			# deal with data
 | 
			
		||||
			slave = netrender.blacklist.pop(netsettings.active_blacklisted_slave_index)
 | 
			
		||||
			netrender.slaves.append(slave)
 | 
			
		||||
            # deal with data
 | 
			
		||||
            slave = netrender.blacklist.pop(netsettings.active_blacklisted_slave_index)
 | 
			
		||||
            netrender.slaves.append(slave)
 | 
			
		||||
 | 
			
		||||
			# deal with rna
 | 
			
		||||
			netsettings.slaves.add()
 | 
			
		||||
			netsettings.slaves[-1].name = slave.name
 | 
			
		||||
            # deal with rna
 | 
			
		||||
            netsettings.slaves.add()
 | 
			
		||||
            netsettings.slaves[-1].name = slave.name
 | 
			
		||||
 | 
			
		||||
			netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index)
 | 
			
		||||
			netsettings.active_blacklisted_slave_index = -1
 | 
			
		||||
            netsettings.slaves_blacklist.remove(netsettings.active_blacklisted_slave_index)
 | 
			
		||||
            netsettings.active_blacklisted_slave_index = -1
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    def invoke(self, context, event):
 | 
			
		||||
        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"
 | 
			
		||||
    '''Refresh status about available Render slaves'''
 | 
			
		||||
    bl_idname = "render.netclientslaves"
 | 
			
		||||
    bl_label = "Client Slaves"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return True
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
		conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
        conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
 | 
			
		||||
		if conn:
 | 
			
		||||
			conn.request("GET", "/slaves")
 | 
			
		||||
        if conn:
 | 
			
		||||
            conn.request("GET", "/slaves")
 | 
			
		||||
 | 
			
		||||
			response = conn.getresponse()
 | 
			
		||||
			print( response.status, response.reason )
 | 
			
		||||
            response = conn.getresponse()
 | 
			
		||||
            print( response.status, response.reason )
 | 
			
		||||
 | 
			
		||||
			slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8')))
 | 
			
		||||
            slaves = (netrender.model.RenderSlave.materialize(s) for s in eval(str(response.read(), encoding='utf8')))
 | 
			
		||||
 | 
			
		||||
			while(len(netsettings.slaves) > 0):
 | 
			
		||||
				netsettings.slaves.remove(0)
 | 
			
		||||
            while(len(netsettings.slaves) > 0):
 | 
			
		||||
                netsettings.slaves.remove(0)
 | 
			
		||||
 | 
			
		||||
			netrender.slaves = []
 | 
			
		||||
            netrender.slaves = []
 | 
			
		||||
 | 
			
		||||
			for s in slaves:
 | 
			
		||||
				for i in range(len(netrender.blacklist)):
 | 
			
		||||
					slave = netrender.blacklist[i]
 | 
			
		||||
					if slave.id == s.id:
 | 
			
		||||
						netrender.blacklist[i] = s
 | 
			
		||||
						netsettings.slaves_blacklist[i].name = s.name
 | 
			
		||||
						break
 | 
			
		||||
				else:
 | 
			
		||||
					netrender.slaves.append(s)
 | 
			
		||||
            for s in slaves:
 | 
			
		||||
                for i in range(len(netrender.blacklist)):
 | 
			
		||||
                    slave = netrender.blacklist[i]
 | 
			
		||||
                    if slave.id == s.id:
 | 
			
		||||
                        netrender.blacklist[i] = s
 | 
			
		||||
                        netsettings.slaves_blacklist[i].name = s.name
 | 
			
		||||
                        break
 | 
			
		||||
                else:
 | 
			
		||||
                    netrender.slaves.append(s)
 | 
			
		||||
 | 
			
		||||
					netsettings.slaves.add()
 | 
			
		||||
					slave = netsettings.slaves[-1]
 | 
			
		||||
					slave.name = s.name
 | 
			
		||||
                    netsettings.slaves.add()
 | 
			
		||||
                    slave = netsettings.slaves[-1]
 | 
			
		||||
                    slave.name = s.name
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    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"
 | 
			
		||||
    '''Cancel the selected network rendering job.'''
 | 
			
		||||
    bl_idname = "render.netclientcancel"
 | 
			
		||||
    bl_label = "Client Cancel"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
		return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
        return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
		conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
        conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
 | 
			
		||||
		if conn:
 | 
			
		||||
			job = netrender.jobs[netsettings.active_job_index]
 | 
			
		||||
        if conn:
 | 
			
		||||
            job = netrender.jobs[netsettings.active_job_index]
 | 
			
		||||
 | 
			
		||||
			conn.request("POST", cancelURL(job.id))
 | 
			
		||||
            conn.request("POST", cancelURL(job.id))
 | 
			
		||||
 | 
			
		||||
			response = conn.getresponse()
 | 
			
		||||
			print( response.status, response.reason )
 | 
			
		||||
            response = conn.getresponse()
 | 
			
		||||
            print( response.status, response.reason )
 | 
			
		||||
 | 
			
		||||
			netsettings.jobs.remove(netsettings.active_job_index)
 | 
			
		||||
            netsettings.jobs.remove(netsettings.active_job_index)
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    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"
 | 
			
		||||
    '''Cancel all running network rendering jobs.'''
 | 
			
		||||
    bl_idname = "render.netclientcancelall"
 | 
			
		||||
    bl_label = "Client Cancel All"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return True
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
		conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
        conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
 | 
			
		||||
		if conn:
 | 
			
		||||
			conn.request("POST", "/clear")
 | 
			
		||||
        if conn:
 | 
			
		||||
            conn.request("POST", "/clear")
 | 
			
		||||
 | 
			
		||||
			response = conn.getresponse()
 | 
			
		||||
			print( response.status, response.reason )
 | 
			
		||||
            response = conn.getresponse()
 | 
			
		||||
            print( response.status, response.reason )
 | 
			
		||||
 | 
			
		||||
			while(len(netsettings.jobs) > 0):
 | 
			
		||||
				netsettings.jobs.remove(0)
 | 
			
		||||
            while(len(netsettings.jobs) > 0):
 | 
			
		||||
                netsettings.jobs.remove(0)
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    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"
 | 
			
		||||
    '''Download render results from the network'''
 | 
			
		||||
    bl_idname = "render.netclientdownload"
 | 
			
		||||
    bl_label = "Client Download"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
		return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
        return netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
		rd = context.scene.render_data
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
        rd = context.scene.render_data
 | 
			
		||||
 | 
			
		||||
		conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
        conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
 | 
			
		||||
		if conn:
 | 
			
		||||
			job = netrender.jobs[netsettings.active_job_index]
 | 
			
		||||
        if conn:
 | 
			
		||||
            job = netrender.jobs[netsettings.active_job_index]
 | 
			
		||||
 | 
			
		||||
			for frame in job.frames:
 | 
			
		||||
				client.requestResult(conn, job.id, frame.number)
 | 
			
		||||
				response = conn.getresponse()
 | 
			
		||||
            for frame in job.frames:
 | 
			
		||||
                client.requestResult(conn, job.id, frame.number)
 | 
			
		||||
                response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
				if response.status != http.client.OK:
 | 
			
		||||
					print("missing", frame.number)
 | 
			
		||||
					continue
 | 
			
		||||
                if response.status != http.client.OK:
 | 
			
		||||
                    print("missing", frame.number)
 | 
			
		||||
                    continue
 | 
			
		||||
 | 
			
		||||
				print("got back", frame.number)
 | 
			
		||||
                print("got back", frame.number)
 | 
			
		||||
 | 
			
		||||
				f = open(netsettings.path + "%06d" % frame.number + ".exr", "wb")
 | 
			
		||||
				buf = response.read(1024)
 | 
			
		||||
                f = open(netsettings.path + "%06d" % frame.number + ".exr", "wb")
 | 
			
		||||
                buf = response.read(1024)
 | 
			
		||||
 | 
			
		||||
				while buf:
 | 
			
		||||
					f.write(buf)
 | 
			
		||||
					buf = response.read(1024)
 | 
			
		||||
                while buf:
 | 
			
		||||
                    f.write(buf)
 | 
			
		||||
                    buf = response.read(1024)
 | 
			
		||||
 | 
			
		||||
				f.close()
 | 
			
		||||
                f.close()
 | 
			
		||||
 | 
			
		||||
			conn.close()
 | 
			
		||||
            conn.close()
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    def invoke(self, context, event):
 | 
			
		||||
        return self.execute(context)
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class netclientscan(bpy.types.Operator):
 | 
			
		||||
	__slots__ = []
 | 
			
		||||
	'''Operator documentation text, will be used for the operator tooltip and python docs.'''
 | 
			
		||||
	bl_idname = "render.netclientscan"
 | 
			
		||||
	bl_label = "Client Scan"
 | 
			
		||||
    __slots__ = []
 | 
			
		||||
    '''Operator documentation text, will be used for the operator tooltip and python docs.'''
 | 
			
		||||
    bl_idname = "render.netclientscan"
 | 
			
		||||
    bl_label = "Client Scan"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return True
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		address, port = clientScan(self.report)
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        address, port = clientScan(self.report)
 | 
			
		||||
 | 
			
		||||
		if address:
 | 
			
		||||
			scene = context.scene
 | 
			
		||||
			netsettings = scene.network_render
 | 
			
		||||
			netsettings.server_address = address
 | 
			
		||||
			netsettings.server_port = port
 | 
			
		||||
        if address:
 | 
			
		||||
            scene = context.scene
 | 
			
		||||
            netsettings = scene.network_render
 | 
			
		||||
            netsettings.server_address = address
 | 
			
		||||
            netsettings.server_port = port
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		print(dir(self))
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    def invoke(self, context, event):
 | 
			
		||||
        print(dir(self))
 | 
			
		||||
        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"
 | 
			
		||||
    '''Open new window with information about running rendering jobs'''
 | 
			
		||||
    bl_idname = "render.netclientweb"
 | 
			
		||||
    bl_label = "Open Master Monitor"
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
		return netsettings.server_address != "[default]"
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
        return netsettings.server_address != "[default]"
 | 
			
		||||
 | 
			
		||||
	def execute(self, context):
 | 
			
		||||
		netsettings = context.scene.network_render
 | 
			
		||||
    def execute(self, context):
 | 
			
		||||
        netsettings = context.scene.network_render
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		# open connection to make sure server exists
 | 
			
		||||
		conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
        # open connection to make sure server exists
 | 
			
		||||
        conn = clientConnection(netsettings.server_address, netsettings.server_port, self.report)
 | 
			
		||||
 | 
			
		||||
		if conn:
 | 
			
		||||
			conn.close()
 | 
			
		||||
        if conn:
 | 
			
		||||
            conn.close()
 | 
			
		||||
 | 
			
		||||
			webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port))
 | 
			
		||||
            webbrowser.open("http://%s:%i" % (netsettings.server_address, netsettings.server_port))
 | 
			
		||||
 | 
			
		||||
		return {'FINISHED'}
 | 
			
		||||
        return {'FINISHED'}
 | 
			
		||||
 | 
			
		||||
	def invoke(self, context, event):
 | 
			
		||||
		return self.execute(context)
 | 
			
		||||
    def invoke(self, context, event):
 | 
			
		||||
        return self.execute(context)
 | 
			
		||||
 
 | 
			
		||||
@@ -30,218 +30,218 @@ MAX_TIMEOUT = 10
 | 
			
		||||
INCREMENT_TIMEOUT = 1
 | 
			
		||||
 | 
			
		||||
if platform.system() == 'Windows' and platform.version() >= '5': # Error mode is only available on Win2k or higher, that's version 5
 | 
			
		||||
	import ctypes
 | 
			
		||||
	def SetErrorMode():
 | 
			
		||||
		val = ctypes.windll.kernel32.SetErrorMode(0x0002)
 | 
			
		||||
		ctypes.windll.kernel32.SetErrorMode(val | 0x0002)
 | 
			
		||||
		return val
 | 
			
		||||
    import ctypes
 | 
			
		||||
    def SetErrorMode():
 | 
			
		||||
        val = ctypes.windll.kernel32.SetErrorMode(0x0002)
 | 
			
		||||
        ctypes.windll.kernel32.SetErrorMode(val | 0x0002)
 | 
			
		||||
        return val
 | 
			
		||||
 | 
			
		||||
	def RestoreErrorMode(val):
 | 
			
		||||
		ctypes.windll.kernel32.SetErrorMode(val)
 | 
			
		||||
    def RestoreErrorMode(val):
 | 
			
		||||
        ctypes.windll.kernel32.SetErrorMode(val)
 | 
			
		||||
else:
 | 
			
		||||
	def SetErrorMode():
 | 
			
		||||
		return 0
 | 
			
		||||
    def SetErrorMode():
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
	def RestoreErrorMode(val):
 | 
			
		||||
		pass
 | 
			
		||||
    def RestoreErrorMode(val):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
def slave_Info():
 | 
			
		||||
	sysname, nodename, release, version, machine, processor = platform.uname()
 | 
			
		||||
	slave = netrender.model.RenderSlave()
 | 
			
		||||
	slave.name = nodename
 | 
			
		||||
	slave.stats = sysname + " " + release + " " + machine + " " + processor
 | 
			
		||||
	return slave
 | 
			
		||||
    sysname, nodename, release, version, machine, processor = platform.uname()
 | 
			
		||||
    slave = netrender.model.RenderSlave()
 | 
			
		||||
    slave.name = nodename
 | 
			
		||||
    slave.stats = sysname + " " + release + " " + machine + " " + processor
 | 
			
		||||
    return slave
 | 
			
		||||
 | 
			
		||||
def testCancel(conn, job_id, frame_number):
 | 
			
		||||
		conn.request("HEAD", "/status", headers={"job-id":job_id, "job-frame": str(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:
 | 
			
		||||
			return True
 | 
			
		||||
		else:
 | 
			
		||||
			return False
 | 
			
		||||
        # cancelled if job isn't found anymore
 | 
			
		||||
        if conn.getresponse().status == http.client.NO_CONTENT:
 | 
			
		||||
            return True
 | 
			
		||||
        else:
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
def testFile(conn, job_id, slave_id, file_index, JOB_PREFIX, file_path, main_path = None):
 | 
			
		||||
	job_full_path = prefixPath(JOB_PREFIX, file_path, main_path)
 | 
			
		||||
    job_full_path = prefixPath(JOB_PREFIX, file_path, main_path)
 | 
			
		||||
 | 
			
		||||
	if not os.path.exists(job_full_path):
 | 
			
		||||
		temp_path = JOB_PREFIX + "slave.temp.blend"
 | 
			
		||||
		conn.request("GET", fileURL(job_id, file_index), headers={"slave-id":slave_id})
 | 
			
		||||
		response = conn.getresponse()
 | 
			
		||||
    if not os.path.exists(job_full_path):
 | 
			
		||||
        temp_path = JOB_PREFIX + "slave.temp.blend"
 | 
			
		||||
        conn.request("GET", fileURL(job_id, file_index), headers={"slave-id":slave_id})
 | 
			
		||||
        response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
		if response.status != http.client.OK:
 | 
			
		||||
			return None # file for job not returned by server, need to return an error code to server
 | 
			
		||||
        if response.status != http.client.OK:
 | 
			
		||||
            return None # file for job not returned by server, need to return an error code to server
 | 
			
		||||
 | 
			
		||||
		f = open(temp_path, "wb")
 | 
			
		||||
		buf = response.read(1024)
 | 
			
		||||
        f = open(temp_path, "wb")
 | 
			
		||||
        buf = response.read(1024)
 | 
			
		||||
 | 
			
		||||
		while buf:
 | 
			
		||||
			f.write(buf)
 | 
			
		||||
			buf = response.read(1024)
 | 
			
		||||
        while buf:
 | 
			
		||||
            f.write(buf)
 | 
			
		||||
            buf = response.read(1024)
 | 
			
		||||
 | 
			
		||||
		f.close()
 | 
			
		||||
        f.close()
 | 
			
		||||
 | 
			
		||||
		os.renames(temp_path, job_full_path)
 | 
			
		||||
        os.renames(temp_path, job_full_path)
 | 
			
		||||
 | 
			
		||||
	return job_full_path
 | 
			
		||||
    return job_full_path
 | 
			
		||||
 | 
			
		||||
def render_slave(engine, netsettings):
 | 
			
		||||
	timeout = 1
 | 
			
		||||
    timeout = 1
 | 
			
		||||
 | 
			
		||||
	engine.update_stats("", "Network render node initiation")
 | 
			
		||||
    engine.update_stats("", "Network render node initiation")
 | 
			
		||||
 | 
			
		||||
	conn = clientConnection(netsettings.server_address, netsettings.server_port)
 | 
			
		||||
    conn = clientConnection(netsettings.server_address, netsettings.server_port)
 | 
			
		||||
 | 
			
		||||
	if conn:
 | 
			
		||||
		conn.request("POST", "/slave", repr(slave_Info().serialize()))
 | 
			
		||||
		response = conn.getresponse()
 | 
			
		||||
    if conn:
 | 
			
		||||
        conn.request("POST", "/slave", repr(slave_Info().serialize()))
 | 
			
		||||
        response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
		slave_id = response.getheader("slave-id")
 | 
			
		||||
        slave_id = response.getheader("slave-id")
 | 
			
		||||
 | 
			
		||||
		NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep
 | 
			
		||||
		if not os.path.exists(NODE_PREFIX):
 | 
			
		||||
			os.mkdir(NODE_PREFIX)
 | 
			
		||||
        NODE_PREFIX = netsettings.path + "slave_" + slave_id + os.sep
 | 
			
		||||
        if not os.path.exists(NODE_PREFIX):
 | 
			
		||||
            os.mkdir(NODE_PREFIX)
 | 
			
		||||
 | 
			
		||||
		while not engine.test_break():
 | 
			
		||||
        while not engine.test_break():
 | 
			
		||||
 | 
			
		||||
			conn.request("GET", "/job", headers={"slave-id":slave_id})
 | 
			
		||||
			response = conn.getresponse()
 | 
			
		||||
            conn.request("GET", "/job", headers={"slave-id":slave_id})
 | 
			
		||||
            response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
			if response.status == http.client.OK:
 | 
			
		||||
				timeout = 1 # reset timeout on new job
 | 
			
		||||
            if response.status == http.client.OK:
 | 
			
		||||
                timeout = 1 # reset timeout on new job
 | 
			
		||||
 | 
			
		||||
				job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8')))
 | 
			
		||||
                job = netrender.model.RenderJob.materialize(eval(str(response.read(), encoding='utf8')))
 | 
			
		||||
 | 
			
		||||
				JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep
 | 
			
		||||
				if not os.path.exists(JOB_PREFIX):
 | 
			
		||||
					os.mkdir(JOB_PREFIX)
 | 
			
		||||
                JOB_PREFIX = NODE_PREFIX + "job_" + job.id + os.sep
 | 
			
		||||
                if not os.path.exists(JOB_PREFIX):
 | 
			
		||||
                    os.mkdir(JOB_PREFIX)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
				if job.type == netrender.model.JOB_BLENDER:
 | 
			
		||||
					job_path = job.files[0].filepath # path of main file
 | 
			
		||||
					main_path, main_file = os.path.split(job_path)
 | 
			
		||||
                if job.type == netrender.model.JOB_BLENDER:
 | 
			
		||||
                    job_path = job.files[0].filepath # path of main file
 | 
			
		||||
                    main_path, main_file = os.path.split(job_path)
 | 
			
		||||
 | 
			
		||||
					job_full_path = testFile(conn, job.id, slave_id, 0, JOB_PREFIX, job_path)
 | 
			
		||||
					print("Fullpath", job_full_path)
 | 
			
		||||
					print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
 | 
			
		||||
					engine.update_stats("", "Render File "+ main_file+ " for job "+ job.id)
 | 
			
		||||
                    job_full_path = testFile(conn, job.id, slave_id, 0, JOB_PREFIX, job_path)
 | 
			
		||||
                    print("Fullpath", job_full_path)
 | 
			
		||||
                    print("File:", main_file, "and %i other files" % (len(job.files) - 1,))
 | 
			
		||||
                    engine.update_stats("", "Render File "+ main_file+ " for job "+ job.id)
 | 
			
		||||
 | 
			
		||||
					for rfile in job.files[1:]:
 | 
			
		||||
						print("\t", rfile.filepath)
 | 
			
		||||
						testFile(conn, job.id, slave_id, rfile.index, JOB_PREFIX, rfile.filepath, main_path)
 | 
			
		||||
                    for rfile in job.files[1:]:
 | 
			
		||||
                        print("\t", rfile.filepath)
 | 
			
		||||
                        testFile(conn, job.id, slave_id, rfile.index, JOB_PREFIX, rfile.filepath, main_path)
 | 
			
		||||
 | 
			
		||||
				# announce log to master
 | 
			
		||||
				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()
 | 
			
		||||
                # announce log to master
 | 
			
		||||
                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()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
				first_frame = job.frames[0].number
 | 
			
		||||
                first_frame = job.frames[0].number
 | 
			
		||||
 | 
			
		||||
				# start render
 | 
			
		||||
				start_t = time.time()
 | 
			
		||||
                # start render
 | 
			
		||||
                start_t = time.time()
 | 
			
		||||
 | 
			
		||||
				if job.type == netrender.model.JOB_BLENDER:
 | 
			
		||||
					frame_args = []
 | 
			
		||||
                if job.type == netrender.model.JOB_BLENDER:
 | 
			
		||||
                    frame_args = []
 | 
			
		||||
 | 
			
		||||
					for frame in job.frames:
 | 
			
		||||
						print("frame", frame.number)
 | 
			
		||||
						frame_args += ["-f", str(frame.number)]
 | 
			
		||||
                    for frame in job.frames:
 | 
			
		||||
                        print("frame", frame.number)
 | 
			
		||||
                        frame_args += ["-f", str(frame.number)]
 | 
			
		||||
 | 
			
		||||
					val = SetErrorMode()
 | 
			
		||||
					process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-o", 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
 | 
			
		||||
					val = SetErrorMode()
 | 
			
		||||
					process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
 | 
			
		||||
					RestoreErrorMode(val)
 | 
			
		||||
                    val = SetErrorMode()
 | 
			
		||||
                    process = subprocess.Popen([BLENDER_PATH, "-b", "-noaudio", job_full_path, "-o", 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
 | 
			
		||||
                    val = SetErrorMode()
 | 
			
		||||
                    process = subprocess.Popen(command.split(" "), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
 | 
			
		||||
                    RestoreErrorMode(val)
 | 
			
		||||
 | 
			
		||||
				headers = {"slave-id":slave_id}
 | 
			
		||||
                headers = {"slave-id":slave_id}
 | 
			
		||||
 | 
			
		||||
				cancelled = False
 | 
			
		||||
				stdout = bytes()
 | 
			
		||||
				run_t = time.time()
 | 
			
		||||
				while process.poll() == None and not cancelled:
 | 
			
		||||
					stdout += process.stdout.read(32)
 | 
			
		||||
					current_t = time.time()
 | 
			
		||||
					cancelled = engine.test_break()
 | 
			
		||||
					if current_t - run_t > CANCEL_POLL_SPEED:
 | 
			
		||||
                cancelled = False
 | 
			
		||||
                stdout = bytes()
 | 
			
		||||
                run_t = time.time()
 | 
			
		||||
                while process.poll() == None and not cancelled:
 | 
			
		||||
                    stdout += process.stdout.read(32)
 | 
			
		||||
                    current_t = time.time()
 | 
			
		||||
                    cancelled = engine.test_break()
 | 
			
		||||
                    if current_t - run_t > CANCEL_POLL_SPEED:
 | 
			
		||||
 | 
			
		||||
						# update logs if needed
 | 
			
		||||
						if stdout:
 | 
			
		||||
							# (only need to update on one frame, they are linked
 | 
			
		||||
							conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
 | 
			
		||||
							response = conn.getresponse()
 | 
			
		||||
                        # update logs if needed
 | 
			
		||||
                        if stdout:
 | 
			
		||||
                            # (only need to update on one frame, they are linked
 | 
			
		||||
                            conn.request("PUT", logURL(job.id, first_frame), stdout, headers=headers)
 | 
			
		||||
                            response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
							stdout = bytes()
 | 
			
		||||
                            stdout = bytes()
 | 
			
		||||
 | 
			
		||||
						run_t = current_t
 | 
			
		||||
						if testCancel(conn, job.id, first_frame):
 | 
			
		||||
							cancelled = True
 | 
			
		||||
                        run_t = current_t
 | 
			
		||||
                        if testCancel(conn, job.id, first_frame):
 | 
			
		||||
                            cancelled = True
 | 
			
		||||
 | 
			
		||||
				# read leftovers if needed
 | 
			
		||||
				stdout += process.stdout.read()
 | 
			
		||||
                # read leftovers if needed
 | 
			
		||||
                stdout += process.stdout.read()
 | 
			
		||||
 | 
			
		||||
				if cancelled:
 | 
			
		||||
					# kill process if needed
 | 
			
		||||
					if process.poll() == None:
 | 
			
		||||
						process.terminate()
 | 
			
		||||
					continue # to next frame
 | 
			
		||||
                if cancelled:
 | 
			
		||||
                    # kill process if needed
 | 
			
		||||
                    if process.poll() == None:
 | 
			
		||||
                        process.terminate()
 | 
			
		||||
                    continue # to next frame
 | 
			
		||||
 | 
			
		||||
				total_t = time.time() - start_t
 | 
			
		||||
                total_t = time.time() - start_t
 | 
			
		||||
 | 
			
		||||
				avg_t = total_t / len(job.frames)
 | 
			
		||||
                avg_t = total_t / len(job.frames)
 | 
			
		||||
 | 
			
		||||
				status = process.returncode
 | 
			
		||||
                status = process.returncode
 | 
			
		||||
 | 
			
		||||
				print("status", status)
 | 
			
		||||
                print("status", status)
 | 
			
		||||
 | 
			
		||||
				# flush the rest of the logs
 | 
			
		||||
				if stdout:
 | 
			
		||||
					# (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:
 | 
			
		||||
						continue
 | 
			
		||||
                # flush the rest of the logs
 | 
			
		||||
                if stdout:
 | 
			
		||||
                    # (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:
 | 
			
		||||
                        continue
 | 
			
		||||
 | 
			
		||||
				headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)}
 | 
			
		||||
                headers = {"job-id":job.id, "slave-id":slave_id, "job-time":str(avg_t)}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
				if status == 0: # non zero status is error
 | 
			
		||||
					headers["job-result"] = str(DONE)
 | 
			
		||||
					for frame in job.frames:
 | 
			
		||||
						headers["job-frame"] = str(frame.number)
 | 
			
		||||
                if status == 0: # non zero status is error
 | 
			
		||||
                    headers["job-result"] = str(DONE)
 | 
			
		||||
                    for frame in job.frames:
 | 
			
		||||
                        headers["job-frame"] = str(frame.number)
 | 
			
		||||
 | 
			
		||||
						if job.type == netrender.model.JOB_BLENDER:
 | 
			
		||||
							# send image back to server
 | 
			
		||||
							f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
 | 
			
		||||
							conn.request("PUT", "/render", f, headers=headers)
 | 
			
		||||
							f.close()
 | 
			
		||||
							if conn.getresponse().status == 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:
 | 
			
		||||
								continue
 | 
			
		||||
				else:
 | 
			
		||||
					headers["job-result"] = str(ERROR)
 | 
			
		||||
					for frame in job.frames:
 | 
			
		||||
						headers["job-frame"] = str(frame.number)
 | 
			
		||||
						# send error result back to server
 | 
			
		||||
						conn.request("PUT", "/render", headers=headers)
 | 
			
		||||
						if conn.getresponse().status == http.client.NO_CONTENT:
 | 
			
		||||
							continue
 | 
			
		||||
			else:
 | 
			
		||||
				if timeout < MAX_TIMEOUT:
 | 
			
		||||
					timeout += INCREMENT_TIMEOUT
 | 
			
		||||
                        if job.type == netrender.model.JOB_BLENDER:
 | 
			
		||||
                            # send image back to server
 | 
			
		||||
                            f = open(JOB_PREFIX + "%06d" % frame.number + ".exr", 'rb')
 | 
			
		||||
                            conn.request("PUT", "/render", f, headers=headers)
 | 
			
		||||
                            f.close()
 | 
			
		||||
                            if conn.getresponse().status == 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:
 | 
			
		||||
                                continue
 | 
			
		||||
                else:
 | 
			
		||||
                    headers["job-result"] = str(ERROR)
 | 
			
		||||
                    for frame in job.frames:
 | 
			
		||||
                        headers["job-frame"] = str(frame.number)
 | 
			
		||||
                        # send error result back to server
 | 
			
		||||
                        conn.request("PUT", "/render", headers=headers)
 | 
			
		||||
                        if conn.getresponse().status == http.client.NO_CONTENT:
 | 
			
		||||
                            continue
 | 
			
		||||
            else:
 | 
			
		||||
                if timeout < MAX_TIMEOUT:
 | 
			
		||||
                    timeout += INCREMENT_TIMEOUT
 | 
			
		||||
 | 
			
		||||
				for i in range(timeout):
 | 
			
		||||
					time.sleep(1)
 | 
			
		||||
					if engine.test_break():
 | 
			
		||||
						conn.close()
 | 
			
		||||
						return
 | 
			
		||||
                for i in range(timeout):
 | 
			
		||||
                    time.sleep(1)
 | 
			
		||||
                    if engine.test_break():
 | 
			
		||||
                        conn.close()
 | 
			
		||||
                        return
 | 
			
		||||
 | 
			
		||||
		conn.close()
 | 
			
		||||
        conn.close()
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
	pass
 | 
			
		||||
    pass
 | 
			
		||||
 
 | 
			
		||||
@@ -37,319 +37,319 @@ DONE = 2
 | 
			
		||||
ERROR = 3
 | 
			
		||||
 | 
			
		||||
class RenderButtonsPanel(bpy.types.Panel):
 | 
			
		||||
	bl_space_type = "PROPERTIES"
 | 
			
		||||
	bl_region_type = "WINDOW"
 | 
			
		||||
	bl_context = "render"
 | 
			
		||||
	# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
 | 
			
		||||
    bl_space_type = "PROPERTIES"
 | 
			
		||||
    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):
 | 
			
		||||
		rd = context.scene.render_data
 | 
			
		||||
		return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        rd = context.scene.render_data
 | 
			
		||||
        return (rd.use_game_engine==False) and (rd.engine in self.COMPAT_ENGINES)
 | 
			
		||||
 | 
			
		||||
# Setting panel, use in the scene for now.
 | 
			
		||||
@rnaType
 | 
			
		||||
class RENDER_PT_network_settings(RenderButtonsPanel):
 | 
			
		||||
	bl_label = "Network Settings"
 | 
			
		||||
	COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
    bl_label = "Network Settings"
 | 
			
		||||
    COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		rd = scene.render_data
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        rd = scene.render_data
 | 
			
		||||
 | 
			
		||||
		layout.active = True
 | 
			
		||||
        layout.active = True
 | 
			
		||||
 | 
			
		||||
		split = layout.split()
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
		col = split.column()
 | 
			
		||||
        col = split.column()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		if scene.network_render.mode in ("RENDER_MASTER", "RENDER_SLAVE"):
 | 
			
		||||
			col.operator("screen.render", text="Start", icon='PLAY').animation = True
 | 
			
		||||
        if scene.network_render.mode in ("RENDER_MASTER", "RENDER_SLAVE"):
 | 
			
		||||
            col.operator("screen.render", text="Start", icon='PLAY').animation = True
 | 
			
		||||
 | 
			
		||||
		col.prop(scene.network_render, "mode")
 | 
			
		||||
		col.prop(scene.network_render, "path")
 | 
			
		||||
		col.prop(scene.network_render, "server_address")
 | 
			
		||||
		col.prop(scene.network_render, "server_port")
 | 
			
		||||
        col.prop(scene.network_render, "mode")
 | 
			
		||||
        col.prop(scene.network_render, "path")
 | 
			
		||||
        col.prop(scene.network_render, "server_address")
 | 
			
		||||
        col.prop(scene.network_render, "server_port")
 | 
			
		||||
 | 
			
		||||
		if scene.network_render.mode == "RENDER_MASTER":
 | 
			
		||||
			col.prop(scene.network_render, "server_broadcast")
 | 
			
		||||
		else:
 | 
			
		||||
			col.operator("render.netclientscan", icon='FILE_REFRESH', text="")
 | 
			
		||||
        if scene.network_render.mode == "RENDER_MASTER":
 | 
			
		||||
            col.prop(scene.network_render, "server_broadcast")
 | 
			
		||||
        else:
 | 
			
		||||
            col.operator("render.netclientscan", icon='FILE_REFRESH', text="")
 | 
			
		||||
 | 
			
		||||
		col.operator("render.netclientweb", icon='QUESTION')
 | 
			
		||||
        col.operator("render.netclientweb", icon='QUESTION')
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class RENDER_PT_network_job(RenderButtonsPanel):
 | 
			
		||||
	bl_label = "Job Settings"
 | 
			
		||||
	COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
    bl_label = "Job Settings"
 | 
			
		||||
    COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		return (super().poll(context)
 | 
			
		||||
				and scene.network_render.mode == "RENDER_CLIENT")
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        return (super().poll(context)
 | 
			
		||||
                and scene.network_render.mode == "RENDER_CLIENT")
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		rd = scene.render_data
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        rd = scene.render_data
 | 
			
		||||
 | 
			
		||||
		layout.active = True
 | 
			
		||||
        layout.active = True
 | 
			
		||||
 | 
			
		||||
		split = layout.split()
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
		col = split.column()
 | 
			
		||||
		if scene.network_render.server_address != "[default]":
 | 
			
		||||
			col.operator("render.netclientanim", icon='RENDER_ANIMATION')
 | 
			
		||||
			col.operator("render.netclientsend", icon='FILE_BLEND')
 | 
			
		||||
			if scene.network_render.job_id:
 | 
			
		||||
				col.operator("screen.render", text="Get Results", icon='RENDER_ANIMATION').animation = True
 | 
			
		||||
		col.prop(scene.network_render, "job_name")
 | 
			
		||||
		col.prop(scene.network_render, "job_category")
 | 
			
		||||
		row = col.row()
 | 
			
		||||
		row.prop(scene.network_render, "priority")
 | 
			
		||||
		row.prop(scene.network_render, "chunks")
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        if scene.network_render.server_address != "[default]":
 | 
			
		||||
            col.operator("render.netclientanim", icon='RENDER_ANIMATION')
 | 
			
		||||
            col.operator("render.netclientsend", icon='FILE_BLEND')
 | 
			
		||||
            if scene.network_render.job_id:
 | 
			
		||||
                col.operator("screen.render", text="Get Results", icon='RENDER_ANIMATION').animation = True
 | 
			
		||||
        col.prop(scene.network_render, "job_name")
 | 
			
		||||
        col.prop(scene.network_render, "job_category")
 | 
			
		||||
        row = col.row()
 | 
			
		||||
        row.prop(scene.network_render, "priority")
 | 
			
		||||
        row.prop(scene.network_render, "chunks")
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class RENDER_PT_network_slaves(RenderButtonsPanel):
 | 
			
		||||
	bl_label = "Slaves Status"
 | 
			
		||||
	COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
    bl_label = "Slaves Status"
 | 
			
		||||
    COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		return (super().poll(context)
 | 
			
		||||
				and scene.network_render.mode == "RENDER_CLIENT"
 | 
			
		||||
				and scene.network_render.server_address != "[default]")
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        return (super().poll(context)
 | 
			
		||||
                and scene.network_render.mode == "RENDER_CLIENT"
 | 
			
		||||
                and scene.network_render.server_address != "[default]")
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		netsettings = scene.network_render
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        netsettings = scene.network_render
 | 
			
		||||
 | 
			
		||||
		row = layout.row()
 | 
			
		||||
		row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2)
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
        row.template_list(netsettings, "slaves", netsettings, "active_slave_index", rows=2)
 | 
			
		||||
 | 
			
		||||
		sub = row.column(align=True)
 | 
			
		||||
		sub.operator("render.netclientslaves", icon='FILE_REFRESH', text="")
 | 
			
		||||
		sub.operator("render.netclientblacklistslave", icon='ZOOMOUT', text="")
 | 
			
		||||
        sub = row.column(align=True)
 | 
			
		||||
        sub.operator("render.netclientslaves", icon='FILE_REFRESH', text="")
 | 
			
		||||
        sub.operator("render.netclientblacklistslave", icon='ZOOMOUT', text="")
 | 
			
		||||
 | 
			
		||||
		if len(netrender.slaves) == 0 and len(netsettings.slaves) > 0:
 | 
			
		||||
			while(len(netsettings.slaves) > 0):
 | 
			
		||||
				netsettings.slaves.remove(0)
 | 
			
		||||
        if len(netrender.slaves) == 0 and len(netsettings.slaves) > 0:
 | 
			
		||||
            while(len(netsettings.slaves) > 0):
 | 
			
		||||
                netsettings.slaves.remove(0)
 | 
			
		||||
 | 
			
		||||
		if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0:
 | 
			
		||||
			layout.separator()
 | 
			
		||||
        if netsettings.active_slave_index >= 0 and len(netsettings.slaves) > 0:
 | 
			
		||||
            layout.separator()
 | 
			
		||||
 | 
			
		||||
			slave = netrender.slaves[netsettings.active_slave_index]
 | 
			
		||||
            slave = netrender.slaves[netsettings.active_slave_index]
 | 
			
		||||
 | 
			
		||||
			layout.label(text="Name: " + slave.name)
 | 
			
		||||
			layout.label(text="Address: " + slave.address[0])
 | 
			
		||||
			layout.label(text="Seen: " + time.ctime(slave.last_seen))
 | 
			
		||||
			layout.label(text="Stats: " + slave.stats)
 | 
			
		||||
            layout.label(text="Name: " + slave.name)
 | 
			
		||||
            layout.label(text="Address: " + slave.address[0])
 | 
			
		||||
            layout.label(text="Seen: " + time.ctime(slave.last_seen))
 | 
			
		||||
            layout.label(text="Stats: " + slave.stats)
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class RENDER_PT_network_slaves_blacklist(RenderButtonsPanel):
 | 
			
		||||
	bl_label = "Slaves Blacklist"
 | 
			
		||||
	COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
    bl_label = "Slaves Blacklist"
 | 
			
		||||
    COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		return (super().poll(context)
 | 
			
		||||
				and scene.network_render.mode == "RENDER_CLIENT"
 | 
			
		||||
				and scene.network_render.server_address != "[default]")
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        return (super().poll(context)
 | 
			
		||||
                and scene.network_render.mode == "RENDER_CLIENT"
 | 
			
		||||
                and scene.network_render.server_address != "[default]")
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		netsettings = scene.network_render
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        netsettings = scene.network_render
 | 
			
		||||
 | 
			
		||||
		row = layout.row()
 | 
			
		||||
		row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2)
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
        row.template_list(netsettings, "slaves_blacklist", netsettings, "active_blacklisted_slave_index", rows=2)
 | 
			
		||||
 | 
			
		||||
		sub = row.column(align=True)
 | 
			
		||||
		sub.operator("render.netclientwhitelistslave", icon='ZOOMOUT', text="")
 | 
			
		||||
        sub = row.column(align=True)
 | 
			
		||||
        sub.operator("render.netclientwhitelistslave", icon='ZOOMOUT', text="")
 | 
			
		||||
 | 
			
		||||
		if len(netrender.blacklist) == 0 and len(netsettings.slaves_blacklist) > 0:
 | 
			
		||||
			while(len(netsettings.slaves_blacklist) > 0):
 | 
			
		||||
				netsettings.slaves_blacklist.remove(0)
 | 
			
		||||
        if len(netrender.blacklist) == 0 and len(netsettings.slaves_blacklist) > 0:
 | 
			
		||||
            while(len(netsettings.slaves_blacklist) > 0):
 | 
			
		||||
                netsettings.slaves_blacklist.remove(0)
 | 
			
		||||
 | 
			
		||||
		if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0:
 | 
			
		||||
			layout.separator()
 | 
			
		||||
        if netsettings.active_blacklisted_slave_index >= 0 and len(netsettings.slaves_blacklist) > 0:
 | 
			
		||||
            layout.separator()
 | 
			
		||||
 | 
			
		||||
			slave = netrender.blacklist[netsettings.active_blacklisted_slave_index]
 | 
			
		||||
            slave = netrender.blacklist[netsettings.active_blacklisted_slave_index]
 | 
			
		||||
 | 
			
		||||
			layout.label(text="Name: " + slave.name)
 | 
			
		||||
			layout.label(text="Address: " + slave.address[0])
 | 
			
		||||
			layout.label(text="Seen: " + time.ctime(slave.last_seen))
 | 
			
		||||
			layout.label(text="Stats: " + slave.stats)
 | 
			
		||||
            layout.label(text="Name: " + slave.name)
 | 
			
		||||
            layout.label(text="Address: " + slave.address[0])
 | 
			
		||||
            layout.label(text="Seen: " + time.ctime(slave.last_seen))
 | 
			
		||||
            layout.label(text="Stats: " + slave.stats)
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class RENDER_PT_network_jobs(RenderButtonsPanel):
 | 
			
		||||
	bl_label = "Jobs"
 | 
			
		||||
	COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
    bl_label = "Jobs"
 | 
			
		||||
    COMPAT_ENGINES = {'NET_RENDER'}
 | 
			
		||||
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		return (super().poll(context)
 | 
			
		||||
				and scene.network_render.mode == "RENDER_CLIENT"
 | 
			
		||||
				and scene.network_render.server_address != "[default]")
 | 
			
		||||
    def poll(self, context):
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        return (super().poll(context)
 | 
			
		||||
                and scene.network_render.mode == "RENDER_CLIENT"
 | 
			
		||||
                and scene.network_render.server_address != "[default]")
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
		scene = context.scene
 | 
			
		||||
		netsettings = scene.network_render
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
        netsettings = scene.network_render
 | 
			
		||||
 | 
			
		||||
		row = layout.row()
 | 
			
		||||
		row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2)
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
        row.template_list(netsettings, "jobs", netsettings, "active_job_index", rows=2)
 | 
			
		||||
 | 
			
		||||
		sub = row.column(align=True)
 | 
			
		||||
		sub.operator("render.netclientstatus", icon='FILE_REFRESH', text="")
 | 
			
		||||
		sub.operator("render.netclientcancel", icon='ZOOMOUT', text="")
 | 
			
		||||
		sub.operator("render.netclientcancelall", icon='PANEL_CLOSE', text="")
 | 
			
		||||
		sub.operator("render.netclientdownload", icon='RENDER_ANIMATION', text="")
 | 
			
		||||
        sub = row.column(align=True)
 | 
			
		||||
        sub.operator("render.netclientstatus", icon='FILE_REFRESH', text="")
 | 
			
		||||
        sub.operator("render.netclientcancel", icon='ZOOMOUT', text="")
 | 
			
		||||
        sub.operator("render.netclientcancelall", icon='PANEL_CLOSE', text="")
 | 
			
		||||
        sub.operator("render.netclientdownload", icon='RENDER_ANIMATION', text="")
 | 
			
		||||
 | 
			
		||||
		if len(netrender.jobs) == 0 and len(netsettings.jobs) > 0:
 | 
			
		||||
			while(len(netsettings.jobs) > 0):
 | 
			
		||||
				netsettings.jobs.remove(0)
 | 
			
		||||
        if len(netrender.jobs) == 0 and len(netsettings.jobs) > 0:
 | 
			
		||||
            while(len(netsettings.jobs) > 0):
 | 
			
		||||
                netsettings.jobs.remove(0)
 | 
			
		||||
 | 
			
		||||
		if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0:
 | 
			
		||||
			layout.separator()
 | 
			
		||||
        if netsettings.active_job_index >= 0 and len(netsettings.jobs) > 0:
 | 
			
		||||
            layout.separator()
 | 
			
		||||
 | 
			
		||||
			job = netrender.jobs[netsettings.active_job_index]
 | 
			
		||||
            job = netrender.jobs[netsettings.active_job_index]
 | 
			
		||||
 | 
			
		||||
			layout.label(text="Name: %s" % job.name)
 | 
			
		||||
			layout.label(text="Length: %04i" % len(job))
 | 
			
		||||
			layout.label(text="Done: %04i" % job.results[DONE])
 | 
			
		||||
			layout.label(text="Error: %04i" % job.results[ERROR])
 | 
			
		||||
            layout.label(text="Name: %s" % job.name)
 | 
			
		||||
            layout.label(text="Length: %04i" % len(job))
 | 
			
		||||
            layout.label(text="Done: %04i" % job.results[DONE])
 | 
			
		||||
            layout.label(text="Error: %04i" % job.results[ERROR])
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class NetRenderSettings(bpy.types.IDPropertyGroup):
 | 
			
		||||
	pass
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class NetRenderSlave(bpy.types.IDPropertyGroup):
 | 
			
		||||
	pass
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
@rnaType
 | 
			
		||||
class NetRenderJob(bpy.types.IDPropertyGroup):
 | 
			
		||||
	pass
 | 
			
		||||
    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]")
 | 
			
		||||
                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)
 | 
			
		||||
                name="Server port",
 | 
			
		||||
                description="port of the master render server",
 | 
			
		||||
                default = 8000,
 | 
			
		||||
                min=1,
 | 
			
		||||
                max=65535)
 | 
			
		||||
 | 
			
		||||
NetRenderSettings.BoolProperty( attr="server_broadcast",
 | 
			
		||||
				name="Broadcast server address",
 | 
			
		||||
				description="broadcast server address on local network",
 | 
			
		||||
				default = True)
 | 
			
		||||
                name="Broadcast server address",
 | 
			
		||||
                description="broadcast server address on local network",
 | 
			
		||||
                default = True)
 | 
			
		||||
 | 
			
		||||
default_path = os.environ.get("TEMP", None)
 | 
			
		||||
 | 
			
		||||
if not default_path:
 | 
			
		||||
	if os.name == 'nt':
 | 
			
		||||
		default_path = "c:/tmp/"
 | 
			
		||||
	else:
 | 
			
		||||
		default_path = "/tmp/"
 | 
			
		||||
    if os.name == 'nt':
 | 
			
		||||
        default_path = "c:/tmp/"
 | 
			
		||||
    else:
 | 
			
		||||
        default_path = "/tmp/"
 | 
			
		||||
elif not default_path.endswith(os.sep):
 | 
			
		||||
	default_path += os.sep
 | 
			
		||||
    default_path += os.sep
 | 
			
		||||
 | 
			
		||||
NetRenderSettings.StringProperty( attr="path",
 | 
			
		||||
				name="Path",
 | 
			
		||||
				description="Path for temporary files",
 | 
			
		||||
				maxlen = 128,
 | 
			
		||||
				default = default_path)
 | 
			
		||||
                name="Path",
 | 
			
		||||
                description="Path for temporary files",
 | 
			
		||||
                maxlen = 128,
 | 
			
		||||
                default = default_path)
 | 
			
		||||
 | 
			
		||||
NetRenderSettings.StringProperty( attr="job_name",
 | 
			
		||||
				name="Job name",
 | 
			
		||||
				description="Name of the job",
 | 
			
		||||
				maxlen = 128,
 | 
			
		||||
				default = "[default]")
 | 
			
		||||
                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 = "")
 | 
			
		||||
                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)
 | 
			
		||||
                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)
 | 
			
		||||
                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 = "")
 | 
			
		||||
                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)
 | 
			
		||||
                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)
 | 
			
		||||
                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)
 | 
			
		||||
                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")
 | 
			
		||||
                        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 = "")
 | 
			
		||||
                name="Name of the slave",
 | 
			
		||||
                description="",
 | 
			
		||||
                maxlen = 64,
 | 
			
		||||
                default = "")
 | 
			
		||||
 | 
			
		||||
NetRenderJob.StringProperty( attr="name",
 | 
			
		||||
				name="Name of the job",
 | 
			
		||||
				description="",
 | 
			
		||||
				maxlen = 128,
 | 
			
		||||
				default = "")
 | 
			
		||||
                name="Name of the job",
 | 
			
		||||
                description="",
 | 
			
		||||
                maxlen = 128,
 | 
			
		||||
                default = "")
 | 
			
		||||
 
 | 
			
		||||
@@ -51,15 +51,15 @@ DONE = 2
 | 
			
		||||
ERROR = 3
 | 
			
		||||
 | 
			
		||||
FRAME_STATUS_TEXT = {
 | 
			
		||||
		QUEUED: "Queued",
 | 
			
		||||
		DISPATCHED: "Dispatched",
 | 
			
		||||
		DONE: "Done",
 | 
			
		||||
		ERROR: "Error"
 | 
			
		||||
		}
 | 
			
		||||
        QUEUED: "Queued",
 | 
			
		||||
        DISPATCHED: "Dispatched",
 | 
			
		||||
        DONE: "Done",
 | 
			
		||||
        ERROR: "Error"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
def rnaType(rna_type):
 | 
			
		||||
	if bpy: bpy.types.register(rna_type)
 | 
			
		||||
	return rna_type
 | 
			
		||||
    if bpy: bpy.types.register(rna_type)
 | 
			
		||||
    return rna_type
 | 
			
		||||
 | 
			
		||||
def reporting(report, message, errorType = None):
 | 
			
		||||
    if errorType:
 | 
			
		||||
@@ -123,21 +123,21 @@ def clientConnection(address, port, report = None):
 | 
			
		||||
            raise
 | 
			
		||||
 | 
			
		||||
def clientVerifyVersion(conn):
 | 
			
		||||
	conn.request("GET", "/version")
 | 
			
		||||
	response = conn.getresponse()
 | 
			
		||||
    conn.request("GET", "/version")
 | 
			
		||||
    response = conn.getresponse()
 | 
			
		||||
 | 
			
		||||
	if response.status != http.client.OK:
 | 
			
		||||
		conn.close()
 | 
			
		||||
		return False
 | 
			
		||||
    if response.status != http.client.OK:
 | 
			
		||||
        conn.close()
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
	server_version = response.read()
 | 
			
		||||
    server_version = response.read()
 | 
			
		||||
 | 
			
		||||
	if server_version != VERSION:
 | 
			
		||||
		print("Incorrect server version!")
 | 
			
		||||
		print("expected", str(VERSION, encoding='utf8'), "received", str(server_version, encoding='utf8'))
 | 
			
		||||
		return False
 | 
			
		||||
    if server_version != VERSION:
 | 
			
		||||
        print("Incorrect server version!")
 | 
			
		||||
        print("expected", str(VERSION, encoding='utf8'), "received", str(server_version, encoding='utf8'))
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
	return True
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
def fileURL(job_id, file_index):
 | 
			
		||||
    return "/file_%s_%i" % (job_id, file_index)
 | 
			
		||||
@@ -152,20 +152,20 @@ def cancelURL(job_id):
 | 
			
		||||
    return "/cancel_%s" % (job_id)
 | 
			
		||||
 | 
			
		||||
def prefixPath(prefix_directory, file_path, prefix_path):
 | 
			
		||||
	if os.path.isabs(file_path):
 | 
			
		||||
		# if an absolute path, make sure path exists, if it doesn't, use relative local path
 | 
			
		||||
		full_path = file_path
 | 
			
		||||
		if not os.path.exists(full_path):
 | 
			
		||||
			p, n = os.path.split(full_path)
 | 
			
		||||
    if os.path.isabs(file_path):
 | 
			
		||||
        # if an absolute path, make sure path exists, if it doesn't, use relative local path
 | 
			
		||||
        full_path = file_path
 | 
			
		||||
        if not os.path.exists(full_path):
 | 
			
		||||
            p, n = os.path.split(full_path)
 | 
			
		||||
 | 
			
		||||
			if prefix_path and p.startswith(prefix_path):
 | 
			
		||||
				directory = prefix_directory + p[len(prefix_path):]
 | 
			
		||||
				full_path = directory + os.sep + n
 | 
			
		||||
				if not os.path.exists(directory):
 | 
			
		||||
					os.mkdir(directory)
 | 
			
		||||
			else:
 | 
			
		||||
				full_path = prefix_directory + n
 | 
			
		||||
	else:
 | 
			
		||||
		full_path = prefix_directory + file_path
 | 
			
		||||
            if prefix_path and p.startswith(prefix_path):
 | 
			
		||||
                directory = prefix_directory + p[len(prefix_path):]
 | 
			
		||||
                full_path = directory + os.sep + n
 | 
			
		||||
                if not os.path.exists(directory):
 | 
			
		||||
                    os.mkdir(directory)
 | 
			
		||||
            else:
 | 
			
		||||
                full_path = prefix_directory + n
 | 
			
		||||
    else:
 | 
			
		||||
        full_path = prefix_directory + file_path
 | 
			
		||||
 | 
			
		||||
	return full_path
 | 
			
		||||
    return full_path
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user