<commit_before>/**
 * Module dependencies.
 */
var fs = require("fs")
var path = require("path")
var base64 = require("js-base64").Base64
var mime = require("mime")
var reduceFunctionCall = require("reduce-function-call");

/**
 * Fix url() according to source (`from`) or destination (`to`)
 *
 * @param {Object} options
 */
module.exports = function fixUrl(options) {
  options = options || {}
  var mode = options.url !== undefined ? options.url : "rebase"

  return function(styles, postcssOptions) {
    var from = postcssOptions.from ? path.dirname(postcssOptions.from) : "."
    var to = postcssOptions.to ? path.dirname(postcssOptions.to) : from

    styles.eachDecl(function(decl) {
      if (!decl.value) {
        return
      }

      if (decl.value.indexOf("url(") > -1) {
        processDecl(decl, from, to, mode, options)
      }
    })
  }
}

/**
 * Processes one delcaration
 *
 * @param {Object} decl
 * @param {String} from
 * @param {String} to
 * @param {String} mode
 * @param {Object} options
 */
function processDecl(decl, from, to, mode, options) {
  var dirname = path.dirname(decl.source.file)
  decl.value = reduceFunctionCall(decl.value, "url", function(value) {
    // save quote style
    var quote = getQuote(value)
    value = unquote(value, quote)

    // ignore absolute url
    if (value.indexOf("/") === 0) {
      return value
    }

    var newPath = value

    switch (mode) {
    case "rebase":
      return processRebase(from, dirname, newPath, quote, to)
      break
    case "inline":
      return processInline(from, dirname, newPath, quote, value, options)
      break
    default:
      throw new Error("Unknow mode for postcss-url: " + mode)
      break
    }
  })
}

/**
 * Fix url() according to source (`from`) or destination (`to`)
 *
 * @param {String} from
 * @param {String} dirname
 * @param {String} newPath
 * @param {String} quote
 * @param {String} to
 */
function processRebase(from, dirname, newPath, quote, to) {
  if (dirname !== from) {
    newPath = path.relative(from, dirname + path.sep + newPath)
  }
  newPath = path.resolve(from, newPath)
  newPath = path.relative(to, newPath)
  if (path.sep == "\\") {
    newPath = newPath.replace(/\\/g, "\/");
  }
  return createUrl(quote, newPath);
}

/**
 * Inline image in url()
 *
 * @param {String} from
 * @param {String} dirname
 * @param {String} newPath
 * @param {String} quote
 * @param {String} value
 * @param {Object} options
 */
function processInline(from, dirname, newPath, quote, value, options) {
  var maxSize = typeof(options.maxSize) == "undefined" ? 14 : options.maxSize
  maxSize *= 1024 * 8
  var file = path.resolve(from,
    dirname !== from ? dirname + path.sep + value : value)
  if (!fs.existsSync(file)) {
    console.warn("Can't read file '" + file + "', ignoring")
  }
  else {
    var mimeType = mime.lookup(file)
    var stats = fs.statSync(file);
    if (stats.size >= maxSize) {
      return createUrl(quote, newPath)
    }
    if (!mimeType) {
      console.warn("Unable to find asset mime-type for " + file)
    }
    else {
      file = fs.readFileSync(file).toString()
      newPath = "data:" + mimeType + ";base64," + base64.encode(file)
    }
  }
  return createUrl(quote, newPath)
}

function createUrl(quote, newPath) {
  return "url(" + quote + newPath + quote + ")"
}

/**
 * remove quote around a string
 *
 * @param  {String} string
 * @param  {String} quote
 * @return {String}        unquoted string
 */
function unquote(string, quote) {
  if (quote) {
    return string.substr(1, string.length - 2)
  }

  return string
}

/**
 * return quote type
 *
 * @param  {String} string quoted (or not) value
 * @return {String}        quote if any, or empty string
 */
function getQuote(string) {
  var quote = ""
  Array("\"", "'").forEach(function(q) {
    if (string.charAt(0) === q && string.charAt(string.length - 1) === q) {
      quote = q
    }
  })

  return quote
}
<commit_msg>add ability for basePath<commit_after>/**
 * Module dependencies.
 */
var fs = require("fs")
var path = require("path")
var base64 = require("js-base64").Base64
var mime = require("mime")
var reduceFunctionCall = require("reduce-function-call");

/**
 * Fix url() according to source (`from`) or destination (`to`)
 *
 * @param {Object} options
 */
module.exports = function fixUrl(options) {
  options = options || {}
  var mode = options.url !== undefined ? options.url : "rebase"

  return function(styles, postcssOptions) {
    var from = postcssOptions.from ? path.dirname(postcssOptions.from) : "."
    var to = postcssOptions.to ? path.dirname(postcssOptions.to) : from

    styles.eachDecl(function(decl) {
      if (!decl.value) {
        return
      }

      if (decl.value.indexOf("url(") > -1) {
        processDecl(decl, from, to, mode, options)
      }
    })
  }
}

/**
 * Processes one delcaration
 *
 * @param {Object} decl
 * @param {String} from
 * @param {String} to
 * @param {String} mode
 * @param {Object} options
 */
function processDecl(decl, from, to, mode, options) {
  var dirname = path.dirname(decl.source.file)
  decl.value = reduceFunctionCall(decl.value, "url", function(value) {
    // save quote style
    var quote = getQuote(value)
    value = unquote(value, quote)

    // ignore absolute url
    if (value.indexOf("/") === 0) {
      return value
    }

    var newPath = value

    switch (mode) {
    case "rebase":
      return processRebase(from, dirname, newPath, quote, to)
      break
    case "inline":
      return processInline(from, dirname, newPath, quote, value, options)
      break
    default:
      throw new Error("Unknow mode for postcss-url: " + mode)
      break
    }
  })
}

/**
 * Fix url() according to source (`from`) or destination (`to`)
 *
 * @param {String} from
 * @param {String} dirname
 * @param {String} newPath
 * @param {String} quote
 * @param {String} to
 */
function processRebase(from, dirname, newPath, quote, to) {
  if (dirname !== from) {
    newPath = path.relative(from, dirname + path.sep + newPath)
  }
  newPath = path.resolve(from, newPath)
  newPath = path.relative(to, newPath)
  if (path.sep == "\\") {
    newPath = newPath.replace(/\\/g, "\/");
  }
  return createUrl(quote, newPath);
}

/**
 * Inline image in url()
 *
 * @param {String} from
 * @param {String} dirname
 * @param {String} newPath
 * @param {String} quote
 * @param {String} value
 * @param {Object} options
 */
function processInline(from, dirname, newPath, quote, value, options) {
  var maxSize = typeof(options.maxSize) == "undefined" ? 14 : options.maxSize
  var basePath = options.basePath || from;
  maxSize *= 1024 * 8
  var file = path.resolve(basePath,
    dirname !== from ? dirname + path.sep + value : value)
  if (!fs.existsSync(file)) {
    console.warn("Can't read file '" + file + "', ignoring")
  }
  else {
    var mimeType = mime.lookup(file)
    var stats = fs.statSync(file);
    if (stats.size >= maxSize) {
      return createUrl(quote, newPath)
    }
    if (!mimeType) {
      console.warn("Unable to find asset mime-type for " + file)
    }
    else {
      file = fs.readFileSync(file).toString()
      newPath = "data:" + mimeType + ";base64," + base64.encode(file)
    }
  }
  return createUrl(quote, newPath)
}

function createUrl(quote, newPath) {
  return "url(" + quote + newPath + quote + ")"
}

/**
 * remove quote around a string
 *
 * @param  {String} string
 * @param  {String} quote
 * @return {String}        unquoted string
 */
function unquote(string, quote) {
  if (quote) {
    return string.substr(1, string.length - 2)
  }

  return string
}

/**
 * return quote type
 *
 * @param  {String} string quoted (or not) value
 * @return {String}        quote if any, or empty string
 */
function getQuote(string) {
  var quote = ""
  Array("\"", "'").forEach(function(q) {
    if (string.charAt(0) === q && string.charAt(string.length - 1) === q) {
      quote = q
    }
  })

  return quote
}
<|endoftext|>


<commit_before>'use strict'

var visit = require('unist-util-visit')

module.exports = referenceLinks

var own = {}.hasOwnProperty

function referenceLinks() {
  return transformer
}

function transformer(node) {
  var definitions = {}
  var existing = []

  visit(node, 'definition', find(definitions, existing))
  visit(node, factory(node, definitions, existing))
}

/* Find existing definitions. */
function find(definitions, existing) {
  return one

  function one(node) {
    var url = node.url

    existing.push(node.identifier)

    if (!own.call(definitions, url)) {
      definitions[url] = {}
    }

    definitions[url][node.title] = node
  }
}

/* Transform normal links and images into references and definitions,
 * replaces the current node, and adds a definition if needed. */
function factory(root, definitions, existing) {
  var id = 0

  return one

  /* Transform a normal link/image based on bound
   * `definitions`. */
  function one(node, index, parent) {
    var url = node.url
    var title = node.title
    var replacement
    var identifier
    var titles
    var definition

    if (node.type !== 'image' && node.type !== 'link') {
      return
    }

    if (own.call(definitions, url)) {
      titles = definitions[url]
    } else {
      titles = {}
      definitions[url] = titles
    }

    if (own.call(titles, title)) {
      identifier = titles[title].identifier
    } else {
      do {
        identifier = String(++id)
      } while (existing.indexOf(identifier) !== -1)

      definition = {
        type: 'definition',
        identifier: identifier,
        title: title,
        url: url
      }

      titles[title] = definition

      root.children.push(definition)
    }

    replacement = {
      type: node.type + 'Reference',
      identifier: identifier,
      referenceType: 'full'
    }

    if (node.type === 'image') {
      replacement.alt = node.alt
    } else {
      replacement.children = node.children
    }

    parent.children[index] = replacement
  }
}
<commit_msg>Refactor algorithm<commit_after>'use strict'

var visit = require('unist-util-visit')

module.exports = referenceLinks

var own = {}.hasOwnProperty

function referenceLinks() {
  return transformer
}

function transformer(node) {
  var definitions = {}
  var existing = []

  visit(node, 'definition', find(definitions, existing))
  visit(node, ['image', 'link'], factory(node, definitions, existing))
}

/* Find existing definitions. */
function find(definitions, existing) {
  return one

  function one(node) {
    var url = node.url

    existing.push(node.identifier)

    if (!own.call(definitions, url)) {
      definitions[url] = {}
    }

    definitions[url][node.title] = node
  }
}

/* Transform normal links and images into references and definitions,
 * replaces the current node, and adds a definition if needed. */
