aboutsummaryrefslogblamecommitdiffstats
path: root/data/lib/rhbzpage.js
blob: bca090184e7002fa24291a1b8e7102abef0d3617 (plain) (tree)
1
2
3
4


                                                     
                                                                      
















                                                                               
                                                       

                               










                                                                                              
      





                                                                
                                

                                                                                       


     






















                                                                              
                                  
                                   
                                               



                                        

                                                                   
              


     

                        





                                                       


                                                       

 





                                                                       

                                      
 
                                   
                                                         


                                                            
           
     
 

   
                                                            
   
                             




                                            

                                         
                        
 
                          
                                      

                                                                        



                                   
                                                     
 



                                                                             
                                                        
                       
















                                       
                                    




                                                                                       
     
 
 





                                                                                 




                                                                                 

                                               
 
                                                    
                                                                              
                    

     

                            
                                           

                                         
                                

                    
 
                                              
                                                                   





                                         
 
 
                                
   
  
   
                                         



                                                           
                                                                  




                                                                 
      
 


                                                                    


                                                                           
 
                            
                                                                        
 

                                                                    
 

                                                            

     
                                                            
                                                
                                
                                       
                                                            
               



                                                                        
                                                                         
                           

                                                                         

                                

                                                     


                                                                      
                             
                         
                     
                         


                 
                          
                                       
                                                       

                                     
     
 
 





                                                      


                                                                             
 
 




                                                        
                                   
                                                       

                                                                   
 
 
   
                                                         
   
                                     
                               
                    
                                                                           

                                                      
 
                                   



                                                                       
 


                                                                                  
 

                                                                                     
 
                                                                                                        
 

                                                                 









                                                                                             
 
                                                          



                                                                          
 
 
   
                                                                
  


                                              
   
                                            
                                                          
  
                                                                                   

                                                                                                  
                                                            
                     
  
 
 
   
                                                                           
  
                                             
               
   
                                   
                                                                                 
                                                    
                                                                                 
                    
     
 
                                                    
                                                


                                    

                                                                           
                                                     
 
                                                                            
                                                       

                                    
                                 
                                                  

                           
     
 





                                           


                                                                   

                  
 





                                                                

                                     
 








                                                                          
                        


                          





                                                              
                
                                 
         


                                                                                     
                
                                     



                                                                       
                                                                          

                       
                                                                              



                                                                              
                                                              

                                                           
                                                                                        




                                                                     

                                                                              



                                                       

                                                                                



                                        
                  

                                                                    
                                    


                                                                      
 
 
   













                                                                                   


                                                                             
   
                          



                                                                     




                                                                  
     
 

   
                                                          
  
               
   




                                                                             
 
                                                
                    



                                                                       
 
 




                                                  


                                        

                                                          
                                                               
                                                                               
           
     
 
 



                                                                        


                                                           


                                               
                                        


                       
                      








                                                                            

                                                                       




                                                        
     
 


                                                                   
                                                                 
 





                                                                              
                                     

               


                                                     
 
                                            
                       
                                       
                                                     



                                                                         



                                                        
               
         
     
 
 
                               
                         
 
                             




                                                
           
                                           



                                                         
 
                                                













                                                                                      

















                                                
                                           
 
 
   




                                                                             
                                       
                        
                                                       

                                               



                        
 









                                                                  




                                         

                 
 






















                                                                               


                                         






                              



                                                                     



                           
 
                                              
                                                                   





                                                
 

   





                                                  
                           

                                                  

                                                   
 






                                                                   
                               
                                                             
                                        
 
                                             
                                                       



                                               
                                                                    


                                          
                                                        
                            

                                           
                                             

                                                          

                                                     
                                                                            





                                                                     


                                                                        
                                                                    
                                                    


                                                         


                                                                                
 
 
                           
                                                                             

                                                                  

                                                                  
                                            
 



   
                               


                                                                              




                                               
                                                               
                    
                                                





                  
                                                                   




                                                                       
                                           





                                                      
                      
     
              

 
                     
                                                     
                                               
                                                                 
                       
 

                                      
 
                        



                                       
 
                                                               


                                                                    

                                       


                                                          
                   
 
                                                         

                                                           


                                         
                                                          


                                                                     
                                                             

                                        





                                                                           
                                   


                                                    
                                                       
                                     
                                                                                   
                                               
                                                  

         

                                                              





                                                                             

                                                   
                                                          
                                                     
                                                                         
                                


                                                                            


                          
                  

                                                      
                                                           
                                               
                                                                       
                            
                                              

                          
 


                                                                                 
                                 
                  
 
