<commit_before>/*
Potential problems:
domains loaded on subsequent calls, self signed ssl, multi-process firefox support

Improvements:
Modularize
*/

let { Cc, Ci, Cu } = require('chrome');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import("resource://gre/modules/FileUtils.jsm");

const windowUtils = require("sdk/window/utils");
const notifications = require("sdk/notifications");
const CategoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);

var { indexedDB, IDBKeyRange } = require('sdk/indexed-db');
var { ToggleButton } = require('sdk/ui/button/toggle');
var prefs = require('sdk/simple-prefs');
var sdkPanels = require("sdk/panel");
var self = require("sdk/self");
var tabs = require("sdk/tabs");
var ui = require("sdk/ui");

var recentLocationChange = 0;
var gBrowser = windowUtils.getMostRecentBrowserWindow().getBrowser();

var onLocationChange = function(){
    recentLocationChange = 1;
    var data = {"name":"","times_seen":""};
    updatePanel(data);
};

var onSecurityChange = function(webProgress, request, state){
  var currentBrowser = gBrowser.selectedBrowser;
  var serverCert = currentBrowser.securityUI.SSLStatus.serverCert;
  var rootInfo = getRootInfo(serverCert);
  if (rootInfo) {
      getFromDatabase(rootInfo.sha256Fingerprint, function (data) {
          if (typeof(data) == 'undefined') {
              data = {};
              data.fingerprint = rootInfo.sha256Fingerprint;
              data.name = rootInfo.issuerOrganization;
              data.times_seen = 1;
              if (prefs.prefs['alert_on_new']) {
                  notifications.notify({
                      title: "New CA",
                      text: "The CA " + rootInfo.issuerOrganization + " was seen for the first time"
                  });
              }
          } else if(request && recentLocationChange){
              data.times_seen += 1;
          }
          recentLocationChange = 0;
          updateCA(data);
          updatePanel(data);
      });
  }
};

var getRootInfo = function(serverCert){
  if(serverCert.issuer){
    if(serverCert.issuer.isBuiltInRoot){
      return {'issuerOrganization': serverCert.issuer.issuerOrganization,'sha256Fingerprint': serverCert.issuer.sha256Fingerprint};
    }
    return getRootInfo(serverCert.issuer);
  }
  return false;
};

var updateListener = {
  onStateChange:    function(){},
  onProgressChange: function(){},
  onLocationChange: onLocationChange,
  onStatusChange:   function(){},
  onSecurityChange: onSecurityChange
};

gBrowser.addProgressListener(updateListener);

/* -- Panel -- */
var panelButton = ToggleButton({
  id: "panel-button",
  label: "CA Info",
  icon: "./icons/icon.png",
  onChange: handleChange
});

var CAPanel = sdkPanels.Panel({
  contentURL: "./panel/panel.html",
  contentScriptFile: "./panel/panel-content-script.js",
  onHide: handleHide
});

function handleChange(state) {
  if (state.checked) {
      CAPanel.show({
      position: panelButton
    });
  }
}

function handleHide() {
  panelButton.state('window', {checked: false});
}

function updatePanel(data){
    CAPanel.port.emit("changeInfo", {"name": data.name, "times_seen": data.times_seen});
}

CAPanel.port.on("openStatsPage",function(){
    openStats();
});

/* -- Stats Tab -- */
function openStats() {
    tabs.open({
        url: self.data.url("stats/stats.html"),
        onLoad: function(tab){
            var worker = tab.attach({
                contentScriptFile: "./stats/stats-content-script.js"
            });
            getAllFromDatabase(function(data){
                data.sort(function(a, b){
                    return b.times_seen-a.times_seen
                })
                worker.port.emit("populateStatsTable",data);
            });
        }
    });
}

/* -- IndexedDB -- */
var database = {};

database.onerror = function(e) {
    console.error(e.value)
};

function openDB(version) {
    var request = indexedDB.open("care", version);

    request.onupgradeneeded = function(e) {
        var db = e.target.result;
        e.target.transaction.onerror = database.onerror;

        if(db.objectStoreNames.contains("CAs")) {
            db.deleteObjectStore("CAs");
        }

        var store = db.createObjectStore("CAs",
            {
                keyPath: "fingerprint",
            });
    };

    request.onsuccess = function(e) {
        database.db = e.target.result;
    };

    request.onerror = database.onerror;
}
function updateCA(data) {
    var db = database.db;
    var trans = db.transaction(["CAs"], "readwrite");
    var store = trans.objectStore("CAs");
    var request = store.put({
        "fingerprint": data.fingerprint,
        "name": data.name,
        "times_seen": data.times_seen
    });
    request.onerror = database.onerror;
}

function getFromDatabase(fingerprint,callback){
    var db = database.db;
    var transaction = db.transaction(["CAs"], "readwrite");
    var objectStore = transaction.objectStore("CAs");
    var request = objectStore.get(fingerprint);
    request.onerror = database.onerror;
    request.onsuccess = function(event) {
        var data = event.target.result;
        return callback(data);
    };
}
function getAllFromDatabase(callback){
    var db = database.db;
    var transaction = db.transaction(["CAs"], "readwrite");
    var objectStore = transaction.objectStore("CAs");
    var request = objectStore.getAll();
    request.onerror = database.onerror;
    request.onsuccess = function(event) {
        var data = event.target.result;
        return callback(data);
    };
}

openDB(1);<commit_msg>checking for location flags before setting location changed<commit_after>/*
Potential problems:
domains loaded on subsequent calls, self signed ssl, multi-process firefox support

Improvements:
Modularize
*/

let { Cc, Ci, Cu } = require('chrome');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import("resource://gre/modules/FileUtils.jsm");

const windowUtils = require("sdk/window/utils");
const notifications = require("sdk/notifications");
const CategoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);

var { indexedDB, IDBKeyRange } = require('sdk/indexed-db');
var { ToggleButton } = require('sdk/ui/button/toggle');
var prefs = require('sdk/simple-prefs');
var sdkPanels = require("sdk/panel");
var self = require("sdk/self");
var tabs = require("sdk/tabs");
var ui = require("sdk/ui");

var recentLocationChange = 0;
var gBrowser = windowUtils.getMostRecentBrowserWindow().getBrowser();

var onLocationChange = function(webProgress, request,location,flags){
    if(flags !== 1) {
        recentLocationChange = 1;
        var data = {"name": "", "times_seen": ""};
        updatePanel(data);
    }
};

var onSecurityChange = function(webProgress, request, state){
  var currentBrowser = gBrowser.selectedBrowser;
  var serverCert = currentBrowser.securityUI.SSLStatus.serverCert;
  var rootInfo = getRootInfo(serverCert);
  if (rootInfo) {
      getFromDatabase(rootInfo.sha256Fingerprint, function (data) {
          if (typeof(data) == 'undefined') {
              data = {};
              data.fingerprint = rootInfo.sha256Fingerprint;
              data.name = rootInfo.issuerOrganization;
              data.times_seen = 1;
              if (prefs.prefs['alert_on_new']) {
                  notifications.notify({
                      title: "New CA",
                      text: "The CA " + rootInfo.issuerOrganization + " was seen for the first time"
                  });
              }
          } else if(request && recentLocationChange){
              data.times_seen += 1;
          }
          recentLocationChange = 0;
          updateCA(data);
          updatePanel(data);
      });
  }
};

var getRootInfo = function(serverCert){
  if(serverCert.issuer){
    if(serverCert.issuer.isBuiltInRoot){
      return {'issuerOrganization': serverCert.issuer.issuerOrganization,'sha256Fingerprint': serverCert.issuer.sha256Fingerprint};
    }
    return getRootInfo(serverCert.issuer);
  }
  return false;
};

var updateListener = {
  onStateChange:    function(){},
  onProgressChange: function(){},
  onLocationChange: onLocationChange,
  onStatusChange:   function(){},
  onSecurityChange: onSecurityChange
};

gBrowser.addProgressListener(updateListener);

/* -- Panel -- */
var panelButton = ToggleButton({
  id: "panel-button",
  label: "CA Info",
  icon: "./icons/icon.png",
  onChange: handleChange
});

var CAPanel = sdkPanels.Panel({
  contentURL: "./panel/panel.html",
  contentScriptFile: "./panel/panel-content-script.js",
  onHide: handleHide
});

function handleChange(state) {
  if (state.checked) {
      CAPanel.show({
      position: panelButton
    });
  }
}

function handleHide() {
  panelButton.state('window', {checked: false});
}

function updatePanel(data){
    CAPanel.port.emit("changeInfo", {"name": data.name, "times_seen": data.times_seen});
}

CAPanel.port.on("openStatsPage",function(){
    openStats();
});

/* -- Stats Tab -- */
function openStats() {
    tabs.open({
        url: self.data.url("stats/stats.html"),
        onLoad: function(tab){
            var worker = tab.attach({
                contentScriptFile: "./stats/stats-content-script.js"
            });
            getAllFromDatabase(function(data){
                data.sort(function(a, b){
                    return b.times_seen-a.times_seen
                })
                worker.port.emit("populateStatsTable",data);
            });
        }
    });
}

/* -- IndexedDB -- */
var database = {};

database.onerror = function(e) {
    console.error(e.value)
};

function openDB(version) {
    var request = indexedDB.open("care", version);

    request.onupgradeneeded = function(e) {
        var db = e.target.result;
        e.target.transaction.onerror = database.onerror;

        if(db.objectStoreNames.contains("CAs")) {
            db.deleteObjectStore("CAs");
        }

        var store = db.createObjectStore("CAs",
            {
                keyPath: "fingerprint",
            });
    };

    request.onsuccess = function(e) {
        database.db = e.target.result;
    };

    request.onerror = database.onerror;
}
function updateCA(data) {
    var db = database.db;
    var trans = db.transaction(["CAs"], "readwrite");
    var store = trans.objectStore("CAs");
    var request = store.put({
        "fingerprint": data.fingerprint,
        "name": data.name,
        "times_seen": data.times_seen
    });
    request.onerror = database.onerror;
}

