<commit_before>import eutil from 'ethereumjs-util';
import http from 'http';
import httpProxy from 'http-proxy';
import HttpError from './HttpError';
import resource from '../imports/resource';
import url from 'url';
import web3 from '../imports/web3';

const validOwners = (() => {
  if (process.env.ETH_ACCOUNTS) {
    const validOwners = process.env.ETH_ACCOUNTS.split(',');

    for (let i = 0; i < validOwners.length; ++i) {
      validOwners[i] = validOwners[i].trim();
    }
    return validOwners;
  }
  return [web3.eth.accounts[0]];
})();

// Proxy server which checks the block chain permission and then proxies the request
const opts = { target: process.env.PROXIED_SERVER };

const proxy = httpProxy.createProxyServer({});
const port = parseInt(process.env.PROXY_PORT) || 9042;

console.log('Running proxy on port', port, 'in front of ' + opts.target + '...');

http.createServer((req, res) => {
  // We just do wide open CORS for demonstration purposes.
  res.setHeader('Access-Control-Allow-Origin', '*');
  if (req.method === 'OPTIONS') {
    return handleOptionsRequest(req, res);
  }
  try {
    // HACKHACKHACK - this is just an example - we're not doing any authorization on QIDO requests.
    if (!isQidoRequest(req)) {
      checkBlockChain(req);
    }
  } catch (err) {
    if (err instanceof HttpError) {
      console.log('refusing to proxy', req.url, 'error:', err);
      res.statusCode = err.statusCode;
    } else {
      console.log('unexpected error:', err);
      res.statusCode = 500;
    }
    res.end();
    return;
  }

  console.log('proxying', req.url);
  proxy.web(req, res, opts);
}).listen(port);

function isQidoRequest(req) {
  let path = url.parse(req.url).pathname;
  while (path.endsWith('/')) {
    path = path.substr(0, path.length - 1);
  }
  return path.endsWith('/studies');
}

function handleOptionsRequest(req, res) {
  res.setHeader('Access-Control-Allow-Methods', 'DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT');
  const allowedHeaders = req.headers['access-control-request-headers'];

  if (allowedHeaders) {
    res.setHeader('Access-Control-Allow-Headers', allowedHeaders);
  }
  res.setHeader('Access-Control-Max-Age', '86400');
  res.end();
}

function getRequestTimestamp(req, asInteger = true) {
  const timestampString = req.headers['x-timestamp'];
  if (!asInteger) {
    return timestampString;
  }
  const requestTimestamp = parseInt(timestampString);
  if (isNaN(requestTimestamp)) {
    throw new HttpError(400, 'missing or invalid x-timestamp header')
  }
  return requestTimestamp;
}

function checkTimeStamp(req) {
  const requestTimestamp = getRequestTimestamp(req);
  const now = Date.now();
  const delta = Math.abs(now - requestTimestamp);
  const timeLimitS = 30;
  if (delta > (timeLimitS * 1000)) {
    throw new HttpError(403, 'Detected a time skew of more than ' + timeLimitS +
      's. Rejecting request');
  }
}

function getSigFromHeaders(req) {
  return {
    r: Buffer.from(req.headers['x-secp256k1-r'], 'hex'),
    s: Buffer.from(req.headers['x-secp256k1-s'], 'hex'),
    v: parseInt(req.headers['x-secp256k1-v'])
  };
}

function getContractAddresses(req) {
  const list = req.headers['x-contractaddresses'].split(',');
  for (let i = 0; i < list.length; i++) {
    list[i] = trim(list[i]);
  }
  return list;
}

function getContractAddress(req) {
  const list = getContractAddresses(req);
  if (list.length < 1) {
    throw new HttpError(400, 'bad x-contract-addresses header value: "' + list.join(',') + '"');
  }
  return list[0];
}

function getMessageHash(req) {
  const contractAddressesForSigning = getContractAddresses(req).slice(1);
  const requestTimestamp = getRequestTimestamp(req, false/* leave as string */);
  const message = contractAddressesForSigning.join('') + requestTimestamp;
  const hash = web3.sha3(message);
  return eutil.toBuffer(hash);
}

function getSignerAddress(req) {
  const sig = getSigFromHeaders(req);
  const msgHash = getMessageHash(req);
  const publicKey = eutil.ecrecover(msgHash, sig.v, sig.r, sig.s);
  return eutil.bufferToHex(eutil.publicToAddress(publicKey));
}

function getContractInstance(req) {
  const contractAddress = getContractAddress(req);
  return resource.contract.at(contractAddress);
}

function checkOwner(req, instance) {
  if (!validOwners.includes(instance.owner())) {
    throw new HttpError(403, 'owner is unknown:' + instance.owner());
  }
}

function checkRecipient(req, instance) {
  const signerAddress = getSignerAddress(req);
  if (instance.recipient() !== signerAddress) {
    throw new HttpError(403, 'signer\'s address: "' + signerAddress +
      '" does not match recipient: "' + instance.recipient() + '"');
  }
}

function checkUrl(req, instance) {
  const requestUrl = req.url;
  const instanceUrl = url.parse(instance.url()).pathname;

  if (!requestUrl.startsWith(instanceUrl)) {
    throw new HttpError(403, 'client attempted an invalid access to "' + requestUrl + '" (1)');
  }
  // Okay, the request URL starts with the contract's registered URL. Need to still check that
  // the request refers to a sub-resource of the contract's URL and isn't just a basic straight
  // prefix:
  //
  // Examples of acceptable URLs:
  //  Request URL: /aaa/bbb        Contract URL: /aaa/bbb
  //  Request URL: /aaa/bbb/ccc    Contract URL: /aaa/bbb
  //  Request URL: /aaa/bbb/ccc/d  Contract URL: /aaa/bbb
  //
  // Not acceptable:
  //  Request URL: /aaa/bbbb       Contract URL: /aaa/bbb
  //
  if ((requestUrl.length > instanceUrl.length) &&
      (requestUrl.length[instanceUrl.length] !== '/')) {
    throw new HttpError(403, 'client attempted an invalid access to "' + requestUrl + '" (2)');
  }
  // All good
}

function checkBlockChain(req) {
  checkTimeStamp(req);
  const instance = getContractInstance(req);
  checkOwner(req, instance);
  checkRecipient(req, instance);
  checkUrl(req, instance);
}
<commit_msg>fixed erroneous trim call<commit_after>import eutil from 'ethereumjs-util';
import http from 'http';
import httpProxy from 'http-proxy';
import HttpError from './HttpError';
import resource from '../imports/resource';
import url from 'url';
import web3 from '../imports/web3';

const validOwners = (() => {
  if (process.env.ETH_ACCOUNTS) {
    const validOwners = process.env.ETH_ACCOUNTS.split(',');

    for (let i = 0; i < validOwners.length; ++i) {
      validOwners[i] = validOwners[i].trim();
    }
    return validOwners;
  }
  return [web3.eth.accounts[0]];
})();

// Proxy server which checks the block chain permission and then proxies the request
const opts = { target: process.env.PROXIED_SERVER };

const proxy = httpProxy.createProxyServer({});
const port = parseInt(process.env.PROXY_PORT) || 9042;

console.log('Running proxy on port', port, 'in front of ' + opts.target + '...');

http.createServer((req, res) => {
  // We just do wide open CORS for demonstration purposes.
  res.setHeader('Access-Control-Allow-Origin', '*');
  if (req.method === 'OPTIONS') {
    return handleOptionsRequest(req, res);
  }
  try {
    // HACKHACKHACK - this is just an example - we're not doing any authorization on QIDO requests.
    if (!isQidoRequest(req)) {
      checkBlockChain(req);
    }
  } catch (err) {
    if (err instanceof HttpError) {
      console.log('refusing to proxy', req.url, 'error:', err);
      res.statusCode = err.statusCode;
    } else {
      console.log('unexpected error:', err);
      res.statusCode = 500;
    }
    res.end();
    return;
  }

  console.log('proxying', req.url);
  proxy.web(req, res, opts);
}).listen(port);

function isQidoRequest(req) {
  let path = url.parse(req.url).pathname;
  while (path.endsWith('/')) {
    path = path.substr(0, path.length - 1);
  }
  return path.endsWith('/studies');
}

function handleOptionsRequest(req, res) {
  res.setHeader('Access-Control-Allow-Methods', 'DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT');
  const allowedHeaders = req.headers['access-control-request-headers'];

  if (allowedHeaders) {
    res.setHeader('Access-Control-Allow-Headers', allowedHeaders);
  }
  res.setHeader('Access-Control-Max-Age', '86400');
  res.end();
}

function getRequestTimestamp(req, asInteger = true) {
  const timestampString = req.headers['x-timestamp'];
  if (!asInteger) {
    return timestampString;
  }
  const requestTimestamp = parseInt(timestampString);
  if (isNaN(requestTimestamp)) {
    throw new HttpError(400, 'missing or invalid x-timestamp header')
  }
  return requestTimestamp;
}

function checkTimeStamp(req) {
  const requestTimestamp = getRequestTimestamp(req);
  const now = Date.now();
  const delta = Math.abs(now - requestTimestamp);
  const timeLimitS = 30;
  if (delta > (timeLimitS * 1000)) {
    throw new HttpError(403, 'Detected a time skew of more than ' + timeLimitS +
      's. Rejecting request');
  }
}

function getSigFromHeaders(req) {
  return {
    r: Buffer.from(req.headers['x-secp256k1-r'], 'hex'),
    s: Buffer.from(req.headers['x-secp256k1-s'], 'hex'),
    v: parseInt(req.headers['x-secp256k1-v'])
  };
}

function getContractAddresses(req) {
  const list = req.headers['x-contractaddresses'].split(',');
  for (let i = 0; i < list.length; i++) {
    list[i] = list[i].trim();
  }
  return list;
}

function getContractAddress(req) {
  const list = getContractAddresses(req);
  if (list.length < 1) {
    throw new HttpError(400, 'bad x-contract-addresses header value: "' + list.join(',') + '"');
  }
  return list[0];
}

function getMessageHash(req) {
  const contractAddressesForSigning = getContractAddresses(req).slice(1);
  const requestTimestamp = getRequestTimestamp(req, false/* leave as string */);
  const message = contractAddressesForSigning.join('') + requestTimestamp;
  const hash = web3.sha3(message);
  return eutil.toBuffer(hash);
}

