192 lines
5 KiB
JavaScript
192 lines
5 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;
|