function getFromDatabase(fingerprint,callback){
    var db = database.db;
    var transaction = db.transaction(["CAs"], "readwrite");
    var objectStore = transaction.objectStore("CAs");
    var request = objectStore.get(fingerprint);
    request.onerror = database.onerror;
    request.onsuccess = function(event) {
        var data = event.target.result;
        return callback(data);
    };
}
function getAllFromDatabase(callback){
    var db = database.db;
    var transaction = db.transaction(["CAs"], "readwrite");
    var objectStore = transaction.objectStore("CAs");
    var request = objectStore.getAll();
    request.onerror = database.onerror;
    request.onsuccess = function(event) {
        var data = event.target.result;
        return callback(data);
    };
}

openDB(1);<|endoftext|>


<commit_before>'use babel'
const FS = require('fs')
const Path = require('path')
const {View} = require('./view')
const callsite = require('callsite')
import {guessName, installPackages, packagesToInstall} from './helpers'

// Renamed for backward compatibility
if (typeof window.__steelbrain_package_deps === 'undefined') {
  window.__steelbrain_package_deps = new Set()
}

export function install(name = null, enablePackages = false) {
  if (!name) {
    const filePath = require('sb-callsite').capture()[1].file
    name = guessName(filePath)
    if (!name) {
      console.log(`Unable to get package name for file: ${filePath}`)
      return Promise.resolve()
    }
  }
  const {toInstall, toEnable} = packagesToInstall(name)
  let promise = Promise.resolve()

  if (enablePackages && toEnable.length) {
    promise = toEnable.reduce(function(promise, name) {
      atom.packages.enablePackage(name)
      return atom.packages.activatePackage(name)
    }, promise)
  }
  if (toInstall.length) {
    const view = new View(name, toInstall)
    promise = Promise.all([view.show(), promise]).then(function() {
      return installPackages(toInstall, function(name, status) {
        if (status) {
          view.advance()
        } else {
          atom.notifications.addError(`Error Installing ${name}`, {detail: 'Something went wrong. Try installing this package manually.'})
        }
      })
    })
  }

  return promise
}
<commit_msg>:fire: Remove callsite import<commit_after>'use babel'
const FS = require('fs')
const Path = require('path')
const {View} = require('./view')
import {guessName, installPackages, packagesToInstall} from './helpers'

// Renamed for backward compatibility
if (typeof window.__steelbrain_package_deps === 'undefined') {
  window.__steelbrain_package_deps = new Set()
}

export function install(name = null, enablePackages = false) {
  if (!name) {
    const filePath = require('sb-callsite').capture()[1].file
    name = guessName(filePath)
    if (!name) {
      console.log(`Unable to get package name for file: ${filePath}`)
      return Promise.resolve()
    }
  }
  const {toInstall, toEnable} = packagesToInstall(name)
  let promise = Promise.resolve()

  if (enablePackages && toEnable.length) {
    promise = toEnable.reduce(function(promise, name) {
      atom.packages.enablePackage(name)
      return atom.packages.activatePackage(name)
    }, promise)
  }
  if (toInstall.length) {
    const view = new View(name, toInstall)
    promise = Promise.all([view.show(), promise]).then(function() {
      return installPackages(toInstall, function(name, status) {
        if (status) {
          view.advance()
        } else {
          atom.notifications.addError(`Error Installing ${name}`, {detail: 'Something went wrong. Try installing this package manually.'})
        }
      })
    })
  }

  return promise
}
<|endoftext|>


<commit_before>define(["moment", "router", "leaflet", "gui", "numeral"],
function (moment, Router, L, GUI, numeral) {
  return function (config) {
    function handleData(data) {
      var dataNodes = {}
      dataNodes.nodes = []
      var dataGraph = {}
      dataGraph.batadv = {}
      dataGraph.batadv.nodes = []
      dataGraph.batadv.links = []

      function rearrangeLinks(d) {
        d.source += dataGraph.batadv.nodes.length
        d.target += dataGraph.batadv.nodes.length
      }

      for (var i = 0; i < data.length; ++i) {
        var vererr
        if(i % 2)
          if (data[i].version !== 1) {
            vererr = "Unsupported graph version: " + data[i].version
            console.log(vererr) //silent fail
          } else {
            data[i].batadv.links.forEach(rearrangeLinks)
            dataGraph.batadv.nodes = dataGraph.batadv.nodes.concat(data[i].batadv.nodes)
            dataGraph.batadv.links = dataGraph.batadv.links.concat(data[i].batadv.links)
            dataGraph.timestamp = data[i].timestamp
          }
        else
          if (data[i].version !== 2) {
            vererr = "Unsupported nodes version: " + data[i].version
            console.log(vererr) //silent fail
          } else {
            dataNodes.nodes = dataNodes.nodes.concat(data[i].nodes)
            dataNodes.timestamp = data[i].timestamp
          }
      }

      var nodes = dataNodes.nodes.filter( function (d) {
        return "firstseen" in d && "lastseen" in d
      })

      nodes.forEach( function(node) {
        node.firstseen = moment.utc(node.firstseen).local()
        node.lastseen = moment.utc(node.lastseen).local()
      })

      var now = moment()
      var age = moment(now).subtract(config.maxAge, "days")

      var newnodes = limit("firstseen", age, sortByKey("firstseen", nodes).filter(online))
      var lostnodes = limit("lastseen", age, sortByKey("lastseen", nodes).filter(offline))

      var graphnodes = {}

      dataNodes.nodes.forEach( function (d) {
        graphnodes[d.nodeinfo.node_id] = d
      })

      var graph = dataGraph.batadv

      graph.nodes.forEach( function (d) {
        if (d.node_id in graphnodes)
          d.node = graphnodes[d.node_id]
      })

      graph.links.forEach( function (d) {
        d.source = graph.nodes[d.source]

        if (graph.nodes[d.target].node)
          d.target = graph.nodes[d.target]
        else
          d.target = undefined
      })

      var links = graph.links.filter( function (d) {
        return d.target !== undefined
      })

      links.forEach( function (d) {
        var unknown = (d.source.node === undefined)
        var ids
        if (unknown)
          ids = [d.source.id.replace(/:/g, ""), d.target.node.nodeinfo.node_id]
        else
          ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id]
        d.id = ids.join("-")

        if (unknown ||
            !d.source.node.nodeinfo.location ||
            !d.target.node.nodeinfo.location ||
            isNaN(d.source.node.nodeinfo.location.latitude) ||
            isNaN(d.source.node.nodeinfo.location.longitude) ||
            isNaN(d.target.node.nodeinfo.location.latitude) ||
            isNaN(d.target.node.nodeinfo.location.longitude))
          return

        d.latlngs = []
        d.latlngs.push(L.latLng(d.source.node.nodeinfo.location.latitude, d.source.node.nodeinfo.location.longitude))
        d.latlngs.push(L.latLng(d.target.node.nodeinfo.location.latitude, d.target.node.nodeinfo.location.longitude))

        d.distance = d.latlngs[0].distanceTo(d.latlngs[1])
      })

      nodes.forEach( function (d) {
        d.neighbours = []
      })

      links.forEach( function (d) {
        if (d.type === "tunnel")
          d.type = "VPN"
        else if (d.type === "wireless")
          d.type = "Wifi"
        else if (d.type === "other")
          d.type = "Kabel"
        else
          d.type = "N/A"
        var unknown = (d.source.node === undefined)
        if (unknown) {
          d.target.node.neighbours.push({ id: d.source.id, link: d, incoming: true })
          return
        }
        d.source.node.neighbours.push({ node: d.target.node, link: d, incoming: false })
        d.target.node.neighbours.push({ node: d.source.node, link: d, incoming: true })
        if (d.type !== "VPN")
          d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1
      })

      links.sort( function (a, b) {
        return b.tq - a.tq
      })

      return { now: now,
               timestamp: moment.utc(dataNodes.timestamp).local(),
               nodes: {
                 all: nodes,
                 new: newnodes,
                 lost: lostnodes
               },
               graph: {
                 links: links,
                 nodes: graph.nodes
               }
             }
    }

    numeral.language("de")
    moment.locale("de")

    var router = new Router()

    var urls = []

    if (typeof config.dataPath === "string" || config.dataPath instanceof String)
      config.dataPath = [config.dataPath]

    for (var i in config.dataPath) {
      urls.push(config.dataPath[i] + "nodes.json")
      urls.push(config.dataPath[i] + "graph.json")
    }

    function update() {
      return Promise.all(urls.map(getJSON))
                    .then(handleData)
    }

    update()
      .then(function (d) {
        var gui = new GUI(config, router)
        gui.setData(d)
        router.setData(d)
        router.start()

        window.setInterval(function () {
          update().then(function (d) {
            gui.setData(d)
            router.setData(d)
          })
        }, 60000)
      })
      .catch(function (e) {
        document.body.textContent = e
        console.log(e)
      })
  }
})
<commit_msg>main: unseen nodes are online<commit_after>define(["moment", "router", "leaflet", "gui", "numeral"],
function (moment, Router, L, GUI, numeral) {
  return function (config) {
    function handleData(data) {
      var dataNodes = {}
      dataNodes.nodes = []
      var dataGraph = {}
      dataGraph.batadv = {}
      dataGraph.batadv.nodes = []
      dataGraph.batadv.links = []

      function rearrangeLinks(d) {
        d.source += dataGraph.batadv.nodes.length
        d.target += dataGraph.batadv.nodes.length
      }

      for (var i = 0; i < data.length; ++i) {
        var vererr
        if(i % 2)
          if (data[i].version !== 1) {
            vererr = "Unsupported graph version: " + data[i].version
            console.log(vererr) //silent fail
          } else {
            data[i].batadv.links.forEach(rearrangeLinks)
            dataGraph.batadv.nodes = dataGraph.batadv.nodes.concat(data[i].batadv.nodes)
            dataGraph.batadv.links = dataGraph.batadv.links.concat(data[i].batadv.links)
            dataGraph.timestamp = data[i].timestamp
          }
        else
          if (data[i].version !== 2) {
            vererr = "Unsupported nodes version: " + data[i].version
            console.log(vererr) //silent fail
          } else {
            dataNodes.nodes = dataNodes.nodes.concat(data[i].nodes)
            dataNodes.timestamp = data[i].timestamp
          }
      }

      var nodes = dataNodes.nodes.filter( function (d) {
        return "firstseen" in d && "lastseen" in d
      })

      nodes.forEach( function(node) {
        node.firstseen = moment.utc(node.firstseen).local()
        node.lastseen = moment.utc(node.lastseen).local()
      })

      var now = moment()
      var age = moment(now).subtract(config.maxAge, "days")

      var newnodes = limit("firstseen", age, sortByKey("firstseen", nodes).filter(online))
      var lostnodes = limit("lastseen", age, sortByKey("lastseen", nodes).filter(offline))

      var graphnodes = {}

      dataNodes.nodes.forEach( function (d) {
        graphnodes[d.nodeinfo.node_id] = d
      })

      var graph = dataGraph.batadv

      graph.nodes.forEach( function (d) {
        if (d.node_id in graphnodes) {
          d.node = graphnodes[d.node_id]
          if (d.unseen) {
            d.node.flags.online = true
            d.node.flags.unseen = true
          }
        }
      })

      graph.links.forEach( function (d) {
        d.source = graph.nodes[d.source]

        if (graph.nodes[d.target].node)
          d.target = graph.nodes[d.target]
        else
          d.target = undefined
      })

      var links = graph.links.filter( function (d) {
        return d.target !== undefined
      })

      links.forEach( function (d) {
        var unknown = (d.source.node === undefined)
        var ids
        if (unknown)
          ids = [d.source.id.replace(/:/g, ""), d.target.node.nodeinfo.node_id]
        else
          ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id]
        d.id = ids.join("-")

        if (unknown ||
            !d.source.node.nodeinfo.location ||
            !d.target.node.nodeinfo.location ||
            isNaN(d.source.node.nodeinfo.location.latitude) ||
            isNaN(d.source.node.nodeinfo.location.longitude) ||
            isNaN(d.target.node.nodeinfo.location.latitude) ||
            isNaN(d.target.node.nodeinfo.location.longitude))
          return

        d.latlngs = []
        d.latlngs.push(L.latLng(d.source.node.nodeinfo.location.latitude, d.source.node.nodeinfo.location.longitude))
        d.latlngs.push(L.latLng(d.target.node.nodeinfo.location.latitude, d.target.node.nodeinfo.location.longitude))

        d.distance = d.latlngs[0].distanceTo(d.latlngs[1])
      })

      nodes.forEach( function (d) {
        d.neighbours = []
      })

      links.forEach( function (d) {
        if (d.type === "tunnel")
          d.type = "VPN"
        else if (d.type === "wireless")
          d.type = "Wifi"
        else if (d.type === "other")
          d.type = "Kabel"
        else
          d.type = "N/A"
        var unknown = (d.source.node === undefined)
        if (unknown) {
          d.target.node.neighbours.push({ id: d.source.id, link: d, incoming: true })
          return
        }
        d.source.node.neighbours.push({ node: d.target.node, link: d, incoming: false })
        d.target.node.neighbours.push({ node: d.source.node, link: d, incoming: true })
        if (d.type !== "VPN")
          d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1
      })

      links.sort( function (a, b) {
        return b.tq - a.tq
      })

      return { now: now,
               timestamp: moment.utc(dataNodes.timestamp).local(),
               nodes: {
                 all: nodes,
                 new: newnodes,
                 lost: lostnodes
               },
               graph: {
                 links: links,
                 nodes: graph.nodes
               }
             }
    }

    numeral.language("de")
    moment.locale("de")

    var router = new Router()

    var urls = []

    if (typeof config.dataPath === "string" || config.dataPath instanceof String)
      config.dataPath = [config.dataPath]

    for (var i in config.dataPath) {
      urls.push(config.dataPath[i] + "nodes.json")
      urls.push(config.dataPath[i] + "graph.json")
    }

    function update() {
      return Promise.all(urls.map(getJSON))
                    .then(handleData)
    }

    update()
      .then(function (d) {
        var gui = new GUI(config, router)
        gui.setData(d)
        router.setData(d)
        router.start()

        window.setInterval(function () {
          update().then(function (d) {
            gui.setData(d)
            router.setData(d)
          })
        }, 60000)
      })
      .catch(function (e) {
        document.body.textContent = e
        console.log(e)
      })
  }
})
<|endoftext|>