function getSignerAddress(req) {
  const sig = getSigFromHeaders(req);
  const msgHash = getMessageHash(req);
  const publicKey = eutil.ecrecover(msgHash, sig.v, sig.r, sig.s);
  return eutil.bufferToHex(eutil.publicToAddress(publicKey));
}

function getContractInstance(req) {
  const contractAddress = getContractAddress(req);
  return resource.contract.at(contractAddress);
}

function checkOwner(req, instance) {
  if (!validOwners.includes(instance.owner())) {
    throw new HttpError(403, 'owner is unknown:' + instance.owner());
  }
}

function checkRecipient(req, instance) {
  const signerAddress = getSignerAddress(req);
  if (instance.recipient() !== signerAddress) {
    throw new HttpError(403, 'signer\'s address: "' + signerAddress +
      '" does not match recipient: "' + instance.recipient() + '"');
  }
}

function checkUrl(req, instance) {
  const requestUrl = req.url;
  const instanceUrl = url.parse(instance.url()).pathname;

  if (!requestUrl.startsWith(instanceUrl)) {
    throw new HttpError(403, 'client attempted an invalid access to "' + requestUrl + '" (1)');
  }
  // Okay, the request URL starts with the contract's registered URL. Need to still check that
  // the request refers to a sub-resource of the contract's URL and isn't just a basic straight
  // prefix:
  //
  // Examples of acceptable URLs:
  //  Request URL: /aaa/bbb        Contract URL: /aaa/bbb
  //  Request URL: /aaa/bbb/ccc    Contract URL: /aaa/bbb
  //  Request URL: /aaa/bbb/ccc/d  Contract URL: /aaa/bbb
  //
  // Not acceptable:
  //  Request URL: /aaa/bbbb       Contract URL: /aaa/bbb
  //
  if ((requestUrl.length > instanceUrl.length) &&
      (requestUrl.length[instanceUrl.length] !== '/')) {
    throw new HttpError(403, 'client attempted an invalid access to "' + requestUrl + '" (2)');
  }
  // All good
}

function checkBlockChain(req) {
  checkTimeStamp(req);
  const instance = getContractInstance(req);
  checkOwner(req, instance);
  checkRecipient(req, instance);
  checkUrl(req, instance);
}
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Auto Sell Items using Enhanced Steam Google Chrome plugin
// @namespace    http://github.com/taeram/user-scripts/
// @version      1.0.0
// @description  Auto sell items in your Steam Inventory using the "Quick Sell" feature of the Enhanced Steam google chrome plugin: https://chrome.google.com/webstore/detail/enhanced-steam/okadibdjfemgnhjiembecghcbfknbfhg
// @author       You
// @match        https://steamcommunity.com/id/*/inventory/
// @grant        none
// @license       MIT https://github.com/taeram/user-scripts/blob/master/LICENSE
// @updateURL     https://raw.github.com/taeram/user-scripts/master/auto-sell-steam-items.user.js
// @downloadURL   https://raw.github.com/taeram/user-scripts/master/auto-sell-steam-items.user.js
// ==/UserScript==

var jQueryFound = (typeof(jQuery) !== 'undefined');

if (!jQueryFound) {
    script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
    document.getElementsByTagName("body")[0].appendChild(script);
}

function autoSellAnItem() {
    var items = jQuery('.itemHolder .item.context6');
    for (var i=0; i < items.length; i++) {
        var isGems = jQuery(items[i]).find('.item_currency_amount').length > 0;
        var isSold = jQuery(items[i]).hasClass('btn_disabled');
        if (!isGems && !isSold) {
            jQuery(items[i]).find('.inventory_item_link').click();
            setTimeout(function () {
                var itemName = jQuery('.item_desc_description .hover_item_name').text();
                console.log("Attempting to sell " + itemName);
                var marketActions = jQuery('.item_market_actions');
                for (var j=0; j < marketActions.length; j++) {
                    if (jQuery(marketActions[j]).is(':visible')) {
                        var marketActionButtons = jQuery(marketActions[j]).find('.btn_small');
                        for (var k = 0; k < marketActionButtons.length; k++) {
                            if (jQuery(marketActionButtons[k]).attr('id').match(/es_quicksell/)) {
                                var quickSellPrice = jQuery(marketActionButtons[k]).attr('price');
                                console.log("Quick Selling " + itemName + " for $" + quickSellPrice);
                                jQuery(marketActionButtons[k]).find('span').click();
                                return;
                            } else if (jQuery(marketActionButtons[k]).attr('id').match(/es_instantsell/)) {
                                var instantSellPrice = jQuery(marketActionButtons[k]).attr('price');
                                console.log("Instant Selling " + itemName + " for $" + instantSellPrice);
                                jQuery(marketActionButtons[k]).find('span').click();
                                return;
                            }
                        }
                    }
                }
            }, 2000);
            return;
        }
    }
}

// Add an "Auto Sell" button
var autoSellInterval = null;
var autoSellButton = jQuery('<button class="btn_green_white_innerfade btn_medium" style="margin-right: 12px">Auto-Sell Inventory</button>').prependTo('.inventory_rightnav');
jQuery(autoSellButton).on('click', function () {
    autoSellAnItem();
    autoSellInterval = setInterval(autoSellAnItem, 10000);
});
<commit_msg>Handle page reloads<commit_after>// ==UserScript==
// @name         Auto Sell Items using Enhanced Steam Google Chrome plugin
// @namespace    http://github.com/taeram/user-scripts/
// @version      1.1.0
// @description  Auto sell items in your Steam Inventory using the "Quick Sell" feature of the Enhanced Steam google chrome plugin: https://chrome.google.com/webstore/detail/enhanced-steam/okadibdjfemgnhjiembecghcbfknbfhg
// @author       You
// @match        https://steamcommunity.com/id/*/inventory/
// @grant        none
// ==/UserScript==

var reloadPageInterval = 300; // seconds

var jQueryFound = (typeof(jQuery) !== 'undefined');
if (!jQueryFound) {
    script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
    document.getElementsByTagName("body")[0].appendChild(script);
}

function autoSellAnItem() {
    var items = jQuery('.itemHolder .item.context6');
    for (var i=0; i < items.length; i++) {
        var isGems = jQuery(items[i]).find('.item_currency_amount').length > 0;
        var isSold = jQuery(items[i]).hasClass('btn_disabled');
        if (!isGems && !isSold) {
            jQuery(items[i]).find('.inventory_item_link').click();
            setTimeout(function () {
                var itemName = jQuery('.item_desc_description .hover_item_name').text();
                console.log("Attempting to sell " + itemName);
                var marketActions = jQuery('.item_market_actions');
                for (var j=0; j < marketActions.length; j++) {
                    if (jQuery(marketActions[j]).is(':visible')) {
                        var marketActionButtons = jQuery(marketActions[j]).find('.btn_small');
                        for (var k = 0; k < marketActionButtons.length; k++) {
                            if (jQuery(marketActionButtons[k]).attr('id').match(/es_quicksell/)) {
                                var quickSellPrice = jQuery(marketActionButtons[k]).attr('price');
                                console.log("Quick Selling " + itemName + " for $" + quickSellPrice);
                                jQuery(marketActionButtons[k]).find('span').click();
                                return;
                            } else if (jQuery(marketActionButtons[k]).attr('id').match(/es_instantsell/)) {
                                var instantSellPrice = jQuery(marketActionButtons[k]).attr('price');
                                console.log("Instant Selling " + itemName + " for $" + instantSellPrice);
                                jQuery(marketActionButtons[k]).find('span').click();
                                return;
                            }
                        }
                    }
                }
            }, 2000);
            return;
        }
    }

    // Reload the page and wait for more items to appear
    setTimeout(function () {
        window.location.reload();
    }, reloadPageInterval * 1000);
}

// Add an "Auto Sell" button
var autoSellButton = jQuery('<button class="btn_green_white_innerfade btn_medium" style="margin-right: 12px">Auto-Sell Inventory</button>').prependTo('.inventory_rightnav');
jQuery(autoSellButton).on('click', function () {
    // Turn off auto sell if the button is clicked again
    if (localStorage.getItem('auto_sell_enabled') == "true") {
        localStorage.setItem('auto_sell_enabled', false);
        return;
    }

    // Enable auto selling so it persists between page loads
    localStorage.setItem('auto_sell_enabled', true);

    autoSellAnItem();
});

// Automatically try and sell something if the button is enabled
if (localStorage.getItem('auto_sell_enabled') == "true") {
    autoSellAnItem();
}
<|endoftext|>


<commit_before>var GenericCrud = require('./GenericCrud');
var dbHelper = require('mongoskin/lib/helper');
var ejsonHelper = require('./ejsonHelper');
var util = require('util');
var ObjectID = require('bson').ObjectID

var MetaCrud = function (config) {
	GenericCrud.call(this, config);
	this.db = config.db;
}

util.inherits(MetaCrud, GenericCrud);

MetaCrud.prototype.insert = function (collection, doc, res, next) {
	var me = this;
	collection.count({collection: doc.collection}, function (e, result) {
		if (result > 0) {
			res.status(512).send({status: 512, message: "the collection already exists"})
		} else {
			var col = me.db(doc.db).createCollection(doc.collection, function (e, results) {
				if (e) {
					next(e);
				} else {
					collection.insert(doc, {}, function (e, result) {
						if (e) return next(e)
						res.send(result)
					})
				}
			});
		}
	})
}

MetaCrud.prototype.delete = function (collection, id, res, next) {
	collection.findById(ejsonHelper.deflateId(id), function (e, result) {
		if (e) return next(e);
		this.db(result.db).collection(result.collection).drop(function (e, result) {
			if (e) return next(e);
			collection.removeById(ejsonHelper.deflateId(id), function (e, result) {
				if (e) return next(e)
				res.send((result === 1) ? {msg: 'success'} : {msg: 'error'})
			}.bind(this))
		}.bind(this));
	}.bind(this));
}

MetaCrud.prototype.update = function (collection, doc, id, res, next) {
	var me = this;
	collection.count({collection: doc.collection, _id: {$ne: ejsonHelper.deflateId(id)}}, function (e, result) {
		if (result > 0) {
			res.status(512).send({status: 512, message: "the collection already exists"})
		} else {
			collection.findById(id, function (e, result) {
				if (result != null && result.collection !== doc.collection) {
					me.db.collection(result.collection).rename(doc.collection, function (e, result) {
						if (e) {
							next(e);
						} else {
							collection.updateById(ejsonHelper.deflateId(id), ejsonHelper.deflate(doc), {
								safe: true,
								multi: false
							}, function (e, result) {
								if (e) return next(e)
								res.send((result === 1) ? {msg: 'success'} : {msg: 'error'})
							})
						}
					});
				} else {
					collection.updateById(ejsonHelper.deflateId(id), ejsonHelper.deflate(doc), {
						safe: true,
						multi: false
					}, function (e, result) {
						if (e) return next(e)
						res.send((result === 1) ? {msg: 'success'} : {msg: 'error'})
					})
				}
			});
		}
	})
};

