simple-images-upload/src/middleware/Uploads.js

193 lines
5.0 KiB
JavaScript

import fs, {copyFileSync, mkdirSync, statSync} from 'fs';
import {join, extname} from 'path';
import multer from 'multer';
import sharp from 'sharp';
import {uid} from 'rand-token';
import axios from 'axios';
import Pages from './Pages';
import {getBaseUrl} from '../helpers';
import {pagination, shortUrlSig, shortUrlUri} from '../config';
const checkAndCreateDirectory = async (directory) => {
try {
return statSync(directory);
} catch (err) {
if (err.errno === -2) {
mkdirSync(directory);
} else {
throw err;
}
}
return true;
};
const checkAndCreateDirectories = async (req) => {
const {
user,
} = req;
const baseUrl = getBaseUrl(req);
const baseUploadDir = `${__dirname}/../../uploads/`;
const userUploadDir = join(baseUploadDir, user._id);
const userUri = `${baseUrl}/uploads/${user._id}`;
await checkAndCreateDirectory(baseUploadDir);
await checkAndCreateDirectory(userUploadDir);
return {
userUploadDir,
userUri,
};
};
const resizeImage = async (sourceImage, destImage, w, h) => {
return sharp(sourceImage)
.resize(w, h, {
fit: 'inside',
})
.toFile(destImage);
};
const upload = multer({
storage: multer.diskStorage({}),
fileFilter(multerReq, file, cb) {
const filetypes = /jpeg|jpg|png/;
const mimetype = filetypes.test(file.mimetype);
const filExtname = filetypes.test(
extname(file.originalname).toLowerCase(),
);
if (mimetype && filExtname) {
return cb(null, true);
}
const error = 'Seuls les fichiers de type jpg et png sont acceptés';
req.session.messages.push(error);
return cb(new Error(error));
},
}).single('image');
/**
* Classe permettant la gestion des images
*/
class Uploads extends Pages {
/**
* Méthode permettant d'ajouter un élément à la gallerie d'un utilisateur
* @param {*} req
*/
async postOne(req) {
await new Promise((resolve, reject) => {
upload(req, req.body, (err, data) => {
if (err) {
return reject(err);
}
resolve(data);
});
});
const {
userUploadDir,
userUri,
} = await checkAndCreateDirectories(req);
let ext = req.file.originalname.split('.');
ext = ext[ext.length - 1];
// eslint-disable-next-line max-len
const uploadname = `${uid(4)}_${Buffer.from(req.file.originalname).toString('base64')}.${ext}`;
const originalFileName = uploadname;
const mediumFileName = `medium_${uploadname}`;
const smallFileName = `small_${uploadname}`;
await Promise.all([
copyFileSync(req.file.path, join(userUploadDir, originalFileName)),
resizeImage(
req.file.path,
join(
userUploadDir,
mediumFileName,
),
800,
600,
),
resizeImage(
req.file.path,
join(
userUploadDir,
smallFileName,
),
300,
200,
),
]);
const originalFile = `${userUri}/${originalFileName}`;
// eslint-disable-next-line max-len
const urlshort = await axios.get(`${shortUrlUri}?signature=${shortUrlSig}&action=shorturl&url=${originalFile}&format=json`);
this.pageContent.page.upload = {
originalFile,
mediumFile: `${userUri}/${mediumFileName}`,
smallFile: `${userUri}/${smallFileName}`,
urlshort: urlshort.data.shorturl,
};
return true;
}
/**
* Méthode permettant d'afficher la liste des images d'un utilisateur
* @param {Object} req
*/
async getAll(req) {
const currentPage = Number(req.query.page || 1);
const startAt = (currentPage - 1) * pagination;
const endAt = startAt + pagination;
const listOfFiles = [];
let total = 0;
const {
userUploadDir,
userUri,
} = await checkAndCreateDirectories(req);
const files = fs.readdirSync(userUploadDir)
.map((v) => {
// eslint-disable-next-line max-len
return {name: v, time: statSync(join(userUploadDir, v)).mtime.getTime()};
})
.sort(function(a, b) {
return b.time - a.time;
})
.map(function(v) {
return v.name;
});
for (let i = 0; i < files.length; i += 1) {
const file = files[i];
if (file.indexOf('medium_') === 0) {
total += 1;
if (listOfFiles.length < endAt) {
console.log('file:', statSync(join(userUploadDir, file)));
listOfFiles.push({
originalFile: `${userUri}/${file.replace('medium_', '')}`,
mediumFile: `${userUri}/${file}`,
smallFile: `${userUri}/${file.replace('medium_', 'small_')}`,
time: statSync(join(userUploadDir, file)).mtime.getTime(),
});
}
}
}
this.pageContent.page.images = listOfFiles.slice(startAt);
this.pageContent.page.currentPage = currentPage;
// eslint-disable-next-line max-len
this.pageContent.page.totalPages = Math.floor(total / pagination) + (total % pagination > 0 ? 1 : 0);
}
}
module.exports = Uploads;