2 from zope
.interface
import Interface
3 from twisted
.web
import html
, resource
4 from buildbot
.status
import builder
8 class ITopBox(Interface
):
9 """I represent a box in the top row of the waterfall display: the one
10 which shows the status of the last build for each builder."""
13 class ICurrentBox(Interface
):
14 """I represent the 'current activity' box, just above the builder name."""
17 class IBox(Interface
):
18 """I represent a box in the waterfall display."""
21 class IHTMLLog(Interface
):
26 <span class="label">%(label)s</span>
27 <span class="field">%(field)s</span>
30 def make_row(label
, field
):
31 """Create a name/value row for the HTML.
33 `label` is plain text; it will be HTML-encoded.
35 `field` is a bit of HTML structure; it will not be encoded in
38 label
= html
.escape(label
)
39 return ROW_TEMPLATE
% {"label": label
, "field": field
}
44 def td(text
="", parms
={}, **props
):
47 #if not props.has_key("border"):
50 if props
.has_key("bgcolor"):
51 props
["bgcolor"] = colormap
.get(props
["bgcolor"], props
["bgcolor"])
52 comment
= props
.get("comment", None)
54 data
+= "<!-- %s -->" % comment
56 class_
= props
.get('class_', None)
58 props
["class"] = class_
59 for prop
in ("align", "bgcolor", "colspan", "rowspan", "border",
60 "valign", "halign", "class"):
61 p
= props
.get(prop
, None)
63 data
+= " %s=\"%s\"" % (prop
, p
)
67 if isinstance(text
, list):
68 data
+= "<br />".join(text
)
74 def build_get_class(b
):
76 Return the class to use for a finished build or buildstep,
79 # FIXME: this getResults duplicity might need to be fixed
80 result
= b
.getResults()
81 #print "THOMAS: result for b %r: %r" % (b, result)
82 if isinstance(b
, builder
.BuildStatus
):
83 result
= b
.getResults()
84 elif isinstance(b
, builder
.BuildStepStatus
):
85 result
= b
.getResults()[0]
86 # after forcing a build, b.getResults() returns ((None, []), []), ugh
87 if isinstance(result
, tuple):
90 raise TypeError, "%r is not a BuildStatus or BuildStepStatus" % b
93 # FIXME: this happens when a buildstep is running ?
95 return builder
.Results
[result
]
98 # a Box wraps an Event. The Box has HTML <td> parameters that Events
99 # lack, and it has a base URL to which each File's name is relative.
100 # Events don't know about HTML.
102 def __init__(self
, text
=[], color
=None, class_
=None, urlbase
=None,
107 self
.urlbase
= urlbase
109 if parms
.has_key('show_idle'):
110 del parms
['show_idle']
114 # parms is a dict of HTML parameters for the <td> element that will
115 # represent this Event in the waterfall display.
117 def td(self
, **props
):
118 props
.update(self
.parms
)
120 if not text
and self
.show_idle
:
122 return td(text
, props
, bgcolor
=self
.color
, class_
=self
.class_
)
125 class HtmlResource(resource
.Resource
):
126 # this is a cheap sort of template thingy
127 contentType
= "text/html; charset=UTF-8"
130 def render(self
, request
):
131 data
= self
.content(request
)
132 if isinstance(data
, unicode):
133 data
= data
.encode("utf-8")
134 request
.setHeader("content-type", self
.contentType
)
135 if request
.method
== "HEAD":
136 request
.setHeader("content-length", len(data
))
140 def getStatus(self
, request
):
141 return request
.site
.buildbot_service
.getStatus()
142 def getControl(self
, request
):
143 return request
.site
.buildbot_service
.getControl()
145 def getChangemaster(self
, request
):
146 return request
.site
.buildbot_service
.parent
.change_svc
148 def path_to_root(self
, request
):
149 return "../" * len(request
.prepath
)
151 def getTitle(self
, request
):
154 def fillTemplate(self
, template
, request
):
155 s
= request
.site
.buildbot_service
156 values
= s
.template_values
.copy()
157 values
['root'] = self
.path_to_root(request
)
158 # e.g. to reference the top-level 'buildbot.css' page, use
159 # "%(root)sbuildbot.css"
160 values
['title'] = self
.getTitle(request
)
161 return template
% values
163 def content(self
, request
):
164 s
= request
.site
.buildbot_service
166 data
+= self
.fillTemplate(s
.header
, request
)
168 for he
in s
.head_elements
:
169 data
+= " " + self
.fillTemplate(he
, request
) + "\n"
170 data
+= "</head>\n\n"
172 data
+= '<body %s>\n' % " ".join(['%s="%s"' % (k
,v
)
173 for (k
,v
) in s
.body_attrs
.items()])
174 data
+= self
.body(request
)
176 data
+= self
.fillTemplate(s
.footer
, request
)
179 def body(self
, request
):
182 class StaticHTML(HtmlResource
):
183 def __init__(self
, body
, title
):
184 HtmlResource
.__init
__(self
)
187 def body(self
, request
):