MetaCrud.prototype.generate = function (collection, params, id, res, next) {
	collection.findById(ejsonHelper.deflateId(id), function (e, meta) {
		if (e) {
			return next(e);
		} else {
			var dataCollection = db.collection(meta.collection);
			dataCollection.find({}, {limit: 100}, function (e, results) {
				if (e) {
					return next(e);
				} else {

				}
			})
		}
	})
};

module.exports = MetaCrud;

<commit_msg>fix uniqueness check<commit_after>var GenericCrud = require('./GenericCrud');
var dbHelper = require('mongoskin/lib/helper');
var ejsonHelper = require('./ejsonHelper');
var util = require('util');
var ObjectID = require('bson').ObjectID

var MetaCrud = function (config) {
	GenericCrud.call(this, config);
	this.db = config.db;
}

util.inherits(MetaCrud, GenericCrud);

MetaCrud.prototype.insert = function (collection, doc, res, next) {
	var me = this;
	collection.count({collection: doc.collection}, function (e, result) {
		if (result > 0) {
			res.status(512).send({status: 512, message: "the collection already exists"})
		} else {
			var col = me.db(doc.db).createCollection(doc.collection, function (e, results) {
				if (e) {
					next(e);
				} else {
					collection.insert(doc, {}, function (e, result) {
						if (e) return next(e)
						res.send(result)
					})
				}
			});
		}
	})
}

MetaCrud.prototype.delete = function (collection, id, res, next) {
	collection.findById(ejsonHelper.deflateId(id), function (e, result) {
		if (e) return next(e);
		this.db(result.db).collection(result.collection).drop(function (e, result) {
			if (e) return next(e);
			collection.removeById(ejsonHelper.deflateId(id), function (e, result) {
				if (e) return next(e)
				res.send((result === 1) ? {msg: 'success'} : {msg: 'error'})
			}.bind(this))
		}.bind(this));
	}.bind(this));
}

MetaCrud.prototype.update = function (collection, doc, id, res, next) {
	var me = this;
	collection.count({collection: doc.collection, db:doc.db,_id: {$ne: ejsonHelper.deflateId(id)}}, function (e, result) {
		if (result > 0) {
			res.status(512).send({status: 512, message: "the collection already exists"})
		} else {
			collection.findById(id, function (e, result) {
				if (result != null && result.collection !== doc.collection) {
					me.db.collection(result.collection).rename(doc.collection, function (e, result) {
						if (e) {
							next(e);
						} else {
							collection.updateById(ejsonHelper.deflateId(id), ejsonHelper.deflate(doc), {
								safe: true,
								multi: false
							}, function (e, result) {
								if (e) return next(e)
								res.send((result === 1) ? {msg: 'success'} : {msg: 'error'})
							})
						}
					});
				} else {
					collection.updateById(ejsonHelper.deflateId(id), ejsonHelper.deflate(doc), {
						safe: true,
						multi: false
					}, function (e, result) {
						if (e) return next(e)
						res.send((result === 1) ? {msg: 'success'} : {msg: 'error'})
					})
				}
			});
		}
	})
};

MetaCrud.prototype.generate = function (collection, params, id, res, next) {
	collection.findById(ejsonHelper.deflateId(id), function (e, meta) {
		if (e) {
			return next(e);
		} else {
			var dataCollection = db.collection(meta.collection);
			dataCollection.find({}, {limit: 100}, function (e, results) {
				if (e) {
					return next(e);
				} else {

				}
			})
		}
	})
};

module.exports = MetaCrud;

<|endoftext|>


<commit_before>'use strict';

const FakeWindow = require('../mocks/fake_window');
const MessageHandler = require('./navigate');

describe('Navigate Handler', function() {

  let fakeWindow;
  let transmitter;
  let messageHandler;

  beforeEach(function() {
    fakeWindow = FakeWindow.create(this.sandbox);

    transmitter = {
      messageToService: this.sandbox.spy()
    };

    messageHandler = new MessageHandler(fakeWindow, transmitter);
  });

  const navigateTo = ({ target, params = {} }) => {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target,
        params
      },
      source: {
        integration_instance_id: 1
      }
    });
  };

  it('should listen to messages with event "navigate"', function() {
    expect(messageHandler.MESSAGE_EVENT).to.be.eql('navigate');
  });

  it('should set proper location when calling handleMessage with params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'email_analysis/details',
        params: {
          campaign_id: 666,
          launch_id: 999
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'repmanager.php?session_id=SESSIONID',
      'changed=0',
      'action=analysis',
      'camp_id=666',
      'launch_id=999',
      'page=1',
      'search=',
      'step=1',
      'save_pref=on',
      'tabdetails_length=10',
      'tabfull_length=10',
      'campaign_category=',
      'admin=n',
      'status=current',
      'type=all'
    ].join('&'));
  });

  it('should set proper location when calling handleMessage without params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'email_campaigns/list'
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql('campaignmanager.php?session_id=SESSIONID&action=list');
  });

  it('navigates to admin list', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'administrators/list'
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service',
      'service=user-management',
      'service_path=/admin/list'
    ].join('&'));
  });

  describe('when unload confirm is initialized', function() {
    beforeEach(function() {
      fakeWindow.Emarsys.integration.unload.initialized = true;
      fakeWindow.Emarsys.integration.dialog.confirmNavigation = this.sandbox.stub().returns(fakeWindow.resolved());
    });

    it('should pop a confirm dialog when we have the unload confirm initialized', function() {
      messageHandler.handleMessage({
        event: 'navigate',
        data: {
          target: 'email_campaigns/list'
        },
        source: {
          integration_instance_id: 1
        }
      });

      expect(fakeWindow.Emarsys.integration.dialog.confirmNavigation).to.be.called;
    });

    it('should send response back to the service with success true', function(done) {
      messageHandler.handleMessage({
        event: 'navigate',
        data: {
          eventId: 1,
          target: 'email_campaigns/list'
        },
        source: {
          integration_instance_id: 1
        }
      })
        .then(() => {
          expect(transmitter.messageToService).to.have.been.calledWithMatch(
            'navigate:response',
            { id: 1, success: true }
          );

          done();
        });
    });
  });

  describe('when unload confirm is not initialized', function() {
    beforeEach(function() {
      fakeWindow.Emarsys.integration.unload.initialized = false;
    });

    it('should send response back to the service with success true', function(done) {
      messageHandler.handleMessage({
        event: 'navigate',
        data: {
          eventId: 1,
          target: 'email_campaigns/list'
        },
        source: {
          integration_instance_id: 1
        }
      }).then(() => {
        expect(transmitter.messageToService).to.have.been.calledWithMatch(
          'navigate:response',
          { id: 1, success: true }
        );

        done();
      });
    });
  });

  it('should throw 404 when called with invalid pathname', function() {
    let exceptionThrown;

    try {
      navigateTo({ target: 'invalid/pathname' });
    } catch (e) {
      exceptionThrown = e;
    }

    expect(exceptionThrown.message).to.eql('Error 404: Unknown pathname');
  });

  it('navigates to create campaign with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'email_campaigns/create',
        params: {
          use_template: 'n',
          mailstream: 1
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'campaignmanager.php?session_id=SESSIONID',
      'action=new',
      'use_template=n',
      'mailstream=1'
    ].join('&'));
  });

  it('navigates to create content blocks based campaign with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'email_campaigns/blocks/create',
        params: {
          mailstream: 1
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?r=contentBlocks/selector&session_id=SESSIONID',
      'mailstream=1'
    ].join('&'));
  });

  it('navigates to bounce management page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'bounce_management/list',
        params: {
          only_mailstreams: 1
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'adminmanager.php?session_id=SESSIONID&action=invmails',
      'only_mailstreams=1'
    ].join('&'));
  });

  it('navigates to program edit page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'program/edit',
        params: {
          program_id: 318
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=program/edit',
      'programId=318'
    ].join('&'));
  });

  it('navigates to program report page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'program/report',
        params: {
          program_id: 318
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=program/report',
      'programId=318'
    ].join('&'));
  });

  it('navigates to program summary page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'program/summary',
        params: {
          program_id: 318
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=program/summary',
      'programId=318'
    ].join('&'));
  });

  it('navigates to contact edit page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'contact/edit',
        params: {
          uid: 318,
          return_url: 'triggeredEmail'
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'userprofiles.php?session_id=SESSIONID&action=show',
      'uid=318',
      'sback=triggeredEmail'
    ].join('&'));
  });

  it('navigate to trend reporing page for selecting multiple campaigns', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'trendsreporting/trends/campaigns',
        params: {
          campaign_ids: '42,43'
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=trendsreporting/trends',
      'campaignIds=42,43'
    ].join('&'));
  });

  it('navigates to trend reporting page for specific campaign', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'trendsreporting/trends/campaign',
        params: {
          campaign_id: 42
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'repmanager.php?action=analysis&page=1&step=11&session_id=SESSIONID',
      'camp_id=42'
    ].join('&'));
  });

  it('navigates to permission settings policies page', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'permission_settings/policies'
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=permissionSettings'
    ].join('&'));
  });

  it('navigates to permission settings roles page', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'permission_settings/roles'
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=permissionSettings#/roles'
    ].join('&'));
  });

  it('navigates to Tactics list page', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'tactics/list',
        params: {
          kpi_fake: 'foo_fake',
          kpi: 'foo'
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    const expectedUrl = 'bootstrap.php?session_id=SESSIONID&r=tactics&kpi=foo_fake#/?kpi=foo';
    expect(fakeWindow.location.href).to.eql(expectedUrl);
  });

  it('navigates to Tactics details page', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'tactics/details',
        params: {
          id: 'foo'
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    const expectedUrl = 'bootstrap.php?session_id=SESSIONID&r=tactics#/?id=foo';
    expect(fakeWindow.location.href).to.eql(expectedUrl);
  });

  it('navigates to Mobile Engage push editor page', function() {
    navigateTo({
      target: 'me_push/edit',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/campaigns/foo'
    ].join('&'));
  });

  it('navigates to Mobile Engage push reporting page', function() {
    navigateTo({
      target: 'me_push/report',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/reports/push/foo'
    ].join('&'));
  });

  it('navigates to Mobile Engage Inbox editor page', function() {
    navigateTo({
      target: 'me_inbox/edit',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/campaigns/foo'
    ].join('&'));
  });

  it('navigates to Mobile Engage Inbox reporting page', function() {
    navigateTo({
      target: 'me_inbox/report',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/reports/inbox/foo'
    ].join('&'));
  });

  it('navigates to RTI program edit page', function() {
    navigateTo({
      target: 'rti/edit',
      params: {
        id: 'ukumasing'
      }
    });

    expect(fakeWindow.location.href).to.eql(
      'bootstrap.php?session_id=SESSIONID' +
      '&r=eventCenter/index#/edit/rti/ukumasing'
    );
  });

  it('navigates to RTI program report overview page', function() {
    const programId = 'my-program-id';
    navigateTo({
      target: 'rti/report',
      params: {
        id: programId
      }
    });

    expect(fakeWindow.location.href).to.eql(
      'bootstrap.php?session_id=SESSIONID' +
      '&r=eventCenter/index#/summary/' + programId
    );
  });

  it('navigates to New Revenue Attribution Settings page', function() {
    navigateTo({ target: 'revenue_attributor/settings' });

    expect(fakeWindow.location.href).to.eql(
      'bootstrap.php?session_id=SESSIONID&r=service&service=revenue-attributor'
    );
  });

  it('navigates to Mobile Engage push campaigns page', function() {
    navigateTo({
      target: 'me_push/campaigns'
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/campaigns'
    ].join('&'));
  });

  it('navigates to Mobile Engage inapp campaigns page', function() {
    navigateTo({
      target: 'me_push/inapp-campaigns'
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/inapp-campaigns'
    ].join('&'));
  });

  it('navigates to Mobile Engage inapp reports page', function() {
    navigateTo({
      target: 'me_push/inapp-campaigns/report',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/reports/inapp/foo'
    ].join('&'));
  });
});
<commit_msg>feat(navigate): adds test for form edit page<commit_after>'use strict';

