8 files + 136 − 65 Inline Compare changes Side-by-side Inline Show whitespace changes Files 8 .gitlab-ci.yml +1 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ stages: .eslint: image: node:16.14.0-alpine stage: lint allow_failure: true script: - cd $CONTEXT # install packages Loading .vscode/settings.json +3 −0 Original line number Diff line number Diff line Loading @@ -10,5 +10,8 @@ }, "[javascript][vue]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" }, "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } } algo/adreco.py +31 −24 Original line number Diff line number Diff line Loading @@ -36,6 +36,29 @@ def movieDbToDf(): return df def userDbToDf(): ''' This function convert a movie DataBase from mongoDB into a pandas DataFrame ''' #load DB client = MongoClient("mongodb://group3:GJF6cQqM4RLxBfNb@cs2022.lmichelin.fr:27017/group3?ssl=true") db = client.group3 collection = db.users #projection on useful data cursor = collection.find({},{"_id":1, "liked_movies": 1, "update":1}) df=pd.DataFrame(list(cursor)) return df def loadRecDB(): #load DB client = MongoClient("mongodb://group3:GJF6cQqM4RLxBfNb@cs2022.lmichelin.fr:27017/group3?ssl=true") db = client.group3 collection = db['recommendations'] return collection def preFiltering(df,percent=90): ''' This function removes movies who do not have enough votes to be evaluated Loading Loading @@ -103,7 +126,6 @@ def index_from_id(df,id): ''' return df[df['_id']==id].index.values[0] def recommendations(original_title, df, number_of_recommendations): #prefilter the dataframe Loading @@ -130,6 +152,10 @@ def recommendations(original_title, df, number_of_recommendations): return df['original_title'].iloc[recommendations_indices] def formatingFeatures(df_row): """ This function creates a new column "features" in the df used to calculate similarities between users_profiles et movies """ g = [] genres = [] k=[] Loading @@ -150,21 +176,6 @@ def formatingFeatures(df_row): return ' '.join([genres]*w_genres)+' '+' '.join([keywords]*w_keywords)+' '+' '.join([str(df_row['main_actor'])]*w_actor)+' '+' '.join([str(df_row['director'])]*w_director)+' '+' '.join([str(df_row['release_date'])]*w_release_date) def userDbToDf(): ''' This function convert a movie DataBase from mongoDB into a pandas DataFrame ''' #load DB client = MongoClient("mongodb://group3:GJF6cQqM4RLxBfNb@cs2022.lmichelin.fr:27017/group3?ssl=true") db = client.group3 collection = db.users #projection on useful data cursor = collection.find({},{"_id":1, "liked_movies": 1, "update":1}) df=pd.DataFrame(list(cursor)) return df def user_profile( user_index, moviesdf, usersdf, vectMatrix ): """ This function creates a user profile based on the likef movies of the user Loading Loading @@ -200,15 +211,11 @@ def user_profile( user_index, moviesdf, usersdf, vectMatrix ): else: return [i for i in range(100)] def loadRecDB(): #load DB client = MongoClient("mongodb://group3:GJF6cQqM4RLxBfNb@cs2022.lmichelin.fr:27017/group3?ssl=true") db = client.group3 collection = db['recommendations'] return collection def updateDB(): """ This function update the recommandation DB based on the likes of thes users """ #loadDB moviesdf = movieDbToDf() Loading backend/routes/genres.js +8 −11 Original line number Diff line number Diff line Loading @@ -4,17 +4,14 @@ const router = express.Router(); module.exports = router; // router.get("/popular/:number", async function (req, res) { // try { // const filmNumber = await req.params["number"]; // const getGenres = await GenreModel.find({}) // .sort({ popularity: "desc" }) // .limit(filmNumber); // res.send(getGenres); // } catch (error) { // console.log(error); // } // }); router.get("/", async function (req, res) { try { const getGenres = await GenreModel.find({}); res.send(getGenres); } catch (error) { console.log(error); } }); router.get("/genre/id/:id", async function (req, res) { try { Loading backend/routes/movies.js +12 −11 Original line number Diff line number Diff line Loading @@ -4,17 +4,18 @@ const router = express.Router(); module.exports = router; // router.get("/popular/:number", async function (req, res) { // try { // const filmNumber = await req.params["number"]; // const getMovies = await MovieModel.find({}) // .sort({ popularity: "desc" }) // .limit(filmNumber); // res.send(getMovies); // } catch (error) { // console.log(error); // } // }); router.get("/popular/:number", async function (req, res) { try { console.log('yo') const filmNumber = await req.params["number"]; const getMovies = await MovieModel.find({}) .sort({ popularity: "desc" }) .limit(filmNumber); res.send(getMovies); } catch (error) { console.log(error); } }); router.get("/movie/id/:id", async function (req, res) { try { Loading frontend/src/components/MovieType.vue +34 −10 Original line number Diff line number Diff line <template> <div class="box"> <h1>Genre</h1> <div class="liste-genre"> <li v-for="genre in genres" :key="genre.id" style="list-style-type:none;"> <div class="check"> <input type="checkbox" id="action" value="Action" v-model="genre"> <label for="Action">Action</label> <input type="checkbox" id="genre.id" value="genre" > <label for="genre"> {{ genre.name }} </label> </div> <div class="check"> <input type="checkbox" id="horreur" value="Horreur" v-model="genre"> <label for="horreur">Horreur</label> </div> <div class="check"> <input type="checkbox" id="fantastique" value="Fantastique" v-model="genre"> <label for="fantastique">Fantastique</label> </li> </div> <br> </div> </template> <script> import axios from "axios"; const backendURL = process.env.VUE_APP_BACKEND_BASE_URL; export default { data: function () { return { genrename: "", genres: [], genresLoadingError: "", }; }, methods: { fetchGenres: function () { axios .get( backendURL + "/genres", ) .then((response) => { this.genres = response.data; }) .catch((error) => { this.genresLoadingError = "An error occured while e ing genres."; console.error(error); }); }, }, created() { this.fetchGenres(); }, }; </script> <style scoped> Loading frontend/src/router/index.js +6 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ import Home from "../views/Home.vue"; import Connexion from "../views/Connexion.vue"; import Users from "../views/Users.vue"; import AddUser from "../views/AddUsers.vue"; import MoviePage from "../views/MoviePage.vue"; const routes = [ { Loading @@ -25,6 +26,11 @@ const routes = [ name: "AddUsers", component: AddUser, }, { path: "/movie/:id", name: "MoviePage", component: MoviePage, }, ]; const router = createRouter({ Loading frontend/src/views/Home.vue +41 −9 Original line number Diff line number Diff line Loading @@ -3,11 +3,13 @@ <div class="carousel"> <carousel :items-to-show="5.5" autoplay=1300> <slide v-for="movie in movies" :key="movie.id" autoplay='True' transition="100" > <router-link :to="'/movie/'+ movie.id"> <img :src="'https://image.tmdb.org/t/p/original/' + movie.poster_path" withd="100" height="300" /> </router-link> </slide> <template #addons> <navigation /> Loading @@ -20,27 +22,33 @@ <div class="type"> <MovieType /> </div> <div class="movie-affichage"> <li v-for="movie in movies" :key="movie.id"> <p class="movie-title"> {{ movie.title }} <p class="name"> <h5> {{ movie.title }}</h5> </p> <p class="film"> <router-link :to="'/movie/'+ movie.id"> <img :src="'https://image.tmdb.org/t/p/original/' + movie.poster_path" withd="100" height="300" /> </router-link> </p> </li> </div> </div> </div> </template> <script> import axios from "axios"; import 'vue3-carousel/dist/carousel.css'; import { Carousel, Slide, Pagination, Navigation } from 'vue3-carousel'; import "vue3-carousel/dist/carousel.css"; import { Carousel, Slide, Pagination, Navigation } from "vue3-carousel"; import MovieType from "../components/MovieType.vue"; const backendURL = process.env.VUE_APP_BACKEND_BASE_URL; export default { name: "Home", Loading @@ -62,26 +70,41 @@ export default { fetchMovies: function () { axios .get( `https://api.themoviedb.org/3/movie/popular?api_key=522d421671cf75c2cba341597d86403a` backendURL + "/movies/popular/20", ) .then((response) => { this.movies = response.data.results; this.movies = response.data; console.log(response.data) }) .catch((error) => { this.moviesLoadingError = "An error occured while e ing movies."; console.error(error); }); }, fetchGenres: function () { axios .get( backendURL + "/genres", ) .then((response) => { this.genres = response.data; console.log(response.data) }) .catch((error) => { this.genresLoadingError = "An error occured while e ing genres."; console.error(error); }); }, }, created() { this.fetchMovies(); this.fetchGenres(); }, }; </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> .logo { max-width: 100px; } Loading @@ -108,4 +131,13 @@ li { display: flex; align-self: center; } .name { max-width: 200px; justify-content: center; align-items: center; background-color: #eaf2ef; } .corps { display: flex; } </style>
.gitlab-ci.yml +1 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ stages: .eslint: image: node:16.14.0-alpine stage: lint allow_failure: true script: - cd $CONTEXT # install packages Loading
.vscode/settings.json +3 −0 Original line number Diff line number Diff line Loading @@ -10,5 +10,8 @@ }, "[javascript][vue]": { "editor.defaultFormatter": "dbaeumer.vscode-eslint" }, "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } }
algo/adreco.py +31 −24 Original line number Diff line number Diff line Loading @@ -36,6 +36,29 @@ def movieDbToDf(): return df def userDbToDf(): ''' This function convert a movie DataBase from mongoDB into a pandas DataFrame ''' #load DB client = MongoClient("mongodb://group3:GJF6cQqM4RLxBfNb@cs2022.lmichelin.fr:27017/group3?ssl=true") db = client.group3 collection = db.users #projection on useful data cursor = collection.find({},{"_id":1, "liked_movies": 1, "update":1}) df=pd.DataFrame(list(cursor)) return df def loadRecDB(): #load DB client = MongoClient("mongodb://group3:GJF6cQqM4RLxBfNb@cs2022.lmichelin.fr:27017/group3?ssl=true") db = client.group3 collection = db['recommendations'] return collection def preFiltering(df,percent=90): ''' This function removes movies who do not have enough votes to be evaluated Loading Loading @@ -103,7 +126,6 @@ def index_from_id(df,id): ''' return df[df['_id']==id].index.values[0] def recommendations(original_title, df, number_of_recommendations): #prefilter the dataframe Loading @@ -130,6 +152,10 @@ def recommendations(original_title, df, number_of_recommendations): return df['original_title'].iloc[recommendations_indices] def formatingFeatures(df_row): """ This function creates a new column "features" in the df used to calculate similarities between users_profiles et movies """ g = [] genres = [] k=[] Loading @@ -150,21 +176,6 @@ def formatingFeatures(df_row): return ' '.join([genres]*w_genres)+' '+' '.join([keywords]*w_keywords)+' '+' '.join([str(df_row['main_actor'])]*w_actor)+' '+' '.join([str(df_row['director'])]*w_director)+' '+' '.join([str(df_row['release_date'])]*w_release_date) def userDbToDf(): ''' This function convert a movie DataBase from mongoDB into a pandas DataFrame ''' #load DB client = MongoClient("mongodb://group3:GJF6cQqM4RLxBfNb@cs2022.lmichelin.fr:27017/group3?ssl=true") db = client.group3 collection = db.users #projection on useful data cursor = collection.find({},{"_id":1, "liked_movies": 1, "update":1}) df=pd.DataFrame(list(cursor)) return df def user_profile( user_index, moviesdf, usersdf, vectMatrix ): """ This function creates a user profile based on the likef movies of the user Loading Loading @@ -200,15 +211,11 @@ def user_profile( user_index, moviesdf, usersdf, vectMatrix ): else: return [i for i in range(100)] def loadRecDB(): #load DB client = MongoClient("mongodb://group3:GJF6cQqM4RLxBfNb@cs2022.lmichelin.fr:27017/group3?ssl=true") db = client.group3 collection = db['recommendations'] return collection def updateDB(): """ This function update the recommandation DB based on the likes of thes users """ #loadDB moviesdf = movieDbToDf() Loading
backend/routes/genres.js +8 −11 Original line number Diff line number Diff line Loading @@ -4,17 +4,14 @@ const router = express.Router(); module.exports = router; // router.get("/popular/:number", async function (req, res) { // try { // const filmNumber = await req.params["number"]; // const getGenres = await GenreModel.find({}) // .sort({ popularity: "desc" }) // .limit(filmNumber); // res.send(getGenres); // } catch (error) { // console.log(error); // } // }); router.get("/", async function (req, res) { try { const getGenres = await GenreModel.find({}); res.send(getGenres); } catch (error) { console.log(error); } }); router.get("/genre/id/:id", async function (req, res) { try { Loading
backend/routes/movies.js +12 −11 Original line number Diff line number Diff line Loading @@ -4,17 +4,18 @@ const router = express.Router(); module.exports = router; // router.get("/popular/:number", async function (req, res) { // try { // const filmNumber = await req.params["number"]; // const getMovies = await MovieModel.find({}) // .sort({ popularity: "desc" }) // .limit(filmNumber); // res.send(getMovies); // } catch (error) { // console.log(error); // } // }); router.get("/popular/:number", async function (req, res) { try { console.log('yo') const filmNumber = await req.params["number"]; const getMovies = await MovieModel.find({}) .sort({ popularity: "desc" }) .limit(filmNumber); res.send(getMovies); } catch (error) { console.log(error); } }); router.get("/movie/id/:id", async function (req, res) { try { Loading
frontend/src/components/MovieType.vue +34 −10 Original line number Diff line number Diff line <template> <div class="box"> <h1>Genre</h1> <div class="liste-genre"> <li v-for="genre in genres" :key="genre.id" style="list-style-type:none;"> <div class="check"> <input type="checkbox" id="action" value="Action" v-model="genre"> <label for="Action">Action</label> <input type="checkbox" id="genre.id" value="genre" > <label for="genre"> {{ genre.name }} </label> </div> <div class="check"> <input type="checkbox" id="horreur" value="Horreur" v-model="genre"> <label for="horreur">Horreur</label> </div> <div class="check"> <input type="checkbox" id="fantastique" value="Fantastique" v-model="genre"> <label for="fantastique">Fantastique</label> </li> </div> <br> </div> </template> <script> import axios from "axios"; const backendURL = process.env.VUE_APP_BACKEND_BASE_URL; export default { data: function () { return { genrename: "", genres: [], genresLoadingError: "", }; }, methods: { fetchGenres: function () { axios .get( backendURL + "/genres", ) .then((response) => { this.genres = response.data; }) .catch((error) => { this.genresLoadingError = "An error occured while e ing genres."; console.error(error); }); }, }, created() { this.fetchGenres(); }, }; </script> <style scoped> Loading
frontend/src/router/index.js +6 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ import Home from "../views/Home.vue"; import Connexion from "../views/Connexion.vue"; import Users from "../views/Users.vue"; import AddUser from "../views/AddUsers.vue"; import MoviePage from "../views/MoviePage.vue"; const routes = [ { Loading @@ -25,6 +26,11 @@ const routes = [ name: "AddUsers", component: AddUser, }, { path: "/movie/:id", name: "MoviePage", component: MoviePage, }, ]; const router = createRouter({ Loading
frontend/src/views/Home.vue +41 −9 Original line number Diff line number Diff line Loading @@ -3,11 +3,13 @@ <div class="carousel"> <carousel :items-to-show="5.5" autoplay=1300> <slide v-for="movie in movies" :key="movie.id" autoplay='True' transition="100" > <router-link :to="'/movie/'+ movie.id"> <img :src="'https://image.tmdb.org/t/p/original/' + movie.poster_path" withd="100" height="300" /> </router-link> </slide> <template #addons> <navigation /> Loading @@ -20,27 +22,33 @@ <div class="type"> <MovieType /> </div> <div class="movie-affichage"> <li v-for="movie in movies" :key="movie.id"> <p class="movie-title"> {{ movie.title }} <p class="name"> <h5> {{ movie.title }}</h5> </p> <p class="film"> <router-link :to="'/movie/'+ movie.id"> <img :src="'https://image.tmdb.org/t/p/original/' + movie.poster_path" withd="100" height="300" /> </router-link> </p> </li> </div> </div> </div> </template> <script> import axios from "axios"; import 'vue3-carousel/dist/carousel.css'; import { Carousel, Slide, Pagination, Navigation } from 'vue3-carousel'; import "vue3-carousel/dist/carousel.css"; import { Carousel, Slide, Pagination, Navigation } from "vue3-carousel"; import MovieType from "../components/MovieType.vue"; const backendURL = process.env.VUE_APP_BACKEND_BASE_URL; export default { name: "Home", Loading @@ -62,26 +70,41 @@ export default { fetchMovies: function () { axios .get( `https://api.themoviedb.org/3/movie/popular?api_key=522d421671cf75c2cba341597d86403a` backendURL + "/movies/popular/20", ) .then((response) => { this.movies = response.data.results; this.movies = response.data; console.log(response.data) }) .catch((error) => { this.moviesLoadingError = "An error occured while e ing movies."; console.error(error); }); }, fetchGenres: function () { axios .get( backendURL + "/genres", ) .then((response) => { this.genres = response.data; console.log(response.data) }) .catch((error) => { this.genresLoadingError = "An error occured while e ing genres."; console.error(error); }); }, }, created() { this.fetchMovies(); this.fetchGenres(); }, }; </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> .logo { max-width: 100px; } Loading @@ -108,4 +131,13 @@ li { display: flex; align-self: center; } .name { max-width: 200px; justify-content: center; align-items: center; background-color: #eaf2ef; } .corps { display: flex; } </style>