// Released under the MIT/X11 license
// http://www.opensource.org/licenses/mit-license.php
"use strict";
var titleParsedAttachment = "Part of the thread where crash happened";


// 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:
    */
    "AnalyzeXorgLogBacktrace": {
        re: "^\\s*(\\[[0-9 .]*\\])?\\s*(\\((EE|WW)\\)|.* [cC]hipset:.*)|\\s*Backtrace",
        func: analyzeXorg
    }
};

var ProfessionalProducts = [
    "Red Hat Enterprise Linux",
    "Red Hat Enterprise MRG"
];

// END OF CONSTANTS

var btSnippet = null;
var reqCounter = 0; // TODO should be probably a dict indexed by called method

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);
        break;
    default:
        console.error("Error: unknown RPC call " + msg.toSource());
        break;
    }
}

// RHBugzillaPage object

/**
 * Find default assignee based on the current component
 *
 * @return String what would be a default assignee if
 * we haven't set it up.
 */
function getDefaultAssignee() {
    return filterByRegexp(constantData.defaultAssignee,
        getComponent()).toLowerCase();
}

/**
 * Set default assignee
 *
 * @return none
 * sets this.defaultAssignee property according to defaultAssignee list
 */
function setDefaultAssignee() {
    var defAss = getDefaultAssignee();

    // Add setting default assignee
    if ((defAss.length > 0) && (defAss !== getOwner())) {
        createNewButton("bz_assignee_edit_container",true, {
            "name": "Def. Assignee",
            "assignee": "default"
        });
    }
}

/**
 * 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();
        break;
    case "sendBugUpstream":
        sendBugUpstream();
        break;
    case "markTriaged":
        markBugTriaged();
        break;
    case "chipMagic":
        fillInWhiteBoard(cmdParams);
        break;
    // If we don't have it here, call superclass method
    default:
        console.error("Unknown command:\n" + cmdLabel + "\nparameters:\n" + cmdParams);
        break;
    }
}

function addAttachmentCallback(resp) {
    var newAttachID = parseInt(resp.params.param.value.array.data.value.int, 10);
    console.log("attachID = " + newAttachID);
    // FIXME callback.call(param, newAttachID, data.length);
}

/**
 *
 * This has to stay in RHBugzillaPage because upstream doesn't have addAttachment
 * XML-RPC call yet.
 */
function addAttachment(data, callback, param) {
    var params = [];

    if (!constantData.passwordState.passAvailable) {
        console.error("addAttachment : No password, no XML-RPC calls; sorry");
        return null;
    }

    params.push(getBugNo());
    params.push({
        description: titleParsedAttachment,
        filename: "parsed-backtrace.txt",
        contenttype: "text/plain",
        data: window.btoa(data),
        nomail: true
    });

    postMessage(new Message("MakeXMLRPCall", {
        url: constantData.XMLRPCData[window.location.hostname].url,
        login: getLogin(),
        method: "bugzilla.addAttachment",
        params: params,
        callRPC: "AddAttachmentCallback"
    }));
    reqCounter++;
}

/* === Bugzilla functions === */
/**
 *
 */
function pasteBacktraceInComments(atts) {
    /*
    Let's comment it out, and we'll see if anything breaks.
    TODO This paragraph looks suspicous ... what is it?
    Does it belong to this function?
    var notedLabel = document.querySelector("label[for='newcc']");
    while (notedLabel.firstChild) {
        var node = notedLabel.removeChild(notedLabel.firstChild);
        notedLabel.parentNode.insertBefore(node, notedLabel);
    }
    notedLabel.parentNode.removeChild(notedLabel);
    */

    // FIXME BROKEN and its depending functions are even more broken
    return null;

    var abrtQueryURL = "https://bugzilla.redhat.com/buglist.cgi?" +
        "cmdtype=dorem&remaction=run&namedcmd=all%20NEW%20abrt%20crashes&"+
		  "sharer_id=74116";

    var mainTitle = document
            .getElementsByClassName("bz_alias_short_desc_container")[0];

    createDeadLink ("callAbrtQuery_link",
        "Abrt bugs", mainTitle, abrtQueryURL, [], false, null, "a");

    if (idContainsWord("cf_devel_whiteboard", 'btparsed')) {
        addStuffToTextBox('status_whiteboard', 'btparsed');
    }

    if (!(isTriaged() || idContainsWord("status_whiteboard",
            'btparsed') || (atts.length > 0))) {
        var btAttachments = atts
                .filter(function(att) {
                    return (/File: backtrace/.test(att[0]));
            });
        // TODO we need to go through all backtrace attachments, but
        // just the first one will do for now, we would need to do async
        // parsing
        btAttachments.forEach(function(x) {
            var attURL = "https://bugzilla.redhat.com/attachment.cgi?id="
                    + x[1];
            if ((!btSnippet) && // ???? FIXME
                    (!idContainsWord("status_whiteboard", 'btparsed'))) {
                Request({
                    url: attURL,
                    onComplete: function(response) {
                        if (response.status == 200) {
                            btSnippet = parseBacktrace(response.text);
                            if (btSnippet) {
                                addCheckShowLink(x,btSnippet);
                            }
                        }
                    }
                }).get();
            }
        }, this);
    }
    // Add "show BT" links
    if (parsedAttachments.length > 0) {
        this.parsedAttachments.forEach(function (att) {
            addShowParsedBTLink(att);
        });
    }
}

