// Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php jetpack.future.import("pageMods"); jetpack.future.import("storage.simple"); var RHColor = "#9E292B"; var FedoraColor = "#002867"; var RawhideColor = "#007700"; // or "green" var RHITColor = "#660066"; var SalmonPink = "#FFE0B0"; var ReporterColorHex = "#FFFFA6"; var XMLRPCurl = "https://bugzilla.redhat.com/xmlrpc.cgi"; var myConfig = jetpack.storage.simple; //============================================================== // CONFIGURE: The easiest method how to set up the configuration // value is to uncomment the following line with proper URL as // the second parameter. Then reload the bug page and comment out // again. // myConfig.JSONURL = "URL-somewhere-with-your-JSON"; var jsonDataURL = myConfig.JSONURL ? myConfig.JSONURL : "http://mcepl.fedorapeople.org/scripts/BugZappers_data.json"; var PCIIDsURL = "http://mcepl.fedorapeople.org/scripts/drm_pciids.json"; //var debug = GM_getValue("debug",false); var reqCounter = 0; var msgStrs = {}; 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"] ]; 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 = []; var hashBugzillaWholeURL = []; var defAssigneeList = []; var signatureFedoraString = ""; // TODO we should have an array SpecialFlags instead of multiple Boolean variables var queryButtonAvailable = false; var chipIDsGroupings = []; var AddrArray = []; var PCI_ID_Array = []; var XorgLogAttList = []; var XorgLogAttListIndex = 0; // Get JSON configuration data $.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; defAssigneeList = data.defaultAssignee; queryButtonAvailable = data.queryButton; chipIDsGroupings = data.chipIDsGroupings; // TODO buildButtons(data.topRow,data.bottomRow); }); // Get card translation table $.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 * @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 = []; if (list.length > 0) { chosenPair = list.filter( function (pair) { return new RegExp(pair.regexp, "i").test(chosingMark); }); } if (chosenPair.length > 0) { 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(); 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(); 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); if ((signatureFedoraString.length > 0) && ($.trim(cmntText.text()).length > 0)) { cmntText.text($.trim(cmntText.text()) + signatureFedoraString); } }); } this.setBranding(); this.checkComments(); } /** * Check for the presence of a keyword * * @param str string with the keyword * @return Boolean * */ bzPage.prototype.hasKeyword = function (str) { var kwd = $.trim($('#keywords', this.doc).text()); return (new RegExp(str).test(kwd)); }; /* Bugzilla functions.*/ /** * Set background color of all comments made by reporter in ReporterColorHex color * */ bzPage.prototype.checkComments = function () { var reporter = this.reporter; $("#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); } }); }; /** * Set branding colours to easily distinguish between Fedora and RHEL bugs * * @param brand string with product of the current bug * @param version string with the version of the bug * @param its string with the IsueTracker numbers * @return none * */ bzPage.prototype.setBranding = function () { var brandColor = ""; if (new RegExp("Red Hat Enterprise Linux").test(this.product)) { if (this.its.length > 0) { brandColor = RHITColor; } else { brandColor = RHColor; } } else if (new RegExp("Fedora").test(this.product)) { if (new RegExp("rawhide", "i").test(this.version)) { brandColor = RawhideColor; } else { brandColor = FedoraColor; } } // Comment each of the following lines to get only partial branding $("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({ 'background-image' : 'none', 'background-color' : SalmonPink }); } // 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