[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25405] trunk/blender/release/scripts/io/ netrender: netrender

Martin Poirier theeth at yahoo.com
Tue Dec 15 19:09:05 CET 2009


Revision: 25405
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25405
Author:   theeth
Date:     2009-12-15 19:09:01 +0100 (Tue, 15 Dec 2009)

Log Message:
-----------
netrender

buttons to cancel and reset jobs in the web interface

Modified Paths:
--------------
    trunk/blender/release/scripts/io/netrender/master.py
    trunk/blender/release/scripts/io/netrender/master_html.py
    trunk/blender/release/scripts/io/netrender/operators.py
    trunk/blender/release/scripts/io/netrender/utils.py

Added Paths:
-----------
    trunk/blender/release/scripts/io/netrender/netrender.js

Modified: trunk/blender/release/scripts/io/netrender/master.py
===================================================================
--- trunk/blender/release/scripts/io/netrender/master.py	2009-12-15 18:00:22 UTC (rev 25404)
+++ trunk/blender/release/scripts/io/netrender/master.py	2009-12-15 18:09:01 UTC (rev 25405)
@@ -139,6 +139,7 @@
 		
 	def reset(self, all):
 		if all or self.status == ERROR:
+			self.log_path = None
 			self.slave = None
 			self.time = 0
 			self.status = QUEUED
@@ -151,6 +152,8 @@
 file_pattern = re.compile("/file_([a-zA-Z0-9]+)_([0-9]+)")
 render_pattern = re.compile("/render_([a-zA-Z0-9]+)_([0-9]+).exr")
 log_pattern = re.compile("/log_([a-zA-Z0-9]+)_([0-9]+).log")
+reset_pattern = re.compile("/reset(all|)_([a-zA-Z0-9]+)_([0-9]+)")
+cancel_pattern = re.compile("/cancel_([a-zA-Z0-9]+)")
 
 class RenderHandler(http.server.BaseHTTPRequestHandler):
 	def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"):
@@ -419,17 +422,23 @@
 				self.server.stats("", "New job, missing files (%i total)" % len(job.files))
 				self.send_head(http.client.ACCEPTED, headers=headers)
 		# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-		elif self.path == "/cancel":
-			job_id = self.headers.get('job-id', "")
+		elif self.path.startswith("/cancel"):
+			match = cancel_pattern.match(self.path)
+
+			if match:
+				job_id = match.groups()[0]
 			
-			job = self.server.getJobID(job_id)
-			
-			if job:
-				self.server.stats("", "Cancelling job")
-				self.server.removeJob(job)
-				self.send_head()
+				job = self.server.getJobID(job_id)
+				
+				if job:
+					self.server.stats("", "Cancelling job")
+					self.server.removeJob(job)
+					self.send_head()
+				else: 
+					# no such job id
+					self.send_head(http.client.NO_CONTENT)
 			else: 
-				# no such job id
+				# invalid url
 				self.send_head(http.client.NO_CONTENT)
 				
 		# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@@ -440,31 +449,36 @@
 				
 			self.send_head()
 		# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-		elif self.path == "/reset":
-			job_id = self.headers.get('job-id', "")
-			job_frame = int(self.headers.get('job-frame', "-1"))
-			all = bool(self.headers.get('reset-all', "False"))
+		elif self.path.startswith("/reset"):
+			match = reset_pattern.match(self.path)
 			
-			job = self.server.getJobID(job_id)
-			
-			if job:
-				if job_frame != -1:
-					
-					frame = job[job_frame]
-					if frame:
-						self.server.stats("", "Reset job frame")
-						frame.reset(all)
+			if match:
+				all = match.groups()[0] == 'all'
+				job_id = match.groups()[1]
+				job_frame = int(match.groups()[2])
+
+				job = self.server.getJobID(job_id)
+				
+				if job:
+					if job_frame != 0:
+						
+						frame = job[job_frame]
+						if frame:
+							self.server.stats("", "Reset job frame")
+							frame.reset(all)
+							self.send_head()
+						else:
+							# no such frame
+							self.send_head(http.client.NO_CONTENT)
+							
+					else:
+						self.server.stats("", "Reset job")
+						job.reset(all)
 						self.send_head()
-					else:
-						# no such frame
-						self.send_head(http.client.NO_CONTENT)
 						
-				else:
-					self.server.stats("", "Reset job")
-					job.reset(all)
-					self.send_head()
-					
-			else: # job not found
+				else: # job not found
+					self.send_head(http.client.NO_CONTENT)
+			else: # invalid url
 				self.send_head(http.client.NO_CONTENT)
 		# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 		elif self.path == "/slave":

