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

Martin Poirier theeth at yahoo.com
Wed Sep 23 04:00:05 CEST 2009


Revision: 23430
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23430
Author:   theeth
Date:     2009-09-23 03:59:57 +0200 (Wed, 23 Sep 2009)

Log Message:
-----------
netrender. first draft of html master details. Just point a browser at the master's address and port, et voila. Gives a list of jobs and slaves and well as per frame status for each job and access to slave output logs per frame

Modified Paths:
--------------
    trunk/blender/release/io/netrender/__init__.py
    trunk/blender/release/io/netrender/client.py
    trunk/blender/release/io/netrender/master.py
    trunk/blender/release/io/netrender/model.py
    trunk/blender/release/io/netrender/utils.py

Added Paths:
-----------
    trunk/blender/release/io/netrender/master_html.py

Modified: trunk/blender/release/io/netrender/__init__.py
===================================================================
--- trunk/blender/release/io/netrender/__init__.py	2009-09-23 01:35:45 UTC (rev 23429)
+++ trunk/blender/release/io/netrender/__init__.py	2009-09-23 01:59:57 UTC (rev 23430)
@@ -5,6 +5,7 @@
 import client
 import slave
 import master
+import master_html
 import utils
 import balancing
 import ui

Modified: trunk/blender/release/io/netrender/client.py
===================================================================
--- trunk/blender/release/io/netrender/client.py	2009-09-23 01:35:45 UTC (rev 23429)
+++ trunk/blender/release/io/netrender/client.py	2009-09-23 01:59:57 UTC (rev 23430)
@@ -1,5 +1,5 @@
 import bpy
-import sys, os
+import sys, os, re
 import http, http.client, http.server, urllib
 import subprocess, shutil, time, hashlib
 

Modified: trunk/blender/release/io/netrender/master.py
===================================================================
--- trunk/blender/release/io/netrender/master.py	2009-09-23 01:35:45 UTC (rev 23429)
+++ trunk/blender/release/io/netrender/master.py	2009-09-23 01:59:57 UTC (rev 23430)
@@ -5,6 +5,7 @@
 from netrender.utils import *
 import netrender.model
 import netrender.balancing
+import netrender.master_html
 
 class MRenderFile:
 	def __init__(self, filepath, start, end):
@@ -126,9 +127,9 @@
 # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
 class RenderHandler(http.server.BaseHTTPRequestHandler):
-	def send_head(self, code = http.client.OK, headers = {}):
+	def send_head(self, code = http.client.OK, headers = {}, content = "application/octet-stream"):
 		self.send_response(code)
-		self.send_header("Content-type", "application/octet-stream")
+		self.send_header("Content-type", content)
 		
 		for key, value in headers.items():
 			self.send_header(key, value)
@@ -342,7 +343,10 @@
 			self.send_head()
 			
 			self.wfile.write(bytes(repr(message), encoding='utf8'))
-			
+		# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+		else:
+			# hand over the rest to the html section
+			netrender.master_html.get(self)
 
 	# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 	# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Added: trunk/blender/release/io/netrender/master_html.py
