const Movie = require("../models/class_film.js"); const User = require("../models/class_user.js"); const { getUserInformations, getUserSeenMovies } = require("../services/user.js"); const { getMovieAuthor, getMovieActors, getMovieStyles, getFilmsByAAS } = require("../services/movies.js"); const controllers = require("./userController.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 = controllers.get_user(user_login); //console.log("testtest"); let person = await getUserInformations(user_login); let user = User.toUser(person); let movies = await getUserSeenMovies(user_login); //console.log("movies"); //console.log(movies); const update_movies = function (movie_list) { return new Promise((resolve) => { movie_list.forEach(async movie => { console.log("on déclenche l'appel"); movie.author = await getMovieAuthor(movie.id);//a console.log console.log("on a le resultat"); console.log(movie.author); movie.actors = await getMovieActors(movie.id);//a console.log console.log(movie.actor); movie.styles = await getMovieStyles(movie.id);//a console.log console.log(movie.styles); }); return resolve(movie_list); }) }; let movies2 = [] movies.forEach(movie => { movies2.push(Movie.toMovie(movie)); }); movies = movies2; console.log("update_movies"); console.log(movies); movies = await update_movies(movies); // ça ça update pas console.log(movies); movies.forEach(movie => { //console.log("movie in movies"); //console.log(movie); user.addMovies(movie); //console.log("fin"); }); //let fav_duration; let seen = user.movies; //console.log("user.movies"); //console.log(user.movies); const get_favs_authors = function (movies_seen) { return new Promise((resolve) => { let fav_authors = []; //console.log("get_favs_authors"); //console.log(movies_seen); let authors = getAllAuthors(movies_seen).slice(0, 3); for (let i = 0; i < authors.length; i++) { fav_authors[i] = authors[i][0]; //recuperer seulement l'auteur, pas le reste } //console.log(fav_authors); return resolve(fav_authors); }) }; const get_favs_actors = function (movies_seen) { return new Promise((resolve) => { let fav_actors = []; let actors = getAllElement(movies_seen, getActors).slice(0, 3); for (let i = 0; i < actors.length; i++) { fav_actors[i] = actors[i][0]; //recuperer seulement l'acteur, pas le reste } console.log(fav_actors); return resolve(fav_actors); }) }; const get_favs_styles = function (movies_seen) { return new Promise((resolve) => { let fav_styles = []; let styles = getAllElement(movies_seen, getStyles).slice(0, 3); for (let i = 0; i < styles.length; i++) { fav_styles[i] = styles[i][0]; //recuperer seulement le style, pas le reste } return resolve(fav_styles); }) }; //console.log("films vus"); //console.log(seen); let fav_authors = await get_favs_authors(seen); //auteurs récurents dans les films aimés par l'utilisateur : moyenne (auteur * note du film) let fav_actors = await get_favs_actors(seen); //acteurs récurents dans les films aimés par l'utilisateur : moyenne (acteur * note du film (* %temps écran)) console.log(fav_authors); console.log(fav_actors); let points_films = [[]]; let all_films_sql = await getFilmsByAAS(fav_actors, fav_authors/*, fav_styles*/); let all_films = []; all_films_sql.forEach(film => { all_films.push(Movie.toMovie(film)); }); //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)); } return 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 console.log("doublon d'auteur !!"); return 0; } /** * 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. */ function getAllAuthors(seen) { let authors = [[]]; console.log("getAllAuthors(seen)"); console.log(seen); //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) { authors.push([seen[i].author, 1, seen[i].note]); } } for (let i = 0; i < authors.length; i++) { authors[i][2] /= authors[i][1]; } console.log(authors); authors.sort(comparerLignes); console.log(authors); console.log("fin"); 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. */ function getAllElement(seen, recupElement) { 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]); console.log(temp_elements); //liste d'acteurs 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) { elements.push([recupElement(temp_elements[h]), 1, temp_elements[h].note]); } } } for (let i = 0; i < elements.length; i++) { elements[i][2] /= elements[i][1]; } elements.sort(comparerLignes); return elements; } function getAuthor(movie) { return movie.author; } function getActors(movie) { return movie.actors; } function getStyles(movie) { return movie.styles; } 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; }