function factory(root, definitions, existing) {
  var id = 0

  return one

  /* Transform a normal link/image based on bound
   * `definitions`. */
  function one(node, index, parent) {
    var url = node.url
    var title = node.title
    var replacement
    var identifier
    var titles
    var definition

    if (own.call(definitions, url)) {
      titles = definitions[url]
    } else {
      titles = {}
      definitions[url] = titles
    }

    if (own.call(titles, title)) {
      identifier = titles[title].identifier
    } else {
      do {
        identifier = String(++id)
      } while (existing.indexOf(identifier) !== -1)

      definition = {
        type: 'definition',
        identifier: identifier,
        title: title,
        url: url
      }

      titles[title] = definition

      root.children.push(definition)
    }

    replacement = {
      type: node.type + 'Reference',
      identifier: identifier,
      referenceType: 'full'
    }

    if (node.type === 'image') {
      replacement.alt = node.alt
    } else {
      replacement.children = node.children
    }

    parent.children[index] = replacement
  }
}
<|endoftext|>


<commit_before>module.exports = {
  'env': {
    'browser': true,
    'es6': true,
    'node': true
  },

  'rules': {
    'block-scoped-var': 0,
    'brace-style': [2, '1tbs', { 'allowSingleLine': false }],
    'camelcase': 0,
    'comma-dangle': 0,
    'comma-style': [2, 'last'],
    'complexity': [1, 10],
    'computed-property-spacing': [2, 'never'],
    'consistent-return': 0,
    'eqeqeq': 2,
    'guard-for-in': 2,
    'indent': [2, 2],
    'key-spacing': 0,
    'max-len': [1, 80, 2],
    'max-nested-callbacks': [2, 3],
    'max-params': [1, 4],
    'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }],
    'no-bitwise': 2,
    'no-caller': 2,
    'no-dupe-args': 2,
    'no-dupe-keys': 2,
    'no-duplicate-case': 0,
    'no-eq-null': 2,
    'no-floating-decimal': 2,
    'no-irregular-whitespace': 2,
    'no-lonely-if': 2,
    'no-multi-spaces': 0,
    'no-multiple-empty-lines': 2,
    'no-nested-ternary': 2,
    'no-regex-spaces': 2,
    'no-return-assign': 2,
    'no-self-compare': 2,
    'no-throw-literal': 2,
    'no-underscore-dangle': 0,
    'no-var': 2,
    'no-void': 2,
    'no-with': 2,
    'object-shorthand': [2, 'methods'],
    'operator-assignment': [2, 'always'],
    'operator-linebreak': [2, 'after'],
    'padded-blocks': [2, 'never'],
    'prefer-const': 2,
    'quotes': [2, 'single', 'avoid-escape'],
    'radix': 2,
    'space-after-keywords': [2, 'always'],
    'space-before-blocks': [2, 'always'],
    'space-before-function-paren': [2, 'never'],
    'space-in-parens': [2, 'never'],
    'spaced-line-comment': [2, 'always'],
    'strict': [2, 'never'],
    'use-isnan': 2,
    'valid-jsdoc': [2, {
        'prefer': { 'returns': 'return' },
        'requireParamDescription': false,
        'requireReturn': false,
        'requireReturnDescription': false,
      }
    ],
    'valid-typeof': 2,
    'wrap-iife': [2, 'outside'],
    'yoda': 2,
  }
};
<commit_msg>Downgrade 'space-unary-ops' to warning because of bug<commit_after>module.exports = {
  'env': {
    'browser': true,
    'es6': true,
    'node': true
  },

  'rules': {
    'block-scoped-var': 0,
    'brace-style': [2, '1tbs', { 'allowSingleLine': false }],
    'camelcase': 0,
    'comma-dangle': 0,
    'comma-style': [2, 'last'],
    'complexity': [1, 10],
    'computed-property-spacing': [2, 'never'],
    'consistent-return': 0,
    'eqeqeq': 2,
    'guard-for-in': 2,
    'indent': [2, 2],
    'key-spacing': 0,
    'max-len': [1, 80, 2],
    'max-nested-callbacks': [2, 3],
    'max-params': [1, 4],
    'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }],
    'no-bitwise': 2,
    'no-caller': 2,
    'no-dupe-args': 2,
    'no-dupe-keys': 2,
    'no-duplicate-case': 0,
    'no-eq-null': 2,
    'no-floating-decimal': 2,
    'no-irregular-whitespace': 2,
    'no-lonely-if': 2,
    'no-multi-spaces': 0,
    'no-multiple-empty-lines': 2,
    'no-nested-ternary': 2,
    'no-regex-spaces': 2,
    'no-return-assign': 2,
    'no-self-compare': 2,
    'no-throw-literal': 2,
    'no-underscore-dangle': 0,
    'no-var': 2,
    'no-void': 2,
    'no-with': 2,
    'object-shorthand': [2, 'methods'],
    'operator-assignment': [2, 'always'],
    'operator-linebreak': [2, 'after'],
    'padded-blocks': [2, 'never'],
    'prefer-const': 2,
    'quotes': [2, 'single', 'avoid-escape'],
    'radix': 2,
    'space-after-keywords': [2, 'always'],
    'space-before-blocks': [2, 'always'],
    'space-before-function-paren': [2, 'never'],
    'space-in-parens': [2, 'never'],
    'space-unary-ops': 1,
    'spaced-line-comment': [2, 'always'],
    'strict': [2, 'never'],
    'use-isnan': 2,
    'valid-jsdoc': [2, {
        'prefer': { 'returns': 'return' },
        'requireParamDescription': false,
        'requireReturn': false,
        'requireReturnDescription': false,
      }
    ],
    'valid-typeof': 2,
    'wrap-iife': [2, 'outside'],
    'yoda': 2,
  }
};
<|endoftext|>


<commit_before>'use strict';
const path = require('path');
const fs = require('fs');
const {URL} = require('url');
const electron = require('electron');
// -const electronLocalShortcut = require('electron-localshortcut');
const log = require('electron-log');
const {autoUpdater} = require('electron-updater');
const isDev = require('electron-is-dev');
const appMenu = require('./menu');
const config = require('./config');
const tray = require('./tray');
const {sendAction} = require('./util');

require('./touch-bar'); // eslint-disable-line import/no-unassigned-import

require('electron-debug')({enabled: true});
require('electron-dl')();
require('electron-context-menu')();

const domain = config.get('useWorkChat') ? 'facebook.com' : 'messenger.com';
const {app, ipcMain, Menu, nativeImage} = electron;

app.setAppUserModelId('com.sindresorhus.caprine');

if (!isDev) {
	autoUpdater.logger = log;
	autoUpdater.logger.transports.file.level = 'info';
	const FOUR_HOURS = 1000 * 60 * 60 * 4;
	setInterval(() => autoUpdater.checkForUpdates(), FOUR_HOURS);
}

let mainWindow;
let isQuitting = false;
let prevMessageCount = 0;
let dockMenu;

const isAlreadyRunning = app.makeSingleInstance(() => {
	if (mainWindow) {
		if (mainWindow.isMinimized()) {
			mainWindow.restore();
		}

		mainWindow.show();
	}
});

if (isAlreadyRunning) {
	app.quit();
}

function updateBadge(title, titlePrefix) {
	// ignore `Sindre messaged you` blinking
	if (title.indexOf(titlePrefix) === -1) {
		return;
	}

	let messageCount = (/\((\d+)\)/).exec(title);
	messageCount = messageCount ? Number(messageCount[1]) : 0;

	if (process.platform === 'darwin' || process.platform === 'linux') {
		if (config.get('showUnreadBadge')) {
			app.setBadgeCount(messageCount);
		}
		if (process.platform === 'darwin' && config.get('bounceDockOnMessage') && prevMessageCount !== messageCount) {
			app.dock.bounce('informational');
			prevMessageCount = messageCount;
		}
	}

	if ((process.platform === 'linux' || process.platform === 'win32') && config.get('showUnreadBadge')) {
		tray.setBadge(messageCount);
	}

	if (process.platform === 'win32') {
		if (config.get('showUnreadBadge')) {
			if (messageCount === 0) {
				mainWindow.setOverlayIcon(null, '');
			} else {
				// Delegate drawing of overlay icon to renderer process
				mainWindow.webContents.send('render-overlay-icon', messageCount);
			}
		}

		if (config.get('flashWindowOnMessage')) {
			mainWindow.flashFrame(messageCount !== 0);
		}
	}
}

ipcMain.on('update-overlay-icon', (event, data, text) => {
	const img = electron.nativeImage.createFromDataURL(data);
	mainWindow.setOverlayIcon(img, text);
});

function enableHiresResources() {
	const scaleFactor = Math.max(...electron.screen.getAllDisplays().map(x => x.scaleFactor));
	if (scaleFactor === 1) {
		return;
	}

	const filter = {urls: [`*://*.${domain}/`]};
	electron.session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, callback) => {
		let cookie = details.requestHeaders.Cookie;

		if (cookie && details.method === 'GET') {
			if (/(; )?dpr=\d/.test(cookie)) {
				cookie = cookie.replace(/dpr=\d/, `dpr=${scaleFactor}`);
			} else {
				cookie = `${cookie}; dpr=${scaleFactor}`;
			}

			details.requestHeaders.Cookie = cookie;
		}

		callback({
			cancel: false,
			requestHeaders: details.requestHeaders
		});
	});
}

function setUpPrivacyBlocking() {
	const ses = electron.session.defaultSession;
	const filter = {urls: [`*://*.${domain}/*typ.php*`, `*://*.${domain}/*change_read_status.php*`]};
	ses.webRequest.onBeforeRequest(filter, (details, callback) => {
		let blocking = false;
		if (details.url.includes('typ.php')) {
			blocking = config.get('block.typingIndicator');
		} else {
			blocking = config.get('block.chatSeen');
		}
		callback({cancel: blocking});
	});
}

function setUserLocale() {
	const facebookLocales = require('facebook-locales');
	const userLocale = facebookLocales.bestFacebookLocaleFor(app.getLocale().replace('-', '_'));
	const cookie = {
		url: 'https://www.messenger.com/',
		name: 'locale',
		value: userLocale
	};
	electron.session.defaultSession.cookies.set(cookie, () => {});
}

function setNotificationsMute(status) {
	const label = 'Mute Notifications';
	const muteMenuItem = Menu.getApplicationMenu().items[0].submenu.items
		.find(x => x.label === label);

	config.set('notificationsMuted', status);
	muteMenuItem.checked = status;

	if (process.platform === 'darwin') {
		const item = dockMenu.items.find(x => x.label === label);
		item.checked = status;
	}
}