const FakeWindow = require('../mocks/fake_window');
const MessageHandler = require('./navigate');

describe('Navigate Handler', function() {

  let fakeWindow;
  let transmitter;
  let messageHandler;

  beforeEach(function() {
    fakeWindow = FakeWindow.create(this.sandbox);

    transmitter = {
      messageToService: this.sandbox.spy()
    };

    messageHandler = new MessageHandler(fakeWindow, transmitter);
  });

  const navigateTo = ({ target, params = {} }) => {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target,
        params
      },
      source: {
        integration_instance_id: 1
      }
    });
  };

  it('should listen to messages with event "navigate"', function() {
    expect(messageHandler.MESSAGE_EVENT).to.be.eql('navigate');
  });

  it('should set proper location when calling handleMessage with params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'email_analysis/details',
        params: {
          campaign_id: 666,
          launch_id: 999
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'repmanager.php?session_id=SESSIONID',
      'changed=0',
      'action=analysis',
      'camp_id=666',
      'launch_id=999',
      'page=1',
      'search=',
      'step=1',
      'save_pref=on',
      'tabdetails_length=10',
      'tabfull_length=10',
      'campaign_category=',
      'admin=n',
      'status=current',
      'type=all'
    ].join('&'));
  });

  it('should set proper location when calling handleMessage without params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'email_campaigns/list'
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql('campaignmanager.php?session_id=SESSIONID&action=list');
  });

  it('navigates to admin list', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'administrators/list'
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service',
      'service=user-management',
      'service_path=/admin/list'
    ].join('&'));
  });

  describe('when unload confirm is initialized', function() {
    beforeEach(function() {
      fakeWindow.Emarsys.integration.unload.initialized = true;
      fakeWindow.Emarsys.integration.dialog.confirmNavigation = this.sandbox.stub().returns(fakeWindow.resolved());
    });

    it('should pop a confirm dialog when we have the unload confirm initialized', function() {
      messageHandler.handleMessage({
        event: 'navigate',
        data: {
          target: 'email_campaigns/list'
        },
        source: {
          integration_instance_id: 1
        }
      });

      expect(fakeWindow.Emarsys.integration.dialog.confirmNavigation).to.be.called;
    });

    it('should send response back to the service with success true', function(done) {
      messageHandler.handleMessage({
        event: 'navigate',
        data: {
          eventId: 1,
          target: 'email_campaigns/list'
        },
        source: {
          integration_instance_id: 1
        }
      })
        .then(() => {
          expect(transmitter.messageToService).to.have.been.calledWithMatch(
            'navigate:response',
            { id: 1, success: true }
          );

          done();
        });
    });
  });

  describe('when unload confirm is not initialized', function() {
    beforeEach(function() {
      fakeWindow.Emarsys.integration.unload.initialized = false;
    });

    it('should send response back to the service with success true', function(done) {
      messageHandler.handleMessage({
        event: 'navigate',
        data: {
          eventId: 1,
          target: 'email_campaigns/list'
        },
        source: {
          integration_instance_id: 1
        }
      }).then(() => {
        expect(transmitter.messageToService).to.have.been.calledWithMatch(
          'navigate:response',
          { id: 1, success: true }
        );

        done();
      });
    });
  });

  it('should throw 404 when called with invalid pathname', function() {
    let exceptionThrown;

    try {
      navigateTo({ target: 'invalid/pathname' });
    } catch (e) {
      exceptionThrown = e;
    }

    expect(exceptionThrown.message).to.eql('Error 404: Unknown pathname');
  });

  it('navigates to create campaign with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'email_campaigns/create',
        params: {
          use_template: 'n',
          mailstream: 1
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'campaignmanager.php?session_id=SESSIONID',
      'action=new',
      'use_template=n',
      'mailstream=1'
    ].join('&'));
  });

  it('navigates to create content blocks based campaign with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'email_campaigns/blocks/create',
        params: {
          mailstream: 1
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?r=contentBlocks/selector&session_id=SESSIONID',
      'mailstream=1'
    ].join('&'));
  });

  it('navigates to bounce management page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'bounce_management/list',
        params: {
          only_mailstreams: 1
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'adminmanager.php?session_id=SESSIONID&action=invmails',
      'only_mailstreams=1'
    ].join('&'));
  });

  it('navigates to program edit page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'program/edit',
        params: {
          program_id: 318
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=program/edit',
      'programId=318'
    ].join('&'));
  });

  it('navigates to program report page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'program/report',
        params: {
          program_id: 318
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=program/report',
      'programId=318'
    ].join('&'));
  });

  it('navigates to program summary page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'program/summary',
        params: {
          program_id: 318
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=program/summary',
      'programId=318'
    ].join('&'));
  });

  it('navigates to contact edit page with proper params', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'contact/edit',
        params: {
          uid: 318,
          return_url: 'triggeredEmail'
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'userprofiles.php?session_id=SESSIONID&action=show',
      'uid=318',
      'sback=triggeredEmail'
    ].join('&'));
  });

  it('navigate to trend reporing page for selecting multiple campaigns', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'trendsreporting/trends/campaigns',
        params: {
          campaign_ids: '42,43'
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=trendsreporting/trends',
      'campaignIds=42,43'
    ].join('&'));
  });

  it('navigates to trend reporting page for specific campaign', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'trendsreporting/trends/campaign',
        params: {
          campaign_id: 42
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'repmanager.php?action=analysis&page=1&step=11&session_id=SESSIONID',
      'camp_id=42'
    ].join('&'));
  });

  it('navigates to permission settings policies page', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'permission_settings/policies'
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=permissionSettings'
    ].join('&'));
  });

  it('navigates to permission settings roles page', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'permission_settings/roles'
      },
      source: {
        integration_instance_id: 1
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=permissionSettings#/roles'
    ].join('&'));
  });

  it('navigates to Tactics list page', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'tactics/list',
        params: {
          kpi_fake: 'foo_fake',
          kpi: 'foo'
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    const expectedUrl = 'bootstrap.php?session_id=SESSIONID&r=tactics&kpi=foo_fake#/?kpi=foo';
    expect(fakeWindow.location.href).to.eql(expectedUrl);
  });

  it('navigates to Tactics details page', function() {
    messageHandler.handleMessage({
      event: 'navigate',
      data: {
        target: 'tactics/details',
        params: {
          id: 'foo'
        }
      },
      source: {
        integration_instance_id: 1
      }
    });

    const expectedUrl = 'bootstrap.php?session_id=SESSIONID&r=tactics#/?id=foo';
    expect(fakeWindow.location.href).to.eql(expectedUrl);
  });

  it('navigates to Mobile Engage push editor page', function() {
    navigateTo({
      target: 'me_push/edit',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/campaigns/foo'
    ].join('&'));
  });

  it('navigates to Mobile Engage push reporting page', function() {
    navigateTo({
      target: 'me_push/report',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/reports/push/foo'
    ].join('&'));
  });

  it('navigates to Mobile Engage Inbox editor page', function() {
    navigateTo({
      target: 'me_inbox/edit',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/campaigns/foo'
    ].join('&'));
  });

  it('navigates to Mobile Engage Inbox reporting page', function() {
    navigateTo({
      target: 'me_inbox/report',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/reports/inbox/foo'
    ].join('&'));
  });

  it('navigates to RTI program edit page', function() {
    navigateTo({
      target: 'rti/edit',
      params: {
        id: 'ukumasing'
      }
    });

    expect(fakeWindow.location.href).to.eql(
      'bootstrap.php?session_id=SESSIONID' +
      '&r=eventCenter/index#/edit/rti/ukumasing'
    );
  });

  it('navigates to RTI program report overview page', function() {
    const programId = 'my-program-id';
    navigateTo({
      target: 'rti/report',
      params: {
        id: programId
      }
    });

    expect(fakeWindow.location.href).to.eql(
      'bootstrap.php?session_id=SESSIONID' +
      '&r=eventCenter/index#/summary/' + programId
    );
  });

  it('navigates to New Revenue Attribution Settings page', function() {
    navigateTo({ target: 'revenue_attributor/settings' });

    expect(fakeWindow.location.href).to.eql(
      'bootstrap.php?session_id=SESSIONID&r=service&service=revenue-attributor'
    );
  });

  it('navigates to Mobile Engage push campaigns page', function() {
    navigateTo({
      target: 'me_push/campaigns'
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/campaigns'
    ].join('&'));
  });

  it('navigates to Mobile Engage inapp campaigns page', function() {
    navigateTo({
      target: 'me_push/inapp-campaigns'
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/inapp-campaigns'
    ].join('&'));
  });

  it('navigates to Mobile Engage inapp reports page', function() {
    navigateTo({
      target: 'me_push/inapp-campaigns/report',
      params: {
        id: 'foo'
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'bootstrap.php?session_id=SESSIONID',
      'r=service/index',
      'service=push-notification',
      'iframe=show',
      '#/reports/inapp/foo'
    ].join('&'));
  });

  it('navigates to Form edit page', function() {
    navigateTo({
      target: 'forms/edit',
      params: {
        form_id: 123
      }
    });

    expect(fakeWindow.location.href).to.eql([
      'regmanager.php?session_id=SESSIONID',
      'form_id=123',
      'action=description'
    ].join('&'));
  });
});
<|endoftext|>


