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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2009-09-23 05:59:57 +0400
committerMartin Poirier <theeth@yahoo.com>2009-09-23 05:59:57 +0400
commitefa757fd8d57891f6feb3fc85fdd3e2ab88e7623 (patch)
tree80f8a4be7b9cb50abcf179120489d150d0e66524 /release
parentd98700360838e5dbb52ac633d0a32c5558754eb7 (diff)
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
Diffstat (limited to 'release')
-rw-r--r--release/io/netrender/__init__.py1
-rw-r--r--release/io/netrender/client.py2
-rw-r--r--release/io/netrender/master.py10
-rw-r--r--release/io/netrender/master_html.py119
-rw-r--r--release/io/netrender/model.py5
-rw-r--r--release/io/netrender/utils.py7
6 files changed, 139 insertions, 5 deletions
diff --git a/release/io/netrender/__init__.py b/release/io/netrender/__init__.py
index b313d64ccbb..4a1dd2238e3 100644
--- a/release/io/netrender/__init__.py
+++ b/release/io/netrender/__init__.py
@@ -5,6 +5,7 @@ import operators
import client
import slave
import master
+import master_html
import utils
import balancing
import ui
diff --git a/release/io/netrender/client.py b/release/io/netrender/client.py
index f445fe2f608..65b2937867f 100644
--- a/release/io/netrender/client.py
+++ b/release/io/netrender/client.py
@@ -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
diff --git a/release/io/netrender/master.py b/release/io/netrender/master.py
index 1bff5f6340b..0e3c7063cab 100644
--- a/release/io/netrender/master.py
+++ b/release/io/netrender/master.py
@@ -5,6 +5,7 @@ import subprocess, shutil, time, hashlib
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 MRenderFrame(netrender.model.RenderFrame):
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
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 @@ class RenderHandler(http.server.BaseHTTPRequestHandler):
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)
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
diff --git a/release/io/netrender/master_html.py b/release/io/netrender/master_html.py
new file mode 100644
index 00000000000..6a337c8d71d
--- /dev/null
+++ b/release/io/netrender/master_html.py
@@ -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 "&nbsp;", link("view log", "/html/log%s_%i" % (job_id, frame.number)) if frame.log_path else "&nbsp;")
+
+ 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>")
diff --git a/release/io/netrender/model.py b/release/io/netrender/model.py
index e8046d7ac8c..9cacfb54a35 100644
--- a/release/io/netrender/model.py
+++ b/release/io/netrender/model.py
@@ -32,7 +32,7 @@ class RenderSlave:
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 @@ class RenderFrame:
self.status = QUEUED
self.slave = None
+ def statusText(self):
+ return STATUS_TEXT[self.status]
+
def serialize(self):
return {
"number": self.number,
diff --git a/release/io/netrender/utils.py b/release/io/netrender/utils.py
index 50ca08d1723..62288aecf94 100644
--- a/release/io/netrender/utils.py
+++ b/release/io/netrender/utils.py
@@ -19,6 +19,13 @@ DISPATCHED = 1
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