<commit_before>/*
   Jooks
   Copyright : 2014
   Contributor : ppalludan
*/
(function() {
	var jook = this;

	// references
	jook.options = require('./options');
	jook.repositories = new Array();

	jook.main = function(args, cwd) {
		var program = require('commander');
		var colors = require('colors');
		var pjson = require('../package.json');

		// Process program arguments
		program.version(pjson.version)
	      .option('-p, --port [number]', 'Port Number (default: ' + jook.options.port)
	      .option('-c, --config [filename]', 'Configuration Filename (default: ' + jook.options.files.config);

		program.on('--help', function(){
	      console.log('  Examples:');
	      console.log('');
	      console.log('    jook --help');
	      console.log('    jook --p 9001');
	      console.log('');
	    });
	    program.parse(args);

	 	if (program.config && program.config!=true) {
	 		jook.options.files.config = program.config;
	 	}

   	 	jook.readConfig(jook.options, cwd);

	 	// Set the port if none present
	 	if (!isNaN(parseInt(program.port,10))) {
			jook.options.port = parseInt(program.port, 10);
	 	}

	 	// Start the webserver to handle the webhooks
		jook.startServer();

		// writing out the status for the repositories
		console.log('['.grey +('Jook v ' + program._version + ' running').cyan + ']'.grey + ' ' +
			'['.grey + ('Port: ' + jook.options.port + ', config: ' + jook.options.files.config).cyan + ']'.grey);

		jook.repositories.map(function(rep) {
			console.log('\tRepository: ' + rep.name);
		})
	}

	jook.startServer = function(options) {
		var http = require('http');

		var server = http.createServer(jook.handleRequest).listen(jook.options.port);
	}

	jook.handleRequest = function(req, res) {
		if (req.method == 'POST') {
			var payLoad = '';

			req.on('data', function(chunk) {
				console.log('data');
				payLoad += chunk;
			});

			req.on('end', function() {
				jook.offLoad(JSON.parse(payLoad), function(err) {

					if (err) {
						res.writeHead(500, {'Content-Type':'application/json'});
						res.write('err: ' + err);
					} else {
						res.writeHead(200, {'Content-Type':'application/json'});
						res.write('ok');
					}
					res.end();
				});
			});
		} else {
			res.writeHead(200, {'Content-Type':'application/json'});
            res.write('yes hello?');
			res.end();
		}
	}

	// Handle the webhook payload
	// callback = function(err)
	jook.offLoad = function(payLoad, callback) {
		var exec = require('child_process').exec;

		function cbError(err) {
			console.log(err);
			callback(err);
		}

		if (payLoad == null || payLoad.repository == null) {
			cbError('missing repository in payload');
			return;
		}

		var repository = jook.getRepositoryByName(payLoad.repository.name);
		if (repository == null) {
			console.log('dont know repository payload name: "' + payLoad.repository.name + '"')
			callback(null);
			return;
		}

		for (var i=0;i<repository.process.length;i++) {
			var p = repository[i];
			if (p == null) {
				console.log('Emtpty Process: ' + i);
				continue;
			}

			try {
				exec(p.exec, function (error, stdout, stderr) {
				  	if (error) {
				  		cbError('Error invoking exec: ' + error);
				  		return;
				  	}

				  	if (stdError) {
				  		cbError('Error with exec: ' + stdError);
				  		return;
				  	}

				  	console.log('Process Out [' + i + ' ]: ');
				  	console.log(stdout);
				});
			} catch (err) {
				cbError('Unknown err: ' + err);
				return;
			}
		}

		callback(null);
	}

	jook.getRepositoryByName = function(name) {
		var rep = null;
		this.repositories.map(function(repository) {
			if (repository.name == name) {
				rep = repository;
				return;
			}
		});
		return rep;
	}

	jook.readConfig = function(options, cwd) {
		var fs = require('fs');
		var path = require('path');

		var file = path.join(cwd, jook.options.files.config);

		if (!fs.existsSync(file)) {
			throw 'Config File not found: ' + jook.options.files.config;
		}

		var data = fs.readFileSync(file);
    	var json = JSON.parse(data);

		if (!isNaN(parseInt(json.port,10))) {
			jook.options.port = parseInt(json.port, 10);
	 	}

    	if (json.repositories == null || json.repositories.length == 0) {
    		throw 'Repositories not defined in config';
    	}

    	json.repositories.map(function(rep) {
    		if (rep == null || rep.name == null || rep.process==null)
    			return;

    		var process = new Array();

    		var repository = {
    			name : rep.name,
    			process : new Array()
    		};

    		rep.process.map(function(p) {
    			process.push({
    				exec : p.exec
    			});
    		});

    		jook.repositories.push(repository);
    	})
	}

	jook.main(process.argv, process.cwd());

}).call(this);<commit_msg>use full_name name from repository<commit_after>/*
   Jooks
   Copyright : 2014
   Contributor : ppalludan
*/
(function() {
	var jook = this;

	// references
	jook.options = require('./options');
	jook.repositories = new Array();

	jook.main = function(args, cwd) {
		var program = require('commander');
		var colors = require('colors');
		var pjson = require('../package.json');

		// Process program arguments
		program.version(pjson.version)
	      .option('-p, --port [number]', 'Port Number (default: ' + jook.options.port)
	      .option('-c, --config [filename]', 'Configuration Filename (default: ' + jook.options.files.config);

		program.on('--help', function(){
	      console.log('  Examples:');
	      console.log('');
	      console.log('    jook --help');
	      console.log('    jook --p 9001');
	      console.log('');
	    });
	    program.parse(args);

	 	if (program.config && program.config!=true) {
	 		jook.options.files.config = program.config;
	 	}

   	 	jook.readConfig(jook.options, cwd);

	 	// Set the port if none present
	 	if (!isNaN(parseInt(program.port,10))) {
			jook.options.port = parseInt(program.port, 10);
	 	}

	 	// Start the webserver to handle the webhooks
		jook.startServer();

		// writing out the status for the repositories
		console.log('['.grey +('Jook v ' + program._version + ' running').cyan + ']'.grey + ' ' +
			'['.grey + ('Port: ' + jook.options.port + ', config: ' + jook.options.files.config).cyan + ']'.grey);

		jook.repositories.map(function(rep) {
			console.log('\tRepository: ' + rep.name);
		})
	}

	jook.startServer = function(options) {
		var http = require('http');

		var server = http.createServer(jook.handleRequest).listen(jook.options.port);
	}

	jook.handleRequest = function(req, res) {
		if (req.method == 'POST') {
			var payLoad = '';

			req.on('data', function(chunk) {
				console.log('data');
				payLoad += chunk;
			});

			req.on('end', function() {
				jook.offLoad(JSON.parse(payLoad), function(err) {

					if (err) {
						res.writeHead(500, {'Content-Type':'application/json'});
						res.write('err: ' + err);
					} else {
						res.writeHead(200, {'Content-Type':'application/json'});
						res.write('ok');
					}
					res.end();
				});
			});
		} else {
			res.writeHead(200, {'Content-Type':'application/json'});
            res.write('yes hello?');
			res.end();
		}
	}

	// Handle the webhook payload
	// callback = function(err)
	jook.offLoad = function(payLoad, callback) {
		var exec = require('child_process').exec;

		function cbError(err) {
			console.log(err);
			callback(err);
		}

		if (payLoad == null || payLoad.repository == null) {
			cbError('missing repository in payload');
			return;
		}

		var repository = jook.getRepositoryByName(payLoad.repository.full_name);
		if (repository == null) {
			console.log('dont know repository payload name: "' + payLoad.repository.full_name + '"')
			callback(null);
			return;
		}

		for (var i=0;i<repository.process.length;i++) {
			var p = repository[i];
			if (p == null) {
				console.log('Emtpty Process: ' + i);
				continue;
			}

			try {
				exec(p.exec, function (error, stdout, stderr) {
				  	if (error) {
				  		cbError('Error invoking exec: ' + error);
				  		return;
				  	}

				  	if (stdError) {
				  		cbError('Error with exec: ' + stdError);
				  		return;
				  	}

				  	console.log('Process Out [' + i + ' ]: ');
				  	console.log(stdout);
				});
			} catch (err) {
				cbError('Unknown err: ' + err);
				return;
			}
		}

		callback(null);
	}

	jook.getRepositoryByName = function(name) {
		var rep = null;
		this.repositories.map(function(repository) {
			if (repository.name == name) {
				rep = repository;
				return;
			}
		});
		return rep;
	}

	jook.readConfig = function(options, cwd) {
		var fs = require('fs');
		var path = require('path');

		var file = path.join(cwd, jook.options.files.config);

		if (!fs.existsSync(file)) {
			throw 'Config File not found: ' + jook.options.files.config;
		}

		var data = fs.readFileSync(file);
    	var json = JSON.parse(data);

		if (!isNaN(parseInt(json.port,10))) {
			jook.options.port = parseInt(json.port, 10);
	 	}

    	if (json.repositories == null || json.repositories.length == 0) {
    		throw 'Repositories not defined in config';
    	}

    	json.repositories.map(function(rep) {
    		if (rep == null || rep.name == null || rep.process==null)
    			return;

    		var process = new Array();

    		var repository = {
    			name : rep.name,
    			process : new Array()
    		};

    		rep.process.map(function(p) {
    			process.push({
    				exec : p.exec
    			});
    		});

    		jook.repositories.push(repository);
    	})
	}

	jook.main(process.argv, process.cwd());

}).call(this);<|endoftext|>