<commit_before>var fighters = Alloy.Collections.fighters;
var counter = 1;

function showId(e) {
	if (e.row.model) {
		alert(e.row.model);
	}
}

function addTestFighter(e) {
	// create the test fighter model
	var model = Alloy.createModel('fighters', {
		name: 'Name ' + counter,
		nickname: 'Nickname ' + counter
	});
	counter++;

	// add model to the collection and save it to sqlite
	fighters.add(model);
	model.save();

	// let's refresh so we can see the ids coming from the
	// autoincrement field in the sqlite database in the
	// row click alerts
	fighters.fetch();
}

fighters.fetch();

$.index.open();<commit_msg>no need to fetch() to get the db is anymore<commit_after>var fighters = Alloy.Collections.fighters;
var counter = 1;

function showId(e) {
	if (e.row.model) {
		alert(e.row.model);
	}
}

function addTestFighter(e) {
	// create the test fighter model
	var model = Alloy.createModel('fighters', {
		name: 'Name ' + counter,
		nickname: 'Nickname ' + counter
	});
	counter++;

	// add model to the collection and save it to sqlite
	fighters.add(model);
	model.save();
}

fighters.fetch();

$.index.open();<|endoftext|>


<commit_before>'use strict';

var async = require('async'),
    mkdirp = require('mkdirp'),
    fs = require('fs'),
    spawn = require('child_process').spawn;
var discourse, config, log = [],
    oncomplete = [],
    executing = false;
exports.name = 'Backups';
exports.version = '0.0.1';
exports.description = 'Backup Manager';
exports.configuration = {
    'enabled': false,
    'auto_download': true,
    'download_dir': 'backups',
    'remove_old_backups': true,
    'auto_restore': true,
    'auto_backup': true,
    'auto_backup_time': '05:00',
    'auto_size_limit': 20971520,
    'notify_users': 'accalia'
};

exports.begin = function begin(browser, configuration) {
    discourse = browser;
    config = configuration;
    if (!config.enabled) {
        return;
    }
    if (config.auto_backup) {
        async.forever(function (next) {
            autoBackup(next);
        });
    }
};

function autoBackup(callback) {
    var hour = parseInt(/(\d+)/.exec(config.auto_backup_time)[1], 10),
        minute = parseInt(/:(\d+)/.exec(config.auto_backup_time)[1], 10),
        now = new Date(),
        utc = new Date();
    utc.setUTCHours(hour);
    utc.setUTCMinutes(minute);
    utc.setUTCSeconds(0);
    utc.setMilliseconds(0);
    now = now.getTime();
    utc = utc.getTime();
    if (now > utc) {
        // add a day if scheduling after 23:40 UTC
        utc += 24 * 60 * 60 * 1000;
    }
    setTimeout(function () {
        discourse.log('Starting Scheduled Backup.');
        startBackup(function (err) {
            if (err) {
                discourse.warn('Backup Failed');
            } else {
                discourse.log('Backup Succeeded');
            }
            callback();
        });
    }, utc - now);
}

exports.backup = function backup(args, callback) {
    if (!config.enabled) {
        return callback(true, 'Disabled');
    }
    executing = true;
    var arg = (args || []).shift() || '';
    arg = arg.toLowerCase();
    switch (arg) {
    case '':
    case 'all':
    case 'start':
    case 'download':
    case 'load':
        async.series([
            function (flow) {
                if (arg === 'all' || arg === 'start') {
                    return startBackup(flow);
                }
                flow(null, []);
            },
            function (flow) {
                if (arg === 'all' || arg === 'download') {
                    return downloadLatestBackup(false, flow);
                }
                flow(null, []);
            },
            function (flow) {
                if (arg === 'all' || arg === 'load') {
                    return restoreBackup(flow);
                }
                flow(null, []);
            }
        ], function (err, results) {
            var logs = err ? 'ERROR:\n' : 'SUCCESS:\n';
            results.forEach(function (i) {
                logs += i.join('\n') + '\n';
            });
            executing = false;
            callback(null, logs);
        });
        break;
    default:
        executing = false;
        callback(null, 'Usage: !admin download [all|start|download|load]');
        break;
    }
};
exports.backup.command = 'backup';
exports.backup.description = 'Do backup things';
exports.backup.trustLevel = 8;
exports.backup.muteable = false;
exports.backup.prefix = false;

function startBackup(callback) {
    var abort = false;
    oncomplete.push(function (err, log2, after) {
        if (abort) {
            return;
        }
        callback(err, log2);
        after();
    });
    discourse.postForm('admin/backups', {
        'with_uploads': false
    }, function (err) {
        if (err) {
            abort = true;
            callback(err, 'Backup failed to start');
        }
    });
}

function exec(command, args, pipeTo, callback) {
    function split(data) {
        return ('' + data).split('\n').filter(function (i) {
            return !!i;
        });
    }
    if (!callback) {
        callback = pipeTo;
        pipeTo = null;
    }
    var stdout = [],
        stderr = [],
        process;
    process = spawn(command, args);
    process.stderr.on('data', function (data) {
        if (!pipeTo) {
            stderr = stderr.concat(split(data));
        }
    });
    process.stdout.on('data', function (data) {
        if (pipeTo) {
            return pipeTo.stdin.write(data);
        }
        stdout = stdout.concat(split(data));
    });
    process.on('close', function (code) {
        if (pipeTo) {
            pipeTo.stdin.end();
        }
        callback(code, stdout, stderr);
    });
    return process;
}

function afterBackup(success) {
    var running = executing;
    var messages = log.slice();
    var m = oncomplete;
    oncomplete = [];
    async.each(m, function (func, flow) {
        func(!success, messages, flow);
    });
    if (running) {
        return;
    }
    async.series([
        function (flow) {
            if (!config.auto_download) {
                return flow(true);
            }
            downloadLatestBackup(true, function (err, output) {
                messages = messages.concat(output);
                flow(err);
            });
        },
        function (flow) {
            if (!config.auto_restore) {
                flow(true);
            }
            restoreBackup(function (err, output) {
                messages = messages.concat(output);
                flow(err);
            });
        }
    ], function () {
        mailLog(messages, function () {});
    });
}

function downloadLatestBackup(isauto, callback) {
    var messages = [];
    async.series([
        function (flow) {
            mkdirp(config.download_dir, function (err) {
                var prefix = 'DOWNLOAD: Ensuring Downloads Directory Exists: ';
                if (err) {
                    messages.push(prefix + 'Failed');
                } else {
                    messages.push(prefix + 'Success');
                }
                flow(err);
            });
        },
        function (flow) {
            if (!config.remove_old_backups) {
                return flow();
            }
            messages.push('DOWNLOAD: Removing Old Backups');
            fs.readdir(config.download_dir, function (err, files) {
                if (err) {
                    messages.push('DOWNLOAD: List Directory Failed');
                    return flow(err);
                }
                async.each(files.filter(function (i) {
                    return /tar[.]gz$/.test(i);
                }).map(function (i) {
                    return config.download_dir + '/' + i;
                }), fs.unlink, function (err2) {
                    if (err2) {
                        messages.push('DOWNLOAD: Removing Old Backups Failed');
                    }
                    flow(err2);
                });
            });
        },
        function (flow) {
            discourse.getForm('admin/backups.json', function (err, b, data) {
                if (err) {
                    messages.push('DOWNLOAD: Error Loading Backups');
                    return flow(err);
                }
                if (isauto && data[0].size > config.auto_size_limit) {
                    messages.push('DOWNLOAD: Aborting Download As Over Limit');
                    flow(true);
                }
                var src = 'http:' + data[0].link;
                var dest = config.download_dir + '/' + data[0].filename;
                discourse.saveFile(src, dest, function (err2) {
                    if (err2) {
                        messages.push('DOWNLOAD: Error Downloading Backup');
                    } else {
                        messages.push('DOWNLOAD: Downloaded Backup');
                    }
                    flow(err2);
                });
            });
        }
    ], function (err) {
        callback(err, messages);
    });
}

function restoreBackup(callback) {
    var src, messages = [];
    async.series([
        function (flow) {
            fs.readdir(config.download_dir, function (err, files) {
                if (err) {
                    messages.push('RESTORE: No Backup Found');
                    return flow(err);
                }
                var file = files.filter(function (i) {
                    return /tar[.]gz$/.test(i);
                });
                file.sort();
                file = file.pop();
                if (!file) {
                    return flow(true);
                }
                messages.push('RESTORE: Restoring ' + file);
                src = config.download_dir + '/' + file;
                flow();
            });
        },
        function (flow) {
            exec('psql', [
                '-d', 'discourse', '-c',
                'DROP SCHEMA backup CASCADE'
            ], function () {
                messages.push('RESTORE: Dropped Old `restore` Schema');
                flow();
            });
        },
        function (flow) {
            var psql = exec('psql', ['-d', 'discourse'], function (err) {
                if (err) {
                    messages.push('RESTORE: Load to `restore` Schema Failed');
                    return flow(err);
                }
                messages.push('RESTORE: Load to `restore` Schema Done');
                flow();
            });
            exec('tar', ['-xOzf', src, 'dump.sql'], psql, function () {});
        },
        function (flow) {
            exec('psql', [
                '-d', 'discourse', '-c',
                'ALTER SCHEMA public RENAME TO backup'
            ], function (err, out, errors) {
                if (err) {
                    messages.push('RESTORE: Rename Current Schema Failed');
                    messages = messages.concat(errors);
                    return flow(err);
                }
                messages.push('RESTORE: Rename Current Schema Succeded');
                flow();
            });
        },
        function (flow) {
            exec('psql', [
                '-d', 'discourse', '-c',
                'ALTER SCHEMA restore RENAME TO public'
            ], function (err, out, errors) {
                if (err) {
                    messages.push('RESTORE: Restore Database Failed');
                    messages = messages.concat(errors);
                    return flow(err);
                }
                messages.push('RESTORE: Restore Database Succeded');
                flow();
            });
        }
    ], function (err) {
        callback(err, messages);
    });
}

