From f7993cebf69b9b2dcc343ba05c749c177c028293 Mon Sep 17 00:00:00 2001 From: Mihir Kamat Date: Fri, 1 Nov 2024 10:22:19 -0400 Subject: [PATCH] Modified backend and frontend to work more refined --- INSTALL.md | 22 ++++++++++++++++++++++ README.md | 6 +++--- requirements.txt | 12 ++++++------ src/backend/app.py | 13 ++++++++----- src/frontend/src/Login.js | 8 ++++++-- src/frontend/src/pages/.func.js | 10 ---------- src/frontend/src/pages/Preferences.js | 5 +++-- src/frontend/src/pages/Recommendations.js | 1 - src/test_core_algo.py | 12 ++++++------ test/test_api_core_remote.py | 7 +++++-- 10 files changed, 59 insertions(+), 37 deletions(-) create mode 100644 INSTALL.md delete mode 100644 src/frontend/src/pages/.func.js diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 000000000..95a8cfbb5 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,22 @@ +# Prerequisites + +To install dependencies for the backend, run: + + pip install -r requirements.txt + +For the frontend, navigate to ```./src/frontend``` and run: + + npm install + +# How to run + +To start the backend, cd to ./src/backend and run: + + python3 app.py ../../data/movies.csv + +To start the frontend, navigate to ./src/frontend and then run: + + npm start + +The frontend and backend will be available at localhost 3000 and 5000 respectively. + diff --git a/README.md b/README.md index a825b5297..a4639b0d1 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,14 @@ Coverage Status License: MIT Code style: black +