function createMainWindow() {
	const lastWindowState = config.get('lastWindowState');
	const isDarkMode = config.get('darkMode');
	// Messenger or Work Chat
	const mainURL = config.get('useWorkChat') ? 'https://work.facebook.com/chat' : 'https://www.messenger.com/login/';
	const titlePrefix = config.get('useWorkChat') ? 'Workplace Chat' : 'Messenger';

	const win = new electron.BrowserWindow({
		title: app.getName(),
		show: false,
		x: lastWindowState.x,
		y: lastWindowState.y,
		width: lastWindowState.width,
		height: lastWindowState.height,
		icon: process.platform === 'linux' && path.join(__dirname, 'static/Icon.png'),
		minWidth: 400,
		minHeight: 200,
		alwaysOnTop: config.get('alwaysOnTop'),
		// Temp workaround for macOS High Sierra, see #295
		titleBarStyle: 'hiddenInset',
		autoHideMenuBar: config.get('autoHideMenuBar'),
		darkTheme: isDarkMode, // GTK+3
		webPreferences: {
			preload: path.join(__dirname, 'browser.js'),
			nodeIntegration: false,
			plugins: true
		}
	});

	setUserLocale();
	setUpPrivacyBlocking();

	if (process.platform === 'darwin') {
		win.setSheetOffset(40);
	}

	win.loadURL(mainURL);

	win.on('close', e => {
		if (!isQuitting) {
			e.preventDefault();

			// Workaround for electron/electron#10023
			win.blur();

			if (process.platform === 'darwin') {
				app.hide();
			} else {
				win.hide();
			}
		}
	});

	win.on('page-title-updated', (e, title) => {
		e.preventDefault();
		updateBadge(title, titlePrefix);
	});

	win.on('focus', () => {
		if (config.get('flashWindowOnMessage')) {
			// This is a security in the case where messageCount is not reset by page title update
			win.flashFrame(false);
		}
	});

	return win;
}

app.on('ready', () => {
	const trackingUrlPrefix = `https://l.${domain}/l.php`;
	electron.Menu.setApplicationMenu(appMenu);
	mainWindow = createMainWindow();
	tray.create(mainWindow);

	if (process.platform === 'darwin') {
		const firstItem = {
			label: 'Mute Notifications',
			type: 'checkbox',
			checked: config.get('notificationsMuted'),
			click() {
				mainWindow.webContents.send('toggle-mute-notifications');
			}
		};
		dockMenu = electron.Menu.buildFromTemplate([firstItem]);
		app.dock.setMenu(dockMenu);

		ipcMain.on('conversations', (event, conversations) => {
			if (conversations.length === 0) {
				return;
			}

			const items = conversations.map(({label, icon}, index) => {
				return {
					label: `${label}`,
					icon: nativeImage.createFromDataURL(icon),
					click: () => {
						mainWindow.show();
						sendAction('jump-to-conversation', index + 1);
					}
				};
			});
			app.dock.setMenu(electron.Menu.buildFromTemplate([firstItem, {type: 'separator'}, ...items]));
		});
	}

	enableHiresResources();

	const {webContents} = mainWindow;

	// Disabled because of #258
	// electronLocalShortcut.register(mainWindow, 'CmdOrCtrl+V', () => {
	// 	const clipboardHasImage = electron.clipboard.availableFormats().some(type => type.includes('image'));

	// 	if (clipboardHasImage && config.get('confirmImagePaste')) {
	// 		electron.dialog.showMessageBox(mainWindow, {
	// 			type: 'info',
	// 			buttons: ['Send', 'Cancel'],
	// 			message: 'Are you sure you want to send the image in the clipboard?',
	// 			icon: electron.clipboard.readImage(),
	// 			checkboxLabel: 'Don\'t ask me again',
	// 			checkboxChecked: false
	// 		}, (resp, checkboxChecked) => {
	// 			if (resp === 0) {
	// 				// User selected send
	// 				webContents.paste();
	// 				config.set('confirmImagePaste', !checkboxChecked);
	// 			}
	// 		});
	// 	} else {
	// 		webContents.paste();
	// 	}
	// });

	webContents.on('dom-ready', () => {
		webContents.insertCSS(fs.readFileSync(path.join(__dirname, 'browser.css'), 'utf8'));
		webContents.insertCSS(fs.readFileSync(path.join(__dirname, 'dark-mode.css'), 'utf8'));
		webContents.insertCSS(fs.readFileSync(path.join(__dirname, 'vibrancy.css'), 'utf8'));
		if (config.get('useWorkChat')) {
			webContents.insertCSS(fs.readFileSync(path.join(__dirname, 'workchat.css'), 'utf8'));
		}

		if (config.get('launchMinimized') || app.getLoginItemSettings().wasOpenedAsHidden) {
			mainWindow.hide();
		} else {
			mainWindow.show();
		}

		mainWindow.webContents.send('toggle-mute-notifications', config.get('notificationsMuted'));
		mainWindow.webContents.send('toggle-message-buttons', config.get('showMessageButtons'));
	});

	webContents.on('new-window', (event, url, frameName, disposition, options) => {
		event.preventDefault();

		if (url === 'about:blank') {
			if (frameName !== 'about:blank') { // Voice/video call popup
				options.show = true;
				options.titleBarStyle = 'default';
				options.webPreferences.nodeIntegration = false;
				options.webPreferences.preload = path.join(__dirname, 'browser-call.js');
				event.newGuest = new electron.BrowserWindow(options);
			}
		} else {
			if (url.startsWith(trackingUrlPrefix)) {
				url = new URL(url).searchParams.get('u');
			}

			electron.shell.openExternal(url);
		}
	});

	webContents.on('will-navigate', (event, url) => {
		const {hostname} = new URL(url);
		const twoFactorAuthURL = 'https://www.facebook.com/checkpoint/start';
		if (hostname === 'www.messenger.com' || url.startsWith(twoFactorAuthURL)) {
			return;
		}

		event.preventDefault();
		electron.shell.openExternal(url);
	});
});

ipcMain.on('set-vibrancy', () => {
	if (config.get('vibrancy')) {
		mainWindow.setVibrancy(config.get('darkMode') ? 'ultra-dark' : 'light');
	} else {
		mainWindow.setVibrancy(null);
	}
});

ipcMain.on('mute-notifications-toggled', (event, status) => {
	setNotificationsMute(status);
});

app.on('activate', () => {
	mainWindow.show();
});

app.on('before-quit', () => {
	isQuitting = true;

	if (!mainWindow.isFullScreen()) {
		config.set('lastWindowState', mainWindow.getBounds());
	}
});
<commit_msg>Fix Work Chat (#530)<commit_after>'use strict';
const path = require('path');
const fs = require('fs');
const {URL} = require('url');
const electron = require('electron');
// -const electronLocalShortcut = require('electron-localshortcut');
const log = require('electron-log');
const {autoUpdater} = require('electron-updater');
const isDev = require('electron-is-dev');
const appMenu = require('./menu');
const config = require('./config');
const tray = require('./tray');
const {sendAction} = require('./util');

require('./touch-bar'); // eslint-disable-line import/no-unassigned-import

require('electron-debug')({enabled: true});
require('electron-dl')();
require('electron-context-menu')();

const domain = config.get('useWorkChat') ? 'facebook.com' : 'messenger.com';
const {app, ipcMain, Menu, nativeImage} = electron;

app.setAppUserModelId('com.sindresorhus.caprine');

if (!isDev) {
	autoUpdater.logger = log;
	autoUpdater.logger.transports.file.level = 'info';
	const FOUR_HOURS = 1000 * 60 * 60 * 4;
	setInterval(() => autoUpdater.checkForUpdates(), FOUR_HOURS);
}

let mainWindow;
let isQuitting = false;
let prevMessageCount = 0;
let dockMenu;

const isAlreadyRunning = app.makeSingleInstance(() => {
	if (mainWindow) {
		if (mainWindow.isMinimized()) {
			mainWindow.restore();
		}

		mainWindow.show();
	}
});

if (isAlreadyRunning) {
	app.quit();
}

function updateBadge(title, titlePrefix) {
	// ignore `Sindre messaged you` blinking
	if (title.indexOf(titlePrefix) === -1) {
		return;
	}

	let messageCount = (/\((\d+)\)/).exec(title);
	messageCount = messageCount ? Number(messageCount[1]) : 0;

	if (process.platform === 'darwin' || process.platform === 'linux') {
		if (config.get('showUnreadBadge')) {
			app.setBadgeCount(messageCount);
		}
		if (process.platform === 'darwin' && config.get('bounceDockOnMessage') && prevMessageCount !== messageCount) {
			app.dock.bounce('informational');
			prevMessageCount = messageCount;
		}
	}

	if ((process.platform === 'linux' || process.platform === 'win32') && config.get('showUnreadBadge')) {
		tray.setBadge(messageCount);
	}

	if (process.platform === 'win32') {
		if (config.get('showUnreadBadge')) {
			if (messageCount === 0) {
				mainWindow.setOverlayIcon(null, '');
			} else {
				// Delegate drawing of overlay icon to renderer process
				mainWindow.webContents.send('render-overlay-icon', messageCount);
			}
		}

		if (config.get('flashWindowOnMessage')) {
			mainWindow.flashFrame(messageCount !== 0);
		}
	}
}

ipcMain.on('update-overlay-icon', (event, data, text) => {
	const img = electron.nativeImage.createFromDataURL(data);
	mainWindow.setOverlayIcon(img, text);
});

function enableHiresResources() {
	const scaleFactor = Math.max(...electron.screen.getAllDisplays().map(x => x.scaleFactor));
	if (scaleFactor === 1) {
		return;
	}

	const filter = {urls: [`*://*.${domain}/`]};
	electron.session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, callback) => {
		let cookie = details.requestHeaders.Cookie;

		if (cookie && details.method === 'GET') {
			if (/(; )?dpr=\d/.test(cookie)) {
				cookie = cookie.replace(/dpr=\d/, `dpr=${scaleFactor}`);
			} else {
				cookie = `${cookie}; dpr=${scaleFactor}`;
			}

			details.requestHeaders.Cookie = cookie;
		}

		callback({
			cancel: false,
			requestHeaders: details.requestHeaders
		});
	});
}

function setUpPrivacyBlocking() {
	const ses = electron.session.defaultSession;
	const filter = {urls: [`*://*.${domain}/*typ.php*`, `*://*.${domain}/*change_read_status.php*`]};
	ses.webRequest.onBeforeRequest(filter, (details, callback) => {
		let blocking = false;
		if (details.url.includes('typ.php')) {
			blocking = config.get('block.typingIndicator');
		} else {
			blocking = config.get('block.chatSeen');
		}
		callback({cancel: blocking});
	});
}

function setUserLocale() {
	const facebookLocales = require('facebook-locales');
	const userLocale = facebookLocales.bestFacebookLocaleFor(app.getLocale().replace('-', '_'));
	const cookie = {
		url: 'https://www.messenger.com/',
		name: 'locale',
		value: userLocale
	};
	electron.session.defaultSession.cookies.set(cookie, () => {});
}

function setNotificationsMute(status) {
	const label = 'Mute Notifications';
	const muteMenuItem = Menu.getApplicationMenu().items[0].submenu.items
		.find(x => x.label === label);

	config.set('notificationsMuted', status);
	muteMenuItem.checked = status;

	if (process.platform === 'darwin') {
		const item = dockMenu.items.find(x => x.label === label);
		item.checked = status;
	}
}