function mailLog(lines, callback) {
    var msg = 'Backup completed: \n\n```text\n' + lines.join('\n') + '\n```\n';
    discourse.createPrivateMessage(config.notify_users, 'Backup Completed', msg,
        callback);
}

exports.registerListeners = function registerListeners(callback) {
    if (!config.enabled) {
        return callback(null, []);
    }
    callback(null, ['/admin/backups/logs']);
};

exports.onMessage = function onMessage(message, post, callback) {
    if (!config.enabled) {
        return callback();
    }
    if (message.data && message.data.operation === 'backup') {
        if (message.data.message === '[STARTED]') {
            log = [];
        }
        if (!/^pg_dump/.test(message.data.message)) {
            log.push(message.data.message);
        }
        if (message.data.message === '[SUCCESS]' ||
            message.data.message === '[FAILED]') {
            afterBackup(message.data.message === '[SUCCESS]');
        }
    }
    callback();
};
<commit_msg>stop logging stderr or stdin.<commit_after>'use strict';

var async = require('async'),
    mkdirp = require('mkdirp'),
    fs = require('fs'),
    spawn = require('child_process').spawn;
var discourse, config, log = [],
    oncomplete = [],
    executing = false;
exports.name = 'Backups';
exports.version = '0.0.1';
exports.description = 'Backup Manager';
exports.configuration = {
    'enabled': false,
    'auto_download': true,
    'download_dir': 'backups',
    'remove_old_backups': true,
    'auto_restore': true,
    'auto_backup': true,
    'auto_backup_time': '05:00',
    'auto_size_limit': 20971520,
    'notify_users': 'accalia'
};

exports.begin = function begin(browser, configuration) {
    discourse = browser;
    config = configuration;
    if (!config.enabled) {
        return;
    }
    if (config.auto_backup) {
        async.forever(function (next) {
            autoBackup(next);
        });
    }
};

function autoBackup(callback) {
    var hour = parseInt(/(\d+)/.exec(config.auto_backup_time)[1], 10),
        minute = parseInt(/:(\d+)/.exec(config.auto_backup_time)[1], 10),
        now = new Date(),
        utc = new Date();
    utc.setUTCHours(hour);
    utc.setUTCMinutes(minute);
    utc.setUTCSeconds(0);
    utc.setMilliseconds(0);
    now = now.getTime();
    utc = utc.getTime();
    if (now > utc) {
        // add a day if scheduling after 23:40 UTC
        utc += 24 * 60 * 60 * 1000;
    }
    setTimeout(function () {
        discourse.log('Starting Scheduled Backup.');
        startBackup(function (err) {
            if (err) {
                discourse.warn('Backup Failed');
            } else {
                discourse.log('Backup Succeeded');
            }
            callback();
        });
    }, utc - now);
}

exports.backup = function backup(args, callback) {
    if (!config.enabled) {
        return callback(true, 'Disabled');
    }
    executing = true;
    var arg = (args || []).shift() || '';
    arg = arg.toLowerCase();
    switch (arg) {
    case '':
    case 'all':
    case 'start':
    case 'download':
    case 'load':
        async.series([
            function (flow) {
                if (arg === 'all' || arg === 'start') {
                    return startBackup(flow);
                }
                flow(null, []);
            },
            function (flow) {
                if (arg === 'all' || arg === 'download') {
                    return downloadLatestBackup(false, flow);
                }
                flow(null, []);
            },
            function (flow) {
                if (arg === 'all' || arg === 'load') {
                    return restoreBackup(flow);
                }
                flow(null, []);
            }
        ], function (err, results) {
            var logs = err ? 'ERROR:\n' : 'SUCCESS:\n';
            results.forEach(function (i) {
                logs += i.join('\n') + '\n';
            });
            executing = false;
            callback(null, logs);
        });
        break;
    default:
        executing = false;
        callback(null, 'Usage: !admin download [all|start|download|load]');
        break;
    }
};
exports.backup.command = 'backup';
exports.backup.description = 'Do backup things';
exports.backup.trustLevel = 8;
exports.backup.muteable = false;
exports.backup.prefix = false;

function startBackup(callback) {
    var abort = false;
    oncomplete.push(function (err, log2, after) {
        if (abort) {
            return;
        }
        callback(err, log2);
        after();
    });
    discourse.postForm('admin/backups', {
        'with_uploads': false
    }, function (err) {
        if (err) {
            abort = true;
            callback(err, 'Backup failed to start');
        }
    });
}

function exec(command, args, pipeTo, callback) {
    if (!callback) {
        callback = pipeTo;
        pipeTo = null;
    }
    var stdout = [],
        stderr = [],
        process;
    process = spawn(command, args);
    process.stdout.on('data', function (data) {
        if (pipeTo) {
            return pipeTo.stdin.write(data);
        }
    });
    process.on('close', function (code) {
        if (pipeTo) {
            pipeTo.stdin.end();
        }
        callback(code, stdout, stderr);
    });
    return process;
}

function afterBackup(success) {
    var running = executing;
    var messages = log.slice();
    var m = oncomplete;
    oncomplete = [];
    async.each(m, function (func, flow) {
        func(!success, messages, flow);
    });
    if (running) {
        return;
    }
    async.series([
        function (flow) {
            if (!config.auto_download) {
                return flow(true);
            }
            downloadLatestBackup(true, function (err, output) {
                messages = messages.concat(output);
                flow(err);
            });
        },
        function (flow) {
            if (!config.auto_restore) {
                flow(true);
            }
            restoreBackup(function (err, output) {
                messages = messages.concat(output);
                flow(err);
            });
        }
    ], function () {
        mailLog(messages, function () {});
    });
}

function downloadLatestBackup(isauto, callback) {
    var messages = [];
    async.series([
        function (flow) {
            mkdirp(config.download_dir, function (err) {
                var prefix = 'DOWNLOAD: Ensuring Downloads Directory Exists: ';
                if (err) {
                    messages.push(prefix + 'Failed');
                } else {
                    messages.push(prefix + 'Success');
                }
                flow(err);
            });
        },
        function (flow) {
            if (!config.remove_old_backups) {
                return flow();
            }
            messages.push('DOWNLOAD: Removing Old Backups');
            fs.readdir(config.download_dir, function (err, files) {
                if (err) {
                    messages.push('DOWNLOAD: List Directory Failed');
                    return flow(err);
                }
                async.each(files.filter(function (i) {
                    return /tar[.]gz$/.test(i);
                }).map(function (i) {
                    return config.download_dir + '/' + i;
                }), fs.unlink, function (err2) {
                    if (err2) {
                        messages.push('DOWNLOAD: Removing Old Backups Failed');
                    }
                    flow(err2);
                });
            });
        },
        function (flow) {
            discourse.getForm('admin/backups.json', function (err, b, data) {
                if (err) {
                    messages.push('DOWNLOAD: Error Loading Backups');
                    return flow(err);
                }
                if (isauto && data[0].size > config.auto_size_limit) {
                    messages.push('DOWNLOAD: Aborting Download As Over Limit');
                    flow(true);
                }
                var src = 'http:' + data[0].link;
                var dest = config.download_dir + '/' + data[0].filename;
                discourse.saveFile(src, dest, function (err2) {
                    if (err2) {
                        messages.push('DOWNLOAD: Error Downloading Backup');
                    } else {
                        messages.push('DOWNLOAD: Downloaded Backup');
                    }
                    flow(err2);
                });
            });
        }
    ], function (err) {
        callback(err, messages);
    });
}

function restoreBackup(callback) {
    var src, messages = [];
    async.series([
        function (flow) {
            fs.readdir(config.download_dir, function (err, files) {
                if (err) {
                    messages.push('RESTORE: No Backup Found');
                    return flow(err);
                }
                var file = files.filter(function (i) {
                    return /tar[.]gz$/.test(i);
                });
                file.sort();
                file = file.pop();
                if (!file) {
                    return flow(true);
                }
                messages.push('RESTORE: Restoring ' + file);
                src = config.download_dir + '/' + file;
                flow();
            });
        },
        function (flow) {
            exec('psql', [
                '-d', 'discourse', '-c',
                'DROP SCHEMA backup CASCADE'
            ], function () {
                messages.push('RESTORE: Dropped Old `restore` Schema');
                flow();
            });
        },
        function (flow) {
            var psql = exec('psql', ['-d', 'discourse'], function (err) {
                if (err) {
                    messages.push('RESTORE: Load to `restore` Schema Failed');
                    return flow(err);
                }
                messages.push('RESTORE: Load to `restore` Schema Done');
                flow();
            });
            exec('tar', ['-xOzf', src, 'dump.sql'], psql, function () {});
        },
        function (flow) {
            exec('psql', [
                '-d', 'discourse', '-c',
                'ALTER SCHEMA public RENAME TO backup'
            ], function (err, out, errors) {
                if (err) {
                    messages.push('RESTORE: Rename Current Schema Failed');
                    messages = messages.concat(errors);
                    return flow(err);
                }
                messages.push('RESTORE: Rename Current Schema Succeded');
                flow();
            });
        },
        function (flow) {
            exec('psql', [
                '-d', 'discourse', '-c',
                'ALTER SCHEMA restore RENAME TO public'
            ], function (err, out, errors) {
                if (err) {
                    messages.push('RESTORE: Restore Database Failed');
                    messages = messages.concat(errors);
                    return flow(err);
                }
                messages.push('RESTORE: Restore Database Succeded');
                flow();
            });
        }
    ], function (err) {
        callback(err, messages);
    });
}

function mailLog(lines, callback) {
    var msg = 'Backup completed: \n\n```text\n' + lines.join('\n') + '\n```\n';
    discourse.createPrivateMessage(config.notify_users, 'Backup Completed', msg,
        callback);
}

exports.registerListeners = function registerListeners(callback) {
    if (!config.enabled) {
        return callback(null, []);
    }
    callback(null, ['/admin/backups/logs']);
};

