recommendation.js 6.44 KiB
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} = 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) {
// 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);
movies.forEach(async movie => {
movie = Movie.toMovie(movie);
movie.author = await getMovieAuthor(movie.id);
movie.actors = await getMovieActors(movie.id);
console.log("movie.actors");
console.log(movie.actors);
movie.styles = await getMovieStyles(movie.id);
console.log("movie.styles");
console.log(movie.styles);
user.addMovies(movie);
});
console.log("movies");
console.log(movies);
console.log("user");
console.log(user);
console.log("user.movies");
console.log(user.movies);
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 seen = user.movies;
let authors = getAllAuthors(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
}
let actors = getAllElement(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
}
let styles = getAllElement(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
}
let points_films = [[]];
//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
return [new Movie("Mariokart", "Nintendo", 5), new Movie("MarioBros", "Nintendo", 3), new Movie("MarioMaker", "Nintendo", 4)];
}
/**
* 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 = [[]];
//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];
}
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.
*/
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
console.log(seen);
console.log(recupElement);
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;
}