function createMainWindow() {
	const lastWindowState = config.get('lastWindowState');
	const isDarkMode = config.get('darkMode');
	// Messenger or Work Chat
	const mainURL = config.get('useWorkChat') ? 'https://work.facebook.com/chat' : 'https://www.messenger.com/login/';
	const titlePrefix = config.get('useWorkChat') ? 'Workplace Chat' : 'Messenger';

	const win = new electron.BrowserWindow({
		title: app.getName(),
		show: false,
		x: lastWindowState.x,
		y: lastWindowState.y,
		width: lastWindowState.width,
		height: lastWindowState.height,
		icon: process.platform === 'linux' && path.join(__dirname, 'static/Icon.png'),
		minWidth: 400,
		minHeight: 200,
		alwaysOnTop: config.get('alwaysOnTop'),
		// Temp workaround for macOS High Sierra, see #295
		titleBarStyle: 'hiddenInset',
		autoHideMenuBar: config.get('autoHideMenuBar'),
		darkTheme: isDarkMode, // GTK+3
		webPreferences: {
			preload: path.join(__dirname, 'browser.js'),
			nodeIntegration: false,
			plugins: true
		}
	});

	setUserLocale();
	setUpPrivacyBlocking();

	if (process.platform === 'darwin') {
		win.setSheetOffset(40);
	}

	win.loadURL(mainURL);

	win.on('close', e => {
		if (!isQuitting) {
			e.preventDefault();

			// Workaround for electron/electron#10023
			win.blur();

			if (process.platform === 'darwin') {
				app.hide();
			} else {
				win.hide();
			}
		}
	});

	win.on('page-title-updated', (e, title) => {
		e.preventDefault();
		updateBadge(title, titlePrefix);
	});

	win.on('focus', () => {
		if (config.get('flashWindowOnMessage')) {
			// This is a security in the case where messageCount is not reset by page title update
			win.flashFrame(false);
		}
	});

	return win;
}

app.on('ready', () => {
	const trackingUrlPrefix = `https://l.${domain}/l.php`;
	electron.Menu.setApplicationMenu(appMenu);
	mainWindow = createMainWindow();
	tray.create(mainWindow);

	if (process.platform === 'darwin') {
		const firstItem = {
			label: 'Mute Notifications',
			type: 'checkbox',
			checked: config.get('notificationsMuted'),
			click() {
				mainWindow.webContents.send('toggle-mute-notifications');
			}
		};
		dockMenu = electron.Menu.buildFromTemplate([firstItem]);
		app.dock.setMenu(dockMenu);

		ipcMain.on('conversations', (event, conversations) => {
			if (conversations.length === 0) {
				return;
			}

			const items = conversations.map(({label, icon}, index) => {
				return {
					label: `${label}`,
					icon: nativeImage.createFromDataURL(icon),
					click: () => {
						mainWindow.show();
						sendAction('jump-to-conversation', index + 1);
					}
				};
			});
			app.dock.setMenu(electron.Menu.buildFromTemplate([firstItem, {type: 'separator'}, ...items]));
		});
	}

	enableHiresResources();

	const {webContents} = mainWindow;

	// Disabled because of #258
	// electronLocalShortcut.register(mainWindow, 'CmdOrCtrl+V', () => {
	// 	const clipboardHasImage = electron.clipboard.availableFormats().some(type => type.includes('image'));

	// 	if (clipboardHasImage && config.get('confirmImagePaste')) {
	// 		electron.dialog.showMessageBox(mainWindow, {
	// 			type: 'info',
	// 			buttons: ['Send', 'Cancel'],
	// 			message: 'Are you sure you want to send the image in the clipboard?',
	// 			icon: electron.clipboard.readImage(),
	// 			checkboxLabel: 'Don\'t ask me again',
	// 			checkboxChecked: false
	// 		}, (resp, checkboxChecked) => {
	// 			if (resp === 0) {
	// 				// User selected send
	// 				webContents.paste();
	// 				config.set('confirmImagePaste', !checkboxChecked);
	// 			}
	// 		});
	// 	} else {
	// 		webContents.paste();
	// 	}
	// });

	webContents.on('dom-ready', () => {
		webContents.insertCSS(fs.readFileSync(path.join(__dirname, 'browser.css'), 'utf8'));
		webContents.insertCSS(fs.readFileSync(path.join(__dirname, 'dark-mode.css'), 'utf8'));
		webContents.insertCSS(fs.readFileSync(path.join(__dirname, 'vibrancy.css'), 'utf8'));
		if (config.get('useWorkChat')) {
			webContents.insertCSS(fs.readFileSync(path.join(__dirname, 'workchat.css'), 'utf8'));
		}

		if (config.get('launchMinimized') || app.getLoginItemSettings().wasOpenedAsHidden) {
			mainWindow.hide();
		} else {
			mainWindow.show();
		}

		mainWindow.webContents.send('toggle-mute-notifications', config.get('notificationsMuted'));
		mainWindow.webContents.send('toggle-message-buttons', config.get('showMessageButtons'));
	});

	webContents.on('new-window', (event, url, frameName, disposition, options) => {
		event.preventDefault();

		if (url === 'about:blank') {
			if (frameName !== 'about:blank') { // Voice/video call popup
				options.show = true;
				options.titleBarStyle = 'default';
				options.webPreferences.nodeIntegration = false;
				options.webPreferences.preload = path.join(__dirname, 'browser-call.js');
				event.newGuest = new electron.BrowserWindow(options);
			}
		} else {
			if (url.startsWith(trackingUrlPrefix)) {
				url = new URL(url).searchParams.get('u');
			}

			electron.shell.openExternal(url);
		}
	});

	webContents.on('will-navigate', (event, url) => {
		const isMessengerDotCom = url => {
			const {hostname} = new URL(url);
			return hostname === 'www.messenger.com';
		};

		const isTwoFactorAuth = url => {
			const twoFactorAuthURL = 'https://www.facebook.com/checkpoint/start';
			return url.startsWith(twoFactorAuthURL);
		};

		const isWorkChat = url => {
			const {hostname, pathname} = new URL(url);

			if (hostname === 'work.facebook.com') {
				return true;
			}

			if (
				// Example: https://company-name.facebook.com/login
				hostname.endsWith('.facebook.com') &&
				(pathname.startsWith('/login') || pathname.startsWith('/chat'))
			) {
				return true;
			}

			return false;
		};

		if (
			isMessengerDotCom(url) ||
			isTwoFactorAuth(url) ||
			isWorkChat(url)
		) {
			return;
		}

		event.preventDefault();
		electron.shell.openExternal(url);
	});
});

ipcMain.on('set-vibrancy', () => {
	if (config.get('vibrancy')) {
		mainWindow.setVibrancy(config.get('darkMode') ? 'ultra-dark' : 'light');
	} else {
		mainWindow.setVibrancy(null);
	}
});

ipcMain.on('mute-notifications-toggled', (event, status) => {
	setNotificationsMute(status);
});

app.on('activate', () => {
	mainWindow.show();
});

app.on('before-quit', () => {
	isQuitting = true;

	if (!mainWindow.isFullScreen()) {
		config.set('lastWindowState', mainWindow.getBounds());
	}
});
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var chain = require('slide').chain;
var last = chain.last;
var Heroku = require('heroku-client');
var spawn = require('child_process').spawn;
var superagent = require('superagent');

/**
 * Create a GitHub hook
 *
 * @param {Object} config
 * @return {Function}
 */

module.exports = function(config) {
  config = config || {};

  var token = config.token;
  var prefix = config.prefix;
  var drain = config.drain;

  if (!token) throw new Error('missing heroku token');
  if (!prefix) throw new Error('missing heroku prefix');

  var client = new Heroku({token: token});
  var api = new API(client, token);

  return deploy;
  return function(app) {
    return app.deploy('heroku', deploy);
  };

  function deploy(task, log, fn) {
    var name = task.repo.replace(/-/g, '');
    var branch = task.branch.replace(/-/g, '');

    if (branch === 'prod' || branch === 'test') return fn(new Error('cannot deploy reserved branch ' + branch));

    if (branch === 'master') branch = 'test';

    var app = [prefix, name, branch].join('-');

    chain([
      [api, 'exists', app, log],
      [api, 'create', app, last, log],
      [api, 'enableFeature', app, 'log-runtime-metrics', log],
      [api, 'enableFeature', app, 'user-env-compile', log],
      [api, 'addDrain', app, drain, log],
      [createSlug, task.dir, log],
      [api, 'release', app, last, log]
    ], fn);
  };
};

function API(client, token) {
  this.client = client;
  this.token = token;
}

API.prototype.exists = function(app, log, fn) {
  log('checking app existance');
  this.client.apps(app).info(function(err, info) {
    if (err && err.statusCode === 404) return fn(null, false);
    if (err) return fn(err);
    fn(null, true);
  });
};

API.prototype.create = function(app, exists, log, fn) {
  if (exists) return fn();
  var params = {
    name: app
  };
  log('creating app ' + app);
  this.client.apps().create(params, fn);
};

API.prototype.enableFeature = function(app, feature, log, fn) {
  log('enabling feature ' + feature);
  this.client.apps(app).features(feature).update({enabled: true}, fn);
};

API.prototype.addDrain = function(app, drain, log, fn) {
  if (!drain) return fn();
  log('adding log drain ' + drain);
  this.client.apps(app).logDrains().create({url: drain}, function(err) {
    if (err && err.statusCode === 422) return fn();
    if (err) return fn(err);
    fn();
  });
};

API.prototype.release = function(app, url, log, fn) {
  log('releasing slug');
  var host = 'https://:' + this.token + '@cisaurus.heroku.com';
  superagent
    .post(host + '/v1/apps/' + app + '/release')
    .send({description: 'Building from grappler', slug_url: url})
    .end(function(err, res) {
      if (err) return fn(err);
      if (res.status === 202) return poll(res.header['location']);
      if (res.error) return fn(new Error(res.body ? res.body.error : res.text));
      fn(null);
    });

  function poll(location) {
    setTimeout(function() {
      superagent
        .get(host + location)
        .end(function(err, res) {
          if (err) return fn(err);
          if (res.status === 202) return poll(location);
          if (res.error) return fn(new Error(res.text));
          log('release ' + res.body.release);
          fn(null);
        });
    }, 2000);
  }
};

