<commit_before>/**
 *	Class for fetching an image stored on Contentful servers, resizing them
 *	and storing them on the local running server.
 *
 *	@class ImageProcessor
 *	@static
 */
ImageProcessor = {

	/**
	 *	Meteor Fiber needed for making async calls
	 */
	Fiber: false,

	/**
	 *	Imagemagick module for resizing images
	 */
	Imagemagick: false,

	/**
	 *	Server side collection to store information about
	 *	processed image assets
	 */
	imageCollection: new Mongo.Collection(CFConfig.processedImageCollectionName),

	/**
	 *	Incoming cursor for existing Contentful assets
	 */
	contentfulAssets: false,

	/**
	 *	Function to iterate through each contentful asset
	 *
	 *	@method 	init
	 */
	init: function() {

		this.Fiber = Meteor.npmRequire('fibers');
		this.Imagemagick = Meteor.npmRequire('node-imagemagick');

		if(!Meteor.npmRequire) {
			console.log('Image processor init, meteor npm require not found.');
		}

		var self = this;

		this.Fiber(function() {
			this.contentfulAssets = Contentful.collections.assets.find({}).fetch();
			_.each(this.contentfulAssets, function(asset) {

				self.saveImagesFromAsset(asset, function(result) {
					console.log(result);
				});

			});
		}).run();
	},

	/**
	 *	Function to process an image, creating resized copies and saving them to disk
	 *
	 *	@method 	saveImageFromAsset
	 *	@param  	{Object} asset - the Conteontful assset 
	 *	@param 		{Object} callback - the callback function on save
	 */
	saveImagesFromAsset: function(asset, callback) {

		var self 		= this,
			assetId 	= asset.sys.id,
			sourceUrl 	= asset.fields.file.url;

		this.readRemoteFileFromUrl(sourceUrl)
		.then(function(result) {

			self.writeFile(result.data, '/var/www/matt<EMAIL>', Date.now() + '.jpg');			

		}).fail(function(error) {

			console.log(error);

		});
	},

	/**
	 *	Function to read the contents of a remote resource
	 *
	 *	@method 	readRemoteFileFromUrl
	 *	@param 		{String} url - the url for the resource
	 *	@return  	{Object} - a resolved or rejected promise
	 */
	readRemoteFileFromUrl: function(url) {
		var deferred 	= Q.defer(),
			http 		= Npm.require('http'),
			url 		= 'http:' + url;
		/**
		 *	We need to use the nodejs http module,
		 *	since Meteor HTTP can only deal with 
		 *	String and Json data.
		 */
		var req = http.get(url, function(response) {

			/**
			 *	Buffer to store incoming stream of data
			 */ 
			var buffer = new Buffer('', 'binary');

			/**
			 *	When data comes in, ammend the buffer
			 */
			response.on('data', function(chunk) {	
				buffer = Buffer.concat([buffer, chunk]);
			});

			/**
			 *	If there was an error
			 */
			response.on('error', function(error) {
				deferred.reject({
					status: 'error',
					data: error
				});
			});

			/**
			 *	Download complete
			 */
			response.on('end', function() {
				deferred.resolve({
					status: 'ok',
					data: buffer
				});
			});
		});

		return deferred.promise;
	},

	/**
	 *	Function to write out data to the filesystem
	 *
	 *	@method 	writeFile
	 *	@param   	{Object} data - the data to be written
	 *	@param 		{String} path - the filesystem path
	 *	@param 		{String} name - the filename
	 *	@return 	{Object} a promise resolved or rejected
	 */
	writeFile: function(data, path, name) {

		var deferred 	= Q.defer(),
			fs 			= Npm.require('fs'),
			start 		= Date.now(),
			end; 

		fs.writeFile(path + '/' + name, data, function(error) {
			if(error) {
				deferred.reject({
					status: 'error',
					data: error
				});
			}
			else {
				end = Date.now();
				deferred.resolve({
					status: 'ok',
					data: {
						time: (end - start) + ' milliseconds'
					}
				});
			}
		});

		return deferred.promise;
	}

};<commit_msg>Imageprocessor can now resize images.<commit_after>/**
 *	Class for fetching an image stored on Contentful servers, resizing them
 *	and storing them on the local running server.
 *
 *	@class ImageProcessor
 *	@static
 */