exports.onMessage = function onMessage(message, post, callback) {
    if (!config.enabled) {
        return callback();
    }
    if (message.data && message.data.operation === 'backup') {
        if (message.data.message === '[STARTED]') {
            log = [];
        }
        if (!/^pg_dump/.test(message.data.message)) {
            log.push(message.data.message);
        }
        if (message.data.message === '[SUCCESS]' ||
            message.data.message === '[FAILED]') {
            afterBackup(message.data.message === '[SUCCESS]');
        }
    }
    callback();
};
<|endoftext|>


<commit_before>const util = require('util');
const {RichEmbed} = require('discord.js');
const path = require('path');
const jsonQuery = require('json-query');
const titlecase = require('titlecase');
const escapeStringRegexp = require('escape-string-regexp');
const botUtils = require(path.join(__dirname, 'common-bot-utils.js'));

const fs = require('fs');

const enlirJsonPath = path.join(__dirname, '..', 'enlir_json');
const enlirAbilitiesPath = path.join(enlirJsonPath, 'abilities.json');
const enlirAbilitiesFile = fs.readFileSync(enlirAbilitiesPath);
const enlirAbilities = JSON.parse(enlirAbilitiesFile);

/** exports.ability:
 * Retrieves information about an ability.
 * @param {Object} msg: A message object from the Discord.js bot.
 * @param {Array} args: An array of arguments. This should only be
 * one value, and should contain only the following:
 *  * @param {String} abilityName: The desired ability name to look
 *    up. If the ability name has a space, the ability name should be
 *    encased in 'quotes'.
 **/
exports.ability = function lookupAbility(msg, args) {
  if (args.length < 3) {
    msg.reply('Search query must be at least three characters.');
    return;
  };
  let query;
  query = titlecase.toLaxTitleCase(args);
  query = escapeStringRegexp(query);
  console.log(`Ability to lookup: ${query}`);
  console.log(util.format('.ability caller: %s#%s',
    msg.author.username, msg.author.discriminator));
  let queryString = util.format('[name~/%s/i]', query);
  console.log(`queryString: ${queryString}`);
  let result = jsonQuery(queryString, {
    data: enlirAbilities,
    allowRegexp: true,
  });
  if (result.value === null) {
    msg.channel.send(`Ability '${query}' not found.`);
  } else {
    sendRichEmbedAbility(result, msg)
      .catch( (err) => {
        processAbility(result, msg);
      });
  };
};
/** processAbility:
 * Processes and outputs information about an ability.
 * @param {Object} result: A JSON list of a given ability.
 * @param {Object} msg: a discord.js message object.
 **/
exports.processAbility = function processAbility(result, msg) {
  ability = result.value;
  let description = botUtils.returnDescription(ability);
  let multiplier = botUtils.returnMultiplier(ability);
  let element = botUtils.returnElement(ability);
  let padLength = 20;
  let typeMsg = botUtils.returnPropertyString(
      ability.type, 'Type', padLength);
  let elementMsg = botUtils.returnPropertyString(element, 'Element');
  let targetMsg = botUtils.returnPropertyString(
    ability.target, 'Target', padLength);
  let multiplierMsg = botUtils.returnPropertyString(multiplier, 'Multiplier');
  let castMsg = botUtils.returnPropertyString(ability.time, 'Cast Time',
    padLength);
  let sbMsg = botUtils.returnPropertyString(ability.sb, 'Soul Break Charge');
  let message = (
    '**```\n' +
    util.format('%s\n', result.value.name) +
    util.format('%s\n', description) +
    util.format('%s || %s\n', typeMsg, elementMsg) +
    util.format('%s || %s\n', targetMsg, multiplierMsg) +
    util.format('%s || %s\n', castMsg, sbMsg) +
    '```**'
    );
  msg.channel.send(message);
};
/** sendRichEmbedAbility:
 * Processes and outputs information about an ability in RichEmbed format.
 * @param {object} result: the result from lookupAbility.
 * @param {object} msg: Discord.js-command message object.
 * @return {object} Promise
 **/
exports.sendRichEmbedAbility = function sendRichEmbedAbility(result, msg) {
  ability = result.value;
  let description = botUtils.returnDescription(ability);
  let multiplier = botUtils.returnMultiplier(ability);
  let element = botUtils.returnElement(ability);
  let abilityType = ability.school;
  let target = ability.target;
  let castTime = ability.time;
  let sbCharge = ability.sb;
  let sbImage = botUtils.returnImageLink(ability, 'ability');
  let embed = new RichEmbed()
    .setTitle(ability.name)
    .setDescription(description)
    .setColor('#53ddff')
    .setThumbnail(sbImage)
    .addField('**Type**', abilityType, true)
    .addField('**Element**', element, true)
    .addField('**Target**', target, true)
    .addField('**Multiplier**', multiplier, true)
    .addField('**Cast Time**', castTime, true)
    .addField('**Soul Break Charge**', sbCharge, true);
  return new Promise( (res, err) => {
    msg.channel.send({embed})
      .then( (resolve) => {
        res(resolve);
      }).catch( (error) => {
        console.log(`error in sendRichEmbedAbility: ${error}`);
        err(error);
      });
  });
};
<commit_msg>Moved exports to own variable in ability-bot-utils.<commit_after>const util = require('util');
const {RichEmbed} = require('discord.js');
const path = require('path');
const jsonQuery = require('json-query');
const titlecase = require('titlecase');
const escapeStringRegexp = require('escape-string-regexp');
const botUtils = require(path.join(__dirname, 'common-bot-utils.js'));

const fs = require('fs');

const enlirJsonPath = path.join(__dirname, '..', 'enlir_json');
const enlirAbilitiesPath = path.join(enlirJsonPath, 'abilities.json');
const enlirAbilitiesFile = fs.readFileSync(enlirAbilitiesPath);
const enlirAbilities = JSON.parse(enlirAbilitiesFile);

/** lookupAbility:
 * Retrieves information about an ability.
 * @param {Object} msg: A message object from the Discord.js bot.
 * @param {Array} args: An array of arguments. This should only be
 * one value, and should contain only the following:
 *  * @param {String} abilityName: The desired ability name to look
 *    up. If the ability name has a space, the ability name should be
 *    encased in 'quotes'.
 **/
function lookupAbility(msg, args) {
  if (args.length < 3) {
    msg.reply('Search query must be at least three characters.');
    return;
  };
  let query;
  query = titlecase.toLaxTitleCase(args);
  query = escapeStringRegexp(query);
  console.log(`Ability to lookup: ${query}`);
  console.log(util.format('.ability caller: %s#%s',
    msg.author.username, msg.author.discriminator));
  let queryString = util.format('[name~/%s/i]', query);
  console.log(`queryString: ${queryString}`);
  let result = jsonQuery(queryString, {
    data: enlirAbilities,
    allowRegexp: true,
  });
  if (result.value === null) {
    msg.channel.send(`Ability '${query}' not found.`);
  } else {
    sendRichEmbedAbility(result, msg)
      .catch( (err) => {
        processAbility(result, msg);
      });
  };
};
/** processAbility:
 * Processes and outputs information about an ability.
 * @param {Object} result: A JSON list of a given ability.
 * @param {Object} msg: a discord.js message object.
 **/
function processAbility(result, msg) {
  ability = result.value;
  let description = botUtils.returnDescription(ability);
  let multiplier = botUtils.returnMultiplier(ability);
  let element = botUtils.returnElement(ability);
  let padLength = 20;
  let typeMsg = botUtils.returnPropertyString(
      ability.type, 'Type', padLength);
  let elementMsg = botUtils.returnPropertyString(element, 'Element');
  let targetMsg = botUtils.returnPropertyString(
    ability.target, 'Target', padLength);
  let multiplierMsg = botUtils.returnPropertyString(multiplier, 'Multiplier');
  let castMsg = botUtils.returnPropertyString(ability.time, 'Cast Time',
    padLength);
  let sbMsg = botUtils.returnPropertyString(ability.sb, 'Soul Break Charge');
  let message = (
    '**```\n' +
    util.format('%s\n', result.value.name) +
    util.format('%s\n', description) +
    util.format('%s || %s\n', typeMsg, elementMsg) +
    util.format('%s || %s\n', targetMsg, multiplierMsg) +
    util.format('%s || %s\n', castMsg, sbMsg) +
    '```**'
    );
  msg.channel.send(message);
};
/** sendRichEmbedAbility:
 * Processes and outputs information about an ability in RichEmbed format.
 * @param {object} result: the result from lookupAbility.
 * @param {object} msg: Discord.js-command message object.
 * @return {object} Promise
 **/
function sendRichEmbedAbility(result, msg) {
  ability = result.value;
  let description = botUtils.returnDescription(ability);
  let multiplier = botUtils.returnMultiplier(ability);
  let element = botUtils.returnElement(ability);
  let abilityType = ability.school;
  let target = ability.target;
  let castTime = ability.time;
  let sbCharge = ability.sb;
  let sbImage = botUtils.returnImageLink(ability, 'ability');
  let embed = new RichEmbed()
    .setTitle(ability.name)
    .setDescription(description)
    .setColor('#53ddff')
    .setThumbnail(sbImage)
    .addField('**Type**', abilityType, true)
    .addField('**Element**', element, true)
    .addField('**Target**', target, true)
    .addField('**Multiplier**', multiplier, true)
    .addField('**Cast Time**', castTime, true)
    .addField('**Soul Break Charge**', sbCharge, true);
  return new Promise( (res, err) => {
    msg.channel.send({embed})
      .then( (resolve) => {
        res(resolve);
      }).catch( (error) => {
        console.log(`error in sendRichEmbedAbility: ${error}`);
        err(error);
      });
  });
};

module.exports = {
  sendRichEmbedAbility: sendRichEmbedAbility,
  ability: lookupAbility,
  processAbility: processAbility,
};
<|endoftext|>


<commit_before>"use strict";

Template.course_edit.helpers({
	query: function() {
		return Session.get('search')
	},

	available_categories: function(parent) {
		if (parent) return Categories.find({parent: parent})
		return Categories.find({parent: {$lt:1}})   //only shows cats with parents undefined
	},

	available_roles: function() {
		return Roles.find({'preset': { $ne: true }})
	},

	// Emit 'checked' string if id shows up as member or property of cats
	checked: function(id, cats) {
		if (cats === undefined) return;
		if (cats.length) {
			return cats.indexOf(id) >= 0 ? 'checked' : ''
		} else {
			return (id in cats) ? 'checked' : ''
		}
	},

	show_subcats: function(id, cats) {
		if (cats === undefined) return 'none';
		if (cats.length) {
			return cats.indexOf(id) >= 0 ? 'block' : 'none'
		} else {
			return (id in cats) ? 'block' : 'none'
		}
	},

	regions: function(){
	  return Regions.find();
	},

	currentRegion: function(region) {
		var currentRegion = Session.get('region')
		return currentRegion && region._id == currentRegion;
	}
});