function createSlug(dir, log, fn) {
  log('building slug');
  var anvil = spawn(__dirname + '/vendor/bin/anvil', ['build', dir, '-p'], {
    env: {
      GEM_HOME: __dirname + '/vendor'
    }
  });

  var url;
  anvil.stdout.on('data', function(data) {
    url = '' + data;
  });

  anvil.stderr.on('data', function(data) {
    log('' + data);
  });

  anvil.on('error', function(err) {
    if (err.code === 'ENOENT') return log('error', 'missing anvil build tool');
  });

  anvil.on('close', function(code) {
    if (code !== 0) return fn(new Error('slug was not compiled'));
    if (!url) return new Error('missing slug url');
    setTimeout(function() {
      fn(null, url);
    }, 2000);
  });
}
<commit_msg>support branch deletion<commit_after>/**
 * Module dependencies
 */

var chain = require('slide').chain;
var last = chain.last;
var Heroku = require('heroku-client');
var spawn = require('child_process').spawn;
var superagent = require('superagent');

/**
 * Create a GitHub hook
 *
 * @param {Object} config
 * @return {Function}
 */

module.exports = function(config) {
  config = config || {};

  var token = config.token;
  var prefix = config.prefix;
  var drain = config.drain;

  if (!token) throw new Error('missing heroku token');
  if (!prefix) throw new Error('missing heroku prefix');

  var client = new Heroku({token: token});
  var api = new API(client, token);

  return deploy;
  return function(app) {
    return app.deploy('heroku', deploy);
  };

  function deploy(task, log, fn) {
    var name = task.repo.replace(/-/g, '');
    var branch = task.branch.replace(/-/g, '');

    if (branch === 'prod' || branch === 'test') return fn(new Error('cannot deploy reserved branch ' + branch));

    if (branch === 'master') branch = 'test';

    var app = [prefix, name, branch].join('-');

    if (task.event === 'delete') {
      if (branch === 'test') return fn(new Error('cannot delete master branch'));
      return api.delete(app, log, fn);
    }

    function create(appname, push) {
      return [
        [api, 'exists', appname, log],
        [api, 'create', appname, last, log],
        [api, 'enableFeature', appname, 'log-runtime-metrics', log],
        [api, 'enableFeature', appname, 'user-env-compile', log],
        [api, 'addDrain', appname, drain, log]
      ].concat(push);
    }

    chain(create(app, [
      [createSlug, task.dir, log],
      [api, 'release', app, last, log],
      [api, 'test', app, log]
    ]), function(err, res) {
      if (err) return fn(err);
      if (branch !== 'test') return fn();

      // Deploy to prod
      var prod = [prefix, name, 'prod'].join('-');
      chain(create(prod, [
        [api, 'release', prod, res[1], log]
      ]), fn);
    });
  };
};

function API(client, token) {
  this.client = client;
  this.token = token;
}

API.prototype.exists = function(app, log, fn) {
  log('checking existance of ' + app);
  this.client.apps(app).info(function(err, info) {
    if (err && err.statusCode === 404) return fn(null, false);
    if (err) return fn(err);
    fn(null, true);
  });
};

API.prototype.create = function(app, exists, log, fn) {
  if (exists) return fn();
  var params = {
    name: app
  };
  log('creating ' + app);
  this.client.apps().create(params, fn);
};

API.prototype.enableFeature = function(app, feature, log, fn) {
  log('enabling feature ' + feature + ' on ' + app);
  this.client.apps(app).features(feature).update({enabled: true}, function(err) {
    fn(err);
  });
};

API.prototype.addDrain = function(app, drain, log, fn) {
  if (!drain) return fn();
  log('adding log drain ' + drain + ' to ' + app);
  this.client.apps(app).logDrains().create({url: drain}, function(err) {
    if (err && err.statusCode === 422) return fn();
    if (err) return fn(err);
    fn();
  });
};

API.prototype.release = function(app, url, log, fn) {
  log('releasing slug to ' + app);

  var host = 'https://:' + this.token + '@cisaurus.heroku.com';

  superagent
    .post(host + '/v1/apps/' + app + '/release')
    .send({description: 'Building from grappler', slug_url: url})
    .end(function(err, res) {
      if (err) return fn(err);
      if (res.status === 202) return poll(res.header['location']);
      if (res.error) return fn(new Error(res.body ? res.body.error : res.text));
      fn(null);
    });

  function poll(location) {
    setTimeout(function() {
      superagent
        .get(host + location)
        .end(function(err, res) {
          if (err) return fn(err);
          if (res.status === 202) return poll(location);
          if (res.error) return fn(new Error(res.text));
          log('release ' + res.body.release);
          fn(null);
        });
    }, 2000);
  }
};

API.prototype.test = function(app, log, fn) {
  log('running tests');
  // TODO
  // this.client.apps(app).dynos().create({command: '', attach: true, env: {}}, fn);
  fn();
}

API.prototype.delete = function(app, log, fn) {
  log('deleting app ' + app);
  this.client.apps(app).delete(fn);
}

function createSlug(dir, log, fn) {
  log('building slug');
  var anvil = spawn(__dirname + '/vendor/bin/anvil', ['build', dir, '-p'], {
    env: {
      GEM_HOME: __dirname + '/vendor'
    }
  });

  var url;
  anvil.stdout.on('data', function(data) {
    url = ('' + data).replace("\n", '');
  });

  anvil.stderr.on('data', function(data) {
    log('' + data);
  });

  anvil.on('error', function(err) {
    if (err.code === 'ENOENT') return log('error', 'missing anvil build tool');
  });

  anvil.on('close', function(code) {
    if (code !== 0) return fn(new Error('slug was not compiled'));
    if (!url) return new Error('missing slug url');
    setTimeout(function() {
      fn(null, url);
    }, 2000);
  });
}
<|endoftext|>


<commit_before>'use strict';

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var pack = require('./package.json');
var request = require('request');
var fs = require('fs');
var childProcess = require('child_process');
var path = require('path');

app.locals.ENV = process.env.NODE_ENV;
app.set('env', process.env.NODE_ENV);
app.set('branch', process.env.DEFAULT_BRANCH);
app.set('debug', process.env.NODE_ENV === 'development');
app.set('port', process.env.PORT || 3000);
app.set('name', pack.name);
app.set('secret', process.env.WEBHOOK_SECRET || '');

app.use(bodyParser.json());

app.post('/', function(req, res){
  var secret = req.body.secret;
  if(app.get('secret') !== secret){
    return res.status(403).json({error: 'Invalid secret!'});
  }

  if(!req.body.repository){
    return res.status(400).json({error: 'no repository is given'});
  }

  var branch = app.get('branch');
  var url = `${req.body.repository.url}/src/${branch}/crane-route`;

  return request(url, (error, response, body) => {
    if (error || response.statusCode != 200) return res.status(400).json({error: 'error during fetching the file: ${url} error: ${error}'});

    var tmpFile = path.resolve(__dirname, '.tmp_script');
    fs.writeFile(tmpFile, body, {mode: 0o777}, (err) => {
      if(err) return res.status(400).json({err: err});

      childProcess.execFile(tmpFile, [], (err, stdout, stderr) => {
        if(err) return res.status(400).json({err: err});
        else return res.send(`stdout:\n${stdout}stderr:\n${stderr}`);
      });
    });
  });
});

app.use(function (req, res) {
  res.status(404).json({error: 'Not Found :('});
});

var server = app.listen(app.get('port'), function () {
  console.log('%s is running on port!', app.get('name'), app.get('port'));
});

module.exports = {server: server, app: app};

<commit_msg>added console logging<commit_after>'use strict';

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var pack = require('./package.json');
var request = require('request');
var fs = require('fs');
var childProcess = require('child_process');
var path = require('path');

app.locals.ENV = process.env.NODE_ENV;
app.set('env', process.env.NODE_ENV);
app.set('branch', process.env.DEFAULT_BRANCH);
app.set('debug', process.env.NODE_ENV === 'development');
app.set('port', process.env.PORT || 3000);
app.set('name', pack.name);
app.set('secret', process.env.WEBHOOK_SECRET || '');

app.use(bodyParser.json());

app.post('/', function(req, res){
  var secret = req.body.secret;
  if(app.get('secret') !== secret){
    return res.status(403).json({error: 'Invalid secret!'});
  }

  if(!req.body.repository){
    return res.status(400).json({error: 'no repository is given'});
  }

  var branch = app.get('branch');
  var url = `${req.body.repository.url}/src/${branch}/crane-route`;

  return request(url, (error, response, body) => {
    if (error || response.statusCode != 200) {
      console.log('error fetching from: ' + url);
      console.log(error);
      return res.status(400).json({error: `error during fetching the file: ${url} error: ${error}`});
    }

    var tmpFile = path.resolve(__dirname, '.tmp_script');
    fs.writeFile(tmpFile, body, {mode: 0o777}, (err) => {
      if(err) return res.status(400).json({err: err});

      childProcess.execFile(tmpFile, [], (err, stdout, stderr) => {
        if(err) return res.status(400).json({err: err});
        else return res.send(`stdout:\n${stdout}stderr:\n${stderr}`);
      });
    });
  });
});

app.use(function (req, res) {
  res.status(404).json({error: 'Not Found :('});
});

var server = app.listen(app.get('port'), function () {
  console.log(`${app.get('name')} is running on port: ${app.get('port')}!`);
});

module.exports = {server: server, app: app};

<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var http = require('http');
var util = require('util');

var del = require('del');
var gutil = require('gulp-util');
var ecstatic = require('ecstatic');
var DefaultRegistry = require('undertaker-registry');

function CommonRegistry(opts){
  DefaultRegistry.call(this);

  opts = opts || {};

  this.config = {
    port: opts.port || 8080,
    buildDir: opts.buildDir || './build'
  };
}

util.inherits(CommonRegistry, DefaultRegistry);

CommonRegistry.prototype.init = function init(taker){
  var port = this.config.port;
  var buildDir = this.config.buildDir;
  var exists = fs.existsSync(buildDir);

  if(exists){
    throw new Error('Cannot initialize undertaker-common-tasks registry. `build/` directory exists.');
  }

  taker.set('clean', function(cb){
    del([buildDir], cb);
  });

  taker.set('serve', function(cb){
    http.createServer(
      ecstatic({ root: buildDir })
    ).listen(port, function(){
      gutil.log('Server started at http://0.0.0.0:' + port);
      cb();
    });
  });
};

module.exports = CommonRegistry;
<commit_msg>derp, no set method<commit_after>'use strict';

var fs = require('fs');
var http = require('http');
var util = require('util');

var del = require('del');
var gutil = require('gulp-util');
var ecstatic = require('ecstatic');
var DefaultRegistry = require('undertaker-registry');

function CommonRegistry(opts){
  DefaultRegistry.call(this);

  opts = opts || {};

  this.config = {
    port: opts.port || 8080,
    buildDir: opts.buildDir || './build'
  };
}

util.inherits(CommonRegistry, DefaultRegistry);

