Some changes...

This commit is contained in:
Damien Broqua 2023-09-25 00:31:06 +02:00
parent 2ff0798632
commit d02887b2da
16 changed files with 108 additions and 140 deletions

9
package-lock.json generated
View file

@ -18,6 +18,7 @@
"express": "^4.18.2",
"express-session": "^1.17.3",
"knacss": "^8.0.4",
"luxon": "^3.4.3",
"mongoose": "^7.5.2",
"mongoose-unique-validator": "^4.0.0",
"multer": "^1.4.5-lts.1",
@ -5046,6 +5047,14 @@
"node": ">=10"
}
},
"node_modules/luxon": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.3.tgz",
"integrity": "sha512-tFWBiv3h7z+T/tDaoxA8rqTxy1CHV6gHS//QdaH4pulbq/JuBSGgQspQQqcgnwdAx6pNI7cmvz5Sv/addzHmUg==",
"engines": {
"node": ">=12"
}
},
"node_modules/make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",

View file

@ -8,6 +8,7 @@
"build": "npx babel ./src --out-dir dist --copy-files",
"sass": "npx sass sass/index.scss public/css/main.css -s compressed --color",
"watch": "npx nodemon -e js,scss",
"build:all": "npm-run-all build sass",
"start": "node ./dist/bin/www",
"lint": "npx eslint ./src --ext .js",
"lint:fix": "npx eslint --fix ./src --ext .js",
@ -56,6 +57,7 @@
"express": "^4.18.2",
"express-session": "^1.17.3",
"knacss": "^8.0.4",
"luxon": "^3.4.3",
"mongoose": "^7.5.2",
"mongoose-unique-validator": "^4.0.0",
"multer": "^1.4.5-lts.1",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -6,7 +6,7 @@
border: 2px solid var(--border-color);
background-color: var(--bg-alternate-color);
display: flex;
flex-direction: row;
flex-direction: column;
justify-content: center;
align-items: center;
@include transition() {}

View file

@ -17,8 +17,6 @@ import {trustProxy, env, mongoDbUri, secret, port} from './config';
import {isXhr, getBaseUrl} from './helpers';
// import indexmkactRouterApiV1 from "./routes/api/v1/contact";
passportConfig(passport);
mongoose.set('strictQuery', false);

View file

@ -1,3 +1,5 @@
import {DateTime} from 'luxon';
export default (req, res, error, page, redirectTo) => {
if (error) {
res.status(500);
@ -13,6 +15,7 @@ export default (req, res, error, page, redirectTo) => {
query: {},
user: req.user || null,
error,
DateTime,
});
}

View file

@ -1,23 +0,0 @@
/**
* Classe permettant la gestion des erreurs personilisées
*/
class ErrorEvent extends Error {
/**
* @param {Number} errorCode
* @param {String} title
* @param {Mixed} ...params
*/
constructor(errorCode, title, ...params) {
super(...params);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, ErrorEvent);
}
this.errorCode = parseInt(errorCode, 10);
this.title = title;
this.date = new Date();
}
}
export default ErrorEvent;

View file

@ -1,39 +0,0 @@
/**
* Fonction permettant de formater une réponse basée sur la méthode utilisée
* @param {Object} req
* @param {Object} res
* @param {Object} data
*
* @return {Object}
*/
export const sendResponse = (req, res, data) => {
let status = 200;
const path = req.route.path.split('/');
switch (req.method) {
case 'GET':
// INFO: On regarde de quel type de get il s'agit (liste ou item)
if (path[path.length - 1].indexOf(':') === 0) {
// INFO: Cas d'un item
status = !data ? 404 : 200;
} else {
// INFO: Cas d'une liste
status =
data.rows === undefined || data.rows.length > 0 ? 200 : 204;
}
return res.status(status).json(data).end();
case 'PATCH':
return res.status(200).json(data).end();
case 'DELETE':
return res.status(200).json(data).end();
case 'POST':
return res.status(201).json(data).end();
default:
return res.status(500).json({message: 'Not implemented'});
}
};
export default (res, page) => {
res.status(200).render('index', page.render());
};

View file

