Skip to content

Commit

Permalink
Merge branch 'main' into dashboard_stats
Browse files Browse the repository at this point in the history
  • Loading branch information
Shrimadh authored Oct 31, 2024
2 parents 75cefe1 + f36fcbe commit 9f99bf4
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 100 deletions.
24 changes: 15 additions & 9 deletions src/recommenderapp/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@
# pylint: disable=import-error
import json
from flask import Flask, jsonify, render_template, request
import pandas as pd
from flask_cors import CORS
from bson.objectid import ObjectId
from pymongo.errors import (
OperationFailure,
DuplicateKeyError,
)

from bson.objectid import ObjectId

from src.recommenderapp.search import Search

from src.recommenderapp.client import client
from src.recommenderapp.utils import (
beautify_feedback_data,
Expand All @@ -28,6 +33,7 @@
get_username,
add_friend,
get_friends,
get_recent_movies,
get_recent_friend_movies,
get_genre_count,
fetch_streaming_link,
Expand All @@ -42,7 +48,9 @@

cors = CORS(app, resources={r"/*": {"origins": "*"}})
user = {1: None}
user[1] = "671b289a193d2a9361ebf39a" # Hardcoded user id for testing purposes
# user[1] = "671b289a193d2a9361ebf39a" # Hardcoded user id for testing purposes

movies_df = pd.read_csv("data/movies.csv")


@app.route("/")
Expand Down Expand Up @@ -172,6 +180,7 @@ def login():
resp = login_to_account(client, data["username"], data["password"])
if not resp:
return "Invalid credentials", 400
user[1] = resp
return request.data


Expand Down Expand Up @@ -218,20 +227,17 @@ def recent_movies():
"""
Gets the recent movies of the active user
"""
movies = list(
client.PopcornPicksDB.reviews.find(
{"user_id": ObjectId(user[1])}, {"movie": 1, "_id": 0}
).sort("_id", -1)
)
return json.dumps(movies)
return get_recent_movies(client, user[1], movies_df)


@app.route("/getRecentFriendMovies", methods=["POST"])
def recent_friend_movies():
"""
Gets the recent movies of a certain friend
"""
return get_recent_friend_movies(client, user[1])
data = json.loads(request.data)
user_id = ObjectId(data["friend_id"]["_id"])
return get_recent_friend_movies(client, user_id, movies_df)


@app.route("/getUserName", methods=["GET"])
Expand All @@ -247,7 +253,7 @@ def get_friend():
"""
Gets the friends of the active user
"""
return get_friends(client, user)
return get_friends(client, user[1])


@app.route("/feedback", methods=["POST"])
Expand Down
41 changes: 15 additions & 26 deletions src/recommenderapp/templates/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -170,52 +170,45 @@ <h2>Your Friends</h2>
url: '/getRecentMovies',
contentType: "application/json;charset=UTF-8",
success: function (response) {
const userMovies = document.getElementById("userMovies");
userMovies.innerHTML = '';
response.forEach(function(element) {
const userMovies = document.getElementById("userMovies");
const listItem = document.createElement("li");
listItem.classList.add("movie");
const movieText = document.createTextNode(element.name + ": " + element.score + "/10 stars");
const movieText = document.createTextNode(element.title + ": " + element.score + "/10 stars");
listItem.appendChild(movieText);
userMovies.appendChild(listItem);
});
},
error: function (error) {
console.error("Error fetching recent movies:", error);
}
});
}

