Skip to content

Commit

Permalink
Merge pull request #18 from philippebeck/dev
Browse files Browse the repository at this point in the history
Release 1.0.2
  • Loading branch information
philippebeck authored Dec 24, 2023
2 parents d29461c + b740008 commit 84e9618
Show file tree
Hide file tree
Showing 11 changed files with 746 additions and 547 deletions.
203 changes: 114 additions & 89 deletions controller/ArticleCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,19 @@ require("dotenv").config();

const { ARTICLE_NOT_FOUND, ARTICLES_NOT_FOUND, IMG_EXT, IMG_URL, THUMB_URL } = process.env;

const ARTICLES_IMG = IMG_URL + "articles/";
const ARTICLES_THUMB = THUMB_URL + "articles/";
const ARTICLES_IMG = `${IMG_URL}articles/`;
const ARTICLES_THUMB = `${THUMB_URL}articles/`;

const form = formidable({ uploadDir: ARTICLES_IMG, keepExtensions: true });

const Article = db.article;
const form = formidable({ uploadDir: ARTICLES_IMG, keepExtensions: true });

//! ******************** UTILS ********************

/**
* ? CHECK ARTICLE DATA
* * Checks the validity of article data.
*
* @param {string} name - The name of the article.
* @param {string} text - The text of the article.
* @param {string} alt - The alternative text for the article.
Expand All @@ -30,12 +32,12 @@ const form = formidable({ uploadDir: ARTICLES_IMG, keepExtensions: true });
exports.checkArticleData = (name, text, alt, cat, res) => {
const { CHECK_CAT, CHECK_NAME, CHECK_TEXT, STRING_MAX, STRING_MIN, TEXT_MAX, TEXT_MIN } = process.env;

if (
!nem.checkRange(cat, STRING_MIN, STRING_MAX) ||
!nem.checkRange(alt, STRING_MIN, STRING_MAX) ||
!nem.checkRange(text, TEXT_MIN, TEXT_MAX) ||
!nem.checkRange(name, STRING_MIN, STRING_MAX)
) {
const IS_NAME_CHECKED = nem.checkRange(name, STRING_MIN, STRING_MAX);
const IS_TEXT_CHECKED = nem.checkRange(text, TEXT_MIN, TEXT_MAX);
const IS_ALT_CHECKED = nem.checkRange(alt, STRING_MIN, STRING_MAX);
const ID_CAT_CHECKED = nem.checkRange(cat, STRING_MIN, STRING_MAX);

if (!IS_NAME_CHECKED || !IS_TEXT_CHECKED || !IS_ALT_CHECKED || !ID_CAT_CHECKED) {
return res.status(403).json({
message: CHECK_CAT || CHECK_NAME || CHECK_TEXT || CHECK_NAME
});
Expand All @@ -45,6 +47,7 @@ exports.checkArticleData = (name, text, alt, cat, res) => {
/**
* ? CHECK ARTICLE UNIQUE
* * Checks if an article is unique based on its name & text.
*
* @param {string} name - The name of the article.
* @param {string} text - The text of the article.
* @param {object} article - The existing article to compare with.
Expand All @@ -62,15 +65,16 @@ exports.checkArticleUnique = (name, text, article, res) => {
/**
* ? SET IMAGE
* * Sets the image for an article.
*
* @param {string} input - The name of the input image.
* @param {string} output - The name of the output image.
*/
exports.setImage = (input, output) => {
exports.setImage = async (input, output) => {
const INPUT = `articles/${input}`;
const OUTPUT = `articles/${output}`;

nem.setImage(INPUT, OUTPUT);
nem.setThumbnail(INPUT, OUTPUT);
await nem.setImage(INPUT, OUTPUT);
await nem.setThumbnail(INPUT, OUTPUT);
}

//! ******************** PUBLIC ********************
Expand All @@ -84,27 +88,37 @@ exports.setImage = (input, output) => {
* @return {Object} The JSON response containing the list of articles.
* @throws {Error} If the articles are not found in the database.
*/
exports.listArticles = (req, res) => {
Article.findAll()
.then((articles) => { res.status(200).json(articles) })
.catch(() => res.status(404).json({ message: ARTICLES_NOT_FOUND }));
exports.listArticles = async (req, res) => {
try {
const articles = await Article.findAll();
res.status(200).json(articles);

} catch (error) {
console.error(error);
res.status(404).json({ message: ARTICLES_NOT_FOUND });
}
}

/**
* ? READ ARTICLE
* * Retrieves an article by its ID & sends it as a JSON response.
* * Retrieves an article by its ID.
*
* @param {Object} req - The HTTP request object.
* @param {Object} res - The HTTP response object.
* @return {Object} The retrieved article as a JSON response.
* @throws {Error} If the article is not found in the database.
*/
exports.readArticle = (req, res) => {
exports.readArticle = async (req, res) => {
const ID = parseInt(req.params.id, 10);

Article.findByPk(ID)
.then((article) => { res.status(200).json(article) })
.catch(() => res.status(404).json({ message: ARTICLE_NOT_FOUND }));
try {
const article = await Article.findByPk(ID);
res.status(200).json(article);

} catch (error) {
console.error(error);
res.status(404).json({ message: ARTICLE_NOT_FOUND });
}
}

//! ******************** PRIVATE ********************
Expand All @@ -119,117 +133,128 @@ exports.readArticle = (req, res) => {
* @return {Object} A message indicating that the article was created.
* @throws {Error} If the article is not created in the database.
*/
exports.createArticle = (req, res, next) => {
exports.createArticle = async (req, res, next) => {
const { ARTICLE_CREATED, ARTICLE_NOT_CREATED } = process.env;

form.parse(req, (err, fields, files) => {
form.parse(req, async (err, fields, files) => {
if (err) { next(err); return }

const { name, text, alt, cat } = fields;
const { image } = files;

const IMG = nem.getName(name) + "." + IMG_EXT;
if (image && image.newFilename) this.setImage(image.newFilename, IMG);

this.checkArticleData(name, text, alt, cat, res);

Article.findAll()
.then((articles) => {
for (const article of articles) {
this.checkArticleUnique(name, text, article, res);
}

const article = { ...fields, image: IMG };

Article.create(article)
.then(() => {
if (image && image.newFilename) {
fs.unlink(ARTICLES_IMG + image.newFilename, () => {
res.status(201).json({ message: ARTICLE_CREATED })
})
}
})
.catch(() => res.status(400).json({ message: ARTICLE_NOT_CREATED }));
})
.catch(() => res.status(404).json({ message: ARTICLES_NOT_FOUND }));
try {
this.checkArticleData(name, text, alt, cat, res);

const articles = await Article.findAll();

if (!articles || articles.length === 0) {
return res.status(404).json({ message: ARTICLES_NOT_FOUND });
}

for (const article of articles) {
this.checkArticleUnique(name, text, article, res);
}

const IMG = `${nem.getName(name)}-${Date.now()}.${IMG_EXT}`;

if (image && image.newFilename) {
await this.setImage(image.newFilename, IMG);
await fs.promises.unlink(ARTICLES_IMG + image.newFilename);
}

await Article.create({ ...fields, image: IMG });
res.status(201).json({ message: ARTICLE_CREATED });

} catch (error) {
console.error(error);
res.status(400).json({ message: ARTICLE_NOT_CREATED });
}
})
}

/**
* ? UPDATE ARTICLE
* * Updates an article based on the request.
* * Updates an article by its ID & based on the request data.
*
* @param {Object} req - the request object
* @param {Object} res - the response object
* @param {Function} next - the next middleware function
* @return {Object} A message indicating that the article was updated.
* @throws {Error} If the article is not updated in the database.
*/
exports.updateArticle = (req, res, next) => {
exports.updateArticle = async (req, res, next) => {
const { ARTICLE_UPDATED, ARTICLE_NOT_UPDATED } = process.env;
const ID = parseInt(req.params.id, 10);

form.parse(req, (err, fields, files) => {
form.parse(req, async (err, fields, files) => {
if (err) { next(err); return }

const { name, text, alt, cat } = fields;
const { image } = files;

this.checkArticleData(name, text, alt, cat, res);
try {
this.checkArticleData(name, text, alt, cat, res);

const articles = await Article.findAll();

if (!articles || articles.length === 0) {
return res.status(404).json({ message: ARTICLES_NOT_FOUND });
}

Article.findAll()
.then((articles) => {
let img;
articles
.filter(article => article.id !== ID)
.forEach(article => this.checkArticleUnique(name, text, article, res));

if (image && image.newFilename) {
img = nem.getName(name) + "." + IMG_EXT;
this.setImage(image.newFilename, img);
let img;

} else {
img = articles.find(article => article.id === ID)?.image;
}
if (image && image.newFilename) {
img = nem.getName(name) + "." + IMG_EXT;

articles.filter(article => article.id !== ID).forEach(article =>
this.checkArticleUnique(name, text, article, res));
await this.setImage(image.newFilename, img);
await fs.promises.unlink(ARTICLES_IMG + image.newFilename);

const article = { ...fields, image: img };
} else {
img = articles.find(article => article.id === ID)?.image;
}

Article.update(article, { where: { id: ID }})
.then(() => {
if (image && image.newFilename) {
fs.unlink(ARTICLES_IMG + image.newFilename, () => {})
}
res.status(200).json({ message: ARTICLE_UPDATED });
})
.catch(() => res.status(400).json({ message: ARTICLE_NOT_UPDATED }));
})
.catch(() => res.status(404).json({ message: ARTICLES_NOT_FOUND }));
await Article.update({ ...fields, image: img }, { where: { id: ID }});
res.status(200).json({ message: ARTICLE_UPDATED });

} catch (error) {
console.error(error);
res.status(400).json({ message: ARTICLE_NOT_UPDATED });
}
})
}

/**
* ? DELETE ARTICLE
* * Deletes an article from the database.
*
* * Deletes an article by its ID.
*
* @param {Object} req - The request object.
* @param {Object} res - The response object.
* @return {Object} A message indicating that the article was deleted.
* @throws {Error} If the article is not deleted in the database.
*/
exports.deleteArticle = (req, res) => {
exports.deleteArticle = async (req, res) => {
const { ARTICLE_DELETED, ARTICLE_NOT_DELETED } = process.env;
const ID = parseInt(req.params.id, 10);

Article.findByPk(ID)
.then(article => {
fs.unlink(ARTICLES_THUMB + article.image, () => {
fs.unlink(ARTICLES_IMG + article.image, () => {

Article.destroy({ where: { id: ID }})
.then(() => res.status(204).json({ message: ARTICLE_DELETED }))
.catch(() => res.status(400).json({ message: ARTICLE_NOT_DELETED }));
})
})
})
.catch(() => res.status(404).json({ message: ARTICLE_NOT_FOUND }));
}
try {
const article = await Article.findByPk(ID);

if (!article) {
return res.status(404).json({ message: ARTICLE_NOT_FOUND });
}

await fs.promises.unlink(ARTICLES_THUMB + article.image);
await fs.promises.unlink(ARTICLES_IMG + article.image);

await Article.destroy({ where: { id: ID } });
res.status(204).json({ message: ARTICLE_DELETED });

} catch (error) {
console.error(error);
res.status(400).json({ message: ARTICLE_NOT_DELETED });
}
};
Loading

0 comments on commit 84e9618

Please sign in to comment.