<commit_before>/*!
 * node-imager
 * Copyright(c) 2012 <NAME> <<EMAIL>>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var gm = require('gm').subClass({ imageMagick: true })
  , fs = require('fs')
  , path = require('path')
  , mime = require('mime')
  , pkgcloud = require('pkgcloud')
  , knox = require('knox')
  , async = require('async')
  , os = require('os')
  , _ = require('underscore');

var debug, config, storage, uploadedFiles = [];
var tempDir = path.normalize(os.tmpDir() + path.sep);
var contentType = {
  'image/jpeg': '.jpg',
  'image/jpg': '.jpg',
  'image/png': '.png',
  'image/gif': '.gif'
};

/**
 * Initialize Imager with config
 *
 * @param {Object} config
 * @param {Array} storage
 * @return {Imager}
 * @api public
 */

var Imager = module.exports = function Imager (config, storage) {
  if (!config || typeof config !== 'object') {
    throw new Error('Please provide the config');
  }

  if (!config.storage) {
    throw new Error('Please specify a storage');
  }

  if (typeof storage === 'undefined') {
    throw new Error('Please specify the storage');
  }

  if (typeof storage === 'string') {
    storage = [storage];
  }

  for (var i in storage) {
    if (!config.storage[storage[i]]) {
      throw new Error('The storage you have specified does not exist');
    }
  }

  debug = config.debug;

  this.config = config;
  this.storage = storage;
  this.uploadedFiles = [];
  this.clientCache = {};
};


Imager.prototype = {

  /**
   * Uploads variants to the provided storage
   *
   * @param {Array} files
   * @param {Function} callback
   * @param {String} variant
   * @return {Imager}
   * @api public
   */

  upload: function (files, callback, variant) {
    var self = this;

    // to check if the files are local
    if (Array.isArray(files) && typeof files[0] === 'string') {
      async.map(files, getFileInfo, function (err, result) {
        files = result;
      });
    } else if (!Array.isArray(files) && typeof files === 'string') {
      files = files.split();
      async.map(files, getFileInfo, function (err, result) {
        files = result;
      });
    }

    if (!variant) {
      variant = callback
      callback = function () {}
    }

    if (typeof variant !== 'string' && !this.config.variants.default) {
      throw new Error('Please specify a proper variant OR provide a default');
    }

    if (!variant && this.config.variants.default) {
      variant = 'default';
    }

    if (typeof variant === 'string' && !this.config.variants[variant]) {
      throw new Error('Please provide a variant which you have specified in the config file');
    }

    variant = self.config.variants[variant];

    var prepare = function (file, fn) {
      var ct = file['type'] || file.headers['content-type']
      var filename = variant.keepNames ? path.basename(file.name) :
        Math.round(new Date().getTime()) + contentType[ct];

      self.prepareUpload(file, filename, variant, fn);
    };

    async.forEach(files, prepare, function (err) {
      if (err) return callback(err);
      callback(null, self.cdnUri, self.uploadedFiles);
    });

    return this;
  },

  /**
   * Remove all variants from the provided storage
   *
   * @param {String|Array} files
   * @param {Function} callback
   * @param {String} variant
   * @return {Imager}
   * @api public
   */

  remove: function (files, callback, variant) {
    if (!variant) {
      variant = callback
      callback = function () {}
    }

    if (typeof variant !== 'string' && !this.config.variants.default) {
      throw new Error('Please specify a proper variant to remove the files');
    }

    if (!variant && this.config.variants.default) {
      variant = 'default';
    }

    if (typeof variant === 'string' && !this.config.variants[variant]) {
      throw new Error('Please provide a variant which you have specified in the config file');<commit_msg>Eliminated a race condition in upload() method (with async.map).<commit_after>/*!
 * node-imager
 * Copyright(c) 2012 <NAME> <<EMAIL>>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var gm = require('gm').subClass({ imageMagick: true })
  , fs = require('fs')
  , path = require('path')
  , mime = require('mime')
  , pkgcloud = require('pkgcloud')
  , knox = require('knox')
  , async = require('async')
  , os = require('os')
  , _ = require('underscore');

var debug, config, storage, uploadedFiles = [];
var tempDir = path.normalize(os.tmpDir() + path.sep);
var contentType = {
  'image/jpeg': '.jpg',
  'image/jpg': '.jpg',
  'image/png': '.png',
  'image/gif': '.gif'
};

/**
 * Initialize Imager with config
 *
 * @param {Object} config
 * @param {Array} storage
 * @return {Imager}
 * @api public
 */

var Imager = module.exports = function Imager (config, storage) {
  if (!config || typeof config !== 'object') {
    throw new Error('Please provide the config');
  }

  if (!config.storage) {
    throw new Error('Please specify a storage');
  }

  if (typeof storage === 'undefined') {
    throw new Error('Please specify the storage');
  }

  if (typeof storage === 'string') {
    storage = [storage];
  }

  for (var i in storage) {
    if (!config.storage[storage[i]]) {
      throw new Error('The storage you have specified does not exist');
    }
  }

  debug = config.debug;

  this.config = config;
  this.storage = storage;
  this.uploadedFiles = [];
  this.clientCache = {};
};


Imager.prototype = {

  /**
   * Uploads variants to the provided storage
   *
   * @param {Array} files
   * @param {Function} callback
   * @param {String} variant
   * @return {Imager}
   * @api public
   */

  upload: function (files, callback, variant) {
    var self = this;

    if (!variant) {
      variant = callback
      callback = function () {};
    }

    if (typeof variant !== 'string' && !this.config.variants.default) {
      throw new Error('Please specify a proper variant OR provide a default');
    }

    if (!variant && this.config.variants.default) {
      variant = 'default';
    }

    if (typeof variant === 'string' && !this.config.variants[variant]) {
      throw new Error('Please provide a variant which you have specified in the config file');
    }

    if (!files) {
      throw new Error('Please provide the files to upload.');
    } else if (typeof files === 'string') {
      files = [files];
    }

    variant = this.config.variants[variant];

    async.map(files, getFileInfo, function (err, files) {
      if (err) return callback(err);

      var prepare = function (file, fn) {
        var ct = file['type'] || file.headers['content-type'];
        var filename = variant.keepNames ? path.basename(file.name) :
          Math.round(new Date().getTime()) + contentType[ct];

        self.prepareUpload(file, filename, variant, fn);
      };

      async.forEach(files, prepare, function (err) {
        if (err) return callback(err);
        callback(null, self.cdnUri, self.uploadedFiles);
      });
    });

    return this;
  },

  /**
   * Remove all variants from the provided storage
   *
   * @param {String|Array} files
   * @param {Function} callback
   * @param {String} variant
   * @return {Imager}
   * @api public
   */

  remove: function (files, callback, variant) {
    if (!variant) {
      variant = callback
      callback = function () {};
    }

    if (typeof variant !== 'string' && !this.config.variants.default) {
      throw new Error('Please specify a proper variant to remove the files');
    }

    if (!variant && this.config.variants.default) {
      variant = 'default';
    }

    if (typeof variant === 'string' && !this.config.variants[variant]) {
      throw new Error('Please provide a variant which you have specified in the config file');
{'fraction_non_alphanumeric': 0.15411490683229814, 'fraction_numerical': 0.0011645962732919255, 'mean_word_length': 2.8858722976370035, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, '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': '1012106', 'n_tokens_mistral': 2387, 'n_tokens_neox': 2314, 'n_words': 687}