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

  'rules': {
    'block-scoped-var': 0,
    'brace-style': [2, '1tbs', { 'allowSingleLine': false }],
    'camelcase': [2, { 'properties': 'never' }],
    'comma-dangle': 0,
    'comma-spacing': [2, { 'before': false, 'after': true }],
    'comma-style': [2, 'last'],
    'complexity': [1, 10],
    'computed-property-spacing': [2, 'never'],
    'consistent-return': 0,
    'curly': 2,
    'dot-notation': 2,
    'eqeqeq': 2,
    'guard-for-in': 2,
    'indent': [2, 2, { 'SwitchCase': 1 }],
    'key-spacing': 0,
    'max-len': [1, 80, 2],
    'max-nested-callbacks': [2, 3],
    'max-params': [1, 4],
    'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }],
    'new-parens': 2,
    'no-alert': 2,
    'no-array-constructor': 2,
    'no-bitwise': 2,
    'no-caller': 2,
    'no-catch-shadow': 0, // Off because we don't support IE8 and older
    'no-cond-assign': 2,
    'no-console': 2,
    'no-constant-condition': 2,
    'no-control-regex': 2,
    'no-debugger': 2,
    'no-delete-var': 2,
    'no-dupe-args': 2,
    'no-dupe-keys': 2,
    'no-duplicate-case': 0,
    'no-empty': 2,
    'no-empty-character-class': 2,
    'no-empty-label': 2,
    'no-eq-null': 2,
    'no-eval': 2,
    'no-ex-assign': 2,
    'no-extend-native': 2,
    'no-extra-bind': 2,
    'no-extra-boolean-cast': 2,
    'no-extra-parens': [2, 'functions'],
    'no-extra-semi': 2,
    'no-fallthrough': 2,
    'no-floating-decimal': 2,
    'no-func-assign': 2,
    'no-implied-eval': 2,
    'no-inner-declarations': 2,
    'no-invalid-regexp': 2,
    'no-irregular-whitespace': 2,
    'no-iterator': 2,
    'no-label-var': 2,
    'no-labels': 2,
    'no-lone-blocks': 2,
    'no-lonely-if': 2,
    'no-loop-func': 2,
    'no-mixed-spaces-and-tabs': 2,
    'no-multi-spaces': 0,
    'no-multi-str': 2,
    'no-multiple-empty-lines': 2,
    'no-native-reassign': 2,
    'no-negated-in-lhs': 2,
    'no-nested-ternary': 2,
    'no-new': 2,
    'no-new-func': 2,
    'no-new-object': 2,
    'no-new-wrappers': 2,
    'no-obj-calls': 2,
    'no-octal': 2,
    'no-octal-escape': 2,
    'no-process-exit': 2,
    'no-proto': 2,
    'no-redeclare': 2,
    'no-regex-spaces': 2,
    'no-return-assign': 2,
    'no-script-url': 2,
    'no-self-compare': 2,
    'no-sequences': 2,
    'no-shadow': 2,
    'no-shadow-restricted-names': 2,
    'no-spaced-func': 2,
    'no-sparse-arrays': 2,
    'no-throw-literal': 2,
    'no-trailing-spaces': 2,
    'no-undef': 2,
    'no-undef-init': 2,
    'no-underscore-dangle': 0,
    'no-unreachable': 2,
    'no-unused-expressions': 2,
    'no-unused-vars': 2,
    'no-use-before-define': 2,
    '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,
    'semi': [2, 'always'],
    'semi-spacing': [2, { 'before': false, 'after': true }],
    'space-after-keywords': [2, 'always'],
    'space-before-blocks': [2, 'always'],
    'space-before-function-paren': [2, 'never'],
    'space-in-parens': [2, 'never'],
    'space-infix-ops': 2,
    'space-return-throw-case': 2,
    'space-unary-ops': 2,
    'spaced-comment': [2, 'always'],
    'strict': [2, 'never'],
    'use-isnan': 2,
    'valid-typeof': 2,
    'valid-jsdoc': [2, {
      'prefer': { 'returns': 'return' },
      'requireParamDescription': false,
      'requireReturn': false,
      'requireReturnDescription': false,
    }],
    'valid-typeof': 2,
    'wrap-iife': [2, 'outside'],
    'yoda': 2,
  }
};
<commit_msg>Remove duplicate 'valid-typeof' rule<commit_after>module.exports = {
  'env': {
    'browser': true,
    'es6': true,
    'node': true
  },

  'rules': {
    'block-scoped-var': 0,
    'brace-style': [2, '1tbs', { 'allowSingleLine': false }],
    'camelcase': [2, { 'properties': 'never' }],
    'comma-dangle': 0,
    'comma-spacing': [2, { 'before': false, 'after': true }],
    'comma-style': [2, 'last'],
    'complexity': [1, 10],
    'computed-property-spacing': [2, 'never'],
    'consistent-return': 0,
    'curly': 2,
    'dot-notation': 2,
    'eqeqeq': 2,
    'guard-for-in': 2,
    'indent': [2, 2, { 'SwitchCase': 1 }],
    'key-spacing': 0,
    'max-len': [1, 80, 2],
    'max-nested-callbacks': [2, 3],
    'max-params': [1, 4],
    'new-cap': [2, { 'newIsCap': true, 'capIsNew': false }],
    'new-parens': 2,
    'no-alert': 2,
    'no-array-constructor': 2,
    'no-bitwise': 2,
    'no-caller': 2,
    'no-catch-shadow': 0, // Off because we don't support IE8 and older
    'no-cond-assign': 2,
    'no-console': 2,
    'no-constant-condition': 2,
    'no-control-regex': 2,
    'no-debugger': 2,
    'no-delete-var': 2,
    'no-dupe-args': 2,
    'no-dupe-keys': 2,
    'no-duplicate-case': 0,
    'no-empty': 2,
    'no-empty-character-class': 2,
    'no-empty-label': 2,
    'no-eq-null': 2,
    'no-eval': 2,
    'no-ex-assign': 2,
    'no-extend-native': 2,
    'no-extra-bind': 2,
    'no-extra-boolean-cast': 2,
    'no-extra-parens': [2, 'functions'],
    'no-extra-semi': 2,
    'no-fallthrough': 2,
    'no-floating-decimal': 2,
    'no-func-assign': 2,
    'no-implied-eval': 2,
    'no-inner-declarations': 2,
    'no-invalid-regexp': 2,
    'no-irregular-whitespace': 2,
    'no-iterator': 2,
    'no-label-var': 2,
    'no-labels': 2,
    'no-lone-blocks': 2,
    'no-lonely-if': 2,
    'no-loop-func': 2,
    'no-mixed-spaces-and-tabs': 2,
    'no-multi-spaces': 0,
    'no-multi-str': 2,
    'no-multiple-empty-lines': 2,
    'no-native-reassign': 2,
    'no-negated-in-lhs': 2,
    'no-nested-ternary': 2,
    'no-new': 2,
    'no-new-func': 2,
    'no-new-object': 2,
    'no-new-wrappers': 2,
    'no-obj-calls': 2,
    'no-octal': 2,
    'no-octal-escape': 2,
    'no-process-exit': 2,
    'no-proto': 2,
    'no-redeclare': 2,
    'no-regex-spaces': 2,
    'no-return-assign': 2,
    'no-script-url': 2,
    'no-self-compare': 2,
    'no-sequences': 2,
    'no-shadow': 2,
    'no-shadow-restricted-names': 2,
    'no-spaced-func': 2,
    'no-sparse-arrays': 2,
    'no-throw-literal': 2,
    'no-trailing-spaces': 2,
    'no-undef': 2,
    'no-undef-init': 2,
    'no-underscore-dangle': 0,
    'no-unreachable': 2,
    'no-unused-expressions': 2,
    'no-unused-vars': 2,
    'no-use-before-define': 2,
    '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,
    'semi': [2, 'always'],
    'semi-spacing': [2, { 'before': false, 'after': true }],
    'space-after-keywords': [2, 'always'],
    'space-before-blocks': [2, 'always'],
    'space-before-function-paren': [2, 'never'],
    'space-in-parens': [2, 'never'],
    'space-infix-ops': 2,
    'space-return-throw-case': 2,
    'space-unary-ops': 2,
    'spaced-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>var express = require("express");
var app = express();
var http = require("http");
var theServer = http.createServer(app); // create a server.
var theSocket = require("socket.io"); // create a socket.
var socketListener = theSocket.listen(theServer); // the socket has to listen to the server.
var port = process.env.PORT || 3000;
theServer.listen(port); // the server has to listen to a port..

app.use(express.static('public/public/sources'));
app.get("/", function(req, res) // we send them the index html file one theyre connected..
{
    // console.log(__dirname);

    // res.sendFile(__dirname+"/index.html");

});

var player1Health = 100;
var player2Health = 100;
var player1Sheild = false;
var player2Sheild = false;
var connectedPlayers = [];
var game = true;

function executeAction(spell,playerId) {
	var player = connectedPlayers.indexOf(playerId);

	switch(spell) {
		case 'sheild':
			if(player == 0) {
				player1Sheild = true;
			} else {
				player2Sheild = true;
			}
		break;
		case 'basic attack':
			if(player == 0) {
				if(!player2Sheild) {
					player2Health -= 30;
					checkHealth(player2Health,0);
				} else {
					player2Sheild = !player2Sheild;
				}
			} else {
				if(!player1Sheild) {
					player1Health -= 30;
					checkHealth(player1Health,1);
				} else {
					player1Sheild = !player1Sheild;
				}
			}
		break;
		case 'super attack':
			if(player == 0) {
				if(!player2Sheild) {
					player2Health -= 50;
					checkHealth(player2Health,0);
				} else {
					player2Sheild = !player2Sheild;
				}
			} else {
				if(!player1Sheild) {
					player1Health -= 50;
					checkHealth(player1Health,1);
				} else {
					player1Sheild = !player1Sheild;
				}
			}
		break;
		default :
		break;
	}
}

function checkHealth(health, player) {
	if(health <= 0 && game) {
		game = false;
		win(player);
	}
}

function win(who) {
	player1Health = 100;
	player2Health = 100;
	player1Sheild = false;
	player2Sheild = false;
	connectedPlayers[who].emit('win');
	connectedPlayers[who].emit('end', {all:connectedPlayers.length});
	game = true;
}

socketListener.sockets.on('connection', function(socket)
{
	connectedPlayers.push(socket);

	socket.on('action', function(data)
	{
		executeAction(data.spell,socket);
	});

	socket.on('disconnect', function() {
		var i = connectedPlayers.indexOf(socket);
		connectedPlayers.splice(i,1);
		console.log(connectedPlayers);
		//socket.broadcast('end');
	});
});<commit_msg>broadcast<commit_after>var express = require("express");
var app = express();
var http = require("http");
var theServer = http.createServer(app); // create a server.
var theSocket = require("socket.io"); // create a socket.
var socketListener = theSocket.listen(theServer); // the socket has to listen to the server.
var port = process.env.PORT || 3000;
theServer.listen(port); // the server has to listen to a port..

app.use(express.static('public/public/sources'));
app.get("/", function(req, res) // we send them the index html file one theyre connected..
{
    // console.log(__dirname);

    // res.sendFile(__dirname+"/index.html");

});

var player1Health = 100;
var player2Health = 100;
var player1Sheild = false;
var player2Sheild = false;
var connectedPlayers = [];
var game = true;

function executeAction(spell,playerId) {
	var player = connectedPlayers.indexOf(playerId);

	switch(spell) {
		case 'sheild':
			if(player == 0) {
				player1Sheild = true;
			} else {
				player2Sheild = true;
			}
		break;
		case 'basic attack':
			if(player == 0) {
				if(!player2Sheild) {
					player2Health -= 30;
					checkHealth(player2Health,0);
				} else {
					player2Sheild = !player2Sheild;
				}
			} else {
				if(!player1Sheild) {
					player1Health -= 30;
					checkHealth(player1Health,1);
				} else {
					player1Sheild = !player1Sheild;
				}
			}
		break;
		case 'super attack':
			if(player == 0) {
				if(!player2Sheild) {
					player2Health -= 50;
					checkHealth(player2Health,0);
				} else {
					player2Sheild = !player2Sheild;
				}
			} else {
				if(!player1Sheild) {
					player1Health -= 50;
					checkHealth(player1Health,1);
				} else {
					player1Sheild = !player1Sheild;
				}
			}
		break;
		default :
		break;
	}
}

function checkHealth(health, player) {
	if(health <= 0 && game) {
		game = false;
		win(player);
	}
}

function win(who) {
	player1Health = 100;
	player2Health = 100;
	player1Sheild = false;
	player2Sheild = false;
	connectedPlayers[who].emit('win');
	connectedPlayers[who].broadcast('end', {all:connectedPlayers.length});
	game = true;
}

socketListener.sockets.on('connection', function(socket)
{
	connectedPlayers.push(socket);

	socket.on('action', function(data)
	{
		executeAction(data.spell,socket);
	});

	socket.on('disconnect', function() {
		var i = connectedPlayers.indexOf(socket);
		connectedPlayers.splice(i,1);
		console.log(connectedPlayers);
		//socket.broadcast('end');
	});
});<|endoftext|>


<commit_before>#!/usr/bin/env node
var JSON5 = require('json5');
var path = require('path');
var program = require('commander');
var fs = require('fs');
var queue = require('queue-async');
var chalk = require('chalk');
var newman = require('newman');
var runCount = 1;
var failCount = 0;
var successCount = 0;

program.arguments('<file> [otherFiles...]')
.option('-e, --environment <environment>', 'The postman environment to use')
.option('-d, --data-path <dataPath>', 'The directory to search for data files')
.option('-r, --repetitions <repetitions>', 'The number of times to repeat (not the same as newman "iterations")')
.action(function(file, otherFiles) {

	var allFiles = [ file ];
	if (otherFiles)	{
		allFiles = allFiles.concat(otherFiles);
	}

    console.log('');
	console.log(chalk.magenta('Pat: the newman runner /////////'));
    console.log('');

	allFiles.forEach(function(file)	{
		console.log(chalk.yellow('Collection: %s'), file);
	})

	console.log('');
	console.log(chalk.yellow.underline('Total: ' + allFiles.length + ' file(s)'));
	console.log('');
	console.log(chalk.cyan('Environment: %s'), program.environment);
	console.log(chalk.blue('Data path: %s'), program.dataPath);
	console.log('');

	runPostmanForFiles(allFiles, program.dataPath, program.environment);
})
.parse(process.argv);

function runPostmanForFiles(allFiles, dataPath, environment) {

    // queue with a concurrency of 1 - i.e. run newman tasks sequentially
	var q = queue(1);
	var tasks = [];
	allFiles.forEach(function(file) {

		var split = path.basename(file).split('.');
		var name = split[0];

		var dataFile = path.join(dataPath, name + ".data.json");

		try	{
			if (!fs.statSync(dataFile).isFile()) {
				console.log(chalk.bold.red('Data file for %s does not exist at: %s'), name, dataFile);
				process.exit(1);
			}
			else {
				console.log('Found data for %s at: %s', name, dataFile);
			}
		}
		catch (error) {
			console.log(chalk.bold.red('Data file for %s does not exist at: %s'), name, dataFile);
		    process.exit(1);
		}

	    tasks.push({
				file: file,
				dataFile: dataFile,
				environment: environment
			}
		);
	})

    console.log('Queueing %s newman task(s)...', tasks.length);

	tasks.forEach(function(t) {
		q.defer(runPostmanExternal, t.file, t.dataFile, t.environment);
	})

	// await all the tasks
	q.awaitAll(function(error, results) {
		console.log('');
		console.log('Finished all tasks for this run...');
		if (runCount++ > program.repetitions) {
			console.log(chalk.magenta('Finished all runs.'));
			process.exit();
		}
		else {
			console.log('');
			console.log(chalk.magenta('Run #%s'), runCount);
			console.log('');
			runPostmanForFiles(allFiles, dataPath, environment);
		}
	})
}

function runPostman(file, dataFile, environment, callback) {

	// read the collectionJson file
	var collectionJson = fs.readFileSync(file, 'utf8');
	var collection = JSON5.parse(collectionJson);

	// define Newman options
	var newmanOptions = {
		envJson: JSON5.parse(fs.readFileSync(environment, "utf-8")), // environment file (in parsed json format)
		dataFile: dataFile,                    // data file if required
		iterationCount: 1,                    // define the number of times the runner should run
		stopOnError: false,
		responseHandler: "TestResponseHandler"
	}

	console.log('');
	console.log('Running %s...', collection.name);

	newman.execute(collection, newmanOptions, function() {
		callback();
	});
}

function runPostmanExternal(file, dataFile, environment, callback) {

	var collectionJson = fs.readFileSync(file, 'utf8');
	var collection = JSON5.parse(collectionJson);

	console.log('');
	console.log('Running %s tests...', collection.name);

	var cmd = 'newman'
	var args = [ '-c', file,
 				 '-e', environment,
  				 '-d', dataFile,
				 '-r', 40000, // timeout
				 '-n', '1', // iterations
				 '-j', // don't print summary
				 '-x']; // use non-zero exit code to indicate one or more tests failed.

	var spawn = require('child_process').spawn;
    var newman = spawn(cmd, args);

	newman.stdout.on('data', function (data) {
		process.stdout.write(data);
	});

	newman.stderr.on('data', function (data) {
		process.stderr.write(data);
	});

	newman.on('close', function (code) {

		if (code !== 0) {
			console.log(chalk.red(''));
			console.log(chalk.red('✗ One or more tests failed in this collection'));
			failCount++;
		}
		else {
			console.log(chalk.green(''));
			console.log(chalk.green('✔ Clean sweep!'));
			successCount++;
		}

		callback();
	});
}

<commit_msg>Change default timeout per request to 60s<commit_after>#!/usr/bin/env node
var JSON5 = require('json5');
var path = require('path');
var program = require('commander');
var fs = require('fs');
var queue = require('queue-async');
var chalk = require('chalk');
var newman = require('newman');
var runCount = 1;
var failCount = 0;
var successCount = 0;

program.arguments('<file> [otherFiles...]')
.option('-e, --environment <environment>', 'The postman environment to use')
.option('-d, --data-path <dataPath>', 'The directory to search for data files')
.option('-r, --repetitions <repetitions>', 'The number of times to repeat (not the same as newman "iterations")')
.action(function(file, otherFiles) {

	var allFiles = [ file ];
	if (otherFiles)	{
		allFiles = allFiles.concat(otherFiles);
	}

    console.log('');
	console.log(chalk.magenta('Pat: the newman runner /////////'));
    console.log('');

	allFiles.forEach(function(file)	{
		console.log(chalk.yellow('Collection: %s'), file);
	})

	console.log('');
	console.log(chalk.yellow.underline('Total: ' + allFiles.length + ' file(s)'));
	console.log('');
	console.log(chalk.cyan('Environment: %s'), program.environment);
	console.log(chalk.blue('Data path: %s'), program.dataPath);
	console.log('');

	runPostmanForFiles(allFiles, program.dataPath, program.environment);
})
.parse(process.argv);

function runPostmanForFiles(allFiles, dataPath, environment) {

    // queue with a concurrency of 1 - i.e. run newman tasks sequentially
	var q = queue(1);
	var tasks = [];
	allFiles.forEach(function(file) {

		var split = path.basename(file).split('.');
		var name = split[0];

		var dataFile = path.join(dataPath, name + ".data.json");

		try	{
			if (!fs.statSync(dataFile).isFile()) {
				console.log(chalk.bold.red('Data file for %s does not exist at: %s'), name, dataFile);
				process.exit(1);
			}
			else {
				console.log('Found data for %s at: %s', name, dataFile);
			}
		}
		catch (error) {
			console.log(chalk.bold.red('Data file for %s does not exist at: %s'), name, dataFile);
		    process.exit(1);
		}

	    tasks.push({
				file: file,
				dataFile: dataFile,
				environment: environment
			}
		);
	})

    console.log('Queueing %s newman task(s)...', tasks.length);

	tasks.forEach(function(t) {
		q.defer(runPostmanExternal, t.file, t.dataFile, t.environment);
	})

	// await all the tasks
	q.awaitAll(function(error, results) {
		console.log('');
		console.log('Finished all tasks for this run...');
		if (runCount++ > program.repetitions) {
			console.log(chalk.magenta('Finished all runs.'));
			process.exit();
		}
		else {
			console.log('');
			console.log(chalk.magenta('Run #%s'), runCount);
			console.log('');
			runPostmanForFiles(allFiles, dataPath, environment);
		}
	})
}

function runPostman(file, dataFile, environment, callback) {

	// read the collectionJson file
	var collectionJson = fs.readFileSync(file, 'utf8');
	var collection = JSON5.parse(collectionJson);

	// define Newman options
	var newmanOptions = {
		envJson: JSON5.parse(fs.readFileSync(environment, "utf-8")), // environment file (in parsed json format)
		dataFile: dataFile,                    // data file if required
		iterationCount: 1,                    // define the number of times the runner should run
		stopOnError: false,
		responseHandler: "TestResponseHandler"
	}

	console.log('');
	console.log('Running %s...', collection.name);

	newman.execute(collection, newmanOptions, function() {
		callback();
	});
}

function runPostmanExternal(file, dataFile, environment, callback) {

	var collectionJson = fs.readFileSync(file, 'utf8');
	var collection = JSON5.parse(collectionJson);

	console.log('');
	console.log('Running %s tests...', collection.name);

	var cmd = 'newman'
	var args = [ '-c', file,
 				 '-e', environment,
  				 '-d', dataFile,
				 '-r', 60000, // timeout
				 '-n', '1', // iterations
				 '-j', // don't print summary
				 '-x']; // use non-zero exit code to indicate one or more tests failed.

	var spawn = require('child_process').spawn;
    var newman = spawn(cmd, args);

	newman.stdout.on('data', function (data) {
		process.stdout.write(data);
	});

	newman.stderr.on('data', function (data) {
		process.stderr.write(data);
	});

	newman.on('close', function (code) {

		if (code !== 0) {
			console.log(chalk.red(''));
			console.log(chalk.red('✗ One or more tests failed in this collection'));
			failCount++;
		}
		else {
			console.log(chalk.green(''));
			console.log(chalk.green('✔ Clean sweep!'));
			successCount++;
		}

		callback();
	});
}

<|endoftext|>


<commit_before>'use strict';

var toString = Object.prototype.toString;

var call = 'call';

function isArguments(value) {
  return (toString[call](value) === '[object Arguments]');
}

var isArray = (Array.isArray) ?
  function isArray(value) {
    return Array.isArray(value);
  } :
  function isArray(value) {
    return (toString[call](value) === '[object Array]');
  };

function isBoolean(value) {
  return (
    typeof value === 'boolean' || toString[call](value) === '[object Boolean]'
  );
}

var isBuffer = (typeof Buffer !== 'undefined' && Buffer.isBuffer) ?
  function isBuffer(value) {
    return Buffer.isBuffer(value);
  } :
  function isBuffer() {
    return false;
  };

function isDate(value) {
  return (toString[call](value) === '[object Date]');
}

function isError(value) {
  return (toString[call](value) === '[object Error]');
}

function isFunction(value) {
  return (
    typeof value === 'function' || toString[call](value) === '[object Function]'
  );
}

var isMap = (typeof Map !== 'undefined') ?
  function isMap(value) {
    return (toString[call](value) === '[object Map]');
  } :
  function isMap() {
    return false;
  };

function isNumber(value) {
  return (
    typeof value === 'number' || toString[call](value) === '[object Number]'
  );
}

function isObjectLike(value) {
  return (value !== null && typeof value === 'object');
}

function isObject(value) {
  return (isObjectLike(value) && toString[call](value) === '[object Object]');
}

function isPromiseLike(value) {
  return (
    isObjectLike(value) && isFunction(value.then) && isFunction(value['catch'])
  );
}

function isPromise(value) {
  return (isPromiseLike(value) && toString[call](value) === '[object Promise]');
}

function isRegExp(value) {
  return (toString[call](value) === '[object RegExp]');
}

var isSet = (typeof Set !== 'undefined') ?
  function isSet() {
    return (toString[call](value) === '[object Set]');
  } :
  function isSet() {
    return false;
  };

function isString(value) {
  return (
    typeof value === 'string' || toString[call](value) === '[object String]'
  );
}

var isSymbol = (typeof Symbol !== 'undefined' && typeof Symbol() === 'symbol') ?
  function isSymbol(value) {
    return (
      // NOTE: `typeof Object(Symbol())` returns 'object', but it is Symbol.
      typeof value === 'symbol' || toString[call](value) === '[object Symbol]'
    );
  } :
  function isSymbol() {
    return false;
  };

var isWeakMap = (typeof WeakMap !== 'undefined') ?
  function isWeakMap(value) {
    return (toString[call](value) === '[object WeakMap]');
  } :
  function isWeakMap() {
    return false;
  };

var isWeakSet = (typeof WeakSet !== 'undefined') ?
  function isWeakSet(value) {
    return (toString[call](value) === '[object WeakSet]');
  } :
  function isWeakSet() {
    return false;
  };

module.exports = {
  isArguments: isArguments,
  isArray: isArray,
  isBoolean: isBoolean,
  isBuffer: isBuffer,
  isDate: isDate,
  isError: isError,
  isFunction: isFunction,
  isMap: isMap,
  isNumber: isNumber,
  isObjectLike: isObjectLike,
  isObject: isObject,
  isPromiseLike: isPromiseLike,
  isPromise: isPromise,
  isRegExp: isRegExp,
  isSet: isSet,
  isString: isString,
  isSymbol: isSymbol,
  isWeakMap: isWeakMap,
  isWeakSet: isWeakSet
};
<commit_msg>fixed isSet<commit_after>'use strict';

var toString = Object.prototype.toString;

var call = 'call';

function isArguments(value) {
  return (toString[call](value) === '[object Arguments]');
}

var isArray = (Array.isArray) ?
  function isArray(value) {
    return Array.isArray(value);
  } :
  function isArray(value) {
    return (toString[call](value) === '[object Array]');
  };

function isBoolean(value) {
  return (
    typeof value === 'boolean' || toString[call](value) === '[object Boolean]'
  );
}

var isBuffer = (typeof Buffer !== 'undefined' && Buffer.isBuffer) ?
  function isBuffer(value) {
    return Buffer.isBuffer(value);
  } :
  function isBuffer() {
    return false;
  };

function isDate(value) {
  return (toString[call](value) === '[object Date]');
}

function isError(value) {
  return (toString[call](value) === '[object Error]');
}

function isFunction(value) {
  return (
    typeof value === 'function' || toString[call](value) === '[object Function]'
  );
}

var isMap = (typeof Map !== 'undefined') ?
  function isMap(value) {
    return (toString[call](value) === '[object Map]');
  } :
  function isMap() {
    return false;
  };

function isNumber(value) {
  return (
    typeof value === 'number' || toString[call](value) === '[object Number]'
  );
}

function isObjectLike(value) {
  return (value !== null && typeof value === 'object');
}

function isObject(value) {
  return (isObjectLike(value) && toString[call](value) === '[object Object]');
}

function isPromiseLike(value) {
  return (
    isObjectLike(value) && isFunction(value.then) && isFunction(value['catch'])
  );
}

function isPromise(value) {
  return (isPromiseLike(value) && toString[call](value) === '[object Promise]');
}

function isRegExp(value) {
  return (toString[call](value) === '[object RegExp]');
}

var isSet = (typeof Set !== 'undefined') ?
  function isSet(value) {
    return (toString[call](value) === '[object Set]');
  } :
  function isSet() {
    return false;
  };

function isString(value) {
  return (
    typeof value === 'string' || toString[call](value) === '[object String]'
  );
}

var isSymbol = (typeof Symbol !== 'undefined' && typeof Symbol() === 'symbol') ?
  function isSymbol(value) {
    return (
      // NOTE: `typeof Object(Symbol())` returns 'object', but it is Symbol.
      typeof value === 'symbol' || toString[call](value) === '[object Symbol]'
    );
  } :
  function isSymbol() {
    return false;
  };

var isWeakMap = (typeof WeakMap !== 'undefined') ?
  function isWeakMap(value) {
    return (toString[call](value) === '[object WeakMap]');
  } :
  function isWeakMap() {
    return false;
  };

var isWeakSet = (typeof WeakSet !== 'undefined') ?
  function isWeakSet(value) {
    return (toString[call](value) === '[object WeakSet]');
  } :
  function isWeakSet() {
    return false;
  };

module.exports = {
  isArguments: isArguments,
  isArray: isArray,
  isBoolean: isBoolean,
  isBuffer: isBuffer,
  isDate: isDate,
  isError: isError,
  isFunction: isFunction,
  isMap: isMap,
  isNumber: isNumber,
  isObjectLike: isObjectLike,
  isObject: isObject,
  isPromiseLike: isPromiseLike,
  isPromise: isPromise,
  isRegExp: isRegExp,
  isSet: isSet,
  isString: isString,
  isSymbol: isSymbol,
  isWeakMap: isWeakMap,
  isWeakSet: isWeakSet
};
<|endoftext|>


<commit_before>"use babel";

import { CompositeDisposable } from 'atom';
import CSSBeautify from 'cssbeautify';

let subscriptions;
let beautifyOnSave;
let indentType;
let indentSize;
let openBrace;
let autoSemicolon;

function getIndent() {
  let indent = '';
  switch (indentType) {
    case 'space':
      indent = Array(indentSize + 1).join(' ');
      break;
    case 'tab':
      indent = '\t';
      break;
  }
  return indent;
}

function beautify(css) {
  try {
    return CSSBeautify(css, {
      indent: getIndent(),
      openbrace: openBrace,
      autosemicolon: autoSemicolon
    });
  } catch (e) {
    console.error(e);
  }
  return null;
}

function execute() {
  const editor = atom.workspace.getActiveTextEditor();

  if (!editor) {
    return;
  }

  let position = editor.getCursorBufferPosition();
  let text = editor.getText();
  let selectedText = editor.getSelectedText();

  if (selectedText.length !== 0) {
    let formatted = beautify(selectedText);
    if (formatted) {
      let range = editor.getSelectedBufferRange();
      editor.setTextInBufferRange(range, formatted);
      editor.setCursorBufferPosition(position);
    }
  } else {
    let formatted = beautify(text);
    if (formatted) {
      editor.setText(formatted);
      editor.setCursorBufferPosition(position);
    }
  }
}

let editorObserver = null;

export function activate(state) {
  subscriptions = new CompositeDisposable();
  subscriptions.add(atom.config.observe('cssbeautify.beautifyOnSave', value => beautifyOnSave = value));
  subscriptions.add(atom.config.observe('cssbeautify.indentType', value => indentType = value));
  subscriptions.add(atom.config.observe('cssbeautify.indentSize', value => indentSize = value));
  subscriptions.add(atom.config.observe('cssbeautify.openBrace', value => openBrace = value));
  subscriptions.add(atom.config.observe('cssbeautify.autoSemicolon', value => autoSemicolon = value));

  atom.commands.add('atom-workspace', 'cssbeautify:execute', () => {
    execute();
  });

  editorObserver = atom.workspace.observeTextEditors(editor => {
    editor.getBuffer().onWillSave(() => {
      if (beautifyOnSave) {
        execute();
      }
    });
  });
}

export function deactivate() {
  subscriptions.dispose();
  editorObserver.dispose();
}
<commit_msg>Tweaks<commit_after>"use babel";

import { CompositeDisposable } from 'atom';
import cssbeautify from 'cssbeautify';

let subscriptions;
let beautifyOnSave;
let indentType;
let indentSize;
let openBrace;
let autoSemicolon;
let editorObserver = null;

export function activate(state) {
  subscriptions = new CompositeDisposable();
  subscriptions.add(atom.config.observe('cssbeautify.beautifyOnSave', value => beautifyOnSave = value));
  subscriptions.add(atom.config.observe('cssbeautify.indentType', value => indentType = value));
  subscriptions.add(atom.config.observe('cssbeautify.indentSize', value => indentSize = value));
  subscriptions.add(atom.config.observe('cssbeautify.openBrace', value => openBrace = value));
  subscriptions.add(atom.config.observe('cssbeautify.autoSemicolon', value => autoSemicolon = value));

  atom.commands.add('atom-workspace', 'cssbeautify:execute', () => {
    execute();
  });

  editorObserver = atom.workspace.observeTextEditors(editor => {
    editor.getBuffer().onWillSave(() => {
      if (beautifyOnSave) {
        execute();
      }
    });
  });
}

export function deactivate() {
  subscriptions.dispose();
  editorObserver.dispose();
}

function getIndent() {
  let indent = '';
  switch (indentType) {
    case 'space':
      indent = Array(indentSize + 1).join(' ');
      break;
    case 'tab':
      indent = '\t';
      break;
  }
  return indent;
}

function beautify(css) {
  try {
    return cssbeautify(css, {
      indent: getIndent(),
      openbrace: openBrace,
      autosemicolon: autoSemicolon
    });
  } catch (e) {
    console.error(e);
  }
  return null;
}

function execute() {
  const editor = atom.workspace.getActiveTextEditor();

  if (!editor) {
    return;
  }

  let position = editor.getCursorBufferPosition();
  let text = editor.getText();
  let selectedText = editor.getSelectedText();

  if (selectedText.length !== 0) {
    let formatted = beautify(selectedText);
    if (formatted) {
      let range = editor.getSelectedBufferRange();
      editor.setTextInBufferRange(range, formatted);
      editor.setCursorBufferPosition(position);
    }
  } else {
    let formatted = beautify(text);
    if (formatted) {
      editor.setText(formatted);
      editor.setCursorBufferPosition(position);
    }
  }
}
<|endoftext|>


<commit_before>
var net = require('net');
var slice = Array.prototype.slice;

var Client = {
	DEFAULT_ADDR : '127.0.0.1',
	DEFAULT_PORT : 11300,
	LOWEST_PRIORITY : 4294967295,

	connect : function(server, callback) {
		var server_tokens, host, port;

		if (server) {
			server_tokens = server.split(':');
			host = server_tokens[0];
			port = server_tokens[1];
		}

		//use defaults for address/port if not specified
		host || (host = Client.DEFAULT_ADDR);
		port || (port = Client.DEFAULT_PORT);

		//establish tcp connection
		var stream = net.createConnection(port, host);

		stream.on('connect', function() {
			return callback(null, new Connection(stream));
		});

		stream.on('error', function(err) {
			return callback(err);
		});

		return stream.on('close', function(has_error) {
		});
	}
};

/**
 * Connection
 */
function Connection(stream) {
	this.stream = stream;
	this.buffer = '';
	this.handlers = [];

	var self = this;
	self.stream.on('data', function(data) {
		self.buffer += data;

		while(self.buffer.length && self._tryToRespond());
	});
};

Connection.prototype._tryToRespond = function() {
	var handler = this.handlers[0];

	var response_handler = handler[0];
	var callback = handler[1];

	response_handler.handle(this.buffer);

	if (response_handler.complete) {
		this.buffer = this.buffer.substr(response_handler.consumed_data_length);
		this.handlers.shift();

		if (response_handler.success) {
			callback.apply(null, [false].concat(response_handler.args));
		} else {
			callback.call(null, response_handler.args[0]);
		}
	}

	return response_handler.complete;
};

Connection.prototype.send = function() {
	var args = slice.call(arguments);
	var packet = args.join(' ') + '\r\n';
	this.stream.write(packet);
};

Connection.prototype.end = function() {
	this.stream.end();
};

//submitting jobs
Connection.prototype.use = makeCommandMethod('use', 'USING');
Connection.prototype.put = makeCommandMethod('put', 'INSERTED', true);
//handling jobs
Connection.prototype.watch = makeCommandMethod('watch', 'WATCHING');
Connection.prototype.ignore = makeCommandMethod('ignore', 'WATCHING');
Connection.prototype.reserve = makeCommandMethod('reserve', 'RESERVED');
Connection.prototype.reserve_with_timeout = makeCommandMethod('reserve-with-timeout', 'RESERVED');
Connection.prototype.destroy = makeCommandMethod('delete', 'DELETED');
Connection.prototype.release = makeCommandMethod('release', 'RELEASED');
Connection.prototype.bury = makeCommandMethod('bury', 'BURIED');
Connection.prototype.touch = makeCommandMethod('touch', 'TOUCHED');
//other stuff
Connection.prototype.peek = makeCommandMethod('peek', 'FOUND');
Connection.prototype.peek_ready = makeCommandMethod('peek-ready', 'FOUND');
Connection.prototype.peek_delayed = makeCommandMethod('peek-delayed', 'FOUND');
Connection.prototype.peek_buried = makeCommandMethod('peek-buried', 'FOUND');
Connection.prototype.kick = makeCommandMethod('kick', 'KICKED');
Connection.prototype.stats_job = makeCommandMethod('stats-job', 'OK');
Connection.prototype.stats_tube = makeCommandMethod('stats-tube', 'OK');
Connection.prototype.stats = makeCommandMethod('stats', 'OK');

function makeCommandMethod(command_name, expected_response, sends_data) {
	return function() {
		var callback = arguments[arguments.length - 1];
		var args = slice.call(arguments, 0, arguments.length - 1);

		args.unshift(command_name);

		var data;

		if (sends_data) {
			data = args.pop();
			args.push(Buffer.byteLength(data, 'utf8'));
		}

		this.send.apply(this, args);

		if (data) {
			this.send(data)
		}

		var handler = [new ResponseHandler(expected_response), callback];

		return this.handlers.push(handler);
	};
};

/**
 * Response handler
 */
function ResponseHandler(success_code) {
	this.success_code = success_code;
};

ResponseHandler.prototype.reset = function() {
	this.complete = false;
	this.success = false;
	this.args = undefined;
	this.header = undefined;
	this.body = undefined;
	this.consumed_data_length = 0;
};

ResponseHandler.prototype.CODES_REQUIRING_BODY = {
	'RESERVED' : true
};

ResponseHandler.prototype.handle = function(data) {
	this.reset();

	var i = data.indexOf('\r\n');

	if (i < 0) {
		return; //response is not yet complete
	}

	this.header = data.substr(0, i);
	this.args = this.header.split(' ');

	var code = this.args[0];

	if (code === this.success_code) {
		this.args.shift();
		//don't include the code in the success args, but do in the err args
		this.success = true;
	}

	if ((this.CODES_REQUIRING_BODY[code])) {
		this.complete = this.parseBody(data.substr(i + 2)) ? true: false;
	} else {
		this.complete = true;
	}

	if (this.complete) {
		this.consumed_data_length = this.header.length + 2;

		if (this.body) {
			this.consumed_data_length += this.body.length + 2;
		}
	}
};

ResponseHandler.prototype.parseBody = function(data) {
	if (! hasValue(data)) {
		return;
	}

	var last_arg = this.args[this.args.length - 1];

	var expected_bodylength_inbytes = parseInt(last_arg, 10);
	var available_data_inbytes = Buffer.byteLength(data, 'utf8')

	if (available_data_inbytes >= (expected_bodylength_inbytes + 2)) {
		this.body = (new Buffer(data)).toString('utf8', 0, expected_bodylength_inbytes);

		//response args : remove the length and add the data
		this.args.pop();
		this.args.push(this.body);

		return true;
	}
};

/**
 * helpers
 */
function hasValue(v) {
	return (typeof v !== 'undefined' && v !== null);
}

/**
 * exports
 */
exports.Client = Client;

<commit_msg>refactored response handler<commit_after>
var net = require('net');

var Client = {
	DEFAULT_ADDR : '127.0.0.1',
	DEFAULT_PORT : 11300,
	LOWEST_PRIORITY : 4294967295,

	connect : function(server, callback) {
		var server_tokens, host, port;

		if (server) {
			server_tokens = server.split(':');
			host = server_tokens[0];
			port = server_tokens[1];
		}

		//use defaults for address/port if not specified
		host || (host = Client.DEFAULT_ADDR);
		port || (port = Client.DEFAULT_PORT);

		//establish tcp connection
		var stream = net.createConnection(port, host);

		stream.on('connect', function() {
			return callback(null, new Connection(stream));
		});

		stream.on('error', function(err) {
			return callback(err);
		});

		return stream.on('close', function(has_error) {
		});
	}
};

/**
 * Connection
 */
function Connection(stream) {
	this.stream = stream;
	this.data = '';
	this.handlers = [];

	var self = this;
	self.stream.on('data', function(data) {
		self.data += data;

		while(self.data.length && self._tryToRespond());
	});
};

Connection.prototype._tryToRespond = function() {
	var handler = this.handlers[0];

	var response = handler[0];
	var callback = handler[1];

	response.parse(this.data);

	if (response.complete) {
		this.data = this.data.substr(response.consumed_data_length);
		this.handlers.shift();

		if (response.success) {
			callback.apply(null, [false].concat(response.args));
		} else {
			callback.call(null, response.args[0]);
		}
	}

	return response.complete;
};

Connection.prototype.send = function(args) {
	var packet = args.join(' ') + '\r\n';
	this.stream.write(packet);
};

Connection.prototype.end = function() {
	this.stream.end();
};

//submitting jobs
Connection.prototype.use = makeCommandMethod('use', 'USING');
Connection.prototype.put = makeCommandMethod('put', 'INSERTED', true);
//handling jobs
Connection.prototype.watch = makeCommandMethod('watch', 'WATCHING');
Connection.prototype.ignore = makeCommandMethod('ignore', 'WATCHING');
Connection.prototype.reserve = makeCommandMethod('reserve', 'RESERVED');
Connection.prototype.reserve_with_timeout = makeCommandMethod('reserve-with-timeout', 'RESERVED');
Connection.prototype.destroy = makeCommandMethod('delete', 'DELETED');
Connection.prototype.release = makeCommandMethod('release', 'RELEASED');
Connection.prototype.bury = makeCommandMethod('bury', 'BURIED');
Connection.prototype.touch = makeCommandMethod('touch', 'TOUCHED');
//other stuff
Connection.prototype.peek = makeCommandMethod('peek', 'FOUND');
Connection.prototype.peek_ready = makeCommandMethod('peek-ready', 'FOUND');
Connection.prototype.peek_delayed = makeCommandMethod('peek-delayed', 'FOUND');
Connection.prototype.peek_buried = makeCommandMethod('peek-buried', 'FOUND');
Connection.prototype.kick = makeCommandMethod('kick', 'KICKED');
Connection.prototype.stats_job = makeCommandMethod('stats-job', 'OK');
Connection.prototype.stats_tube = makeCommandMethod('stats-tube', 'OK');
Connection.prototype.stats = makeCommandMethod('stats', 'OK');

function makeCommandMethod(command_name, expected_response, sends_data) {
	return function() {
		var args = Array.prototype.slice.call(arguments);
		var callback = args.pop();

		args.unshift(command_name);

		if (sends_data) {
			//first send header with length of data in bytes. then send data.
			var data = args.pop();
			args.push(Buffer.byteLength(data, 'utf8'));
			this.send(args);
			this.send([data])
		} else {
			this.send(args);
		}

		var handler = [new Response(expected_response), callback];

		return this.handlers.push(handler);
	};
};

/**
 * Response handler
 */
function Response(success_code) {
	this.success_code = success_code;
};

Response.prototype.reset = function() {
	this.complete = false;
	this.success = false;
	this.args = undefined;
	this.header = undefined;
	this.body = undefined;
	this.consumed_data_length = 0;
};

Response.prototype.CODES_REQUIRING_BODY = {
	'RESERVED' : true
};

Response.prototype.parse = function(data) {
	this.reset();

	var i = data.indexOf('\r\n');

	if (i < 0) {
		return; //response is not yet complete
	}

	this.header = data.substr(0, i);
	this.args = this.header.split(' ');

	var code = this.args[0];

	if (code === this.success_code) {
		this.args.shift();
		//don't include the code in the success args, but do in the err args
		this.success = true;
	}

	if ((this.CODES_REQUIRING_BODY[code])) {
		this.complete = this.parseBody(data.substr(i + 2)) ? true: false;
	} else {
		this.complete = true;
	}

	if (this.complete) {
		this.consumed_data_length = this.header.length + 2;

		if (this.body) {
			this.consumed_data_length += this.body.length + 2;
		}
	}
};

Response.prototype.parseBody = function(data) {
	var last_arg = this.args[this.args.length - 1];

	var expected_bodylength_inbytes = parseInt(last_arg, 10);
	var available_data_inbytes = Buffer.byteLength(data, 'utf8')

	if (available_data_inbytes >= (expected_bodylength_inbytes + 2)) {
		this.body = (new Buffer(data)).toString('utf8', 0, expected_bodylength_inbytes);

		//response args : remove the length and add the data
		this.args.pop();
		this.args.push(this.body);

		return true;
	}
};

/**
 * exports
 */
exports.Client = Client;

<|endoftext|>


<commit_before>'use strict';
const fs = require('fs');
const path = require('path');
const got = require('got');
const tempDir = require('temp-dir');
const makeDir = require('make-dir');
const ini = require('ini');
const trim = require('trim');
const CacheConf = require('cache-conf');
const pkg = require('./package.json');

const PREFERRED_STREAMS = [
  {quality: 'highest', format: 'mp3'},
  {quality: 'highest', format: 'aac'},
  {quality: 'high', format: 'mp3'},
  {quality: 'high', format: 'aacp'},
  {quality: 'low', format: 'aacp'},
  {quality: 'low', format: 'mp3'}
];

const GOT_OPTS = {
  headers: {
    'user-agent': `somafm/${pkg.version} (https://github.com/uschek/somafm)`
  }
};

const configName = (process.env.NODE_ENV === 'test' ? 'channels-test' : 'channels');
const channelsConf = new CacheConf({projectName: pkg.name, configName});

const somafm = {};
let channels = [];

function getChannels(options) {
  options = Object.assign({}, options);
  options.streams = Object.assign(PREFERRED_STREAMS, options.streams);

  return getChannelsFromAPIOrCache(options)
    .then(channels => filterChannels(channels, options.search));
}

function getChannelsFromAPIOrCache(options) {
  if (channels.length === 0) {
    channels = getCachedChannels();
  }

  if (channels.length === 0 || options.forceUpdate) {
    return getChannelsFromAPI(options)
      .then(setCachedChannels);
  }

  return Promise.resolve(channels);
}

function getChannelsFromAPI(options) {
  return got('https://api.somafm.com/channels.json', GOT_OPTS)
    .then(res => parseJSONData(res.body, options));
}

function parseJSONData(json, options) {
  json = JSON.parse(json);

  const channelsRaw = options.sortChannels ?
    json.channels.sort(compareChannelObjects) :
    json.channels;
  const channels = [];

  channelsRaw.forEach(channel => {
    const streamHighestQuality = getHighestQualityStream(channel, options.streams);

    const channelObj = {
      id: channel.id,
      title: channel.title,
      fullTitle: `SomaFM ${channel.title}`,
      description: trim(channel.description),
      dj: channel.dj,
      genre: channel.genre.replace(/\|/g, '/'),
      lastPlaying: channel.lastPlaying,
      listeners: channel.listeners,
      stream: streamHighestQuality,
      image: channel.image
    };
    channels.push(channelObj);
  });

  return Promise.resolve(channels);
}

function compareChannelObjects(a, b) {
  return a.title.toLowerCase().localeCompare(b.title.toLowerCase());
}

function getHighestQualityStream(channel, streams) {
  for (let i = 0; i < streams.length; i++) {
    const stream = streams[i];

    for (let j = 0; j < channel.playlists.length; j++) {
      if (channel.playlists[j].quality === stream.quality && channel.playlists[j].format === stream.format) {
        const res = {
          url: channel.playlists[j].url,
          format: channel.playlists[j].format,
          quality: channel.playlists[j].quality
        };

        return res;
      }
    }
  }

  return null;
}

function filterChannels(channels, search) {
  return new Promise(resolve => {
    if (Array.isArray(search) && search.length > 0) {
      resolve(applyFilter(channels, search));
    } else if (typeof search === 'string') {
      resolve(applyFilter(channels, [search]));
    } else {
      resolve(channels);
    }
  });
}

function applyFilter(channels, search) {
  return channels.filter(channel => {
    for (let i = 0; i < search.length; i++) {
      if (!isSubstringOfAny(String(search[i]).toLowerCase(), [
        channel.id,
        channel.title,
        channel.description,
        channel.genre,
        channel.dj
      ])) {
        return false;
      }
    }

    return true;
  });
}

function isSubstringOf(search, str) {
  return str.toLowerCase().indexOf(search) > -1;
}

function isSubstringOfAny(search, arr) {
  for (let i = 0; i < arr.length; i++) {
    if (isSubstringOf(search, arr[i])) {
      return true;
    }
  }

  return false;
}

function getChannel(id, options) {
  options = Object.assign({sortChannels: true}, options);

  // TODO: get rid of callback hell
  return getChannels(options)
    .then(channels => getChannelById(id, channels))
    .then(channel => {
      return getStreamUrls(channel)
        .then(urls => {
          channel.stream.urls = urls;
          setCachedChannels(channels);

          return Promise.resolve(channel);
        })
        .catch(console.log);
    })
    .then(channel => {
      const imageDir = path.join(tempDir, pkg.name);
      channel.imageFile = path.join(imageDir, channel.id);

      if (!fs.existsSync(channel.imageFile)) {
        makeDir.sync(imageDir);
        got.stream(channel.image).pipe(fs.createWriteStream(channel.imageFile));
      }

      return Promise.resolve(channel);
    });
}

function getChannelById(id, channels) {
  return new Promise((resolve, reject) => {
    for (const channel of channels) {
      if (id.toLowerCase() === channel.id) {
        resolve(channel);
      }
    }

    reject(new Error('Channel not found.'));
  });
}

function getStreamUrls(channel) {
  if (channel.stream.urls) {
    return Promise.resolve(channel.stream.urls);
  }

  return getUrlsFromPlaylist(channel.stream.url);
}

function getUrlsFromPlaylist(playlistUrl) {
  return new Promise((resolve, reject) => {
    got(playlistUrl)
      .then(response => {
        const data = ini.decode(response.body);
        const res = [];

        Object.keys(data.playlist)
          .filter(x => x.match(/^File[0-9]+$/))
          .forEach(key => {
            res.push(data.playlist[key]);
          });

        resolve(res);
      })
      .catch(reject);
  });
}

function getCachedChannels() {
  return channelsConf.get('channels') || [];
}

function setCachedChannels(channels) {
  // Cache channels for one minute
  channelsConf.set('channels', channels, {maxAge: 60000});

  return Promise.resolve(channels);
}

somafm.getChannels = getChannels;
somafm.getChannel = getChannel;

module.exports = somafm;
<commit_msg>Tweak full channel title<commit_after>'use strict';
const fs = require('fs');
const path = require('path');
const got = require('got');
const tempDir = require('temp-dir');
const makeDir = require('make-dir');
const ini = require('ini');
const trim = require('trim');
const CacheConf = require('cache-conf');
const pkg = require('./package.json');

const PREFERRED_STREAMS = [
  {quality: 'highest', format: 'mp3'},
  {quality: 'highest', format: 'aac'},
  {quality: 'high', format: 'mp3'},
  {quality: 'high', format: 'aacp'},
  {quality: 'low', format: 'aacp'},
  {quality: 'low', format: 'mp3'}
];

const GOT_OPTS = {
  headers: {
    'user-agent': `somafm/${pkg.version} (https://github.com/uschek/somafm)`
  }
};

const configName = (process.env.NODE_ENV === 'test' ? 'channels-test' : 'channels');
const channelsConf = new CacheConf({projectName: pkg.name, configName});

const somafm = {};
let channels = [];

function getChannels(options) {
  options = Object.assign({}, options);
  options.streams = Object.assign(PREFERRED_STREAMS, options.streams);

  return getChannelsFromAPIOrCache(options)
    .then(channels => filterChannels(channels, options.search));
}

function getChannelsFromAPIOrCache(options) {
  if (channels.length === 0) {
    channels = getCachedChannels();
  }

  if (channels.length === 0 || options.forceUpdate) {
    return getChannelsFromAPI(options)
      .then(setCachedChannels);
  }

  return Promise.resolve(channels);
}

function getChannelsFromAPI(options) {
  return got('https://api.somafm.com/channels.json', GOT_OPTS)
    .then(res => parseJSONData(res.body, options));
}

function parseJSONData(json, options) {
  json = JSON.parse(json);

  const channelsRaw = options.sortChannels ?
    json.channels.sort(compareChannelObjects) :
    json.channels;
  const channels = [];

  channelsRaw.forEach(channel => {
    const streamHighestQuality = getHighestQualityStream(channel, options.streams);

    const channelObj = {
      id: channel.id,
      title: channel.title,
      fullTitle: channel.title.startsWith('SomaFM') ? channel.title : `SomaFM ${channel.title}`,
      description: trim(channel.description),
      dj: channel.dj,
      genre: channel.genre.replace(/\|/g, '/'),
      lastPlaying: channel.lastPlaying,
      listeners: channel.listeners,
      stream: streamHighestQuality,
      image: channel.image
    };
    channels.push(channelObj);
  });

  return Promise.resolve(channels);
}

function compareChannelObjects(a, b) {
  return a.title.toLowerCase().localeCompare(b.title.toLowerCase());
}

function getHighestQualityStream(channel, streams) {
  for (let i = 0; i < streams.length; i++) {
    const stream = streams[i];

    for (let j = 0; j < channel.playlists.length; j++) {
      if (channel.playlists[j].quality === stream.quality && channel.playlists[j].format === stream.format) {
        const res = {
          url: channel.playlists[j].url,
          format: channel.playlists[j].format,
          quality: channel.playlists[j].quality
        };

        return res;
      }
    }
  }

  return null;
}

function filterChannels(channels, search) {
  return new Promise(resolve => {
    if (Array.isArray(search) && search.length > 0) {
      resolve(applyFilter(channels, search));
    } else if (typeof search === 'string') {
      resolve(applyFilter(channels, [search]));
    } else {
      resolve(channels);
    }
  });
}

function applyFilter(channels, search) {
  return channels.filter(channel => {
    for (let i = 0; i < search.length; i++) {
      if (!isSubstringOfAny(String(search[i]).toLowerCase(), [
        channel.id,
        channel.title,
        channel.description,
        channel.genre,
        channel.dj
      ])) {
        return false;
      }
    }

    return true;
  });
}

function isSubstringOf(search, str) {
  return str.toLowerCase().indexOf(search) > -1;
}

function isSubstringOfAny(search, arr) {
  for (let i = 0; i < arr.length; i++) {
    if (isSubstringOf(search, arr[i])) {
      return true;
    }
  }

  return false;
}

function getChannel(id, options) {
  options = Object.assign({sortChannels: true}, options);

  // TODO: get rid of callback hell
  return getChannels(options)
    .then(channels => getChannelById(id, channels))
    .then(channel => {
      return getStreamUrls(channel)
        .then(urls => {
          channel.stream.urls = urls;
          setCachedChannels(channels);

          return Promise.resolve(channel);
        })
        .catch(console.log);
    })
    .then(channel => {
      const imageDir = path.join(tempDir, pkg.name);
      channel.imageFile = path.join(imageDir, channel.id);

      if (!fs.existsSync(channel.imageFile)) {
        makeDir.sync(imageDir);
        got.stream(channel.image).pipe(fs.createWriteStream(channel.imageFile));
      }

      return Promise.resolve(channel);
    });
}

function getChannelById(id, channels) {
  return new Promise((resolve, reject) => {
    for (const channel of channels) {
      if (id.toLowerCase() === channel.id) {
        resolve(channel);
      }
    }

    reject(new Error('Channel not found.'));
  });
}

function getStreamUrls(channel) {
  if (channel.stream.urls) {
    return Promise.resolve(channel.stream.urls);
  }

  return getUrlsFromPlaylist(channel.stream.url);
}

function getUrlsFromPlaylist(playlistUrl) {
  return new Promise((resolve, reject) => {
    got(playlistUrl)
      .then(response => {
        const data = ini.decode(response.body);
        const res = [];

        Object.keys(data.playlist)
          .filter(x => x.match(/^File[0-9]+$/))
          .forEach(key => {
            res.push(data.playlist[key]);
          });

        resolve(res);
      })
      .catch(reject);
  });
}

function getCachedChannels() {
  return channelsConf.get('channels') || [];
}

function setCachedChannels(channels) {
  // Cache channels for one minute
  channelsConf.set('channels', channels, {maxAge: 60000});

  return Promise.resolve(channels);
}

somafm.getChannels = getChannels;
somafm.getChannel = getChannel;

module.exports = somafm;
<|endoftext|>


<commit_before>/*
 * Grunt Task File
 * ---------------
 *
 * Task: S3
 * Description: Move files to and from s3
 * Dependencies: knox, async, underscore.deferred
 *
 */

module.exports = function (grunt) {

  /**
   * Module dependencies.
   */

  // Core.
  const util = require('util');
  const crypto = require('crypto');
  const fs = require('fs');
  const path = require('path');
  const url = require('url');
  const zlib = require('zlib');

  // Npm.
  const knox = require('knox');
  const mime = require('mime');
  const async = require('async');
  const _ = require('underscore');
  const deferred = require('underscore.deferred');
  _.mixin(deferred);

  /**
   * Grunt aliases.
   */
  var log = grunt.log;

  /**
   * Success/error messages.
   */

  const MSG_UPLOAD_SUCCESS = '✓ Uploaded: %s (%s)';
  const MSG_DOWNLOAD_SUCCESS = '✓ Downloaded: %s (%s)';

  const MSG_ERR_NOT_FOUND = 'File not found: %s';
  const MSG_ERR_UPLOAD = 'Upload error: %s';
  const MSG_ERR_DOWNLOAD = 'Download error: %s';
  const MSG_ERR_CHECKSUM = 'Expected hash: %s but found %s';
  const MSG_ERR_VERIFY = 'Unable to verify upload: %s => %s';

  /**
   * Create an Error object based off of a formatted message. Arguments
   * are identical to those of util.format.
   *
   * @param {String} Format.
   * @param {...string|number} Values to insert into Format.
   */
  function makeError () {
    var msg = util.format.apply(util, _.toArray(arguments));
    return new Error(msg);
  }

  /**
   * Transfer files to/from s3.
   *
   * Uses global s3 grunt config.
   */
  grunt.registerTask('s3', 'Publishes files to s3.', function () {
    var done = this.async();
    var config = _.defaults(grunt.config('s3') || {}, {
      upload: [],
      download: []
    });

    var transfers = [];

    config.upload.forEach(function(upload) {
      // Expand list of files to download.
      var files = grunt.file.expandFiles(upload.src);

      files.forEach(function(file) {
        // If there is only 1 file and it matches the original file wildcard,
        // we know this is a single file transfer. Otherwise, we need to build
        // the destination.
        var dest = (files.length === 1 && file === upload.src)
          ? upload.dest
          : path.join(upload.dest, path.basename(file));

        transfers.push(grunt.helper('s3.put', file, dest, upload));
      });
    });

    config.download.forEach(function(download) {
      transfers.push(grunt.helper('s3.pull', download.src, download.dest, download));
    });

    var total = transfers.length;
    var errors = 0;

    transfers.forEach(function(transfer) {
      transfer.done(function(msg) {
        log.ok(msg);
      });

      transfer.fail(function(msg) {
        log.error(msg);
        ++errors;
      });

      transfer.always(function() {
        if (--total === 0) {
          done(!errors);
        }
      });
    });
  });

  /**
   * Publishes the local file at src to the s3 dest.
   *
   * Verifies that the upload was successful by comparing an md5 checksum of
   * the local and remote versions.
   *
   * @param {String} src The local path to the file to upload.
   * @param {String} dest The s3 path, relative to the bucket, to which the src is
   *     uploaded.
   * @param {Object} [options] An object containing options which override any option
   *     declared in the global s3 config.
   */
  grunt.registerHelper('s3.put', function (src, dest, options) {
    // Make sure the local file exists.
    if (!path.existsSync(src)) {
      return dfd.reject(makeError(MSG_ERR_NOT_FOUND, src));
    }

    var dfd = new _.Deferred();
    var config = _.defaults(options, grunt.config('s3') || {});
    var headers = options.headers || {};

    if (options.access) {
      headers['x-amz-acl'] = options.access;
    }

    // Pick out the configuration options we need for the client.
    var client = knox.createClient(_(config).pick([
      'endpoint', 'port', 'key', 'secret', 'access', 'bucket'
    ]));

    function upload(cb) {
      cb = cb || function () {};

      client.putFile(src, dest, headers, function (err, res) {
        // If there was an upload error any status other than a 200, we
        // can assume something went wrong.
        if (err || res.statusCode !== 200) {
          return dfd.reject(makeError(MSG_ERR_UPLOAD, err || res.statusCode));
        }

        fs.readFile(src, function (err, data) {
          if (err) {
            return dfd.reject(makeError(MSG_ERR_UPLOAD, err));
          }
          else {
            // The etag has double quotes around it. Strip them out.
            var remoteHash = res.headers.etag.replace(/"/g, '');

            // Get an md5 of the file so we can verify the uploads.
            var localHash = crypto.createHash('md5').update(data).digest('hex');

            if (remoteHash === localHash) {
              var msg = util.format(MSG_UPLOAD_SUCCESS, src, localHash);
              dfd.resolve(msg);
            }
            else {
              dfd.reject(makeError(MSG_ERR_CHECKSUM, localHash, remoteHash));
            }
          }

          cb(err);
        });
      });
    }

    // If gzip is enabled, gzip the file into a temp file and then perform the upload.
    if (options.gzip) {
      headers['Content-Encoding'] = 'gzip';
      headers['Content-Type'] = mime.lookup(src);

      var tmp = src + '.gz';
      var incr = 0;
      while (path.existsSync(tmp)) {
        tmp = src + '.' + (incr++) + '.gz';
      }

      var input = fs.createReadStream(src);
      var output = fs.createWriteStream(tmp);

      input.pipe(zlib.createGzip()).pipe(output)
        .on('error', function (err) {
          dfd.reject(makeError(MSG_ERR_UPLOAD, err));
        })
        .on('close', function () {
          src = tmp;
          upload(function () {
            fs.unlinkSync(tmp);
          });
        });
    }
    else {
      upload();
    }

    return dfd;
  });

  /**
   * Download a file from s3.
   *
   * Verifies that the download was successful by downloading the file and
   * comparing an md5 checksum of the local and remote versions.
   *
   * @param {String} src The s3 path, relative to the bucket, of the file being
   *     downloaded.
   * @param {String} dest The local path where the download will be saved.
   * @param {Object} [options] An object containing options which override any option
   *     declared in the global s3 config.
   */
  grunt.registerHelper('s3.pull', function (src, dest, options) {
    var dfd = new _.Deferred();
    var config = _.defaults(options, grunt.config('s3') || {});

    // Create a local stream we can write the downloaded file to.
    var file = fs.createWriteStream(dest);

    // Pick out the configuration options we need for the client.
    var client = knox.createClient(_(config).pick([
      'endpoint', 'port', 'key', 'secret', 'access', 'bucket'
    ]));

    // Upload the file to this endpoint.
    client.getFile(src, function (err, res) {
      // If there was an upload error any status other than a 200, we
      // can assume something went wrong.
      if (err || res.statusCode !== 200) {
        return dfd.reject(makeError(MSG_ERR_DOWNLOAD, err || res.statusCode));
      }

      res
        .on('data', function (chunk) {
          file.write(chunk);
        })
        .on('error', function (err) {
          return dfd.reject(makeError(MSG_ERR_DOWNLOAD, err));
        })
        .on('end', function () {
          file.end();

          fs.readFile(dest, function (err, data) {
            if (err) {
              return dfd.reject(makeError(MSG_ERR_DOWNLOAD, err));
            }
            else {
              // The etag has double quotes around it. Strip them out.
              var remoteHash = res.headers.etag.replace(/"/g, '');
              var localHash = crypto.createHash('md5').update(data).digest('hex');

              if (remoteHash === localHash) {
                var msg = util.format(MSG_DOWNLOAD_SUCCESS, src, localHash);
                dfd.resolve(msg);
              }
              else {
                dfd.reject(makeError(MSG_ERR_CHECKSUM, localHash, remoteHash));
              }
            }
          });
        });
    });

    return dfd;
  });

};

<commit_msg>Add s3.delete. Improve error/success messages.<commit_after>/*
 * Grunt Task File
 * ---------------
 *
 * Task: S3
 * Description: Move files to and from s3
 * Dependencies: knox, async, underscore.deferred
 *
 */

module.exports = function (grunt) {

  /**
   * Module dependencies.
   */

  // Core.
  const util = require('util');
  const crypto = require('crypto');
  const fs = require('fs');
  const path = require('path');
  const url = require('url');
  const zlib = require('zlib');

  // Npm.
  const knox = require('knox');
  const mime = require('mime');
  const async = require('async');
  const _ = require('underscore');
  const deferred = require('underscore.deferred');
  _.mixin(deferred);

  /**
   * Grunt aliases.
   */
  var log = grunt.log;

  /**
   * Success/error messages.
   */

  const MSG_UPLOAD_SUCCESS = '↗ Uploaded: %s (%s)';
  const MSG_DOWNLOAD_SUCCESS = '↙ Downloaded: %s (%s)';
  const MSG_DELETE_SUCCESS = '✗ Deleted: %s (%s)';

  const MSG_ERR_NOT_FOUND = 'File not found: %s';
  const MSG_ERR_UPLOAD = 'Upload error: %s (%s)';
  const MSG_ERR_DOWNLOAD = 'Download error: %s (%s)';
  const MSG_ERR_DELETE = 'Delete error: %s (%s)';
  const MSG_ERR_CHECKSUM = 'Expected hash: %s but found %s for %s';
  const MSG_ERR_VERIFY = 'Unable to verify upload: %s => %s for %s';

  /**
   * Create an Error object based off of a formatted message. Arguments
   * are identical to those of util.format.
   *
   * @param {String} Format.
   * @param {...string|number} Values to insert into Format.
   */
  function makeError () {
    var msg = util.format.apply(util, _.toArray(arguments));
    return new Error(msg);
  }

  /**
   * Transfer files to/from s3.
   *
   * Uses global s3 grunt config.
   */
  grunt.registerTask('s3', 'Publishes files to s3.', function () {
    var done = this.async();
    var config = _.defaults(grunt.config('s3') || {}, {
      upload: [],
      download: [],
      del: []
    });

    var transfers = [];

    config.upload.forEach(function(upload) {
      // Expand list of files to download.
      var files = grunt.file.expandFiles(upload.src);

      files.forEach(function(file) {
        // If there is only 1 file and it matches the original file wildcard,
        // we know this is a single file transfer. Otherwise, we need to build
        // the destination.
        var dest = (files.length === 1 && file === upload.src)
          ? upload.dest
          : path.join(upload.dest, path.basename(file));

        transfers.push(grunt.helper('s3.put', file, dest, upload));
      });
    });

    config.download.forEach(function(download) {
      transfers.push(grunt.helper('s3.pull', download.src, download.dest, download));
    });

    config.del.forEach(function(del) {
      transfers.push(grunt.helper('s3.delete', del.src, del));
    });

    var total = transfers.length;
    var errors = 0;

    transfers.forEach(function(transfer) {
      transfer.done(function(msg) {
        log.ok(msg);
      });

      transfer.fail(function(msg) {
        log.error(msg);
        ++errors;
      });

      transfer.always(function() {
        if (--total === 0) {
          done(!errors);
        }
      });
    });
  });

  /**
   * Publishes the local file at src to the s3 dest.
   *
   * Verifies that the upload was successful by comparing an md5 checksum of
   * the local and remote versions.
   *
   * @param {String} src The local path to the file to upload.
   * @param {String} dest The s3 path, relative to the bucket, to which the src is
   *     uploaded.
   * @param {Object} [options] An object containing options which override any option
   *     declared in the global s3 config.
   */
  grunt.registerHelper('s3.put', function (src, dest, options) {
    // Make sure the local file exists.
    if (!path.existsSync(src)) {
      return dfd.reject(makeError(MSG_ERR_NOT_FOUND, src));
    }

    var dfd = new _.Deferred();
    var config = _.defaults(options, grunt.config('s3') || {});
    var headers = options.headers || {};

    if (options.access) {
      headers['x-amz-acl'] = options.access;
    }

    // Pick out the configuration options we need for the client.
    var client = knox.createClient(_(config).pick([
      'endpoint', 'port', 'key', 'secret', 'access', 'bucket'
    ]));

    function upload(cb) {
      cb = cb || function () {};

      client.putFile(src, dest, headers, function (err, res) {
        // If there was an upload error any status other than a 200, we
        // can assume something went wrong.
        if (err || res.statusCode !== 200) {
          return dfd.reject(makeError(MSG_ERR_UPLOAD, src, err || res.statusCode));
        }

        fs.readFile(src, function (err, data) {
          if (err) {
            return dfd.reject(makeError(MSG_ERR_UPLOAD, src, err));
          }
          else {
            // The etag has double quotes around it. Strip them out.
            var remoteHash = res.headers.etag.replace(/"/g, '');

            // Get an md5 of the file so we can verify the uploads.
            var localHash = crypto.createHash('md5').update(data).digest('hex');

            if (remoteHash === localHash) {
              var msg = util.format(MSG_UPLOAD_SUCCESS, src, localHash);
              dfd.resolve(msg);
            }
            else {
              dfd.reject(makeError(MSG_ERR_CHECKSUM, localHash, remoteHash));
            }
          }

          cb(err);
        });
      });
    }

    // If gzip is enabled, gzip the file into a temp file and then perform the upload.
    if (options.gzip) {
      headers['Content-Encoding'] = 'gzip';
      headers['Content-Type'] = mime.lookup(src);

      var tmp = src + '.gz';
      var incr = 0;
      while (path.existsSync(tmp)) {
        tmp = src + '.' + (incr++) + '.gz';
      }

      var input = fs.createReadStream(src);
      var output = fs.createWriteStream(tmp);

      input.pipe(zlib.createGzip()).pipe(output)
        .on('error', function (err) {
          dfd.reject(makeError(MSG_ERR_UPLOAD, src, err));
        })
        .on('close', function () {
          src = tmp;
          upload(function () {
            fs.unlinkSync(tmp);
          });
        });
    }
    else {
      upload();
    }

    return dfd;
  });

  /**
   * Download a file from s3.
   *
   * Verifies that the download was successful by downloading the file and
   * comparing an md5 checksum of the local and remote versions.
   *
   * @param {String} src The s3 path, relative to the bucket, of the file being
   *     downloaded.
   * @param {String} dest The local path where the download will be saved.
   * @param {Object} [options] An object containing options which override any option
   *     declared in the global s3 config.
   */
  grunt.registerHelper('s3.pull', function (src, dest, options) {
    var dfd = new _.Deferred();
    var config = _.defaults(options, grunt.config('s3') || {});

    // Create a local stream we can write the downloaded file to.
    var file = fs.createWriteStream(dest);

    // Pick out the configuration options we need for the client.
    var client = knox.createClient(_(config).pick([
      'endpoint', 'port', 'key', 'secret', 'access', 'bucket'
    ]));

    // Upload the file to this endpoint.
    client.getFile(src, function (err, res) {
      // If there was an upload error any status other than a 200, we
      // can assume something went wrong.
      if (err || res.statusCode !== 200) {
        return dfd.reject(makeError(MSG_ERR_DOWNLOAD, src, err || res.statusCode));
      }

      res
        .on('data', function (chunk) {
          file.write(chunk);
        })
        .on('error', function (err) {
          return dfd.reject(makeError(MSG_ERR_DOWNLOAD, src, err));
        })
        .on('end', function () {
          file.end();

          fs.readFile(dest, function (err, data) {
            if (err) {
              return dfd.reject(makeError(MSG_ERR_DOWNLOAD, src, err));
            }
            else {
              // The etag has double quotes around it. Strip them out.
              var remoteHash = res.headers.etag.replace(/"/g, '');
              var localHash = crypto.createHash('md5').update(data).digest('hex');

              if (remoteHash === localHash) {
                var msg = util.format(MSG_DOWNLOAD_SUCCESS, src, localHash);
                dfd.resolve(msg);
              }
              else {
                dfd.reject(makeError(MSG_ERR_CHECKSUM, localHash, remoteHash));
              }
            }
          });
        });
    });

    return dfd;
  });

  grunt.registerHelper('s3.delete', function (src, options) {
    var dfd = new _.Deferred();
    var config = _.defaults(options, grunt.config('s3') || {});

    // Pick out the configuration options we need for the client.
    var client = knox.createClient(_(config).pick([
      'endpoint', 'port', 'key', 'secret', 'access', 'bucket'
    ]));

    // Upload the file to this endpoint.
    client.deleteFile(src, function (err, res) {
      if (err || res.statusCode !== 204) {
        dfd.reject(makeError(MSG_ERR_DELETE, src, err || res.statusCode));
      }
      else {
        dfd.resolve(util.format(MSG_DELETE_SUCCESS, src));
      }
    });

    return dfd;
  });

};

<|endoftext|>


<commit_before>/*jshint camelcase: false */
var fs = require('fs');
var path = require('path');

var S = require('string');
var Twit = require('twit');

var redis = require('redis'),
    client = redis.createClient();

client.on('error', function(err) {
    console.log('Error ' + err);
});

var config = fs.existsSync('./local.config.js') ? require('./local.config.js') : require('./config.js');

var Twitter = new Twit(config.API);

var track = config.track;

if (config.media) {
    var b64media = fs.readFileSync(path.join(__dirname, config.media), {
        encoding: 'base64'
    });
}

var stream = Twitter.stream('statuses/filter', {
    track: track
});

var getPermalink = function(tweet) {
    return 'https://twitter.com/' + tweet.user.screen_name + '/status/' + tweet.id_str;
};

console.log(track);

stream.on('disconnect', function() {
    console.log('Disconnected from stream');
});

stream.on('limit', function() {
    console.log('Stream limited');
});

stream.on('tweet', function(tweet) {
    if (!tweet.retweeted_status && S(tweet.text.toLowerCase()).contains(track.toLowerCase())) {
        var reply = {
            name: tweet.user.screen_name,
            id: tweet.id_str,
            id_user: tweet.user.id_str
        };

        console.log('Pushing to queue:', getPermalink(tweet));

        client.rpush('queue', JSON.stringify(reply));
    }
});

var tweet = function(t) {
    Twitter.post('media/upload', {
        media_data: b64media
    }, function(error, data) {
        if (error) {
            console.log(error);
        }

        var params = {
            status: '.@' + t.name + ' Castelaooo',
            in_reply_to_status_id: t.id,
            media_ids: [data.media_id_string]
        };

        Twitter.post('statuses/update', params, function(error, data) {
            if (error) {
                console.log(error);
            }
            console.log('Done.');
        });
    });
};

var getNext = function() {
    client.lpop('queue', function(error, reply) {
        if (error) {
            console.log(error);
        }

        if (reply) {
            var currentTweet = JSON.parse(reply);

            client.exists('@' + currentTweet.name, function(error, exists) {
                if (error) {
                    console.log(error);
                }

                if (!exists) {
                    console.log('Tweeting to', currentTweet.name);

                    tweet(currentTweet);

                    client.set('@' + currentTweet.name, '1');
                    client.expire('@' + currentTweet.name, 3600 * 12);
                } else {
                    console.log('--');
                    console.log('User blocked for 12 hours');
                    console.log('--');
                }
            });
        }
    });
};

setInterval(function() {
    client.llen('queue', function(error, size) {
        if (error) {
            console.log(error);
        }

        console.log('Queue size:', size);

        if (size) {
            getNext();
        } else {
            console.log('Queue empty.');
        }
    });
}, 1000 * 60 * 2);
<commit_msg>Disable public replies<commit_after>/*jshint camelcase: false */
var fs = require('fs');
var path = require('path');

var S = require('string');
var Twit = require('twit');

var redis = require('redis'),
    client = redis.createClient();

client.on('error', function(err) {
    console.log('Error ' + err);
});

var config = fs.existsSync('./local.config.js') ? require('./local.config.js') : require('./config.js');

var Twitter = new Twit(config.API);

var track = config.track;

if (config.media) {
    var b64media = fs.readFileSync(path.join(__dirname, config.media), {
        encoding: 'base64'
    });
}

var stream = Twitter.stream('statuses/filter', {
    track: track
});

var getPermalink = function(tweet) {
    return 'https://twitter.com/' + tweet.user.screen_name + '/status/' + tweet.id_str;
};

console.log(track);

stream.on('disconnect', function() {
    console.log('Disconnected from stream');
});

stream.on('limit', function() {
    console.log('Stream limited');
});

stream.on('tweet', function(tweet) {
    if (!tweet.retweeted_status && S(tweet.text.toLowerCase()).contains(track.toLowerCase())) {
        var reply = {
            name: tweet.user.screen_name,
            id: tweet.id_str,
            id_user: tweet.user.id_str
        };

        console.log('Pushing to queue:', getPermalink(tweet));

        client.rpush('queue', JSON.stringify(reply));
    }
});

var tweet = function(t) {
    Twitter.post('media/upload', {
        media_data: b64media
    }, function(error, data) {
        if (error) {
            console.log(error);
        }

        var params = {
            status: '@' + t.name + ' Castelaooo',
            in_reply_to_status_id: t.id,
            media_ids: [data.media_id_string]
        };

        Twitter.post('statuses/update', params, function(error, data) {
            if (error) {
                console.log(error);
            }
            console.log('Done.');
        });
    });
};

var getNext = function() {
    client.lpop('queue', function(error, reply) {
        if (error) {
            console.log(error);
        }

        if (reply) {
            var currentTweet = JSON.parse(reply);

            client.exists('@' + currentTweet.name, function(error, exists) {
                if (error) {
                    console.log(error);
                }

                if (!exists) {
                    console.log('Tweeting to', currentTweet.name);

                    tweet(currentTweet);

                    client.set('@' + currentTweet.name, '1');
                    client.expire('@' + currentTweet.name, 3600 * 12);
                } else {
                    console.log('--');
                    console.log('User blocked for 12 hours');
                    console.log('--');
                }
            });
        }
    });
};

setInterval(function() {
    client.llen('queue', function(error, size) {
        if (error) {
            console.log(error);
        }

        console.log('Queue size:', size);

        if (size) {
            getNext();
        } else {
            console.log('Queue empty.');
        }
    });
}, 1000 * 60 * 2);
<|endoftext|>


<commit_before>const cool = require('cool-ascii-faces')
const funky_intro = require('funny-words')
const express = require('express')
const emoji = require('emoji-cool');

const app = express()

app.get('/', function(req, res) {
  res.send('Hello Mars!
 Days until next year:' + Math.round(( new Date().setFullYear(new Date().getFullYear() + 1, 0, 1) - new Date() )/(1000 * 60 * 60 * 24)));
})

app.get('/hangUnlessSomeoneElseReturnsFromHere', function(req, res) {}); // To make this route work, someone else needs to return a response
app.get('/useless', function(req, res){ res.redirect('http://www.theuselessweb.com/'); })
app.get('/findMoreHacktoberfestLabelledIssues', function(req, res){ res.redirect('http://issuehub.io/?label[]=hacktoberfest'); })

app.get('/hello/:name', function(req, res) { res.json({"hello" : req.params.name}); })

console.log(emoji)
console.log(cool())
console.log(funky_intro("Welcome to jkup, a Node.js app where you can only contribute one line at a time. Inspired by jkup himself."))

app.listen(process.env.PORT || 3000, function () {});
console.log("I like this idea. :p");
<commit_msg>Update index.js<commit_after>const cool = require('cool-ascii-faces')
const funky_intro = require('funny-words')
const express = require('express')
const emoji = require('emoji-cool');

const app = express()

app.get('/', function(req, res) {
  res.send('Hello Mars!
 Days until next year:' + Math.round(( new Date().setFullYear(new Date().getFullYear() + 1, 0, 1) - new Date() )/(1000 * 60 * 60 * 24)));
})

app.get('/hangUnlessSomeoneElseReturnsFromHere', function(req, res) {}); // To make this route work, someone else needs to return a response
app.get('/useless', function(req, res){ res.redirect('http://www.theuselessweb.com/'); })
app.get('/findMoreHacktoberfestLabelledIssues', function(req, res){ res.redirect('http://issuehub.io/?label[]=hacktoberfest'); })

app.get('/hello/:name', function(req, res) { res.json({"hello" : req.params.name}); })

console.log(emoji)
console.log(cool())
console.log(funky_intro("Welcome to jkup, a Node.js app where you can only contribute one line at a time. Inspired by jkup himself."))

app.listen(process.env.PORT || 3000, function () {});
app.use(express.static('public'));
console.log("I like this idea. :p");
<|endoftext|>


<commit_before>'use strict';

const Discord = require('discord.js');
const client = new Discord.Client();
const winston = require('winston');

require('dotenv').config();

// Configure logging to file and console
// Developers can then just `require('winston')` to log in their modules
winston.configure({
  transports: [
    new (winston.transports.Console)({
      level: 'debug',
      timestamp: true,
    }),
    new (winston.transports.File)({
      filename: 'sgs_bot.log',
    }),
  ],
});

// set up our event handlers
const channelHandler = require('./event_handlers/channel_handler');
const messageHandler = require('./event_handlers/message_handler');
const presenceHandler = require('./event_handlers/presence_handler');

client.on('ready', async function() {
  winston.log('info', 'Logged into Discord as %s', client.user.tag);
  // set a useful presence message
  await client.user.setPresence({
    status: 'online',
    afk: false,
    activity: {
      name: `Ask me for ${process.env.COMMAND_PREFIX}help`,
    },
  });
  winston.log('info', 'Using %s as prefix for commands',
    process.env.COMMAND_PREFIX);
  // fire off an update for all channels in case they've gotten inconsistent
  winston.log('info', 'Performing initial channel scan');
  client.guilds.array().forEach((guild) => channelHandler.updateChannelsForGuild(guild));
});

client.on('voiceStateUpdate', channelHandler.handleVoiceStateUpdate);
client.on('message', messageHandler.dispatchMessage);
client.on('presenceUpdate', presenceHandler);

// If something bad happens, let the process manager restart us properly
client.on('disconnect', function(ev) {
  winston.log('debug', 'Discord.js websocket disconnected, terminating.', ev);
  process.exit(1);
});
client.on('error', function(err) {
  winston.log('debug', 'Discord.js client emitted error event, terminating.', err);
  process.exit(1);
});

client.login(process.env.DISCORD_KEY);
<commit_msg>Make an error spit out less useless guff<commit_after>'use strict';

const Discord = require('discord.js');
const client = new Discord.Client();
const winston = require('winston');

require('dotenv').config();

// Configure logging to file and console
// Developers can then just `require('winston')` to log in their modules
winston.configure({
  transports: [
    new (winston.transports.Console)({
      level: 'debug',
      timestamp: true,
    }),
    new (winston.transports.File)({
      filename: 'sgs_bot.log',
    }),
  ],
});

// set up our event handlers
const channelHandler = require('./event_handlers/channel_handler');
const messageHandler = require('./event_handlers/message_handler');
const presenceHandler = require('./event_handlers/presence_handler');

client.on('ready', async function() {
  winston.log('info', 'Logged into Discord as %s', client.user.tag);
  // set a useful presence message
  await client.user.setPresence({
    status: 'online',
    afk: false,
    activity: {
      name: `Ask me for ${process.env.COMMAND_PREFIX}help`,
    },
  });
  winston.log('info', 'Using %s as prefix for commands',
    process.env.COMMAND_PREFIX);
  // fire off an update for all channels in case they've gotten inconsistent
  winston.log('info', 'Performing initial channel scan');
  client.guilds.array().forEach((guild) => channelHandler.updateChannelsForGuild(guild));
});

client.on('voiceStateUpdate', channelHandler.handleVoiceStateUpdate);
client.on('message', messageHandler.dispatchMessage);
client.on('presenceUpdate', presenceHandler);

// If something bad happens, let the process manager restart us properly
client.on('disconnect', function(ev) {
  winston.log('debug', 'Discord.js websocket disconnected, terminating.', ev.reason);
  process.exit(1);
});
client.on('error', function(err) {
  winston.log('debug', 'Discord.js client emitted error event, terminating.', err);
  process.exit(1);
});

client.login(process.env.DISCORD_KEY);
<|endoftext|>