Some changes...
This commit is contained in:
parent
2ff0798632
commit
d02887b2da
16 changed files with 108 additions and 140 deletions
9
package-lock.json
generated
9
package-lock.json
generated
|
@ -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",
|
||||||
|
|
|
@ -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
|
@ -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() {}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
|
@ -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());
|
|
||||||
};
|
|
|
@ -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}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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 = [];
|
||||||
|
|
||||||
|
|
|
@ -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,50 +50,36 @@ const resizeImage = async (sourceImage, destImage, w, h) => {
|
||||||
.toFile(destImage);
|
.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
|
* Classe permettant la gestion des images
|
||||||
*/
|
*/
|
||||||
class Uploads extends Pages {
|
class Uploads extends Pages {
|
||||||
/**
|
/**
|
||||||
* @param {Object} req
|
* Méthode permettant d'ajouter un élément à la gallerie d'un utilisateur
|
||||||
* @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}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @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(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -13,7 +13,14 @@
|
||||||
data-small="<%= image.smallFile %>"
|
data-small="<%= image.smallFile %>"
|
||||||
onclick="displayImageDetails('<%= i %>')"
|
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>
|
</div>
|
||||||
<%
|
<%
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue