VirtualBox

Ignore:
Timestamp:
Dec 31, 2016 2:29:50 AM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
112535
Message:

testmanager: More details in the system wide changelog.

Location:
trunk/src/VBox/ValidationKit/testmanager/webui
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuiadmin.py

    r65039 r65040  
    167167        # System Log actions.
    168168        #
     169        self._dDispatch[self.ksActionSystemChangelogList]       = self._actionSystemChangelogList;
    169170        self._dDispatch[self.ksActionSystemLogList]             = self._actionSystemLogList;
    170         self._dDispatch[self.ksActionSystemChangelogList]       = self._actionSystemChangelogList;
    171171
    172172        #
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuiadminsystemchangelog.py

    r65039 r65040  
    3030
    3131
     32from common import webutils;
     33
    3234# Validation Kit imports.
    33 from testmanager.webui.wuicontentbase   import WuiListContentBase #, WuiTmLink;
    34 #from testmanager.core.testbox           import TestBoxData;
    35 #from testmanager.core.systemchangelog   import SystemChangelogLogic;
    36 #from testmanager.core.useraccount       import UserAccountData;
     35from testmanager.webui.wuicontentbase   import WuiListContentBase, WuiHtmlKeeper, WuiAdminLink, \
     36                                               WuiMainLink, WuiElementText, WuiHtmlBase;
     37
     38from testmanager.core.base              import AttributeChangeEntryPre;
     39from testmanager.core.buildblacklist    import BuildBlacklistLogic, BuildBlacklistData;
     40from testmanager.core.build             import BuildLogic, BuildData;
     41from testmanager.core.buildsource       import BuildSourceLogic, BuildSourceData;
     42from testmanager.core.globalresource    import GlobalResourceLogic, GlobalResourceData;
     43from testmanager.core.failurecategory   import FailureCategoryLogic, FailureCategoryData;
     44from testmanager.core.failurereason     import FailureReasonLogic, FailureReasonData;
     45from testmanager.core.systemlog         import SystemLogData;
     46from testmanager.core.systemchangelog   import SystemChangelogLogic;
     47from testmanager.core.schedgroup        import SchedGroupLogic, SchedGroupData;
     48from testmanager.core.testbox           import TestBoxLogic, TestBoxData;
     49from testmanager.core.testcase          import TestCaseLogic, TestCaseData;
     50from testmanager.core.testgroup         import TestGroupLogic, TestGroupData;
     51from testmanager.core.testset           import TestSetData;
     52from testmanager.core.useraccount       import UserAccountLogic, UserAccountData;
    3753
    3854
     
    4561        WuiListContentBase.__init__(self, aoEntries, iPage, cItemsPerPage, tsEffective, 'System Changelog',
    4662                                    fnDPrint = fnDPrint, oDisp = oDisp);
    47         self._asColumnHeaders = ['Date', 'Author', 'What', 'Description'];
    48         self._asColumnAttribs = ['', '', '', ''];
     63        self._asColumnHeaders = [ 'When', 'User', 'Event', 'Details' ];
     64        self._asColumnAttribs = [ 'align="center"', 'align="center"', '', '' ];
     65        self._oBuildBlacklistLogic  = BuildBlacklistLogic(oDisp.getDb());
     66        self._oBuildLogic           = BuildLogic(oDisp.getDb());
     67        self._oBuildSourceLogic     = BuildSourceLogic(oDisp.getDb());
     68        self._oFailureCategoryLogic = FailureCategoryLogic(oDisp.getDb());
     69        self._oFailureReasonLogic   = FailureReasonLogic(oDisp.getDb());
     70        self._oGlobalResourceLogic  = GlobalResourceLogic(oDisp.getDb());
     71        self._oSchedGroupLogic      = SchedGroupLogic(oDisp.getDb());
     72        self._oTestBoxLogic         = TestBoxLogic(oDisp.getDb());
     73        self._oTestCaseLogic        = TestCaseLogic(oDisp.getDb());
     74        self._oTestGroupLogic       = TestGroupLogic(oDisp.getDb());
     75        self._oUserAccountLogic     = UserAccountLogic(oDisp.getDb());
     76        self._sPrevDate             = '';
    4977        _ = cDaysBack;
    5078
    51     def _formatListEntry(self, iEntry):
    52         from testmanager.webui.wuiadmin import WuiAdmin;
    53         oEntry  = self._aoEntries[iEntry];
    54 
    55         return [
    56             oEntry.tsEffective,
    57             oEntry.oAuthor.sUsername if oEntry.oAuthor is not None else '',
    58             '%s(%s)' % (oEntry.sWhat, oEntry.idWhat,),
    59             oEntry.sDesc,
    60         ];
    61 
    62 
     79    #   oDetails = self._createBlacklistingDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     80    def _createBlacklistingDetailsLink(self, idBlacklisting, tsEffective):
     81        """ Creates a link to the build source details. """
     82        oBlacklisting = self._oBuildBlacklistLogic.cachedLookup(idBlacklisting);
     83        if oBlacklisting is not None:
     84            from testmanager.webui.wuiadmin import WuiAdmin;
     85            return WuiAdminLink('Blacklisting #%u' % (oBlacklisting.idBlacklisting,),
     86                                WuiAdmin.ksActionBuildBlacklistDetails, tsEffective,
     87                                { BuildBlacklistData.ksParam_idBlacklisting: oBlacklisting.idBlacklisting },
     88                                fBracketed = False);
     89        return WuiElementText('[blacklisting #%u not found]' % (idBlacklisting,));
     90
     91    def _createBuildDetailsLink(self, idBuild, tsEffective):
     92        """ Creates a link to the build details. """
     93        oBuild = self._oBuildLogic.cachedLookup(idBuild);
     94        if oBuild is not None:
     95            from testmanager.webui.wuiadmin import WuiAdmin;
     96            return WuiAdminLink('%s %sr%u' % ( oBuild.oCat.sProduct, oBuild.sVersion, oBuild.iRevision),
     97                                WuiAdmin.ksActionBuildDetails, tsEffective,
     98                                { BuildData.ksParam_idBuild: oBuild.idBuild },
     99                                fBracketed = False,
     100                                sTitle = 'build #%u for %s, type %s'
     101                                       % (oBuild.idBuild, ' & '.join(oBuild.oCat.asOsArches), oBuild.oCat.sType));
     102        return WuiElementText('[build #%u not found]' % (idBuild,));
     103
     104    def _createBuildSourceDetailsLink(self, idBuildSrc, tsEffective):
     105        """ Creates a link to the build source details. """
     106        oBuildSource = self._oBuildSourceLogic.cachedLookup(idBuildSrc);
     107        if oBuildSource is not None:
     108            from testmanager.webui.wuiadmin import WuiAdmin;
     109            return WuiAdminLink(oBuildSource.sName, WuiAdmin.ksActionBuildSrcDetails, tsEffective,
     110                                { BuildSourceData.ksParam_idBuildSrc: oBuildSource.idBuildSrc },
     111                                fBracketed = False,
     112                                sTitle = 'Build source #%u' % (oBuildSource.idBuildSrc,));
     113        return WuiElementText('[build source #%u not found]' % (idBuildSrc,));
     114
     115    def _createFailureCategoryDetailsLink(self, idFailureCategory, tsEffective):
     116        """ Creates a link to the failure category details. """
     117        oFailureCategory = self._oFailureCategoryLogic.cachedLookup(idFailureCategory);
     118        if oFailureCategory is not None:
     119            from testmanager.webui.wuiadmin import WuiAdmin;
     120            return WuiAdminLink(oFailureCategory.sShort, WuiAdmin.ksActionFailureCategoryDetails, tsEffective,
     121                                { FailureCategoryData.ksParam_idFailureCategory: oFailureCategory.idFailureCategory },
     122                                fBracketed = False,
     123                                sTitle = 'Failure category #%u' % (oFailureCategory.idFailureCategory,));
     124        return WuiElementText('[failure category #%u not found]' % (idFailureCategory,));
     125
     126    def _createFailureReasonDetailsLink(self, idFailureReason, tsEffective):
     127        """ Creates a link to the failure reason details. """
     128        oFailureReason = self._oFailureReasonLogic.cachedLookup(idFailureReason);
     129        if oFailureReason is not None:
     130            from testmanager.webui.wuiadmin import WuiAdmin;
     131            return WuiAdminLink(oFailureReason.sShort, WuiAdmin.ksActionFailureReasonDetails, tsEffective,
     132                                { FailureReasonData.ksParam_idFailureReason: oFailureReason.idFailureReason },
     133                                fBracketed = False,
     134                                sTitle = 'Failure reason #%u, category %s'
     135                                       % (oFailureReason.idFailureReason, oFailureReason.oCategory.sShort));
     136        return WuiElementText('[failure reason #%u not found]' % (idFailureReason,));
     137
     138    def _createGlobalResourceDetailsLink(self, idGlobalRsrc, tsEffective):
     139        """ Creates a link to the global resource details. """
     140        oGlobalResource = self._oGlobalResourceLogic.cachedLookup(idGlobalRsrc);
     141        if oGlobalResource is not None:
     142            from testmanager.webui.wuiadmin import WuiAdmin;
     143            return WuiAdminLink(oGlobalResource.sName, '@todo', tsEffective,
     144                                { GlobalResourceData.ksParam_idGlobalRsrc: oGlobalResource.idGlobalRsrc },
     145                                fBracketed = False,
     146                                sTitle = 'Global resource #%u' % (oGlobalResource.idGlobalRsrc,));
     147        return WuiElementText('[global resource #%u not found]' % (idGlobalRsrc,));
     148
     149    def _createSchedGroupDetailsLink(self, idSchedGroup, tsEffective):
     150        """ Creates a link to the scheduling group details. """
     151        oSchedGroup = self._oSchedGroupLogic.cachedLookup(idSchedGroup);
     152        if oSchedGroup is not None:
     153            from testmanager.webui.wuiadmin import WuiAdmin;
     154            return WuiAdminLink(oSchedGroup.sName, WuiAdmin.ksActionSchedGroupDetails, tsEffective,
     155                                { SchedGroupData.ksParam_idSchedGroup: oSchedGroup.idSchedGroup },
     156                                fBracketed = False,
     157                                sTitle = 'Scheduling group #%u' % (oSchedGroup.idSchedGroup,));
     158        return WuiElementText('[scheduling group #%u not found]' % (idSchedGroup,));
     159
     160    def _createTestBoxDetailsLink(self, idTestBox, tsEffective):
     161        """ Creates a link to the testbox details. """
     162        oTestBox = self._oTestBoxLogic.cachedLookup(idTestBox);
     163        if oTestBox is not None:
     164            from testmanager.webui.wuiadmin import WuiAdmin;
     165            return WuiAdminLink(oTestBox.sName, WuiAdmin.ksActionTestBoxDetails, tsEffective,
     166                                { TestBoxData.ksParam_idTestBox: oTestBox.idTestBox },
     167                                fBracketed = False, sTitle = 'Testbox #%u' % (oTestBox.idTestBox,));
     168        return WuiElementText('[testbox #%u not found]' % (idTestBox,));
     169
     170    def _createTestCaseDetailsLink(self, idTestCase, tsEffective):
     171        """ Creates a link to the test case details. """
     172        oTestCase = self._oTestCaseLogic.cachedLookup(idTestCase);
     173        if oTestCase is not None:
     174            from testmanager.webui.wuiadmin import WuiAdmin;
     175            return WuiAdminLink(oTestCase.sName, WuiAdmin.ksActionTestCaseDetails, tsEffective,
     176                                { TestCaseData.ksParam_idTestCase: oTestCase.idTestCase },
     177                                fBracketed = False, sTitle = 'Test case #%u' % (oTestCase.idTestCase,));
     178        return WuiElementText('[test case #%u not found]' % (idTestCase,));
     179
     180    def _createTestGroupDetailsLink(self, idTestGroup, tsEffective):
     181        """ Creates a link to the test group details. """
     182        oTestGroup = self._oTestGroupLogic.cachedLookup(idTestGroup);
     183        if oTestGroup is not None:
     184            from testmanager.webui.wuiadmin import WuiAdmin;
     185            return WuiAdminLink(oTestGroup.sName, WuiAdmin.ksActionTestGroupDetails, tsEffective,
     186                                { TestGroupData.ksParam_idTestGroup: oTestGroup.idTestGroup },
     187                                fBracketed = False, sTitle = 'Test group #%u' % (oTestGroup.idTestGroup,));
     188        return WuiElementText('[test group #%u not found]' % (idTestGroup,));
     189
     190    def _createTestSetResultsDetailsLink(self, idTestSet, tsEffective):
     191        """ Creates a link to the test set results. """
     192        _ = tsEffective;
     193        from testmanager.webui.wuimain import WuiMain;
     194        return WuiMainLink('test set #%u' % idTestSet, WuiMain.ksActionTestSetDetails,
     195                           { TestSetData.ksParam_idTestSet: idTestSet }, fBracketed = False);
     196
     197    def _createTestSetDetailsLinkByResult(self, idTestResult, tsEffective):
     198        """ Creates a link to the test set results. """
     199        _ = tsEffective;
     200        from testmanager.webui.wuimain import WuiMain;
     201        return WuiMainLink('test result #%u' % idTestResult, WuiMain.ksActionTestSetDetailsFromResult,
     202                           { TestSetData.ksParam_idTestResult: idTestResult }, fBracketed = False);
     203
     204    def _createUserAccountDetailsLink(self, uid, tsEffective):
     205        """ Creates a link to the user account details. """
     206        oUser = self._oUserAccountLogic.cachedLookup(uid);
     207        if oUser is not None:
     208            from testmanager.webui.wuiadmin import WuiAdmin;
     209            return WuiAdminLink(oUser.sUsername, '@todo', tsEffective, { UserAccountData.ksParam_uid: oUser.uid },
     210                                fBracketed = False, sTitle = '%s (#%u)' % (oUser.sFullName, oUser.uid));
     211        return WuiElementText('[user #%u not found]' % (uid,));
     212
     213    def _formatDescGeneric(self, sDesc, oEntry):
     214        """
     215        Generically format system log the description.
     216        """
     217        oRet = WuiHtmlKeeper();
     218        asWords = sDesc.split();
     219        for sWord in asWords:
     220            offEqual = sWord.find('=');
     221            if offEqual > 0:
     222                sKey = sWord[:offEqual];
     223                try:    idValue = int(sWord[offEqual+1:].rstrip('.,'));
     224                except: pass;
     225                else:
     226                    if sKey == 'idTestSet':
     227                        oRet.append(self._createTestSetResultsDetailsLink(idValue, oEntry.tsEffective));
     228                        continue;
     229                    if sKey == 'idTestBox':
     230                        oRet.append(self._createTestBoxDetailsLink(idValue, oEntry.tsEffective));
     231                        continue;
     232                    if sKey == 'idSchedGroup':
     233                        oRet.append(self._createSchedGroupDetailsLink(idValue, oEntry.tsEffective));
     234                        continue;
     235
     236            oRet.append(WuiElementText(sWord));
     237        return oRet;
     238
     239    def _formatListEntryHtml(self, iEntry):
     240        """
     241        Overridden parent method.
     242        """
     243        oEntry = self._aoEntries[iEntry];
     244
     245        #
     246        # Format the timestamp.
     247        #
     248        sDate = self.formatTsShort(oEntry.tsEffective);
     249        if sDate[:10] == self._sPrevDate:
     250            sDate = sDate[11:]
     251        else:
     252            self._sPrevDate = sDate[:10];
     253            sDate = '<b>' + sDate[:10] + '</b><br>' + sDate[11:];
     254
     255        #
     256        # System log events.
     257        # pylint: disable=redefined-variable-type
     258        #
     259        aoChanges = None;
     260        if   oEntry.sEvent == SystemLogData.ksEvent_CmdNacked:
     261            sEvent = 'Command not acknowleged';
     262            oDetails = oEntry.sDesc;
     263
     264        elif oEntry.sEvent == SystemLogData.ksEvent_TestBoxUnknown:
     265            sEvent = 'Unknown testbox';
     266            oDetails = oEntry.sDesc;
     267
     268        elif oEntry.sEvent == SystemLogData.ksEvent_TestSetAbandoned:
     269            sEvent = 'Abandoned test set';
     270            oDetails = self._formatDescGeneric(oEntry.sDesc, oEntry);
     271
     272        elif oEntry.sEvent == SystemLogData.ksEvent_UserAccountUnknown:
     273            sEvent = 'Unknown user account';
     274            oDetails = oEntry.sDesc;
     275
     276        elif oEntry.sEvent == SystemLogData.ksEvent_XmlResultMalformed:
     277            sEvent = 'Malformed XML result';
     278            oDetails = oEntry.sDesc;
     279
     280        elif oEntry.sEvent == SystemLogData.ksEvent_SchedQueueRecreate:
     281            sEvent = 'Recreating scheduling queue';
     282            asWords = oEntry.sDesc.split();
     283            if len(asWords) > 3 and asWords[0] == 'User' and asWords[1][0] == '#':
     284                try:    idAuthor = int(asWords[1][1:]);
     285                except: pass;
     286                else:
     287                    oEntry.oAuthor = self._oUserAccountLogic.cachedLookup(idAuthor);
     288                    if oEntry.oAuthor is not None:
     289                        i = 2;
     290                        if asWords[i] == 'recreated':   i += 1;
     291                        oEntry.sDesc = ' '.join(asWords[i:]);
     292            oDetails = self._formatDescGeneric(oEntry.sDesc.replace('sched queue #', 'for scheduling group idSchedGroup='),
     293                                               oEntry);
     294        #
     295        # System changelog events.
     296        #
     297        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_Blacklisting:
     298            sEvent = 'Modified blacklisting';
     299            oDetails = self._createBlacklistingDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     300
     301        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_Build:
     302            sEvent = 'Modified build';
     303            oDetails = self._createBuildDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     304
     305        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_BuildSource:
     306            sEvent = 'Modified build source';
     307            oDetails = self._createBuildSourceDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     308
     309        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_GlobalRsrc:
     310            sEvent = 'Modified global resource';
     311            oDetails = self._createGlobalResourceDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     312
     313        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_FailureCategory:
     314            sEvent = 'Modified failure category';
     315            oDetails = self._createFailureCategoryDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     316            (aoChanges, _) = self._oFailureCategoryLogic.fetchForChangeLog(oEntry.idWhat, 0, 1, oEntry.tsEffective);
     317
     318        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_FailureReason:
     319            sEvent = 'Modified failure reason';
     320            oDetails = self._createFailureReasonDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     321            (aoChanges, _) = self._oFailureReasonLogic.fetchForChangeLog(oEntry.idWhat, 0, 1, oEntry.tsEffective);
     322
     323        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_SchedGroup:
     324            sEvent = 'Modified scheduling group';
     325            oDetails = self._createSchedGroupDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     326
     327        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_TestBox:
     328            sEvent = 'Modified testbox';
     329            oDetails = self._createTestBoxDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     330            (aoChanges, _) = self._oTestBoxLogic.fetchForChangeLog(oEntry.idWhat, 0, 1, oEntry.tsEffective);
     331
     332        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_TestCase:
     333            sEvent = 'Modified test case';
     334            oDetails = self._createTestCaseDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     335            (aoChanges, _) = self._oTestCaseLogic.fetchForChangeLog(oEntry.idWhat, 0, 1, oEntry.tsEffective);
     336
     337        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_TestGroup:
     338            sEvent = 'Modified test group';
     339            oDetails = self._createTestGroupDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     340
     341        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_TestResult:
     342            sEvent = 'Modified test failure reason';
     343            oDetails = self._createTestSetDetailsLinkByResult(oEntry.idWhat, oEntry.tsEffective);
     344
     345        elif oEntry.sEvent == SystemChangelogLogic.ksWhat_User:
     346            sEvent = 'Modified user account';
     347            oDetails = self._createUserAccountDetailsLink(oEntry.idWhat, oEntry.tsEffective);
     348
     349        else:
     350            sEvent   = '%s(%s)' % (oEntry.sEvent, oEntry.idWhat,);
     351            oDetails = '!Unknown event!' + (oEntry.sDesc if oEntry.sDesc else '');
     352
     353        #
     354        # Do the formatting.
     355        #
     356        sRowClass = 'tmodd' if (iEntry + 1) & 1 else 'tmeven';
     357
     358        if aoChanges is not None and len(aoChanges) > 0:
     359            oChangeEntry    = aoChanges[0];
     360            cAttribsChanged = len(oChangeEntry.aoChanges) + 1;
     361        else:
     362            oChangeEntry    = None;
     363            cAttribsChanged = 1;
     364
     365        sHtml = u'  <tr class="%s">\n' \
     366                u'    <td rowspan="%d">%s</td>\n' \
     367                u'    <td rowspan="%d">%s</td>\n' \
     368                u'    <td rowspan="%d">%s</td>\n' \
     369                u'    <td colspan="3">%s</td>\n' \
     370                u'  </tr>\n' \
     371              % ( sRowClass,
     372                 cAttribsChanged, sDate,
     373                 cAttribsChanged, webutils.escapeElem(oEntry.oAuthor.sUsername if oEntry.oAuthor is not None else ''),
     374                 cAttribsChanged, webutils.escapeElem(sEvent),
     375                 oDetails.toHtml() if isinstance(oDetails, WuiHtmlBase) else oDetails,
     376                 );
     377
     378        if oChangeEntry is not None:
     379            for j, oChange in enumerate(oChangeEntry.aoChanges):
     380                if isinstance(oChange, AttributeChangeEntryPre):
     381                    sHtml += '        <tr class="%s%s tmsyschlogattr"><td>%s</td>'\
     382                             '<td><div class="tdpre"><pre>%s</pre></div></td>' \
     383                             '<td><div class="tdpre"><pre>%s</pre></div></td></tr>\n' \
     384                           % ( sRowClass, 'odd' if j & 1 else 'even',
     385                               webutils.escapeElem(oChange.sAttr),
     386                               webutils.escapeElem(oChange.sOldText),
     387                               webutils.escapeElem(oChange.sNewText), );
     388                else:
     389                    sHtml += '        <tr class="%s%s tmsyschlogattr"><td>%s</td><td>%s</td><td>%s</td></tr>\n' \
     390                           % ( sRowClass, 'odd' if j & 1 else 'even',
     391                               webutils.escapeElem(oChange.sAttr),
     392                               webutils.escapeElem(oChange.sOldText),
     393                               webutils.escapeElem(oChange.sNewText), );
     394        sHtml += u'  </tr>\n'
     395        return sHtml;
     396
     397
     398    def _generateTableHeaders(self):
     399        """
     400        Overridden parent method.
     401        """
     402
     403        sHtml = u'<thead class="tmheader">\n' \
     404                u' <tr>\n' \
     405                u'  <th rowspan="2">When</th>\n' \
     406                u'  <th rowspan="2">Who</th>\n' \
     407                u'  <th rowspan="2">Event</th>\n' \
     408                u'  <th colspan="3">Details</th>\n' \
     409                u' </tr>\n' \
     410                u' <tr>\n' \
     411                u'  <th>Attribute</th>\n' \
     412                u'  <th>Old Value</th>\n' \
     413                u'  <th>New Value</th>\n' \
     414                u' </tr>\n' \
     415                u'</thead>\n';
     416        return sHtml;
     417
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuicontentbase.py

    r65039 r65040  
    111111        return sFmt % (sExtraAttrs, webutils.escapeAttr(self.sUrl), webutils.escapeElem(self.sName));
    112112
     113
    113114class WuiTmLink(WuiLinkBase): # pylint: disable=R0903
    114115    """ Local link to the test manager. """
     
    132133
    133134
     135class WuiAdminLink(WuiTmLink): # pylint: disable=R0903
     136    """ Local link to the test manager's admin portion. """
     137
     138    def __init__(self, sName, sAction, tsEffectiveDate = None, dParams = None, sConfirm = None, sTitle = None,
     139                 sFragmentId = None, fBracketed = True):
     140        from testmanager.webui.wuiadmin import WuiAdmin;
     141        if dParams is None or len(dParams) == 0:
     142            dParams = dict();
     143        else:
     144            dParams = dict(dParams);
     145        if sAction is not None:
     146            dParams[WuiAdmin.ksParamAction] = sAction;
     147        if tsEffectiveDate is not None:
     148            dParams[WuiAdmin.ksParamEffectiveDate] = tsEffectiveDate;
     149        WuiTmLink.__init__(self, sName, WuiAdmin.ksScriptName, dParams = dParams, sConfirm = sConfirm, sTitle = sTitle,
     150                           sFragmentId = sFragmentId, fBracketed = fBracketed);
     151
     152class WuiMainLink(WuiTmLink): # pylint: disable=R0903
     153    """ Local link to the test manager's main portion. """
     154
     155    def __init__(self, sName, sAction, dParams = None, sConfirm = None, sTitle = None,
     156                 sFragmentId = None, fBracketed = True):
     157        from testmanager.webui.wuimain import WuiMain;
     158        if dParams is None or len(dParams) == 0:
     159            dParams = dict();
     160        else:
     161            dParams = dict(dParams);
     162        if sAction is not None:
     163            dParams[WuiMain.ksParamAction] = sAction;
     164        WuiTmLink.__init__(self, sName, WuiMain.ksScriptName, dParams = dParams, sConfirm = sConfirm, sTitle = sTitle,
     165                           sFragmentId = sFragmentId, fBracketed = fBracketed);
     166
    134167class WuiSvnLink(WuiLinkBase): # pylint: disable=R0903
    135168    """
     
    214247                                % ( webutils.escapeAttr(sSpanClass), webutils.escapeAttr(sTitle), webutils.escapeElem(sText),));
    215248
     249class WuiElementText(WuiRawHtml): # pylint: disable=R0903
     250    """
     251    Outputs the given element text.
     252    """
     253    def __init__(self, sText):
     254        WuiRawHtml.__init__(self, webutils.escapeElem(sText));
    216255
    217256
     
    254293            self._fnDPrint(sText);
    255294
    256     def formatTsShort(self, oTs):
     295    @staticmethod
     296    def formatTsShort(oTs):
    257297        """
    258298        Formats a timestamp (db rep) into a short form.
     
    399439        return [];
    400440
    401     def _calcChangeLogEntryLinks(self, aoEntries, iEntry):
     441    @staticmethod
     442    def _calcChangeLogEntryLinks(aoEntries, iEntry):
    402443        """
    403444        Returns an array of links to go with the change log entry.
     
    410451        return [];
    411452
    412     def _guessChangeLogEntryDescription(self, aoEntries, iEntry):
     453    @staticmethod
     454    def _guessChangeLogEntryDescription(aoEntries, iEntry):
    413455        """
    414456        Guesses the action + author that caused the change log entry.
     
    435477        return 'Modified by %s.' % (sAuthor,);
    436478
    437     def _formatChangeLogEntry(self, aoEntries, iEntry):
     479    @staticmethod
     480    def formatChangeLogEntry(aoEntries, iEntry):
    438481        """
    439482        Formats one change log entry into one or more HTML table rows.
     
    453496                   '    </tr>\n' \
    454497                 % ( sRowClass,
    455                      len(oEntry.aoChanges) + 1, webutils.escapeElem(self.formatTsShort(oEntry.tsEffective)),
    456                      len(oEntry.aoChanges) + 1, webutils.escapeElem(self.formatTsShort(oEntry.tsExpire)),
    457                      self._guessChangeLogEntryDescription(aoEntries, iEntry),
    458                      ' '.join(oLink.toHtml() for oLink in self._calcChangeLogEntryLinks(aoEntries, iEntry)),);
     498                     len(oEntry.aoChanges) + 1, webutils.escapeElem(WuiFormContentBase.formatTsShort(oEntry.tsEffective)),
     499                     len(oEntry.aoChanges) + 1, webutils.escapeElem(WuiFormContentBase.formatTsShort(oEntry.tsExpire)),
     500                     WuiFormContentBase._guessChangeLogEntryDescription(aoEntries, iEntry),
     501                     ' '.join(oLink.toHtml() for oLink in WuiFormContentBase._calcChangeLogEntryLinks(aoEntries, iEntry)),);
    459502
    460503        # Additional rows for each changed attribute.
     
    574617                    '    <tbody>\n';
    575618
    576         for iEntry in range(len(aoEntries)):
    577             sContent += self._formatChangeLogEntry(aoEntries, iEntry);
     619        for iEntry, _ in enumerate(aoEntries):
     620            sContent += self.formatChangeLogEntry(aoEntries, iEntry);
    578621
    579622        sContent += '    <tbody>\n' \
     
    894937        return sNavigation;
    895938
     939    def _generateTableHeaders(self):
     940        """
     941        Generate table headers.
     942        Returns raw html string.
     943        Overridable.
     944        """
     945
     946        sHtml  = '  <thead class="tmheader"><tr>';
     947        for oHeader in self._asColumnHeaders:
     948            if isinstance(oHeader, WuiHtmlBase):
     949                sHtml += '<th>' + oHeader.toHtml() + '</th>';
     950            else:
     951                sHtml += '<th>' + webutils.escapeElem(oHeader) + '</th>';
     952        sHtml += '</tr><thead>\n';
     953        return sHtml
     954
    896955    def _generateTable(self):
    897956        """
     
    910969            self._asColumnHeaders = self._aoEntries[0].getDataAttributes();
    911970
    912         sPageBody += '  <thead class="tmheader"><tr>';
    913         for oHeader in self._asColumnHeaders:
    914             if isinstance(oHeader, WuiHtmlBase):
    915                 sPageBody += '<th>' + oHeader.toHtml() + '</th>';
    916             else:
    917                 sPageBody += '<th>' + webutils.escapeElem(oHeader) + '</th>';
    918         sPageBody += '</tr><thead>\n';
     971        sPageBody += self._generateTableHeaders();
    919972
    920973        #
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette