def debugDumpDict(self, sName, dDict, fSorted = True, fnWrite = None): """ Dumps dictionary. """ if fnWrite is None: fnWrite = self.write; asKeys = list(dDict.keys()); if fSorted: asKeys.sort(); if self._fHtmlDebugOutput: fnWrite('<h2>%s</h2>\n' '<table border="1"><tr><th>name</th><th>value</th></tr>\n' % (sName,)); for sKey in asKeys: fnWrite(' <tr><td>' + webutils.escapeElem(sKey) + '</td><td>' \ + webutils.escapeElem(str(dDict.get(sKey))) \ + '</td></tr>\n'); fnWrite('</table>\n'); else: for i in range(len(sName) - 1): fnWrite('%s ' % (sName[i],)); fnWrite('%s\n\n' % (sName[-1],)); fnWrite('%28s Value\n' % ('Name',)); fnWrite('------------------------------------------------------------------------\n'); for sKey in asKeys: fnWrite('%28s: %s\n' % (sKey, dDict.get(sKey),)); fnWrite('\n'); return True;
def _formatSeriesNameForTable(self, oSet, idKey): oTestBox = oSet.dSubjects[idKey] sHtml = u'<td>' sHtml += WuiTestResultsForTestBoxLink( idKey, oTestBox.sName, self._dExtraTestResultsParams).toHtml() sHtml += u' ' sHtml += WuiTestBoxDetailsLinkShort(oTestBox).toHtml() sHtml += u' ' sHtml += WuiReportSummaryLink( ReportModelBase.ksSubTestBox, oTestBox.idTestBox, dExtraParams=self._dExtraParams).toHtml() sHtml += u'</td>' sOsAndVer = '%s %s' % ( oTestBox.sOs, oTestBox.sOsVersion.strip(), ) if len(sOsAndVer) < 22: sHtml += u'<td>%s</td>' % (webutils.escapeElem(sOsAndVer), ) else: # wonder if td.title works.. sHtml += u'<td title="%s" width="1%%" style="white-space:nowrap;">%s...</td>' \ % (webutils.escapeAttr(sOsAndVer), webutils.escapeElem(sOsAndVer[:20])) sHtml += u'<td>%s</td>' % (webutils.escapeElem( oTestBox.getArchBitString()), ) sHtml += u'<td>%s</td>' % (webutils.escapeElem( oTestBox.getPrettyCpuVendor()), ) sHtml += u'<td>%s' % (oTestBox.getPrettyCpuVersion(), ) if oTestBox.fCpuNestedPaging: sHtml += u', np' elif oTestBox.fCpuHwVirt: sHtml += u', hw' else: sHtml += u', raw' if oTestBox.fCpu64BitGuest: sHtml += u', 64' sHtml += u'</td>' return sHtml
def _formatCommentCell(self, sComment, cMaxLines = 3, cchMaxLine = 63): """ Helper functions for formatting comment cell. Returns None or WuiRawHtml instance. """ # Nothing to do for empty comments. if sComment is None: return None; sComment = sComment.strip(); if len(sComment) == 0: return None; # Restrict the text if necessary, making the whole text available thru mouse-over. ## @todo this would be better done by java script or smth, so it could automatically adjust to the table size. if len(sComment) > cchMaxLine or sComment.count('\n') >= cMaxLines: sShortHtml = ''; for iLine, sLine in enumerate(sComment.split('\n')): if iLine >= cMaxLines: break; if iLine > 0: sShortHtml += '<br>\n'; if len(sLine) > cchMaxLine: sShortHtml += webutils.escapeElem(sLine[:(cchMaxLine - 3)]); sShortHtml += '...'; else: sShortHtml += webutils.escapeElem(sLine); return WuiRawHtml('<span class="tmcomment" title="%s">%s</span>' % (webutils.escapeAttr(sComment), sShortHtml,)); return WuiRawHtml('<span class="tmcomment">%s</span>' % (webutils.escapeElem(sComment).replace('\n', '<br>'),));
def _generateTableHeaders(self): """ Generate table headers. Returns raw html string. Overridable. """ sHtml = ' <thead class="tmheader"><tr>'; for iHeader, oHeader in enumerate(self._asColumnHeaders): if isinstance(oHeader, WuiHtmlBase): sHtml += '<th>' + oHeader.toHtml() + '</th>'; elif iHeader < len(self._aaiColumnSorting) and self._aaiColumnSorting[iHeader] is not None: sHtml += '<th>' iSorting = self._checkSortingByColumnAscending(self._aaiColumnSorting[iHeader]); if iSorting > 0: sDirection = ' ▴' if iSorting == 1 else '<small> ▵</small>'; sSortParams = ','.join([str(-i) for i in self._aaiColumnSorting[iHeader]]); else: sDirection = ''; if iSorting < 0: sDirection = ' ▾' if iSorting == -1 else '<small> ▿</small>' sSortParams = ','.join([str(i) for i in self._aaiColumnSorting[iHeader]]); sHtml += '<a href="javascript:ahrefActionSortByColumns(\'%s\',[%s]);">' \ % (WuiDispatcherBase.ksParamSortColumns, sSortParams); sHtml += webutils.escapeElem(oHeader) + '</a>' + sDirection + '</th>'; else: sHtml += '<th>' + webutils.escapeElem(oHeader) + '</th>'; sHtml += '</tr><thead>\n'; return sHtml
def _formatCommentCell(self, sComment, cMaxLines = 3, cchMaxLine = 63): """ Helper functions for formatting comment cell. Returns None or WuiRawHtml instance. """ # Nothing to do for empty comments. if sComment is None: return None; sComment = sComment.strip(); if not sComment: return None; # Restrict the text if necessary, making the whole text available thru mouse-over. ## @todo this would be better done by java script or smth, so it could automatically adjust to the table size. if len(sComment) > cchMaxLine or sComment.count('\n') >= cMaxLines: sShortHtml = ''; for iLine, sLine in enumerate(sComment.split('\n')): if iLine >= cMaxLines: break; if iLine > 0: sShortHtml += '<br>\n'; if len(sLine) > cchMaxLine: sShortHtml += webutils.escapeElem(sLine[:(cchMaxLine - 3)]); sShortHtml += '...'; else: sShortHtml += webutils.escapeElem(sLine); return WuiRawHtml('<span class="tmcomment" title="%s">%s</span>' % (webutils.escapeAttr(sComment), sShortHtml,)); return WuiRawHtml('<span class="tmcomment">%s</span>' % (webutils.escapeElem(sComment).replace('\n', '<br>'),));
def _formatChangeLogEntry(self, aoEntries, iEntry): """ Formats one change log entry into one or more HTML table rows. Note! The parameters are given as array + index in case someone wishes to access adjacent entries later in order to generate better change descriptions. """ oEntry = aoEntries[iEntry]; # The primary row. sRowClass = 'tmodd' if (iEntry + 1) & 1 else 'tmeven'; sContent = ' <tr class="%s">\n' \ ' <td rowspan="%d">%s</td>\n' \ ' <td rowspan="%d">%s</td>\n' \ ' <td colspan="3">%s%s</td>\n' \ ' </tr>\n' \ % ( sRowClass, len(oEntry.aoChanges) + 1, webutils.escapeElem(self.formatTsShort(oEntry.tsEffective)), len(oEntry.aoChanges) + 1, webutils.escapeElem(self.formatTsShort(oEntry.tsExpire)), self._guessChangeLogEntryDescription(aoEntries, iEntry), ' '.join(oLink.toHtml() for oLink in self._calcChangeLogEntryLinks(aoEntries, iEntry)),); # Additional rows for each changed attribute. j = 0; for oChange in oEntry.aoChanges: sContent += ' <tr class="%s%s"><td>%s</td><td>%s</td><td>%s</td></tr>\n' \ % ( sRowClass, 'odd' if j & 1 else 'even', webutils.escapeElem(oChange.sAttr), webutils.escapeElem(oChange.sOldText), webutils.escapeElem(oChange.sNewText), ); j += 1; return sContent;
def _formatChangeLogEntry(self, aoEntries, iEntry): """ Formats one change log entry into one or more HTML table rows. Note! The parameters are given as array + index in case someone wishes to access adjacent entries later in order to generate better change descriptions. """ oEntry = aoEntries[iEntry] # The primary row. sRowClass = 'tmodd' if (iEntry + 1) & 1 else 'tmeven' sContent = ' <tr class="%s">\n' \ ' <td rowspan="%d">%s</td>\n' \ ' <td rowspan="%d">%s</td>\n' \ ' <td colspan="3">%s%s</td>\n' \ ' </tr>\n' \ % ( sRowClass, len(oEntry.aoChanges) + 1, webutils.escapeElem(self.formatTsShort(oEntry.tsEffective)), len(oEntry.aoChanges) + 1, webutils.escapeElem(self.formatTsShort(oEntry.tsExpire)), self._guessChangeLogEntryDescription(aoEntries, iEntry), ' '.join(oLink.toHtml() for oLink in self._calcChangeLogEntryLinks(aoEntries, iEntry)),) # Additional rows for each changed attribute. j = 0 for oChange in oEntry.aoChanges: sContent += ' <tr class="%s%s"><td>%s</td><td>%s</td><td>%s</td></tr>\n' \ % ( sRowClass, 'odd' if j & 1 else 'even', webutils.escapeElem(oChange.sAttr), webutils.escapeElem(oChange.sOldText), webutils.escapeElem(oChange.sNewText), ) j += 1 return sContent
def _formatSeriesNameForTable(self, oSet, idKey): oReason = oSet.dSubjects[idKey] sHtml = u'<td>' sHtml += u'%s / %s' % ( webutils.escapeElem(oReason.oCategory.sShort), webutils.escapeElem(oReason.sShort), ) sHtml += u'</td>' return sHtml
def _toHtml(self, oObject): """Translate some object to HTML.""" if isinstance(oObject, WuiHtmlBase): return oObject.toHtml() if db.isDbTimestamp(oObject): return webutils.escapeElem(self.formatTsShort(oObject)) if utils.isString(oObject): return webutils.escapeElem(oObject) return webutils.escapeElem(str(oObject))
def _toHtml(self, oObject): """Translate some object to HTML.""" if isinstance(oObject, WuiHtmlBase): return oObject.toHtml(); if db.isDbTimestamp(oObject): return webutils.escapeElem(self.formatTsShort(oObject)); if utils.isString(oObject): return webutils.escapeElem(oObject); return webutils.escapeElem(str(oObject));
def _addList(self, sName, aoRows, sLabel, fUseTable=False, sId="dummy", sExtraAttribs=""): """ Adds a list of items to check. @param sName Name of HTML form element @param aoRows List of [sValue, fChecked, sName] sub-arrays. @param sLabel Label of HTML form element """ fReadOnly = self._fReadOnly ## @todo add this as a parameter. if fReadOnly: sExtraAttribs += ' readonly onclick="return false" onkeydown="return false"' self._addLabel(sName, sLabel, "list") if len(aoRows) == 0: return self._add("No items</div></div></li>") sNameEscaped = escapeAttr(sName) self._add(' <div class="tmform-checkboxes-container" id="%s">\n' % (escapeAttr(sId),)) if fUseTable: self._add(" <table>\n") for asRow in aoRows: assert len(asRow) == 3 # Don't allow sloppy input data! fChecked = self._reinterpretBool(asRow[1]) self._add( " <tr>\n" ' <td><input type="checkbox" name="%s" value="%s"%s%s></td>\n' " <td>%s</td>\n" " </tr>\n" % ( sNameEscaped, escapeAttr(str(asRow[0])), " checked" if fChecked else "", sExtraAttribs, escapeElem(str(asRow[2])), ) ) self._add(" </table>\n") else: for asRow in aoRows: assert len(asRow) == 3 # Don't allow sloppy input data! fChecked = self._reinterpretBool(asRow[1]) self._add( ' <div class="tmform-checkbox-holder">' '<input type="checkbox" name="%s" value="%s"%s%s> %s</input></div>\n' % ( sNameEscaped, escapeAttr(str(asRow[0])), " checked" if fChecked else "", sExtraAttribs, escapeElem(str(asRow[2])), ) ) return self._add(" </div></div></div>\n" " </li>\n")
def _escapeErrorText(self, sText): """Escapes error text, preserving some predefined HTML tags.""" if sText.find("<br>") >= 0: asParts = sText.split("<br>") for i in range(len(asParts)): asParts[i] = escapeElem(asParts[i].strip()) sText = "<br>\n".join(asParts) else: sText = escapeElem(sText) return sText
def _escapeErrorText(self, sText): """Escapes error text, preserving some predefined HTML tags.""" if sText.find('<br>') >= 0: asParts = sText.split('<br>'); for i in range(len(asParts)): asParts[i] = escapeElem(asParts[i].strip()); sText = '<br>\n'.join(asParts); else: sText = escapeElem(sText); return sText;
def showForm(self, dErrors=None, sErrorMsg=None): """ Render the form. """ oForm = WuiHlpForm( self._sId, '?' + webutils.encodeUrlParams( {WuiDispatcherBase.ksParamAction: self._sSubmitAction}), dErrors if dErrors is not None else dict(), fReadOnly=self._sMode == self.ksMode_Show) self._oData.convertToParamNull() # If form cannot be constructed due to some reason we # need to show this reason try: self._populateForm(oForm, self._oData) if self._sRedirectTo is not None: oForm.addTextHidden(self._oDisp.ksParamRedirectTo, self._sRedirectTo) except WuiException as oXcpt: sContent = unicode(oXcpt) else: sContent = oForm.finalize() # Add any post form content. atPostFormContent = self._generatePostFormContent(self._oData) if atPostFormContent: for iSection, tSection in enumerate(atPostFormContent): (sSectionTitle, sSectionContent) = tSection sContent += u'<div id="postform-%d" class="tmformpostsection">\n' % ( iSection, ) if sSectionTitle: sContent += '<h3 class="tmformpostheader">%s</h3>\n' % ( webutils.escapeElem(sSectionTitle), ) sContent += u' <div id="postform-%d-content" class="tmformpostcontent">\n' % ( iSection, ) sContent += sSectionContent sContent += u' </div>\n' \ u'</div>\n' # Add action to the top. aoActions = self._generateTopRowFormActions(self._oData) if aoActions: sActionLinks = '<p>%s</p>' % (' '.join( unicode(oLink) for oLink in aoActions)) sContent = sActionLinks + sContent # Add error info to the top. if sErrorMsg is not None: sContent = '<p class="tmerrormsg">' + webutils.escapeElem( sErrorMsg) + '</p>\n' + sContent return (self._sTitle, sContent)
def _generateMenus(self): """ Generates the two menus, returning them as (sTopMenuItems, sSideMenuItems). """ # # We use the action to locate the side menu. # aasSideMenu = None for cchAction in range(len(self._sAction), 1, -1): sActionParam = "%s=%s" % (self.ksParamAction, self._sAction[:cchAction]) for aoItem in self._aaoMenus: if aoItem[1].find(sActionParam) > 0: aasSideMenu = aoItem[2] break for asSubItem in aoItem[2]: if asSubItem[1].find(sActionParam) > 0: aasSideMenu = aoItem[2] break if aasSideMenu is not None: break # # Top menu first. # sTopMenuItems = "" for aoItem in self._aaoMenus: if aasSideMenu is aoItem[2]: sTopMenuItems += '<li class="current_page_item">' else: sTopMenuItems += "<li>" sTopMenuItems += ( '<a href="' + webutils.escapeAttr(aoItem[1]) + '">' + webutils.escapeElem(aoItem[0]) + "</a></li>\n" ) # # Side menu (if found). # sActionParam = "%s=%s" % (self.ksParamAction, self._sAction) sSideMenuItems = "" if aasSideMenu is not None: for asSubItem in aasSideMenu: if asSubItem[1].find(sActionParam) > 0: sSideMenuItems += '<li class="current_page_item">' else: sSideMenuItems += "<li>" sSideMenuItems += ( '<a href="' + webutils.escapeAttr(asSubItem[1]) + '">' + webutils.escapeElem(asSubItem[0]) + "</a></li>\n" ) return (sTopMenuItems, sSideMenuItems)
def _generateMenus(self): """ Generates the two menus, returning them as (sTopMenuItems, sSideMenuItems). """ fReadOnly = self.isReadOnlyUser(); # # We use the action to locate the side menu. # aasSideMenu = None; for cchAction in range(len(self._sAction), 1, -1): sActionParam = '%s=%s' % (self.ksParamAction, self._sAction[:cchAction]); for aoItem in self._aaoMenus: if self._isMenuMatch(aoItem[1], sActionParam): aasSideMenu = aoItem[2]; break; for asSubItem in aoItem[2]: if self._isMenuMatch(asSubItem[1], sActionParam): aasSideMenu = aoItem[2]; break; if aasSideMenu is not None: break; # # Top menu first. # sTopMenuItems = ''; for aoItem in self._aaoMenus: if aasSideMenu is aoItem[2]: sTopMenuItems += '<li class="current_page_item">'; else: sTopMenuItems += '<li>'; sTopMenuItems += '<a href="' + webutils.escapeAttr(aoItem[1]) + '">' \ + webutils.escapeElem(aoItem[0]) + '</a></li>\n'; # # Side menu (if found). # sActionParam = '%s=%s' % (self.ksParamAction, self._sAction); sSideMenuItems = ''; if aasSideMenu is not None: for asSubItem in aasSideMenu: if asSubItem[1] is not None: if not asSubItem[2] or not fReadOnly: if self._isSideMenuMatch(asSubItem[1], sActionParam): sSideMenuItems += '<li class="current_page_item">'; else: sSideMenuItems += '<li>'; sSideMenuItems += '<a href="' + webutils.escapeAttr(asSubItem[1]) + '">' \ + webutils.escapeElem(asSubItem[0]) + '</a></li>\n'; else: sSideMenuItems += '<li class="subheader_item">' + webutils.escapeElem(asSubItem[0]) + '</li>'; return (sTopMenuItems, sSideMenuItems);
def __init__(self, sSpanClass, sText, sTitle=None): if sTitle is None: WuiRawHtml.__init__( self, u'<span class="%s">%s</span>' % ( webutils.escapeAttr(sSpanClass), webutils.escapeElem(sText), )) else: WuiRawHtml.__init__( self, u'<span class="%s" title="%s">%s</span>' % ( webutils.escapeAttr(sSpanClass), webutils.escapeAttr(sTitle), webutils.escapeElem(sText), ))
def _generateMenus(self): """ Generates the two menus, returning them as (sTopMenuItems, sSideMenuItems). """ # # We use the action to locate the side menu. # aasSideMenu = None for cchAction in range(len(self._sAction), 1, -1): sActionParam = '%s=%s' % (self.ksParamAction, self._sAction[:cchAction]) for aoItem in self._aaoMenus: if self._isMenuMatch(aoItem[1], sActionParam): aasSideMenu = aoItem[2] break for asSubItem in aoItem[2]: if self._isMenuMatch(asSubItem[1], sActionParam): aasSideMenu = aoItem[2] break if aasSideMenu is not None: break # # Top menu first. # sTopMenuItems = '' for aoItem in self._aaoMenus: if aasSideMenu is aoItem[2]: sTopMenuItems += '<li class="current_page_item">' else: sTopMenuItems += '<li>' sTopMenuItems += '<a href="' + webutils.escapeAttr(aoItem[1]) + '">' \ + webutils.escapeElem(aoItem[0]) + '</a></li>\n' # # Side menu (if found). # sActionParam = '%s=%s' % (self.ksParamAction, self._sAction) sSideMenuItems = '' if aasSideMenu is not None: for asSubItem in aasSideMenu: if self._isSideMenuMatch(asSubItem[1], sActionParam): sSideMenuItems += '<li class="current_page_item">' else: sSideMenuItems += '<li>' sSideMenuItems += '<a href="' + webutils.escapeAttr(asSubItem[1]) + '">' \ + webutils.escapeElem(asSubItem[0]) + '</a></li>\n' return (sTopMenuItems, sSideMenuItems)
def _formatListEntryHtml(self, iEntry): """ Formats the specified list entry as HTML. Returns HTML for a table row. The child class can override this to """ if (iEntry + 1) & 1: sRow = u' <tr class="tmodd">\n' else: sRow = u' <tr class="tmeven">\n' aoValues = self._formatListEntry(iEntry) assert len(aoValues) == len( self._asColumnHeaders), '%s vs %s' % (len(aoValues), len(self._asColumnHeaders)) for i in range(len(aoValues)): if i < len(self._asColumnAttribs) and len( self._asColumnAttribs[i]) > 0: sRow += u' <td ' + self._asColumnAttribs[i] + '>' else: sRow += u' <td>' if isinstance(aoValues[i], WuiHtmlBase): sRow += aoValues[i].toHtml() elif isinstance(aoValues[i], list): if len(aoValues[i]) > 0: for oElement in aoValues[i]: if isinstance(oElement, WuiHtmlBase): sRow += oElement.toHtml() elif db.isDbTimestamp(oElement): sRow += webutils.escapeElem( self.formatTsShort(oElement)) else: sRow += webutils.escapeElem(unicode(oElement)) sRow += ' ' elif db.isDbTimestamp(aoValues[i]): sRow += webutils.escapeElem(self.formatTsShort(aoValues[i])) elif db.isDbInterval(aoValues[i]): sRow += webutils.escapeElem( self.formatIntervalShort(aoValues[i])) elif aoValues[i] is not None: sRow += webutils.escapeElem(unicode(aoValues[i])) sRow += u'</td>\n' return sRow + u' </tr>\n'
def _addLabel(self, sName, sLabel, sDivSubClass = 'normal'): """Internal worker for adding a label.""" if sName in self._dErrors: sError = self._dErrors[sName]; if utils.isString(sError): # List error trick (it's an associative array). return self._add(' <li>\n' ' <div class="tmform-field"><div class="tmform-field-%s">\n' ' <label for="%s" class="tmform-error-label">%s\n' ' <span class="tmform-error-desc">%s</span>\n' ' </label>\n' % (escapeAttr(sDivSubClass), escapeAttr(sName), escapeElem(sLabel), self._escapeErrorText(sError), ) ); return self._add(' <li>\n' ' <div class="tmform-field"><div class="tmform-field-%s">\n' ' <label for="%s">%s</label>\n' % (escapeAttr(sDivSubClass), escapeAttr(sName), escapeElem(sLabel)) );
def addTextHidden(self, sName, sValue, sExtraAttribs = ''): """Adds a hidden text input.""" return self._add(' <div class="tmform-field-hidden">\n' ' <input name="%s" id="%s" type="text" hidden%s value="%s" class="tmform-hidden">\n' ' </div>\n' ' </li>\n' % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)) ));
def _generateTable(self): """ show worker that just generates the table. """ # # Create a table. # If no colum headers are provided, fall back on database field # names, ASSUMING that the entries are ModelDataBase children. # Note! the cellspacing is for IE8. # sPageBody = '<table class="tmtable" id="' + self._sId + '" cellspacing="0">\n' if len(self._asColumnHeaders) == 0: self._asColumnHeaders = self._aoEntries[0].getDataAttributes() sPageBody += ' <thead class="tmheader"><tr>' for oHeader in self._asColumnHeaders: if isinstance(oHeader, WuiHtmlBase): sPageBody += "<th>" + oHeader.toHtml() + "</th>" else: sPageBody += "<th>" + webutils.escapeElem(oHeader) + "</th>" sPageBody += "</tr><thead>\n" # # Format the body and close the table. # sPageBody += " <tbody>\n" for iEntry in range(min(len(self._aoEntries), self._cItemsPerPage)): sPageBody += self._formatListEntryHtml(iEntry) sPageBody += " </tbody>\n" "</table>\n" return sPageBody
def debugDumpList(self, sName, aoStuff, fnWrite = None): """ Dumps array. """ if fnWrite is None: fnWrite = self.write; if self._fHtmlDebugOutput: fnWrite('<h2>%s</h2>\n' '<table border="1"><tr><th>index</th><th>value</th></tr>\n' % (sName,)); for i in range(len(aoStuff)): fnWrite(' <tr><td>' + str(i) + '</td><td>' + webutils.escapeElem(str(aoStuff[i])) + '</td></tr>\n'); fnWrite('</table>\n'); else: for i in range(len(sName) - 1): fnWrite('%s ' % (sName[i],)); fnWrite('%s\n\n' % (sName[-1],)); fnWrite('Index Value\n'); fnWrite('------------------------------------------------------------------------\n'); for i in range(len(aoStuff)): fnWrite('%5u %s\n' % (i, str(aoStuff[i]))); fnWrite('\n'); return True;
def debugDumpList(self, sName, aoStuff, fnWrite = None): """ Dumps array. """ if fnWrite is None: fnWrite = self.write; if self._fHtmlDebugOutput: fnWrite('<h2>%s</h2>\n' '<table border="1"><tr><th>index</th><th>value</th></tr>\n' % (sName,)); for i, _ in enumerate(aoStuff): fnWrite(' <tr><td>' + str(i) + '</td><td>' + webutils.escapeElem(str(aoStuff[i])) + '</td></tr>\n'); fnWrite('</table>\n'); else: for ch in sName[:-1]: fnWrite('%s ' % (ch,)); fnWrite('%s\n\n' % (sName[-1],)); fnWrite('Index Value\n'); fnWrite('------------------------------------------------------------------------\n'); for i, oStuff in enumerate(aoStuff): fnWrite('%5u %s\n' % (i, str(oStuff))); fnWrite('\n'); return True;
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin; oEntry = self._aoEntries[iEntry]; aoActions = [ WuiTmLink('Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildCategoryDetails, BuildCategoryData.ksParam_idBuildCategory: oEntry.idBuildCategory, }), WuiTmLink('Clone', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildCategoryClone, BuildCategoryData.ksParam_idBuildCategory: oEntry.idBuildCategory, }), WuiTmLink('Try Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildCategoryDoRemove, BuildCategoryData.ksParam_idBuildCategory: oEntry.idBuildCategory, }), ]; sHtml = '<ul class="tmshowall">\n'; for sOsArch in oEntry.asOsArches: sHtml += ' <li class="tmshowall">%s</li>\n' % (webutils.escapeElem(sOsArch),); sHtml += '</ul>\n' return [ oEntry.idBuildCategory, oEntry.sRepository, oEntry.sProduct, oEntry.sBranch, oEntry.sType, WuiRawHtml(sHtml), aoActions, ];
def debugDumpList(self, sName, aoStuff, fnWrite=None): """ Dumps array. """ if fnWrite is None: fnWrite = self.write if self._fHtmlDebugOutput: fnWrite( '<h2>%s</h2>\n' '<table border="1"><tr><th>index</th><th>value</th></tr>\n' % (sName, )) for i, _ in enumerate(aoStuff): fnWrite(' <tr><td>' + str(i) + '</td><td>' + webutils.escapeElem(str(aoStuff[i])) + '</td></tr>\n') fnWrite('</table>\n') else: for ch in sName[:-1]: fnWrite('%s ' % (ch, )) fnWrite('%s\n\n' % (sName[-1], )) fnWrite('Index Value\n') fnWrite( '------------------------------------------------------------------------\n' ) for i, oStuff in enumerate(aoStuff): fnWrite('%5u %s\n' % (i, str(oStuff))) fnWrite('\n') return True
def _htmlTable(self, aoTableContent): """Generate HTML code for table""" sHtml = u' <table class="tmtbl-testresult-details" width="100%%">\n'; for aoSubRows in aoTableContent: if len(aoSubRows) == 0: continue; # Can happen if there is no testsuit. oCaption = aoSubRows[0]; sHtml += u' \n' \ u' <tr class="tmtbl-result-details-caption">\n' \ u' <td colspan="2">%s</td>\n' \ u' </tr>\n' \ % (self._toHtml(oCaption),); iRow = 0; for aoRow in aoSubRows[1:]: iRow += 1; sHtml += u' <tr class="%s">\n' % ('tmodd' if iRow & 1 else 'tmeven',); if len(aoRow) == 1: sHtml += u' <td class="tmtbl-result-details-subcaption" colspan="2">%s</td>\n' \ % (self._toHtml(aoRow[0]),); else: sHtml += u' <th scope="row">%s</th>\n' % (webutils.escapeElem(aoRow[0]),); if len(aoRow) > 2: sHtml += u' <td>%s</td>\n' % (aoRow[2](aoRow[1]),); else: sHtml += u' <td>%s</td>\n' % (self._toHtml(aoRow[1]),); sHtml += u' </tr>\n'; sHtml += u' </table>\n'; return sHtml
def _generatePostFormContent(self, oData): from testmanager.webui.wuihlpform import WuiHlpForm; oForm = WuiHlpForm('testbox-machine-settable', '', fReadOnly = True); oForm.addTextRO( TestBoxData.ksParam_sOs, oData.sOs, 'TestBox OS'); oForm.addTextRO( TestBoxData.ksParam_sOsVersion, oData.sOsVersion, 'TestBox OS version'); oForm.addTextRO( TestBoxData.ksParam_sCpuArch, oData.sCpuArch, 'TestBox OS kernel architecture'); oForm.addTextRO( TestBoxData.ksParam_sCpuVendor, oData.sCpuVendor, 'TestBox CPU vendor'); oForm.addTextRO( TestBoxData.ksParam_sCpuName, oData.sCpuName, 'TestBox CPU name'); if oData.lCpuRevision: oForm.addTextRO( TestBoxData.ksParam_lCpuRevision, '%#x' % (oData.lCpuRevision,), 'TestBox CPU revision', sPostHtml = ' (family=%#x model=%#x stepping=%#x)' % (oData.getCpuFamily(), oData.getCpuModel(), oData.getCpuStepping(),), sSubClass = 'long'); else: oForm.addLongRO( TestBoxData.ksParam_lCpuRevision, oData.lCpuRevision, 'TestBox CPU revision'); oForm.addIntRO( TestBoxData.ksParam_cCpus, oData.cCpus, 'Number of CPUs, cores and threads'); oForm.addCheckBoxRO( TestBoxData.ksParam_fCpuHwVirt, oData.fCpuHwVirt, 'VT-x or AMD-V supported'); oForm.addCheckBoxRO( TestBoxData.ksParam_fCpuNestedPaging, oData.fCpuNestedPaging, 'Nested paging supported'); oForm.addCheckBoxRO( TestBoxData.ksParam_fCpu64BitGuest, oData.fCpu64BitGuest, '64-bit guest supported'); oForm.addCheckBoxRO( TestBoxData.ksParam_fChipsetIoMmu, oData.fChipsetIoMmu, 'I/O MMU supported'); oForm.addMultilineTextRO(TestBoxData.ksParam_sReport, oData.sReport, 'Hardware/software report'); oForm.addLongRO( TestBoxData.ksParam_cMbMemory, oData.cMbMemory, 'Installed RAM size (MB)'); oForm.addLongRO( TestBoxData.ksParam_cMbScratch, oData.cMbScratch, 'Available scratch space (MB)'); oForm.addIntRO( TestBoxData.ksParam_iTestBoxScriptRev, oData.iTestBoxScriptRev, 'TestBox Script SVN revision'); sHexVer = oData.formatPythonVersion(); oForm.addIntRO( TestBoxData.ksParam_iPythonHexVersion, oData.iPythonHexVersion, 'Python version (hex)', sPostHtml = webutils.escapeElem(sHexVer)); return [('Machine Only Settables', oForm.finalize()),];
def _generateTable(self): """ show worker that just generates the table. """ # # Create a table. # If no colum headers are provided, fall back on database field # names, ASSUMING that the entries are ModelDataBase children. # Note! the cellspacing is for IE8. # sPageBody = '<table class="tmtable" id="' + self._sId + '" cellspacing="0">\n' if len(self._asColumnHeaders) == 0: self._asColumnHeaders = self._aoEntries[0].getDataAttributes() sPageBody += ' <thead class="tmheader"><tr>' for oHeader in self._asColumnHeaders: if isinstance(oHeader, WuiHtmlBase): sPageBody += '<th>' + oHeader.toHtml() + '</th>' else: sPageBody += '<th>' + webutils.escapeElem(oHeader) + '</th>' sPageBody += '</tr><thead>\n' # # Format the body and close the table. # sPageBody += ' <tbody>\n' for iEntry in range(min(len(self._aoEntries), self._cItemsPerPage)): sPageBody += self._formatListEntryHtml(iEntry) sPageBody += ' </tbody>\n' \ '</table>\n' return sPageBody
def generateReportBody(self): self._sTitle = 'Summary'; sHtml = '<p>This will display several reports and listings useful to get an overview of %s (id=%s).</p>' \ % (self._oModel.sSubject, self._oModel.aidSubjects,); aoReports = []; aoReports.append(WuiReportSuccessRate( self._oModel, self._dParams, fSubReport = True, aiSortColumns = self._aiSortColumns, fnDPrint = self._fnDPrint, oDisp = self._oDisp)); aoReports.append(WuiReportTestCaseFailures(self._oModel, self._dParams, fSubReport = True, aiSortColumns = self._aiSortColumns, fnDPrint = self._fnDPrint, oDisp = self._oDisp)); if self._oModel.sSubject == ReportModelBase.ksSubTestCase: aoReports.append(WuiReportTestCaseArgsFailures(self._oModel, self._dParams, fSubReport = True, aiSortColumns = self._aiSortColumns, fnDPrint = self._fnDPrint, oDisp = self._oDisp)); aoReports.append(WuiReportTestBoxFailures( self._oModel, self._dParams, fSubReport = True, aiSortColumns = self._aiSortColumns, fnDPrint = self._fnDPrint, oDisp = self._oDisp)); aoReports.append(WuiReportFailureReasons( self._oModel, self._dParams, fSubReport = True, aiSortColumns = self._aiSortColumns, fnDPrint = self._fnDPrint, oDisp = self._oDisp)); for oReport in aoReports: (sTitle, sContent) = oReport.show(); sHtml += '<br>'; # drop this layout hack sHtml += '<div>'; sHtml += '<h3>%s</h3>\n' % (webutils.escapeElem(sTitle),); sHtml += sContent; sHtml += '</div>'; return sHtml;
def showForm(self, dErrors = None, sErrorMsg = None): """ Render the form. """ oForm = WuiHlpForm(self._sId, '?' + webutils.encodeUrlParams({WuiDispatcherBase.ksParamAction: self._sSubmitAction}), dErrors if dErrors is not None else dict(), fReadOnly = self._sMode == self.ksMode_Show); self._oData.convertToParamNull(); # If form cannot be constructed due to some reason we # need to show this reason try: self._populateForm(oForm, self._oData); if self._sRedirectTo is not None: oForm.addTextHidden(self._oDisp.ksParamRedirectTo, self._sRedirectTo); except WuiException as oXcpt: sContent = unicode(oXcpt) else: sContent = oForm.finalize(); # Add any post form content. atPostFormContent = self._generatePostFormContent(self._oData); if atPostFormContent: for iSection, tSection in enumerate(atPostFormContent): (sSectionTitle, sSectionContent) = tSection; sContent += u'<div id="postform-%d" class="tmformpostsection">\n' % (iSection,); if sSectionTitle: sContent += '<h3 class="tmformpostheader">%s</h3>\n' % (webutils.escapeElem(sSectionTitle),); sContent += u' <div id="postform-%d-content" class="tmformpostcontent">\n' % (iSection,); sContent += sSectionContent; sContent += u' </div>\n' \ u'</div>\n'; # Add action to the top. aoActions = self._generateTopRowFormActions(self._oData); if aoActions: sActionLinks = '<p>%s</p>' % (' '.join(unicode(oLink) for oLink in aoActions)); sContent = sActionLinks + sContent; # Add error info to the top. if sErrorMsg is not None: sContent = '<p class="tmerrormsg">' + webutils.escapeElem(sErrorMsg) + '</p>\n' + sContent; return (self._sTitle, sContent);
def debugHtmlReport(self, tsStart = 0): """ Used to get a SQL activity dump as HTML, usually for WuiBase._sDebug. """ cNsElapsed = 0; for aEntry in self._aoTraceBack: cNsElapsed += aEntry[2]; sDebug = '<h3>SQL Debug Log (total time %s ns):</h3>\n' \ '<table class="tmsqltable">\n' \ ' <tr>\n' \ ' <th>No.</th>\n' \ ' <th>Timestamp (ns)</th>\n' \ ' <th>Elapsed (ns)</th>\n' \ ' <th>Rows Returned</th>\n' \ ' <th>Command</th>\n' \ ' <th>Caller</th>\n' \ ' </tr>\n' \ % (utils.formatNumber(cNsElapsed, ' '),); iEntry = 0; for aEntry in self._aoTraceBack: iEntry += 1; sDebug += ' <tr>\n' \ ' <td align="right">%s</td>\n' \ ' <td align="right">%s</td>\n' \ ' <td align="right">%s</td>\n' \ ' <td align="right">%s</td>\n' \ ' <td><pre>%s</pre></td>\n' \ ' <td>%s</td>\n' \ ' </tr>\n' \ % (iEntry, utils.formatNumber(aEntry[0] - tsStart, ' '), utils.formatNumber(aEntry[2], ' '), utils.formatNumber(aEntry[3], ' '), webutils.escapeElem(aEntry[1]), webutils.escapeElem(aEntry[4]), ); if aEntry[5] is not None: sDebug += ' <tr>\n' \ ' <td colspan="6"><pre style="white-space: pre-wrap;">%s</pre></td>\n' \ ' </tr>\n' \ % (webutils.escapeElem('\n'.join([aoRow[0] for aoRow in aEntry[5]])),); sDebug += '</table>'; return sDebug;
def addTextRO(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = '', sPostHtml = ''): """Adds a read-only text input.""" if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp', 'wide'): raise Exception(sSubClass); self._addLabel(sName, sLabel, sSubClass); return self._add(' <input name="%s" id="%s" type="text" readonly%s value="%s" class="tmform-input-readonly">%s\n' ' </div></div>\n' ' </li>\n' % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)), sPostHtml ));
def debugHtmlReport(self, tsStart=0): """ Used to get a SQL activity dump as HTML, usually for WuiBase._sDebug. """ cNsElapsed = 0 for aEntry in self._aoTraceBack: cNsElapsed += aEntry[2] sDebug = '<h3>SQL Debug Log (total time %s ns):</h3>\n' \ '<table class="tmsqltable">\n' \ ' <tr>\n' \ ' <th>No.</th>\n' \ ' <th>Timestamp (ns)</th>\n' \ ' <th>Elapsed (ns)</th>\n' \ ' <th>Rows Returned</th>\n' \ ' <th>Command</th>\n' \ ' <th>Caller</th>\n' \ ' </tr>\n' \ % (utils.formatNumber(cNsElapsed, ' '),) iEntry = 0 for aEntry in self._aoTraceBack: iEntry += 1 sDebug += ' <tr>\n' \ ' <td align="right">%s</td>\n' \ ' <td align="right">%s</td>\n' \ ' <td align="right">%s</td>\n' \ ' <td align="right">%s</td>\n' \ ' <td><pre>%s</pre></td>\n' \ ' <td>%s</td>\n' \ ' </tr>\n' \ % (iEntry, utils.formatNumber(aEntry[0] - tsStart, ' '), utils.formatNumber(aEntry[2], ' '), utils.formatNumber(aEntry[3], ' '), webutils.escapeElem(aEntry[1]), webutils.escapeElem(aEntry[4]), ) if aEntry[5] is not None: sDebug += ' <tr>\n' \ ' <td colspan="6"><pre style="white-space: pre-wrap;">%s</pre></td>\n' \ ' </tr>\n' \ % (webutils.escapeElem('\n'.join([aoRow[0] for aoRow in aEntry[5]])),) sDebug += '</table>' return sDebug
def addMultilineTextRO(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = ''): """Adds a multiline read-only text input.""" if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp'): raise Exception(sSubClass) self._addLabel(sName, sLabel, sSubClass) sNewValue = str(sValue) if not isinstance(sValue, list) else '\n'.join(sValue) return self._add(' <textarea name="%s" id="%s" readonly %s>%s</textarea>\n' ' </div></div>\n' ' </li>\n' % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(sNewValue)))
def __init__(self, sSpanClass, sText, sTitle = None): if sTitle is None: WuiRawHtml.__init__(self, u'<span class="%s">%s</span>' % ( webutils.escapeAttr(sSpanClass), webutils.escapeElem(sText),)); else: WuiRawHtml.__init__(self, u'<span class="%s" title="%s">%s</span>' % ( webutils.escapeAttr(sSpanClass), webutils.escapeAttr(sTitle), webutils.escapeElem(sText),));
def getTcDepsHtmlList(aoTestCaseData): """Get HTML <ul> list of Test Case name items""" if len(aoTestCaseData) > 0: sTmp = '<ul>' for oTestCaseData in aoTestCaseData: sTmp += '<li>%s</li>' % (webutils.escapeElem(oTestCaseData.sName),); sTmp += '</ul>' else: sTmp = 'No items' return sTmp
def addTextRO(self, sName, sValue, sLabel, sSubClass="string", sExtraAttribs="", sPostHtml=""): """Adds a read-only text input.""" if sSubClass not in ("int", "long", "string", "uuid", "timestamp", "wide"): raise Exception(sSubClass) self._addLabel(sName, sLabel, sSubClass) return self._add( ' <input name="%s" id="%s" type="text" readonly%s value="%s" class="tmform-input-readonly">%s\n' " </div></div>\n" " </li>\n" % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)), sPostHtml) )
def _formatListEntryHtml(self, iEntry): """ Formats the specified list entry as HTML. Returns HTML for a table row. The child class can override this to """ if (iEntry + 1) & 1: sRow = u' <tr class="tmodd">\n'; else: sRow = u' <tr class="tmeven">\n'; aoValues = self._formatListEntry(iEntry); assert len(aoValues) == len(self._asColumnHeaders), '%s vs %s' % (len(aoValues), len(self._asColumnHeaders)); for i, _ in enumerate(aoValues): if i < len(self._asColumnAttribs) and len(self._asColumnAttribs[i]) > 0: sRow += u' <td ' + self._asColumnAttribs[i] + '>'; else: sRow += u' <td>'; if isinstance(aoValues[i], WuiHtmlBase): sRow += aoValues[i].toHtml(); elif isinstance(aoValues[i], list): if len(aoValues[i]) > 0: for oElement in aoValues[i]: if isinstance(oElement, WuiHtmlBase): sRow += oElement.toHtml(); elif db.isDbTimestamp(oElement): sRow += webutils.escapeElem(self.formatTsShort(oElement)); else: sRow += webutils.escapeElem(unicode(oElement)); sRow += ' '; elif db.isDbTimestamp(aoValues[i]): sRow += webutils.escapeElem(self.formatTsShort(aoValues[i])); elif db.isDbInterval(aoValues[i]): sRow += webutils.escapeElem(self.formatIntervalShort(aoValues[i])); elif aoValues[i] is not None: sRow += webutils.escapeElem(unicode(aoValues[i])); sRow += u'</td>\n'; return sRow + u' </tr>\n';
def getGrDepsHtmlList(aoGlobalResourceData): """Get HTML <ul> list of Global Resource name items""" if len(aoGlobalResourceData) > 0: sTmp = '<ul>' for oGlobalResourceData in aoGlobalResourceData: sTmp += '<li>%s</li>' % (webutils.escapeElem(oGlobalResourceData.sName),); sTmp += '</ul>' else: sTmp = 'No items' return sTmp
def addMultilineTextRO(self, sName, sValue, sLabel, sSubClass="string", sExtraAttribs=""): """Adds a multiline read-only text input.""" if sSubClass not in ("int", "long", "string", "uuid", "timestamp"): raise Exception(sSubClass) self._addLabel(sName, sLabel, sSubClass) sNewValue = str(sValue) if not isinstance(sValue, list) else "\n".join(sValue) return self._add( ' <textarea name="%s" id="%s" readonly %s>%s</textarea>\n' " </div></div>\n" " </li>\n" % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(sNewValue)) )
def show(self): """ Generates the tooltip. Returns (sTitle, HTML). """ sHtml = '<div class="tmvcstimeline tmvcstimelinetooltip">\n' oCurDate = None for oEntry in self.aoEntries: oTsZulu = db.dbTimestampToZuluDatetime(oEntry.tsCreated) if oCurDate is None or oCurDate != oTsZulu.date(): if oCurDate is not None: sHtml += ' </dl>\n' oCurDate = oTsZulu.date() sHtml += ' <h2>%s:</h2>\n' \ ' <dl>\n' \ % (oTsZulu.strftime('%Y-%m-%d'),) sEntry = ' <dt id="r%s">' % (oEntry.iRevision, ) sEntry += '<a href="%s">' \ % ( webutils.escapeAttr(config.g_ksTracChangsetUrlFmt % { 'iRevision': oEntry.iRevision, 'sRepository': oEntry.sRepository,}), ) sEntry += '<span class="tmvcstimeline-time">%s</span>' % ( oTsZulu.strftime('%H:%MZ'), ) sEntry += ' Changeset <span class="tmvcstimeline-rev">[%s]</span>' % ( oEntry.iRevision, ) sEntry += ' by <span class="tmvcstimeline-author">%s</span>' % ( webutils.escapeElem(oEntry.sAuthor), ) sEntry += '</a>\n' sEntry += '</dt>\n' sEntry += ' <dd>%s</dd>\n' % (webutils.escapeElem( oEntry.sMessage), ) sHtml += sEntry if oCurDate is not None: sHtml += ' </dl>\n' sHtml += '</div>\n' return ('VCS History Tooltip', sHtml)
def _formatListEntryHtml(self, iEntry): """ Formats the specified list entry as HTML. Returns HTML for a table row. The child class can override this to """ if (iEntry + 1) & 1: sRow = u' <tr class="tmodd">\n' else: sRow = u' <tr class="tmeven">\n' aoValues = self._formatListEntry(iEntry) assert len(aoValues) == len(self._asColumnHeaders), "%s vs %s" % (len(aoValues), len(self._asColumnHeaders)) for i in range(len(aoValues)): if i < len(self._asColumnAttribs) and len(self._asColumnAttribs[i]) > 0: sRow += u" <td " + self._asColumnAttribs[i] + ">" else: sRow += u" <td>" if isinstance(aoValues[i], WuiHtmlBase): sRow += aoValues[i].toHtml() elif isinstance(aoValues[i], list): if len(aoValues[i]) > 0: for oElement in aoValues[i]: if isinstance(oElement, WuiHtmlBase): sRow += oElement.toHtml() elif db.isDbTimestamp(oElement): sRow += webutils.escapeElem(self.formatTsShort(oElement)) else: sRow += webutils.escapeElem(unicode(oElement)) sRow += " " elif db.isDbTimestamp(aoValues[i]): sRow += webutils.escapeElem(self.formatTsShort(aoValues[i])) elif aoValues[i] is not None: sRow += webutils.escapeElem(unicode(aoValues[i])) sRow += u"</td>\n" return sRow + u" </tr>\n"
def addSubmit(self, sLabel = 'Submit'): """Adds the submit button to the form.""" if self._fReadOnly: return True; return self._add(' <li>\n' ' <br>\n' ' <div class="tmform-field"><div class="tmform-field-submit">\n' ' <label> </label>\n' ' <input type="submit" value="%s">\n' ' </div></div>\n' ' </li>\n' % (escapeElem(sLabel),));
def _addList(self, sName, aoRows, sLabel, fUseTable = False, sId = 'dummy', sExtraAttribs = ''): """ Adds a list of items to check. @param sName Name of HTML form element @param aoRows List of [sValue, fChecked, sName] sub-arrays. @param sLabel Label of HTML form element """ fReadOnly = self._fReadOnly; ## @todo add this as a parameter. if fReadOnly: sExtraAttribs += ' readonly onclick="return false" onkeydown="return false"'; self._addLabel(sName, sLabel, 'list'); if len(aoRows) == 0: return self._add('No items</div></div></li>') sNameEscaped = escapeAttr(sName); self._add(' <div class="tmform-checkboxes-container" id="%s">\n' % (escapeAttr(sId),)); if fUseTable: self._add(' <table>\n'); for asRow in aoRows: assert len(asRow) == 3; # Don't allow sloppy input data! fChecked = self._reinterpretBool(asRow[1]) self._add(' <tr>\n' ' <td><input type="checkbox" name="%s" value="%s"%s%s></td>\n' ' <td>%s</td>\n' ' </tr>\n' % ( sNameEscaped, escapeAttr(str(asRow[0])), ' checked' if fChecked else '', sExtraAttribs, escapeElem(str(asRow[2])), )); self._add(' </table>\n'); else: for asRow in aoRows: assert len(asRow) == 3; # Don't allow sloppy input data! fChecked = self._reinterpretBool(asRow[1]) self._add(' <div class="tmform-checkbox-holder">' '<input type="checkbox" name="%s" value="%s"%s%s> %s</input></div>\n' % ( sNameEscaped, escapeAttr(str(asRow[0])), ' checked' if fChecked else '', sExtraAttribs, escapeElem(str(asRow[2])),)); return self._add(' </div></div></div>\n' ' </li>\n');