382 lines
16 KiB
JavaScript
382 lines
16 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
const Joi = require('joi');
|
||
|
const Jwt = require('@hapi/jwt');
|
||
|
|
||
|
|
||
|
module.exports = [
|
||
|
{
|
||
|
method: 'POST',
|
||
|
path: '/movie',
|
||
|
options: {
|
||
|
auth: {
|
||
|
scope : 'admin'
|
||
|
},
|
||
|
tags: ['api'],
|
||
|
validate: {
|
||
|
payload: Joi.object({
|
||
|
title: Joi.string().required().min(3).example('The Matrix').description('Title of the movie'),
|
||
|
description: Joi.string().required().min(3).example('A computer hacker learns from mysterious rebels about the true nature of his reality and his role in the war against its controllers.').description('Description of the movie'),
|
||
|
director: Joi.string().required().min(3).example('Lana Wachowski').description('Director of the movie'),
|
||
|
releaseDate: Joi.date().required().example('1999-03-31').description('Release date of the movie'),
|
||
|
})
|
||
|
}
|
||
|
},
|
||
|
handler: async (request, h) => {
|
||
|
const { User } = request.models();
|
||
|
const { movieService } = request.services();
|
||
|
|
||
|
const { title, description, director, releaseDate } = request.payload;
|
||
|
|
||
|
//send email to all users
|
||
|
const { emailService } = request.services();
|
||
|
const users = await User.query();
|
||
|
for (const user of users) {
|
||
|
await emailService.sendEmail(
|
||
|
user.email,
|
||
|
user.firstName,
|
||
|
user.lastName,
|
||
|
'New movie added',
|
||
|
'<!DOCTYPE html>\n' +
|
||
|
'<html lang="en">\n' +
|
||
|
'\n' +
|
||
|
'<head>\n' +
|
||
|
' <meta charset="UTF-8">\n' +
|
||
|
' <meta name="viewport" content="width=device-width, initial-scale=1.0">\n' +
|
||
|
' <title>A new movie was added !</title>\n' +
|
||
|
' <style>\n' +
|
||
|
' body {\n' +
|
||
|
' font-family: Arial, sans-serif;\n' +
|
||
|
' background-color: #f7f7f7;\n' +
|
||
|
' margin: 0;\n' +
|
||
|
' padding: 0;\n' +
|
||
|
' color: #333;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .container {\n' +
|
||
|
' max-width: 600px;\n' +
|
||
|
' margin: 50px auto;\n' +
|
||
|
' padding: 20px;\n' +
|
||
|
' background-color: #fff;\n' +
|
||
|
' border-radius: 10px;\n' +
|
||
|
' box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n' +
|
||
|
' text-align: center;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .header {\n' +
|
||
|
' text-align: center;\n' +
|
||
|
' margin-bottom: 30px;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .logo {\n' +
|
||
|
' width: 100px;\n' +
|
||
|
' height: auto;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .content {\n' +
|
||
|
' text-align: justify;\n' +
|
||
|
' line-height: 1.6;\n' +
|
||
|
' margin-bottom: 30px;\n' +
|
||
|
' font-size: 16px;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .cta-button {\n' +
|
||
|
' display: inline-block;\n' +
|
||
|
' padding: 10px 20px;\n' +
|
||
|
' background-color: #ff6f61;\n' +
|
||
|
' color: #fff;\n' +
|
||
|
' text-decoration: none;\n' +
|
||
|
' border-radius: 5px;\n' +
|
||
|
' margin-top: 30px;\n' +
|
||
|
' transition: background-color 0.3s ease;\n' +
|
||
|
' font-weight: bold;\n' +
|
||
|
' text-align: center;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .footer {\n' +
|
||
|
' text-align: center;\n' +
|
||
|
' margin-top: 30px;\n' +
|
||
|
' font-size: 12px;\n' +
|
||
|
' color: #666;\n' +
|
||
|
' }\n' +
|
||
|
' </style>\n' +
|
||
|
'</head>\n' +
|
||
|
'\n' +
|
||
|
'<body>\n' +
|
||
|
'<div class="container">\n' +
|
||
|
' <div class="header">\n' +
|
||
|
' <h1>A new movie was added !</h1>\n' +
|
||
|
' </div>\n' +
|
||
|
' <div class="content">\n' +
|
||
|
' <p>Hello,</p>\n' +
|
||
|
' <p>A new movie was just added to the library.</p>\n' +
|
||
|
' <p>Go discover it now !</p>\n' +
|
||
|
' <a href="http://localhost:4000/documentation#/movies/getMovies" class="cta-button">Discover new movie</a>\n' +
|
||
|
' <p>Happy exploring!</p>\n' +
|
||
|
' </div>\n' +
|
||
|
' <div class="footer">\n' +
|
||
|
' <p>© 2024 Cemal. All rights reserved.</p>\n' +
|
||
|
' </div>\n' +
|
||
|
'</div>\n' +
|
||
|
'</body>\n' +
|
||
|
'\n' +
|
||
|
'</html>\n'
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// Appelle la méthode create du movieService en passant les champs nécessaires
|
||
|
return await movieService.create({
|
||
|
title: title,
|
||
|
description: description,
|
||
|
director: director,
|
||
|
releaseDate: releaseDate
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
|
||
|
{
|
||
|
method: 'GET',
|
||
|
path: '/movies',
|
||
|
options: {
|
||
|
tags: ['api'],
|
||
|
auth: false
|
||
|
},
|
||
|
handler: async (request, h) => {
|
||
|
const { Movie } = request.models();
|
||
|
const { movieService } = request.services();
|
||
|
|
||
|
// Appelle la méthode list du movieService pour récupérer tous les films
|
||
|
return await movieService.list();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
{
|
||
|
method: 'GET',
|
||
|
path: '/movie/{id}',
|
||
|
options: {
|
||
|
tags: ['api'],
|
||
|
auth: false,
|
||
|
validate: {
|
||
|
params: Joi.object({
|
||
|
id: Joi.number().integer().required().example(1).description('ID of the movie')
|
||
|
})
|
||
|
}
|
||
|
},
|
||
|
handler: async (request, h) => {
|
||
|
const { Movie } = request.models();
|
||
|
const { movieService } = request.services();
|
||
|
|
||
|
const { id } = request.params;
|
||
|
|
||
|
// Appelle la méthode get du movieService pour récupérer le film par son ID
|
||
|
return await movieService.get(id);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
{
|
||
|
method: 'DELETE',
|
||
|
path: '/movie/{id}',
|
||
|
options: {
|
||
|
auth: {
|
||
|
scope : 'admin'
|
||
|
},
|
||
|
tags: ['api'],
|
||
|
validate: {
|
||
|
params: Joi.object({
|
||
|
id: Joi.number().integer().positive().required().example(1).description('ID of the movie to delete')
|
||
|
})
|
||
|
}
|
||
|
},
|
||
|
handler: async (request, h) => {
|
||
|
const { movieService } = request.services();
|
||
|
const { id } = request.params;
|
||
|
|
||
|
// Appelle la méthode delete du movieService pour supprimer le film par son ID
|
||
|
await movieService.delete(id);
|
||
|
|
||
|
// Renvoie une réponse vide lorsque la suppression se déroule correctement
|
||
|
return 'deleted';
|
||
|
}
|
||
|
},
|
||
|
|
||
|
{
|
||
|
method: 'PATCH',
|
||
|
path: '/movie/{id}',
|
||
|
options: {
|
||
|
auth: {
|
||
|
scope : 'admin'
|
||
|
},
|
||
|
tags: ['api'],
|
||
|
validate: {
|
||
|
params: Joi.object({
|
||
|
id: Joi.number().integer().positive().required().example(1).description('ID of the movie to update')
|
||
|
}),
|
||
|
payload: Joi.object({
|
||
|
title: Joi.string().min(3).example('The Matrix').description('Title of the movie'),
|
||
|
description: Joi.string().min(3).example('A computer hacker learns from mysterious rebels about the true nature of his reality and his role in the war against its controllers.').description('Description of the movie'),
|
||
|
director: Joi.string().min(3).example('Lana Wachowski').description('Director of the movie'),
|
||
|
releaseDate: Joi.date().example('1999-03-31').description('Release date of the movie'),
|
||
|
})
|
||
|
}
|
||
|
},
|
||
|
handler: async (request, h) => {
|
||
|
const { movieService } = request.services();
|
||
|
const { id } = request.params;
|
||
|
|
||
|
//Email users who have favorited the movie
|
||
|
const { emailService } = request.services();
|
||
|
const { Favorite } = request.models();
|
||
|
const { User } = request.models();
|
||
|
|
||
|
const favorites = await Favorite.query().where('movie_id', id);
|
||
|
|
||
|
for (const favorite of favorites) {
|
||
|
const user = await User.query().findById(favorite.user_id);
|
||
|
await emailService.sendEmail(
|
||
|
user.email,
|
||
|
user.firstName,
|
||
|
user.lastName,
|
||
|
'Movie updated',
|
||
|
'<!DOCTYPE html>\n' +
|
||
|
'<html lang="en">\n' +
|
||
|
'\n' +
|
||
|
'<head>\n' +
|
||
|
' <meta charset="UTF-8">\n' +
|
||
|
' <meta name="viewport" content="width=device-width, initial-scale=1.0">\n' +
|
||
|
' <title>A movie was updated !</title>\n' +
|
||
|
' <style>\n' +
|
||
|
' body {\n' +
|
||
|
' font-family: Arial, sans-serif;\n' +
|
||
|
' background-color: #f7f7f7;\n' +
|
||
|
' margin: 0;\n' +
|
||
|
' padding: 0;\n' +
|
||
|
' color: #333;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .container {\n' +
|
||
|
' max-width: 600px;\n' +
|
||
|
' margin: 50px auto;\n' +
|
||
|
' padding: 20px;\n' +
|
||
|
' background-color: #fff;\n' +
|
||
|
' border-radius: 10px;\n' +
|
||
|
' box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n' +
|
||
|
' text-align: center;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .header {\n' +
|
||
|
' text-align: center;\n' +
|
||
|
' margin-bottom: 30px;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .logo {\n' +
|
||
|
' width: 100px;\n' +
|
||
|
' height: auto;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .content {\n' +
|
||
|
' text-align: justify;\n' +
|
||
|
' line-height: 1.6;\n' +
|
||
|
' margin-bottom: 30px;\n' +
|
||
|
' font-size: 16px;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .cta-button {\n' +
|
||
|
' display: inline-block;\n' +
|
||
|
' padding: 10px 20px;\n' +
|
||
|
' background-color: #ff6f61;\n' +
|
||
|
' color: #fff;\n' +
|
||
|
' text-decoration: none;\n' +
|
||
|
' border-radius: 5px;\n' +
|
||
|
' margin-top: 30px;\n' +
|
||
|
' transition: background-color 0.3s ease;\n' +
|
||
|
' font-weight: bold;\n' +
|
||
|
' text-align: center;\n' +
|
||
|
' }\n' +
|
||
|
'\n' +
|
||
|
' .footer {\n' +
|
||
|
' text-align: center;\n' +
|
||
|
' margin-top: 30px;\n' +
|
||
|
' font-size: 12px;\n' +
|
||
|
' color: #666;\n' +
|
||
|
' }\n' +
|
||
|
' </style>\n' +
|
||
|
'</head>\n' +
|
||
|
'\n' +
|
||
|
'<body>\n' +
|
||
|
'<div class="container">\n' +
|
||
|
' <div class="header">\n' +
|
||
|
' <h1>A movie was updated !</h1>\n' +
|
||
|
' </div>\n' +
|
||
|
' <div class="content">\n' +
|
||
|
' <p>Hello,</p>\n' +
|
||
|
' <p>The movie ' + request.payload.title + ' was just updated in the library.</p>\n' +
|
||
|
' <p>Go check it out now !</p>\n' +
|
||
|
' <a href="http://localhost:4000/documentation#/movie/getMovieId" class="cta-button">Discover updated movie</a>\n' +
|
||
|
' <p>Happy exploring!</p>\n' +
|
||
|
' </div>\n' +
|
||
|
' <div class="footer">\n' +
|
||
|
' <p>© 2024 Cemal. All rights reserved.</p>\n' +
|
||
|
' </div>\n' +
|
||
|
'</div>\n' +
|
||
|
'</body>\n' +
|
||
|
'\n' +
|
||
|
'</html>\n'
|
||
|
);
|
||
|
|
||
|
}
|
||
|
|
||
|
// Appelle la méthode update du movieService pour mettre à jour le film par son ID
|
||
|
return await movieService.update(id, request.payload);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
{
|
||
|
method: 'GET',
|
||
|
path: '/movie/csv',
|
||
|
options: {
|
||
|
auth: {
|
||
|
scope: 'admin'
|
||
|
},
|
||
|
tags: ['api']
|
||
|
},
|
||
|
handler: async (request, h) => {
|
||
|
const { rabbitmqService } = request.services();
|
||
|
const { Movie } = request.models();
|
||
|
const { movieService } = request.services();
|
||
|
|
||
|
try {
|
||
|
// Récupérer les films depuis la base de données
|
||
|
const movies = await Movie.query();
|
||
|
|
||
|
// Générer le fichier CSV
|
||
|
const csvData = await movieService.generateCsvData(movies);
|
||
|
console.log(csvData);
|
||
|
|
||
|
// Envoyer le fichier CSV via RabbitMQ pour l'envoi par e-mail
|
||
|
await rabbitmqService.sendCsvToQueue();
|
||
|
|
||
|
//When message is received, send the csv to the admin email
|
||
|
await rabbitmqService.receiveAndReturnCSV().then(
|
||
|
//Send the csv to the admin email
|
||
|
async () => {
|
||
|
const {emailService} = request.services();
|
||
|
await emailService.sendEmailWithAttachment(
|
||
|
request.auth.credentials.email,
|
||
|
'Admin',
|
||
|
'Admin',
|
||
|
'Movie list in CSV',
|
||
|
'Find the movie list in CSV format attached to this email.',
|
||
|
csvData
|
||
|
);
|
||
|
});
|
||
|
|
||
|
return h.response({ message: 'CSV sent to the admin email' }).code(200);
|
||
|
|
||
|
} catch (error) {
|
||
|
console.error('Erreur lors de l\'export CSV :', error);
|
||
|
return h.response({ message: 'Erreur lors du traitement de la requête' + error }).code(500);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
]
|