File size: 3,912 Bytes
7adf8b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# Importing necessary libraries from Flask
from flask import Flask, render_template, request  # Flask creates web applications; render_template serves HTML, and request handles form data.
import pickle  # pickle is used for loading pre-trained models or data stored in serialized files.
import requests  # requests is used to make HTTP requests to external APIs.

# Initializing a Flask application
app = Flask(__name__)

# Load the movie list and similarity matrix
movies = pickle.load(open('artifacts/model.pkl', 'rb'))  # Loads the list of movies from a serialized file.
similarity = pickle.load(open('artifacts/similarity.pkl', 'rb'))  # Loads the similarity matrix for movies, used for recommendations.

# Function to fetch the poster image of a movie from The Movie Database (TMDB) API
def fetch_poster(movie_id):
    # TMDB API URL, dynamically formatted with a movie ID and API key to get movie details
    url = f"https://api.themoviedb.org/3/movie/{movie_id}?api_key=8265bd1679663a7ea12ac168da84d2e8&language=en-US"
    data = requests.get(url).json()  # Sends a GET request to the URL and retrieves the response in JSON format.
    poster_path = data.get('poster_path')  # Extracts the poster path if available.
    if poster_path:  # Checks if a poster path exists for the movie.
        return "https://image.tmdb.org/t/p/w500/" + poster_path  # Returns the full URL for the poster image.
    return None  # If no poster is available, returns None.

# Function to recommend similar movies
def recommend(movie):
    # Gets the index of the selected movie in the movies DataFrame based on the movie title
    index = movies[movies['title'] == movie].index[0]
    # Enumerates similarity scores with the selected movie and sorts them in descending order
    distances = sorted(list(enumerate(similarity[index])), reverse=True, key=lambda x: x[1])
    recommended_movie_names = []  # List to store recommended movie titles.
    recommended_movie_posters = []  # List to store corresponding poster images.

    # Loop to get the top 5 similar movies (ignoring the first entry, which is the movie itself)
    for i in distances[1:5]:
        movie_id = movies.iloc[i[0]].movie_id  # Gets the movie ID for each recommended movie.
        recommended_movie_posters.append(fetch_poster(movie_id))  # Fetches and appends the movie's poster.
        recommended_movie_names.append(movies.iloc[i[0]].title)  # Adds the movie title to recommendations.

    return recommended_movie_names, recommended_movie_posters  # Returns lists of recommended movie titles and posters.

# Route for the homepage, handling both GET and POST requests
@app.route('/', methods=['GET', 'POST'])
def index():
    # When a movie is selected and form is submitted (POST request)
    if request.method == 'POST':
        selected_movie = request.form.get('movie')  # Retrieves the selected movie from the form.
        # Calls the recommend function and gets recommended movie names and posters
        recommended_movie_names, recommended_movie_posters = recommend(selected_movie)
        # Renders the HTML page with the selected movie, recommendations, and movie list for dropdown
        return render_template('index.html', selected_movie=selected_movie,
                               recommended_movie_names=recommended_movie_names,
                               recommended_movie_posters=recommended_movie_posters,
                               movies=movies['title'].values,
                               zip=zip)  # Adds zip function to enable pairing movie names with posters.

    # For GET requests, render the page with the movie list only.
    return render_template('index.html', movies=movies['title'].values)

# Running the application in debug mode for development (provides error details on crashes)
if __name__ == '__main__':
    app.run(debug=True)