diff options
author | Matěj Cepl <mcepl@redhat.com> | 2009-11-15 23:40:43 +0100 |
---|---|---|
committer | Matěj Cepl <mcepl@redhat.com> | 2009-11-15 23:40:43 +0100 |
commit | ceea1e8adb15846bafee330ff92f6d8361c6f22f (patch) | |
tree | 592cea23707f29ab7190869e5974fd7265c5b930 /bugzillaBugTriage.js | |
parent | b6738cd9139240534d4d3f95d08a47d3dfdc75fe (diff) | |
download | bugzilla-triage-ceea1e8adb15846bafee330ff92f6d8361c6f22f.tar.gz |
Another step to jetpackization.
* bugzillaBugTriage.js -- huge step towards attachments management and
generating buttons.
* skip-process-bug.js -- comment out unnecessary console.log
Diffstat (limited to 'bugzillaBugTriage.js')
-rw-r--r-- | bugzillaBugTriage.js | 496 |
1 files changed, 411 insertions, 85 deletions
diff --git a/bugzillaBugTriage.js b/bugzillaBugTriage.js index bfe1419..38274c9 100644 --- a/bugzillaBugTriage.js +++ b/bugzillaBugTriage.js @@ -26,119 +26,144 @@ var PCIIDsURL = "http://mcepl.fedorapeople.org/scripts/drm_pciids.json"; var reqCounter = 0; var msgStrs = {}; -var CommentRe = RegExp("^\\s*#"); -var BlankLineRe = RegExp("^\\s*$"); -var ChipsetRE = RegExp("^\\(--\\) ([A-Za-z]+)\\([0-9]?\\): Chipset: (.*)$"); -var ATIgetIDRE = RegExp("^.*\\(ChipID = 0x([0-9a-fA-F]+)\\).*$"); +var CommentRe = new RegExp("^\\s*#"); +var BlankLineRe = new RegExp("^\\s*$"); +var ChipsetRE = new RegExp("^\\(--\\) ([A-Za-z]+)\\([0-9]?\\): Chipset: (.*)$"); +var ATIgetIDRE = new RegExp("^.*\\(ChipID = 0x([0-9a-fA-F]+)\\).*$"); // For identification of graphics card var manuChipStrs = [ - ["ATI Radeon","ATI","1002"], - ["ATI Mobility Radeon","ATI","1002"], - ["Intel Corporation","INTEL","8086"], - ["NVIDIA","NV","10de"] + ["ATI Radeon", "ATI", "1002"], + ["ATI Mobility Radeon", "ATI", "1002"], + ["Intel Corporation", "INTEL", "8086"], + ["NVIDIA", "NV", "10de"] ]; var backTranslateManufacturerPCIID = [{ regexp: "ATI Technologies Inc", addr: "1002" - },{ + }, { regexp: "Intel Corporation", addr: "8086" - },{ + }, { regexp: "nVidia Corporation", addr: "10de" }]; // Initialize data from remote URL var XMLHTTPRequestDone = false; -var hashBugzillaName = Array(); -var hashBugzillaWholeURL = Array(); -var defAssigneeList = Array(); +var hashBugzillaName = []; +var hashBugzillaWholeURL = []; +var defAssigneeList = []; var signatureFedoraString = ""; // TODO we should have an array SpecialFlags instead of multiple Boolean variables var queryButtonAvailable = false; -var chipIDsGroupings = Array(); -var AddrArray = Array(); -var PCI_ID_Array = Array(); -var XorgLogAttList = Array(); +var chipIDsGroupings = []; +var AddrArray = []; +var PCI_ID_Array = []; +var XorgLogAttList = []; var XorgLogAttListIndex = 0; // Get JSON configuration data -var JSONXHR = new XMLHttpRequest(); -JSONXHR.open("GET",jsonDataURL,true); -JSONXHR.onreadystatechange = function(response) { - var data = JSON.parse(response.responseText); - console.log("data = " + data); - msgStrs = data['strings']; - signatureFedoraString = data['signature']; - hashBugzillaName = data['bugzillalabelNames']; - hashBugzillaWholeURL = data['bugzillaIDURLs']; +$.getJSON(jsonDataURL, function (response) { + var data = response; + msgStrs = data.strings; + signatureFedoraString = data.signature; + hashBugzillaName = data.bugzillalabelNames; + hashBugzillaWholeURL = data.bugzillaIDURLs; // [{'regexp to match component':'email address of an universal maintainer'}, ...] - AddrArray = data['CCmaintainer'], - console.log("AddrArray = " + AddrArray); - defAssigneeList = data['defaultAssignee'], - queryButtonAvailable = data['queryButton']; - chipIDsGroupings = data['chipIDsGroupings']; - buildButtons(data['topRow'],data['bottomRow']); -}; -JSONXHR.send(null); + AddrArray = data.CCmaintainer; + defAssigneeList = data.defaultAssignee; + queryButtonAvailable = data.queryButton; + chipIDsGroupings = data.chipIDsGroupings; + // TODO buildButtons(data.topRow,data.bottomRow); +}); // Get card translation table -var PCIXHR = new XMLHttpRequest(); -PCIXHR.open("GET",PCIIDsURL,true); -PCIXHR.onreadystatechange = function(response) { - if (response.readyState == 4) { - if (response.status == 200) - PCI_ID_Array = JSON.parse(response.responseText); - } -}; -PCIXHR.send(null); +$.getJSON(PCIIDsURL, + function (response) { + PCI_ID_Array = response; +}); //============================================================== /** * select element of the array where regexp in the first element matches second parameter - * of this function + * of this function * @param list array with regexps and return values * @param chosingMark string by which the element of array is to be matched * @return string chosen element */ -function filterByRegexp(list,chosingMark) { - var chosenPair = Array(); +function filterByRegexp(list, chosingMark) { + var chosenPair = []; if (list.length > 0) { chosenPair = list.filter( - function(pair){ - return RegExp(pair['regexp'],"i").test(chosingMark); + function (pair) { + return new RegExp(pair.regexp, "i").test(chosingMark); }); - }; + } if (chosenPair.length > 0) { - return $.trim(chosenPair[0]['addr']); + return $.trim(chosenPair[0].addr); } else { return ""; } } +/** + * Converts attributes value of the given list of elements to the + * Javascript list. + * @param list array of elements + * @return array of values + */ +function valuesToList(list) { + var outL = []; + + list.forEach(function (e, i, a) { + if (e.hasAttribute("value")) { + outL.push(e.getAttribute("value").trim()); + } + }); + return outL; +} + +/** + * Check whether an item is member of the list. Idea is just to + * make long if commands slightly more readable. + * + * @param mbr string to be searched in the list + * @param list list + * @return position of the string in the list, or -1 if none found. + */ +function isInList(mbr, list) { + return (list.indexOf(mbr) !== -1); +} + /////////////////////////////////////////////////////////////////////////////// function bzPage(doc) { this.doc = $(doc); + var bugNoTitle = $.trim($("#title > p:first", this.doc).text()); + this.bugNo = new RegExp("[0-9]+").exec(bugNoTitle)[0]; + this.reporter = $("#bz_show_bug_column_2 > table .vcard:first > a", this.doc).attr("title"); - this.product = $("#product option:selected:first",this.doc).text(); - this.component = $("#component option:selected:first",this.doc).text(); - console.log("component = " + this.component); - console.log("AddrArray = " + AddrArray.toSource()); - this.version = $("#version option:selected:first",this.doc).text(); - this.its = $.trim($("#cf_issuetracker",this.doc).text()); + this.product = $("#product option:selected:first", this.doc).text(); + this.component = $("#component option:selected:first", this.doc).text(); + this.version = $("#version option:selected:first", this.doc).text(); + this.its = $.trim($("#cf_issuetracker", this.doc).text()); + this.CCList = $("#cc", this.doc).attr("value"); + this.defaultAssignee = filterByRegexp(defAssigneeList, this.component).toLowerCase(); this.maintCCAddr = filterByRegexp(AddrArray,this.component).toLowerCase(); - console.log("maintCCAddr = " + this.maintCCAddr); + this.attachments = this.getAttachments(); + console.log("attachments = " + this.attachments); + + this.originalButton = $("#commit", this.doc).get(0); // Take care of signature for Fedora bugzappers if (signatureFedoraString.length > 0) { // (or a form named "changeform") - $("form::nth-child(2)",this.doc).submit(function () { - var cmntText = $("#comment",this.doc); + $("form::nth-child(2)", this.doc).submit(function () { + var cmntText = $("#comment", this.doc); if ((signatureFedoraString.length > 0) && ($.trim(cmntText.text()).length > 0)) { - cmntText.text($.trim(cmntText.text()) + signatureFedoraString); + cmntText.text($.trim(cmntText.text()) + signatureFedoraString); } }); } @@ -154,10 +179,10 @@ function bzPage(doc) { * @return Boolean * */ -bzPage.prototype.hasKeyword = function(str) { - var kwd = $.trim($('keywords',this.doc).text()); - return (RegExp(str).test(kwd)); -} +bzPage.prototype.hasKeyword = function (str) { + var kwd = $.trim($('#keywords', this.doc).text()); + return (new RegExp(str).test(kwd)); +}; /* Bugzilla functions.*/ @@ -165,12 +190,12 @@ bzPage.prototype.hasKeyword = function(str) { * Set background color of all comments made by reporter in ReporterColorHex color * */ -bzPage.prototype.checkComments = function() { +bzPage.prototype.checkComments = function () { var reporter = this.reporter; - $("#comments .bz_comment",this.doc).each(function (i) { - var email = $(".vcard a",this).text(); - if (RegExp(reporter).test(email)) { - $(this).css("background-color",ReporterColorHex); + $("#comments .bz_comment", this.doc).each(function (i) { + var email = $(".vcard a", this).text(); + if (new RegExp(reporter).test(email)) { + $(this).css("background-color", ReporterColorHex); } }); }; @@ -187,14 +212,14 @@ bzPage.prototype.checkComments = function() { bzPage.prototype.setBranding = function () { var brandColor = ""; - if (RegExp("Red Hat Enterprise Linux").test(this.product)) { + if (new RegExp("Red Hat Enterprise Linux").test(this.product)) { if (this.its.length > 0) { brandColor = RHITColor; } else { brandColor = RHColor; } - } else if (RegExp("Fedora").test(this.product)) { - if (RegExp("rawhide","i").test(this.version)) { + } else if (new RegExp("Fedora").test(this.product)) { + if (new RegExp("rawhide", "i").test(this.version)) { brandColor = RawhideColor; } else { brandColor = FedoraColor; @@ -202,30 +227,331 @@ bzPage.prototype.setBranding = function () { } // Comment each of the following lines to get only partial branding - $("body",this.doc).css("background",brandColor); - $("#titles",this.doc).css("background",brandColor); + $("body", this.doc).css("background", brandColor); + $("#titles", this.doc).css("background", brandColor); // Make background-color of the body of bug salmon pink // for security bugs. if (this.hasKeyword("Security")) { - $("#bugzilla-body",this.doc).css({ + $("#bugzilla-body", this.doc).css({ 'background-image' : 'none', 'background-color' : SalmonPink }); } -// // we should make visible whether maintCCAddr is in CCList -// if (isInList(maintCCAddr, CCList)) { -// var switchCCEdit=document.getElementById("cc_edit_area_showhide"); -// //switchCCEdit.textContent = "*"+switchCCEdit.textContent; -// switchCCEdit.style.color = "navy"; -// switchCCEdit.style.fontWeight = "bolder"; -// switchCCEdit.style.textDecoration = "underline"; -// } + // we should make visible whether maintCCAddr is in CCList + if (isInList(this.maintCCAddr, this.CCList)) { + $("#cc_edit_area_showhide", this.doc). + css({ "color": "navy", + "font-weight": "bolder", + "text-decoration": "underline"}); + } +}; -} +bzPage.prototype.groupIDs = function (manStr,cardStrID) { + var outStr = filterByRegexp(chipIDsGroupings,manStr+","+cardStrID); + if (outStr.length == 0) { + outStr = "UNGROUPED_" + manStr+"/"+cardStrID; + } + return outStr; +}; + +/** + * Given PCI IDs for manufacturer and card ID return chipset string + * + * @param manufacturerNo string with manufacturer PCI ID + * @param cardNo string with card PCI ID + * + * @return array with chip string and optinoal variants + */ +bzPage.prototype.checkChipStringFromID = function (manufacturerNo,cardNo) { + console.log("This is the card ID: " + cardNo + " manufactured by " + manufacturerNo); + var soughtID = (manufacturerNo+","+cardNo).toUpperCase(); + var outList = PCI_ID_Array[soughtID]; + console.log("nalezeno = " + outList.toSource()); + if (outList) { + return outList; + } else { + return ""; + } +}; + +/** + * Given line to be parsed, find out which chipset it is and fill in the whiteboard + * + * @param iLine string with the whole unparsed "interesting line" + * @param driverStr string with the driver name + * @return None + */ +bzPage.prototype.fillInWhiteBoard = function (iLine,driverStr) { + var outStr = ""; + var cardIDStr = ""; + var cardIDArr = []; + + console.log("driverStr = " + driverStr); + console.log("iLine: " + iLine); + + chipSwitchboard: + if (driverStr == "RADEON") { + var cardID = iLine.replace(ATIgetIDRE,"$1"); + cardIDArr = checkChipStringFromID("1002",cardID); + if (cardIDArr.length > 0) { + cardIDStr = cardIDArr[0]; + if (cardIDArr[1]) { + optionStr = cardIDArr[1]; + outStr = groupIDs(driverStr,cardIDStr)+"/" + optionStr; + console.log("cardIDArr = " + cardIDArr.toSource() + ", outStr = "+outStr); + } else { + outStr = groupIDs(driverStr,cardIDStr); + optionStr = ""; + } + console.log("found IDs: " + cardIDStr + "," + optionStr); + } else { + outStr = "**** FULLSTRING: " + iLine; + } + } else { + // Intel Corporation, NVIDIA + cardIDArr = manuChipStrs.filter(function (el, ind, arr) { + return RegExp(el[0],"i").test(iLine); + }); + console.log("cardIDArr = " + cardIDArr.toSource()); + if (cardIDArr && (cardIDArr.length > 0)) { + cardIDArr = cardIDArr[0]; + } else { + outStr = iLine; + break chipSwitchboard; + } + // cardIDArr [0] = RE, [1] = ("RADEON","INTEL","NOUVEAU"), [2] = manu PCIID + iLine = trim(iLine.replace(RegExp(cardIDArr[0],"i"),"")); + // FIXME is this necessary? Let's try without it + // outStr = iLine.replace(/^\W*(\w*).*$/,"$1"); + // nVidia developers opted-out from grouping + if (driverStr == "INTEL") { + outStr = groupIDs(cardIDArr[1],iLine); + } else { + outStr = iLine; + } + } + console.log("result = " + outStr); + var whiteboardInput = document.getElementById("status_whiteboard"); + var attachedText = trim("card_"+outStr); + if (whiteboardInput.value.length == 0) { + whiteboardInput.value = attachedText; + } else { + whiteboardInput.value += ", " + attachedText; + } +}; + +// +bzPage.prototype.fillInAddButton = function (interestLine,driverString) { + var newButt = originalButton.cloneNode(true); + var whiteboardInput = document.getElementById("status_whiteboard"); + + newButt.setAttribute("id","chipmagic"); + newButt.setAttribute("value","Fill In"); + newButt.addEventListener('click',function (evt) { + fillInWhiteBoard(interestLine,driverString); + },true); + newButt.setAttribute("type","button"); + whiteboardInput.parentNode.appendChild(newButt); + whiteboardInput.parentNode.insertBefore(document.createTextNode("\u00A0"),newButt); +}; + +/** + * Recursive function to run Get attached Xorg.0.log, parse it and find the value of chip + * @return None + * + */ +bzPage.prototype.fillInChipMagicProcessAtts = function (ret) { + if (ret) { + if (ret.status != 200) { + alert([ret.status,ret.statusText,ret.responseHeaders, + ret.responseText]); + throw "XMLHTTPRequest got return code " + ret.status; + } + console.log('fetched ' + ret.finalUrl); + var interestingLineArr = ret.responseText.split("\n").filter(function (v,i,a) { + return ChipsetRE.test(v); + }); + console.log("interestingLineArr = " + interestingLineArr.toSource()); + if (interestingLineArr.length >0) { + // Process and exit + // .replace(ChipsetRE,"$1\t$2").split("\t") + var interestingArray = ChipsetRE.exec(interestingLineArr[0]); + console.log("interesting array = " + interestingArray.toSource()); + interestingLine = trim(interestingArray[2].replace(/[\s"]+/g," ")); + console.log("interesting line = " + interestingLine); + fillInAddButton(interestingLine,interestingArray[1].toUpperCase()); + console.log("XMLHTTPRequest done!"); + return; + } + } + + if (XorgLogAttList[XorgLogAttListIndex]) { + var XorgLogAttID = XorgLogAttList[XorgLogAttListIndex][1]; + var attURL = "https://bugzilla.redhat.com/attachment.cgi?id="+XorgLogAttID; + GM_xmlhttpRequest({ + method: 'GET', + url: attURL, + headers: { + 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey getXorgLog', + 'Accept': 'text/plain', + 'Content-type': 'text/xml' + }, + onload:fillInChipMagicProcessAtts + }); + XorgLogAttListIndex++; + } else { + console.log("No more Xorg.0.log attachments!"); + } +}; + +/** + * Get attached Xorg.0.log, parse it and find the value of chip. + * Does not fill the whiteboard itself, just adds button to do so, + * so that slow XMLHTTPRequest is done in advance. + * + * @return None + */ +bzPage.prototype.fillInChipMagic = function () { + var XorgLogURL = ""; + var XorgLogAttID = ""; + var XorgLogFound = false; + + // Find out Xorg.0.log attachment URL + XorgLogAttList = this.attachments.filter(function (value, index, array) { + // Xorg.0.log must be text, otherwise we cannot parse it + return (RegExp("[xX].*log").test(value[0]) && /text/.test(value[2])); + }); + console.log("XorgLogAttList = " + XorgLogAttList.toSource()); + if (XorgLogAttList.length == 0) { + console.log("No Xorg.0.log attachments found.") + return; + } + fillInChipMagicProcessAtts(); +}; + +/** + * Parse the row with the attachment + * + * @param <tr> DOM element to be parsed + * @return array with string name of the attachment, + integer its id number, + string of MIME type, + integer of size in kilobytes, + and the whole element itself + */ +bzPage.prototype.parseAttachmentLine = function (inElem) { + var MIMEtype = String(); + var size = Number(); + inElem.normalize(); + + // Skip over obsolete attachments + if ($(".bz_obsolete",inElem).length>0) { + return; + } + + // getting name of the attachment + var attName = $.trim($("b:first",inElem).text()); + // getting id + var id = parseInt($("a:first",inElem).attr("href"). + replace(/^.*attachment.cgi\?id=/,""),10); + + //getting MIME type and size + var stringArray = $(".bz_attach_extra_info >*:first",inElem).text(). + replace(/[\n ()]+/g," ").trim().split(", "); + size = parseInt(stringArray[0],10); + MIMEtype = stringArray[1]; + + return([attName,id,MIMEtype,size,inElem]); +}; + +/** + * Get list of attachments to the bug + * + * @return array of attachments + */ +bzPage.prototype.getAttachments = function () { + var tempT = $("#attachment_table tr:gt(1)", this.doc); + var tempTLen = tempT.length-1; + return($("lt("+tempTLen+")",tempT). + get().map(this.parseAttachmentLine)); +}; + +/** + * Main executable functioning actually building all buttons on the page -- + * separated into function, so that + * it could be called from onload method of the GM_XMLHTTPRequest. + * + * @param jsonList Array created from JSON + * @return none + */ +bzPage.prototype.buildButtons = function (above,below) { + //Generate a list of <input> elements in the page + var IBList = $("input[name*='submit']", this.doc); + var IBLast = IBList.get(IBList.length-4); + addNewButton(IBLast,"changeOwnerbtn","reASSIGN", + "","ASSIGNED","NODEFAULTASSIGNEE"); + + // BUTTONS ABOVE THE COMMENT BOX + var insAElem = $("<br>"); + $("#comment", this.doc).before(insAElem); + generateToolBar(insAElem,above); + + // BUTTONS BELOW THE COMMENT BOX + generateToolBar(this.originalButton,below); + + // FIXME put this somehow into addNewButton and generalPurposeCureForAllDisease + // framework + if (queryButtonAvailable){ + // Add query search button + var newPosition = $("#newcommentprivacy", this.doc).siblings("eq(3)"); + var newButt = originalButton.clone(true).attr({ + "id":"newqueryintab", + "value":"Query for string", + "type":"button" + }).click(function (evt) { + queryForSelection(); + }).prependTo(newPosition).before("\u00A0"); + } + if ((chipIDsGroupings.length >0) && this.maintCCAddr == "xgl-maint@redhat.com") { + // Add find chip magic button + if (!$("#status_whiteboard:contains('card_')", this.doc)) { + this.fillInChipMagic(); //FIXME missing!!! + } + } + // Add setting default assignee + if ((this.defAssignee.length > 0) && (this.defAssignee != owner)) { + var divAssigned = $("#bz_assignee_edit_container", this.doc); + var divAssignedInput = $("#assigned_to", this.doc); + var divAssignedActiveCheckbox = $("#bz_assignee_edit_action"); + newButt = originalButton.clone(true). + attr({"id":"setdefaultassigneebutton", + "value":"Def. Assignee", + "type":"button" + }).click(function (evt) { + if (defAssignee.length > 0) { + clickMouse(divAssignedActiveCheckbox); + $(divAssignedInput,this.doc).text(defAssignee); + } + }); //FIXME SHOULD CONTINUE WHERE I ENDED HERE! + divAssigned.appendChild(newButt); + newButt.parentNode.insertBefore(document.createTextNode("\u00A0"),newButt); + } + $("component").change( + function (event) { + //FIXME We screw up default assignee value for unknown components + var assignee = this.defAssignee; + // FIXME tohlenějak rozesraný Ježe. + if (assignee.length > 0) { + clickMouse(document.getElementById("bz_assignee_edit_action")); + $.ID("assigned_to").value = assignee; + document.getElementById("set_default_assignee").checked = false; + } + }); +}; -var callback = function(doc) { +var callback = function (doc) { var curPage = new bzPage(doc); }; |