/*jslint rhino: true, forin: true, onevar: false, browser: true, evil: true, laxbreak: true, undef: true, nomen: true, eqeqeq: false, bitwise: true, maxerr: 1000, immed: false, white: false, plusplus: false, regexp: false, undef: false */ // Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php // "use strict"; var preferences = require("preferences-service"); var prompts = require("prompts"); var clipboard = require("clipboard"); var tabs = require("tabs"); //var logger = require("logger"); var passUtils = require("passwords"); var Request = require("request").Request; var selfMod = require("self"); var urlMod = require("url"); var JSONURLDefault = "https://fedorahosted.org/released"+ "/bugzilla-triage-scripts/Config_data.json"; var BTSPrefNS = "bugzilla-triage.setting."; var BTSPassRealm = "BTSXMLRPCPass"; function Message(cmd, data) { console.log("Message: cmd = " + cmd + ", data = " + data); this.cmd = cmd; this.data = data; } function log(msg) { postMessage(new Message("LogMessage", msg)); } /** * parse XML object out of string working around various bugs in Gecko implementation * see https://developer.mozilla.org/en/E4X for more information * * @param inStr String with unparsed XML string * @return XML object */ function parseXMLfromString (inStuff) { // if (typeof inStuff !== 'string') In future we should recognize this.response // and get just .text property out of it. TODO var respStr = inStuff.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, ""); // bug 336551 return new XML(respStr); } /** * In case URL contains alias, not the real bug number, get the real bug no * from the XML representation. Sets correct value to this.bugNo. * * somewhere in RPC functions which need it, we should have * if (isNAN(parseInt(bugNo, 10))) { * getRealBugNo(bugNo, location, callback); * } * Or not */ function getRealBugNo(bugNo, location, callback) { console.log("We have to deal with bug aliased as " + this.bugNo); // https://bugzilla.redhat.com/show_bug.cgi?ctype=xml&id=serialWacom Request({ url: location.href+"&ctype=xml", onComplete: function(response) { if (response.status === 200) { var xmlRepr = parseXMLfromString(response.text); // TODO this is probably wrong, both XPath and .text attribute var bugID = parseInt(xmlRepr.bug.bug_id.text, 10); if (isNaN(bugID)) { throw new Error("Cannot get bug no. even from XML representation!"); } console.log("The real bug no. is " + bugID); callback(bugID) } } }).get(); } exports.getPassword = function getPassword(login, domain, callback) { var passPrompt = "Enter your Bugzilla password for fixing MIME attachment types"; var switchPrompt = "Do you want to switch off features requiring password completely"; var prefName = BTSPrefNS+"withoutPassowrd"; var domain = window.location.protocol + "//" + window.location.hostname; var pass = passUtils.getPassword(login, domain, BTSPassRealm); var retObject = { password: null, withoutPass: false }; // pass === null means no appropriate password in the storage if (!preferences.get(prefName,false) && (pass === null)) { passwordText = prompts.promptPassword(passPrompt); if (passwordText && passwordText.length > 0) { passUtils.setLogin(login, passwordText, domain, BTSPassRealm); retObject.password = passwordText; } else { var switchOff = prompts.promptYesNoCancel(switchPrompt); if (switchOff) { preferences.set(prefName,true); } retObject.withoutPass = switchOff; } } else { retObject.password = pass; } callback(new Message("RetPassword", retObject)); }; exports.changeJSONURL = function changeJSONURL() { var prfNm = BTSPrefNS+"JSONURL"; var url = preferences.get(prfNm,""); var reply = prompts.prompt("New location of JSON configuration file", url); if (reply) { preferences.set(prfNm, reply.trim()); // TODO Restartless add-on needs to resolve this. prompts.alert("For now, you should really restart Firefox!"); } }; /** * libbz.getInstalledPackages(msg.data, function (pkgsMsg) { worker.postMessage(pkgsMsg); */ exports.getInstalledPackages = function getInstalledPackages(location, config, callback) { var installedPackages = {}; var enabledPackages = []; if (typeof location == "string") { location = new urlMod.URL(location); } console.log("location = " + location); console.log("typeof location = " + typeof location); // Collect enabled packages per hostname (plus default ones) if (config.gJSONData && ("commentPackages" in config.gJSONData)) { if ("enabledPackages" in config.gJSONData.configData) { var epObject = config.gJSONData.configData.enabledPackages; if (location.host in epObject) { enabledPackages = enabledPackages.concat(epObject[location.host].split(/[,\s]+/)); } if ("any" in epObject) { enabledPackages = enabledPackages.concat(epObject.any.split(/[,\s]+/)); } } if ((enabledPackages.length === 1) && (enabledPackages[0] === "all")) { enabledPackages = []; for (var key in config.gJSONData.commentPackages) { enabledPackages.push(key); } } // TODO To be decided, whether we cannot just eliminate packages in // installedPackages and having it just as a plain list of all cmdObjects. enabledPackages.forEach(function (pkg, idx, arr) { if (pkg in config.gJSONData.commentPackages) { installedPackages[pkg] = config.gJSONData.commentPackages[pkg]; } }); } // Expand commentIdx properties into full comments var cmdObj = {}; for (var pkgKey in installedPackages) { for (var cmdObjKey in installedPackages[pkgKey]) { cmdObj = installedPackages[pkgKey][cmdObjKey]; if ("commentIdx" in cmdObj) { cmdObj.comment = config.gJSONData.commentStrings[cmdObj.commentIdx]; delete cmdObj.commentIdx; } } } callback(new Message("CreateButtons", { instPkgs: installedPackages, constData: config.constantData, kNodes: config.gJSONData.configData.killNodes })); }; exports.getClipboard = function getClipboard(command, cb) { cb(new Message("RetClipboard", { text: clipboard.get(), cmd: command })); }; exports.openURLinNewTab = function openURLinNewTab(urlStr) { tabs.open({ url: urlStr, inBackground: true, onReady: function (t) { t.activate(); } }); }; exports.initialize = function initialize(config, callback) { var prefName = BTSPrefNS+"JSONURL"; var urlStr = ""; if (preferences.isSet(prefName)) { urlStr = preferences.get(prefName); } else { urlStr = JSONURLDefault; preferences.set(prefName, JSONURLDefault); } // Randomize URL to avoid caching // TODO see https://fedorahosted.org/bugzilla-triage-scripts/ticket/21 // for more thorough discussion and possible further improvement urlStr += (urlStr.match(/\?/) == null ? "?" : "&") + (new Date()).getTime(); Request({ url: urlStr, onComplete: function (response) { if (response.status == 200) { config.gJSONData = response.json; // Get additional tables if ("downloadJSON" in config.gJSONData.configData) { var URLsList = config.gJSONData.configData.downloadJSON; var dwnldObj = ""; URLsList.forEach(function (arr) { var title = arr[0]; var url = arr[1]; Request({ url: url, onComplete: function(response) { if (response.status == 200) { config.gJSONData.constantData[title] = response.json; } } }).get(); }); } // config.logger = new logger.Logger(JSON.parse(self.data.load("bugzillalabelAbbreviations.json"))); config.matches = config.gJSONData.configData.matches; config.skipMatches = config.matches.map(function(x) { return x.replace("show_bug.cgi.*","((process|post)_bug|attachment)\.cgi$"); }); config.objConstructor = {}; // var bzType = config.gJSONData.configData.objectStyle; // if (bzType === "RH") { // config.objConstructor = require("rhbzpage").RHBugzillaPage; // } else if (bzType === "MoFo") { // } // config.objConstructor = require("mozillabzpage").MozillaBugzilla; // callback(config); config.constantData = {}; // TODO this is important and missing if ("constantData" in config.gJSONData) { config.constantData = config.gJSONData.constantData; config.constantData.queryUpstreamBug = JSON.parse( selfMod.data.load("queryUpstreamBug.json")); config.constantData.XMLRPCData = JSON.parse( selfMod.data.load("XMLRPCdata.json")); } if ("CCmaintainer" in config.constantData) { config.defBugzillaMaintainerArr = config.constantData.CCmaintainer; } if ("suspiciousComponents" in config.gJSONData.configData) { config.suspiciousComponents = config.gJSONData.configData.suspiciousComponents; } if ("XorgLogAnalysis" in config.gJSONData.configData) { config.xorglogAnalysis = config.gJSONData.configData.XorgLogAnalysis; } if ("submitsLogging" in config.gJSONData.configData && config.gJSONData.configData.submitsLogging) { // config.log = config.logger; // FIXME this.setUpLogging(); } } callback(); } }).get(); }