-[![GitHub release](https://img.shields.io/github/release/git-ankit/MovieRecommender.svg)](https://github.com/SoftwareEngg2024/CineScout/releases) [![black](https://img.shields.io/badge/StyleChecker-black-purple.svg)](https://pypi.org/project/black/) -## Bug? 🐛 -Raise an issue on this repository, we would love to look at it ❤️ +## Bug +Raise an issue on this repository, we would love to look at it! ## License 📃 This project is under MIT License. diff --git a/requirements.txt b/requirements.txt index b7e4c7203..a1f9b393b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -numpy>=1.18.5,<=1.20.3 -pandas>=1.0.4,<=1.2.4 -Flask>=1.1.2,<=2.1 -Flask-Cors>=3.0.9,<=3.1 -autopep8>=1.5.4,<=1.6 -requests>=2.22.0,<=2.25.0 +Flask +flask-cors +flask-sqlalchemy +flask-login +requests +pytest \ No newline at end of file diff --git a/src/backend/app.py b/src/backend/app.py index ffa88943d..d12df76b5 100644 --- a/src/backend/app.py +++ b/src/backend/app.py @@ -8,6 +8,7 @@ from werkzeug.security import generate_password_hash, check_password_hash from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user import json +import random import csv import sys, string from datetime import datetime @@ -27,9 +28,9 @@ def find_in_list(title, listp): cond = True T2 = title.split("(")[0].strip().lower().translate(str.maketrans('','',string.punctuation)) T2_list = T2.split() - print(T2_list) - print(T1_list) - for i in range(len(T2_list)): + # print(T2_list) + # print(T1_list) + for i in range(min(len(T1_list), len(T2_list))): cond = cond and (T2_list[i] in T1_list[i]) if cond: @@ -176,7 +177,7 @@ def register(): username = request.form.get('username') password = request.form.get('password') if (len(User.query.filter_by(username = username).all()) == 0): - user = User(username=username) + user = User(username=username, newuser=1) user.set_password(password) db.session.add(user) db.session.commit() @@ -223,6 +224,7 @@ def raw_getmovielist(): db.session.add(rec) db.session.commit() recmovies = [t[1][0] for t in recommended_movies] + random.shuffle(recmovies) return {"movie_list" : recmovies} # get recommended movie list based on history @@ -244,7 +246,8 @@ def watchmovie(): """ if (current_user.newuser): User.query.filter_by(id=current_user.id).update({"newuser" : 0}) - + db.session.commit() + moviename_other= json.loads(request.data)["movie_title"] moviename = translate_local(moviename_other) Recommendation.query.filter_by(user_id = current_user.id)\ diff --git a/src/frontend/src/Login.js b/src/frontend/src/Login.js index 3f2ff990a..e7d98d944 100644 --- a/src/frontend/src/Login.js +++ b/src/frontend/src/Login.js @@ -17,8 +17,9 @@ const Login = ({ onLogin, movieListGet, movieListSet}) => { formData.append('password', password); fetch("http://localhost:5000/login", { method : "post", - body : formData - // credentials : 'include' + body : formData, + // credentials : "include" + }) .then((response) => response.json()) .then((resp) => { @@ -36,6 +37,9 @@ const Login = ({ onLogin, movieListGet, movieListSet}) => { console.log("c") var error_string = resp["errstring"] } + else if (resp["redirect_url_key"] == "LOGIN") { + console.log("c") + } }) } diff --git a/src/frontend/src/pages/.func.js b/src/frontend/src/pages/.func.js deleted file mode 100644 index af41a141b..000000000 --- a/src/frontend/src/pages/.func.js +++ /dev/null @@ -1,10 +0,0 @@ -var movielist = Array(); - -export function getmovielist() { - return movielist; -} - -export function setmovielist(_movielist) { - movielist = _movielist; -} - diff --git a/src/frontend/src/pages/Preferences.js b/src/frontend/src/pages/Preferences.js index 582572d16..878438876 100644 --- a/src/frontend/src/pages/Preferences.js +++ b/src/frontend/src/pages/Preferences.js @@ -2,7 +2,6 @@ import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import './Preferences.css'; -import { getmovielist, setmovielist } from './.func'; const Preferences = ({movieListGet, movieListSet}) => { const availableGenres = [28, 35, 18, 27, 10749, 878]; // TMDB genre IDs @@ -25,10 +24,12 @@ const Preferences = ({movieListGet, movieListSet}) => { genreList = genreList.concat(genreNames[i]) } } + console.log(genreList) fetch("http://localhost:5000/registeruserprefs", { method: 'post', + credentials : 'include', body : JSON.stringify({genre_list : genreList}), - credentials : 'include' + }).then((response) => response.json()) .then((resp) => { movieListSet(resp["movie_list"]) diff --git a/src/frontend/src/pages/Recommendations.js b/src/frontend/src/pages/Recommendations.js index 0e3dac4fa..4c1272495 100644 --- a/src/frontend/src/pages/Recommendations.js +++ b/src/frontend/src/pages/Recommendations.js @@ -2,7 +2,6 @@ import React, { useEffect, useState } from 'react'; import MovieCard from '../components/MovieCard'; import './Recommendations.css'; -import { getmovielist } from './.func'; const Recommendations = ({ language, movieListGet, movieListSet}) => { const [recommendedMovies, setRecommendedMovies] = useState([]); diff --git a/src/test_core_algo.py b/src/test_core_algo.py index d00f2afbc..ed7d74af2 100644 --- a/src/test_core_algo.py +++ b/src/test_core_algo.py @@ -115,7 +115,7 @@ def test_core_algo_genre_consistency_two(): for movie in list_movies: watched_genres.update(get_genres_for_movie(movie[0])) - for movie, processed_movie in result: + for movie, processed_movie in result[0:200]: recommended_genres = get_genres_for_movie(movie[0]) assert all(genre in recommended_genres for genre in watched_genres) # At least one genre must match @@ -127,7 +127,7 @@ def test_core_algo_genre_consistency_three(): for movie in list_movies: watched_genres.update(get_genres_for_movie(movie[0])) - for movie, processed_movie in result: + for movie, processed_movie in result[0:200]: recommended_genres = get_genres_for_movie(movie[0]) assert all(genre in recommended_genres for genre in watched_genres) # At least one genre must match @@ -139,7 +139,7 @@ def test_core_algo_genre_consistency_five(): for movie in list_movies: watched_genres.update(get_genres_for_movie(movie[0])) - for movie, processed_movie in result: + for movie, processed_movie in result[0:200]: recommended_genres = get_genres_for_movie(movie[0]) assert all(genre in recommended_genres for genre in watched_genres) # At least one genre must match @@ -151,7 +151,7 @@ def test_core_algo_genre_consistency_single(): for movie in list_movies: watched_genres.update(get_genres_for_movie(movie[0])) - for movie, processed_movie in result: + for movie, processed_movie in result[0:200]: recommended_genres = get_genres_for_movie(movie[0]) assert all(genre in recommended_genres for genre in watched_genres) # At least one genre must match @@ -165,7 +165,7 @@ def test_surprise_me_horror(): for movie in watched_list: watched_genres.update(get_genres_for_movie(movie)) - for movie, processed_movie in result: + for movie, processed_movie in result[0:200]: recommended_genres = get_genres_for_movie(movie) assert any(genre in recommended_genres for genre in watched_genres) @@ -179,7 +179,7 @@ def test_surprise_me_comedy(): for movie in watched_list: watched_genres.update(get_genres_for_movie(movie)) - for movie, processed_movie in result: + for movie, processed_movie in result[0:200]: recommended_genres = get_genres_for_movie(movie) assert any(genre in recommended_genres for genre in watched_genres) diff --git a/test/test_api_core_remote.py b/test/test_api_core_remote.py index 6f89ada2d..a1836a767 100644 --- a/test/test_api_core_remote.py +++ b/test/test_api_core_remote.py @@ -67,7 +67,8 @@ def test_apicall_recommend_movie_newuser(): # get recommendations without having watched code, res, resp = formdata_apicall2("getmovielist", get, req_body, pcookies=user_cookies) assert code == 200 and "movie_list" in dict(res).keys() - + + def test_apicall_update_user_history(): # register and login user @@ -115,6 +116,7 @@ def test_recommend_based_on_watched_history(): code, res, resp = formdata_apicall2("/getmovielist", get, "", pcookies=user_cookies) assert code == 200 and "movie_list" in dict(res).keys() + def test_recommend_search(): user = {'username' : "newuser5", "password" : "new_password5"} code, res = formdata_apicall("register", post, user) @@ -130,6 +132,7 @@ def test_recommend_search(): assert code == 200 and "movie_list" in dict(res).keys() + def test_recommend_sort(): user = {'username' : "newuser6", "password" : "new_password5"} code, res = formdata_apicall("register", post, user) @@ -168,7 +171,7 @@ def test_recommend_searchyear(): # user searches movie req_body = json.dumps({"year" : "1998"}) - code, res, resp = formdata_apicall2("searchyear", get, "descending", pcookies=user_cookies) + code, res, resp = formdata_apicall2("searchyear", get, req_body, pcookies=user_cookies) assert code == 200 and "movie_list" in dict(res).keys()