ImageProcessor = {

	/**
	 *	Meteor Fiber needed for making async calls
	 */
	Fiber: false,

	/**
	 *	Imagemagick module for resizing images
	 */
	Imagemagick: false,

	/**
	 *	Server side collection to store information about
	 *	processed image assets
	 */
	imageCollection: new Mongo.Collection(CFConfig.processedImageCollectionName),

	/**
	 *	Incoming cursor for existing Contentful assets
	 */
	contentfulAssets: false,

	/**
	 *	Function to iterate through each contentful asset
	 *
	 *	@method 	init
	 */
	init: function() {

		/**
		 *	Required meteor npm modules
		 */
		this.Fiber = Meteor.npmRequire('fibers');
		this.Imagemagick = Meteor.npmRequire('node-imagemagick');

		if(!Meteor.npmRequire) {
			console.log('Image processor init, meteor npm require not found.');
		}

		var self = this;

		this.Fiber(function() {
			this.contentfulAssets = Contentful.collections.assets.find({}).fetch();
			_.each(this.contentfulAssets, function(asset) {

				self.saveImagesFromAsset(asset, function(result) {
					console.log(result);
				});

			});
		}).run();
	},

	/**
	 *	Function to process an image, creating resized copies and saving them to disk
	 *
	 *	@method 	saveImageFromAsset
	 *	@param  	{Object} asset - the Conteontful assset 
	 *	@param 		{Object} callback - the callback function on save
	 */
	saveImagesFromAsset: function(asset, callback) {

		var self 		= this,
			assetId 	= asset.sys.id,
			sourceUrl 	= asset.fields.file.url,
			fs 			= Meteor.npmRequire('fs');

		this.readRemoteFileFromUrl(sourceUrl)
		.then(function(result) {

			/**
			 *	Resize the fetched image
			 */
			self.Imagemagick.resize({
				srcData: result.data,
				width: 256
			}, function(error, stdout, stderr) {

				if(error || stderr) throw error;

				//fs.writeFileSync('/var/www/mattfinucane.com/' + Date.now() + '.jpg', stdout, 'binary');
				self.writeFile(stdout, '/var/www/mattfinucane.com', Date.now() + '.jpg');
			});


		}).fail(function(error) {

			console.log('Image asset save failed.')

		});
	},

	/**
	 *	Function to write out data to the filesystem
	 *
	 *	@method 	writeFile
	 *	@param   	{Object} data - the data to be written
	 *	@param 		{String} path - the filesystem path
	 *	@param 		{String} name - the filename
	 *	@return 	{Object} a promise resolved or rejected
	 */
	writeFile: function(data, path, name) {

		var deferred 	= Q.defer(),
			fs 			= Npm.require('fs');

		fs.writeFileSync(path + '/' + name, data, 'binary', function(error) {
			if(error) {
				deferred.reject({
					status: 'error',
					data: error
				});
			}
			else {
				end = Date.now();
				deferred.resolve({
					status: 'ok'
				});
			}
		});

		return deferred.promise;
	},

	/**
	 *	Function to read the contents of a remote resource
	 *
	 *	@method 	readRemoteFileFromUrl
	 *	@param 		{String} url - the url for the resource
	 *	@return  	{Object} - a resolved or rejected promise
	 */
	readRemoteFileFromUrl: function(url) {
		var deferred 	= Q.defer(),
			http 		= Npm.require('http'),
			url 		= 'http:' + url;
		/**
		 *	We need to use the nodejs http module,
		 *	since Meteor HTTP can only deal with 
		 *	String and Json data.
		 */
		var req = http.get(url, function(response) {

			/**
			 *	Buffer to store incoming stream of data
			 */ 
			//var buffer = new Buffer('', 'binary');
			var data = '';

			/**
			 *	Expecting a binary encoded response
			 */
			response.setEncoding('binary');

			/**
			 *	When data comes in, ammend the buffer
			 */
			response.on('data', function(chunk) {	
				//buffer = Buffer.concat([buffer, chunk]);
				data += chunk;
			});

			/**
			 *	If there was an error
			 */
			response.on('error', function(error) {

				console.log('image fetch error');

				deferred.reject({
					status: 'error',
					data: error
				});
			});

			/**
			 *	Download complete
			 */
			response.on('end', function() {
				deferred.resolve({
					status: 'ok',
					data: data
				});
			});
		});

		return deferred.promise;
	}
};
{'fraction_non_alphanumeric': 0.13897319170460293, 'fraction_numerical': 0.00037936267071320183, 'mean_word_length': 2.7465656087162484, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1777235', 'n_tokens_mistral': 3150, 'n_tokens_neox': 2529, 'n_words': 682}