diff options
-rw-r--r-- | bugzillaBugTriage.js | 1366 | ||||
-rw-r--r-- | skip-process-bug.js | 56 |
2 files changed, 161 insertions, 1261 deletions
diff --git a/bugzillaBugTriage.js b/bugzillaBugTriage.js index eea33d2..bfe1419 100644 --- a/bugzillaBugTriage.js +++ b/bugzillaBugTriage.js @@ -4,40 +4,32 @@ jetpack.future.import("pageMods"); jetpack.future.import("storage.simple"); -// Static values -// ****************** STATIC DATA ************************* +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 myStorage = jetpack.storage.simple; +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. -//GM_setValue("JSONURL","URL-somewhere-with-your-JSON"); -var jsonDataURL = ""; -myStorage.JSONURL = "http://barstool.build.redhat.com/~mcepl/RH_Data.json"; -if (myStorage.JSONURL) { - jsonDataURL = myStorage.JSONURL; -} -if (!jsonDataURL) { - jsonDataURL = "http://mcepl.fedorapeople.org/scripts/BugZappers_data.json"; -} -console.log("jsonDataURL = " + jsonDataURL); +// 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 debug = true; var reqCounter = 0; var msgStrs = {}; -var RHColor = "#9E292B"; -var FedoraColor = "#002867"; -var RawhideColor = "#007700"; // or "green" -var RHITColor = "#660066"; -var SalmonPink = "#FFE0B0"; 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 PCI_ID_Array = []; // For identification of graphics card var manuChipStrs = [ @@ -56,32 +48,52 @@ var backTranslateManufacturerPCIID = [{ regexp: "nVidia Corporation", addr: "10de" }]; +// Initialize data from remote URL +var XMLHTTPRequestDone = false; +var hashBugzillaName = Array(); +var hashBugzillaWholeURL = Array(); +var defAssigneeList = Array(); +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 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']; + // [{'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); // Get card translation table -XMLHttpRequest({ - // anything called inside of this Request cannot have variables set in MAIN - method: 'GET', - url: PCIIDsURL, - onload: function(response) { - PCI_ID_Array = JSON.parse(response.responseText); +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); -// ************* FUNCTIONS ******************** -/** - * Clean the string from spaces around - * - * @param string to be cleaned - * @return string which was cleaned - * - */ -function trim(str,cleanRE) { - var re = RegExp("^\\s*(.*)\\s*$"); - if (cleanRE) { - re = RegExp(cleanRE); - } - return str.replace(re,"$1"); -} +//============================================================== /** * select element of the array where regexp in the first element matches second parameter @@ -91,7 +103,7 @@ function trim(str,cleanRE) { * @return string chosen element */ function filterByRegexp(list,chosingMark) { - var chosenPair = []; + var chosenPair = Array(); if (list.length > 0) { chosenPair = list.filter( function(pair){ @@ -105,784 +117,84 @@ function filterByRegexp(list,chosingMark) { } } -/** - * 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 = []; - var member = ""; - - for (var element in list) { - if (element.hasAttribute("value")) { - outL[outL.length] = $.trim(element.getAttribute("value")); - } - } - 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); -} - -/** - * returns content of the system clipboard - * @return string with the content of the clipboard or "" if empty. - * originally from - * https://developer.mozilla.org/en/Using_the_Clipboard - * - */ -// TODO to-be-replaced by -// var contents = jetpack.clipboard.get(); -function getClipboardText() { - this.netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); - - var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(Components.interfaces.nsIClipboard); - if (!clip) return(false); -; - - var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); - if (!trans) return(false); - trans.addDataFlavor("text/unicode"); - - clip.getData(trans, clip.kGlobalClipboard); - - var str = new {}; - var strLength = new {}; - - trans.getTransferData("text/unicode", str, strLength); - - if (str) { - str = str.value.QueryInterface(Components.interfaces.nsISupportsString); - } - if (str) { - pastetext = str.data.substring(0, strLength.value / 2); - } - - return pastetext; -}; - -/* Bugzilla functions.*/ - +/////////////////////////////////////////////////////////////////////////////// function bzPage(doc) { - this.document = $(doc); - - this.hashBugzillaName = []; - this.hashBugzillaWholeURL = []; - this.defAssigneeList = []; - this.signatureFedoraString = ""; - // TODO we should have an array SpecialFlags instead of multiple Boolean variables - this.queryButtonAvailable = false; - this.chipIDsGroupings = []; - this.AddrArray = []; - // Initialize data from remote URL - this.XMLHttpRequestDone = false; - this.XorgLogAttList = []; - this.XorgLogAttListIndex = 0; - - // Get JSON configuration data - XMLHttpRequest({ - // anything called inside of this Request cannot have variables set in MAIN - method: 'GET', - url: jsonDataURL, - onload: function(response) { - var data = JSON.parse(response.responseText); - msgStrs = data['strings']; - signatureFedoraString = data['signature']; - hashBugzillaName = data['bugzillalabelNames']; - hashBugzillaWholeURL = data['bugzillaIDURLs']; - AddrArray = data['CCmaintainer']; - defAssigneeList = data['defaultAssignee']; - queryButtonAvailable = data['queryButton']; - chipIDsGroupings = data['chipIDsGroupings']; - buildButtons(data['topRow'],data['bottomRow']); - if (signatureFedoraString.length > 0) { - // (or a form named "changeform") - document.forms[1].addEventListener("submit",addSignature,true); - } - } - }); - - // FOR DEBUGGING ONLY!!! - if (debug) { - //console.log("signatureFedoraString = " + signatureFedoraString); - $("#bz_field_status",this.document).append("<span inline='font-size:x-small'>"+jsonDataURL+"</span>"); - } - - // *** collect information about the bug - // var bugNo = getBugNo(); - console.log("BBB"); - var bugNo = $("#title > p:first",this.document).text(); - console.log("BBB"); - console.log(bugNo); - this.reporter = $('#bz_show_bug_column_2 > .fn:first',this.document).text(); - this.owner = $.trim($("#bz_assignee_edit_container > .fn:first",this.document).text()).toLowerCase(); - this.CCList = $("select[name*='cc']:first > *[value]",this.document); - console.log(typeof(this.CCList)); - this.product = this.getProduct(); - this.version = this.getVersion(); - this.issueTracker = this.getIssueTracker(); - this.maintCCAddr = this.getCCMaintainer(AddrArray); - this.component = this.getComponent(); - - this.checkPrivateValues(); - - this.login = this.getLogin(); - this.password = myStorage.BZpassword; - - //*** set the main environment - this.setBranding(product,version,issueTracker); - - // fix process.cgi HREFs so that to avoid confusion on IRC - if (this.document.location.href.search(/process.cgi/) != -1) { - this.fixAllHrefs(bugNo); - } - - this.fixAttachments(); - - this.originalButton = this.document("#commit"); // source button to be copied from - this.originalButton.attr("accesskey",'s'); - this.originalButton.attr("value","Submit"); -} - -/** - * This function creates a new anchor element and uses location properties (inherent) - * to get the desired URL data. Some String operations are used (to normalize results - * across browsers). - * originally from http://snipplr.com/view.php?codeview&id=12659 - * - * @param url String with URL - * @return object with parameters set - * - */ -function bzPage.prototype.parseURL(url) { - var a = $('<a href="'+url+'"></a>',this.document).get(0); - return { - source: url, - protocol: a.protocol.replace(':',''), - host: a.hostname, - port: a.port, - query: a.search, - params: (function(){ - var ret = {}, - seg = a.search.replace(/^\?/,'').split('&'), - len = seg.length, i = 0, s; - for (var i=0;i<len;i++) { - if (!seg[i]) { continue; } - s = seg[i].split('='); - ret[s[0]] = s[1]; - } - return ret; - })(), - file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,''])[1], - hash: a.hash.replace('#',''), - path: a.pathname.replace(/^([^\/])/,'/$1'), - relative: (a.href.match(/tp:\/\/[^\/]+(.+)/) || [,''])[1], - segments: a.pathname.replace(/^\//,'').split('/') - }; -} - -/** - * add Fedora Bug zapper's signature to the comment of the current bug - */ -function bzPage.prototype.addSignature = function(evt) { - var cmntText = $("#comment",this.document); - if ((this.signatureFedoraString.length > 0) && - ($.trim(cmntText.value).length > 0)) { - cmntText.value = $.trim(cmntText.value) + this.signatureFedoraString; - } - } - -/** - * Get list of attachments to the bug - * - * @return array of attachments - */ -function bzPage.prototype.fixAttachments(){ - - /** - * Parse the row with the attachment - * @param <tr> 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 - */ - function parseAttachmentLine(inElem) { - var name = ""; - var MIMEtype = ""; - var size = Number(); - var id = Number(); - - // FIXME we should skip obsolete attachments - inElem.normalize(); - - // getting name of the attachment - var bElem = $("b:first",inElem); - name = $.trim(bElem.text()); - - // getting id - id = parseInt($("a:first",inElem).attr("href").replace(/^.*attachment.cgi\?id=/,""),10); - - //getting MIME type and size - var roundedText = $(".bz_attach_extra_info:first",inElem).html(); - - var stringArray = $.trim(roundedText.replace(/^\s*\((.*)\s*KB,\s*$/,"$1")); - size = parseInt(stringArray,10); - MIMEtype = roundedText.split("\n")[2].replace(/^\s*(.*)\)\s*$/,"$1"); - - return([name,id,MIMEtype,size,inElem]); - } - - function getAttachments(attTable) { - var attList = []; - - var tempT = $("tr",attTable).get(); - if (tempT.length > 2) { - for (var i=1;i<tempT.length-1;i++) { - attList.push(parseAttachmentLine(tempT[i])); - } - } - return(attList); - } - - function isOctetStream(element, index, array) { - var inArray = ["application/octet-stream","text/x-log"]; - return(inArray.indexOf(element[2]) != -1); - } - - var aTable = $("#attachment_table",this.document); - var attachmentsList = getAttachments(aTable.get()); - var badAttachments = attachmentsList.filter(isOctetStream); - - if (badAttachments.length>0) { - var titleElement = $(".bz_alias_short_desc_container:first",this.document); - titleElement.css("background-color","olive"); - titleElement.append(createFixAllButton(badAttachments)); - for(var i=0;i<badAttachments.length;i++) { - addTextLink(badAttachments[i]); - } - } -} - -/** - * 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 - */ -function bzPage.prototype.fillInWhiteBoard(iLine,driverStr) { - var outStr = ""; - var cardIDStr = ""; - var cardIDArr = []; - - function groupIDs(manStr,cardStrID) { - // console.log("RegExpArr = " + chipIDsGroupings.toSource() + ", hledam = " + 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 - */ - function checkChipStringFromID(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 ""; - } - } - - 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 = ""; + this.doc = $(doc); + 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.maintCCAddr = filterByRegexp(AddrArray,this.component).toLowerCase(); + console.log("maintCCAddr = " + this.maintCCAddr); + + // 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); } - 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 = $("#status_whiteboard",this.document); - var attachedText = $.trim("card_"+outStr); - if (whiteboardInput.val().length == 0) { - whiteboardInput.val(attachedText); - } else { - whiteboardInput.val(whiteboardInput.val()+", " + attachedText); - } -} - -/** - * Insert "Fill In" button to the status whiteboard - * @param interestLine string with the interesting part of the Chipset: line - * @param driverString string with name of the driver ("INTEL", "RADEON", "NOUVEAU", - * etc.) - * @return none - */ -function bzPage.prototype.fillInAddButton(interestLine,driverString) { - var newButt = $(this.originalButton).clone(); - var whiteboardInput = $("#status_whiteboard",this.document); - - newButt.attr("id","chipmagic"); - newButt.attr("value","Fill In"); - newButt.attr("type","button"); - newButt.click(function (evt) { - this.fillInWhiteBoard(interestLine,driverString); - }); - whiteboardInput.after(newButt); - whiteboardInput.after("\u00A0"); -} - -/** - * 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. - * @param none - * @return none - */ -function bzPage.prototype.fillInChipMagic() { - /** - * Recursive function to run Get attached Xorg.0.log, parse it and find the value of chip - * @return None - */ - function fillInChipMagicProcessAtts(ret) { - if (ret) { - if (ret.status != 200) { - jetpack.notifications.show([ret.status,ret.statusText,ret.responseHeaders, - ret.responseText].toSource()); - 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; - 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!"); - } - } - - var XorgLogURL = ""; - var XorgLogAttID = ""; - var XorgLogFound = false; - - // Find out Xorg.0.log attachment URL - XorgLogAttList = attachmentsList.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(); -} - -/** - * Opens a new tab with a query for the given text in the selected component - * @param text to be searched for - * @param component string with the component name (maybe latter regexp?) - * @param product (optional) string with the product name - * @return None - * - * old - * long_desc=Xpress%20200&bug_status=NEW&bug_status=ASSIGNED - * new - * long_desc_type=substring&long_desc=Xpress%20200&bug_status=NEW&bug_status=ASSIGNED - */ -function bzPage.prototype.queryInNewTab(text,component,product) { - // Optional parameter - if (product == null) { - product = "Fedora"; - } - var url = "https://bugzilla.redhat.com/buglist.cgi?query_format=advanced"; - if (product) { - url += "&product="+product; } - if (component) { - url += "&component="+component; - } - if (text) { - url += "&long_desc_type=substring&long_desc="+ text.replace(" ","%20"); - } - console.log("queryInNewTab: url = " + url); - window.open(url); -} - -function bzPage.prototype.queryForSelection(component) { - var text = window.getSelection().to""; - if (text.length < 1) { - text = getClipboardText(); - }; - if (text.length > 0) { - this.queryInNewTab(text, getComponent()); - } -} - -/** - * Sends XMLRPC request - * - * @param url string with URL of the XML-RPC interface - * @param data string with XML of the data to be sent - * @param method string -- either 'post' or 'get' - * @param callback function catching callback - */ -function bzPage.prototype.sendRequest(url,data,method,callback) { - //$.rpc(url, dataType, onLoadCallback, version); - XMLHttpRequest({ - method: method, - url: url, - headers: { - 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey fixAttType XMLRPC', - 'Accept': 'application/atom+xml,application/xml,text/xml', - 'Content-type': 'text/xml' - }, - data: data, - onload: callback - }); -} - -/** - * Callback function for the XMLRPC request - * - * @param ret object with XMLHttpRequest response - * with attributes: - * + status -- int return code - * + statusText - * + responseHeaders - * + responseText - */ -function bzPage.prototype.callBack(ret) { - if (ret.status != 200) { - jetpack.notifications.show([ret.status,ret.statusText,ret.responseHeaders, - ret.responseText].toSource()); - } - if (--reqCounter <= 0) { - setTimeout("document.location.reload()",1000); - } -} - -/** - * Callback function for "Fix all attachments" button - * @param list Array of - * @return none - */ -function bzPage.prototype.fixAllAttachments(list) { - var tmpElem = {}; - - /** - * 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, e.g. "text/plain" - * - */ - function fixAttachById(id,type) { - // FIXME XMLRPCMessage - var msg = new XMLRPCMessage("bugzilla.updateAttachMimeType"); - msg.addParameter({'attach_id':id, 'mime_type':type}); - msg.addParameter(login); - msg.addParameter(password); - try { - var ret = sendRequest(XMLRPCurl, - msg.xml(),'post',callBack); - } - catch (e) { - jetpack.notifications.show([e,ret].toSource()); - } - reqCounter++; - } - - for(var i=0;i<list.length;i++) { - tmpElem = list[i]; - fixAttachById(tmpElem[1],"text/plain"); - } -} - -function bzPage.prototype.createFixAllButton(list) { - var aElem = $("<a href=''></a>"); - aElem.click(function(event) { - fixAllAttachments(list); - }); - fixElement(aElem,"","F","ix all"); - return aElem; -} - -function bzPage.prototype.addTextLink(row) { - var aList = row[row.length-1].getElementsByTagName("a"); - var curElem = aList[aList.length-1]; - var tElem = {}; - var t2Elem = {}; - - tElem = $(" <a href=''>Text</a>").bind("click", - function(event) { - fixAttachById(row[1],"text/plain"); - }); - tElem.appendChild(t2Elem); - $(curElem).parent().append("<br>"); - $(curElem).parent().append(tElem); -} - -//=========================== - - -/** - * Find the next (or previous) sibling element of given tagName - * starting from given element. - * - * @param startElement element from which to start searching - * @param tagName string tagName of the searched for element (case insensitive) - * @param forward boolean optional should we search forward or backward? - * @return element of the given tagName or null - */ -function bzPage.prototype.findNextSiblingByTagName(startElement,tagName,forward) { - if (forward === null) { // missing optional argument - forward = true; - } - var tempElement = startElement; - tagName = tagName.toUpperCase(); - while (tempElement && tempElement.tagName != tagName) { - if (forward) { - tempElement = tempElement.nextSibling; - } else { - tempElement = tempElement.previousSibling; - } - } - return tempElement; -} - -/** - * Select option with given label on the <SELECT> element with given id. - * - * Also execute change HTMLEvent, so that the form behaves accordingly. - * - * @param id - * @param label - * @return none - */ -function bzPage.prototype.selectOption(id,label) { - var selectElement = jetpack.tabs.focused.contentDocument.getElementById(id); - var values = selectElement.options; - for (var i = 0; i < values.length; i++) { - values[i].normalize(); - if (values[i].text.search(label) != -1) { - values[i].selected = true; - var intEvent = jetpack.tabs.focused.contentDocument.createEvent("HTMLEvents"); - intEvent.initEvent("change", true, true); - selectElement.dispatchEvent(intEvent); - break; - } - } -} -/** - * Returns the component of the bug - * - * @return string component of the bug - */ -function bzPage.prototype.getComponent() { - return $.trim($("#component",this.document).attr("value")); + this.setBranding(); + this.checkComments(); } /** - * Returns the product the bug belongs to + * Check for the presence of a keyword * - * @return string product the bug belongs to - */ -function bzPage.prototype.getProduct() { - var productSelect = $("#product",this.document); - var index = productSelect.selectedIndex; - return productSelect.options[index].value; -} - -/** - * Returns the version of product the bug belongs to + * @param str string with the keyword + * @return Boolean * - * @return string revision of the product the bug belongs to */ -function bzPage.prototype.getVersion() { - var versionSelect = $("#version",this.document).get(0); - if (versionSelect) { - var index = versionSelect.selectedIndex; - return versionSelect.options[index].value; - } else { - return null; - } +bzPage.prototype.hasKeyword = function(str) { + var kwd = $.trim($('keywords',this.doc).text()); + return (RegExp(str).test(kwd)); } -/** - * Returns the number of the current bug - * - * @return int with the bug number - */ -function bzPage.prototype.getBugNo() { - var title = $.trim($("#title > p:first",this.document).html()); - return eval(title.split(" ")[1]); -} +/* Bugzilla functions.*/ /** - * Returns an email address for collective maintainers - * who should be on the CC of the bug. + * Set background color of all comments made by reporter in ReporterColorHex color * - * @return string email address to be on CC list. */ -function bzPage.prototype.getCCMaintainer(addrs) { - return filterByRegexp(addrs,getComponent()).toLowerCase(); -} - -/** - * Returns default assignee for the bug's component - * @return string with the default assignee for given component - */ -function bzPage.prototype.getDefaultAssignee() { - return filterByRegexp(defAssigneeList,getComponent()).toLowerCase(); -} - -/** - * Get Issuetracker string from the bug page - * @return string issuetracker numbers or empty string (either because we have no IT - * or because it is not a RHEL bug). - */ -function bzPage.prototype.getIssueTracker() { - var interestingElement = $("#cf_issuetracker",this.document); - if (interestingElement) { - return $.trim(interestingElement.value); - } else { - return ""; - } -} - -/** - * Is this bug RHEL bug? - * @return boolean - */ -function bzPage.prototype.isRHELBug() { - return getProduct().search(/Red Hat Enterprise Linux/) != -1; -} - -/** - * Add accesskey to the particular element - * - * @param rootElement element to which the new text object will be attached - * @param beforeText text before the accesskey character - * @param accKey what will be the accesskey itself - * @param afterText text after the accesskey character - * @return modified element with the fixed accesskey - * -*/ -function bzPage.prototype.fixElement(rootElement,beforeText,accKey,afterText) { - rootElement.attr("accesskey",accKey.toLowerCase()); - rootElement.innerHTML = beforeText + "<b><u>" + accKey + "</u></b>" + afterText; - return rootElement; -} +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); + } + }); +}; /** * 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 + * @return none + * */ -function bzPage.prototype.setBranding(brand,version,its) { +bzPage.prototype.setBranding = function () { var brandColor = ""; - - if (brand.search(/Red Hat Enterprise Linux/) != -1) { - if (its.length > 0) { + + if (RegExp("Red Hat Enterprise Linux").test(this.product)) { + if (this.its.length > 0) { brandColor = RHITColor; } else { brandColor = RHColor; } - } else if (brand.search(/Fedora/) != -1) { - if (version.search(/rawhide/i) != -1) { + } else if (RegExp("Fedora").test(this.product)) { + if (RegExp("rawhide","i").test(this.version)) { brandColor = RawhideColor; } else { brandColor = FedoraColor; @@ -890,471 +202,33 @@ function bzPage.prototype.setBranding(brand,version,its) { } // Comment each of the following lines to get only partial branding - jetpack.tabs.focused.contentDocument.body.style.background = brandColor; - $("#titles",this.document).style.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 (hasKeyword("Security")) { - var divBody = $("#bugzilla-body",this.document); - divBody.style.backgroundImage = "none"; - divBody.style.backgroundColor = SalmonPink; + 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(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(maintCCAddr, CCList)) { - var switchCCEdit=$("#cc_edit_area_showhide",this.document); - //switchCCEdit.textContent = "*"+switchCCEdit.textContent; - switchCCEdit.style.color = "navy"; - switchCCEdit.style.fontWeight = "bolder"; - switchCCEdit.style.textDecoration = "underline"; - } - -} - -/** - * Generic function to add new button to the page. - * Actually copies new button from the old one (in order to have the same - * look-and-feel, etc. - * @param originalLocation object with the button to be copied from - * @param newId string with the id of the new button; has to be unique in - whole page - * @param newLabel string with the label which will be shown to user - * @param commentString string with comment to be added to the comment box - * @param nState string with the new state bug should switch to (see - * generalPurposeCureForAllDisease function for details) - * @param secPar string with second parameter for generalPurposeForAllDisease - * @param doSubmit bool optional whether the button should submit whole page - * (default true) - * - * @return none - */ -function bzPage.prototype.addNewButton(originalLocation,newId,newLabel,commentString,nState,secPar,doSubmit) { - if (doSubmit === null) { // missing optional argument - doSubmit = true; - } - var newButton = this.originalButton.cloneNode(true); - if (!doSubmit) { - newButton.attr("type","button"); - } - newButton.id=newId; - newButton.attr("value",newLabel); - var commStr = ""; - if (msgStrs[commentString]) { - commStr = msgStrs[commentString]; - } - newButton.addEventListener('click',function (evt) { - generalPurposeCureForAllDisease(commStr, nState, secPar); - },true); - var textNode = $("\u00A0"); - originalLocation.parentNode.insertBefore(textNode,originalLocation); - originalLocation.parentNode.insertBefore(newButton,textNode); -} - -/** - * Add new keyword among the keywords. - * - * @param str string with the new keyword - * @return none - * - * Checks for the existing keywords. - */ -function bzPage.prototype.addKeyword(str) { - var kwd = jetpack.tabs.focused.contentDocument.getElementById('keywords'); - if (kwd.value.length == 0) { - kwd.value = str; - }else{ - kwd.value = kwd.value + ", " + str; - } -} - -/** - * Check for the presence of a keyword - * - * @param str string with the keyword - * @return Boolean - * - */ -function bzPage.prototype.hasKeyword(str) { - var kwd = $.trim($('#keywords').text()); - return (RegExp(str).test(kwd)); -} - -/** - * Add XGL to the CC list - * - * @param evt event which made this function active - * @return none - */ -function bzPage.prototype.changeOwnerHandler(evt) { - /** Take care that when changing assignment of the bug, - * current owner is added to CC list. - * Switch off setting to the default assignee - */ - if (!isInList(maintCCAddr, CCList)) { - addToCC(maintCCAddr); - } - var setDefaultAssigneeCheckbox = $("#set_default_assignee",this.document); - setDefaultAssigneeCheckbox.checked = false; - selectOption("bug_status", "ASSIGNED"); -} - -/** - * Set the bug to NEEDINFO state - * - * Working function. - * @return none - */ -function bzPage.prototype.setNeedinfoReporter() { - var checkbox = $("#needinfo",this.document); - checkbox.click(); - selectOption("needinfo_role", "reporter"); -} - -/** - * Add text to the comment. - * @param string2BAdded string to be added to the comment box - * - * @return none - */ -function bzPage.prototype.addTextToComment(string2BAdded) { - var commentTextarea = $("#comment",this.document); - - // don't remove the current content of the comment box, - // just behave accordingly - if (commentTextarea.value.length > 0) { - commentTextarea.value += "\n\n"; - } - commentTextarea.value += string2BAdded; -} - -/** - * add address to CC of this bug - * - * @param address string address to be added - * @return none - */ -function bzPage.prototype.addToCC(address) { - var sel = $("#newcc",this.document); - sel.value = address; } -/** - * Generalized function for all actions - * - * @param addString string to be added as new comment - * @param nextState string signifying next state of the bug (whatever is in Bugzilla + - "NEEDINFO" meaning NEEDINFO(Reporter)) - * @param secondParameter string with label on the subbutton for reason - * of closing the bug - * @return none - */ -function bzPage.prototype.generalPurposeCureForAllDisease(addString,nextState,secondParameter) { - if (addString.length >0) { - addTextToComment(addString); - } - - if (nextState == "CLOSED") { - if (secondParameter == "UPSTREAM") { - addClosingUpstream(); - } else if (secondParameter.length > 0) { - selectOption("bug_status", nextState); - selectOption("resolution",secondParameter); - return 0; - } else { - throw("Missing resolution for CLOSED status."); - } - } - - // Now closing bugs is done, what about the rest? - if (nextState == "NEEDINFO") { - setNeedinfoReporter(); - } else if (nextState == "ADDKEYWORD") { - if (secondParameter.length == 0) { - throw "Keyword has to be defined"; - } - addKeyword(secondParameter); - } else if (nextState == "ASSIGNED") { - if (!isInList(maintCCAddr, CCList)) { - addToCC(maintCCAddr); - } - selectOption("bug_status", nextState); - } else if (nextState.length >0) { - selectOption("bug_status", nextState); - } - - if (secondParameter == "ADDSELFCC") { - $("#addselfcc",this.document).checked = true; - } else if (secondParameter == "NODEFAULTASSIGNEE") { - $("#set_default_assignee",this.document).checked = false; - } -} - -/** - * Return string with the ID for the external_id SELECT for - * external bugzilla - * - * @param URLhostname string hostname of the external bugzilla - * @return string with the string for the external_id SELECT - */ -function bzPage.prototype.getBugzillaName(URLhostname) { - var bugzillaID = ""; - if (hashBugzillaName[URLhostname]) { - bugzillaID = hashBugzillaName[URLhostname]; - } else { - bugzillaID = ""; - } - return bugzillaID; -} - -/** - * Generate URL of the bug on remote bugzilla - * @param selectValue Number which is index of the bugzilla in hashBugzillaWholeURL - * @param bugID Number which is bug ID - * @return string with the URL - */ -function bzPage.prototype.getWholeURL(selectValue,bugID) { - var returnURL = ""; - if (hashBugzillaWholeURL[selectValue]) { - returnURL = hashBugzillaWholeURL[selectValue]+bugID; - } else { - returnURL = ""; - } - return returnURL; -} - -/** - * Add information about the upstream bug upstream, and closing it. - * @param evt event which called this handler - * - * @return none - */ -function bzPage.prototype.addClosingUpstream() { - var refs = $("#external_bugs_table > tr",this.document); - var inputBox = $("#inputbox",this.document); - var externalBugID = 0; - var wholeURL = ""; - - // Fix missing ID on the external_id SELECT - $("*[name*='external_id']:first",this.document).attr("id","external_id"); - - if (inputBox.text().match(/^http.*/)) { - wholeURL = inputBox.text(); - var IBURLArr = this.parseURL(wholeURL); - console.log("IBURLArr = " + IBURLArr.toSource()); - externalBugID = parseInt(IBURLArr.params["id"]); - inputBox.text(externalBugID); - var bugzillaName = getBugzillaName(IBURLArr.host); - selectOption("external_id", bugzillaName); - console.log("externalBugID = " + externalBugID); - } else if (!isNaN(inputBox.text())) { - externalBugID = parseInt(inputBox.text()); - var bugzillaID = $("#external_id",this.document).text(); - wholeURL = getWholeURL(bugzillaID,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 ((refs.get().length > 2) || (externalBugID > 0)) { - addTextToComment(msgStrs['sentUpstreamString'].replace("§§§",wholeURL)); - selectOption("bug_status", "CLOSED"); - selectOption("resolution", "UPSTREAM"); - } else { - jetpack.notifications.show("No external bug specified among the External References!"); - } -} - -/** - * Currently we don't use this function - * @param evt event send from DOM (not used) - * @return none - */ -function bzPage.prototype.swapXGLMainToCCListHandler(evt) { - /** Remove mcepl@redhat.com from CC list and put there - * xgl-maint@redhat.com - */ - - myAddrIndex = CCList.indexOf(login); - if (!isInList(maintCCAddr, CCList)) { - addToCC(maintCCAddr); - } - if (isInList(login, CCList)) { - var selBox = $("#cc",this.document); - selBox[myAddrIndex].selected = true; - $("#removecc",this.document).checked = true; - } - evt.stopPropagation(); - evt.preventDefault(); -} - -/** - * Go through all <a> elements in the page and fix those starting with # - * to point to the real bug, not to process.cgi page. - * @param bugNo - */ -function bzPage.prototype.fixAllHrefs(bugNo) { - var AList = $("a").get(); - var curA; - var hrefStr = ""; - var reProcess = RegExp(""); - - for(var i=0;i<AList.length;i++) { - curA = $(AList[i]); - if (curA.attr("href")) { - hrefStr = curA.attr("href"); - if (reProcess.test(hrefStr)) { - hrefStr = "show_bug.cgi?id="+bugNo.to""+hrefStr; - curA.attr("href",hrefStr); - } - } - } -} - -/** Insert row of buttons before the marked element - * @param anchor element before which the row of buttons will be inserted - * @param array array of data for buttons to be generated - */ -function bzPage.prototype.generateToolBar(anchor,array) { - for (var i=0; i<array.length; i++) { - var butt = array[i]; - addNewButton(anchor, butt['idx'], - butt['msg'], butt['string'], butt['state'], butt['parameter'], butt['submit']); - } -} - -/** - * make sure that prefs.js contain password for bugzilla - * @return None - */ -function bzPage.prototype.checkPrivateValues() { - var password = ""; - if (myStorage.BZpassword) { - password = myStorage.BZpassword; - } - if (password == "") { - password = prompt("Enter your Bugzilla password",""); - myStorage.BZpassword = password; - } -} - -/** - * Main executable functioning actually building all buttons on the page -- separated into function, so that - * it could be called from onload method of the XMLHttpRequest. - * @param jsonList Array created from JSON - * @return none - */ -function bzPage.prototype.buildButtons(above,below) { - /** - * There is a login printed on each page, go get it. - * @return string with the login - */ - function getLogin() { - var tmpElement = {}; - var tmpText = ""; - - // FIXME tohle bude špatně - var loginText = $.trim($("#header > ul:first > li:last >*:last",this.document).text()); - console.log("loginText = " + loginText); - return loginText; - } - - /** - * Is this bug Xorg bug? - * @return boolean - */ - function isXorgBug() { - return this.maintCCAddr == "xgl-maint@redhat.com"; - } - - //---------------------------------------------- - //Generate a list of <input> elements in the page - var IBList = $("input[type*='submit']",this.document).get(); - - // BUTTONS ON THE BOTTOM OF THE FORM - // Create a new SUBMIT button adding current owner of the bug to - // the CC list - var IBLast = IBList[IBList.length-4]; - addNewButton(IBLast,"changeOwnerbtn","reASSIGN", - "","ASSIGNED","NODEFAULTASSIGNEE"); - - // BUTTONS ABOVE THE COMMENT BOX - var insertAfterElement = $("<br/>"); - $("#comment",this.document).before(insertAfterElement); - //var brElement = findNextSiblingByTagName(textCommentElement,"BR",false); - this.generateToolBar(insertAfterElement.get(0),above); - - // BUTTONS BELOW THE COMMENT BOX - this.generateToolBar(this.originalButton,below); - - // TODO put this somehow into addNewButton and generalPurposeCureForAllDisease - // framework - if (this.queryButtonAvailable){ - // Add query search button - var newPosition = $("#newcommentprivacy",this.document).siblings()[2]; - var newButt = $(this.originalButton).clone(); - newButt.attr("id","newqueryintab"); - newButt.attr("value","Query for string"); - newButt.addEventListener('click',function (evt) { - queryForSelection(); - },true); - newButt.attr("type","button"); - newPosition.before(newButt); - newPosition.before("\u00A0"); - } - if ((chipIDsGroupings.length >0) && isXorgBug()) { - // Add find chip magic button - var whiteboardInput = $("#status_whiteboard",this.document); - if (whiteboardInput.text().search(/card_/) == -1) { - fillInChipMagic(); - } - } - // Add setting default assignee - var defAssignee = getDefaultAssignee(); - if ((defAssignee.length > 0) && (defAssignee != this.owner)) { - var divAssigned = $("#bz_assignee_edit_container",this.document); - var divAssignedInput = $("#assigned_to",this.document); - var divAssignedActiveCheckbox = $("#bz_assignee_edit_action",this.document); - newButt = $(this.originalButton).clone(); - newButt.attr("id","setdefaultassigneebutton"); - newButt.attr("value","Def. Assignee"); - newButt.click(function (evt) { - if (defAssignee.length > 0) { - $(divAssignedActiveCheckbox).click(); - divAssignedInput.value = defAssignee; - } - }); - newButt.attr("type","button"); - divAssigned.append(newButt); - newButt.before("\u00A0"); - } - var curComponentElement = $("#component",this.document); - $(curComponentElement).change( - function(event) { - var assignee = getDefaultAssignee(); - if (assignee.length > 0) { - $("#bz_assignee_edit_action",this.document).click(); - $("#assigned_to",this.document).val(assignee); - $("#set_default_assignee",this.document).get(0).checked = false; - } - }); -} - -// https://bugzilla.redhat.com/show_bug.cgi?id=451951 -// - -// Interesting JEPs -// https://wiki.mozilla.org/Labs/Jetpack/JEP/10 -- clipboard access -// https://wiki.mozilla.org/Labs/Jetpack/JEP/17 -- page mods - var callback = function(doc) { - console.log("BOOOM!"); var curPage = new bzPage(doc); }; + var options = {}; options.matches = [ "https://bugzilla.redhat.com/show_bug.cgi*", diff --git a/skip-process-bug.js b/skip-process-bug.js index 3972893..045eb8d 100644 --- a/skip-process-bug.js +++ b/skip-process-bug.js @@ -1,16 +1,42 @@ -jetpack.tabs.onReady(function(doc){ - var root = 'https://bugzilla.mozilla.org/', - pages = ['attachment', 'post_bug', 'process_bug'], - paths = pages.map(function(p) root + p + '.cgi'), - collision = 'Mid-air collision!'; - if (paths.some(function(p) doc.location == p) && doc.title != collision) { - var $doc = $(doc), - mail = $doc.find('#bugzilla-body > dl').text(), - bug = $($doc.find('.bz_alias_short_desc_container > a')); - /* Bail if we sense a disturbance. */ - if (bug.size() != 0) { - jetpack.notifications.show({title: 'Mail sent for ' + bug.text(), body: mail}); - doc.location = root + bug.attr('href'); +jetpack.future.import("pageMods"); + +var callback = function(document){ + var stemURL = "https://HOSTNAME/show_bug.cgi?id="; + var titleStr = $("title",document).text(); + var REArr = RegExp("[0-9]+").exec(titleStr); + var REHostname = RegExp("\/\/([^/]+)\/").exec(document.location.toString()); + if (REArr) { + var bugNo = REArr[0]; + var hostname = REHostname[1]; + console.log("bugNo = " + bugNo + ", hostname = " + hostname); +// jetpack.notifications.show('Bug ' + bugNo); + var emailsSent = $("#bugzilla-body > dl:first",document).text(); + emailsSent = emailsSent.replace(/^(\s*)$/mg,""); + console.log(emailsSent); // to be sent to jetpack.notifications.show when available + document.location = stemURL.replace("HOSTNAME",hostname) + bugNo; } - } -}); +}; + +var options = {}; +options.matches = [ + "https://bugzilla.redhat.com/process_bug.cgi", + "https://bugzilla.mozilla.org/post_bug.cgi", + ]; +jetpack.pageMods.add(callback, options); + +// "https://bugzilla.redhat.com/attachment.cgi", +// http://code.google.com/chrome/extensions/match_patterns.html sucks, we don't have $ + +// paths = pages.map(function(p) root + p + '.cgi'), +// collision = 'Mid-air collision!'; +// if (paths.some(function(p) doc.location == p) && doc.title != collision) { +// var $doc = $(doc), +// mail = $doc.find('#bugzilla-body > dl').text(), +// bug = $($doc.find('.bz_alias_short_desc_container > a')); +// /* Bail if we sense a disturbance. */ +// if (bug.size() != 0) { +// jetpack.notifications.show({title: 'Mail sent for ' + bug.text(), body: mail}); +// doc.location = root + bug.attr('href'); +// } +// } +//}); |