Modified: trunk/blender/release/scripts/io/netrender/master_html.py
===================================================================
--- trunk/blender/release/scripts/io/netrender/master_html.py	2009-12-15 18:00:22 UTC (rev 25404)
+++ trunk/blender/release/scripts/io/netrender/master_html.py	2009-12-15 18:09:01 UTC (rev 25405)
@@ -16,14 +16,23 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
+import os
 import re
-
+import shutil
 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 head(title):
+		output("<html><head>")
+		output("<script src='/html/netrender.js' type='text/javascript'></script>")
+		output("<title>")
+		output(title)
+		output("</title></head><body>")
 	
 	def link(text, url):
 		return "<a href='%s'>%s</a>" % (url, text)
@@ -50,12 +59,21 @@
 	def endTable():
 		output("</table>")
 	
-	if handler.path == "/html" or handler.path == "/":
+	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)
+		
+		f.close()		
+	elif handler.path == "/html" or handler.path == "/":
 		handler.send_head(content = "text/html")
-		output("<html><head><title>NetRender</title></head><body>")
+		head("NetRender")
 	
 		output("<h2>Master</h2>")
-	
+		
+		output("""<button title="remove all jobs" onclick="request('/clear', null);">CLEAR</button>""")
+		
 		output("<h2>Slaves</h2>")
 		
 		startTable()
@@ -70,6 +88,7 @@
 		
 		startTable()
 		headerTable(	
+				                    " ",
 									"name",
 									"category",
 									"priority",
@@ -79,6 +98,7 @@
 									"done",
 									"dispatched",
 									"error",
+				                    " ",
 									"first",
 									"exception"
 								)
@@ -88,6 +108,7 @@
 		for job in handler.server.jobs:
 			results = job.framesStatus()
 			rowTable(	
+								"""<button title="cancel job" onclick="request('/cancel_%s', null);">X</button>""" % job.id,
 								link(job.name, "/html/job" + job.id),
 								job.category if job.category else " ",
 								job.priority,
@@ -97,6 +118,7 @@
 								results[DONE],
 								results[DISPATCHED],
 								results[ERROR],
+								"""<button title="reset error frames" onclick="request('/reset_%s_0', null);">R</button>""" % job.id,
 								handler.server.balancer.applyPriorities(job), handler.server.balancer.applyExceptions(job)
 							)
 		
@@ -108,7 +130,7 @@
 		handler.send_head(content = "text/html")
 		job_id = handler.path[9:]
 		
-		output("<html><head><title>NetRender</title></head><body>")
+		head("NetRender")
 	
 		job = handler.server.getJobID(job_id)
 		

Added: trunk/blender/release/scripts/io/netrender/netrender.js
===================================================================
--- trunk/blender/release/scripts/io/netrender/netrender.js	                        (rev 0)
+++ trunk/blender/release/scripts/io/netrender/netrender.js	2009-12-15 18:09:01 UTC (rev 25405)
@@ -0,0 +1,26 @@
+function post_to_url(path, params, method) {
+    method = method || "post"; // Set method to post by default, if not specified.
+
+    var form = document.createElement("form");
+    form.setAttribute("method", method);
+    form.setAttribute("action", path);
+
+    for(var key in params) {
+        var hiddenField = document.createElement("input");
+        hiddenField.setAttribute("type", "hidden");
+        hiddenField.setAttribute("name", key);
+        hiddenField.setAttribute("value", params[key]);
+
+        form.appendChild(hiddenField);
+    }
+
+    document.body.appendChild(form);
+    form.submit();
+}
+
+function request(url, data) {
+	xmlhttp = new XMLHttpRequest();
+	xmlhttp.open("POST", url, false);
+	xmlhttp.send(data);
+	window.location.reload()	
+}

Modified: trunk/blender/release/scripts/io/netrender/operators.py
===================================================================
--- trunk/blender/release/scripts/io/netrender/operators.py	2009-12-15 18:00:22 UTC (rev 25404)
+++ trunk/blender/release/scripts/io/netrender/operators.py	2009-12-15 18:09:01 UTC (rev 25405)
@@ -299,7 +299,7 @@
 		if conn:
 			job = netrender.jobs[netsettings.active_job_index]
 			
-			conn.request("POST", "/cancel", headers={"job-id":job.id})
+			conn.request("POST", cancelURL(job.id))
 			
 			response = conn.getresponse()
 			print( response.status, response.reason )

Modified: trunk/blender/release/scripts/io/netrender/utils.py
===================================================================
--- trunk/blender/release/scripts/io/netrender/utils.py	2009-12-15 18:00:22 UTC (rev 25404)
+++ trunk/blender/release/scripts/io/netrender/utils.py	2009-12-15 18:09:01 UTC (rev 25405)
@@ -118,6 +118,9 @@
 def renderURL(job_id, frame_number):
     return "/render_%s_%i.exr" % (job_id, frame_number)
 
+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





More information about the Bf-blender-cvs mailing list