function getFriends() {

$.ajax({
type: 'GET',
url: '/getFriends',
contentType: "application/json;charset=UTF-8",
success: function (response) {
friendsData = response;
console.log(friendsData);
success: function (friendsData) {
console.log(friendsData);

// Populate friends list with buttons to show recent movies
const friendsList = document.getElementById("friendsList");
friendsData = JSON.stringify(friendsData);

JSON.parse(friendsData).forEach(function(friend) {

friend = friend[0];
friendsData.forEach(function(friend) {
console.log(friend);

$.ajax({
type: 'POST',
url: '/getRecentFriendMovies',
data: JSON.stringify(friend),
data: JSON.stringify({ "friend_id": friend }),
contentType: "application/json;charset=UTF-8",
success: function (response) {

recentMovies = response;

success: function (recentMovies) {
const listItem = document.createElement("li");
listItem.classList.add("friend");

const friendName = document.createTextNode(friend + " ");
const friendName = document.createTextNode(friend.username + " ");
listItem.appendChild(friendName);

const showMoviesButton = document.createElement("button");
Expand All @@ -229,33 +222,29 @@ <h2>Your Friends</h2>
const dropdown = document.createElement("div");
dropdown.classList.add("friend-dropdown");

console.log(recentMovies);

recentMovies.forEach(function(recentMovie) {
const movieLink = document.createElement("a");
movieLink.textContent = recentMovie.name + ": " + recentMovie.score + "/10 stars";
movieLink.textContent = recentMovie.title + ": " + recentMovie.score + "/10 stars";
dropdown.appendChild(movieLink);
});

listItem.appendChild(dropdown);

friendsList.appendChild(listItem);

},
error: function (error) {

console.log("Error retrieving recent movies:", error);
}
});
});
},
error: function (error) {
console.log("Error retrieving friends data:", error);
}
});



}



function showFriendMovies(recentMovies) {
// Hide all friend-dropdowns
const friendDropdowns = document.querySelectorAll(".friend-dropdown");
Expand Down
2 changes: 1 addition & 1 deletion src/recommenderapp/templates/search_page.html
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ <h1>Thanks!! Your response was stored.</h1>
contentType: "application/json;charset=UTF-8",
success: function(response) {
response.forEach(element => {
addRecentMovie(element.name)
addRecentMovie(element.title)
});
},
error: function(error) {
Expand Down
129 changes: 65 additions & 64 deletions src/recommenderapp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from pymongo.errors import PyMongoError
from bson.errors import InvalidId
from bson.objectid import ObjectId
import json
import pandas as pd
import os
import requests
Expand Down Expand Up @@ -230,9 +229,14 @@ def add_friend(client, user, username):
"""
Utility function for adding a friend
"""
client.PopcornPicksDB.users.update_one(
{"_id": ObjectId(user[1])}, {"$addToSet": {"friends": username}}
)
try:
client.PopcornPicksDB.users.update_one(
{"_id": ObjectId(user[1])}, {"$addToSet": {"friends": username}}
)
return True
except PyMongoError as e:
print(f"Error adding friend: {str(e)}")
return False


def login_to_account(client, username, password):
Expand Down Expand Up @@ -373,89 +377,86 @@ def get_user_ratings(client):
return posts


def get_recent_movies(client, user_id):
def get_recent_movies(client, user_id, movies_df):
"""
Utility function for getting recent movies reviewed by a user
Gets the recent movies of the active user with their names and ratings.
"""
try:
db = client.PopcornPicksDB
pipeline = [
{"$match": {"user_id": ObjectId(user_id)}},
{"$sort": {"time": -1}},
{"$limit": 5},
{
"$lookup": {
"from": "movies",
"localField": "movie_id",
"foreignField": "_id",
"as": "movie",
}
},
{"$unwind": "$movie"},
{"$project": {"_id": 0, "name": "$movie.name", "score": "$score"}},
user_id = ObjectId(user_id)
movies = list(
client.PopcornPicksDB.ratings.find({"user_id": user_id}).sort("_id", -1)
)
if not movies:
return jsonify([])
movie_data = [
{"movie_id": movie["movie_id"], "score": movie["score"]} for movie in movies
]

results = list(db.ratings.aggregate(pipeline))
return jsonify(results)

ratings_df = pd.DataFrame(movie_data)
merged_df = pd.merge(
ratings_df, movies_df, how="left", left_on="movie_id", right_on="movieId"
)
recent_movies_list = merged_df[["title", "score"]].to_dict(orient="records")
return jsonify(recent_movies_list)
except PyMongoError as e:
print(f"Database error: {str(e)}")
return jsonify([])
print(f"Database error retrieving recent movies: {str(e)}")
return jsonify({"error": "Database error occurred"})


def get_username(client, user):
"""
Utility function for getting the current users username
"""
user_data = client.PopcornPicksDB.users.find_one({"_id": ObjectId(user[1])})
return user_data["username"] if user_data else ""
try:
user_data = client.PopcornPicksDB.users.find_one({"_id": ObjectId(user[1])})
return user_data["username"] if user_data else ""
except PyMongoError as e:
print(f"Database error retrieving username: {str(e)}")
return ""


def get_recent_friend_movies(client, username):
def get_recent_friend_movies(client, user_id, movies_df):
"""
Utility function for getting recent movies from user's friends
Utility function for getting recent movies from user's friends.
"""
try:
db = client.PopcornPicksDB

user = db.users.find_one({"username": username})
if not user:
return jsonify([])

friends = user.get("friends", [])
if not friends:
movies = list(
client.PopcornPicksDB.ratings.find({"user_id": user_id}).sort("_id", -1)
)
if not movies:
return jsonify([])

pipeline = [
{"$match": {"user_id": {"$in": friends}}},
{"$sort": {"time": -1}},
{"$limit": 5},
{
"$lookup": {
"from": "movies",
"localField": "movie_id",
"foreignField": "_id",
"as": "movie",
}
},
{"$unwind": "$movie"},
{"$project": {"_id": 0, "name": "$movie.name", "score": "$score"}},
movie_data = [
{"movie_id": movie["movie_id"], "score": movie["score"]} for movie in movies
]

results = list(db.ratings.aggregate(pipeline))
return jsonify(results)

ratings_df = pd.DataFrame(movie_data)
merged_df = pd.merge(
ratings_df, movies_df, how="left", left_on="movie_id", right_on="movieId"
)
recent_movies_list = merged_df[["title", "score"]].to_dict(orient="records")
return jsonify(recent_movies_list)
except PyMongoError as e:
print(f"Database error: {str(e)}")
return jsonify([])
print(f"Database error retrieving friend movies: {str(e)}")
return jsonify({"error": "Database error occurred"})


def get_friends(client, user):
def get_friends(client, user_id):
"""
Utility function for getting the current users friends
Utility function to get a user's friends list with their user IDs and usernames.
"""
user_data = client.PopcornPicksDB.users.find_one({"_id": ObjectId(user[1])})
return json.dumps(user_data.get("friends", []))
user_data = client.PopcornPicksDB.users.find_one({"_id": ObjectId(user_id)})

friend_usernames = user_data.get("friends", [])

friends_info = list(
client.PopcornPicksDB.users.find(
{"username": {"$in": friend_usernames}, "_id": {"$ne": ObjectId(user_id)}},
{"_id": 1, "username": 1},
)
)

return [
{"_id": str(friend["_id"]), "username": friend["username"]}
for friend in friends_info
]


def get_user_history(client, user_id):
Expand Down

0 comments on commit 9f99bf4

Please sign in to comment.