/**
 * Open new window with the content of the attachment.
 *
 * @param id Number of the attachment id
 * @return none
 */
function showAttachment(id) {
    postMessage(new Message("OpenURLinPanel",
        "https://" + window.location.hostname + "/attachment.cgi?id=" + id));
}

/**
 * add a link opening a window with the parsed backtrace
 *
 * @param att Attachment object
 */
function addShowParsedBTLink(att) {
    var elem = att[4].querySelector("td:last-of-type");
    createDeadLink("showParsedBacktraceWindow-" + att[1], "showBT",
        elem, showAttachment, att[1], true);
}

/**
 * Unfinished ... see above FIXME BROKEN AND DOESN'T WORK
 */
function addNewAttachmentRow(origAtt,
        newAttId, newAttSize) {
    var that = this;
    var oldAddBTLink = document.getElementById("attachBacktraceActivator");
    oldAddBTLink.parentNode.removeChild(oldAddBTLink);
    var newTRElem = origAtt[4].cloneNode(true);

    // fix number of the attachment
    Array.forEach(newTRElem.getElementsByTagName("a"), function (aEl) {
        aEl.setAttribute("href",
            aEl.getAttribute("href").replace(origAtt[1], newAttId));
    });

    var aElements = newTRElem.getElementsByTagName("a");
    aElements[0].setAttribute("name","parsed-backtrace.txt");
    aElements[0].getElementsByTagName("b")[0].textContent = titleParsedAttachment;

    var sizeSpan = newTRElem.getElementsByClassName("bz_attach_extra_info")[0];
    sizeSpan.textContent = "(" + (newAttSize / 1024).toFixed(2) + " KB, text/plain)";

    // aElements[1].textContent = new Date().toString(); TODO we should add eventually, but not pressing

    var vcardSpan = newTRElem.getElementsByClassName("vcard")[0];
    if (vcardSpan !== undefined) {
        var vcardSpanClassList = vcardSpan.classList;
        if (/@redhat\.com/.test(this.login) && !vcardSpanClassList.contains("redhat_user")) {
            vcardSpanClassList.add("redhat_user");
        }
        var vcardAElem = vcardSpan.getElementsByTagName("a")[0];
        vcardAElem.setAttribute("title", this.login);
        vcardAElem.setAttribute("href", "mailto:" + this.login);
        vcardAElem.className = "email";
        vcardAElem.innerHTML="<span class='fn'>" + this.login + "</span>";
    }

    var elem = newTRElem.querySelector("td:last-of-type");
    this.createDeadLink("showBacktrace", "show BT", elem,
        this.showAttachment, newAttId, false);

    origAtt[4].parentNode.insertBefore(newTRElem, origAtt[4].nextSibling);
}

/**
 * Add a link to create a new attachment with a parsed backtrace
 *
 * @param oldAtt Object with an attachment row
 * @param snippet String with parsed backtrace
 * @return none
 */
function addCheckShowLink(oldAtt, snippet) {
    var elem = oldAtt[4].querySelector("td:last-of-type");
/*
    createDeadLink("attachBacktraceActivator", "add parsed BT", elem, function(x) {
        // pass function and parameters as two separate parameters, the function to be called from
        // addAttachment
        addAttachment(snippet, addNewAttachmentRow, oldAtt);
        }, [], true);
*/
}

