netrender. first draft of html master details. Just point a browser at the master...
[blender.git] / release / io / netrender / master_html.py
1 import re
2
3 from netrender.utils import *
4
5
6 def get(handler):
7         def output(text):
8                 handler.wfile.write(bytes(text, encoding='utf8'))
9         
10         def link(text, url):
11                 return "<a href='%s'>%s</a>" % (url, text)
12         
13         def startTable(border=1):
14                 output("<table border='%i'>" % border)
15         
16         def headerTable(*headers):
17                 output("<thead><tr>")
18                 
19                 for c in headers:
20                         output("<td>" + c + "</td>")
21                 
22                 output("</tr></thead>")
23         
24         def rowTable(*data):
25                 output("<tr>")
26                 
27                 for c in data:
28                         output("<td>" + str(c) + "</td>")
29                 
30                 output("</tr>")
31         
32         def endTable():
33                 output("</table>")
34         
35         handler.send_head(content = "text/html")
36         
37         if handler.path == "/html" or handler.path == "/":
38                 output("<html><head><title>NetRender</title></head><body>")
39         
40                 output("<h2>Master</h2>")
41         
42                 output("<h2>Slaves</h2>")
43                 
44                 startTable()
45                 headerTable("id", "name", "address", "stats")
46                 
47                 for slave in handler.server.slaves:
48                         rowTable(slave.id, slave.name, slave.address[0], slave.stats)
49                 
50                 endTable()
51                 
52                 output("<h2>Jobs</h2>")
53                 
54                 startTable()
55                 headerTable("id", "name", "length", "done", "dispatched", "error")
56                 
57                 for job in handler.server.jobs:
58                         results = job.framesStatus()
59                         rowTable(link(job.id, "/html/job" + job.id), job.name, len(job), results[DONE], results[DISPATCHED], results[ERROR])
60                 
61                 endTable()
62                 
63                 output("</body></html>")
64         
65         elif handler.path.startswith("/html/job"):
66                 job_id = handler.path[9:]
67                 
68                 output("<html><head><title>NetRender</title></head><body>")
69         
70                 job = handler.server.getJobByID(job_id)
71                 
72                 if job:
73                         output("<h2>Frames</h2>")
74                 
75                         startTable()
76                         headerTable("no", "status", "render time", "slave", "log")
77                         
78                         for frame in job.frames:
79                                 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;")
80                         
81                         endTable()
82                 else:
83                         output("no such job")
84                 
85                 output("</body></html>")
86         
87         elif handler.path.startswith("/html/log"):
88                 pattern = re.compile("([a-zA-Z0-9]+)_([0-9]+)")
89                 
90                 output("<html><head><title>NetRender</title></head><body>")
91                 
92                 match = pattern.match(handler.path[9:])
93                 if match:
94                         job_id = match.groups()[0]
95                         frame_number = int(match.groups()[1])
96                         
97                         job = handler.server.getJobByID(job_id)
98                         
99                         if job:
100                                 frame = job[frame_number]
101                                 
102                                 if frame:
103                                                 f = open(frame.log_path, 'rb')
104                                                 
105                                                 output("<pre>")
106                                                 
107                                                 shutil.copyfileobj(f, handler.wfile)
108                                                 
109                                                 output("</pre>")
110                                                 
111                                                 f.close()
112                                 else:
113                                         output("no such frame")
114                         else:
115                                 output("no such job")
116                 else:
117                         output("malformed url")
118                 
119                 output("</body></html>")