Exemplo n.º 1
0
    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;
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
    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>'),));
Exemplo n.º 4
0
    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 _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  = '&nbsp;&#x25b4;' if iSorting == 1  else '<small>&nbsp;&#x25b5;</small>';
                    sSortParams = ','.join([str(-i) for i in self._aaiColumnSorting[iHeader]]);
                else:
                    sDirection = '';
                    if iSorting < 0:
                        sDirection  = '&nbsp;&#x25be;' if iSorting == -1 else '<small>&nbsp;&#x25bf;</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
Exemplo n.º 6
0
    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>'),));
Exemplo n.º 7
0
    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  = '&nbsp;&#x25b4;' if iSorting == 1  else '<small>&nbsp;&#x25b5;</small>';
                    sSortParams = ','.join([str(-i) for i in self._aaiColumnSorting[iHeader]]);
                else:
                    sDirection = '';
                    if iSorting < 0:
                        sDirection  = '&nbsp;&#x25be;' if iSorting == -1 else '<small>&nbsp;&#x25bf;</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
Exemplo n.º 8
0
    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;
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
 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
Exemplo n.º 11
0
 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))
Exemplo n.º 12
0
 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
Exemplo n.º 15
0
 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;
Exemplo n.º 16
0
 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;
Exemplo n.º 17
0
    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)
Exemplo n.º 18
0
    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)
Exemplo n.º 19
0
    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 _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);
Exemplo n.º 21
0
 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),
             ))
Exemplo n.º 22
0
    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)
Exemplo n.º 23
0
    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'
Exemplo n.º 24
0
 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)) );
Exemplo n.º 25
0
 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;
Exemplo n.º 28
0
    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 _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,
        ];
Exemplo n.º 31
0
    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
Exemplo n.º 32
0
    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
Exemplo n.º 33
0
 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)) ));
Exemplo n.º 34
0
    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()),];
Exemplo n.º 35
0
    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
Exemplo n.º 36
0
    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;
Exemplo n.º 37
0
 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)) );
Exemplo n.º 38
0
    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 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;
Exemplo n.º 40
0
    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 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);
Exemplo n.º 42
0
    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, '&nbsp;'),);

        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, '&nbsp;'),
                       utils.formatNumber(aEntry[2], '&nbsp;'),
                       utils.formatNumber(aEntry[3], '&nbsp;'),
                       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;
Exemplo n.º 43
0
 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 ));
Exemplo n.º 44
0
    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, '&nbsp;'),)

        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, '&nbsp;'),
                       utils.formatNumber(aEntry[2], '&nbsp;'),
                       utils.formatNumber(aEntry[3], '&nbsp;'),
                       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
Exemplo n.º 45
0
 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 ));
Exemplo n.º 46
0
 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)))
Exemplo n.º 47
0
 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),));
Exemplo n.º 48
0
 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)))
Exemplo n.º 49
0
 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)
     )
Exemplo n.º 51
0
 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
Exemplo n.º 52
0
    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';
Exemplo n.º 53
0
 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
Exemplo n.º 54
0
 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))
     )
Exemplo n.º 56
0
    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"
Exemplo n.º 58
0
 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>&nbsp;</label>\n'
                      '           <input type="submit" value="%s">\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % (escapeElem(sLabel),));
Exemplo n.º 59
0
 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>&nbsp;</label>\n'
                      '           <input type="submit" value="%s">\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % (escapeElem(sLabel),));
Exemplo n.º 60
0
    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');