===================================================================
--- trunk/blender/release/io/netrender/master_html.py	                        (rev 0)
+++ trunk/blender/release/io/netrender/master_html.py	2009-09-23 01:59:57 UTC (rev 23430)
@@ -0,0 +1,119 @@
+import re
+
+from netrender.utils import *
+
+
+def get(handler):
+	def output(text):
+		handler.wfile.write(bytes(text, encoding='utf8'))
+	
+	def link(text, url):
+		return "<a href='%s'>%s</a>" % (url, text)
+	
+	def startTable(border=1):
+		output("<table border='%i'>" % border)
+	
+	def headerTable(*headers):
+		output("<thead><tr>")
+		
+		for c in headers:
+			output("<td>" + c + "</td>")
+		
+		output("</tr></thead>")
+	
+	def rowTable(*data):
+		output("<tr>")
+		
+		for c in data:
+			output("<td>" + str(c) + "</td>")
+		
+		output("</tr>")
+	
+	def endTable():
+		output("</table>")
+	
+	handler.send_head(content = "text/html")
+	
+	if handler.path == "/html" or handler.path == "/":
+		output("<html><head><title>NetRender</title></head><body>")
+	
+		output("<h2>Master</h2>")
+	
+		output("<h2>Slaves</h2>")
+		
+		startTable()
+		headerTable("id", "name", "address", "stats")
+		
+		for slave in handler.server.slaves:
+			rowTable(slave.id, slave.name, slave.address[0], slave.stats)
+		
+		endTable()
+		
+		output("<h2>Jobs</h2>")
+		
+		startTable()
+		headerTable("id", "name", "length", "done", "dispatched", "error")
+		
+		for job in handler.server.jobs:
+			results = job.framesStatus()
+			rowTable(link(job.id, "/html/job" + job.id), job.name, len(job), results[DONE], results[DISPATCHED], results[ERROR])
+		
+		endTable()
+		
+		output("</body></html>")
+	
+	elif handler.path.startswith("/html/job"):
+		job_id = handler.path[9:]
+		
+		output("<html><head><title>NetRender</title></head><body>")
+	
+		job = handler.server.getJobByID(job_id)
+		
+		if job:
+			output("<h2>Frames</h2>")
+		
+			startTable()
+			headerTable("no", "status", "render time", "slave", "log")
+			
+			for frame in job.frames:
+				rowTable(frame.number, frame.statusText(), "%.1fs" % frame.time, frame.slave.name if frame.slave else " ", link("view log", "/html/log%s_%i" % (job_id, frame.number)) if frame.log_path else " ")
+			
+			endTable()
+		else:
+			output("no such job")
+		
+		output("</body></html>")
+	
+	elif handler.path.startswith("/html/log"):
+		pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)")
+		
+		output("<html><head><title>NetRender</title></head><body>")
+		
+		match = pattern.match(handler.path[9:])
+		if match:
+			job_id = match.groups()[0]
+			frame_number = int(match.groups()[1])
+			
+			job = handler.server.getJobByID(job_id)
+			
+			if job:
+				frame = job[frame_number]
+				
+				if frame:
+						f = open(frame.log_path, 'rb')
+						
+						output("<pre>")
+						
+						shutil.copyfileobj(f, handler.wfile)
+						
+						output("</pre>")
+						
+						f.close()
+				else:
+					output("no such frame")
+			else:
+				output("no such job")
+		else:
+			output("malformed url")
+		
+		output("</body></html>")


Property changes on: trunk/blender/release/io/netrender/master_html.py
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Modified: trunk/blender/release/io/netrender/model.py
===================================================================
--- trunk/blender/release/io/netrender/model.py	2009-09-23 01:35:45 UTC (rev 23429)
+++ trunk/blender/release/io/netrender/model.py	2009-09-23 01:59:57 UTC (rev 23430)
@@ -32,7 +32,7 @@
 	def __init__(self):
 		self.id = ""
 		self.name = ""
-		self.address = (0,0)
+		self.address = ("",0)
 		self.stats = ""
 		self.total_done = 0
 		self.total_error = 0
@@ -173,6 +173,9 @@
 		self.status = QUEUED
 		self.slave = None
 
+	def statusText(self):
+		return STATUS_TEXT[self.status]
+
 	def serialize(self):
 		return 	{
 							"number": self.number,

Modified: trunk/blender/release/io/netrender/utils.py
===================================================================
--- trunk/blender/release/io/netrender/utils.py	2009-09-23 01:35:45 UTC (rev 23429)
+++ trunk/blender/release/io/netrender/utils.py	2009-09-23 01:59:57 UTC (rev 23430)
@@ -19,6 +19,13 @@
 DONE = 2
 ERROR = 3
 
+STATUS_TEXT = {
+								QUEUED: "Queued",
+								DISPATCHED: "Dispatched",
+								DONE: "Done",
+								ERROR: "Error"
+							}
+
 def rnaType(rna_type):
 	bpy.types.register(rna_type)
 	return rna_type





More information about the Bf-blender-cvs mailing list