diff options
author | Matěj Cepl <mcepl@redhat.com> | 2011-04-28 14:28:10 +0200 |
---|---|---|
committer | Matěj Cepl <mcepl@redhat.com> | 2011-04-28 19:14:20 +0200 |
commit | af9a8239914fb783ddd41a9dc571bd5fb2126050 (patch) | |
tree | 5f2414fa4e3fb6251e35c547a6152a780296ca9a /data/rhlib | |
parent | 32af48e442a960b8c3f199f5ffad28a34590fcda (diff) | |
download | bugzilla-triage-af9a8239914fb783ddd41a9dc571bd5fb2126050.tar.gz |
Reorganization.
* fixingAttMIME, rhbzpage, xorgBugCategories moved to data/rhlib
directory,
* docs directory removed ... keep documentation in JSDocs; rewrite in MD
is a waste of time.
* move Ehsan’s scripts to separate data/tweaks directory.
Diffstat (limited to 'data/rhlib')
-rw-r--r-- | data/rhlib/fixingAttMIME.js | 90 | ||||
-rw-r--r-- | data/rhlib/rhbzpage.js | 510 | ||||
-rw-r--r-- | data/rhlib/xorgBugCategories.js | 74 |
3 files changed, 674 insertions, 0 deletions
diff --git a/data/rhlib/fixingAttMIME.js b/data/rhlib/fixingAttMIME.js new file mode 100644 index 0000000..365cfae --- /dev/null +++ b/data/rhlib/fixingAttMIME.js @@ -0,0 +1,90 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php + +var reqCounter = 0; // TODO should be probably a dict indexed by called method + +/** + * Callback function for the XMLRPC request + * + * @param ret + * Object with xmlhttprequest response with attributes: + status -- int + * return code + statusText + responseHeaders + responseText + */ +function XMLRPCcallback() { + reqCounter--; + if (reqCounter <= 0) { + setTimeout(function() { + window.location.reload(true); + }, 1000); + } +} + +/** + * The worker function -- call XMLRPC to fix MIME type of the particular + * attachment + * + * @param id + * Integer with the attachment id to be fixed + * @param type + * String with the new MIME type, optional defaults to "text/plain" + * @param email + * Boolean whether email should be sent to appropriate person; option, + * defaults to false + * + * updateAttachMimeType($data_ref, $username, $password) + * + * Update the attachment mime type of an attachment. The first argument is a + * data hash containing information on the new MIME type and the attachment id + * that you want to act on. + * + * $data_ref = { "attach_id" => "<Attachment ID>", # Attachment ID to perform + * MIME type change on. "mime_type" => "<New MIME Type Value>", # Legal MIME + * type value that you want to change the attachment to. "nomail" => 0, # + * OPTIONAL Flag that is either 1 or 0 if you want email to be sent or not for + * this change }; + * + */ +function fixAttachById(id, XMLRPCURL, type, email) { + var params = []; + + if (type === undefined) { + type = "text/plain"; + } + if (email === undefined) { + email = false; + } + + // https://bugzilla.redhat.com/\ + // docs/en/html/api/extensions/compat_xmlrpc/code/webservice.html + // test on https://bugzilla.redhat.com/show_bug.cgi?id=485145 + params.push({ + 'attach_id' : id, + 'mime_type' : type, + 'nomail' : !email + }); + + self.postMessage(new Message("MakeXMLRPCall", { + url : XMLRPCURL, + login : getLogin(), + method : "bugzilla.updateAttachMimeType", + params : params, + callRPC : "FixAttachmentMIMECallback" + })); + reqCounter++; +} + +/** + * Add a link to the bad attachment for fixing it. + * + * @param + * <TR> DOM jQuery element with a bad attachment + * @return none + */ +function addTextLink(row, xmlRpcUrl) { + var elemS = row[4].getElementsByTagName("td"); + var elem = elemS[elemS.length - 1]; + createDeadLink("addFix2TextLink", "text", elem, fixAttachById, + [ + row[1], xmlRpcUrl + ], "br"); +} diff --git a/data/rhlib/rhbzpage.js b/data/rhlib/rhbzpage.js new file mode 100644 index 0000000..14fe19d --- /dev/null +++ b/data/rhlib/rhbzpage.js @@ -0,0 +1,510 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php + +// For identification of graphics card +var manuChipStrs = [ [ "ATI Radeon", "ATI", "1002" ], + [ "ATI Mobility Radeon", "ATI", "1002" ], + [ "Intel Corporation", "INTEL", "8086" ], [ "NVIDIA", "NV", "10de" ] ]; + +// http://en.wikipedia.org/wiki/HSL_color_space +// when only the value of S is changed +// stupido!!! the string is value in hex for each color +var RHColor = new Color(158, 41, 43); // RGB 158, 41, 43; HSL 359, 1, 39 +var FedoraColor = new Color(0, 40, 103); // RGB 0, 40, 103; HSL 359, 1, 39 +var RawhideColor = new Color(0, 119, 0); // or "green", or RGB 0, 119, 0, or + // HSL +// 120, 0, 23 +var RHITColor = new Color(102, 0, 102); // RGB 102, 0, 102; HSL 300, 0, 20 + +// [ 126.386] (--) NOUVEAU(0): Chipset: "NVIDIA NVaf" +var logAnalyzeLogic = { + "AnalyzeInterestingLine": { + /* + * [ 126.378] (--) PCI:*(0:4:0:0) 10de:08a0:106b:00c2 rev 162, Mem @ + * 0xd2000000/16777216, \ 0xc0000000/268435456, 0xd0000000/33554432, I/O @ + * 0x00001000/128, BIOS @ 0x????????/131072 + */ + re: [ + "^(\\[[ .0-9]+\\])?\\s*\\(--\\) PCI:\\*\\([0-9:]+\\)\\s*" + + "([0-9a-f:]+).*$", + "^\\s*\\[?[ 0-9.]*\\]?\\s*\\(--\\) "+ + "([A-Za-z]+)\\([0-9]?\\): Chipset: (.*)$", + ], + func: chipsetMagic + }, + /* + * [ 126.385] (WW) Falling back to old probe method for vesa [ 126.385] (WW) + * Falling back to old probe method for fbdev [ 126.386] (--) NOUVEAU(0): + * Chipset: "NVIDIA NVaf" Backtrace: [ 33.158] Kernel command line: ro + * root=LABEL=root rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 + * SYSFONT=latarcyrheb-sun16 KEYTABLE=us drm.debug=0x04 + * + */ + "AnalyzeXorgLogBacktrace": { + re: "^\\s*(\\[[0-9 .]*\\])?\\s*(\\((EE|WW)\\)|.* [cC]hipset:.*)|\\s*(Backtrace|Kernel command line)", + func: analyzeXorg + } +}; + +var ProfessionalProducts = [ + "Red Hat Enterprise Linux", + "Red Hat Enterprise MRG" +]; + +// END OF CONSTANTS + +var btSnippet = null; + +function RHOnMessageHandler(msg) { + switch (msg.cmd) { + case "Error": + alert("Error " + msg.data); + break; + case "Unhandled": + break; + case "AddAttachmentCallback": + addAttachmentCallback(msg.data); + break; + case "FixAttachmentMIMECallback": + XMLRPCcallback(); + break; + case "AnalyzeInterestingLine": + case "AnalyzeXorgLogBacktrace": + findInterestingLine(msg.data, msg.cmd); + break; + case "queryUpstream": + queryUpstreamCallback(msg.data, constantData.queryUpstreamBug); + break; + default: + console.error("Error: unknown RPC call " + msg.toSource()); + break; + } +} + +// RHBugzillaPage object + +/** + * Auxiliary function to compute more complicated resolution + */ +function closeSomeRelease() { + // for RAWHIDE close as RAWHIDE, + // if active selection -> CURRENTRELEASE + // and put the release version to + // "Fixed in Version" textbox + // otherwise -> NEXTRELEASE + selectOption("bug_status", "CLOSED"); + var text = getSelection(); + var resolution = ""; + + if (text.length > 0) { + resolution = "CURRENTRELEASE"; + document.getElementById("cf_fixed_in").value = text; + } + else if (document.getElementById("version").value === "rawhide") { + resolution = "RAWHIDE"; + } + else { + resolution = "NEXTRELEASE"; + } + centralCommandDispatch("resolution", resolution); +} + +/** + * Additional commands specific for this subclass, overriding superclass one. + */ +function RHcentralCommandDispatch(cmdLabel, cmdParams) { + switch (cmdLabel) { + // Set up our own commands + case "closeUpstream": + addClosingUpstream(); + break; + case "computeResolution": + closeSomeRelease(); + break; + case "queryStringUpstreamBugzilla": + queryUpstream(constantData.queryUpstreamBug); + break; + case "sendBugUpstream": + sendBugUpstream(); + break; + case "markTriaged": + markBugTriaged(); + break; + case "chipMagic": + console.myDebug("cmdParams = " + cmdParams.toSource()); + fillInWhiteBoard(cmdParams); + break; + // If we don't have it here, call superclass method + default: + console.error("Unknown command:\n" + cmdLabel + "\nparameters:\n" + cmdParams); + break; + } +} + +/** + * Make it sailent that the some attachments with bad MIME type are present + * + * @param atts + * Array of attachments subarrays + * @return none + */ +function markBadAttachments(atts) { + var badMIMEArray = [ "application/octet-stream", "text/x-log", "undefined" ]; + if (!constantData.passwordState.passAvailable) { + console.myDebug("markBadAttachments : No password, no XML-RPC calls; sorry"); + return null; + } + + var badAttachments = atts.filter(function(att) { + return (isInList(att[2], badMIMEArray)); + }); + + if (badAttachments.length > 0) { + var titleElement = document. + getElementsByClassName("bz_alias_short_desc_container")[0]; + titleElement.style.backgroundColor = "olive"; + + createDeadLink("fixAllButton", "Fix all", titleElement, function() { + Array.forEach(badAttachments, function(x) { + fixAttachById(x[1], constantData.XMLRPCData[window.location.hostname].url); + }); + }, [], false, null, "f"); + badAttachments.forEach(function(x, i, a) { + addTextLink(x, constantData.XMLRPCData[window.location.hostname].url); + }); + } +} + +/** + * Open a tab in the upstream bugzilla to create a new bug + * + * @return none + */ +function sendBugUpstream() { + var urlStr = filterByRegexp(constantData.newUpstreamBug, getComponent()); + if (!urlStr) { + return null; + } + + self.postMessage(new Message("OpenBugUpstream", { + url: urlStr, + subject: document.getElementById("short_desc_nonedit_display"). + textContent.trim(), + comment: collectComments() + })); +} + +/** + * Add a link opening selected lines of Xorg.0.log + * + * @return none + */ +function addCheckXorgLogLink(attList) { + if (config.XorgLogAnalysis) { + attList.forEach(function (row) { + var elemS = row[4].getElementsByTagName("td"); + var elem = elemS[elemS.length - 1]; + createDeadLink("xorgLogAnalyzeLink", "check", elem, + analyzeXorgLog, [row[1], "AnalyzeXorgLogBacktrace"], "br"); + }); + } +} + +/** + * Given line to be parsed, find out which chipset it is and fill in the + * whiteboard + * + * @param PCIidArrObj + * object with two fields id Array manufacturer-ID and product-ID (PCI + * IDs) chipsetLine whole line containing PCI ID. + * @param driverStr + * String with the driver name + * @return None + * + */ +function fillInWhiteBoard(cardName) { + console.myDebug("fillInWhiteBoard: cardName = " + cardName); + clickMouse("editme_action"); + var titleElem = document.getElementById('short_desc'); + titleElem.value = '[' + cardName + ']\u00A0' + titleElem.value; + document.getElementById("fillin_btn").style.display = "none"; +} + +/** + * 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,paramList so that slow + * XMLHttpRequest is done in advance. + * + * @param log + * array of XorgLogAttList + * @return None + */ +function fillInChipMagic(XlogID) { + analyzeXorgLog(XlogID, "AnalyzeInterestingLine"); +} + +/** + * Creates a button to change summary by adding a graphic chip label + * + * @param Array + * with matching results of re.exec() + */ +function chipsetMagic (interestingLineArr) { + // parse Xorg.0.log + var cardStr = ""; + console.myDebug("interestingLineArr = " + interestingLineArr.toSource()); + console.myDebug("interestingLineArr[1] = " + interestingLineArr[1]); + + if (interestingLineArr.length >0) { + var interestingArray = interestingLineArr[0]; + if (interestingArray.length > 1) { + var interestingPCIID = interestingArray[2].trim().split(":"); + // If we have Chipset line, we should parse it as well and + // add to the button + if (interestingLineArr.length > 1) { + var PCIid = (interestingPCIID[0] + "," + interestingPCIID[1]). + toUpperCase(); + // Nvidia driver provides good code in the Chipset line + if (interestingPCIID[0].toLowerCase() == "10de") { + cardStr = interestingLineArr[1][2]. + replace(/\s*nvidia\s*/ig,""). + replace('"','','g'); + } else { + try { + cardStr = constantData.chipNames[PCIid][0]; + } catch (e if e instanceof TypeError) { + PCIid = PCIid.toLowerCase().replace(",",":"); + cardStr = null; + alert("PCI ID " + PCIid + " is not known!"); + self.postMessage(new Message("SetClipboard", PCIid.toString())); + } catch (e) { + throw e; + } + } + } + else { + cardStr = null; + } + + if (cardStr) { + createNewButton("short_desc_nonedit_display", false, { + "name": "Fill In", + "chipMagic": cardStr + }); + } + } + } +} + +function analyzeXorg(results) { + var innerString = ""; + + if (results.length > 0) { + results.splice(0, 1); // remove headers + results.sort(); + + results.forEach(function(lRE) { + innerString += lRE.input + "<br>\n"; + }); + innerString += "----------<br>\n" + + results.length + " interesting lines found."; + } + else { + innerString += "No matching lines found!"; + } + + self.postMessage(new Message("OpenStringInPanel", + '<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">' + + "<html><head><title>Xorg.0.log analysis</title></head><body><pre>\n" + + innerString.trim() + + "\n</pre></body></html>")); +} + +function analyzeXorgLog(attachID, backMsg) { + self.postMessage(new Message("GetURL", { + url: "https://" + window.location.hostname + "/attachment.cgi?id=" + attachID, + backMessage: backMsg + })); +} + +function findInterestingLine(wholeLog, backMsg) { + var REstr = logAnalyzeLogic[backMsg].re; + var REarr = []; + if (typeof REstr == "string") { + REarr = [new RegExp(REstr)]; + } + else if (Array.isArray(REstr)) { + REarr = REstr.map(function (reone) { + return new RegExp(reone); + }); + } + console.myDebug("Current REs:"); + REarr.forEach(function (re) { + console.myDebug("re: " + re.source); + }); + + var results = []; + wholeLog.split("\n"). + forEach(function(line) { + REarr.forEach(function (re, reIdx) { + if (re.test(line)) { + console.myDebug("Found match on line:\n" + line); + console.myDebug("Result: " + re.exec(line).toSource()); + results.push(re.exec(line)); + } + }); + }); + console.myDebug("results = " + results.toSource()); + logAnalyzeLogic[backMsg].func(results); +} + +/** + * Add information about the upstream bug upstream, and closing it. + * + * @param evt + * Event which called this handler + * @return none + */ +function addClosingUpstream() { + var refs = document.getElementById("external_bugs_table") + .getElementsByTagName("tr"); + + // that's a bad id, if there is a one. :) + var inputBox = document.getElementById("inputbox"); + var externalBugID = 0; + var wholeURL = ""; + + // Fix missing ID on the external_id SELECT + document.getElementsByName("external_id")[0].setAttribute("id", + "external_id"); + + if (inputBox.value.match(/^http.*/)) { + externalBugID = getBugNoFromURL(inputBox.value); + if (externalBugID) { + inputBox.value = externalBugID; + } + // get bugzillaName and set the label + var bugzillaName = getBugzillaName(wholeURL.host, constantData.bugzillaLabelNames); + selectOptionByLabel("external_id", bugzillaName); + } + else if (!isNaN(inputBox.value)) { + externalBugID = parseInt(inputBox.value, 10); + var bugzillaHostname = document.getElementById("external_id").value; + wholeURL = bugzillaHostname+"show_bug.cgi?id="+externalBugID; + } + else { + // no inputBox.value -- maybe there is an external bug from + // the previous commit? + } + + // It is not good to close bug as UPSTREAM, if there is no reference + // to the upstream bug. + if ((externalBugID > 0) || (refs.length > 2)) { + var msgStr = constantData.commentStrings.sentUpstreamString; + msgStr = msgStr.replace("§§§", wholeURL); + centralCommandDispatch("comment",msgStr); + centralCommandDispatch("status", "CLOSED"); + centralCommandDispatch("resolution", "UPSTREAM"); + } + else { + console.myDebug("No external bug specified among the External References!"); + } +} + +/** + * + */ +function parseBacktrace (ret) { + var signalHandler = new RegExp("^\\s*#[0-9]*\\s*<signal handler called>"); + var frameNo = new RegExp("^\\s*#([0-9]*)\\s"); + + var splitArray = ret.split("\n"); + var i = 0, ii = splitArray.length; + var outStr = "", curLine = "", numStr = ""; + var lineCounter = 0, endLineNo = 0; + + // TODO shouldn't we just cut off and analyze whole thread? + while (i < ii) { + if (signalHandler.test(splitArray[i])) { + break; + } + i++; + } + + if (i < ii) { + lineCounter = parseInt(frameNo.exec(splitArray[i])[1], 10); + endLineNo = lineCounter + NumberOfFrames; + curLine = splitArray[i]; + while ((lineCounter < endLineNo) && (curLine.trim().length > 0) + && (i < ii)) { + outStr += curLine + '\n'; + numStr = frameNo.exec(curLine); + if (numStr) { + lineCounter = parseInt(numStr[1], 10); + } + i++; + curLine = splitArray[i]; + } + return outStr; + } + return ""; +} + +function RHBZinit() { + // inheritance ... call superobject's constructor + var AbrtRE = new RegExp("^\\s*\\[abrt\\]"); + var btSnippet = ""; + + var chipMagicInterestingLine = ""; + + // getBadAttachments + var XorgLogAttList = []; + var XorgLogAttListIndex = 0; + var attachments = getAttachments(); + markBadAttachments(attachments); + + var parsedAttachments = attachments.filter(function (att) { + return (new RegExp(titleParsedAttachment).test(att[0])); + }); + + if (constantData.defaultAssignee) { + setDefaultAssignee(); + } + + if (constantData.xorgBugsCategories) { + var XBZlist = filterByRegexp(constantData. + xorgBugsCategories, getComponent()); + if (XBZlist) { + makeBugCategoriesList(XBZlist); + } + } + + // setup logging only when we ask for it + if (config.submitsLogging && (window.location.hostname == "bugzilla.redhat.com")) { + setUpLogging(); + } + + // Dig out backtrace protection against double-firing? + btSnippet = ""; + + var parseAbrtBacktraces = config.parseAbrtBacktraces; + if (parseAbrtBacktraces && AbrtRE.test(getSummary())) { + pasteBacktraceInComments(parsedAttachments); + } + + // Find out Xorg.0.log attachment URL + XorgLogAttList = attachments.filter(function (value) { + // Xorg.0.log must be text, otherwise we cannot parse it + return (/[xX].*log/.test(value[0]) && /text/.test(value[2])); + }); + // Just add a link to every Xorg.0.log link analyzing it. + addCheckXorgLogLink(XorgLogAttList); + + setBranding(XorgLogAttList); + + // Uncheck "set default assignee" when the assignee is changed by other means + document.getElementById("assigned_to").addEventListener("change", + function() { + changeAssignee(null); + }, false); +} diff --git a/data/rhlib/xorgBugCategories.js b/data/rhlib/xorgBugCategories.js new file mode 100644 index 0000000..3357ed7 --- /dev/null +++ b/data/rhlib/xorgBugCategories.js @@ -0,0 +1,74 @@ +// Released under the MIT/X11 license +// http://www.opensource.org/licenses/mit-license.php +"use strict"; + +/** + * Returns true if the bug is in a good shape + * + * @return Boolean if the bug is either not in the category where we care about + * it (i.e., we don't have set up categories for this component) or if + * it is in the concerned categories, then it has a category recorded in + * the whiteboard input box. + * + */ +function hasXorgBugsCategory() { + var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether + // there is already category tag in the Whiteboard + + var isXOrgBug = filterByRegexp( + constantData.xorgBugsCategories, getComponent()); + var whiteboardContent = document + .getElementById("status_whiteboard").value; + + if (isXOrgBug) { // is it XOR? + return catRE.test(whiteboardContent); + } + else { + return true; + } +} + +/** + * Create a category list to the upper toolbar + */ +function makeBugCategoriesList(catList) { + var catRE = /\s*\[cat:.*?\]\s*/; // RE for testing whether + // there is already category tag in the Whiteboard + + // Create <select> element and add it first blank <option> + var targetDiv = document.getElementById("commit_top").parentNode; + var categoryList = document.createElement("select"); + categoryList.setAttribute("id", "xorgBugsCategoriesSelect"); + categoryList.setAttribute("name", "xorgBugsCategoriesSelect"); + var optionElement = document.createElement("option"); + optionElement.value = null; + optionElement.setAttribute("id", "catId_blank"); + optionElement.appendChild(document.createTextNode("---")); + categoryList.appendChild(optionElement); + + // Fill-in <select> with <options>s for each category one + if (catList) { + catList.forEach(function(cat) { + optionElement = document.createElement("option"); + optionElement.value = cat; + optionElement.setAttribute("id", "catId_" + + cat.replace(" ", "").toLowerCase()); + optionElement.appendChild(document.createTextNode(cat)); + categoryList.appendChild(optionElement); + }); + } + + categoryList.addEventListener("change", function(evt) { + var selectedCategory = "[cat:" + this.value + "]"; + var whiteboardElement = document + .getElementById("status_whiteboard"); + + if (hasXorgBugsCategory()) { + whiteboardElement.value = whiteboardElement.value.replace( + catRE, ""); + } + addStuffToTextBox("status_whiteboard", selectedCategory); + }, false); + + targetDiv.insertBefore(categoryList, targetDiv.firstChild); +} |