<commit_before>'use strict'

function main (cppBridge) {
  const xs = cppBridge.fsOpenSync(
    'test-file-sync.txt',
    cppBridge.constants.O_WRONLY |
    cppBridge.constants.O_CREAT |
    cppBridge.constants.O_TRUNC,
    cppBridge.constants.S_IRUSR |
    cppBridge.constants.S_IRGRP
  )

  cppBridge.fsOpen(
    'test-file.txt',
    cppBridge.constants.O_WRONLY |
    cppBridge.constants.O_CREAT |
    cppBridge.constants.O_TRUNC,
    cppBridge.constants.S_IRUSR |
    cppBridge.constants.S_IRGRP
  ).then(fd => {
    cppBridge.print(`hello: ${Number(fd)}`)
  }).catch(err => {
    cppBridge.print(`<UV error: ${Number(err)}>`)
  })
}

// NB(chrisdickinson): "main" must come last here - the last value in this
// script is used as the entry point.
main
<commit_msg>nix ws<commit_after>'use strict'

function main (cppBridge) {
  const xs = cppBridge.fsOpenSync(
    'test-file-sync.txt',
    cppBridge.constants.O_WRONLY |
    cppBridge.constants.O_CREAT |
    cppBridge.constants.O_TRUNC,
    cppBridge.constants.S_IRUSR |
    cppBridge.constants.S_IRGRP
  )

  cppBridge.fsOpen(
    'test-file.txt',
    cppBridge.constants.O_WRONLY |
    cppBridge.constants.O_CREAT |
    cppBridge.constants.O_TRUNC,
    cppBridge.constants.S_IRUSR |
    cppBridge.constants.S_IRGRP
  ).then(fd => {
    cppBridge.print(`hello: ${Number(fd)}`)
  }).catch(err => {
    cppBridge.print(`<UV error: ${Number(err)}>`)
  })
}

// NB(chrisdickinson): "main" must come last here - the last value in this
// script is used as the entry point.
main
<|endoftext|>


<commit_before>const {CompositeDisposable, Disposable} = require('atom')
const getIconServices = require('./get-icon-services')
const ReporterProxy = require('./reporter-proxy')

const metricsReporter = new ReporterProxy()

module.exports = {
  activate (state) {
    this.active = true

    this.disposables = new CompositeDisposable()

    this.disposables.add(atom.commands.add('atom-workspace', {
      'fuzzy-finder:toggle-file-finder': () => {
        this.createProjectView().toggle()
      },
      'fuzzy-finder:toggle-buffer-finder': () => {
        this.createBufferView().toggle()
      },
      'fuzzy-finder:toggle-git-status-finder': () => {
        this.createGitStatusView().toggle()
      }
    }))

    process.nextTick(() => this.startLoadPathsTask())

    for (let editor of atom.workspace.getTextEditors()) {
      editor.lastOpened = state[editor.getPath()]
    }

    this.disposables.add(atom.workspace.observePanes(pane => {
      this.disposables.add(pane.observeActiveItem(item => {
        if (item != null) item.lastOpened = Date.now()
      }))
    }))
  },

  deactivate () {
    this.disposables.dispose()

    if (this.projectView != null) {
      this.projectView.destroy()
      this.projectView = null
    }
    if (this.bufferView != null) {
      this.bufferView.destroy()
      this.bufferView = null
    }
    if (this.gitStatusView != null) {
      this.gitStatusView.destroy()
      this.gitStatusView = null
    }
    this.projectPaths = null
    this.stopLoadPathsTask()
    this.active = false
  },

  consumeElementIcons (service) {
    getIconServices().setElementIcons(service)
    return new Disposable(() => getIconServices().resetElementIcons())
  },

  consumeFileIcons (service) {
    getIconServices().setFileIcons(service)
    return new Disposable(() => getIconServices().resetFileIcons())
  },

  consumeTeletype (teletypeService) {
    this.teletypeService = teletypeService
    if (this.bufferView) this.bufferView.setTeletypeService(teletypeService)
    if (this.projectView) this.projectView.setTeletypeService(teletypeService)
  },

  consumeMetricsReporter (metricsReporterService) {
    metricsReporter.setReporter(metricsReporterService)

    return new Disposable(() => metricsReporter.unsetReporter())
  },

  serialize () {
    const paths = {}
    for (let editor of atom.workspace.getTextEditors()) {
      const path = editor.getPath()
      if (path != null) { paths[path] = editor.lastOpened }
    }
    return paths
  },

  createProjectView () {
    this.stopLoadPathsTask()

    if (this.projectView == null) {
      const ProjectView = require('./project-view')
      this.projectView = new ProjectView(this.projectPaths, metricsReporter)
      this.projectPaths = null
      if (this.teletypeService) {
        this.projectView.setTeletypeService(this.teletypeService)
      }
    }
    return this.projectView
  },

  createGitStatusView () {
    if (this.gitStatusView == null) {
      const GitStatusView = require('./git-status-view')
      this.gitStatusView = new GitStatusView()
    }
    return this.gitStatusView
  },

  createBufferView () {
    if (this.bufferView == null) {
      const BufferView = require('./buffer-view')
      this.bufferView = new BufferView(metricsReporter)
      if (this.teletypeService) {
        this.bufferView.setTeletypeService(this.teletypeService)
      }
    }
    return this.bufferView
  },

  startLoadPathsTask () {
    this.stopLoadPathsTask()

    if (!this.active) return
    if (atom.project.getPaths().length === 0) return

    const PathLoader = require('./path-loader')
    this.loadPathsTask = PathLoader.startTask((projectPaths) => {
      this.projectPaths = projectPaths
    }, metricsReporter)
    this.projectPathsSubscription = atom.project.onDidChangePaths(() => {
      this.projectPaths = null
      this.stopLoadPathsTask()
    })
  },

  stopLoadPathsTask () {
    if (this.projectPathsSubscription != null) {
      this.projectPathsSubscription.dispose()
    }
    this.projectPathsSubscription = null

    if (this.loadPathsTask != null) {
      this.loadPathsTask.terminate()
    }
    this.loadPathsTask = null
  }
}
<commit_msg>Pass metricsReporter into GitStatusView to avoid null exception<commit_after>const {CompositeDisposable, Disposable} = require('atom')
const getIconServices = require('./get-icon-services')
const ReporterProxy = require('./reporter-proxy')

