aboutsummaryrefslogtreecommitdiffstats
path: root/bugzillaBugTriage.js
diff options
context:
space:
mode:
Diffstat (limited to 'bugzillaBugTriage.js')
-rw-r--r--bugzillaBugTriage.js496
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);
};