<commit_before>var _ = require('lodash');
var async = require('async');
var crypto = require('crypto');
var path = require('path');
var fs = require('fs');

module.exports = function(self, options) {

  // Accept a file as submitted by an HTTP file upload.
  // req is checked for permissions. The callback receives an error if any
  // followed by a file object.
  //
  // "file" should be an object with "name" and "path" properties.
  // "name" must be the name the user claims for the file, while "path"
  // must be the actual full path to the file on disk and need not have
  // any file extension necessarily.
  //
  // (Note that when using Express to handle file uploads,
  // req.files['yourfieldname'] will be such an object as long as you
  // configure jquery fileupload to submit one per request.)

  self.accept = function(req, file, callback) {
    var extension = path.extname(file.name);
    if (extension && extension.length) {
      extension = extension.substr(1);
    }
    extension = extension.toLowerCase();
    // Do we accept this file extension?
    var group = self.getFileGroup(extension);
    if (!group) {
      var accepted = _.union(_.pluck(self.fileGroups, 'extensions'));
      return callback("File extension not accepted. Acceptable extensions: " + accepted.join(","));
    }
    var image = group.image;
    var info = {
      _id: self.apos.utils.generateId(),
      length: file.length,
      group: group.name,
      createdAt: new Date(),
      name: self.apos.utils.slugify(path.basename(file.name, path.extname(file.name))),
      title: self.apos.utils.sortify(path.basename(file.name, path.extname(file.name))),
      extension: extension,
      type: 'attachment'
    };

    function permissions(callback) {
      // TODO port permissions
      return callback(self.apos.permissions.can(req, 'edit-attachment') ? null : 'forbidden');
    }

    function md5(callback) {
      return self.apos.utils.md5File(file.path, function(err, md5) {
        if (err) {
          return callback(err);
        }
        info.md5 = md5;
        return callback(null);
      });
    }

    function upload(callback) {
      if (image) {
        // For images we correct automatically for common file extension mistakes
        return self.uploadfs.copyImageIn(file.path, '/attachments/' + info._id + '-' + info.name, function(err, result) {
          if (err) {
            return callback(err);
          }
          info.extension = result.extension;
          info.width = result.width;
          info.height = result.height;
          if (info.width > info.height) {
            info.landscape = true;
          } else {
            info.portrait = true;
          }
          return callback(null);
        });
      } else {
        // For non-image files we have to trust the file extension
        // (but we only serve it as that content type, so this should
        // be reasonably safe)
        return self.uploadfs.copyIn(file.path, '/attachments/' + info._id + '-' + info.name + '.' + info.extension, callback);
      }
    }

    function remember(callback) {
      info.ownerId = self.apos.permissions.getEffectiveUserId(req);
      info.createdAt = new Date();
      return self.db.insert(info, callback);<commit_msg>Add an insert method to apostrophe-attachments to match pieces behaviour<commit_after>var _ = require('lodash');
var async = require('async');
var crypto = require('crypto');
var path = require('path');
var fs = require('fs');

module.exports = function(self, options) {

  // Accept a file as submitted by an HTTP file upload.
  // req is checked for permissions. The callback receives an error if any
  // followed by a file object.
  //
  // "file" should be an object with "name" and "path" properties.
  // "name" must be the name the user claims for the file, while "path"
  // must be the actual full path to the file on disk and need not have
  // any file extension necessarily.
  //
  // (Note that when using Express to handle file uploads,
  // req.files['yourfieldname'] will be such an object as long as you
  // configure jquery fileupload to submit one per request.)

  self.accept = function(req, file, callback) {
    self.insert(req, file, {}, callback);
  };

  // Extending the functionnality of `accept`. Provide a way to bypass
  // permissions for backend tasks purposes.

  self.insert = function(req, file, options, callback) {
    var extension = path.extname(file.name);
    if (extension && extension.length) {
      extension = extension.substr(1);
    }
    extension = extension.toLowerCase();
    // Do we accept this file extension?
    var group = self.getFileGroup(extension);
    if (!group) {
      var accepted = _.union(_.pluck(self.fileGroups, 'extensions'));
      return callback("File extension not accepted. Acceptable extensions: " + accepted.join(","));
    }
    var image = group.image;
    var info = {
      _id: self.apos.utils.generateId(),
      length: file.length,
      group: group.name,
      createdAt: new Date(),
      name: self.apos.utils.slugify(path.basename(file.name, path.extname(file.name))),
      title: self.apos.utils.sortify(path.basename(file.name, path.extname(file.name))),
      extension: extension,
      type: 'attachment'
    };

    function permissions(callback) {
      if (options && options.permissions === false) {
        return callback(null);
      } else {
        // TODO port permissions
        return callback(self.apos.permissions.can(req, 'edit-attachment') ? null : 'forbidden');
      }
    }

    function md5(callback) {
      return self.apos.utils.md5File(file.path, function(err, md5) {
        if (err) {
          return callback(err);
        }
        info.md5 = md5;
        return callback(null);
      });
    }

    function upload(callback) {
      if (image) {
        // For images we correct automatically for common file extension mistakes
        return self.uploadfs.copyImageIn(file.path, '/attachments/' + info._id + '-' + info.name, function(err, result) {
          if (err) {
            return callback(err);
          }
          info.extension = result.extension;
          info.width = result.width;
          info.height = result.height;
          if (info.width > info.height) {
            info.landscape = true;
          } else {
            info.portrait = true;
          }
          return callback(null);
        });
      } else {
        // For non-image files we have to trust the file extension
        // (but we only serve it as that content type, so this should
        // be reasonably safe)
        return self.uploadfs.copyIn(file.path, '/attachments/' + info._id + '-' + info.name + '.' + info.extension, callback);
      }
    }

    function remember(callback) {
      if (options && options.permissions !== false) {
        info.ownerId = self.apos.permissions.getEffectiveUserId(req);
      }
      info.createdAt = new Date();
      return self.db.insert(info, callback);
{'fraction_non_alphanumeric': 0.12251608291636884, 'fraction_numerical': 0.0017155110793423873, 'mean_word_length': 2.461652647204354, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '1360648', 'n_tokens_mistral': 1967, 'n_tokens_neox': 1970, 'n_words': 606}