From 6bc8e6db8a1888bddebadf516543f731dbb86563 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Thu, 19 Nov 2009 22:09:43 +0100 Subject: Mark assigned bugs with highlighting the status field with lighter version of the branding color. XML-RPC changing MIME type works Marking suspicious components (xorg-x11, xorg-x11-drivers) still broken. --- bugzillaBugTriage.js | 313 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 264 insertions(+), 49 deletions(-) diff --git a/bugzillaBugTriage.js b/bugzillaBugTriage.js index 6cfa8c6..0370890 100644 --- a/bugzillaBugTriage.js +++ b/bugzillaBugTriage.js @@ -6,16 +6,20 @@ jetpack.future.import("storage.simple"); jetpack.future.import("selection"); jetpack.future.import("clipboard"); -var RHColor = "#9E292B"; -var FedoraColor = "#002867"; -var RawhideColor = "#007700"; // or "green" -var RHITColor = "#660066"; -var SalmonPink = "#FFE0B0"; -var ReporterColor = "#FFFFA6"; -var TriagedColor = "#F58989"; +// 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 +var SalmonPink = new Color(255, 224, 176); // RGB 255, 224, 176; HSL 36, 2, 85 +var ReporterColor = new Color(255, 255, 166); // RGB 255, 255, 166; HSL 60, 2, 83 +var Luminosity = 0.85; +var Desaturated = 0.4; var XMLRPCurl = "https://bugzilla.redhat.com/xmlrpc.cgi"; var myConfig = jetpack.storage.simple; -var badMIMEArray = ["application/octet-stream","text/x-log"]; +var badMIMEArray = ["application/octet-stream","text/x-log","undefined"]; var TriagedDistro = 12 //============================================================== @@ -36,8 +40,6 @@ 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]+)\\).*$"); -var inArray = ["application/octet-stream","text/x-log"]; - // For identification of graphics card var manuChipStrs = [ ["ATI Radeon", "ATI", "1002"], @@ -60,6 +62,8 @@ var XMLHTTPRequestDone = false; var hashBugzillaName = []; var hashBugzillaWholeURL = []; var defAssigneeList = []; +var suspiciousComponents = []; + var signatureFedoraString = ""; // TODO we should have an array SpecialFlags instead of multiple Boolean variables var queryButtonAvailable = false; @@ -73,6 +77,7 @@ var bottomRow = {}; $.getJSON(jsonDataURL, function (response) { msgStrs = response.strings; signatureFedoraString = response.signature; + suspiciousComponents = response.suspiciousComponents; hashBugzillaName = response.bugzillalabelNames; hashBugzillaWholeURL = response.bugzillaIDURLs; // [{'regexp to match component':'email address of an universal maintainer'}, ...] @@ -181,6 +186,194 @@ function parseURL(url) { }; } +// ============================================================================ +// Color management methods +// originally from +// http://www.mjijackson.com/2008/02\ +// /rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + +function Color(r,g,b) { + if (r instanceof Array) { + this.r, this.g, this.b = r; + } else { + this.r = r; + this.g = g; + this.b = b; + } +}; + +Color.prototype.update = function(r,g,b) { + this.r = r; + this.g = g; + this.b = b; +}; + +Color.prototype.hs = function(nStr) { + if (nStr == 0) { + return "00"; + } else if (nStr.length < 2) { + return "0" + nStr; + } else { + return nStr; + } +} + +Color.prototype.hex = function() { + var rH = Number(this.r.toFixed()).toString(16); + var gH = Number(this.g.toFixed()).toString(16); + var bH = Number(this.b.toFixed()).toString(16); + return "#"+this.hs(rH)+this.hs(gH)+this.hs(bH); +}; + +/** + * Converts an RGB color value to HSL. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes r, g, and b are contained in the set [0, 255] and + * returns h, s, and l in the set [0, 1]. + * + * @param Number r The red color value + * @param Number g The green color value + * @param Number b The blue color value + * @return Array The HSL representation + */ +Color.prototype.hsl = function (){ + r = this.r / 255, g = this.g / 255, b = this.b / 255; + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, l = (max + min) / 2; + + if(max == min){ + h = s = 0; // achromatic + }else{ + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch(max){ + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + + return [h, s, l]; +}; + +/** + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param Number h The hue + * @param Number s The saturation + * @param Number l The lightness + * @return Array The RGB representation + */ +Color.prototype.hslToRgb = function (h, s, l){ + var r, g, b; + + if(s == 0){ + r = g = b = l; // achromatic + }else{ + function hue2rgb(p, q, t){ + if(t < 0) t += 1; + if(t > 1) t -= 1; + if(t < 1/6) return p + (q - p) * 6 * t; + if(t < 1/2) return q; + if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; + return p; + } + + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hue2rgb(p, q, h + 1/3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1/3); + } + + return [r * 255, g * 255, b * 255]; +}; + +/** + * Converts an RGB color value to HSV. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSV_color_space. + * Assumes r, g, and b are contained in the set [0, 255] and + * returns h, s, and v in the set [0, 1]. + * + * @param Number r The red color value + * @param Number g The green color value + * @param Number b The blue color value + * @return Array The HSV representation + */ +Color.prototype.hsv = function (){ + r = this.r/255, g = this.g/255, b = this.b/255; + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, v = max; + + var d = max - min; + s = max == 0 ? 0 : d / max; + + if(max == min){ + h = 0; // achromatic + }else{ + switch(max){ + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + + return [h, s, v]; +}; + +/** + * Converts an HSV color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSV_color_space. + * Assumes h, s, and v are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param Number h The hue + * @param Number s The saturation + * @param Number v The value + * @return Array The RGB representation + */ +Color.prototype.hsvToRgb = function (h, s, v){ + var r, g, b; + + var i = Math.floor(h * 6); + var f = h * 6 - i; + var p = v * (1 - s); + var q = v * (1 - f * s); + var t = v * (1 - (1 - f) * s); + + switch(i % 6){ + case 0: r = v, g = t, b = p; break; + case 1: r = q, g = v, b = p; break; + case 2: r = p, g = v, b = t; break; + case 3: r = p, g = q, b = v; break; + case 4: r = t, g = p, b = v; break; + case 5: r = v, g = p, b = q; break; + } + + return [r * 255, g * 255, b * 255]; +}; + +/** + * Provide + */ +Color.prototype.lightColor = function() { + var hslArray = this.hsl(); + var h = Number(hslArray[0]); + var s = Number(hslArray[1]) * Desaturated; + var l = Luminosity; + var desA = this.hslToRgb(h, s, l) + return new Color(desA[0],desA[1],desA[2]); +}; + + +//==================================================================================== +// bzPage's methods + /** * Check for the presence of a keyword * @@ -235,7 +428,7 @@ bzPage.prototype.clickMouse = function(target) { this.doc.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null); $(target).get(0).dispatchEvent(localEvent); -} +}; /** * Add new keyword among the keywords. @@ -252,7 +445,7 @@ bzPage.prototype.addKeyword = function (str) { }else{ kwd.text(kwd.text() + ", " + str); } -} +}; /* Bugzilla functions.*/ @@ -265,7 +458,7 @@ bzPage.prototype.checkComments = function () { $("#comments .bz_comment", this.doc).each(function (i) { var email = $(".vcard a", this).text(); if (new RegExp(that.reporter).test(email)) { - $(this).css("background-color", ReporterColor); + $(this).css("background-color", ReporterColor.hex()); } }); }; @@ -277,6 +470,15 @@ bzPage.prototype.checkComments = function () { */ bzPage.prototype.isRHEL = function() { return /Red Hat Enterprise Linux/.test(this.product); +}; + + +bzPage.prototype.isTriaged = function() { + if (this.version > 11) { + return this.hasKeyword("Triaged"); + } else { + return $("#bug_status", this.doc).val().toUpperCase() != "NEW"; + } } /** @@ -289,7 +491,8 @@ bzPage.prototype.isRHEL = function() { * */ bzPage.prototype.setBranding = function () { - var brandColor = ""; + var brandColor = {}; + var TriagedColor = {}; if (this.isRHEL()) { if (this.its.length > 0) { @@ -307,24 +510,24 @@ 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.hex()); + $("#titles", this.doc).css("background", brandColor.hex()); // 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 + 'background-color' : SalmonPink.hex() }); } // Make it visible whether the bug has been triaged - if (this.hasKeyword("Triaged")) { - console.log("Nastav barvu"); + if (this.isTriaged()) { + var triagedColor = brandColor.lightColor(); $("#bz_field_status",this.doc).css({ 'background-image' : 'none', - 'background-color' : TriagedColor + 'background-color' : triagedColor.hex() }); } @@ -335,6 +538,17 @@ bzPage.prototype.setBranding = function () { "font-weight": "bolder", "text-decoration": "underline"}); } + + // mark suspicious components + // FIXME use https://bugzilla.redhat.com/show_bug.cgi?id=538818 for testing + console.log("component = " + this.component); + if (suspiciousComponents && (suspiciousComponents.indexOf(this.component) != -1)) { + $("#bz_component_edit_container",this.doc). + css({ + "background-color": "red", + "background-image": "none" + }); + } }; /** @@ -454,10 +668,10 @@ bzPage.prototype.addNewButton = function (originalLocation,newId,newLabel, commentString,nState,secPar,doSubmit,after) { var that = this; var commStr = ""; - if (doSubmit === null) { // missing optional argument + if (doSubmit === undefined) { // missing optional argument doSubmit = false; } - if (after === null) { // missing optional argument + if (after === undefined) { // missing optional argument after = false; } if (msgStrs[commentString]) { @@ -478,7 +692,7 @@ bzPage.prototype.addNewButton = function (originalLocation,newId,newLabel, if (!doSubmit) { newButton.get(0).setAttribute("type","button"); } -} +}; /** * Get attached Xorg.0.log, parse it and find the value of chip. @@ -541,7 +755,7 @@ bzPage.prototype.fillInChipMagic = function () { */ bzPage.prototype.queryInNewTab = function(text,component,product) { // Optional parameter - if (product == null) { + if (product == undefined) { product = "Fedora"; } var url = "https://bugzilla.redhat.com/buglist.cgi?query_format=advanced"; @@ -557,7 +771,7 @@ bzPage.prototype.queryInNewTab = function(text,component,product) { "&field0-0-2=status_whiteboard&type0-0-2=substring&value0-0-2="+text; } jetpack.tabs.open(url); -} +}; /** * Get the text to search for and prepare other things for the real executive @@ -571,7 +785,7 @@ bzPage.prototype.queryForSelection = function() { if (text.length > 0) { this.queryInNewTab(text, this.component); } -} +}; /** * Parse the row with the attachment @@ -625,7 +839,7 @@ bzPage.prototype.selectOption = function(id,label) { intEvent.initEvent("change", true, true); selectElement.get(0).dispatchEvent(intEvent); // $("#"+id,this.doc).value(label).change(); -} +}; /** * Check for the presence of a keyword @@ -638,7 +852,7 @@ bzPage.prototype.hasKeyword = function(str) { var kwd = $.trim($('#keywords',this.doc).val()); console.log("Keywords = " + kwd); return (RegExp(str).test(kwd)); -} +}; /** * Add accesskey to the particular element @@ -655,7 +869,7 @@ bzPage.prototype.fixElement = function (rootElement,beforeText,accKey,afterText) elem.attr("accesskey",accKey.toLowerCase()); elem.html(beforeText + "" + accKey + "" + afterText); return elem; -} +}; /** * Add XGL to the CC list @@ -676,7 +890,7 @@ bzPage.prototype.changeOwner = function(newAssignee) { $("#set_default_assignee",this.doc).removeAttr("checked"); $("#assigned_to", this.doc).val(newAssignee); $("#setdefaultassigneebutton", this.doc).css("display","none"); -} +}; /** * Set the bug to NEEDINFO state @@ -687,7 +901,7 @@ bzPage.prototype.changeOwner = function(newAssignee) { bzPage.prototype.setNeedinfoReporter = function() { $("#needinfo",this.doc).click(); this.selectOption("needinfo_role", "reporter"); -} +}; /** * Add text to the comment. @@ -704,7 +918,7 @@ bzPage.prototype.addTextToComment = function(string2BAdded) { commentTextarea.val(commentTextarea.val() + "\n\n"); } commentTextarea.val(commentTextarea.val() + string2BAdded); -} +}; /** * Return string with the ID for the external_id SELECT for @@ -721,7 +935,7 @@ bzPage.prototype.getBugzillaName = function(URLhostname) { bugzillaID = ""; } return bugzillaID; -} +}; /** * Generate URL of the bug on remote bugzilla @@ -737,7 +951,7 @@ bzPage.prototype.getWholeURL = function(selectValue,bugID) { returnURL = ""; } return returnURL; -} +}; /** * Sends XMLRPC request @@ -760,7 +974,7 @@ bzPage.prototype.sendRequest = function(url,data,method,callback) { data: data, onload: callback }); -} +}; /** * Callback function for the XMLRPC request @@ -780,7 +994,7 @@ bzPage.prototype.callBack = function(data,textStatus) { if (--this.reqCounter <= 0) { setTimeout(document.location.reload,1000); } -} +}; /** * Create XML-RPC message for updateAttachMimeType procedure with given parameters. @@ -807,10 +1021,11 @@ Update the attachment mime type of an attachment. The first argument is a data h }; */ bzPage.prototype.createXMLRPCMessage = function(login,password,attachId,mimeType,email) { - if (mimeType === null) { + console.log("mimeType = " + mimeType); + if (mimeType === undefined) { mimeType = "text/plain"; } - if (email === null) { + if (email === undefined) { email = false; }; var emailStr = email ? "0" : "1"; @@ -825,7 +1040,7 @@ bzPage.prototype.createXMLRPCMessage = function(login,password,attachId,mimeType {attachId} - mimeType + mime_type {mimeType} @@ -843,7 +1058,7 @@ bzPage.prototype.createXMLRPCMessage = function(login,password,attachId,mimeType ; return msg.toXMLString(); -} +}; /** * The worker function -- call XMLRPC to fix MIME type of the @@ -872,7 +1087,7 @@ bzPage.prototype.fixAttachById = function(id,type) { // spec is http://www.xmlrpc.com/spec // FIXME content-type MUST be text/xml this.reqCounter++; -} +}; bzPage.prototype.fixAllAttachments = function(list) { var tmpElem = {}; @@ -881,7 +1096,7 @@ bzPage.prototype.fixAllAttachments = function(list) { tmpElem = list[i]; this.fixAttachById(tmpElem[1]); } -} +}; /** * Create a button for fixing all bad attachments. @@ -899,7 +1114,7 @@ bzPage.prototype.createFixAllButton = function (list) { that.fixAllAttachments(list); }); return jQelem.get(0); -} +}; /** * @@ -919,14 +1134,14 @@ bzPage.prototype.addTextLink = function (row) { }); $("a",row).after(tElem).after("
"); -} +}; /** * */ bzPage.prototype.isOctetStream = function (element, index, array) { - return(inArray.indexOf(element[2]) != -1); -} + return(badMIMEArray.indexOf(element[2]) != -1); +}; /** * Add information about the upstream bug upstream, and closing it. @@ -971,7 +1186,7 @@ bzPage.prototype.addClosingUpstream = function() { } else { alert("No external bug specified among the External References!"); } -} +}; /** Insert a row of buttons before the marked element * @@ -986,7 +1201,7 @@ bzPage.prototype.generateToolBar = function(anchor,array) { butt['msg'], butt['string'], butt['state'], butt['parameter'], butt['submit']); } -} +}; /** * Generalized function for all actions @@ -1057,7 +1272,7 @@ bzPage.prototype.generalPurposeCureForAllDisease = function } else if (secondParameter == "NODEFAULTASSIGNEE") { $("#set_default_assignee", this.doc).removeAttr("checked"); } -} +}; /** * Main executable functioning actually building all buttons on the page -- -- cgit