/**
 * 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.log("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]);
            });
        }, [], false, null, "f");
        badAttachments.forEach(function(x, i, a) {
            addTextLink(x);
        });
    }
}

/**
 * Is this bug a RHEL bug?
 *
 * @return Boolean true if it is a RHEL bug
 */
function isEnterprise() {
    var result = ProfessionalProducts.some(function(elem,idx,arr) {
        return new RegExp(elem).test(getProduct());
    });
    return result;
}

/**
 * Find out whether the bug is needed an attention of bugZappers
 *
 * @return Boolean whether the bug has been triaged or not
 */
function isTriaged() {
        return hasKeyword("Triaged");
}

/**
 * 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
 */
function setBranding() {
    var brandColor = {};
    var TriagedColor = {};

    var ITbutton = document.getElementById("cf_issuetracker");
    var its = ITbutton ? ITbutton.value.trim() : "";

    if (isEnterprise()) {
        if (its && (its.length > 0)) {
            brandColor = RHITColor;
        } else {
            brandColor = RHColor;
        }
    } else if (new RegExp("Fedora").test(document.getElementById("product").value)) {
        if (document.getElementById("version").value === "rawhide") {
            brandColor = RawhideColor;
        } else {
            brandColor = FedoraColor;
        }
    }

    // Comment each of the following lines to get only partial branding
    document.getElementsByTagName("body")[0].style.background = brandColor
            .toString()
            + " none";
    document.getElementById("titles").style.background = brandColor.toString()
            + " none";

    // Remove "Bug" from the title of the bug page, so we have more space with
    // plenty of tabs
    var titleElem = document.getElementsByTagName("title")[0];

    titleElem.textContent = titleElem.textContent.slice(4);
    var bodyTitleParent = document.getElementById("summary_alias_container").parentNode;
    var bodyTitleElem = bodyTitleParent.getElementsByTagName("b")[0];
    bodyTitleElem.textContent = bodyTitleElem.textContent.slice(4);

    // Make background-color of the body of bug salmon pink
    // for security bugs.
    if (hasKeyword("Security")) {
        document.getElementById("bugzilla-body").style.background = SalmonPink
                .toString() + ' none';
    }

    // Make it visible whether the bug has been triaged
    if (isTriaged()) {
        document.getElementById("bz_field_status").style.background = brandColor
                .lightColor().toString()
                + " none";
    }

    var compElems;
    if (config.suspiciousComponents
            && isInList(getComponent(), config.suspiciousComponents)
            && (compElems = document
                    .getElementById("bz_component_edit_container"))) {
        compElems.style.background = "red none";
    }
}

/**
 *
 */
function queryUpstreamCallback(text) {
    var searchData = filterByRegexp(constantData.queryUpstreamBug, getComponent());
    var urlBase = searchData.url;
    text = searchData.searchBy+":"+searchData.fillIn+" "+text.trim();
    if (searchData.fillIn == "$$$") {
        text = text.replace("$$$", getComponent());
    }
    text = encodeURIComponent(text).replace("%20","+");
    postMessage(new Message("OpenURLinTab", urlBase + text));
}

/**
 * Search simple query in the upstream bugzilla appropriate for the component
 *
 * @return none
 */
function queryUpstream() {
    if (!constantData.queryUpstreamBug) {
        alert("We don't have constantData.queryUpstreamBug set up!");
        return null;
    }
    var text = getSelection();
    if (!text) {
        postMessage(new Message("GetClipboard", "queryUpstream"));
    } else {
        queryUpstreamCallback(text);
    }
}

/**
 * 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;
    }

    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 RE
 * @param driverStr String with the driver name
 * @return None
 */
function fillInWhiteBoard(PCIidArrObj) {
    var outStr = "";
    var cardIDStr = "";
    var cardIDArr = [];
    var cardName = "";
    var PCIid = (PCIidArrObj.id[0] + "," + PCIidArrObj.id[1]).toUpperCase();

    if (PCIidArrObj.id[0].toLowerCase() == "10de") {
        cardName = PCIidArrObj.chipsetLine[2].replace(/\s*nvidia\s*/ig,"").
            replace('"','','g');
    } else {
        try {
            cardName = constantData.chipNames[PCIid][0];
        } catch (e if e instanceof TypeError)  {
            PCIid = PCIid.toLowerCase().replace(",",":");
            postMessage(new Message("SetClipboard", PCIid.toString()));
            alert("PCI ID " + PCIid + " is not known!");
            return ; // early termination
        } catch (e) {
            throw e;
        }
    }

    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");
}

