<commit_before>/**
* Undo buffer web worker
* This module acts like a circular buffer - pushing and poping complex objects from a stack
*
* It is intended to be invoked as a web worker object
*
* @author Matt Carter <m@ttcarter.com>
* @example
* 	// Boot buffer
* 	var undoBufferWorker = new Worker('/js/undoBuffer.js');
*
* 	// Listen for messages back
* 	undoBuffer.addEventListener('message', function(e) {
* 		switch (e.data.cmd) {
*			case 'message':
* 				console.log('UndoBuffer:', e.data.payload);
* 				break;
* 			case 'pop':
* 				console.log('Restore undo buffer item', e.data.payload);
* 				break;
* 			default:
* 				throw new Error('Unknown response from UndoBuffer: ' + e.data.cmd);
* 		}
* 	}, false);
*
* 	// Push one item into the buffer
* 	worker.postMessage({'cmd': 'push', 'payload': someObject});
*
* 	// Pop last item
*/

/**
* Main undo buffer
* Each buffer item is an object of the form:
* {
* 	compressed: Boolean|String, // Either true, false or 'compressing'
* 	contents: Object, // The actual object itself
* }
* @var {array}
*/
var buffer = [];

/**
* The maxmim size of the circular undo buffer
* Set to 0 for infinite (not recommended as this will slowly eat all system memory)
* @var {number}
*/
var maxBufferSize = 10;

self.addEventListener('message', function(e) {
	switch (e.data.cmd) {
		case 'start':
			self.postMessage({id: e.data.id, cmd: 'message', payload: 'UndoBuffer started'});
			break;
		case 'end':
			self.close();
			self.postMessage({id: e.data.id, cmd: 'message', payload: 'UndoBuffer closed'});
			break;
		case 'ping':
			self.postMessage({id: e.data.id, cmd: 'message', payload: 'PONG!'});
			break;
		case 'clear':
			buffer = [];
			self.postMessage({id: e.data.id, cmd: 'clear'});
			break;
		case 'push':
			buffer.push({
				compressed: false,
				contents: e.data.payload,
			});
			if (maxBufferSize && buffer.length > maxBufferSize) buffer.shift(); // Shift off start of buffer if we are limiting the buffer size
			break;
		case 'pop':
			var contents = buffer.pop(e.data.payload);
			if (contents) contents = contents.contents;
			self.postMessage({id: e.data.id, cmd: 'pop', payload: contents});
			break;
		case 'getHistory':
			self.postMessage({id: e.data.id, cmd: 'getHistory', payload: buffer.map(function(buffer) { return buffer.contents })});
			break;
		case 'setMaxBufferSize':
			maxBufferSize = e.data.payload;
			if (buffer.length > maxBufferSize) buffer = buffer.slice(buffer.length - maxBufferSize);
			self.postMessage({id: e.data.id, cmd: 'setMaxBufferSize', payload: maxBufferSize});
			break;
		default:
			self.postMessage({id: e.data.id, cmd: 'error', payload: 'Unknown UndoBuffer command: ' + e.data.cmd});
	}
}, false);
<commit_msg>GetHistory now returns the raw buffer info (including meta fields) rather than just the contents<commit_after>/**
* Undo buffer web worker
* This module acts like a circular buffer - pushing and poping complex objects from a stack
*
* It is intended to be invoked as a web worker object
*
* @author Matt Carter <m@ttcarter.com>
* @example
* 	// Boot buffer
* 	var undoBufferWorker = new Worker('/js/undoBuffer.js');
*
* 	// Listen for messages back
* 	undoBuffer.addEventListener('message', function(e) {
* 		switch (e.data.cmd) {
*			case 'message':
* 				console.log('UndoBuffer:', e.data.payload);
* 				break;
* 			case 'pop':
* 				console.log('Restore undo buffer item', e.data.payload);
* 				break;
* 			default:
* 				throw new Error('Unknown response from UndoBuffer: ' + e.data.cmd);
* 		}
* 	}, false);
*
* 	// Push one item into the buffer
* 	worker.postMessage({'cmd': 'push', 'payload': someObject});
*
* 	// Pop last item
*/

/**
* Main undo buffer
* Each buffer item is an object of the form:
* {
* 	compressed: Boolean|String, // Either true, false or 'compressing'
* 	contents: Object, // The actual object itself
* }
* @var {array}
*/
var buffer = [];

/**
* The maxmim size of the circular undo buffer
* Set to 0 for infinite (not recommended as this will slowly eat all system memory)
* @var {number}
*/
var maxBufferSize = 10;

self.addEventListener('message', function(e) {
	switch (e.data.cmd) {
		case 'start':
			self.postMessage({id: e.data.id, cmd: 'message', payload: 'UndoBuffer started'});
			break;
		case 'end':
			self.close();
			self.postMessage({id: e.data.id, cmd: 'message', payload: 'UndoBuffer closed'});
			break;
		case 'ping':
			self.postMessage({id: e.data.id, cmd: 'message', payload: 'PONG!'});
			break;
		case 'clear':
			buffer = [];
			self.postMessage({id: e.data.id, cmd: 'clear'});
			break;
		case 'push':
			buffer.push({
				compressed: false,
				contents: e.data.payload,
			});
			if (maxBufferSize && buffer.length > maxBufferSize) buffer.shift(); // Shift off start of buffer if we are limiting the buffer size
			break;
		case 'pop':
			var contents = buffer.pop(e.data.payload);
			if (contents) contents = contents.contents;
			self.postMessage({id: e.data.id, cmd: 'pop', payload: contents});
			break;
		case 'getHistory':
			self.postMessage({id: e.data.id, cmd: 'getHistory', payload: buffer});
			break;
		case 'setMaxBufferSize':
			maxBufferSize = e.data.payload;
			if (buffer.length > maxBufferSize) buffer = buffer.slice(buffer.length - maxBufferSize);
			self.postMessage({id: e.data.id, cmd: 'setMaxBufferSize', payload: maxBufferSize});
			break;
		default:
			self.postMessage({id: e.data.id, cmd: 'error', payload: 'Unknown UndoBuffer command: ' + e.data.cmd});
	}
}, false);
<|endoftext|>


<commit_before>global.self = global

var WebSocketClient = require('websocket').client
var Paho = require('paho-mqtt')
require('dotenv').config()

global.WebSocket = function(wsurl, protocol) {
  var ws = new WebSocketClient()
  var connection
  var obj = {
    send: function(msg) {
      var nodeBuf = new Buffer(new Uint8Array(msg))
      connection.send(nodeBuf)
    },
    get readyState() {
      return ws.readyState;
    }
  };

  ws.binaryType = 'arraybuffer';

  ws.on("connect", function(conn) {
    connection = conn;
    conn.on("error", function(error) {
      console.log("socket error ", error);
      if (obj.onerror) {
        obj.onerror();
      }
    });

    conn.on("close", function(reasonCode, description) {
      console.log("socket closed ", description);
    })

    conn.on("message", function(message) {
      if (message.type === "binary") {
        if (obj.onmessage) {
          obj.onmessage({
            data: message.binaryData
          });
        }
      }
    });
    if (obj.onopen) {
      obj.onopen();
    }
  });
  ws.on('connectFailed', function(error) {
    console.log('Connect Error: ' + error.toString());
    if (obj.onerror) {
      obj.onerror(error);
    }
  });
  ws.connect(wsurl, protocol);
  return obj;
}

var LocalStorage = require('node-localstorage').LocalStorage
global.localStorage = new LocalStorage('./persistence')

var Paho = require('../paho-mqtt')
global.Paho = Paho

function ensureValue(prop, value) {
  if (prop === '' || prop[0] === '$') {
    return value
  }
  return prop
}

function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1)
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4()
}

function printConfig(settings) {
  console.log(' - Eclipse Paho Javascript Client Test Harness Settings - ')
  console.log('Server URI: ' + settings.server + ':' + settings.port + settings.path)
  console.log('MQTT Version: ' + settings.mqttVersion)
  console.log('Interop Server URI: ' + settings.interopServer + ':' + settings.interopPort + settings.interopPath)
}

module.exports = {
  server: ensureValue(process.env.TEST_SERVER, 'localhost'),
  port: parseInt(ensureValue(process.env.TEST_SERVER_PORT, '443')),
  path: ensureValue(process.env.TEST_SERVER_PATH, '/ws'),
  mqttVersion: parseInt(ensureValue(process.env.TEST_SERVER_MQTTVER, '3')),
  interopServer: ensureValue(process.env.TEST_INTEROPSERVER, 'localhost'),
  interopPort: parseInt(ensureValue(process.env.TEST_INTEROPPORT, '443')),
  interopPath: ensureValue(process.env.TEST_INTEROPPATH, '/ws'),
  useSSL: ensureValue((process.env.TEST_USE_SSL === 'true'), true),
  topicPrefix: 'paho-mqtt-test-' + guid(),
  Paho: Paho,
  printConfig: printConfig
}<commit_msg>More javascript and tests.<commit_after>global.self = global

var WebSocketClient = require('websocket').client
var Paho = require('paho-mqtt')
require('dotenv').config()

global.WebSocket = function(wsurl, protocol) {
  var ws = new WebSocketClient()
  var connection
  var obj = {
    send: function(msg) {
      var nodeBuf = new Buffer(new Uint8Array(msg))
      connection.send(nodeBuf)
    },
    get readyState() {
      return ws.readyState;
    }
  };

  ws.binaryType = 'arraybuffer';

  ws.on("connect", function(conn) {
    connection = conn;
    conn.on("error", function(error) {
      console.log("socket error ", error);
      if (obj.onerror) {
        obj.onerror();
      }
    });

    conn.on("close", function(reasonCode, description) {
      console.log("socket closed ", description);
    })

    conn.on("message", function(message) {
      if (message.type === "binary") {
        if (obj.onmessage) {
          obj.onmessage({
            data: message.binaryData
          });
        }
      }
    });
    if (obj.onopen) {
      obj.onopen();
    }
  });
  ws.on('connectFailed', function(error) {
    console.log('Connect Error: ' + error.toString());
    if (obj.onerror) {
      obj.onerror(error);
    }
  });
  ws.connect(wsurl, protocol);
  return obj;
}

var LocalStorage = require('node-localstorage').LocalStorage
global.localStorage = new LocalStorage('./persistence')

var Paho = require('paho-mqtt')
global.Paho = Paho

function ensureValue(prop, value) {
  if (prop === '' || prop[0] === '$') {
    return value
  }
  return prop
}

function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1)
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4()
}

function printConfig(settings) {
  console.log(' - Eclipse Paho Javascript Client Test Harness Settings - ')
  console.log('Server URI: ' + settings.server + ':' + settings.port + settings.path)
  console.log('MQTT Version: ' + settings.mqttVersion)
  console.log('Interop Server URI: ' + settings.interopServer + ':' + settings.interopPort + settings.interopPath)
}