const metricsReporter = new ReporterProxy()

module.exports = {
  activate (state) {
    this.active = true

    this.disposables = new CompositeDisposable()

    this.disposables.add(atom.commands.add('atom-workspace', {
      'fuzzy-finder:toggle-file-finder': () => {
        this.createProjectView().toggle()
      },
      'fuzzy-finder:toggle-buffer-finder': () => {
        this.createBufferView().toggle()
      },
      'fuzzy-finder:toggle-git-status-finder': () => {
        this.createGitStatusView().toggle()
      }
    }))

    process.nextTick(() => this.startLoadPathsTask())

    for (let editor of atom.workspace.getTextEditors()) {
      editor.lastOpened = state[editor.getPath()]
    }

    this.disposables.add(atom.workspace.observePanes(pane => {
      this.disposables.add(pane.observeActiveItem(item => {
        if (item != null) item.lastOpened = Date.now()
      }))
    }))
  },

  deactivate () {
    this.disposables.dispose()

    if (this.projectView != null) {
      this.projectView.destroy()
      this.projectView = null
    }
    if (this.bufferView != null) {
      this.bufferView.destroy()
      this.bufferView = null
    }
    if (this.gitStatusView != null) {
      this.gitStatusView.destroy()
      this.gitStatusView = null
    }
    this.projectPaths = null
    this.stopLoadPathsTask()
    this.active = false
  },

  consumeElementIcons (service) {
    getIconServices().setElementIcons(service)
    return new Disposable(() => getIconServices().resetElementIcons())
  },

  consumeFileIcons (service) {
    getIconServices().setFileIcons(service)
    return new Disposable(() => getIconServices().resetFileIcons())
  },

  consumeTeletype (teletypeService) {
    this.teletypeService = teletypeService
    if (this.bufferView) this.bufferView.setTeletypeService(teletypeService)
    if (this.projectView) this.projectView.setTeletypeService(teletypeService)
  },

  consumeMetricsReporter (metricsReporterService) {
    metricsReporter.setReporter(metricsReporterService)

    return new Disposable(() => metricsReporter.unsetReporter())
  },

  serialize () {
    const paths = {}
    for (let editor of atom.workspace.getTextEditors()) {
      const path = editor.getPath()
      if (path != null) { paths[path] = editor.lastOpened }
    }
    return paths
  },

  createProjectView () {
    this.stopLoadPathsTask()

    if (this.projectView == null) {
      const ProjectView = require('./project-view')
      this.projectView = new ProjectView(this.projectPaths, metricsReporter)
      this.projectPaths = null
      if (this.teletypeService) {
        this.projectView.setTeletypeService(this.teletypeService)
      }
    }
    return this.projectView
  },

  createGitStatusView () {
    if (this.gitStatusView == null) {
      const GitStatusView = require('./git-status-view')
      this.gitStatusView = new GitStatusView(metricsReporter)
    }
    return this.gitStatusView
  },

  createBufferView () {
    if (this.bufferView == null) {
      const BufferView = require('./buffer-view')
      this.bufferView = new BufferView(metricsReporter)
      if (this.teletypeService) {
        this.bufferView.setTeletypeService(this.teletypeService)
      }
    }
    return this.bufferView
  },

  startLoadPathsTask () {
    this.stopLoadPathsTask()

    if (!this.active) return
    if (atom.project.getPaths().length === 0) return

    const PathLoader = require('./path-loader')
    this.loadPathsTask = PathLoader.startTask((projectPaths) => {
      this.projectPaths = projectPaths
    }, metricsReporter)
    this.projectPathsSubscription = atom.project.onDidChangePaths(() => {
      this.projectPaths = null
      this.stopLoadPathsTask()
    })
  },

  stopLoadPathsTask () {
    if (this.projectPathsSubscription != null) {
      this.projectPathsSubscription.dispose()
    }
    this.projectPathsSubscription = null

    if (this.loadPathsTask != null) {
      this.loadPathsTask.terminate()
    }
    this.loadPathsTask = null
  }
}
<|endoftext|>


<commit_before>var url = require('url');
var proxy = require('../lib/proxy/proxy');
var router = require('../lib/router/router')
var WorkerRegistry = require('../lib/worker/worker-registry');

// If SHINY_HOMEPAGE is defined, redirect to it on /
var homepageRedirect = process.env.SHINY_HOMEPAGE && function(req, res) {
  if (url.parse(req.url).pathname == '/') {
    res.writeHead(302, {
      'Location': process.env.SHINY_HOMEPAGE
    });
    res.end();
    return true;
  }
  return false;
};

var autouserOptions = {
  gaTrackingId: process.env.SHINY_GAID
};

var shinyProxy = new proxy.ShinyProxy(
  router.join(
    new router.AutouserRouter(autouserOptions),
    homepageRedirect
  ),
  new WorkerRegistry()
);
shinyProxy.httpServer.listen(
  parseInt(process.env.SHINY_PORT || 80),
  process.env.SHINY_HOST);
<commit_msg>Add hashbang to main.js<commit_after>#!/usr/bin/env node

var url = require('url');
var proxy = require('../lib/proxy/proxy');
var router = require('../lib/router/router')
var WorkerRegistry = require('../lib/worker/worker-registry');

// If SHINY_HOMEPAGE is defined, redirect to it on /
var homepageRedirect = process.env.SHINY_HOMEPAGE && function(req, res) {
  if (url.parse(req.url).pathname == '/') {
    res.writeHead(302, {
      'Location': process.env.SHINY_HOMEPAGE
    });
    res.end();
    return true;
  }
  return false;
};

var autouserOptions = {
  gaTrackingId: process.env.SHINY_GAID
};

var shinyProxy = new proxy.ShinyProxy(
  router.join(
    new router.AutouserRouter(autouserOptions),
    homepageRedirect
  ),
  new WorkerRegistry()
);
shinyProxy.httpServer.listen(
  parseInt(process.env.SHINY_PORT || 80),
  process.env.SHINY_HOST);
<|endoftext|>


<commit_before>/*
 * This Source Code is subject to the terms of the Mozilla Public License
 * version 2.0 (the "License"). You can obtain a copy of the License at
 * http://mozilla.org/MPL/2.0/.
 */

let {WindowObserver} = require("windowObserver");
new WindowObserver({
  applyToWindow: function(window)
  {
    if (!("gBrowser" in window))
      return;

    window.gBrowser.addEventListener("mousedown", saveLinkTarget, true);
    window.gBrowser.addEventListener("mousedown", restoreLinkTarget, false);
    window.gBrowser.addEventListener("keydown", interceptReturn, true);
  },

  removeFromWindow: function(window)
  {
    if (!("gBrowser" in window))
      return;

    window.gBrowser.removeEventListener("mousedown", saveLinkTarget, true);
    window.gBrowser.removeEventListener("mousedown", restoreLinkTarget, false);
    window.gBrowser.removeEventListener("keydown", interceptReturn, true);
  }
});

let currentLink = null;
let currentLinkHref = null;

let hostSet = new Set([
  "groups.google.com",
  "yandex.com",
  "yandex.com.tr",
  "yandex.by",
  "yandex.kz",
  "yandex.ru",
  "yandex.ua"
]);

function isSearchPage(window)
{
  try
  {
    if (hostSet.has(window.location.host))
      return true;
  }
  catch (e) {}

  let sandbox = new Cu.Sandbox(window);
  sandbox.window = XPCNativeWrapper.unwrap(window);
  try
  {
    return Cu.evalInSandbox("window.google && (window.google.sn || window.google.search) ? true : false", sandbox);
  }
  catch (e)
  {
    return false;
  }
}

function saveLinkTarget(event)
{
  if (!isSearchPage(event.target.ownerDocument.defaultView))
    return;

  for (currentLink = event.target; currentLink; currentLink = currentLink.parentNode)
    if (currentLink.localName == "a")
      break;

  currentLinkHref = (currentLink ? currentLink.href : null);
}

function restoreLinkTarget(event)
{
  if (currentLink && currentLink.href != currentLinkHref)
    currentLink.href = currentLinkHref;

  currentLink = currentLinkHref = null;
}

