<commit_before>'use strict';

var request = require('request'),
		sprintf = require('sprintf-js').sprintf,
		_ = require('lodash'),
		Q = require('q'),
		utf8 = require('utf8'),
		validator = require('validator');

/**
	* StopForumSpam Module
	* @exports stopforumspam
	* @namespace sfs
*/
var sfs = {
	/**
	* Default Configuration settings for stopforumspam
	*/
	config: {
		url: 'http://stopforumspam.com',
		routes: [{
			name: 'search',
			path: '/api?f=json&nobadusername'	// ignore partial username string search
		},{
			name: 'submit',
			path: '/add.php?api_key=%s'
		}],
		searchParameters: [{
			name: 'ip',
			searchAdd: '&ip=%s',
			submitAdd: '&ip_addr=%s'
		},{
			name: 'email',
			searchAdd: '&email=%s',
			submitAdd: '&email=%s'
		},{
			name: 'username',
			searchAdd: '&username=%s',
			submitAdd: '&username=%s'
		}],
		apiKey: ''
	}
};

/**
	* Checks if a user is a spammer.  Pass only the parameters you wish to search for
	* @param userObject {object} a hashlike object with each of the  parameters to search for.
	* 	Search for as many or as few as you wish.
	* @example
	* stopforumspam.isSpammer({ ip: '123.456.789.100', email: '<EMAIL>', username: 'Spammer!' })
	*   .then(function (result) {
	*   // result if false if not found
	*   // result = {
	*   //   success: 1,
	*   //   username: {
	*   //     lastseen: '2015-03-09 15:22:49',
	*   //     frequency: 3830,
	*   //     appears: 1,
	*   //     confidence: 90.2 } }
	* });
	* @returns Promise which returns true if the user is found on StopForumSpam.com
	* @throws throws an error if the email or IP is passed and invalid or the IP is not IPv4.
	* 	Stopforumsspam.com does not support IPv6 addresses.
	* @throws throws any error it recieves from the response, including status codes that are not 200
*/
sfs.isSpammer = function (userObject) {
	var deferred = Q.defer();

	var url = sfs.config.url + _.findWhere(sfs.config.routes, { name: 'search' }).path;
	var fail = false;
	_.each(sfs.config.searchParameters, function (parameter) {
		if (userObject[parameter.name]) {
			if (parameter.name === 'email' && userObject[parameter.name] && !validator.isEmail(userObject[parameter.name])) {
				fail = 'email';
			}
			else if (parameter.name === 'ip' && userObject[parameter.name] && !validator.isIP(userObject[parameter.name], 4)) {
				fail = 'ip';
			}
			url += sprintf(parameter.searchAdd, encodeURIComponent(utf8.encode(userObject[parameter.name])));
		}
	});

	if (fail) {
		if (fail === 'email') {
			deferred.reject(new Error('The searched email is not a valid email address'));
		}
		else if (fail === 'ip') {
			deferred.reject(new Error('The searched IP is not a valid IPv4 address'));
		}
	}
	else {
		request(url, function (error, response, body) {
			if (error) { return deferred.reject(error); }
			if (response.statusCode !== 200) { return deferred.reject(new Error('Response Status: ' + response.statusCode + ', ' + body)); }
			var result = false;
			var jsBody = JSON.parse(body);

			_.each(sfs.config.searchParameters, function (parameter) {
				if (userObject[parameter.name] && jsBody[parameter.name].appears > 0) {
					result = JSON.parse(body);
				}
			});
			deferred.resolve(result);
		});
	}

	return deferred.promise;
};

/**
	* Synchronous version of isSpammer
	* Uses ES6 yield trick https://github.com/luciotato/waitfor-ES6#the-funny-thing-is
*/
sfs.isSpammerSync = function* (userObject) {
	yield [sfs.isSpammer, userObject];
};