Template.course_edit.events({
	'submit form.course_edit, click input.save': function (ev) {
		ev.preventDefault()

		try {
			if (!Meteor.userId()){
			    alert("Please log in!")
			    throw "Please log in!"
			}

			var courseId = this._id ? this._id : ''
			var isNew = courseId === ''

			var roles = {}
			$('input.roleselection').each(function(_, rolecheck) {
				roles[rolecheck.name] = rolecheck.checked;
			})

			var changes = {
				description: $('#editform_description').val(),
				categories: $('#editform_categories input:checked').map(function(){ return this.name}).get(),
				name: $('#editform_name').val(),
				roles: roles
			}

			if (isNew) {
				changes.region = $('.region_select').val()
				if (!changes.region) {
					alert("Please select a region")
					return;
				}
			}

			Meteor.call("save_course", courseId, changes, function(err, course) {
				Session.set('search', ''); // clear searchfield
				if (err) alert("Saving the course went terribly wrong: "+err)
				Router.go('showCourse', course)
			})

		} catch(err) {
			if (err instanceof String) alert(err)
			else throw err
		}
	},

	'click input.cancel': function() {
		Session.set("isEditing", false);
	},

	'click #show_categories_to_edit': function(event){
		$('#show_categories_to_edit').toggle();
		$('#edit_categories').toggle();
	},

	'change .categories .checkbox': function(){
		//$('#' + event.currentTarget.id +" .subcategories").toggle();
		$('#cat_' + this._id +" .subcategories").toggle();

		// todo: deselect all children
		var is_checked = $('#cat_' + this._id +" .checkbox").first().prop('checked');
		if(!is_checked)
			$('#cat_' + this._id +" .checkbox_sub").prop('checked', false);

	}
});

<commit_msg>fix category loading<commit_after>"use strict";

Template.course_edit.helpers({
	query: function() {
		return Session.get('search')
	},

	available_categories: function(parent) {
		var query = {}
		if (parent) {
			query.parent = parent;
		} else {
			query.parent = { $exists: false };
		}
		return Categories.find(query);
	},

	available_roles: function() {
		return Roles.find({'preset': { $ne: true }})
	},

	// Emit 'checked' string if id shows up as member or property of cats
	checked: function(id, cats) {
		if (cats === undefined) return;
		if (cats.length) {
			return cats.indexOf(id) >= 0 ? 'checked' : ''
		} else {
			return (id in cats) ? 'checked' : ''
		}
	},

	show_subcats: function(id, cats) {
		if (cats === undefined) return 'none';
		if (cats.length) {
			return cats.indexOf(id) >= 0 ? 'block' : 'none'
		} else {
			return (id in cats) ? 'block' : 'none'
		}
	},

	regions: function(){
	  return Regions.find();
	},

	currentRegion: function(region) {
		var currentRegion = Session.get('region')
		return currentRegion && region._id == currentRegion;
	}
});

Template.course_edit.events({
	'submit form.course_edit, click input.save': function (ev) {
		ev.preventDefault()

		try {
			if (!Meteor.userId()){
			    alert("Please log in!")
			    throw "Please log in!"
			}

			var courseId = this._id ? this._id : ''
			var isNew = courseId === ''

			var roles = {}
			$('input.roleselection').each(function(_, rolecheck) {
				roles[rolecheck.name] = rolecheck.checked;
			})

			var changes = {
				description: $('#editform_description').val(),
				categories: $('#editform_categories input:checked').map(function(){ return this.name}).get(),
				name: $('#editform_name').val(),
				roles: roles
			}

			if (isNew) {
				changes.region = $('.region_select').val()
				if (!changes.region) {
					alert("Please select a region")
					return;
				}
			}

			Meteor.call("save_course", courseId, changes, function(err, course) {
				Session.set('search', ''); // clear searchfield
				if (err) alert("Saving the course went terribly wrong: "+err)
				Router.go('showCourse', course)
			})

		} catch(err) {
			if (err instanceof String) alert(err)
			else throw err
		}
	},

	'click input.cancel': function() {
		Session.set("isEditing", false);
	},

	'click #show_categories_to_edit': function(event){
		$('#show_categories_to_edit').toggle();
		$('#edit_categories').toggle();
	},

	'change .categories .checkbox': function(){
		//$('#' + event.currentTarget.id +" .subcategories").toggle();
		$('#cat_' + this._id +" .subcategories").toggle();

		// todo: deselect all children
		var is_checked = $('#cat_' + this._id +" .checkbox").first().prop('checked');
		if(!is_checked)
			$('#cat_' + this._id +" .checkbox_sub").prop('checked', false);

	}
});

<|endoftext|>


<commit_before>import { connect } from 'react-redux';
import {
  makeSelectCostInfoForUri,
  makeSelectFileInfoForUri,
  makeSelectClaimIsMine,
  doNotify,
} from 'lbry-redux';
import FileActions from './view';

const select = (state, props) => ({
  fileInfo: makeSelectFileInfoForUri(props.uri)(state),
  /* availability check is disabled due to poor performance, TBD if it dies forever or requires daemon fix */
  costInfo: makeSelectCostInfoForUri(props.uri)(state),
  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
  claimId: props.claimId,
});

const perform = dispatch => ({
  openModal: (modal, props) => dispatch(doNotify(modal, props)),
});

export default connect(select, perform)(FileActions);
<commit_msg>Remove selector property as is already being passed in from another component<commit_after>import { connect } from 'react-redux';
import {
  makeSelectCostInfoForUri,
  makeSelectFileInfoForUri,
  makeSelectClaimIsMine,
  doNotify,
} from 'lbry-redux';
import FileActions from './view';

const select = (state, props) => ({
  fileInfo: makeSelectFileInfoForUri(props.uri)(state),
  /* availability check is disabled due to poor performance, TBD if it dies forever or requires daemon fix */
  costInfo: makeSelectCostInfoForUri(props.uri)(state),
  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
});

const perform = dispatch => ({
  openModal: (modal, props) => dispatch(doNotify(modal, props)),
});

export default connect(select, perform)(FileActions);
<|endoftext|>


<commit_before>var fs = require('fs');
var mkdirp = require('mkdirp');
var spawn = require('child_process').spawn;

var path = process.argv[2];

var videos = fs.readdirSync(path).filter(function (video) {
  return video.indexOf("mp4") > -1;
});

videos = videos.map(function (video) {
  return video.replace(".mp4", "");
});

console.log(videos);

videos.forEach(function (video) {
  var videoIndex = parseInt(video.split("_")[1], 10) + 1;
  videoIndex = videoIndex > 9 ? videoIndex : "0" + videoIndex;

  var lectureDir = path + "/Lecture_" + videoIndex;
  fs.mkdirSync(lectureDir);
  fs.renameSync(path + "/" + video + ".wav", lectureDir + "/Full_Lecture_Video_" + videoIndex + ".wav");
  fs.renameSync(path + "/" + video + ".mp4", lectureDir + "/Full_Lecture_Video_" + videoIndex + ".mp4");
});

var folders = fs.readdirSync(path).filter(function (folder) {
  return folder.indexOf("Lecture") > -1;
});

console.log(folders);

var splitsDone = 0;
folders.forEach(function (folder) {
  var folderIndex = folder.split("_")[1];
  var command = 'python';
  var args = ["lectureSegmenter.py", path + "/" + folder + "/Full_Lecture_Video_" + folderIndex + ".wav"];
  var segmenterChild = spawn(command, args);
  segmenterChild.stdout.on('data', function (splitTimes) {
    splitTimes = splitTimes.toString().trim();
    console.log(splitTimes)
    var command = 'node';
    var args = [
      "split.js",
      path + "/" + folder + "/Full_Lecture_Video_" + folderIndex + ".mp4"
    ].concat(splitTimes.split(" "));
    var splitChild = spawn(command, args);
    splitChild.on('close', function() {
      splitsDone++;
      console.log(splitsDone);
      if (folders.length === splitsDone) {
        process.exit();
      }
    });
  });
});
<commit_msg>remove index increment splitRunner<commit_after>var fs = require('fs');
var mkdirp = require('mkdirp');
var spawn = require('child_process').spawn;

var path = process.argv[2];

var videos = fs.readdirSync(path).filter(function (video) {
  return video.indexOf("mp4") > -1;
});

videos = videos.map(function (video) {
  return video.replace(".mp4", "");
});

console.log(videos);

videos.forEach(function (video) {
  var videoIndex = parseInt(video.split("_")[1], 10);
  videoIndex = videoIndex > 9 ? videoIndex : "0" + videoIndex;

  var lectureDir = path + "/Lecture_" + videoIndex;
  fs.mkdirSync(lectureDir);
  fs.renameSync(path + "/" + video + ".wav", lectureDir + "/Full_Lecture_Video_" + videoIndex + ".wav");
  fs.renameSync(path + "/" + video + ".mp4", lectureDir + "/Full_Lecture_Video_" + videoIndex + ".mp4");
});

var folders = fs.readdirSync(path).filter(function (folder) {
  return folder.indexOf("Lecture") > -1;
});

console.log(folders);

var splitsDone = 0;
folders.forEach(function (folder) {
  var folderIndex = folder.split("_")[1];
  var command = 'python';
  var args = ["lectureSegmenter.py", path + "/" + folder + "/Full_Lecture_Video_" + folderIndex + ".wav"];
  var segmenterChild = spawn(command, args);
  segmenterChild.stdout.on('data', function (splitTimes) {
    splitTimes = splitTimes.toString().trim();
    console.log(splitTimes)
    var command = 'node';
    var args = [
      "split.js",
      path + "/" + folder + "/Full_Lecture_Video_" + folderIndex + ".mp4"
    ].concat(splitTimes.split(" "));
    var splitChild = spawn(command, args);
    splitChild.on('close', function() {
      splitsDone++;
      console.log(splitsDone);
      if (folders.length === splitsDone) {
        process.exit();
      }
    });
  });
});
<|endoftext|>