function interceptReturn(event)
{
  let target = event.target;
  if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN &&
      target.localName == "a" &&
      /^\s*https?:/i.test(target.getAttribute("href")) &&
      isSearchPage(target.ownerDocument.defaultView))
  {
    event.stopPropagation();
  }
}
<commit_msg>Closing #3 - Add support for Yahoo Search<commit_after>/*
 * This Source Code is subject to the terms of the Mozilla Public License
 * version 2.0 (the "License"). You can obtain a copy of the License at
 * http://mozilla.org/MPL/2.0/.
 */

let {WindowObserver} = require("windowObserver");
new WindowObserver({
  applyToWindow: function(window)
  {
    if (!("gBrowser" in window))
      return;

    window.gBrowser.addEventListener("mousedown", saveLinkTarget, true);
    window.gBrowser.addEventListener("mousedown", restoreLinkTarget, false);
    window.gBrowser.addEventListener("click", restoreLinkTarget, false);
    window.gBrowser.addEventListener("keydown", interceptReturn, true);
  },

  removeFromWindow: function(window)
  {
    if (!("gBrowser" in window))
      return;

    window.gBrowser.removeEventListener("mousedown", saveLinkTarget, true);
    window.gBrowser.removeEventListener("mousedown", restoreLinkTarget, false);
    window.gBrowser.removeEventListener("click", restoreLinkTarget, false);
    window.gBrowser.removeEventListener("keydown", interceptReturn, true);
  }
});

let currentLink = null;
let currentLinkHref = null;

let hostSet = new Set([
  "groups.google.com",
  "search.yahoo.com",
  "yandex.com",
  "yandex.com.tr",
  "yandex.by",
  "yandex.kz",
  "yandex.ru",
  "yandex.ua"
]);

function isSearchPage(window)
{
  try
  {
    let host = window.location.host;
    if (hostSet.has(host) || hostSet.has(host.replace(/^.*?\./, "")))
      return true;
  }
  catch (e) {}

  let sandbox = new Cu.Sandbox(window);
  sandbox.window = XPCNativeWrapper.unwrap(window);
  try
  {
    return Cu.evalInSandbox("window.google && (window.google.sn || window.google.search) ? true : false", sandbox);
  }
  catch (e)
  {
    return false;
  }
}

function saveLinkTarget(event)
{
  if (!isSearchPage(event.target.ownerDocument.defaultView))
    return;

  for (currentLink = event.target; currentLink; currentLink = currentLink.parentNode)
    if (currentLink.localName == "a")
      break;

  currentLinkHref = (currentLink ? currentLink.href : null);
}

function restoreLinkTarget(event)
{
  try
  {
    if (currentLink && currentLink.href != currentLinkHref)
      currentLink.href = currentLinkHref;
  }
  catch (e)
  {
    // Ignore, likely "can't access dead object" (currentLink has been garbage collected)
  }

  if (event.type == "click")
    currentLink = currentLinkHref = null;
}

function interceptReturn(event)
{
  let target = event.target;
  if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_RETURN &&
      target.localName == "a" &&
      /^\s*https?:/i.test(target.getAttribute("href")) &&
      isSearchPage(target.ownerDocument.defaultView))
  {
    event.stopPropagation();
  }
}
<|endoftext|>


<commit_before>/* @flow */

import {CompositeDisposable} from 'atom'
import FileList from './file-list'
import FileListViewModel from './file-list-view-model'
import DiffViewModel from './diff-view-model'
import DiffPaneItemComponent from './diff-pane-item-component'
import FileListComponent from './file-list-component'
import StatusBarComponent from './status-bar-component'
import StatusBarViewModel from './status-bar-view-model'
import GitService from './git-service'
import {DiffURI} from './common'

import type {Panel} from 'atom'
import type {StatusBar, Tile} from 'status-bar'

type GitState = {panelVisible: boolean}

class Git {
  subscriptions: CompositeDisposable;
  state: GitState;
  changesPanel: ?Panel<FileListViewModel>;
  statusBarTile: ?Tile<StatusBarComponent>;
  fileList: FileList;

  constructor () {
    this.subscriptions = new CompositeDisposable()
  }

  activate (state: GitState = {panelVisible: false}) {
    this.state = state

    atom.commands.add('atom-workspace', 'git:view-and-commit-changes', () => {
      this.openChangesPanel()
    })

    atom.commands.add('atom-workspace', 'git:close-commit-panel', () => {
      this.closeChangesPanel()

      const workspaceElement = atom.views.getView(atom.workspace)
      workspaceElement.focus()
    })

    atom.commands.add('atom-workspace', 'git:open-file-diff', () => {
      this.openDiffForActiveEditor()
    })

    atom.commands.add('atom-workspace', 'git:refresh-status', () => {
      this.update()
    })

    if (state.panelVisible) {
      this.openChangesPanel()
    }

    process.nextTick(() => {
      this.subscriptions.add(atom.workspace.addOpener((uri, options) => {
        if (uri.startsWith(DiffURI)) {
          return createDiffPaneItem({
            uri,
            pending: options.pending
          })
        }
      }))
    })
  }

  update (): Promise<void> {
    const promises = []
    promises.push(this.getFileList().loadFromGitUtils())

    const fileListViewModel = this.getFileListViewModel()
    if (fileListViewModel) {
      promises.push(fileListViewModel.update())
    }

    const statusBarTile = this.statusBarTile
    if (statusBarTile) {
      promises.push(statusBarTile.getItem().viewModel.update())
    }

    return Promise.all(promises).then(() => { return })
  }

  serialize (): GitState {
    const changesPanel = this.changesPanel
    const visible = (changesPanel && changesPanel.isVisible()) || false
    return {
      panelVisible: visible
    }
  }

  deactivate () {
    if (this.subscriptions) {
      this.subscriptions.dispose()
    }
  }

  getFileList (): FileList {
    if (!this.fileList) {
      this.fileList = new FileList([], {stageOnChange: true})
      this.fileList.onDidUserChange(() => {
        this.fileList.loadFromGitUtils()
      })
    }

    return this.fileList
  }

  getGitService (): GitService {
    return GitService.instance()
  }

  closeChangesPanel () {
    if (this.changesPanel) {
      this.changesPanel.hide()
    }
  }

  openChangesPanel () {
    let fileListViewModel
    const changesPanel = this.changesPanel
    if (changesPanel) {
      changesPanel.show()
      fileListViewModel = changesPanel.getItem()
    } else {
      fileListViewModel = new FileListViewModel(this.getFileList())
      fileListViewModel.onDidUserChange(() => this.update())
      this.changesPanel = atom.workspace.addRightPanel({item: fileListViewModel})
    }

    this.update()
    atom.views.getView(fileListViewModel).focus()
  }

  getFileListViewModel (): ?FileListViewModel {
    const changesPanel = this.changesPanel
    if (changesPanel) {
      return changesPanel.getItem()
    }
  }

  openDiffForActiveEditor () {
    const editor = atom.workspace.getActiveTextEditor()
    const editorPath = editor.getPath()
    if (!editorPath) return

    const filePath = atom.project.relativizePath(editorPath)[1]
    return this.getFileList().getOrCreateFileFromPathName(filePath).openDiff({pending: true})
  }

  consumeStatusBar (statusBar: StatusBar) {
    const viewModel = new StatusBarViewModel(this.getGitService())
    const toggleChangesPanel = () => {
      const changesPanel = this.changesPanel
      if (changesPanel && changesPanel.isVisible()) {
        this.closeChangesPanel()
      } else {
        this.openChangesPanel()
      }
    }
    this.statusBarTile = statusBar.addRightTile({item: new StatusBarComponent(viewModel, () => toggleChangesPanel()), priority: -100})
  }
}

const gitInstance = new Git()

function createDiffPaneItem ({uri, pending}) {
  const pathName = uri.replace(DiffURI, '')
  const fileDiff = gitInstance.getFileList().getOrCreateFileFromPathName(pathName)
  return new DiffViewModel({
    uri,
    pathName,
    pending: !!pending,
    deserializer: 'GitDiffPaneItem',
    fileList: new FileList([fileDiff], {stageOnChange: false})
  })
}

atom.deserializers.add({
  name: 'GitDiffPaneItem',
  deserialize: state => createDiffPaneItem(state)
})

atom.views.addViewProvider(DiffViewModel, diffViewModel => {
  const component = new DiffPaneItemComponent({diffViewModel})
  return component.element
})

atom.views.addViewProvider(FileListViewModel, fileListViewModel => {
  const component = new FileListComponent({fileListViewModel})
  return component.element
})

export default gitInstance
<commit_msg>Use the view provider.<commit_after>/* @flow */

import {CompositeDisposable} from 'atom'
import FileList from './file-list'
import FileListViewModel from './file-list-view-model'
import DiffViewModel from './diff-view-model'
import DiffPaneItemComponent from './diff-pane-item-component'
import FileListComponent from './file-list-component'
import StatusBarComponent from './status-bar-component'
import StatusBarViewModel from './status-bar-view-model'
import GitService from './git-service'
import {DiffURI} from './common'

import type {Panel} from 'atom'
import type {StatusBar, Tile} from 'status-bar'

type GitState = {panelVisible: boolean}

class Git {
  subscriptions: CompositeDisposable;
  state: GitState;
  changesPanel: ?Panel<FileListViewModel>;
  statusBarTile: ?Tile<StatusBarViewModel>;
  fileList: FileList;

  constructor () {
    this.subscriptions = new CompositeDisposable()
  }

