0

Help! No mater what I do I cant seem to give an image a custom file name using multer-s3. I have this really cool custom function that uploads images to s3. It works fine if I use the files original file name however when I try to use a custom file name it will upload the first image three times under the new file names. If anyone has any suggestions, insights or knows why this doesnt work. I'd apprecaite it.

var AWS = require("../AWS").AWS;
var s3 = require("../AWS").s3;
var multer = require("multer");
var multerS3 = require("multer-s3");
function generateKey(file, newFileName) {
  //   var finalFileName = newFileName + "." + file.originalname.split(".")[1];
  var finalFileName = newFileName + "." + file.originalname.split(".")[1];
  return finalFileName;
}
async function singleFileUpload(req, res, newFileName, bucketName, fieldName) {
  var fileFilter = (req, file, cb) => {
    var ext = file.originalname.split(".").slice(-1);
    if (ext == "jpg" || ext == "mp4" || ext == "wmv") {
      cb(null, true);
    } else {
      cb(new Error("invalid file format"), false);
    }
  };
  var upload = multer({
    fileFilter,
    storage: multerS3({
      s3,
      bucket: bucketName,
      acl: "public-read",
      metadata: function(req, file, cb) {
        cb(null, { test: "testing_meta_data!" });
      },
      //   key: function(req, file, cb) {
      //     // let fileExtension = file.originalname.split(".")[1];
      //     let finalFileName = file.originalname;
      //     console.log(finalFileName);
      //     cb(null, finalFileName);
      //   }
      key: function(req, file, cb) {
        var newKey = generateKey(file, newFileName);
        console.log("newKey", newKey);
        cb(null, newKey);
      }
    })
  });
  console.log(fieldName);
  var singleUpload = upload.any(fieldName);

  await singleUpload(req, res, error => {
    if (error) {
      throw error;
    } else {
      console.log("it worked");
    }
  });
}

Than i call my custom function like so

singleFileUpload(req, res, "myNewFileName" "mybucketName", fieldName);

I call this several times because I want the ability to rename each file. Thanks.

codernoob8
  • 434
  • 1
  • 9
  • 24

2 Answers2

1

this code works.

var upload = multer({
  storage: multerS3({
    s3,
    bucket: process.env.BUCKET_NAME,
    metadata: function(req, file, cb) {
      cb(null, { fieldName: file.fieldname });
    },
    key: function(req, file, cb) {
      cb(null, reNameFiles(file, req.body.id, req.originalUrl));
    },
    contentType: multerS3.AUTO_CONTENT_TYPE
  })
});
function reNameFiles(file, id, type) {
  let lastIndex = type.lastIndexOf("/");
  let videoType = type.slice(lastIndex + 1);
  let finalFileName = "";
  if (videoType == "templateMainVideoThumbnail") {
    finalFileName =
      "templates/" +
      id +
      "/main/original/" +
      "video" +
      "." +
      file.originalname.split(".").slice(-1);
    return finalFileName;
  }
  for (let i = 1; i <= 4; i++) {
    if (videoType === "templateExampleVideo" + i) {
      finalFileName =
        "templates/" +
        id +
        "/example" +
        i.toString() +
        "/original/example" +
        i.toString() +
        "." +
        file.originalname.split(".").slice(-1);
      return finalFileName;
    }
  }
  for (let j = 1; j <= 4; j++) {
    if (videoType === "templateExamplePoster" + j) {
      finalFileName =
        "templates/" +
        id +
        "/example" +
        j.toString() +
        "/poster." +
        file.originalname.split(".").slice(-1);
      return finalFileName;
    }
  }
  if (videoType === "templatePosterImage") {
    finalFileName =
      "templates/" +
      id +
      "/poster/poster" +
      "." +
      file.originalname.split(".").slice(-1);
    return finalFileName;
  }
  if (videoType == "templateThumbnailFiles") {
    let cleanOrginalName = file.originalname.replace(/\s/g, "");
    finalFileName =
      "templates/" + id + "/thumbnails/" + Date.now() + cleanOrginalName;
    return finalFileName;
  }
  if (videoType == "stockMainVideoThumbnail") {
    finalFileName =
      "stock/" +
      id +
      "/main/original/" +
      "video" +
      "." +
      file.originalname.split(".").slice(-1);
    return finalFileName;
  }
  if (videoType == "stockPosterImage") {
    finalFileName =
      "stock/" +
      id +
      "/poster/poster" +
      "." +
      file.originalname.split(".").slice(-1);
    return finalFileName;
  }
  if (videoType == "stockDownloadableFiles") {
    finalFileName = "stock/" + id + "/downloadable/" + file.originalname;
    return finalFileName;
  }
}
codernoob8
  • 434
  • 1
  • 9
  • 24
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Dharman Mar 19 '20 at 23:07
0

I am using this approach for renaming and uploading my file through s3-multer you can use the same:

key: function (req, file, cb) {
  file.originalname = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)+path.extname(file.originalname);
  var fullPath = 'public/signature/'+ file.originalname;
  cb(null, fullPath)
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Divyesh pal
  • 952
  • 1
  • 11
  • 17