module.exports = {
  server: ensureValue(process.env.TEST_SERVER, 'localhost'),
  port: parseInt(ensureValue(process.env.TEST_SERVER_PORT, '443')),
  path: ensureValue(process.env.TEST_SERVER_PATH, '/ws'),
  mqttVersion: parseInt(ensureValue(process.env.TEST_SERVER_MQTTVER, '3')),
  interopServer: ensureValue(process.env.TEST_INTEROPSERVER, 'localhost'),
  interopPort: parseInt(ensureValue(process.env.TEST_INTEROPPORT, '443')),
  interopPath: ensureValue(process.env.TEST_INTEROPPATH, '/ws'),
  useSSL: ensureValue((process.env.TEST_USE_SSL === 'true'), true),
  topicPrefix: 'paho-mqtt-test-' + guid(),
  Paho: Paho,
  printConfig: printConfig
}<|endoftext|>


<commit_before>if (typeof define !== 'function') { var define = require('amdefine')(module) }
define( function(require,exports,module){

var _ = require('underscore');
var helpers = require('es_client/helpers');
module.exports = module.exports || {};
module.exports['cell_format_dialog'] = _.template("
[close]

Format Cell
\n
bg red
\n
bg white
\n
money
\n");
module.exports['col_menu'] = _.template("
\n
\n

\n

\n
\n
\n

\n");
module.exports['col_menu'] = _.template("
\n
\n

\n

\n
\n
\n

\n");
/*isislab*/
module.exports['cell_menu'] = _.template("
\n
Add a point from the map\n

\n

\n");
/*end isislab*/

module.exports['es_container'] = _.template("
\n
\n

\n

 \n    \n    \n\n

\n
\n
\n

\n

 \n

\n

\n
\n
\n

\n
\n

\n
\n");
module.exports['expression_editor'] = _.template("<textarea class=\"es-expression-editor-input\" type='text'></textarea>\n");
module.exports['function_menu'] = _.template("
\n<% _.each(eh.userFunctions,function(func){ %>\n  <% if(!func || !func.def){ return }; %>\n  <li class=\"es-menu-button\" data-action=<%= func.def %> > <%= func.def %> - <%= func.desc  %>
\n<% }); %>\n
\n");
module.exports['import_dialog'] = _.template("
[close]

Import CSV
\n<form action=\"/import/csv\" method=\"post\" enctype=\"multipart/form-data\">\n  <input type=\"file\" name=\"csv_file\"><input type='submit' value='Upload'>\n  <input type=\"hidden\" name=\"sheet_id\" value=\"<%=sheet_id%>\">\n</form>\n\n\n");
module.exports['row_menu'] = _.template("
\n
\n

\n
\n
\n

\n");
module.exports['sheet_list'] = _.template("
\n<% var _ = require('underscore'); %>\n<% var cls = \"\" %>\n<% sheets.each(function(sheet){ %>\n\t<li class=\"es-menu-button\" id=<%=sheet.id%> > \n  \t<%=sheet.meta.title%> \n  \t<form class=\"es-sheet-edit-form\" style=\"display:none;float:left;padding-top:5px;height:22px;width:155px;\">\n    \t<input class='es-sheet-input-name' type=\"text\" style=\"width: 145px; font-size: 16px; border: 1px solid #ccc;\" value=\"<%=sheet.meta.title%>\">\n    \t<input class='es-sheet-input-id' type=\"hidden\" value=\"<%=sheet.id%>\">\n  \t</form>\n \t\t<button class=\"es-sheet-control\" id=\"delete-sheet\" data-sheet-id=\"<%=sheet.id%>\"></button>\n  \t<button class=\"es-sheet-control\" id=\"rename-sheet\" data-sheet-id=\"<%=sheet.id%>\"></button>\n  \t

\n\t
\n<%});%>\n
\n
\n\t

\n\t<a href=\"/s/<%=current_sheet_id%>.csv\" target=_blank>

\n\t
Import CSV
\n
\n");
module.exports['sheet_table'] = _.template("<div id=\"es-table-<%= id %>\" class=\"es-table-view\">\n  <table id=\"es-column-headers-<%=id%>\" class=\"es-column-headers es-table\">\n

\n

\n
\n  <table id=\"es-row-headers-<%=id%>\" class=\"es-row-headers es-table\">\n

\n

\n
\n  <div id=\"es-grid-container-<%= id %>\" class=\"es-grid-container\">\n    <table id=\"es-grid-<%= id %>\" class=\"es-grid es-table\">\n

\n      <tbody id=\"es-data-table-<%=id%>\">
\n
\n
\n
\n
ES
\n
\n
\n");
module.exports['table'] = _.template("<% var _ = require('underscore'); %>\n<% var clsAry = ['even','odd']; %>\n<% _.each(sheet.rowIds(), function(row_id,i){ %>\n<% if(i == 0){var cls = 'first'} else {var cls = clsAry[i % 2]} %>\n  <tr id=\"<%= row_id %>\" class=\"es-table-row es-row-<%= cls %>\" data-row_id=\"<%= row_id %>\" style=\"height:<%= sheet.getRowHeight(row_id) %>px;\">\n    <% if(i == 0) { %>\n      <% _.each(sheet.colIds(), function(col_id){ %>\n        <td id=\"<%= row_id %>-<%= col_id %>\" style=\"width:<%= sheet.getColWidth(col_id) %>px;\" class=\"<%= sheet.getCellFormatString(row_id,col_id) %>\" data-row_id=\"<%= row_id %>\" data-col_id=\"<%= col_id %>\" data-value=\"<%= sheet.getCellValue(row_id,col_id)%>\"><%= sheet.getCellDisplayById(row_id,col_id) %>	\n      <% }) %>\n    <% } else { %>\n      <% _.each(sheet.colIds(), function(col_id){ %>\n        <td id=\"<%= row_id %>-<%= col_id %>\" class=\"<%= sheet.getCellFormatString(row_id,col_id) %>\" data-row_id=\"<%= row_id %>\" data-col_id=\"<%= col_id %>\" data-value=\"<%= sheet.getCellValue(row_id,col_id)%>\"><%= sheet.getCellDisplayById(row_id,col_id) %>	\n      <% }) %>\n    <% } %>\n
\n<% }) %>\n");
var templateWrapper = function(template){
  return function(data){
    data = data || {};
    data.require = require;
    return template(data);
  }
};
for(i in module.exports) module.exports[i] = templateWrapper(module.exports[i]);

});
<commit_msg>updates<commit_after>if (typeof define !== 'function') { var define = require('amdefine')(module) }
define( function(require,exports,module){

var _ = require('underscore');
var helpers = require('es_client/helpers');
module.exports = module.exports || {};
module.exports['cell_format_dialog'] = _.template("
[close]

Format Cell
\n
bg red
\n
bg white
\n
money
\n");
module.exports['col_menu'] = _.template("
\n
\n

\n

\n
\n
\n

\n");
module.exports['col_menu'] = _.template("
\n
\n

\n

\n
\n
\n

\n");
/*isislab*/
//module.exports['cell_menu'] = _.template("
\n

\n

\n");
  module.exports['cell_menu'] = _.template("
\n

\n

\n");
/*end isislab*/

module.exports['es_container'] = _.template("
\n
\n

\n

 \n    \n    \n\n

\n
\n
\n

\n

 \n

\n

\n
\n
\n

\n
\n

\n
\n");
module.exports['expression_editor'] = _.template("<textarea class=\"es-expression-editor-input\" type='text'></textarea>\n");
module.exports['function_menu'] = _.template("
\n<% _.each(eh.userFunctions,function(func){ %>\n  <% if(!func || !func.def){ return }; %>\n  <li class=\"es-menu-button\" data-action=<%= func.def %> > <%= func.def %> - <%= func.desc  %>
\n<% }); %>\n
\n");
module.exports['import_dialog'] = _.template("
[close]

Import CSV
\n<form action=\"/import/csv\" method=\"post\" enctype=\"multipart/form-data\">\n  <input type=\"file\" name=\"csv_file\"><input type='submit' value='Upload'>\n  <input type=\"hidden\" name=\"sheet_id\" value=\"<%=sheet_id%>\">\n</form>\n\n\n");
module.exports['row_menu'] = _.template("
\n
\n

\n
\n
\n

\n");
module.exports['sheet_list'] = _.template("
\n<% var _ = require('underscore'); %>\n<% var cls = \"\" %>\n<% sheets.each(function(sheet){ %>\n\t<li class=\"es-menu-button\" id=<%=sheet.id%> > \n  \t<%=sheet.meta.title%> \n  \t<form class=\"es-sheet-edit-form\" style=\"display:none;float:left;padding-top:5px;height:22px;width:155px;\">\n    \t<input class='es-sheet-input-name' type=\"text\" style=\"width: 145px; font-size: 16px; border: 1px solid #ccc;\" value=\"<%=sheet.meta.title%>\">\n    \t<input class='es-sheet-input-id' type=\"hidden\" value=\"<%=sheet.id%>\">\n  \t</form>\n \t\t<button class=\"es-sheet-control\" id=\"delete-sheet\" data-sheet-id=\"<%=sheet.id%>\"></button>\n  \t<button class=\"es-sheet-control\" id=\"rename-sheet\" data-sheet-id=\"<%=sheet.id%>\"></button>\n  \t

\n\t
\n<%});%>\n
\n
\n\t

\n\t<a href=\"/s/<%=current_sheet_id%>.csv\" target=_blank>

\n\t
Import CSV
\n
\n");
module.exports['sheet_table'] = _.template("<div id=\"es-table-<%= id %>\" class=\"es-table-view\">\n  <table id=\"es-column-headers-<%=id%>\" class=\"es-column-headers es-table\">\n

\n

\n
\n  <table id=\"es-row-headers-<%=id%>\" class=\"es-row-headers es-table\">\n

\n

\n
\n  <div id=\"es-grid-container-<%= id %>\" class=\"es-grid-container\">\n    <table id=\"es-grid-<%= id %>\" class=\"es-grid es-table\">\n

\n      <tbody id=\"es-data-table-<%=id%>\">
\n
\n
\n
\n
ES
\n
\n
\n");
module.exports['table'] = _.template("<% var _ = require('underscore'); %>\n<% var clsAry = ['even','odd']; %>\n<% _.each(sheet.rowIds(), function(row_id,i){ %>\n<% if(i == 0){var cls = 'first'} else {var cls = clsAry[i % 2]} %>\n  <tr id=\"<%= row_id %>\" class=\"es-table-row es-row-<%= cls %>\" data-row_id=\"<%= row_id %>\" style=\"height:<%= sheet.getRowHeight(row_id) %>px;\">\n    <% if(i == 0) { %>\n      <% _.each(sheet.colIds(), function(col_id){ %>\n        <td id=\"<%= row_id %>-<%= col_id %>\" style=\"width:<%= sheet.getColWidth(col_id) %>px;\" class=\"<%= sheet.getCellFormatString(row_id,col_id) %>\" data-row_id=\"<%= row_id %>\" data-col_id=\"<%= col_id %>\" data-value=\"<%= sheet.getCellValue(row_id,col_id)%>\"><%= sheet.getCellDisplayById(row_id,col_id) %>	\n      <% }) %>\n    <% } else { %>\n      <% _.each(sheet.colIds(), function(col_id){ %>\n        <td id=\"<%= row_id %>-<%= col_id %>\" class=\"<%= sheet.getCellFormatString(row_id,col_id) %>\" data-row_id=\"<%= row_id %>\" data-col_id=\"<%= col_id %>\" data-value=\"<%= sheet.getCellValue(row_id,col_id)%>\"><%= sheet.getCellDisplayById(row_id,col_id) %>	\n      <% }) %>\n    <% } %>\n
\n<% }) %>\n");
var templateWrapper = function(template){
  return function(data){
    data = data || {};
    data.require = require;
    return template(data);
  }
};
for(i in module.exports) module.exports[i] = templateWrapper(module.exports[i]);

});
<|endoftext|>


<commit_before>define(function() {

  'use strict';

  return {
    byExtension: {
      '7z': 'application/x-7z-compressed',
      ace: 'application/x-ace-compressed',
      adf: 'application/x-amiga-disk-format',
      adz: 'application/gzip; compressed-type=application/x-amiga-disk-format',
      aif: 'audio/x-aiff',
      aiff: 'audio/x-aiff',
      avi: 'video/x-avi',
      bat: 'application/x-bat',
      bmp: 'image/bmp',
      bz: 'application/x-bzip',
      bz2: 'application/x-bzip2',
      class: 'application/x-java-class',
      com: 'application/x-exe-msdos-simple',
      dll: 'application/x-exe-ambiguous',
      dms: 'application/x-disk-masher-system',
      exe: 'application/x-exe-ambiguous',
      flc: 'video/x-flic',
      fli: 'video/x-flic',
      flv: 'video/x-flv',
      gif: 'image/gif',
      hlp: 'application/x-winhelp',
      ico: 'image/x-icon',
      jpg: 'image/jpeg',
      jpeg: 'image/jpeg',
      lha: 'application/x-lha',
      mid: 'audio/midi',
      midi: 'audio/midi',
      mov: 'video/quicktime',
      ogg: 'application/ogg',
      pct: 'image/x-pict',
      pcx: 'image/x-pcx',
      pic: 'image/x-pict',
      pict: 'image/x-pict',
      png: 'image/png',
      psd: 'image/x-photoshop',
      rar: 'application/x-rar-compressed',
      rsrc: 'application/x-mac-resource-fork',
      sit: 'application/x-stuffit',
      swf: 'application/x-shockwave-flash',
      tar: 'application/x-tar',
      tgz: 'application/gzip; compressed-type=application/x-tar',
      tiff: 'image/tiff',
      wav: 'audio/x-wav',
      wri: 'application/x-mswrite',
      zip: 'application/zip',
    },
    byMacResourceType: {
      '8BIM': 'image/x-photoshop-image-resource-block',
      ACHR: 'application/x-world-builder-character',
      ACOD: 'application/x-world-builder-code',
    },
    byMacFileType: {
      AIFF: 'audio/x-aiff',
      MOOV: 'video/quicktime',
      MV93: 'application/x-director',
      'M!93': 'application/x-director',
    },
  };

});
<commit_msg>Add entry for .jar<commit_after>define(function() {

  'use strict';

  return {
    byExtension: {
      '7z': 'application/x-7z-compressed',
      ace: 'application/x-ace-compressed',
      adf: 'application/x-amiga-disk-format',
      adz: 'application/gzip; compressed-type=application/x-amiga-disk-format',
      aif: 'audio/x-aiff',
      aiff: 'audio/x-aiff',
      avi: 'video/x-avi',
      bat: 'application/x-bat',
      bmp: 'image/bmp',
      bz: 'application/x-bzip',
      bz2: 'application/x-bzip2',
      class: 'application/x-java-class',
      com: 'application/x-exe-msdos-simple',
      dll: 'application/x-exe-ambiguous',
      dms: 'application/x-disk-masher-system',
      exe: 'application/x-exe-ambiguous',
      flc: 'video/x-flic',
      fli: 'video/x-flic',
      flv: 'video/x-flv',
      gif: 'image/gif',
      hlp: 'application/x-winhelp',
      ico: 'image/x-icon',
      jar: 'application/zip',
      jpg: 'image/jpeg',
      jpeg: 'image/jpeg',
      lha: 'application/x-lha',
      mid: 'audio/midi',
      midi: 'audio/midi',
      mov: 'video/quicktime',
      ogg: 'application/ogg',
      pct: 'image/x-pict',
      pcx: 'image/x-pcx',
      pic: 'image/x-pict',
      pict: 'image/x-pict',
      png: 'image/png',
      psd: 'image/x-photoshop',
      rar: 'application/x-rar-compressed',
      rsrc: 'application/x-mac-resource-fork',
      sit: 'application/x-stuffit',
      swf: 'application/x-shockwave-flash',
      tar: 'application/x-tar',
      tgz: 'application/gzip; compressed-type=application/x-tar',
      tiff: 'image/tiff',
      wav: 'audio/x-wav',
      wri: 'application/x-mswrite',
      zip: 'application/zip',
    },
    byMacResourceType: {
      '8BIM': 'image/x-photoshop-image-resource-block',
      ACHR: 'application/x-world-builder-character',
      ACOD: 'application/x-world-builder-code',
    },
    byMacFileType: {
      AIFF: 'audio/x-aiff',
      MOOV: 'video/quicktime',
      MV93: 'application/x-director',
      'M!93': 'application/x-director',
    },
  };

});
<|endoftext|>


<commit_before>const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gdk = imports.gi.Gdk;
const Gtk = imports.gi.Gtk;

Gio.resources_register(Gio.resource_load('org.gnome.Gnometa.gresource'));

const AsyncContinuous = imports.AsyncContinuous;
const CompilerView = imports.CompilerView;
const InputView = imports.InputView;
const MatchTreeView = imports.MatchTreeView;
const OutputView = imports.OutputView;
const SplitView = imports.SplitView;
const TextView = imports.TextView;
const Options = imports.options;
const UiHelper = imports.UiHelperClient;
const Utils = imports.Utils;

// Options:
const CmdOptions = [
  {
    name: 'compiler',
    shortName: 'c',
    requireArgument: true,
    defaultValue: null,
    help: 'Compiler to use',
  },
  {
    name: 'entry-point',
    shortName: 'e',
    requireArgument: true,
    defaultValue: null,
    help: 'Entry point for the compiler to use',
  },
  {
    name: 'input',
    shortName: 'i',
    requireArgument: true,
    defaultValue: null,
    help: 'Input to give to the compiler',
  },
  {
    name: 'help',
    shortName: 'h',
    requireArgument: false,
    defaultValue: false,
    help: 'Print this screen',
  }
];

let repositionPanedAt = function(paned, ratio, param) {
  if (paned.position == 0) {
    let alloc = paned.get_allocation();
    if (alloc.width == alloc.height == 1)
      alloc = paned.get_parent().get_allocation();
    paned.position = alloc[param] * ratio;
  }
};

let start = function() {
  let config = Options.parseArguments(CmdOptions, ARGV);

  if (config.options.help) {
    Options.printHelp('gnometa', CmdOptions);
    return -1;
  }

  if (config.options.compiler && !config.options['entry-point']) {
    print('Cannot use custom compiler without an entry point');
    return -1;
  }

  UiHelper.start();

  // Source mapping
  let OMetaMap = null;

  let ometaFile = function(id) {
    if (id < 0) return null;
    let sitem = OMetaMap.map[id];
    let filename = OMetaMap.filenames[sitem[0]];
    return config.options.compiler ? filename : ('../' + filename);
  };

  let ometaRange = function(id) {
    if (id < 0) return [0, 0];
    let sitem = OMetaMap.map[id];
    return [sitem[1], sitem[2]];
  };

  let ometaText = function(id) {
    if (id < 0) return '';
    let range = ometaRange(id);
    return Utils.loadFile(ometaFile(id)).slice(range[0], range[1]);
  };

  let source = Utils.loadFile(config.options.input);
  let compilerName = config.options.compiler ? 'view0' : 'OMeta';
  let compilerRule = config.options.compiler ? config.options['entry-point'].split('.')[1] : 'topLevel';

  // Structure tree
  let _structureTreeIdx = -1;

  //
  Gtk.init(null, null);

  //
  let builder = Gtk.Builder.new_from_resource('/org/gnome/Gnometa/ui.ui');
  let widget = function(name) { return builder.get_object(name); };

  let paned = new SplitView.SplitView();
  widget('main-paned').remove(widget('main-paned').get_child1());
  widget('main-paned').add1(paned);

  let textview = new InputView.InputView({ name: 'view0', language: 'js' });
  paned.addWidget(textview);

  let matchtreeview = new MatchTreeView.MatchTreeView();
  widget('compiler-paned').add1(matchtreeview);

  let compilerview = new CompilerView.CompilerView();
  widget('compiler-paned').add2(compilerview);

  let structview = new OutputView.OutputView({ name: 'view1' });
  paned.addWidget(structview);

  //
  let compilerArgs = function(highlightId, hintId) {
    let ret = [ometaFile(highlightId),
               Utils.loadFile(ometaFile(highlightId))].concat(ometaRange(highlightId));
    if (hintId && ret[0] === ometaFile(hintId))
      return ret.concat(ometaRange(hintId));
    return ret.concat([0, 0]);
  };

  // Translation
  let translate = AsyncContinuous.createContinuous(function(ac, text) {
    UiHelper.commands.translate(compilerName, text, compilerRule, 'view0', function(error, ret) {
      if (error) {
        Utils.printError(error);
        textview.hightlightRange('error', error.idx, text.length - 1);
        ac.done();
        return;
      }
      textview.removeHighlightRange('error');
      ac.done();
    }.bind(this));
  });
  let getBestMatch = function(offset) {
    UiHelper.commands.matchStructure('view0', offset, offset, 'view0', function(error, ret) {
      if (error) return Utils.printError(error);
      UiHelper.commands.getBestMatch('view0', function(error, ret) {
        if (error) return Utils.printError(error);
        let  [idx, match] = ret;
        _structureTreeIdx = idx;
        textview.hightlightRange('highlight', match.start.idx, match.stop.idx);
        compilerview.setData.apply(compilerview, compilerArgs(match.id));
        structview.setData(match.value);
      }.bind(this));
    }.bind(this));
    UiHelper.commands.getStructure('view0', offset, offset, function(error, ret) {
      if (error) return Utils.printError(error);
      matchtreeview.setData(ret, ometaText);
    }.bind(this));
  };
  let selectionChanged = function(startOffset, endOffset) {
    UiHelper.commands.matchStructure('view0', startOffset, endOffset, 'view0', function(error, ret) {
      textview.removeSelection();
      if (error) return Utils.printError(error);
      _structureTreeIdx = 0;
      UiHelper.commands.getMatch('view0', _structureTreeIdx, function(error, ret) {
        if (error) return Utils.printError(error);
        let [idx, match] = ret;
        _structureTreeIdx = idx;
        textview.hightlightRange('highlight', match.start.idx, match.stop.idx);
        compilerview.setData.apply(compilerview, compilerArgs(match.id));
        structview.setData(match.value);
      }.bind(this));
    }.bind(this));
    UiHelper.commands.getStructure('view0', startOffset, endOffset, function(error, ret) {
      if (error) return Utils.printError(error);
      matchtreeview.setData(ret, ometaText);
    }.bind(this));
  };
  let alternateMenu = function() {
    compilerview.get_parent().show();
    repositionPanedAt(compilerview.get_parent().get_parent(), 2.0 / 3, 'height');
    repositionPanedAt(compilerview.get_parent(), 1.0 / 2, 'width');
  };

  //
  textview.setData(source);

  textview.connect('changed', function(wid, text) {
    translate.run(text);
  }.bind(this));

  textview.connect('offset-changed', function(wid, offset) {
    getBestMatch(offset);
  }.bind(this));
  textview.connect('selection-changed', function(wid, startOffset, endOffset) {
    selectionChanged(startOffset, endOffset);
  });

  matchtreeview.onHover(function(structure) {
    textview.removeSelection();
    textview.hightlightRange('highlight', structure.start.idx, structure.stop.idx);
    compilerview.setData.apply(compilerview, compilerArgs(structure.id,
                                                          structure.call));
    structview.setData(structure.value);
  });
  matchtreeview.onClick(function(structure) {
    textview.removeSelection();
    textview.hightlightRange('highlight', structure.start.idx, structure.stop.idx);
    if (structure.call)
      compilerview
    compilerview.setData.apply(compilerview, compilerArgs(structure.id,
                                                          structure.call));
    structview.setData(structure.value);
    matchtreeview.setData(structure, ometaText);
  });

  {
    let input = config.options.compiler ? Utils.loadFile(config.options.compiler) : null;
    UiHelper.commands.compile(compilerName, input, function(error, ret) {
      if (error) return Utils.printError(error);

      OMetaMap = ret;
      if (config.options.compiler)
        OMetaMap.filenames[OMetaMap.filenames.length - 1] = config.options.compiler;
      else {
        // Using OMeta.
        translate.run(source);
        return;
      }

      let entryPoint = config.options['entry-point'].split('.');
      UiHelper.commands.compilerConfigure(compilerName, entryPoint[0], entryPoint[1], function(error, ret) {
        if (error) return Utils.printError(error);
        translate.run(source);
      });
    });
  }

  //
  let win = widget('main-window');
  win.set_titlebar(widget('titlebar'));
  widget('add-button').connect('clicked', function() { paned.addWidget(new OutputView.OutputView({ name: 'view' + paned.nbWidgets() })); }.bind(this));
  widget('remove-button').connect('clicked', function() { paned.removeLastWidget(); }.bind(this));
  widget('close-button').connect('clicked', function() { win.hide(); Gtk.main_quit(); }.bind(this));
  win.connect('key-press-event', function(w, event) {
    let keyval = event.get_keyval()[1];
    switch (keyval) {
    case Gdk.KEY_F7: paned.shrinkFocusedChild(10); break;
    case Gdk.KEY_F8: paned.growFocusedChild(10); break;
    case Gdk.KEY_Escape: compilerview.get_parent().hide(); break;
    case Gdk.KEY_Alt_L: alternateMenu(); break;
    }
    return false;
  }.bind(this));
  win.resize(800, 600);
  win.show();

  Gtk.main();
};

start();
<commit_msg>ui: clarify usage of entry point argument<commit_after>const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const Gdk = imports.gi.Gdk;
const Gtk = imports.gi.Gtk;

Gio.resources_register(Gio.resource_load('org.gnome.Gnometa.gresource'));

const AsyncContinuous = imports.AsyncContinuous;
const CompilerView = imports.CompilerView;
const InputView = imports.InputView;
const MatchTreeView = imports.MatchTreeView;
const OutputView = imports.OutputView;
const SplitView = imports.SplitView;
const TextView = imports.TextView;
const Options = imports.options;
const UiHelper = imports.UiHelperClient;
const Utils = imports.Utils;

// Options:
const CmdOptions = [
  {
    name: 'compiler',
    shortName: 'c',
    requireArgument: true,
    defaultValue: null,
    help: 'Compiler to use',
  },
  {
    name: 'entry-point',
    shortName: 'e',
    requireArgument: true,
    defaultValue: null,
    help: 'Entry point for the compiler to use (Grammar.Rule)',
  },
  {
    name: 'input',
    shortName: 'i',
    requireArgument: true,
    defaultValue: null,
    help: 'Input to give to the compiler',
  },
  {
    name: 'help',
    shortName: 'h',
    requireArgument: false,
    defaultValue: false,
    help: 'Print this screen',
  }
];

let repositionPanedAt = function(paned, ratio, param) {
  if (paned.position == 0) {
    let alloc = paned.get_allocation();
    if (alloc.width == alloc.height == 1)
      alloc = paned.get_parent().get_allocation();
    paned.position = alloc[param] * ratio;
  }
};

let start = function() {
  let config = Options.parseArguments(CmdOptions, ARGV);

  if (config.options.help) {
    Options.printHelp('gnometa', CmdOptions);
    return -1;
  }

  if (config.options.compiler && !config.options['entry-point']) {
    print('Cannot use custom compiler without an entry point');
    return -1;
  }

  UiHelper.start();

  // Source mapping
  let OMetaMap = null;

  let ometaFile = function(id) {
    if (id < 0) return null;
    let sitem = OMetaMap.map[id];
    let filename = OMetaMap.filenames[sitem[0]];
    return config.options.compiler ? filename : ('../' + filename);
  };

  let ometaRange = function(id) {
    if (id < 0) return [0, 0];
    let sitem = OMetaMap.map[id];
    return [sitem[1], sitem[2]];
  };

  let ometaText = function(id) {
    if (id < 0) return '';
    let range = ometaRange(id);
    return Utils.loadFile(ometaFile(id)).slice(range[0], range[1]);
  };

  let source = Utils.loadFile(config.options.input);
  let compilerName = config.options.compiler ? 'view0' : 'OMeta';
  let compilerRule = config.options.compiler ? config.options['entry-point'].split('.')[1] : 'topLevel';

  // Structure tree
  let _structureTreeIdx = -1;

  //
  Gtk.init(null, null);

  //
  let builder = Gtk.Builder.new_from_resource('/org/gnome/Gnometa/ui.ui');
  let widget = function(name) { return builder.get_object(name); };

  let paned = new SplitView.SplitView();
  widget('main-paned').remove(widget('main-paned').get_child1());
  widget('main-paned').add1(paned);

  let textview = new InputView.InputView({ name: 'view0', language: 'js' });
  paned.addWidget(textview);

  let matchtreeview = new MatchTreeView.MatchTreeView();
  widget('compiler-paned').add1(matchtreeview);

  let compilerview = new CompilerView.CompilerView();
  widget('compiler-paned').add2(compilerview);

  let structview = new OutputView.OutputView({ name: 'view1' });
  paned.addWidget(structview);

  //
  let compilerArgs = function(highlightId, hintId) {
    let ret = [ometaFile(highlightId),
               Utils.loadFile(ometaFile(highlightId))].concat(ometaRange(highlightId));
    if (hintId && ret[0] === ometaFile(hintId))
      return ret.concat(ometaRange(hintId));
    return ret.concat([0, 0]);
  };

  // Translation
  let translate = AsyncContinuous.createContinuous(function(ac, text) {
    UiHelper.commands.translate(compilerName, text, compilerRule, 'view0', function(error, ret) {
      if (error) {
        Utils.printError(error);
        textview.hightlightRange('error', error.idx, text.length - 1);
        ac.done();
        return;
      }
      textview.removeHighlightRange('error');
      ac.done();
    }.bind(this));
  });
  let getBestMatch = function(offset) {
    UiHelper.commands.matchStructure('view0', offset, offset, 'view0', function(error, ret) {
      if (error) return Utils.printError(error);
      UiHelper.commands.getBestMatch('view0', function(error, ret) {
        if (error) return Utils.printError(error);
        let  [idx, match] = ret;
        _structureTreeIdx = idx;
        textview.hightlightRange('highlight', match.start.idx, match.stop.idx);
        compilerview.setData.apply(compilerview, compilerArgs(match.id));
        structview.setData(match.value);
      }.bind(this));
    }.bind(this));
    UiHelper.commands.getStructure('view0', offset, offset, function(error, ret) {
      if (error) return Utils.printError(error);
      matchtreeview.setData(ret, ometaText);
    }.bind(this));
  };
  let selectionChanged = function(startOffset, endOffset) {
    UiHelper.commands.matchStructure('view0', startOffset, endOffset, 'view0', function(error, ret) {
      textview.removeSelection();
      if (error) return Utils.printError(error);
      _structureTreeIdx = 0;
      UiHelper.commands.getMatch('view0', _structureTreeIdx, function(error, ret) {
        if (error) return Utils.printError(error);
        let [idx, match] = ret;
        _structureTreeIdx = idx;
        textview.hightlightRange('highlight', match.start.idx, match.stop.idx);
        compilerview.setData.apply(compilerview, compilerArgs(match.id));
        structview.setData(match.value);
      }.bind(this));
    }.bind(this));
    UiHelper.commands.getStructure('view0', startOffset, endOffset, function(error, ret) {
      if (error) return Utils.printError(error);
      matchtreeview.setData(ret, ometaText);
    }.bind(this));
  };
  let alternateMenu = function() {
    compilerview.get_parent().show();
    repositionPanedAt(compilerview.get_parent().get_parent(), 2.0 / 3, 'height');
    repositionPanedAt(compilerview.get_parent(), 1.0 / 2, 'width');
  };

  //
  textview.setData(source);

  textview.connect('changed', function(wid, text) {
    translate.run(text);
  }.bind(this));

  textview.connect('offset-changed', function(wid, offset) {
    getBestMatch(offset);
  }.bind(this));
  textview.connect('selection-changed', function(wid, startOffset, endOffset) {
    selectionChanged(startOffset, endOffset);
  });

  matchtreeview.onHover(function(structure) {
    textview.removeSelection();
    textview.hightlightRange('highlight', structure.start.idx, structure.stop.idx);
    compilerview.setData.apply(compilerview, compilerArgs(structure.id,
                                                          structure.call));
    structview.setData(structure.value);
  });
  matchtreeview.onClick(function(structure) {
    textview.removeSelection();
    textview.hightlightRange('highlight', structure.start.idx, structure.stop.idx);
    if (structure.call)
      compilerview
    compilerview.setData.apply(compilerview, compilerArgs(structure.id,
                                                          structure.call));
    structview.setData(structure.value);
    matchtreeview.setData(structure, ometaText);
  });

  {
    let input = config.options.compiler ? Utils.loadFile(config.options.compiler) : null;
    UiHelper.commands.compile(compilerName, input, function(error, ret) {
      if (error) return Utils.printError(error);

      OMetaMap = ret;
      if (config.options.compiler)
        OMetaMap.filenames[OMetaMap.filenames.length - 1] = config.options.compiler;
      else {
        // Using OMeta.
        translate.run(source);
        return;
      }

      let entryPoint = config.options['entry-point'].split('.');
      UiHelper.commands.compilerConfigure(compilerName, entryPoint[0], entryPoint[1], function(error, ret) {
        if (error) return Utils.printError(error);
        translate.run(source);
      });
    });
  }

  //
  let win = widget('main-window');
  win.set_titlebar(widget('titlebar'));
  widget('add-button').connect('clicked', function() { paned.addWidget(new OutputView.OutputView({ name: 'view' + paned.nbWidgets() })); }.bind(this));
  widget('remove-button').connect('clicked', function() { paned.removeLastWidget(); }.bind(this));
  widget('close-button').connect('clicked', function() { win.hide(); Gtk.main_quit(); }.bind(this));
  win.connect('key-press-event', function(w, event) {
    let keyval = event.get_keyval()[1];
    switch (keyval) {
    case Gdk.KEY_F7: paned.shrinkFocusedChild(10); break;
    case Gdk.KEY_F8: paned.growFocusedChild(10); break;
    case Gdk.KEY_Escape: compilerview.get_parent().hide(); break;
    case Gdk.KEY_Alt_L: alternateMenu(); break;
    }
    return false;
  }.bind(this));
  win.resize(800, 600);
  win.show();

  Gtk.main();
};

start();
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

treeherder.controller('PluginCtrl', [
    '$scope', '$rootScope', '$location', 'thUrl', 'ThJobClassificationModel',
    'thClassificationTypes', 'ThJobModel', 'thEvents', 'dateFilter', 'thDateFormat',
    'numberFilter', 'ThBugJobMapModel', 'thResultStatus', 'thJobFilters',
    'ThResultSetModel', 'ThLog', '$q', 'thPinboard', 'ThJobArtifactModel',
    'thBuildApi', 'thNotify', 'ThJobLogUrlModel', 'ThModelErrors', 'thTabs',
    '$timeout', 'thJobSearchStr',
    function PluginCtrl(
        $scope, $rootScope, $location, thUrl, ThJobClassificationModel,
        thClassificationTypes, ThJobModel, thEvents, dateFilter, thDateFormat,
        numberFilter, ThBugJobMapModel, thResultStatus, thJobFilters,
        ThResultSetModel, ThLog, $q, thPinboard, ThJobArtifactModel,
        thBuildApi, thNotify, ThJobLogUrlModel, ThModelErrors, thTabs,
        $timeout, thJobSearchStr) {

        var $log = new ThLog("PluginCtrl");

        $scope.job = {};
        $scope.artifacts = {};

        var getJobSearchStrHref = function(jobSearchStr){

            var absUrl = $location.absUrl();
            var delimiter = '?';

            // If there are parameters the parameter delimiter &
            // should be used
            if(absUrl.indexOf('?') !== -1){
                delimiter = '&';
            }

            return absUrl + delimiter + 'filter-searchStr=' +
                   encodeURIComponent(jobSearchStr);
        };

        $scope.filterByJobSearchStr = function(jobSearchStr) {
            thJobFilters.replaceFilter('searchStr', jobSearchStr || null);
        };

        // this promise will void all the ajax requests
        // triggered by selectJob once resolved
        var selectJobPromise = null;
        var selectJobRetryPromise = null;

        var selectJob = function(job_id) {
            // set the scope variables needed for the job detail panel
            if (job_id) {
                $scope.job_detail_loading = true;
                if(selectJobPromise !== null){
                    $log.debug("timing out previous job request");
                    selectJobPromise.resolve();
                }
                selectJobPromise = $q.defer();

                if( selectJobRetryPromise !== null){
                    $timeout.cancel(selectJobRetryPromise);
                }
                $scope.job = {};
                $scope.artifacts = {};
                $scope.job_details = [];
                var jobDetailPromise = ThJobModel.get(
                    $scope.repoName, job_id,
                    {timeout: selectJobPromise});

                var buildapiArtifactPromise = ThJobArtifactModel.get_list(
                    {name: "buildapi", "type": "json", job_id: job_id},
                    {timeout: selectJobPromise});

                var jobInfoArtifactPromise = ThJobArtifactModel.get_list({
                    name: "Job Info", "type": "json", job_id: job_id},
                    {timeout: selectJobPromise});

                var jobLogUrlPromise = ThJobLogUrlModel.get_list(
                    job_id,
                    {timeout: selectJobPromise});

                return $q.all([
                    jobDetailPromise,
                    buildapiArtifactPromise,
                    jobInfoArtifactPromise,
                    jobLogUrlPromise
                ]).then(function(results){
                    //the first result comes from the job detail promise
                    $scope.job = results[0];
                    $scope.eta = $scope.job.get_current_eta();
                    $scope.eta_abs = Math.abs($scope.job.get_current_eta());
                    $scope.typical_eta = $scope.job.get_typical_eta();
                    // this is a bit hacky but for now talos is the only exception we have
                    if($scope.job.job_group_name.indexOf('Talos') !== -1){
                        $scope.tabService.tabs.talos.enabled = true;
                        if(thResultStatus($scope.job) === 'success'){
                            $scope.tabService.selectedTab = 'talos';
                        }else{
                            $scope.tabService.selectedTab = 'failureSummary';
                        }
                    }else{
                        $scope.tabService.tabs.talos.enabled = false;
                    }
                    // the second result come from the buildapi artifact promise
                    var buildapi_artifact = results[1];

                    // if this is a buildbot job use the buildername for searching
                    if (buildapi_artifact.length > 0 &&
                        _.has(buildapi_artifact[0], 'blob')){
                        // this is needed to cancel/retrigger jobs
                        $scope.artifacts.buildapi = buildapi_artifact[0];
                    }

                    // filtering values for data fields and signature
                    $scope.jobSearchStr = thJobSearchStr($scope.job);
                    $scope.jobSearchSignature = $scope.job.signature;
                    $scope.jobSearchStrHref = getJobSearchStrHref($scope.jobSearchStr);
                    $scope.jobSearchSignatureHref = getJobSearchStrHref($scope.job.signature);

                    // the third result comes from the job info artifact promise
                    var jobInfoArtifact = results[2];
                    if (jobInfoArtifact.length > 0) {
                        // The job artifacts may have many "Job Info" blobs so
                        // we merge them here to make displaying them in the UI
                        // easier.
                        $scope.job_details = jobInfoArtifact.reduce(function(result, artifact) {
                          if (artifact.blob && Array.isArray(artifact.blob.job_details)) {
                            result = result.concat(artifact.blob.job_details);
                          }
                          return result;
                        }, []);
                    }
                    // the fourth result comes from the jobLogUrl artifact
                    // exclude the json log URLs
                    $scope.job_log_urls = _.reject(results[3], {name: 'mozlog_json'});

                    var logsNotParsed = [];
                    $scope.jobLogsAllParsed = _.every($scope.job_log_urls, function(jlu) {
                        if(jlu.parse_status === 'pending'){
                            logsNotParsed.push(jlu);
                            return false;
                        }else{
                            return true;
                        }
                    });
                    // retry to fetch the job info if a log hasn't been parsed yet
                    if(logsNotParsed.length > 0){
                        // first parse all the unparsed logs
                        $q.all(_.map(logsNotParsed, function(log){return log.parse();}))
                        .then(function(parseLogResponses){
                            // then retry to fetch the job info if the parse requests
                            // were successful
                            if(_.every(
                                parseLogResponses,
                                function(parseLogResponse){return parseLogResponse.status === 200;}
                            )){
                                selectJobRetryPromise = $timeout(function(){
                                    // the failure summary tab update must also be triggered here,
                                    // otherwise it will never update.
                                    thTabs.tabs.failureSummary.update();
                                    // refetch the job data details
                                    selectJobAndRender(job_id);
                                }, 5000);
                            }
                        });
                    }
                    $scope.lvUrl = thUrl.getLogViewerUrl($scope.job.id);
                    $scope.lvFullUrl = location.origin + "/" + $scope.lvUrl;
                    $scope.resultStatusShading = "result-status-shading-" + thResultStatus($scope.job);

                    updateVisibleFields();
                    $scope.updateClassifications();
                    $scope.updateBugs();

                    $scope.job_detail_loading = false;
                });
            }
        };

        var updateVisibleFields = function() {
                var undef = "",
                    duration = "";
                // fields that will show in the job detail panel
                $scope.visibleFields = {
                    "Job name": $scope.job.job_type_name || undef,
                    "Build": $scope.job.build_architecture + " " +
                             $scope.job.build_platform  + " " +
                             $scope.job.build_os || undef
                };

                // if the buildername exists, add it as a field
                if ($scope.artifacts.buildapi) {
                    $scope.visibleFields.Buildername = $scope.artifacts.buildapi.blob.buildername;
                }

                // time fields to show in detail panel, but that should be grouped together
                $scope.visibleTimeFields = {
                    requestTime: dateFilter($scope.job.submit_timestamp*1000,
                                            thDateFormat)
                };

                /*
                    display appropriate times and duration

                    If start time is 0, then duration should be from requesttime to now
                    If we have starttime and no endtime, then duration should be starttime to now
                    If we have both starttime and endtime, then duration will be between those two
                */
                var endtime = $scope.job.end_timestamp || Date.now()/1000;
                var starttime = $scope.job.start_timestamp || $scope.job.submit_timestamp;
                duration = numberFilter((endtime-starttime)/60, 0) + " minute(s)";

                $scope.visibleTimeFields.duration = duration;

                if ($scope.job.start_timestamp) {
                    $scope.visibleTimeFields.startTime = dateFilter(
                        $scope.job.start_timestamp*1000, thDateFormat);
                }
                if ($scope.job.end_timestamp) {
                    $scope.visibleTimeFields.endTime = dateFilter(
                        $scope.job.end_timestamp*1000, thDateFormat);
                }

        };

        $scope.getCountPinnedJobs = function() {
            return thPinboard.count.numPinnedJobs;
        };

        $scope.togglePinboardVisibility = function() {
            $scope.isPinboardVisible = !$scope.isPinboardVisible;
        };

        $scope.$watch('getCountPinnedJobs()', function(newVal, oldVal) {
            if (oldVal === 0 && newVal > 0) {
                $scope.isPinboardVisible = true;
            }
        });

        $scope.canCancel = function() {
            return $scope.job &&
                   ($scope.job.state === "pending" || $scope.job.state === "running");
        };

        /**
         * Get the build_id needed to cancel or retrigger from the currently
         * selected job.
         */
        var getBuildbotRequestId = function() {
            if ($scope.artifacts.buildapi) {
                return $scope.artifacts.buildapi.blob.request_id;
            }
        };

        $scope.retriggerJob = function() {
            if ($scope.user.loggedin) {
                // Only enter a retrigger if we have a valid loaded job, if the user
                // tries to retrigger eg. via shortcut before the load we warn them
                if ($scope.job.id) {
                    // The logic here is somewhat complicated because we need to support
                    // two use cases the first is the case where we notify a system
                    // other then buildbot that a retrigger has been requested. The
                    // second is when we have the buildapi id and need to send a request
                    // to the self serve api (which does not listen over pulse!).
                    ThJobModel.retrigger($scope.repoName, $scope.job.id).then(function() {
                        // XXX: Remove this after 1134929 is resolved.
                        var requestId = getBuildbotRequestId();
                        if (requestId) {
                            return thBuildApi.retriggerJob($scope.repoName, requestId);
                        }
                    }).then(function() {
                        thNotify.send("Retriggered job (" + $scope.job.job_type_symbol + ")",
                                      'success');
                    }).catch(function(e) {
                        // Generic error eg. the user doesn't have LDAP access
                        thNotify.send(
                            ThModelErrors.format(e, "Unable to send retrigger"), 'danger');
                    });
                } else {
                    thNotify.send("Job not yet loaded for retrigger", 'warning');
                }
            } else {
                thNotify.send("Must be logged in to retrigger a job", 'danger');
            }
        };

        $scope.cancelJob = function() {
            // See note in retrigger logic.
            ThJobModel.cancel($scope.repoName, $scope.job.id).then(function() {
              // XXX: Remove this after 1134929 is resolved.
              var requestId = getBuildbotRequestId();
              if (requestId) {
                return thBuildApi.cancelJob($scope.repoName, requestId);
              }
            }).catch(function(e) {
                thNotify.send(
                    ThModelErrors.format(e, "Unable to cancel job"),
                    "danger", true
                );
            });
        };

        $scope.cancelAll = function(resultsetId) {
            var rs = ThResultSetModel.getResultSet($scope.repoName, resultsetId);
            thBuildApi.cancelAllJobs($scope.repoName, rs.revision);
        };

        /**
         * Test whether or not the selected job is a reftest
         */
        $scope.isReftest = function() {
            if ($scope.selectedJob) {
                return ($scope.selectedJob.job_group_name.indexOf("Reftest") !== -1);
            } else {
                return false;
            }
        };

        var selectJobAndRender = function(job_id){
            $scope.jobLoadedPromise = selectJob(job_id);
            $scope.jobLoadedPromise.then(function(){
                thTabs.showTab(thTabs.selectedTab, job_id);
            });
        };

        $rootScope.$on(thEvents.jobClick, function(event, job) {
            selectJobAndRender(job.id);
            $rootScope.selectedJob = job;
        });

        $rootScope.$on(thEvents.clearSelectedJob, function(event, job) {
            if(selectJobPromise !== null){
                $timeout.cancel(selectJobPromise);
            }
            if( selectJobRetryPromise !== null){
                $timeout.cancel(selectJobRetryPromise);
            }
        });

        $scope.bug_job_map_list = [];

        $scope.classificationTypes = thClassificationTypes;

        // load the list of existing classifications (including possibly a new one just
        // added).
        $scope.updateClassifications = function() {
            ThJobClassificationModel.get_list({job_id: $scope.job.id}).then(function(response) {
                $scope.classifications = response;
                $scope.job.note = $scope.classifications[0];
            });
        };

        // load the list of bug associations (including possibly new ones just
        // added).
        $scope.updateBugs = function() {
            if (_.has($scope.job, "id")) {
                ThBugJobMapModel.get_list({job_id: $scope.job.id}).then(function (response) {
                    $scope.bugs = response;
                });
            }
        };

        $rootScope.$on(thEvents.jobRetrigger, function(event, job) {
            $scope.retriggerJob();
        });

        $rootScope.$on(thEvents.jobsClassified, function(event, job) {
            $scope.updateClassifications();
        });

        $rootScope.$on(thEvents.bugsAssociated, function(event, job) {
            $scope.updateBugs();
        });

        $scope.pinboard_service = thPinboard;

        // expose the tab service properties on the scope
        $scope.tabService = thTabs;
    }
]);
<commit_msg>Bug 1057260 - Display full Job name in retrigger notification<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

treeherder.controller('PluginCtrl', [
    '$scope', '$rootScope', '$location', 'thUrl', 'ThJobClassificationModel',
    'thClassificationTypes', 'ThJobModel', 'thEvents', 'dateFilter', 'thDateFormat',
    'numberFilter', 'ThBugJobMapModel', 'thResultStatus', 'thJobFilters',
    'ThResultSetModel', 'ThLog', '$q', 'thPinboard', 'ThJobArtifactModel',
    'thBuildApi', 'thNotify', 'ThJobLogUrlModel', 'ThModelErrors', 'thTabs',
    '$timeout', 'thJobSearchStr',
    function PluginCtrl(
        $scope, $rootScope, $location, thUrl, ThJobClassificationModel,
        thClassificationTypes, ThJobModel, thEvents, dateFilter, thDateFormat,
        numberFilter, ThBugJobMapModel, thResultStatus, thJobFilters,
        ThResultSetModel, ThLog, $q, thPinboard, ThJobArtifactModel,
        thBuildApi, thNotify, ThJobLogUrlModel, ThModelErrors, thTabs,
        $timeout, thJobSearchStr) {

        var $log = new ThLog("PluginCtrl");

        $scope.job = {};
        $scope.artifacts = {};

        var getJobSearchStrHref = function(jobSearchStr){

            var absUrl = $location.absUrl();
            var delimiter = '?';

            // If there are parameters the parameter delimiter &
            // should be used
            if(absUrl.indexOf('?') !== -1){
                delimiter = '&';
            }

            return absUrl + delimiter + 'filter-searchStr=' +
                   encodeURIComponent(jobSearchStr);
        };

        $scope.filterByJobSearchStr = function(jobSearchStr) {
            thJobFilters.replaceFilter('searchStr', jobSearchStr || null);
        };

        // this promise will void all the ajax requests
        // triggered by selectJob once resolved
        var selectJobPromise = null;
        var selectJobRetryPromise = null;

        var selectJob = function(job_id) {
            // set the scope variables needed for the job detail panel
            if (job_id) {
                $scope.job_detail_loading = true;
                if(selectJobPromise !== null){
                    $log.debug("timing out previous job request");
                    selectJobPromise.resolve();
                }
                selectJobPromise = $q.defer();

                if( selectJobRetryPromise !== null){
                    $timeout.cancel(selectJobRetryPromise);
                }
                $scope.job = {};
                $scope.artifacts = {};
                $scope.job_details = [];
                var jobDetailPromise = ThJobModel.get(
                    $scope.repoName, job_id,
                    {timeout: selectJobPromise});

                var buildapiArtifactPromise = ThJobArtifactModel.get_list(
                    {name: "buildapi", "type": "json", job_id: job_id},
                    {timeout: selectJobPromise});

                var jobInfoArtifactPromise = ThJobArtifactModel.get_list({
                    name: "Job Info", "type": "json", job_id: job_id},
                    {timeout: selectJobPromise});

                var jobLogUrlPromise = ThJobLogUrlModel.get_list(
                    job_id,
                    {timeout: selectJobPromise});

                return $q.all([
                    jobDetailPromise,
                    buildapiArtifactPromise,
                    jobInfoArtifactPromise,
                    jobLogUrlPromise
                ]).then(function(results){
                    //the first result comes from the job detail promise
                    $scope.job = results[0];
                    $scope.eta = $scope.job.get_current_eta();
                    $scope.eta_abs = Math.abs($scope.job.get_current_eta());
                    $scope.typical_eta = $scope.job.get_typical_eta();
                    // this is a bit hacky but for now talos is the only exception we have
                    if($scope.job.job_group_name.indexOf('Talos') !== -1){
                        $scope.tabService.tabs.talos.enabled = true;
                        if(thResultStatus($scope.job) === 'success'){
                            $scope.tabService.selectedTab = 'talos';
                        }else{
                            $scope.tabService.selectedTab = 'failureSummary';
                        }
                    }else{
                        $scope.tabService.tabs.talos.enabled = false;
                    }
                    // the second result come from the buildapi artifact promise
                    var buildapi_artifact = results[1];

                    // if this is a buildbot job use the buildername for searching
                    if (buildapi_artifact.length > 0 &&
                        _.has(buildapi_artifact[0], 'blob')){
                        // this is needed to cancel/retrigger jobs
                        $scope.artifacts.buildapi = buildapi_artifact[0];
                    }

                    // filtering values for data fields and signature
                    $scope.jobSearchStr = thJobSearchStr($scope.job);
                    $scope.jobSearchSignature = $scope.job.signature;
                    $scope.jobSearchStrHref = getJobSearchStrHref($scope.jobSearchStr);
                    $scope.jobSearchSignatureHref = getJobSearchStrHref($scope.job.signature);

                    // the third result comes from the job info artifact promise
                    var jobInfoArtifact = results[2];
                    if (jobInfoArtifact.length > 0) {
                        // The job artifacts may have many "Job Info" blobs so
                        // we merge them here to make displaying them in the UI
                        // easier.
                        $scope.job_details = jobInfoArtifact.reduce(function(result, artifact) {
                          if (artifact.blob && Array.isArray(artifact.blob.job_details)) {
                            result = result.concat(artifact.blob.job_details);
                          }
                          return result;
                        }, []);
                    }
                    // the fourth result comes from the jobLogUrl artifact
                    // exclude the json log URLs
                    $scope.job_log_urls = _.reject(results[3], {name: 'mozlog_json'});

                    var logsNotParsed = [];
                    $scope.jobLogsAllParsed = _.every($scope.job_log_urls, function(jlu) {
                        if(jlu.parse_status === 'pending'){
                            logsNotParsed.push(jlu);
                            return false;
                        }else{
                            return true;
                        }
                    });
                    // retry to fetch the job info if a log hasn't been parsed yet
                    if(logsNotParsed.length > 0){
                        // first parse all the unparsed logs
                        $q.all(_.map(logsNotParsed, function(log){return log.parse();}))
                        .then(function(parseLogResponses){
                            // then retry to fetch the job info if the parse requests
                            // were successful
                            if(_.every(
                                parseLogResponses,
                                function(parseLogResponse){return parseLogResponse.status === 200;}
                            )){
                                selectJobRetryPromise = $timeout(function(){
                                    // the failure summary tab update must also be triggered here,
                                    // otherwise it will never update.
                                    thTabs.tabs.failureSummary.update();
                                    // refetch the job data details
                                    selectJobAndRender(job_id);
                                }, 5000);
                            }
                        });
                    }
                    $scope.lvUrl = thUrl.getLogViewerUrl($scope.job.id);
                    $scope.lvFullUrl = location.origin + "/" + $scope.lvUrl;
                    $scope.resultStatusShading = "result-status-shading-" + thResultStatus($scope.job);

                    updateVisibleFields();
                    $scope.updateClassifications();
                    $scope.updateBugs();

                    $scope.job_detail_loading = false;
                });
            }
        };

        var updateVisibleFields = function() {
                var undef = "",
                    duration = "";
                // fields that will show in the job detail panel
                $scope.visibleFields = {
                    "Job name": $scope.job.job_type_name || undef,
                    "Build": $scope.job.build_architecture + " " +
                             $scope.job.build_platform  + " " +
                             $scope.job.build_os || undef
                };

                // if the buildername exists, add it as a field
                if ($scope.artifacts.buildapi) {
                    $scope.visibleFields.Buildername = $scope.artifacts.buildapi.blob.buildername;
                }

                // time fields to show in detail panel, but that should be grouped together
                $scope.visibleTimeFields = {
                    requestTime: dateFilter($scope.job.submit_timestamp*1000,
                                            thDateFormat)
                };

                /*
                    display appropriate times and duration

                    If start time is 0, then duration should be from requesttime to now
                    If we have starttime and no endtime, then duration should be starttime to now
                    If we have both starttime and endtime, then duration will be between those two
                */
                var endtime = $scope.job.end_timestamp || Date.now()/1000;
                var starttime = $scope.job.start_timestamp || $scope.job.submit_timestamp;
                duration = numberFilter((endtime-starttime)/60, 0) + " minute(s)";

                $scope.visibleTimeFields.duration = duration;

                if ($scope.job.start_timestamp) {
                    $scope.visibleTimeFields.startTime = dateFilter(
                        $scope.job.start_timestamp*1000, thDateFormat);
                }
                if ($scope.job.end_timestamp) {
                    $scope.visibleTimeFields.endTime = dateFilter(
                        $scope.job.end_timestamp*1000, thDateFormat);
                }

        };

        $scope.getCountPinnedJobs = function() {
            return thPinboard.count.numPinnedJobs;
        };

        $scope.togglePinboardVisibility = function() {
            $scope.isPinboardVisible = !$scope.isPinboardVisible;
        };

        $scope.$watch('getCountPinnedJobs()', function(newVal, oldVal) {
            if (oldVal === 0 && newVal > 0) {
                $scope.isPinboardVisible = true;
            }
        });

        $scope.canCancel = function() {
            return $scope.job &&
                   ($scope.job.state === "pending" || $scope.job.state === "running");
        };

        /**
         * Get the build_id needed to cancel or retrigger from the currently
         * selected job.
         */
        var getBuildbotRequestId = function() {
            if ($scope.artifacts.buildapi) {
                return $scope.artifacts.buildapi.blob.request_id;
            }
        };

        $scope.retriggerJob = function() {
            if ($scope.user.loggedin) {
                // Only enter a retrigger if we have a valid loaded job, if the user
                // tries to retrigger eg. via shortcut before the load we warn them
                if ($scope.job.id) {
                    // The logic here is somewhat complicated because we need to support
                    // two use cases the first is the case where we notify a system
                    // other then buildbot that a retrigger has been requested. The
                    // second is when we have the buildapi id and need to send a request
                    // to the self serve api (which does not listen over pulse!).
                    ThJobModel.retrigger($scope.repoName, $scope.job.id).then(function() {
                        // XXX: Remove this after 1134929 is resolved.
                        var requestId = getBuildbotRequestId();
                        if (requestId) {
                            return thBuildApi.retriggerJob($scope.repoName, requestId);
                        }
                    }).then(function() {
                        thNotify.send("Retriggered job: " + $scope.jobSearchStr,
                                      'success');
                    }).catch(function(e) {
                        // Generic error eg. the user doesn't have LDAP access
                        thNotify.send(
                            ThModelErrors.format(e, "Unable to send retrigger"), 'danger');
                    });
                } else {
                    thNotify.send("Job not yet loaded for retrigger", 'warning');
                }
            } else {
                thNotify.send("Must be logged in to retrigger a job", 'danger');
            }
        };

        $scope.cancelJob = function() {
            // See note in retrigger logic.
            ThJobModel.cancel($scope.repoName, $scope.job.id).then(function() {
              // XXX: Remove this after 1134929 is resolved.
              var requestId = getBuildbotRequestId();
              if (requestId) {
                return thBuildApi.cancelJob($scope.repoName, requestId);
              }
            }).catch(function(e) {
                thNotify.send(
                    ThModelErrors.format(e, "Unable to cancel job"),
                    "danger", true
                );
            });
        };

        $scope.cancelAll = function(resultsetId) {
            var rs = ThResultSetModel.getResultSet($scope.repoName, resultsetId);
            thBuildApi.cancelAllJobs($scope.repoName, rs.revision);
        };

        /**
         * Test whether or not the selected job is a reftest
         */
        $scope.isReftest = function() {
            if ($scope.selectedJob) {
                return ($scope.selectedJob.job_group_name.indexOf("Reftest") !== -1);
            } else {
                return false;
            }
        };

        var selectJobAndRender = function(job_id){
            $scope.jobLoadedPromise = selectJob(job_id);
            $scope.jobLoadedPromise.then(function(){
                thTabs.showTab(thTabs.selectedTab, job_id);
            });
        };

        $rootScope.$on(thEvents.jobClick, function(event, job) {
            selectJobAndRender(job.id);
            $rootScope.selectedJob = job;
        });

        $rootScope.$on(thEvents.clearSelectedJob, function(event, job) {
            if(selectJobPromise !== null){
                $timeout.cancel(selectJobPromise);
            }
            if( selectJobRetryPromise !== null){
                $timeout.cancel(selectJobRetryPromise);
            }
        });

        $scope.bug_job_map_list = [];

        $scope.classificationTypes = thClassificationTypes;

        // load the list of existing classifications (including possibly a new one just
        // added).
        $scope.updateClassifications = function() {
            ThJobClassificationModel.get_list({job_id: $scope.job.id}).then(function(response) {
                $scope.classifications = response;
                $scope.job.note = $scope.classifications[0];
            });
        };

        // load the list of bug associations (including possibly new ones just
        // added).
        $scope.updateBugs = function() {
            if (_.has($scope.job, "id")) {
                ThBugJobMapModel.get_list({job_id: $scope.job.id}).then(function (response) {
                    $scope.bugs = response;
                });
            }
        };

        $rootScope.$on(thEvents.jobRetrigger, function(event, job) {
            $scope.retriggerJob();
        });

        $rootScope.$on(thEvents.jobsClassified, function(event, job) {
            $scope.updateClassifications();
        });

        $rootScope.$on(thEvents.bugsAssociated, function(event, job) {
            $scope.updateBugs();
        });

        $scope.pinboard_service = thPinboard;

        // expose the tab service properties on the scope
        $scope.tabService = thTabs;
    }
]);
<|endoftext|>


<commit_before>'use strict';

// Issue to improve: https://github.com/hashicorp/nomad/issues/7465
const proxyPath = '/v1';

module.exports = function(app, options) {
  // For options, see:
  // https://github.com/nodejitsu/node-http-proxy

  // This is probably not safe to do, but it works for now.
  let cacheKey = `${options.project.configPath()}|${options.environment}`;
  let config = options.project.configCache.get(cacheKey);

  // Disable the proxy completely when Mirage is enabled. No requests to the API
  // will be being made, and having the proxy attempt to connect to Nomad when it
  // is not running can result in socket max connections that block the livereload
  // server from reloading.
  if (config['ember-cli-mirage'].enabled !== false) {
    options.ui.writeInfoLine('Mirage is enabled. Not starting proxy');
    delete options.proxy;
    return;
  }

  let proxyAddress = options.proxy;

  let server = options.httpServer;
  let proxy = require('http-proxy').createProxyServer({
    target: proxyAddress,
    ws: true,
    changeOrigin: true,
  });

  proxy.on('error', function(err, req) {
    // eslint-disable-next-line
    console.error(err, req.url);
  });

  app.use(proxyPath, function(req, res) {
    // include root path in proxied request
    req.url = proxyPath + req.url;
    proxy.web(req, res, { target: proxyAddress });
  });

  server.on('upgrade', function(req, socket, head) {
    if (req.url.startsWith('/v1/client/allocation') && req.url.includes('exec?')) {
      req.headers.origin = proxyAddress;
      proxy.ws(req, socket, head, { target: proxyAddress });
    }
  });
};
<commit_msg>Remove superseded note<commit_after>'use strict';

const proxyPath = '/v1';

module.exports = function(app, options) {
  // For options, see:
  // https://github.com/nodejitsu/node-http-proxy

  // This is probably not safe to do, but it works for now.
  let cacheKey = `${options.project.configPath()}|${options.environment}`;
  let config = options.project.configCache.get(cacheKey);

  // Disable the proxy completely when Mirage is enabled. No requests to the API
  // will be being made, and having the proxy attempt to connect to Nomad when it
  // is not running can result in socket max connections that block the livereload
  // server from reloading.
  if (config['ember-cli-mirage'].enabled !== false) {
    options.ui.writeInfoLine('Mirage is enabled. Not starting proxy');
    delete options.proxy;
    return;
  }

  let proxyAddress = options.proxy;

  let server = options.httpServer;
  let proxy = require('http-proxy').createProxyServer({
    target: proxyAddress,
    ws: true,
    changeOrigin: true,
  });

  proxy.on('error', function(err, req) {
    // eslint-disable-next-line
    console.error(err, req.url);
  });

  app.use(proxyPath, function(req, res) {
    // include root path in proxied request
    req.url = proxyPath + req.url;
    proxy.web(req, res, { target: proxyAddress });
  });

  server.on('upgrade', function(req, socket, head) {
    if (req.url.startsWith('/v1/client/allocation') && req.url.includes('exec?')) {
      req.headers.origin = proxyAddress;
      proxy.ws(req, socket, head, { target: proxyAddress });
    }
  });
};
<|endoftext|>


<commit_before>import _ from 'lodash'

import {
  TEMP_VAR_INTERVAL,
  DEFAULT_DASHBOARD_GROUP_BY_INTERVAL,
} from 'shared/constants'

export default function buildInfluxQLQuery(timeBounds, config) {
  const {groupBy, tags, areTagsAccepted} = config
  const {upper, lower} = timeBounds

  const select = _buildSelect(config)
  if (select === null) {
    return null
  }

  const condition = _buildWhereClause({lower, upper, tags, areTagsAccepted})
  const dimensions = _buildGroupBy(groupBy)

  return `${select}${condition}${dimensions}`
}

function _buildSelect({fields, database, retentionPolicy, measurement}) {
  if (!database || !measurement || !fields || !fields.length) {
    return null
  }

  const rpSegment = retentionPolicy ? `"${retentionPolicy}"` : ''
  const fieldsClause = _buildFields(fields)
  const fullyQualifiedMeasurement = `"${database}".${rpSegment}."${measurement}"`
  const statement = `SELECT ${fieldsClause} FROM ${fullyQualifiedMeasurement}`
  return statement
}

export function buildSelectStatement(config) {
  return _buildSelect(config)
}

function _buildFields(fieldFuncs) {
  const hasAggregate = fieldFuncs.some(f => f.funcs && f.funcs.length)
  if (hasAggregate) {
    return fieldFuncs
      .map(f => {
        return f.funcs
          .map(func => `${func}("${f.field}") AS "${func}_${f.field}"`)
          .join(', ')
      })
      .join(', ')
  }

  return fieldFuncs
    .map(f => {
      return f.field === '*' ? '*' : `"${f.field}"`
    })
    .join(', ')
}

function _buildWhereClause({lower, upper, tags, areTagsAccepted}) {
  const timeClauses = []

  if (lower && lower.includes('Z')) {
    lower = `'${lower}'`
  }

  if (upper && upper.includes('Z')) {
    upper = `'${upper}'`
  }

  if (lower) {
    timeClauses.push(`time > ${lower}`)
  }

  if (upper) {
    timeClauses.push(`time < ${upper}`)
  }

  // If a tag key has more than one value, * e.g. cpu=cpu1, cpu=cpu2, combine
  // them with OR instead of AND for the final query.
  const tagClauses = _.keys(tags).map(k => {
    const operator = areTagsAccepted ? '=' : '!='

    if (tags[k].length > 1) {
      const joinedOnOr = tags[k]
        .map(v => `"${k}"${operator}'${v}'`)
        .join(' OR ')
      return `(${joinedOnOr})`
    }

    return `"${k}"${operator}'${tags[k]}'`
  })

  const subClauses = timeClauses.concat(tagClauses)
  if (!subClauses.length) {
    return ''
  }

  return ` WHERE ${subClauses.join(' AND ')}`
}

function _buildGroupBy(groupBy) {
  return `${_buildGroupByTime(groupBy)}${_buildGroupByTags(groupBy)}`
}

function _buildGroupByTime(groupBy) {
  if (!groupBy || !groupBy.time) {
    return ''
  }

  return ` GROUP BY ${groupBy.time === DEFAULT_DASHBOARD_GROUP_BY_INTERVAL
    ? TEMP_VAR_INTERVAL
    : `time(${groupBy.time})`}`
}

function _buildGroupByTags(groupBy) {
  if (!groupBy || !groupBy.tags.length) {
    return ''
  }

  const tags = groupBy.tags.map(t => `"${t}"`).join(', ')

  if (groupBy.time) {
    return `, ${tags}`
  }

  return ` GROUP BY ${tags}`
}
<commit_msg>Fix for tests. Phew! Thanks unit tests!<commit_after>import _ from 'lodash'

import {
  TEMP_VAR_INTERVAL,
  DEFAULT_DASHBOARD_GROUP_BY_INTERVAL,
} from 'shared/constants'

export default function buildInfluxQLQuery(timeBounds, config) {
  const {groupBy, tags, areTagsAccepted} = config
  const {upper, lower} = timeBounds

  const select = _buildSelect(config)
  if (select === null) {
    return null
  }

  const condition = _buildWhereClause({lower, upper, tags, areTagsAccepted})
  const dimensions = _buildGroupBy(groupBy)

  return `${select}${condition}${dimensions}`
}

function _buildSelect({fields, database, retentionPolicy, measurement}) {
  if (!database || !measurement || !fields || !fields.length) {
    return null
  }

  const rpSegment = retentionPolicy ? `"${retentionPolicy}"` : ''
  const fieldsClause = _buildFields(fields)
  const fullyQualifiedMeasurement = `"${database}".${rpSegment}."${measurement}"`
  const statement = `SELECT ${fieldsClause} FROM ${fullyQualifiedMeasurement}`
  return statement
}

export function buildSelectStatement(config) {
  return _buildSelect(config)
}

function _buildFields(fieldFuncs) {
  const hasAggregate = fieldFuncs.some(f => f.funcs && f.funcs.length)
  if (hasAggregate) {
    return fieldFuncs
      .map(f => {
        return f.funcs
          .map(func => `${func}("${f.field}") AS "${func}_${f.field}"`)
          .join(', ')
      })
      .join(', ')
  }

  return fieldFuncs
    .map(f => {
      return f.field === '*' ? '*' : `"${f.field}"`
    })
    .join(', ')
}

function _buildWhereClause({lower, upper, tags, areTagsAccepted}) {
  const timeClauses = []

  if (lower && lower.includes('Z') && !lower.includes('\'')) {
    lower = `'${lower}'`
  }

  if (upper && upper.includes('Z') && !upper.includes('\'')) {
    upper = `'${upper}'`
  }

  if (lower) {
    timeClauses.push(`time > ${lower}`)
  }

  if (upper) {
    timeClauses.push(`time < ${upper}`)
  }

  // If a tag key has more than one value, * e.g. cpu=cpu1, cpu=cpu2, combine
  // them with OR instead of AND for the final query.
  const tagClauses = _.keys(tags).map(k => {
    const operator = areTagsAccepted ? '=' : '!='

    if (tags[k].length > 1) {
      const joinedOnOr = tags[k]
        .map(v => `"${k}"${operator}'${v}'`)
        .join(' OR ')
      return `(${joinedOnOr})`
    }

    return `"${k}"${operator}'${tags[k]}'`
  })

  const subClauses = timeClauses.concat(tagClauses)
  if (!subClauses.length) {
    return ''
  }

  return ` WHERE ${subClauses.join(' AND ')}`
}

function _buildGroupBy(groupBy) {
  return `${_buildGroupByTime(groupBy)}${_buildGroupByTags(groupBy)}`
}

function _buildGroupByTime(groupBy) {
  if (!groupBy || !groupBy.time) {
    return ''
  }

  return ` GROUP BY ${groupBy.time === DEFAULT_DASHBOARD_GROUP_BY_INTERVAL
    ? TEMP_VAR_INTERVAL
    : `time(${groupBy.time})`}`
}

function _buildGroupByTags(groupBy) {
  if (!groupBy || !groupBy.tags.length) {
    return ''
  }

  const tags = groupBy.tags.map(t => `"${t}"`).join(', ')

  if (groupBy.time) {
    return `, ${tags}`
  }

  return ` GROUP BY ${tags}`
}
<|endoftext|>


<commit_before>const gulp = requireModule("gulp"),
  status = requireModule("status"),
  Git = require("simple-git/promise");

gulp.task(
  "update-git-submodules",
  "Updates all git submodules to latest commit on master branch",
  async () => {
    const git = new Git(".");
    await status.run(
      "Check out master on all submodules...",
      async () => await git.subModule(["foreach", "git", "checkout", "master"])
    );
    await status.run(
      "Update to latest commit on each submodule...",
      async () => await git.subModule(["foreach", "git", "pull", "--rebase"])
    );
  }
);

<commit_msg>:bug: should ensure submodules are initialized before attempting to checkout & update<commit_after>const gulp = requireModule("gulp"),
  status = requireModule("status"),
  Git = require("simple-git/promise");

gulp.task(
  "update-git-submodules",
  "Updates all git submodules to latest commit on master branch",
  async () => {
    const git = new Git(".");
    await status.run(
      "Ensure submodules are initialized...",
      async () => await git.subModule(["update", "--init"])
    );
    await status.run(
      "Check out master on all submodules...",
      async () => await git.subModule(["foreach", "git", "checkout", "master"])
    );
    await status.run(
      "Update to latest commit on each submodule...",
      async () => await git.subModule(["foreach", "git", "pull", "--rebase"])
    );
  }
);

<|endoftext|>


<commit_before>"use strict";

const async = require("async");

const core = require("../core");

const pastec = require("pastec")({
    server: process.env.PASTEC_URL,
});

core.init(() => {
    // Models
    const Artwork = core.models.Artwork;

    console.log("Finding artwork records...");

    Artwork.find({}, {}, {timeout: true}).stream()
        .on("data", function(artwork) {
            this.pause();

            console.log("Syncing", artwork._id);

            async.mapLimit(artwork.images, 1, (image, callback) => {
                const id = image.imageName;

                pastec.idIndexed(id, (err, exists) => {
                    if (err || !exists) {
                        return callback(err);
                    }

                    pastec.similar(id, (err, matches) => {
                        if (err) {
                            return callback(err);
                        }

                        matches = matches.filter((match) => match.id !== id);
                        image.similarImages = matches;
                        callback(err, matches);
                    });
                });
            }, (err, results) => {
                // Calculate artwork matches before saving
                const matches = results.filter((match) => match)
                    .reduce((a, b) => a.concat(b), []);
                const scores = matches.reduce((obj, match) => {
                    obj[match.id] = Math.max(match.score, obj[match.id] || 0);
                    return obj;
                }, {});

                if (matches.length === 0) {
                    artwork.save(() => this.resume());

                } else {
                    const query = matches.map((match) => ({
                        "images.imageName": match.id,
                    }));

                    Artwork.find({$or: query}, (err, artworks) => {
                        if (err) {
                            console.error(err);
                            return;
                        }

                        artwork.similarArtworks = artworks
                            .filter((similar) => similar._id !== artwork._id)
                            .map((similar) => {
                                const imageScores = similar.images.map(
                                    (image) => scores[image.imageName] || 0);

                                return {
                                    id: similar._id,
                                    score: Math.max(...imageScores),
                                };
                            });

                        artwork.save(() => this.resume());
                    });
                }
            });
        })
        .on("close", (err) => {
            if (err) {
                console.error(err);
            } else {
                console.log("DONE");
            }
            process.exit(0);
        });
});
<commit_msg>Fix typo in sync script. Sum scores rather than get the max, for an image.<commit_after>"use strict";

const async = require("async");

const core = require("../core");

const pastec = require("pastec")({
    server: process.env.PASTEC_URL,
});

core.init(() => {
    // Models
    const Artwork = core.models.Artwork;

    console.log("Finding artwork records...");

    Artwork.find({}, {}, {timeout: true}).stream()
        .on("data", function(artwork) {
            this.pause();

            console.log("Syncing", artwork._id);

            async.mapLimit(artwork.images, 1, (image, callback) => {
                const id = image.imageName;

                pastec.idIndexed(id, (err, exists) => {
                    if (err || !exists) {
                        return callback(err);
                    }

                    pastec.similar(id, (err, matches) => {
                        if (err) {
                            return callback(err);
                        }

                        matches = matches.filter((match) => match.id !== id);
                        image.similarImages = matches;
                        callback(err, matches);
                    });
                });
            }, (err, results) => {
                // Calculate artwork matches before saving
                const matches = results.filter((match) => match)
                    .reduce((a, b) => a.concat(b), []);
                const scores = matches.reduce((obj, match) => {
                    obj[match.id] = Math.max(match.score, obj[match.id] || 0);
                    return obj;
                }, {});

                if (matches.length === 0) {
                    artwork.save(() => this.resume());

                } else {
                    const query = matches.map((match) => ({
                        "images.imageName": match.id,
                    }));

                    Artwork.find({$or: query}, (err, artworks) => {
                        if (err) {
                            console.error(err);
                            return;
                        }

                        artwork.similarArtworks = artworks
                            .filter((similar) => similar._id !== artwork._id)
                            .map((similar) => {
                                const imageScores = similar.images.map(
                                    (image) => scores[image.imageName] || 0);

                                return {
                                    artwork: similar._id,
                                    score: imageScores.reduce((a, b) => a + b),
                                };
                            });

                        artwork.save(() => this.resume());
                    });
                }
            });
        })
        .on("close", (err) => {
            if (err) {
                console.error(err);
            } else {
                console.log("DONE");
            }
            process.exit(0);
        });
});
<|endoftext|>