  activate (state: GitState = {panelVisible: false}) {
    this.state = state

    atom.commands.add('atom-workspace', 'git:view-and-commit-changes', () => {
      this.openChangesPanel()
    })

    atom.commands.add('atom-workspace', 'git:close-commit-panel', () => {
      this.closeChangesPanel()

      const workspaceElement = atom.views.getView(atom.workspace)
      workspaceElement.focus()
    })

    atom.commands.add('atom-workspace', 'git:open-file-diff', () => {
      this.openDiffForActiveEditor()
    })

    atom.commands.add('atom-workspace', 'git:refresh-status', () => {
      this.update()
    })

    if (state.panelVisible) {
      this.openChangesPanel()
    }

    process.nextTick(() => {
      this.subscriptions.add(atom.workspace.addOpener((uri, options) => {
        if (uri.startsWith(DiffURI)) {
          return createDiffPaneItem({
            uri,
            pending: options.pending
          })
        }
      }))
    })
  }

  update (): Promise<void> {
    const promises = []
    promises.push(this.getFileList().loadFromGitUtils())

    const fileListViewModel = this.getFileListViewModel()
    if (fileListViewModel) {
      promises.push(fileListViewModel.update())
    }

    const statusBarTile = this.statusBarTile
    if (statusBarTile) {
      promises.push(statusBarTile.getItem().update())
    }

    return Promise.all(promises).then(() => { return })
  }

  serialize (): GitState {
    const changesPanel = this.changesPanel
    const visible = (changesPanel && changesPanel.isVisible()) || false
    return {
      panelVisible: visible
    }
  }

  deactivate () {
    if (this.subscriptions) {
      this.subscriptions.dispose()
    }
  }

  getFileList (): FileList {
    if (!this.fileList) {
      this.fileList = new FileList([], {stageOnChange: true})
      this.fileList.onDidUserChange(() => {
        this.fileList.loadFromGitUtils()
      })
    }

    return this.fileList
  }

  getGitService (): GitService {
    return GitService.instance()
  }

  closeChangesPanel () {
    if (this.changesPanel) {
      this.changesPanel.hide()
    }
  }

  openChangesPanel () {
    let fileListViewModel
    const changesPanel = this.changesPanel
    if (changesPanel) {
      changesPanel.show()
      fileListViewModel = changesPanel.getItem()
    } else {
      fileListViewModel = new FileListViewModel(this.getFileList())
      fileListViewModel.onDidUserChange(() => this.update())
      this.changesPanel = atom.workspace.addRightPanel({item: fileListViewModel})
    }

    this.update()
    atom.views.getView(fileListViewModel).focus()
  }

  getFileListViewModel (): ?FileListViewModel {
    const changesPanel = this.changesPanel
    if (changesPanel) {
      return changesPanel.getItem()
    }
  }

  openDiffForActiveEditor () {
    const editor = atom.workspace.getActiveTextEditor()
    const editorPath = editor.getPath()
    if (!editorPath) return

    const filePath = atom.project.relativizePath(editorPath)[1]
    return this.getFileList().getOrCreateFileFromPathName(filePath).openDiff({pending: true})
  }

  consumeStatusBar (statusBar: StatusBar) {
    const viewModel = new StatusBarViewModel(this.getGitService())
    this.statusBarTile = statusBar.addRightTile({item: viewModel, priority: -100})
  }
}

const gitInstance = new Git()

function createDiffPaneItem ({uri, pending}) {
  const pathName = uri.replace(DiffURI, '')
  const fileDiff = gitInstance.getFileList().getOrCreateFileFromPathName(pathName)
  return new DiffViewModel({
    uri,
    pathName,
    pending: !!pending,
    deserializer: 'GitDiffPaneItem',
    fileList: new FileList([fileDiff], {stageOnChange: false})
  })
}

atom.deserializers.add({
  name: 'GitDiffPaneItem',
  deserialize: state => createDiffPaneItem(state)
})

atom.views.addViewProvider(DiffViewModel, diffViewModel => {
  const component = new DiffPaneItemComponent({diffViewModel})
  return component.element
})

atom.views.addViewProvider(FileListViewModel, fileListViewModel => {
  const component = new FileListComponent({fileListViewModel})
  return component.element
})

atom.views.addViewProvider(StatusBarViewModel, viewModel => {
  const toggleChangesPanel = () => {
    const changesPanel = gitInstance.changesPanel
    if (changesPanel && changesPanel.isVisible()) {
      gitInstance.closeChangesPanel()
    } else {
      gitInstance.openChangesPanel()
    }
  }

  const component = new StatusBarComponent(viewModel, toggleChangesPanel)
  return component.element
})

export default gitInstance
<|endoftext|>


<commit_before>'use strict';

const {
    app,
    dialog,
    BrowserWindow,
    globalShortcut
} = require('electron');

const server = require('./server');

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;

app.on('ready', () => {
    server((e, port) => {
        exitIfError(e);
        //createWindow(port);
    });
});

app.on('window-all-closed', () => {
    // On macOS it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform === 'darwin')
        return;

    app.quit();
});

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
    if (win)
        return;

    createWindow();
});

function createWindow (port) {
  // Create the browser window.
    win = new BrowserWindow({
        width: 1200,
        height: 800,
        webPreferences: {
            nodeIntegration: false
        }
    });

    win.loadURL(`http://localhost:${port}`);

    globalShortcut.register('CommandOrControl+F12', () => {
        win.webContents.openDevTools();
    });

    win.on('closed', () => {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        win = null;
    });
}

function exitIfError(e) {
    if (!e)
        return;

    dialog.shoeMessageBox({
        type: 'error',
        title: 'Cloud Commander',
        message: e.message
    }, () => {
        app.quit();
    });
}

<commit_msg>fix(main) createWindow<commit_after>'use strict';

const {
    app,
    dialog,
    BrowserWindow,
    globalShortcut
} = require('electron');

const server = require('./server');

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;

app.on('ready', () => {
    server((e, port) => {
        exitIfError(e);
        createWindow(port);
    });
});

app.on('window-all-closed', () => {
    // On macOS it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform === 'darwin')
        return;

    app.quit();
});

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
    if (win)
        return;

    createWindow();
});

function createWindow (port) {
  // Create the browser window.
    win = new BrowserWindow({
        width: 1200,
        height: 800,
        webPreferences: {
            nodeIntegration: false
        }
    });

    win.loadURL(`http://localhost:${port}`);

    globalShortcut.register('CommandOrControl+F12', () => {
        win.webContents.openDevTools();
    });

    win.on('closed', () => {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        win = null;
    });
}

function exitIfError(e) {
    if (!e)
        return;

    dialog.shoeMessageBox({
        type: 'error',
        title: 'Cloud Commander',
        message: e.message
    }, () => {
        app.quit();
    });
}

<|endoftext|>


<commit_before>var spawnSync = require('child_process').spawnSync
var jsonfile = require('jsonfile')
var path = require('path')
var config = require('../config.json')

var _exec = function (command) {
  var commands = command.split(' && ')
  commands.forEach(function (_cmd) {
    _cmd = _cmd.split(' ').map(function (r) {
      return r.split('жщ').join(' ')
    })
    spawnSync('git', _cmd, {
      stdio: 'inherit'
    })
  })
}

module.exports = function (command, program) {
  var originArgs = program.args.slice(0, program.args.length - 1)
  var args = originArgs.slice(1)
  var realCommand = config[command]
  if (realCommand) {
    if (realCommand.match(/commit\s/)) {
      args = args.map(function (message) {
        return message.split(' ').join('жщ')
      })
    }

    _exec(realCommand + ' ' + args.join(' '))
  } else if (command === 'alias') {
    // create or update alias config
    config[args[0]] = args.concat().slice(1).join(' ')
    jsonfile.writeFileSync(path.join(process.cwd(), './config.json'), config, {
      spaces: 2
    })
  } else {
    // exec git command
    _exec(originArgs.join(' '))
  }
}
<commit_msg>fix command<commit_after>var spawnSync = require('child_process').spawnSync
var jsonfile = require('jsonfile')
var path = require('path')
var config = require('../config.json')

var _exec = function (command) {
  var commands = command.split(' && ')
  commands.forEach(function (_cmd) {
    _cmd = _cmd.split(' ').map(function (r) {
      return r.split('жщ').join(' ')
    })
    spawnSync('git', _cmd, {
      stdio: 'inherit'
    })
  })
}

module.exports = function (command, program) {
  var originArgs = program.args.slice(0, program.args.length - 1)
  var args = originArgs.slice(1)
  var realCommand = config[command]
  if (realCommand) {
    if (realCommand.match(/commit\s/)) {
      args = args.map(function (message) {
        return message.split(' ').join('жщ')
      })
    }
    if (args.length) {
      realCommand = realCommand + ' ' + args.join(' ')
    }
    _exec(realCommand)
  } else if (command === 'alias') {
    // create or update alias config
    config[args[0]] = args.concat().slice(1).join(' ')
    jsonfile.writeFileSync(path.join(process.cwd(), './config.json'), config, {
      spaces: 2
    })
  } else {
    // exec git command
    _exec(originArgs.join(' '))
  }
}
<|endoftext|>


<commit_before>/*global escape, require, process, console, setTimeout, JSON, __dirname*/

var express = require('express'),
    spawn = require('child_process').spawn,
    exec = require('child_process').exec,
    shell = require('./../scripts/helper/shell'),
    defaultBrowser = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
    defaultArgs =  ["--no-process-singleton-dialog",
                    "--user-data-dir=/tmp/", "--no-first-run",
                    "--disable-default-apps",
                    //"--no-startup-window",
                    "--disable-history-quick-provider",
                    "--disable-history-url-provider",
                    "--disable-breakpad",
                    "--disable-background-mode",
                    "--disable-background-networking",
                    "--disable-preconnect", "--disabled"];

// start with "nodemon minimal_server/serve.js" for development