CommonRegistry.prototype.init = function init(taker){
  var port = this.config.port;
  var buildDir = this.config.buildDir;
  var exists = fs.existsSync(buildDir);

  if(exists){
    throw new Error('Cannot initialize undertaker-common-tasks registry. `build/` directory exists.');
  }

  taker.task('clean', function(cb){
    del([buildDir], cb);
  });

  taker.task('serve', function(cb){
    http.createServer(
      ecstatic({ root: buildDir })
    ).listen(port, function(){
      gutil.log('Server started at http://0.0.0.0:' + port);
      cb();
    });
  });
};

module.exports = CommonRegistry;
<|endoftext|>


<commit_before>"use strict";

var Promise = require('bluebird');
var store = require('./store');
var extend = require('extend');
var NORMAL = 'NORMAL';
var BEFORE = 'BEFORE';
var AFTER = 'AFTER';

function addHook(type, name, key, fn) {
    var attach = function() {
        return addHook(type, name, key, fn);
    };

    if (typeof key === "function") {
        fn = key;
        key = undefined;
    }

    if (Array.isArray(name)) {
        name.forEach(function(n) {
            addHook(type, n, key, fn);
        });
    } else {
        store.add(type, name, {
            fn: fn,
            key: key
        });
    }

    return {
        key: key,
        run: fn,
        name: name,
        type: type,
        attach: attach
    };
}

exports.register = addHook.bind(this, NORMAL);

exports.before = addHook.bind(this, BEFORE);

exports.after = addHook.bind(this, AFTER);

function runHook(hooks, args) {
    var current = Promise.resolve();
    if (!hooks) {
        hooks = [];
    }
    var results = {};
    return Promise.all(hooks.map(function(hook){
        var fn = hook.fn;
        current = current.then(function() {
            return fn.apply(this, args);
        });
        return current.then(function(result) {
            if (hook.key) {
                results[hook.key] = result;
            }
            return result;
        });
    })).then(function() {
        return results;
    });
}

function runHookParallel(hooks, args) {
    if (!hooks) {
        hooks = [];
    }
    return Promise.all(hooks.map(function(hook){
        var fn = hook.fn;
        return fn.apply(this, args);
    })).then(function(results) {
        var props = {};
        results.forEach(function(result, index) {
            var key = hooks[index].key;
            if (key) {
                props[key] = result;
            }
        });
        return props;
    });
}

exports.run = function(name) {
    var result = {};
    var args = Array.prototype.slice.call(arguments);

    // remove first argument
    args.shift();

    return runHook(store.get(BEFORE, name), args).then(function(beforeResult) {
        result = extend(result, beforeResult);
        return runHook(store.get(NORMAL, name), args);
    }).then(function(normalResult) {
        result = extend(result, normalResult);
        return runHook(store.get(AFTER, name), args);
    }).then(function(afterResult) {
        result = extend(result, afterResult);
        return result;
    });
};

exports.parallel = function(name) {
    var result = {};
    var args = Array.prototype.slice.call(arguments);

    // remove first argument
    args.shift();

    return runHookParallel(store.get(BEFORE, name), args).then(function(beforeResult) {
        result = extend(result, beforeResult);
        return runHookParallel(store.get(NORMAL, name), args);
    }).then(function(normalResult) {
        result = extend(result, normalResult);
        return runHookParallel(store.get(AFTER, name), args);
    }).then(function(afterResult) {
        result = extend(result, afterResult);
        return result;
    });
};

exports.___clearHooks = function(name) {
    store.clear(name);
};

<commit_msg>add .clear alias for clear hook<commit_after>"use strict";

var Promise = require('bluebird');
var store = require('./store');
var extend = require('extend');
var NORMAL = 'NORMAL';
var BEFORE = 'BEFORE';
var AFTER = 'AFTER';

function addHook(type, name, key, fn) {
    var attach = function() {
        return addHook(type, name, key, fn);
    };

    if (typeof key === "function") {
        fn = key;
        key = undefined;
    }

    if (Array.isArray(name)) {
        name.forEach(function(n) {
            addHook(type, n, key, fn);
        });
    } else {
        store.add(type, name, {
            fn: fn,
            key: key
        });
    }

    return {
        key: key,
        run: fn,
        name: name,
        type: type,
        attach: attach
    };
}

exports.register = addHook.bind(this, NORMAL);

exports.before = addHook.bind(this, BEFORE);

exports.after = addHook.bind(this, AFTER);

function runHook(hooks, args) {
    var current = Promise.resolve();
    if (!hooks) {
        hooks = [];
    }
    var results = {};
    return Promise.all(hooks.map(function(hook){
        var fn = hook.fn;
        current = current.then(function() {
            return fn.apply(this, args);
        });
        return current.then(function(result) {
            if (hook.key) {
                results[hook.key] = result;
            }
            return result;
        });
    })).then(function() {
        return results;
    });
}

function runHookParallel(hooks, args) {
    if (!hooks) {
        hooks = [];
    }
    return Promise.all(hooks.map(function(hook){
        var fn = hook.fn;
        return fn.apply(this, args);
    })).then(function(results) {
        var props = {};
        results.forEach(function(result, index) {
            var key = hooks[index].key;
            if (key) {
                props[key] = result;
            }
        });
        return props;
    });
}

exports.run = function(name) {
    var result = {};
    var args = Array.prototype.slice.call(arguments);

    // remove first argument
    args.shift();

    return runHook(store.get(BEFORE, name), args).then(function(beforeResult) {
        result = extend(result, beforeResult);
        return runHook(store.get(NORMAL, name), args);
    }).then(function(normalResult) {
        result = extend(result, normalResult);
        return runHook(store.get(AFTER, name), args);
    }).then(function(afterResult) {
        result = extend(result, afterResult);
        return result;
    });
};

exports.parallel = function(name) {
    var result = {};
    var args = Array.prototype.slice.call(arguments);

    // remove first argument
    args.shift();

    return runHookParallel(store.get(BEFORE, name), args).then(function(beforeResult) {
        result = extend(result, beforeResult);
        return runHookParallel(store.get(NORMAL, name), args);
    }).then(function(normalResult) {
        result = extend(result, normalResult);
        return runHookParallel(store.get(AFTER, name), args);
    }).then(function(afterResult) {
        result = extend(result, afterResult);
        return result;
    });
};

exports.clear = exports.___clearHooks = function(name) {
    store.clear(name);
};
<|endoftext|>


<commit_before>var request = require('request');
var crypto = require('crypto');
var qs = require('qs');
var merge = require('merge');

var UNEXPECTED_RESPONSE = 'Unexpected response format.  You might be using the wrong version of the API, or Buttercoin might be MESSING up.';

var environments = {
  production: { host: "api.buttercoin.com" },
  sandbox: { host: "sandbox.buttercoin.com" },
  staging: { host: "sandbox.buttercoin.com" }
};

module.exports = function (api_key, api_secret, mode, version) {
  if (!api_key || api_key.length !== 32)
    throw new Error('API Key parameter must be specified and be of length 32 characters');

  if (!api_secret || api_secret.length !== 32)
    throw new Error('API Secret parameter must be specified and be of length 32 characters');

  var api_url;
  var headers;

  if (environments[mode]) { mode = environments[mode]; }
  if (mode !== null && typeof(mode) === 'object' && mode.host) {
    var protocol = mode.protocol || "https";
    var port = "";
    if(mode.port) { port = ":" + mode.port; }
    api_url = protocol + "://" + mode.host + port;
    headers = mode.headers || {};
  } else {
    throw ("Invalid mode: " + mode);
  }

  return new Buttercoin(api_key, api_secret, api_url, headers, version);
};

function Buttercoin (api_key, api_secret, api_url, headers, version) {
  this.apiKey = api_key;
  this.apiSecret = api_secret;
  this.version = version || "v1"; // default to latest API version as of this Client release
  this.headers = headers || {};
  this.apiUrl = api_url;
}

Buttercoin.prototype.buildUrl = function (endpoint) {
  return this.apiUrl + "/" + this.version + "/" + endpoint;
};

Buttercoin.prototype.signUrl = function (urlString, timestamp) {
  urlString = new Buffer(timestamp + urlString, 'UTF-8').toString('base64');
  var signedHash = crypto.createHmac('sha256', this.apiSecret).update(urlString).digest('base64');
  return signedHash;
};

Buttercoin.prototype.getHeaders = function (signature, timestamp) {
  var headers = merge(true, this.headers);
  if (signature) {
    headers['X-Buttercoin-Access-Key'] = this.apiKey;
    headers['X-Buttercoin-Signature'] = signature;
    headers['X-Buttercoin-Date'] = timestamp;
  }

  return headers;
};

Buttercoin.prototype.buildRequest = function (method, endpoint, timestamp, body) {
  if (typeof timestamp === 'undefined') { timestamp = new Date().getTime(); }
  if (typeof body === 'undefined') { body = {}; }
  var url = this.buildUrl(endpoint);
  var options = {
    url: url,
    strictSSL: true
  };
  var signature;
  if (method === 'GET') {
    var paramString = (Object.getOwnPropertyNames(body).length === 0) ? '' : "?" + qs.stringify(body);
    signature = this.signUrl(url + paramString, timestamp);
    options.qs = body;
    options.json = true;
  } else if (method === 'POST') {
    signature = this.signUrl(url + JSON.stringify(body), timestamp);
    options.json = body;
  } else {
    signature = this.signUrl(url, timestamp);
    options.json = true;
  }
  options.method = method;
  options.headers = this.getHeaders(signature, timestamp);

  return options;
};