/**
	* Submits the user to StopForumSpam.com under your API key
	* Requires config.apiKey is set
	* @param userObject must contain properties for each searchParameter
	* 	empty parameters will throw an error
	* @example
	* stopforumspam.Key('some-api-key');
	* // or stopforumspam.config.apiKey = 'some-api-key';
	* stopforumspam.submit({ ip: '123.456.789.100', email: '<EMAIL>', username: 'Spammer!' }, 'Caught You!');
	* @param evidence {string} (optional) you can tell StopForumSpam.com your reasoning if you like
	* @returns Promise
	* @throws throws an error if you have not set the API key
	* @throws throws an error if you don't pass a user object with all of the parameters
	* 	(ip, email, & username)
	* @throws throws any error it recieves from the response, including status codes that are not 200
*/
sfs.submit = function (userObject, evidence) {
	var deferred = Q.defer();
	if (!sfs.config.apiKey) {
		deferred.reject(new Error('You cannot submit spammers without an API Key.'));
	}
	else {
		var url = sfs.config.url + sprintf(_.findWhere(sfs.config.routes, { name: 'submit' }).path, sfs.config.apiKey);
		var error = false;
		_.each(sfs.config.searchParameters, function (parameter) {
			if (!userObject[parameter.name]) {
				error = true;
			}
			else {
				url += sprintf(parameter.searchAdd, encodeURIComponent(utf8.encode(userObject[parameter.name])));
			}
		});
		if (error) {
			deferred.reject(new Error('You must have all search parameters for StopForumSpam.com to accept your submission.'));
		}
		else {
			if (evidence) {
				// unescape in JS is a simple way to convert to UTF-8, which StopForumSpam requires
				url += sprintf('&evidence=%s', encodeURIComponent(utf8.encode(evidence)));
			}
<commit_msg>replace findWhere, findWhere does not exist in lodash 4.x<commit_after>'use strict';

var request = require('request'),
		sprintf = require('sprintf-js').sprintf,
		_ = require('lodash'),
		Q = require('q'),
		utf8 = require('utf8'),
		validator = require('validator');

/**
	* StopForumSpam Module
	* @exports stopforumspam
	* @namespace sfs
*/
var sfs = {
	/**
	* Default Configuration settings for stopforumspam
	*/
	config: {
		url: 'http://stopforumspam.com',
		routes: [{
			name: 'search',
			path: '/api?f=json&nobadusername'	// ignore partial username string search
		},{
			name: 'submit',
			path: '/add.php?api_key=%s'
		}],
		searchParameters: [{
			name: 'ip',
			searchAdd: '&ip=%s',
			submitAdd: '&ip_addr=%s'
		},{
			name: 'email',
			searchAdd: '&email=%s',
			submitAdd: '&email=%s'
		},{
			name: 'username',
			searchAdd: '&username=%s',
			submitAdd: '&username=%s'
		}],
		apiKey: ''
	}
};

/**
	* Checks if a user is a spammer.  Pass only the parameters you wish to search for
	* @param userObject {object} a hashlike object with each of the  parameters to search for.
	* 	Search for as many or as few as you wish.
	* @example
	* stopforumspam.isSpammer({ ip: '123.456.789.100', email: '<EMAIL>', username: 'Spammer!' })
	*   .then(function (result) {
	*   // result if false if not found
	*   // result = {
	*   //   success: 1,
	*   //   username: {
	*   //     lastseen: '2015-03-09 15:22:49',
	*   //     frequency: 3830,
	*   //     appears: 1,
	*   //     confidence: 90.2 } }
	* });
	* @returns Promise which returns true if the user is found on StopForumSpam.com
	* @throws throws an error if the email or IP is passed and invalid or the IP is not IPv4.
	* 	Stopforumsspam.com does not support IPv6 addresses.
	* @throws throws any error it recieves from the response, including status codes that are not 200
*/
sfs.isSpammer = function (userObject) {
	var deferred = Q.defer();

	var url = sfs.config.url + _.find(sfs.config.routes, { name: 'search' }).path;
	var fail = false;
	_.each(sfs.config.searchParameters, function (parameter) {
		if (userObject[parameter.name]) {
			if (parameter.name === 'email' && userObject[parameter.name] && !validator.isEmail(userObject[parameter.name])) {
				fail = 'email';
			}
			else if (parameter.name === 'ip' && userObject[parameter.name] && !validator.isIP(userObject[parameter.name], 4)) {
				fail = 'ip';
			}
			url += sprintf(parameter.searchAdd, encodeURIComponent(utf8.encode(userObject[parameter.name])));
		}
	});

	if (fail) {
		if (fail === 'email') {
			deferred.reject(new Error('The searched email is not a valid email address'));
		}
		else if (fail === 'ip') {
			deferred.reject(new Error('The searched IP is not a valid IPv4 address'));
		}
	}
	else {
		request(url, function (error, response, body) {
			if (error) { return deferred.reject(error); }
			if (response.statusCode !== 200) { return deferred.reject(new Error('Response Status: ' + response.statusCode + ', ' + body)); }
			var result = false;
			var jsBody = JSON.parse(body);

			_.each(sfs.config.searchParameters, function (parameter) {
				if (userObject[parameter.name] && jsBody[parameter.name].appears > 0) {
					result = JSON.parse(body);
				}
			});
			deferred.resolve(result);
		});
	}

	return deferred.promise;
};

/**
	* Synchronous version of isSpammer
	* Uses ES6 yield trick https://github.com/luciotato/waitfor-ES6#the-funny-thing-is
*/
sfs.isSpammerSync = function* (userObject) {
	yield [sfs.isSpammer, userObject];
};

/**
	* Submits the user to StopForumSpam.com under your API key
	* Requires config.apiKey is set
	* @param userObject must contain properties for each searchParameter
	* 	empty parameters will throw an error
	* @example
	* stopforumspam.Key('some-api-key');
	* // or stopforumspam.config.apiKey = 'some-api-key';
	* stopforumspam.submit({ ip: '123.456.789.100', email: '<EMAIL>', username: 'Spammer!' }, 'Caught You!');
	* @param evidence {string} (optional) you can tell StopForumSpam.com your reasoning if you like
	* @returns Promise
	* @throws throws an error if you have not set the API key
	* @throws throws an error if you don't pass a user object with all of the parameters
	* 	(ip, email, & username)
	* @throws throws any error it recieves from the response, including status codes that are not 200
*/
sfs.submit = function (userObject, evidence) {
	var deferred = Q.defer();
	if (!sfs.config.apiKey) {
		deferred.reject(new Error('You cannot submit spammers without an API Key.'));
	}
	else {
		var url = sfs.config.url + sprintf(_.find(sfs.config.routes, { name: 'submit' }).path, sfs.config.apiKey);
		var error = false;
		_.each(sfs.config.searchParameters, function (parameter) {
			if (!userObject[parameter.name]) {
				error = true;
			}
			else {
				url += sprintf(parameter.searchAdd, encodeURIComponent(utf8.encode(userObject[parameter.name])));
			}
		});
		if (error) {
			deferred.reject(new Error('You must have all search parameters for StopForumSpam.com to accept your submission.'));
		}
		else {
			if (evidence) {
				// unescape in JS is a simple way to convert to UTF-8, which StopForumSpam requires
				url += sprintf('&evidence=%s', encodeURIComponent(utf8.encode(evidence)));
			}

{'fraction_non_alphanumeric': 0.14878892733564014, 'fraction_numerical': 0.013360246059207997, 'mean_word_length': 3.6409455842997325, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5224960', 'n_tokens_mistral': 3858, 'n_tokens_neox': 3502, 'n_words': 982}