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": "^4.18.2",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"knacss": "^8.0.4", "knacss": "^8.0.4",
"luxon": "^3.4.3",
"mongoose": "^7.5.2", "mongoose": "^7.5.2",
"mongoose-unique-validator": "^4.0.0", "mongoose-unique-validator": "^4.0.0",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
@ -5046,6 +5047,14 @@
"node": ">=10" "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": { "node_modules/make-dir": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "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", "build": "npx babel ./src --out-dir dist --copy-files",
"sass": "npx sass sass/index.scss public/css/main.css -s compressed --color", "sass": "npx sass sass/index.scss public/css/main.css -s compressed --color",
"watch": "npx nodemon -e js,scss", "watch": "npx nodemon -e js,scss",
"build:all": "npm-run-all build sass",
"start": "node ./dist/bin/www", "start": "node ./dist/bin/www",
"lint": "npx eslint ./src --ext .js", "lint": "npx eslint ./src --ext .js",
"lint:fix": "npx eslint --fix ./src --ext .js", "lint:fix": "npx eslint --fix ./src --ext .js",
@ -56,6 +57,7 @@
"express": "^4.18.2", "express": "^4.18.2",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"knacss": "^8.0.4", "knacss": "^8.0.4",
"luxon": "^3.4.3",
"mongoose": "^7.5.2", "mongoose": "^7.5.2",
"mongoose-unique-validator": "^4.0.0", "mongoose-unique-validator": "^4.0.0",
"multer": "^1.4.5-lts.1", "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); border: 2px solid var(--border-color);
background-color: var(--bg-alternate-color); background-color: var(--bg-alternate-color);
display: flex; display: flex;
flex-direction: row; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@include transition() {} @include transition() {}

View file

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

View file

@ -1,3 +1,5 @@
import {DateTime} from 'luxon';
export default (req, res, error, page, redirectTo) => { export default (req, res, error, page, redirectTo) => {
if (error) { if (error) {
res.status(500); res.status(500);
@ -13,6 +15,7 @@ export default (req, res, error, page, redirectTo) => {
query: {}, query: {},
user: req.user || null, user: req.user || null,
error, 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 * Méthode permettant de créer un nouvel utilisateur
* @param {Req} req * @param {Req} req
* @param {Function} callback
* *
* @return {Function} * @return {Function}
*/ */

View file

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

View file

@ -24,6 +24,24 @@ const checkAndCreateDirectory = async (directory) => {
return true; 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) => { const resizeImage = async (sourceImage, destImage, w, h) => {
return sharp(sourceImage) return sharp(sourceImage)
.resize(w, h, { .resize(w, h, {
@ -32,18 +50,7 @@ const resizeImage = async (sourceImage, destImage, w, h) => {
.toFile(destImage); .toFile(destImage);
}; };
/** const upload = multer({
* 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({}), storage: multer.diskStorage({}),
fileFilter(multerReq, file, cb) { fileFilter(multerReq, file, cb) {
const filetypes = /jpeg|jpg|png/; const filetypes = /jpeg|jpg|png/;
@ -62,20 +69,17 @@ class Uploads extends Pages {
}, },
}).single('image'); }).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}`;
}
/** /**
* * 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 * @param {*} req
* @param {*} callback
*/ */
async postOne(req) { async postOne(req) {
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
this.upload(req, req.body, (err, data) => { upload(req, req.body, (err, data) => {
if (err) { if (err) {
return reject(err); return reject(err);
} }
@ -84,8 +88,10 @@ class Uploads extends Pages {
}); });
}); });
checkAndCreateDirectory(this.baseUploadDir); const {
checkAndCreateDirectory(this.userUploadDir); userUploadDir,
userUri,
} = await checkAndCreateDirectories(req);
let ext = req.file.originalname.split('.'); let ext = req.file.originalname.split('.');
ext = ext[ext.length - 1]; ext = ext[ext.length - 1];
@ -95,31 +101,32 @@ class Uploads extends Pages {
const mediumFileName = `medium_${uploadname}`; const mediumFileName = `medium_${uploadname}`;
const smallFileName = `small_${uploadname}`; const smallFileName = `small_${uploadname}`;
copyFileSync(req.file.path, join(this.userUploadDir, originalFileName)); Promise.all([
copyFileSync(req.file.path, join(userUploadDir, originalFileName)),
await resizeImage( resizeImage(
req.file.path, req.file.path,
join( join(
this.userUploadDir, userUploadDir,
mediumFileName, mediumFileName,
), ),
800, 800,
600, 600,
); ),
await resizeImage( resizeImage(
req.file.path, req.file.path,
join( join(
this.userUploadDir, userUploadDir,
smallFileName, smallFileName,
), ),
300, 300,
200, 200,
); ),
]);
this.pageContent.page.upload = { this.pageContent.page.upload = {
originalFile: `${this.userUri}/${originalFileName}`, originalFile: `${userUri}/${originalFileName}`,
mediumFile: `${this.userUri}/${mediumFileName}`, mediumFile: `${userUri}/${mediumFileName}`,
smallFile: `${this.userUri}/${smallFileName}`, smallFile: `${userUri}/${smallFileName}`,
}; };
return true; return true;
@ -136,13 +143,15 @@ class Uploads extends Pages {
const listOfFiles = []; const listOfFiles = [];
let total = 0; let total = 0;
checkAndCreateDirectory(this.baseUploadDir); const {
checkAndCreateDirectory(this.userUploadDir); userUploadDir,
userUri,
} = await checkAndCreateDirectories(req);
const files = fs.readdirSync(this.userUploadDir) const files = fs.readdirSync(userUploadDir)
.map((v) => { .map((v) => {
// eslint-disable-next-line max-len // 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) { .sort(function(a, b) {
return b.time - a.time; return b.time - a.time;
@ -156,10 +165,12 @@ class Uploads extends Pages {
if (file.indexOf('medium_') === 0) { if (file.indexOf('medium_') === 0) {
total += 1; total += 1;
if (listOfFiles.length < endAt) { if (listOfFiles.length < endAt) {
console.log('file:', statSync(join(userUploadDir, file)));
listOfFiles.push({ listOfFiles.push({
originalFile: `${this.userUri}/${file.replace('medium_', '')}`, originalFile: `${userUri}/${file.replace('medium_', '')}`,
mediumFile: `${this.userUri}/${file}`, mediumFile: `${userUri}/${file}`,
smallFile: `${this.userUri}/${file.replace('medium_', 'small_')}`, 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 Pages from '../middleware/Pages';
import Auth from '../middleware/Auth'; import Auth from '../middleware/Auth';
import render from '../libs/Render'; import render from '../libs/render';
// eslint-disable-next-line new-cap // eslint-disable-next-line new-cap
const router = express.Router(); const router = express.Router();

View file

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

View file

@ -6,7 +6,7 @@
<%- include('partials/header', {page: page, user: user, baseUrl: baseUrl}); %> <%- 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}); %> <%- include('partials/footer', {page: page, query: query, user: user}); %>
</body> </body>
</html> </html>

View file

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