Buttercoin.prototype.getKey = function (timestamp, callback) {
  if (arguments.length === 1) {
    callback = timestamp;
    timestamp = undefined;
  }

  var endpoint = 'key';
  var options = this.buildRequest('GET', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        if (body.permissions)
          callback(null, body.permissions);
        else
        callback({ errors: [{ message: UNEXPECTED_RESPONSE }]});
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getBalances = function (timestamp, callback) {
  if (arguments.length === 1) {
    callback = timestamp;
    timestamp = undefined;
  }

  var endpoint = 'account/balances';
  var options = this.buildRequest('GET', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getDepositAddress = function (timestamp, callback) {
  if (arguments.length === 1) {
    callback = timestamp;
    timestamp = undefined;
  }

  var endpoint = 'account/depositAddress';
  var options = this.buildRequest('GET', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        if (body.address)
          callback(null, body.address);
        else
					callback({ errors: [{ message: UNEXPECTED_RESPONSE }]});
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getOrders = function (queryParams, timestamp, callback) {
  this.getRecords('orders', queryParams, timestamp, callback);
};

Buttercoin.prototype.getOrderById = function (orderId, timestamp, callback) {
  var endpoint = 'orders/' + orderId;
  this.getRecordById(endpoint, timestamp, callback);
};

Buttercoin.prototype.getOrder = Buttercoin.prototype.getOrderById;

Buttercoin.prototype.getOrderByUrl = function (url, timestamp, callback) {
  var orderId = url.substring(url.lastIndexOf('/')+1);
  return this.getOrderById(orderId, timestamp, callback);
};

Buttercoin.prototype.cancelOrder = function (orderId, timestamp, callback) {
  var endpoint = 'orders/' + orderId;
  this.cancelRecord(endpoint, timestamp, callback);
};

Buttercoin.prototype.createOrder = function (params, timestamp, callback) {
  var endpoint = 'orders';
  this.createRecord(endpoint, params, timestamp, callback);
};

Buttercoin.prototype.getTransactions = function (queryParams, timestamp, callback) {
  this.getRecords('transactions', queryParams, timestamp, callback);
};

Buttercoin.prototype.getTransactionById = function (trxnId, timestamp, callback) {
  var endpoint = 'transactions/' + trxnId;
  this.getRecordById(endpoint, timestamp, callback);
};

Buttercoin.prototype.getTransaction = Buttercoin.prototype.getTransactionById;

Buttercoin.prototype.getTransactionByUrl = function (url, timestamp, callback) {
  var trxnId = url.substring(url.lastIndexOf('/')+1);
  return this.getTransactionById(trxnId, timestamp, callback);
};

Buttercoin.prototype.cancelTransaction = function (trxnId, timestamp, callback) {
  var endpoint = 'transactions/' + trxnId;
  this.cancelRecord(endpoint, timestamp, callback);
};

Buttercoin.prototype.createDeposit = function (params, timestamp, callback) {
  var endpoint = 'transactions/deposit';
  this.createRecord(endpoint, params, timestamp, callback);
};

Buttercoin.prototype.createWithdrawal = function (params, timestamp, callback) {
  var endpoint = 'transactions/withdrawal';
  this.createRecord(endpoint, params, timestamp, callback);
};

Buttercoin.prototype.send = function (params, timestamp, callback) {
  var endpoint = 'transactions/send';
  this.createRecord(endpoint, params, timestamp, callback);
};

Buttercoin.prototype.sendBitcoin = Buttercoin.prototype.send;

Buttercoin.prototype.getOrderbook = function (callback) {
  var url = this.buildUrl('orderbook');
  this.getUnauthenticated(url, callback);
};

Buttercoin.prototype.getTicker = function (callback) {
  var url = this.buildUrl('ticker');
  this.getUnauthenticated(url, callback);
};

Buttercoin.prototype.getTradeHistory = function (callback) {
  var url = this.buildUrl('trades');
  this.getUnauthenticated(url, callback);
};

Buttercoin.prototype.getUnauthenticated = function (url, callback) {
  request.get({
    url: url,
    json: true,
    strictSSL: true
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getRecords = function (endpoint, queryParams, timestamp, callback) {
  // queryParams and timestamp are optional fields, so handle dynamic method parameters
  if (typeof callback === 'undefined') {
    if (typeof timestamp === 'undefined') {
      callback = queryParams;
      timestamp = undefined;
      queryParams = undefined;
    } else {
      callback = timestamp;
      if (+queryParams && isFinite(queryParams) && !(queryParams % 1)) {
        timestamp = queryParams;
        queryParams = undefined;
      } else {
        timestamp = undefined;
      }
    }
  }

  var options = this.buildRequest('GET', endpoint, timestamp, queryParams);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        if (body.results)
          callback(null, body.results);
        else
          callback({ errors: [{ message: UNEXPECTED_RESPONSE }]});
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getRecordById = function(endpoint, timestamp, callback) {
  if (typeof callback === 'undefined') {
    callback = timestamp;
    timestamp = undefined;
  }

  var options = this.buildRequest('get', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.createRecord = function(endpoint, body, timestamp, callback) {
  if (typeof callback === 'undefined') {
    callback = timestamp;
    timestamp = undefined;
  }

  var options = this.buildRequest('POST', endpoint, timestamp, body);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 201) {
        callback(null, { status: 201, message: 'This operation requires email confirmation' });
      } else if (res.statusCode === 202) {
        callback(null, { status: 202, url: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.cancelRecord = function(endpoint, timestamp, callback) {
  if (typeof callback === 'undefined') {
    callback = timestamp;
    timestamp = undefined;
  }

  var options = this.buildRequest('DELETE', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 204) {
        callback(null, { status: 204, message: 'This operation has completed successfully' });
      } else {
        callback(body);
      }
    }
  });
};
<commit_msg>Add custom headers to unauthenticated requests<commit_after>var request = require('request');
var crypto = require('crypto');
var qs = require('qs');
var merge = require('merge');

var UNEXPECTED_RESPONSE = 'Unexpected response format.  You might be using the wrong version of the API, or Buttercoin might be MESSING up.';

var environments = {
  production: { host: "api.buttercoin.com" },
  sandbox: { host: "sandbox.buttercoin.com" },
  staging: { host: "sandbox.buttercoin.com" }
};

module.exports = function (api_key, api_secret, mode, version) {
  if (!api_key || api_key.length !== 32)
    throw new Error('API Key parameter must be specified and be of length 32 characters');

  if (!api_secret || api_secret.length !== 32)
    throw new Error('API Secret parameter must be specified and be of length 32 characters');

  var api_url;
  var headers;

  if (environments[mode]) { mode = environments[mode]; }
  if (mode !== null && typeof(mode) === 'object' && mode.host) {
    var protocol = mode.protocol || "https";
    var port = "";
    if(mode.port) { port = ":" + mode.port; }
    api_url = protocol + "://" + mode.host + port;
    headers = mode.headers || {};
  } else {
    throw ("Invalid mode: " + mode);
  }

  return new Buttercoin(api_key, api_secret, api_url, headers, version);
};

function Buttercoin (api_key, api_secret, api_url, headers, version) {
  this.apiKey = api_key;
  this.apiSecret = api_secret;
  this.version = version || "v1"; // default to latest API version as of this Client release
  this.headers = headers || {};
  this.apiUrl = api_url;
}

Buttercoin.prototype.buildUrl = function (endpoint) {
  return this.apiUrl + "/" + this.version + "/" + endpoint;
};

Buttercoin.prototype.signUrl = function (urlString, timestamp) {
  urlString = new Buffer(timestamp + urlString, 'UTF-8').toString('base64');
  var signedHash = crypto.createHmac('sha256', this.apiSecret).update(urlString).digest('base64');
  return signedHash;
};

Buttercoin.prototype.getHeaders = function (signature, timestamp) {
  var headers = merge(true, this.headers);
  if (signature) {
    headers['X-Buttercoin-Access-Key'] = this.apiKey;
    headers['X-Buttercoin-Signature'] = signature;
    headers['X-Buttercoin-Date'] = timestamp;
  }

  return headers;
};

Buttercoin.prototype.buildRequest = function (method, endpoint, timestamp, body) {
  if (typeof timestamp === 'undefined') { timestamp = new Date().getTime(); }
  if (typeof body === 'undefined') { body = {}; }
  var url = this.buildUrl(endpoint);
  var options = {
    url: url,
    strictSSL: true
  };
  var signature;
  if (method === 'GET') {
    var paramString = (Object.getOwnPropertyNames(body).length === 0) ? '' : "?" + qs.stringify(body);
    signature = this.signUrl(url + paramString, timestamp);
    options.qs = body;
    options.json = true;
  } else if (method === 'POST') {
    signature = this.signUrl(url + JSON.stringify(body), timestamp);
    options.json = body;
  } else {
    signature = this.signUrl(url, timestamp);
    options.json = true;
  }
  options.method = method;
  options.headers = this.getHeaders(signature, timestamp);

  return options;
};

Buttercoin.prototype.getKey = function (timestamp, callback) {
  if (arguments.length === 1) {
    callback = timestamp;
    timestamp = undefined;
  }

  var endpoint = 'key';
  var options = this.buildRequest('GET', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        if (body.permissions)
          callback(null, body.permissions);
        else
        callback({ errors: [{ message: UNEXPECTED_RESPONSE }]});
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getBalances = function (timestamp, callback) {
  if (arguments.length === 1) {
    callback = timestamp;
    timestamp = undefined;
  }

  var endpoint = 'account/balances';
  var options = this.buildRequest('GET', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getDepositAddress = function (timestamp, callback) {
  if (arguments.length === 1) {
    callback = timestamp;
    timestamp = undefined;
  }

  var endpoint = 'account/depositAddress';
  var options = this.buildRequest('GET', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        if (body.address)
          callback(null, body.address);
        else
					callback({ errors: [{ message: UNEXPECTED_RESPONSE }]});
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getOrders = function (queryParams, timestamp, callback) {
  this.getRecords('orders', queryParams, timestamp, callback);
};

Buttercoin.prototype.getOrderById = function (orderId, timestamp, callback) {
  var endpoint = 'orders/' + orderId;
  this.getRecordById(endpoint, timestamp, callback);
};

Buttercoin.prototype.getOrder = Buttercoin.prototype.getOrderById;

Buttercoin.prototype.getOrderByUrl = function (url, timestamp, callback) {
  var orderId = url.substring(url.lastIndexOf('/')+1);
  return this.getOrderById(orderId, timestamp, callback);
};

Buttercoin.prototype.cancelOrder = function (orderId, timestamp, callback) {
  var endpoint = 'orders/' + orderId;
  this.cancelRecord(endpoint, timestamp, callback);
};

Buttercoin.prototype.createOrder = function (params, timestamp, callback) {
  var endpoint = 'orders';
  this.createRecord(endpoint, params, timestamp, callback);
};

Buttercoin.prototype.getTransactions = function (queryParams, timestamp, callback) {
  this.getRecords('transactions', queryParams, timestamp, callback);
};

Buttercoin.prototype.getTransactionById = function (trxnId, timestamp, callback) {
  var endpoint = 'transactions/' + trxnId;
  this.getRecordById(endpoint, timestamp, callback);
};

Buttercoin.prototype.getTransaction = Buttercoin.prototype.getTransactionById;

Buttercoin.prototype.getTransactionByUrl = function (url, timestamp, callback) {
  var trxnId = url.substring(url.lastIndexOf('/')+1);
  return this.getTransactionById(trxnId, timestamp, callback);
};

Buttercoin.prototype.cancelTransaction = function (trxnId, timestamp, callback) {
  var endpoint = 'transactions/' + trxnId;
  this.cancelRecord(endpoint, timestamp, callback);
};

Buttercoin.prototype.createDeposit = function (params, timestamp, callback) {
  var endpoint = 'transactions/deposit';
  this.createRecord(endpoint, params, timestamp, callback);
};

Buttercoin.prototype.createWithdrawal = function (params, timestamp, callback) {
  var endpoint = 'transactions/withdrawal';
  this.createRecord(endpoint, params, timestamp, callback);
};

Buttercoin.prototype.send = function (params, timestamp, callback) {
  var endpoint = 'transactions/send';
  this.createRecord(endpoint, params, timestamp, callback);
};

Buttercoin.prototype.sendBitcoin = Buttercoin.prototype.send;

Buttercoin.prototype.getOrderbook = function (callback) {
  var url = this.buildUrl('orderbook');
  this.getUnauthenticated(url, callback);
};

Buttercoin.prototype.getTicker = function (callback) {
  var url = this.buildUrl('ticker');
  this.getUnauthenticated(url, callback);
};

Buttercoin.prototype.getTradeHistory = function (callback) {
  var url = this.buildUrl('trades');
  this.getUnauthenticated(url, callback);
};

Buttercoin.prototype.getUnauthenticated = function (url, callback) {
  request.get({
    url: url,
    json: true,
    strictSSL: true,
    headers: this.headers
  }, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getRecords = function (endpoint, queryParams, timestamp, callback) {
  // queryParams and timestamp are optional fields, so handle dynamic method parameters
  if (typeof callback === 'undefined') {
    if (typeof timestamp === 'undefined') {
      callback = queryParams;
      timestamp = undefined;
      queryParams = undefined;
    } else {
      callback = timestamp;
      if (+queryParams && isFinite(queryParams) && !(queryParams % 1)) {
        timestamp = queryParams;
        queryParams = undefined;
      } else {
        timestamp = undefined;
      }
    }
  }

  var options = this.buildRequest('GET', endpoint, timestamp, queryParams);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        if (body.results)
          callback(null, body.results);
        else
          callback({ errors: [{ message: UNEXPECTED_RESPONSE }]});
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.getRecordById = function(endpoint, timestamp, callback) {
  if (typeof callback === 'undefined') {
    callback = timestamp;
    timestamp = undefined;
  }

  var options = this.buildRequest('get', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 200) {
        callback(null, body);
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.createRecord = function(endpoint, body, timestamp, callback) {
  if (typeof callback === 'undefined') {
    callback = timestamp;
    timestamp = undefined;
  }

  var options = this.buildRequest('POST', endpoint, timestamp, body);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 201) {
        callback(null, { status: 201, message: 'This operation requires email confirmation' });
      } else if (res.statusCode === 202) {
        callback(null, { status: 202, url: res.headers.location });
      } else {
        callback(body);
      }
    }
  });
};

Buttercoin.prototype.cancelRecord = function(endpoint, timestamp, callback) {
  if (typeof callback === 'undefined') {
    callback = timestamp;
    timestamp = undefined;
  }

  var options = this.buildRequest('DELETE', endpoint, timestamp);

  request(options, function (err, res, body) {
    if (err) {
      callback(err);
    } else {
      if (res.statusCode === 204) {
        callback(null, { status: 204, message: 'This operation has completed successfully' });
      } else {
        callback(body);
      }
    }
  });
};
<|endoftext|>


<commit_before>'use strict';

var through = require('through2');
var { PluginError } = require('gulp-util');
var flexSvg = require('flex-svg');

const PLUGIN_NAME = 'gulp-flex-svg';

module.exports = () => {
  // Create and return a stream through which each file will pass
  return through.obj(function(file, enc, cb) {
    if (file.isNull()) {
      this.push(file); // Do nothing if no contents
      return cb();
    }

    if (file.isBuffer()) {
      flexSvg(file.contents, (err, result) => {
        file.contents = new Buffer(result);
        this.push(file);
        return cb();
      });
    }

    if (file.isStream()) {
      return cb(new PluginError(PLUGIN_NAME, 'Streaming not supported'));
    }
  });
};
<commit_msg>remove comment / fix coding style<commit_after>'use strict';

var through = require('through2');
var {PluginError} = require('gulp-util');
var flexSvg = require('flex-svg');

module.exports = () => {
  // Create and return a stream through which each file will pass
  return through.obj(function(file, enc, cb) {
    if (file.isNull()) {
      this.push(file);
      return cb();
    }

    if (file.isBuffer()) {
      flexSvg(file.contents, (err, result) => {
        file.contents = new Buffer(result);
        this.push(file);
        return cb();
      });
    }

    if (file.isStream()) {
      return cb(new PluginError('gulp-flex-svg', 'Streaming not supported'));
    }
  });
};
<|endoftext|>


<commit_before>
var fs = require("fs")
,   pth = require("path")
,   nopt = require("nopt")
,   cwd = process.cwd()
,   jn = pth.join
,   dn = __dirname
,   res = jn(dn, "res")
,   rfs = function (path) { return fs.readFileSync(path, "utf8"); }
,   wfs = function (path, content) { fs.writeFileSync(path, content, { encoding: "utf8" }); }
,   rjson = function (path) { return JSON.parse(rfs(path)); }
,   wjson = function (path, obj) { wfs(path, JSON.stringify(obj, null, 2)); }
,   tmpl = rfs(jn(res, "template.html"))
,   knownOpts = {
                    "input" :   String
                ,   "output" :  String
                ,   "force":    Boolean
                ,   "help":     Boolean
                }
,   shortHands = {
                    "i":    ["--input"]
                ,   "o":    ["--output"]
                ,   "f":    ["--force"]
                ,   "h":    ["--help"]
                }
,   parsed = nopt(knownOpts, shortHands)
,   options = {
        input:  parsed.input || cwd
    ,   output: parsed.output || cwd
    ,   force:  parsed.force || false
    ,   help:   parsed.help || false
    }
,   err = function (str) {
        console.error("[ERROR] " + str);
        process.exit(1);
    }
,   reports = []
,   consolidated = {}
,   out = {
        ua: []
    ,   results: {}
    }
;

if (options.help) {
    console.log("XXX USAGE");
    process.exit(0);
}

if (!fs.existsSync(options.input)) err("No input directory: " + options.input);
if (!fs.existsSync(options.output)) err("No output directory: " + options.output);

fs.readdirSync(options.input)
    .forEach(function (f) {
        if (!/^\w\w\d\d\.json$/.test(f)) return;
        reports.push(f);
        consolidated[f.replace(/\.json$/, "")] = JSON.parse(rfs(jn(options.input, f)));
    })
;

if (!reports.length) err("No JSON reports matching \\w\\w\\d\\d.json in input directory: " + options.input);

// consolidation
for (var ua in consolidated) {
    out.ua.push(ua);
    for (var i = 0, n = consolidated[ua].results.length; i < n; i++) {
        var testData = consolidated[ua].results[i]
        ,   id = testData.test
        ;
        if (!out.results[id]) {
            out.results[id] = {
                byUA:       {}
            ,   totals:     {}
            ,   subtests:   {}
            };
        }
        out.results[id].byUA[ua] = testData.status;
        if (!out.results[id].totals[testData.status]) out.results[id].totals[testData.status] = 1;
        else out.results[id].totals[testData.status]++;
        for (var j = 0, m = testData.subtests.length; j < m; j++) {
            var st = testData.subtests[j];
            if (!out.results[id].subtests[st.name]) out.results[id].subtests[st.name] = { byUA: {}, totals: {} };
            out.results[id].subtests[st.name].byUA[ua] = st.status;
            if (!out.results[id].subtests[st.name].totals[st.status]) out.results[id].subtests[st.name].totals[st.status] = 1;
            else out.results[id].subtests[st.name].totals[st.status]++;
        }
    }
}
wjson(jn(dn, "consolidated.json"), out);

// support filters.json?
// generate both all, less-than-2, none, filtered reports

<commit_msg>usage<commit_after>
var fs = require("fs")
,   pth = require("path")
,   nopt = require("nopt")
,   cwd = process.cwd()
,   jn = pth.join
,   dn = __dirname
,   res = jn(dn, "res")
,   rfs = function (path) { return fs.readFileSync(path, "utf8"); }
,   wfs = function (path, content) { fs.writeFileSync(path, content, { encoding: "utf8" }); }
,   rjson = function (path) { return JSON.parse(rfs(path)); }
,   wjson = function (path, obj) { wfs(path, JSON.stringify(obj, null, 2)); }
,   tmpl = rfs(jn(res, "template.html"))
,   knownOpts = {
                    "input" :   String
                ,   "output" :  String
                ,   "help":     Boolean
                }
,   shortHands = {
                    "i":    ["--input"]
                ,   "o":    ["--output"]
                ,   "h":    ["--help"]
                }
,   parsed = nopt(knownOpts, shortHands)
,   options = {
        input:  parsed.input || cwd
    ,   output: parsed.output || cwd
    ,   help:   parsed.help || false
    }
,   err = function (str) {
        console.error("[ERROR] " + str);
        process.exit(1);
    }
,   reports = []
,   consolidated = {}
,   out = {
        ua: []
    ,   results: {}
    }
;

if (options.help) {
    console.log([
        "wptreport [--input /path/to/dir] [--output /path/to/dir]"
    ,   "   Generate nice-looking reports of various types based on test run reports coming"
    ,   "   out of Web Platform Tests."
    ,   ""
    ,   "   --input, -i  <directory> that contains all the JSON. JSON files must match the pattern"
    ,   "                \\w{2}\\d{d}\\.json. Defaults to the current directory."
    ,   "   --output, -o <directory> where the generated reports are stored. Defaults to the current"
    ,   "                directory."
    ,   "   --help       Produces this message."
    ].join("\n"));
    process.exit(0);
}

if (!fs.existsSync(options.input)) err("No input directory: " + options.input);
if (!fs.existsSync(options.output)) err("No output directory: " + options.output);

fs.readdirSync(options.input)
    .forEach(function (f) {
        if (!/^\w\w\d\d\.json$/.test(f)) return;
        reports.push(f);
        consolidated[f.replace(/\.json$/, "")] = JSON.parse(rfs(jn(options.input, f)));
    })
;

if (!reports.length) err("No JSON reports matching \\w\\w\\d\\d.json in input directory: " + options.input);

// consolidation
for (var ua in consolidated) {
    out.ua.push(ua);
    for (var i = 0, n = consolidated[ua].results.length; i < n; i++) {
        var testData = consolidated[ua].results[i]
        ,   id = testData.test
        ;
        if (!out.results[id]) {
            out.results[id] = {
                byUA:       {}
            ,   totals:     {}
            ,   subtests:   {}
            };
        }
        out.results[id].byUA[ua] = testData.status;
        if (!out.results[id].totals[testData.status]) out.results[id].totals[testData.status] = 1;
        else out.results[id].totals[testData.status]++;
        for (var j = 0, m = testData.subtests.length; j < m; j++) {
            var st = testData.subtests[j];
            if (!out.results[id].subtests[st.name]) out.results[id].subtests[st.name] = { byUA: {}, totals: {} };
            out.results[id].subtests[st.name].byUA[ua] = st.status;
            if (!out.results[id].subtests[st.name].totals[st.status]) out.results[id].subtests[st.name].totals[st.status] = 1;
            else out.results[id].subtests[st.name].totals[st.status]++;
        }
    }
}
wjson(jn(dn, "consolidated.json"), out);

// support filters.json?
// generate both all, less-than-2, none, filtered reports

<|endoftext|>