Я хочу загрузить несколько файлов в облако Google и сохранить строки URL-адресов в mongodb - PullRequest
0 голосов
/ 05 августа 2020

Какие изменения мне нужно внести, чтобы продолжить эту задачу. Документации о том, как загрузить несколько файлов в облако Google, не так много. У меня есть некоторый опыт работы с nodejs, пожалуйста, поделитесь. Я могу сделать это для одной загрузки, но не для множественной загрузки. Этот код в основном должен делать то, что написано в вопросе

Вот мой маршрут

router.post('/:pid/images',
fileUpload.multer.array('images', 6),
fileUpload.sendUploadToGCS,
postsControllers.addImagestoPost);

Вот мой файлUpload. js

const Multer = require('multer');
const { uuid } = require('uuidv4');
const {Storage} = require('@google-cloud/storage');
const path = require('path');

const MIME_TYPE_MAP = {
  'image/png': 'png',
  'image/jpeg': 'jpeg',
  'image/jpg': 'jpg',
};

const gc = new Storage({
  keyFilename: path.join(__dirname,'../########.json'),
  projectId: '#####'
});

const craigFilesBucket = gc.bucket('craig-files');

function getPublicUrl(filename) {
  return `https://storage.googleapis.com/craig-files/${filename}`;
}

function sendUploadToGCS(req, res, next){
  if(!req.file){
    return next();
  }

  const gcsname = uuid() + req.file.originalname;
  const file = craigFilesBucket.file(gcsname);

  const stream = file.createWriteStream({
    metadata: {
      contentType: req.file.mimetype,
    },
    resumable: false
  });

  stream.on('error', err =>{
    req.file.cloudStorageError = err;
    next(err);
  });

  stream.on('finish', async () => {
    req.file.cloudStorageObject = gcsname;
    await file.makePublic();
    req.file.cloudStoragePublicUrl = getPublicUrl(gcsname);
    next();
  });

  stream.end(req.file.buffer);
}

const multer = Multer({
  storage: Multer.MemoryStorage,
  limits: {
    fileSize: 10 * 1024 * 1024,   // no longer than 10mb
  }
});

module.exports = {
  getPublicUrl,
  sendUploadToGCS,
  multer
};

Вот мой контроллер

const addImagestoPost = async (req, res, next) =>{
  const errors = validationResult(req);
  if(!errors.isEmpty()){
    return next(new HttpError('Invalid inputs passed, please check your data.', 422))
  }

  const postId = req.params.pid;

  let post;
  try{
    post = await Post.findById(postId);
  }catch(err){
    const error = new HttpError(
      'Something went wrong could not update post',
      500
    );
    return next(error);
  }

  if(!req.file || !req.file.cloudStoragePublicUrl){
    return next(new HttpError('cloudStoragePublicUrl err.', 422))
  }

  post.images.push(req.file.cloudStoragePublicUrl);

  try{
    await post.save();
  }catch(err){
    const error = new HttpError(
      'Something went wrong, could not update post', 500
    )
  }

  res.status(200).json({post: post.toObject({getters: true})})
}

1 Ответ

0 голосов
/ 07 августа 2020

Сам API не поддерживает многократную загрузку файлов. Поэтому, если вы можете загрузить один файл, я предлагаю реализовать какой-нибудь метод, который будет oop работать с вашими файлами.

Вы также можете взглянуть на «удобный метод» Bucket.upload, что я считаю очень хорошим эквивалентом File.createWriteStream.

...