import streamlit as st import requests from transformers import pipeline # Enter your TMDb API key here TMDB_API_KEY = '2cc77b08a475b510f54a0dcca2c5c0c7' IMAGE_BASE_URL = "https://image.tmdb.org/t/p/w200" # TMDb base URL for poster images (width 200) @st.cache_resource def load_emotion_analyzer(): return pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base") emotion_analyzer = load_emotion_analyzer() def analyze_emotion(description): """Analyze emotion of a movie's description.""" emotions = emotion_analyzer(description) return emotions[0]['label'] # Return the top emotion def get_movie_genres(): """Fetches movie genres from TMDb API and returns a dictionary of genres.""" url = f'https://api.themoviedb.org/3/genre/movie/list?api_key={TMDB_API_KEY}&language=en-US' response = requests.get(url) if response.status_code == 200: genres = response.json().get('genres', []) return {genre['name']: genre['id'] for genre in genres} else: return None # Return None if the request failed def get_top_movies_by_genre(genre_id): """Fetches the top 10 highest-rated movies for a given genre ID from TMDb, sorted by title length.""" url = f'https://api.themoviedb.org/3/discover/movie?api_key={TMDB_API_KEY}&language=en-US&sort_by=vote_average.desc&vote_count.gte=1000&with_genres={genre_id}' response = requests.get(url) if response.status_code == 200: movies = response.json().get('results', [])[:10] # Get the top 10 results # Sort movies by title length, shortest to longest return sorted([(movie['title'], movie['vote_average'], movie['id'], movie['poster_path']) for movie in movies], key=lambda x: len(x[0])) else: return None def get_similar_movies(movie_id, genre_id): """Fetches similar movies for a given movie ID from TMDb and filters by the selected genre.""" url = f'https://api.themoviedb.org/3/movie/{movie_id}/similar?api_key={TMDB_API_KEY}&language=en-US' response = requests.get(url) if response.status_code == 200: movies = response.json().get('results', [])[:15] # Include the movie description (overview) in the returned values return [ (movie['title'], movie['vote_average'], movie['poster_path'], movie['id'], movie['overview']) for movie in movies if genre_id in movie['genre_ids'] and 'overview' in movie ] else: return None def get_movie_details(movie_id): """Fetches detailed information for a given movie ID from TMDb, including description, release date, director, and cast.""" url = f'https://api.themoviedb.org/3/movie/{movie_id}?api_key={TMDB_API_KEY}&language=en-US&append_to_response=credits' response = requests.get(url) if response.status_code == 200: movie = response.json() directors = [member['name'] for member in movie['credits']['crew'] if member['job'] == 'Director'] cast = [member['name'] for member in movie['credits']['cast'][:5]] # Get top 5 cast members return { "title": movie['title'], "rating": movie['vote_average'], "description": movie['overview'], "poster_path": movie['poster_path'], "release_date": movie['release_date'], "director": ", ".join(directors), "cast": ", ".join(cast) } else: return None # Initialize session state to store selected movies and recommendations if 'selected_movies' not in st.session_state: st.session_state['selected_movies'] = set() if 'recommendations' not in st.session_state: st.session_state['recommendations'] = [] if 'last_genre' not in st.session_state: st.session_state['last_genre'] = None # Streamlit app title st.title("Movie Recommender") # CSS for alignment and button styling st.markdown(""" """, unsafe_allow_html=True) # Fetch genres from TMDb and display in a dropdown genres = get_movie_genres() if genres is None: st.error("Failed to load movie genres. Please check your API key or connection.") else: genre_name = st.selectbox("Select a movie genre:", [""] + list(genres.keys())) # Include an empty option # Check if genre has changed, and reset selections if so if genre_name != st.session_state['last_genre']: st.session_state['selected_movies'].clear() st.session_state['recommendations'].clear() st.session_state['last_genre'] = genre_name # Only fetch and display movies if a genre is selected if genre_name: st.write("Please select at least one movie to generate recommendations.") genre_id = genres[genre_name] # Get the genre ID based on the selected genre name top_movies = get_top_movies_by_genre(genre_id) # Fetch top 10 movies in this genre, sorted by title length # Check if movies were successfully loaded if top_movies is None: st.error("Failed to load movies. Please check your API key or connection.") else: # Display the top 10 movies as clickable titles in a 5x2 grid layout with aligned rows st.write(f"Top 10 movies in the {genre_name} genre:") columns = st.columns(5) # Create 5 columns for each row # First row of 5 movies for index, (title, _, movie_id, poster_path) in enumerate(top_movies[:5]): col = columns[index] with col: st.markdown("