var args = process.argv.slice(2),
    port = args[0] && parseInt(args[0], 10),
    lkDir = args[1],
    verbose = args.indexOf('--verbose') >= 0 || args.indexOf('-v') >= 0;

/*
 * http interface
 */
function setupServer(testHandler, workspaceHandler) {
    var app = express.createServer();
    if (verbose) app.use(express.logger());
    app.use("/", express["static"](lkDir));
    app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
    app.use(express.bodyParser());

    testHandler.registerWith(app);
    workspaceHandler.registerWith(app);

    return app;
}

function getJSONRoute(app, handler, path, method) {
    app.get(path, function (req, res) {
        handler[method](function(json) { res.send(json); });
    });
}

/*
 * Controller that process result responses from LK client
 */
function TestHandler() {}

var testResults;
(TestHandler.resetTestData = function() {
    testResults = {};
})();

TestHandler.prototype.registerWith = function(app) {
    var handler = this;
    app.post('/test-result/:id', function(req, res) {
        var id = req.params.id,
            result = req.body.testResults;
        try {
            result = this.postResult(id, result);
        } catch(e) {
            result = {result: String(e), error: true, requestedData: req.body};
        }
        res.send({result: result});
    });

    app.get('/test-result/:id', function(req, res) {
        res.send(handler.getResult(req.params.id));
    });

    app.get('/test-result', function (req, res) {
        res.send(handler.listResults());
    });
}

// results
TestHandler.prototype.postResult = function(id, result) {
    console.log('Getting result for test run ' + id);
    testResults[id] = {testRunId: id, state: 'done', result: result};
    return {result: 'ok', testRunId: id};
};

TestHandler.prototype.getResult = function(id) {
    return testResults[id] || {testRunId: id, state: 'no result'};
};

TestHandler.prototype.listResults = function(req) {
    return {result: JSON.stringify(testResults)};
};

/*
 * Handler that provides an interface for inspecting / modifying
 * a local LK workspace
 */
function WorkspaceHandler(modules, lkDir) {
    this.modules = modules;
    this.lkDir = lkDir;
}

WorkspaceHandler.prototype.registerWith = function(app) {
    getJSONRoute(app, this, '/workspace/workspace-dir', 'getLKDir');
    getJSONRoute(app, this, '/workspace/branches', 'getBranches');
    var handler = this;
    app.get('/workspace/log/:ref/:howMany', function(req, res) {
        handler.getLog(req.params.ref, req.params.howMany, function(json) { res.send(json); });
    });
}

WorkspaceHandler.prototype.git = function(cmd, whenDone) {
    this.modules.exec("git " + cmd, {cwd: this.lkDir}, whenDone)
}

// curl localhost:9001/workspace/workspace-dir | prettify_json.rb
WorkspaceHandler.prototype.getLKDir = function(whenDone) {
    whenDone({path: this.lkDir});
}

// curl localhost:9001/workspace/branches | prettify_json.rb
WorkspaceHandler.prototype.getBranches = function(whenDone) {
    this.git("branch -a --color=never", function(code, out, err) {
        if (code) { whenDone({error: code, out: out, err: err}); return }
        var lines = out.split('\n'),
            names = [], current;
        lines.forEach(function(line, i) {
            var match = line.match(/(\*?)\s*(.*)/);
            if (!match) return;
            if (match[1] && match[1].length > 0) current = names.length;
            names.push(match[2]);
        });
        whenDone({names: names, current: current});
    })
}

// curl localhost:9001/workspace/log/HEAD/10 | prettify_json.rb
WorkspaceHandler.prototype.getLog = function(fromRef, howMany, whenDone) {
    var cmd = "log --graph "
            + "--pretty=format:'%h -%d %s (%cr) <%an>' "
            + "--abbrev-commit "
            + "--date=relative "
            + (fromRef || "")
            + (howMany ? " -" + howMany : "");
    this.git(cmd, function(code, out, err) {
        if (code) { whenDone({error: code, out: out, err: err}); return }
        var lines = out.split('\n');
        whenDone({lines: lines});
    })
}

/*
 * startup or export
 */
if (port && !isNaN(port)) {
    if (!lkDir) {
        throw new Error('Cannot start server without LK core directory '
                       + 'for serving files from!');
    }

    setupServer(new TestHandler(), new WorkspaceHandler({exec: exec}, lkDir)).listen(port);
} else {
    exports.TestHandler = TestHandler;
    exports.WorkspaceHandler = WorkspaceHandler;
}
<commit_msg>bugfix for test handler<commit_after>/*global escape, require, process, console, setTimeout, JSON, __dirname*/

var express = require('express'),
    spawn = require('child_process').spawn,
    exec = require('child_process').exec,
    shell = require('./../scripts/helper/shell'),
    defaultBrowser = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
    defaultArgs =  ["--no-process-singleton-dialog",
                    "--user-data-dir=/tmp/", "--no-first-run",
                    "--disable-default-apps",
                    //"--no-startup-window",
                    "--disable-history-quick-provider",
                    "--disable-history-url-provider",
                    "--disable-breakpad",
                    "--disable-background-mode",
                    "--disable-background-networking",
                    "--disable-preconnect", "--disabled"];

/*
 * start with
 * nodemon minimal_server/serve.js 9001 $LIVELY --verbose
 * for development
 */

var args = process.argv.slice(2),
    port = args[0] && parseInt(args[0], 10),
    lkDir = args[1],
    verbose = args.indexOf('--verbose') >= 0 || args.indexOf('-v') >= 0;

/*
 * http interface
 */
function setupServer(testHandler, workspaceHandler) {
    var app = express.createServer();
    if (verbose) app.use(express.logger());
    app.use("/", express["static"](lkDir));
    app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
    app.use(express.bodyParser());

    testHandler.registerWith(app);
    workspaceHandler.registerWith(app);

    return app;
}

function getJSONRoute(app, handler, path, method) {
    app.get(path, function (req, res) {
        handler[method](function(json) { res.send(json); });
    });
}

/*
 * Controller that process result responses from LK client
 */
function TestHandler() {}

var testResults;
(TestHandler.resetTestData = function() {
    testResults = {};
})();

TestHandler.prototype.registerWith = function(app) {
    var handler = this;
    app.post('/test-result/:id', function(req, res) {
        var id = req.params.id,
            result = req.body.testResults;
        try {
            result = handler.postResult(id, result);
        } catch(e) {
            result = {result: String(e), error: true, requestedData: req.body};
        }
        res.send({result: result});
    });

    app.get('/test-result/:id', function(req, res) {
        res.send(handler.getResult(req.params.id));
    });

    app.get('/test-result', function (req, res) {
        res.send(handler.listResults());
    });
}

// results
TestHandler.prototype.postResult = function(id, result) {
    console.log('Getting result for test run ' + id);
    testResults[id] = {testRunId: id, state: 'done', result: result};
    return {result: 'ok', testRunId: id};
};

TestHandler.prototype.getResult = function(id) {
    return testResults[id] || {testRunId: id, state: 'no result'};
};

TestHandler.prototype.listResults = function(req) {
    return {result: JSON.stringify(testResults)};
};

/*
 * Handler that provides an interface for inspecting / modifying
 * a local LK workspace
 */
function WorkspaceHandler(modules, lkDir) {
    this.modules = modules;
    this.lkDir = lkDir;
}

WorkspaceHandler.prototype.registerWith = function(app) {
    getJSONRoute(app, this, '/workspace/workspace-dir', 'getLKDir');
    getJSONRoute(app, this, '/workspace/branches', 'getBranches');
    var handler = this;
    app.get('/workspace/log/:ref/:howMany', function(req, res) {
        handler.getLog(req.params.ref, req.params.howMany, function(json) { res.send(json); });
    });
}

WorkspaceHandler.prototype.git = function(cmd, whenDone) {
    this.modules.exec("git " + cmd, {cwd: this.lkDir}, whenDone)
}

// curl localhost:9001/workspace/workspace-dir | prettify_json.rb
WorkspaceHandler.prototype.getLKDir = function(whenDone) {
    whenDone({path: this.lkDir});
}

// curl localhost:9001/workspace/branches | prettify_json.rb
WorkspaceHandler.prototype.getBranches = function(whenDone) {
    this.git("branch -a --color=never", function(code, out, err) {
        if (code) { whenDone({error: code, out: out, err: err}); return }
        var lines = out.split('\n'),
            names = [], current;
        lines.forEach(function(line, i) {
            var match = line.match(/(\*?)\s*(.*)/);
            if (!match) return;
            if (match[1] && match[1].length > 0) current = names.length;
            names.push(match[2]);
        });
        whenDone({names: names, current: current});
    })
}

// curl localhost:9001/workspace/log/HEAD/10 | prettify_json.rb
WorkspaceHandler.prototype.getLog = function(fromRef, howMany, whenDone) {
    var cmd = "log --graph "
            + "--pretty=format:'%h -%d %s (%cr) <%an>' "
            + "--abbrev-commit "
            + "--date=relative "
            + (fromRef || "")
            + (howMany ? " -" + howMany : "");
    this.git(cmd, function(code, out, err) {
        if (code) { whenDone({error: code, out: out, err: err}); return }
        var lines = out.split('\n');
        whenDone({lines: lines});
    })
}

/*
 * startup or export
 */
if (port && !isNaN(port)) {
    if (!lkDir) {
        throw new Error('Cannot start server without LK core directory '
                       + 'for serving files from!');
    }

    setupServer(new TestHandler(), new WorkspaceHandler({exec: exec}, lkDir)).listen(port);
} else {
    exports.TestHandler = TestHandler;
    exports.WorkspaceHandler = WorkspaceHandler;
}
<|endoftext|>