Newer
Older
const User = require("../models/class_user.js");
const { getUserInformations, getUserSeenMovies } = require("../services/user.js");
const { getMovieAuthor, getMovieActors, getMovieStyles} = require("../services/movies.js");
exports.getRecommandations = (req,res,next) => {
let username = req.session.username;
let infos = recommendationForUser(username);
res.status(200).json(infos);
};
/**
* Cette fonction selectionne les 3 meilleurs films pour un utilisateur.
*
* @param {string} user_login - Login de l'utilisateur.
* @returns {Movie[]} - La liste des 3 films.
*/
async function recommendationForUser(user_login, max_number=3) {
let person = await getUserInformations(user_login);
let user = User.toUser(person);
let movies = await getUserSeenMovies(user_login);
movies.forEach(async movie => {
movie = Movie.toMovie(movie);
movie.author = await getMovieAuthor(movie.id);
movie.actors = await getMovieActors(movie.id);
movie.styles = await getMovieStyles(movie.id);
user.addMovies(movie);
let fav_styles = []; //styles des films présents dans les films aimés par l'utilisateur
let fav_authors = []; //auteurs récurents dans les films aimés par l'utilisateur : moyenne (auteur * note du film)
let fav_actors = []; //acteurs récurents dans les films aimés par l'utilisateur : moyenne (acteur * note du film (* %temps écran))
//let fav_duration;
let authors = getAllAuthors(seen).slice(0,3);
for (let i = 0; i < authors.length; i++) {
for (let i = 0; i < actors.length; i++) {
for (let i = 0; i < styles.length; i++) {
let all_films = getFilmsBy(actors, authors/*, styles*/);
//chaques films a un nombre de points dans chaques catégorie :
//indice 0: films - indice 1: points_auteurs - indice 2: points_acteurs - indice 3: points_styles - indice 4: note total (%)
let max_point_author = fav_authors.length*fav_authors.length;
let max_point_actor = fav_actors.length*fav_actors.length;
//let max_point_style = fav_styles.length*fav_styles.length;
for (let i = 0; i < all_films.length; i++) {
points_films[i][0] = all_films[i];
for (let j = 0; j < fav_authors.length; j++) {
if(all_films[i].author == fav_authors[j])points_films[i][1] = (fav_authors.length-j) * fav_authors.length;
}
for (let j = 0; j < fav_actors.length; j++) {
all_films[i].actors.forEach(actor => {
if(actor == fav_actors[j])points_films[i][2] = (fav_actors.length-j) * fav_actors.length/all_films[i].actors.length;
});
}
/*for (let j = 0; j < fav_styles.length; j++) {
all_films[i].styles.forEach(style => {
if(style == fav_styles[j])points_films[i][3] = (fav_styles.length-j) * fav_styles.length/all_films[i].styles.length;
});
}*/
points_films[i][4] = points_films[i][1]/max_point_author + points_films[i][2]/max_point_actor/* + points_films[i][3]/max_point_style*/;
points_films[i][4] /= 3;
}
let res = [];
for (let i = 0; i < max_number; i++) {
res.push(getHighestScore(points_films, res));
}
/**
* trier une matrice par l'indice 1, puis par l'indice 2, puis par l'indice 0.
*
* @param {[string, Number, Number]} a - ligne d'une matrice
* @param {[string, Number, Number]} b - ligne d'une matrice
* @returns {Number} - 1 si a est plus grand, 0 si a=b, -1 si b est plus grand.
*/
function comparerLignes(a, b) {
// trier par le nombre d'apparition de l'auteur dans la liste de film vus (int)
if (a[1] < b[1]) return -1;
if (a[1] > b[1]) return 1;
// Si le nombre d'apparition est le même, trier par la moyenne de notes des films de l'auteur (float)
if (a[2] < b[2]) return -1;
if (a[2] > b[2]) return 1;
// Si la moyenne est la même, trier par le nom de l'auteur (string)
if (a[0] < b[0]) return -1;
if (a[0] > b[0]) return 1;
// Les lignes sont égales
/**
* renvoie une liste d'auteurs, avec leur nombre d'apparition dans la liste des films vus par un utilisateur, puis leur note moyenne
*
* @param {Movie[]} movies - Liste de film vus par un utilisateur.
* @returns {[[string, Number, Number]]} - La liste des auteurs.
*/
//1er indice = indice du couple auteur/nombre d'apparition/moyenne notes films, 2e indice: 0 auteur, 1 nbr apparition, 2 mpyenne films
for (let i = 0; i < seen.length; i++) {
let j = 0;
let found = false;
while(j < authors.length && !found){
if (authors[j][0] == seen[i].author) {
found = true;
authors[j][1] += 1;
authors[j][2] += seen[i].note;
}
j++;
}
if(!found){
}
}
for (let i = 0; i < authors.length; i++) {
authors[i][2] /= authors[i][1];
}
authors.sort(comparerLignes);
return authors;
}
/**
* renvoie une liste d'acteurs/styles, avec leur nombre d'apparition dans la liste des films vus par un utilisateur, puis leur note moyenne
*
* @param {Movie[]} movies - Liste de film vus par un utilisateur.
* @param {string(Movie)} recupElement - Fonction qui recupere un element d'un film (pour generaliser à allElement) (acteurs ou styles).
* @returns {[[string, Number, Number]]} - La liste des auteurs.
*/
let elements = [[]];
//premier indice = couple element/nombre d'apparition/moyenne notes films, 2e indice: 0 auteur, 1 nbr apparition, 2 mpyenne films
for (let i = 0; i < seen.length; i++) {
let j = 0;
let found = false;
temp_elements = recupElement(seen[i]);
for (let h = 0; h < temp_elements.length; h++) {
while(j < elements.length && !found){
if (elements[j][0] == recupElement(temp_elements[h])) {
found = true;
elements[j][1] += 1;
elements[j][2] += temp_elements[h].note;
}
j++;
}
if(!found){
}
}
}
for (let i = 0; i < elements.length; i++) {
elements[i][2] /= elements[i][1];
}
elements.sort(comparerLignes);
return elements;
function getActors(movie){
return movie.actors;
}
function getStyles(movie){
return movie.styles;
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
function getHighestScore(points_films, blacklist){
let found = false;
let i = 0;
let res;
let highscore = 0;
while (i < points_films.length && !found) {
if (points_films[i][4] > highscore) {
if (!isIn(points_films[i][0], blacklist)) {
highscore = points_films[i][4];
res = points_films[i][0];
}
}
}
return res;
}
/**
* Vérifie qu'un object est dans une liste
*
* @param {Object} objet - objet a trouver
* @param {Object[]} liste - liste dans laquelle chercher
*
* @returns {boolean} - true Si l'objet est dans la liste
*/
function isIn(objet, liste){
let res = false;
let i = 0;
while (res == false && i < liste.length)if(objet == liste[i++])res=true;
}