function chipsetMagic (interestingLineArr) {
    // parse Xorg.0.log
    if (interestingLineArr.length >0) {
        var interestingArray = interestingLineArr[0];
        if (interestingArray.length > 1) {
            var interestingPCIID = interestingArray[1].trim().split(":");
            createNewButton("short_desc_nonedit_display", false, {
                "name": "Fill In",
                "chipMagic": {
                    "id": interestingPCIID,
                    "chipsetLine": interestingLineArr[1]
                },
            });
        }
    }
}

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!";
    }

    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) {
    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);
        });
    }
    var results = [];
    wholeLog.split("\n").
        forEach(function(line) {
            REarr.forEach(function (re, reIdx) {
                if (re.test(line)) {
                    results.push(re.exec(line));
                }
            });
        });
    logAnalyzeLogic[backMsg].func(results);
}

/**
 * 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 getBugzillaName(URLhostname) {
    var bugzillaID = "";
    var bzLabelNames = constantData.bugzillaLabelNames;
    if (bzLabelNames[URLhostname]) {
        bugzillaID = bzLabelNames[URLhostname];
    } else {
        bugzillaID = "";
    }
    return bugzillaID;
}

/**
 * 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, 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
    });

    postMessage(new Message("MakeXMLRPCall", {
        url: constantData.XMLRPCData[window.location.hostname].url,
        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) {
    var elemS = row[4].getElementsByTagName("td");
    var elem = elemS[elemS.length - 1];
    createDeadLink("addFix2TextLink", "text", elem,
            fixAttachById, row[1], "br");
}

/**
 * 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);
        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.log("No external bug specified among the External References!");
    }
}

function markBugTriaged() {
    // https://fedoraproject.org/wiki/BugZappers/Meetings/Minutes-2009-Oct-27
    // http://meetbot.fedoraproject.org/fedora-meeting/2009-11-24\
    // /fedora-meeting.2009-11-24-15.11.log.html
    // http://meetbot.fedoraproject.org/fedora-meeting/2009-11-24\
    // /fedora-meeting.2009-11-24-15.11.log.html
    addStuffToTextBox("keywords","Triaged");
}

/**
 *
 */
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 FillMagicDoneRE = new RegExp("^\\s*\\[[0-9a-zA-Z_]*\\]");
    var btSnippet = "";

    var signaturesCounter = 0;
    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();
    }

    // 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);

    var maintCCAddr = "";
    if (constantData.CCmaintainer) {
        maintCCAddr = filterByRegexp(constantData.CCmaintainer,
            getComponent())[0]; // filterByRegexp returns array, not string
    }

    // TODO Get compiz bugs as well
    if ((constantData.chipNames) &&
            (XorgLogAttList[0]) &&
            (!FillMagicDoneRE.test(getSummary())) &&
            (maintCCAddr === "xgl-maint@redhat.com")) {
        // Add find chip magic button
        var whiteboard_string = document.getElementById("status_whiteboard").value;
        if (!/card_/.test(whiteboard_string)) {
            fillInChipMagic(XorgLogAttList[0][1]);
        }
    }

    // we should make visible whether maintCCAddr is in CCList
    if (maintCCAddr && isInList(maintCCAddr, getCCList())) {
        var ccEditBoxElem = document.getElementById("cc_edit_area_showhide");
        ccEditBoxElem.style.color = "navy";
        ccEditBoxElem.style.fontWeight = "bolder";
        ccEditBoxElem.style.textDecoration = "underline";
    }

    // Take care of signature for Fedora bugzappers
    if (config.signature && config.signature.length > 0) {
        var signatureFedoraString = config.signature;
        document.forms.namedItem("changeform").addEventListener("submit",
                function(aEvt) {
                    if (signaturesCounter < 1) {
                        addStuffToTextBox("comment", signatureFedoraString);
                        signaturesCounter += 1;
                    }
                }, false);
    }
    setBranding();

    // set default assignee on change of the component
    var compElement = document.getElementById("component");
    if (compElement && (compElement.options)) {
        document.getElementById("component").addEventListener("change",
                function() {
                    changeAssignee("default");
                }, false);
    }

    // Uncheck "set default assignee" when the assignee is changed by other means
    document.getElementById("assigned_to").addEventListener("change",
        function() {
            changeAssignee(null);
        }, false);
}