@ -8,7 +8,6 @@ class Auth extends Pages {
/**
* Méthode permettant de créer un nouvel utilisateur
* @param {Req} req
* @param {Function} callback
*
* @return {Function}
*/

View file

@ -1,6 +1,7 @@
// import moment from 'moment';
import config from '../config';
import {getBaseUrl} from '../helpers';
import {DateTime} from 'luxon';
/**
* Classe permettant de gérer les page du back office
@ -21,7 +22,6 @@ class Pages {
viewname: `pages/${viewname}`,
baseUrl: getBaseUrl(req),
currentPage: req.originalUrl.split('?')[0],
// moment,
};
this.user = null;
@ -50,6 +50,7 @@ class Pages {
this.pageContent.user = this.user;
this.pageContent.pagename = this.pagename;
this.pageContent.messages = this.req.session.messages;
this.pageContent.DateTime = DateTime;
this.req.session.messages = [];

View file

@ -24,6 +24,24 @@ const checkAndCreateDirectory = async (directory) => {
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, {
@ -32,50 +50,36 @@ const resizeImage = async (sourceImage, destImage, w, h) => {
.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 {
/**
* @param {Object} req
* @param {String} viewname
*/
constructor(req, viewname) {
super(req, viewname);
this.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');
const baseUrl = getBaseUrl(req);
this.baseUploadDir = `${__dirname}/../../uploads/`;
this.userUploadDir = join(this.baseUploadDir, req.user._id);
this.userUri = `${baseUrl}/uploads/${req.user._id}`;
}
/**
*
* Méthode permettant d'ajouter un élément à la gallerie d'un utilisateur
* @param {*} req
* @param {*} callback
*/
async postOne(req) {
await new Promise((resolve, reject) => {
this.upload(req, req.body, (err, data) => {
upload(req, req.body, (err, data) => {
if (err) {
return reject(err);
}
@ -84,8 +88,10 @@ class Uploads extends Pages {
});
});
checkAndCreateDirectory(this.baseUploadDir);
checkAndCreateDirectory(this.userUploadDir);
const {
userUploadDir,
userUri,
} = await checkAndCreateDirectories(req);
let ext = req.file.originalname.split('.');
ext = ext[ext.length - 1];
@ -95,31 +101,32 @@ class Uploads extends Pages {
const mediumFileName = `medium_${uploadname}`;
const smallFileName = `small_${uploadname}`;
copyFileSync(req.file.path, join(this.userUploadDir, originalFileName));
await resizeImage(
req.file.path,
join(
this.userUploadDir,
mediumFileName,
),
800,
600,
);
await resizeImage(
req.file.path,
join(
this.userUploadDir,
smallFileName,
),
300,
200,
);
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,
),
]);
this.pageContent.page.upload = {
originalFile: `${this.userUri}/${originalFileName}`,
mediumFile: `${this.userUri}/${mediumFileName}`,
smallFile: `${this.userUri}/${smallFileName}`,
originalFile: `${userUri}/${originalFileName}`,
mediumFile: `${userUri}/${mediumFileName}`,
smallFile: `${userUri}/${smallFileName}`,
};
return true;
@ -136,13 +143,15 @@ class Uploads extends Pages {
const listOfFiles = [];
let total = 0;
checkAndCreateDirectory(this.baseUploadDir);
checkAndCreateDirectory(this.userUploadDir);
const {
userUploadDir,
userUri,
} = await checkAndCreateDirectories(req);
const files = fs.readdirSync(this.userUploadDir)
const files = fs.readdirSync(userUploadDir)
.map((v) => {
// eslint-disable-next-line max-len
return {name: v, time: statSync(join(this.userUploadDir, v)).mtime.getTime()};
return {name: v, time: statSync(join(userUploadDir, v)).mtime.getTime()};
})
.sort(function(a, b) {
return b.time - a.time;
@ -156,10 +165,12 @@ class Uploads extends Pages {
if (file.indexOf('medium_') === 0) {
total += 1;
if (listOfFiles.length < endAt) {
console.log('file:', statSync(join(userUploadDir, file)));
listOfFiles.push({
originalFile: `${this.userUri}/${file.replace('medium_', '')}`,
mediumFile: `${this.userUri}/${file}`,
smallFile: `${this.userUri}/${file.replace('medium_', 'small_')}`,
originalFile: `${userUri}/${file.replace('medium_', '')}`,
mediumFile: `${userUri}/${file}`,
smallFile: `${userUri}/${file.replace('medium_', 'small_')}`,
time: statSync(join(userUploadDir, file)).mtime.getTime(),
});
}
}

View file

@ -4,7 +4,7 @@ import passport from 'passport';
import Pages from '../middleware/Pages';
import Auth from '../middleware/Auth';
import render from '../libs/Render';
import render from '../libs/render';
// eslint-disable-next-line new-cap
const router = express.Router();

View file

@ -1,7 +1,7 @@
import express from 'express';
import {ensureLoggedIn} from 'connect-ensure-login';
import Uploads from '../middleware/Uploads';
import render from '../libs/Render';
import render from '../libs/render';
// eslint-disable-next-line new-cap
const router = express.Router();

View file

@ -6,7 +6,7 @@
<%- include('partials/header', {page: page, user: user, baseUrl: baseUrl}); %>
<% } %>
<%- include(viewname, {page: page, params: params, query: query, user: user}) %>
<%- include(viewname, {page: page, params: params, query: query, user: user, DateTime: DateTime}) %>
<%- include('partials/footer', {page: page, query: query, user: user}); %>
</body>
</html>

View file

@ -13,7 +13,14 @@
data-small="<%= image.smallFile %>"
onclick="displayImageDetails('<%= i %>')"
>
<img src="<%= image.smallFile %>" alt="Image <%= i %>">
<div>
<img src="<%= image.smallFile %>" alt="Image <%= i %>">
</div>
<div>
<small>
Le <%= DateTime.fromMillis(image.time).setLocale('fr').toFormat('D à T') %>
</small>
</div>
</div>
<%
}