MovieSelect / app.py
Shubham235's picture
Update app.py
88dd5ac verified
import streamlit as st
import pickle
import pandas as pd
from PIL import Image
import base64
# Streamlit App
st.set_page_config(page_title="Movie Select", page_icon=":briefcase:", layout="wide")
st.markdown('<div class="title">Movie Select - Discover Your Movie Mojo</div>', unsafe_allow_html=True)
# Load the movies dictionary and similarity tags
movies_dict = pickle.load(open('notebook/movies_dict.pkl', 'rb'))
movies_dict = pd.DataFrame(movies_dict)
similarity_tags = pickle.load(open('notebook/similarity_tags.pkl', 'rb'))
poster = pickle.load(open('notebook/poster_dict.pkl', 'rb'))
similarity_main_tags = pickle.load(open('notebook/similarity_main_tags.pkl', 'rb'))
# CSS for styling
st.markdown(
f"""
<style>
.stApp {{
background-image: url("https://i.postimg.cc/d114JH9w/image-blurr.jpg");
background-size: cover;
}}
.title {{
font-size: 36px;
font-weight: bold;
color: #FFFFFF;
text-align: center;
text-shadow: 2px 2px #000000;
}}
.subheader {{
font-size: 24px;
font-weight: bold;
color: #FFFFFF;
text-align: center;
text-shadow: 1px 1px #000000;
}}
.movie-title {{
font-size: 16px;
color: #FFFFFF;
text-align: center;
text-shadow: 1px 1px #000000;
padding: 5px;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 5px;
margin-bottom: 10px;
}}
.shaded-box {{
background-color: rgba(0, 0, 0, 0.5);
padding: 10px;
border-radius: 10px;
margin: 10px 0;
}}
.movie-poster {{
width: 150px; /* Set width in pixels */
height: 225px; /* Set height in pixels */
object-fit: cover; /* Ensures the image covers the whole area */
border-radius: 10px;
}}
.movie-container {{
display: flex;
flex-direction: column;
align-items: center;
}}
.stButton button {{
width: 100%;
background-color: #FF4B4B; /* Set button color */
color: white;
font-size: 18px;
padding: 10px;
border: none;
border-radius: 5px;
cursor: pointer;
}}
.stButton button:hover {{
background-color: #FF0000; /* Hover color */
}}
.stSelectbox div[data-baseweb="select"] {{
background-color: rgba(0, 0, 0, 0.5);
}}
.stSelectbox div[data-baseweb="select"] div[role="combobox"] {{
background-color: rgba(0, 0, 0, 0.5);
color: #FFFFFF;
}}
.stSelectbox div[data-baseweb="select"] div[role="listbox"] {{
background-color: rgba(0, 0, 0, 0.5);
color: #FFFFFF;
}}
.stSelectbox div[data-baseweb="select"] div[role="listbox"] ul {{
background-color: rgba(0, 0, 0, 0.5);
color: #FFFFFF;
}}
.stSelectbox div[data-baseweb="select"] div[role="listbox"] ul li {{
background-color: rgba(0, 0, 0, 0.5);
color: #FFFFFF;
}}
.vertical-divider {{
border-left: 2px solid white;
height: 100%;
position: absolute;
left: 50%;
margin-left: -3px;
top: 0;
}}
</style>
""",
unsafe_allow_html=True
)
# Function to recommend movies
def recommend(movie, similarity, exclude_movies=set(), num_recommendations=12, sort_by_rating=False, sort_by_revenue=False):
movie_index = movies_dict[movies_dict['title'] == movie].index[0]
distances = similarity[movie_index]
movies_list = sorted(list(enumerate(distances)), reverse=True, key=lambda x: x[1])[1:112]
recommended_movies = []
recommended_movies_poster = []
for i in movies_list:
movie_title = movies_dict.iloc[i[0]].title
if movie_title not in exclude_movies:
recommended_movies.append(movie_title)
recommended_movies_poster.append(poster[movie_title])
if len(recommended_movies) == num_recommendations:
break
# Combine the movies and their posters into a list of tuples
combined_list = list(zip(recommended_movies, recommended_movies_poster))
# Sort the combined list by IMDB rating and then by revenue if specified
if sort_by_rating:
combined_list = sorted(
combined_list,
key=lambda x: movies_dict[movies_dict['title'] == x[0]]['IMDB_Rating'].values[0],
reverse=(sort_by_rating == "Descending")
)
if sort_by_revenue:
combined_list = sorted(
combined_list,
key=lambda x: movies_dict[movies_dict['title'] == x[0]]['revenue'].values[0],
reverse=(sort_by_revenue == "Descending")
)
# Separate the sorted movies and posters back into two lists
if combined_list:
recommended_movies, recommended_movies_poster = zip(*combined_list)
return list(recommended_movies), list(recommended_movies_poster)
else:
return [], []
# Sidebar for filters
st.sidebar.header("Filter Recommendations")
st.sidebar.markdown(
"""
<style>
.sidebar-content {
position: fixed;
top: 20%;
width: 20%;
}
</style>
""",
unsafe_allow_html=True
)
num_recommendations = st.sidebar.number_input("Number of Recommendations", min_value=12, max_value=51, value=12)
sort_by_rating = st.sidebar.radio("Sort by IMDB Rating", ("None", "Ascending", "Descending"))
release_category = st.sidebar.selectbox("Movie Generation", ["All", "New", "Old", "Classic"])
sort_by_revenue = st.sidebar.radio("Sort by Revenue", ("None", "Ascending", "Descending"))
# Check if the 'Certificate' column exists in the dataframe
if 'Certificate' in movies_dict.columns:
certificate = st.sidebar.selectbox("Certificate", ["All"] + list(movies_dict['Certificate'].dropna().unique()))
else:
certificate = "All"
# Filter movies_dict based on sidebar selections
filtered_movies_dict = movies_dict.copy()
if release_category == "New":
filtered_movies_dict = filtered_movies_dict[filtered_movies_dict['release_year'] >= 2010]
elif release_category == "Old":
filtered_movies_dict = filtered_movies_dict[(filtered_movies_dict['release_year'] >= 1980) & (filtered_movies_dict['release_year'] < 2010)]
elif release_category == "Classic":
filtered_movies_dict = filtered_movies_dict[filtered_movies_dict['release_year'] < 1980]
if certificate != "All":
filtered_movies_dict = filtered_movies_dict[filtered_movies_dict['Certificate'] == certificate]
# Movie selection box and button on the same line
col1, col2 = st.columns([3, 1])
with col1:
selected_movie_name = st.selectbox('', filtered_movies_dict['title'].values)
with col2:
st.markdown("<br>", unsafe_allow_html=True) # Add a break to align the button properly
show_recommendation = st.button('Show Recommendation', use_container_width=True)
if show_recommendation:
# Get the first set of recommendations
recommended_movie_names_1, recommended_movie_posters_1 = recommend(
selected_movie_name, similarity_main_tags, num_recommendations=num_recommendations, sort_by_rating=sort_by_rating, sort_by_revenue=sort_by_revenue
)
# Get the second set of recommendations, excluding the first set
recommended_movie_names_2, recommended_movie_posters_2 = recommend(
selected_movie_name, similarity_tags, set(recommended_movie_names_1), num_recommendations=num_recommendations, sort_by_rating=sort_by_rating, sort_by_revenue=sort_by_revenue
)
col1, col2, col3 = st.columns([1, 0.1, 1])
with col1:
st.markdown('<div class="subheader shaded-box">Top Picks for You</div>', unsafe_allow_html=True)
for i in range(0, len(recommended_movie_names_1), 3):
row = st.columns(3)
for j in range(3):
if i + j < len(recommended_movie_names_1):
with row[j]:
movie_name = recommended_movie_names_1[i + j]
movie_poster = recommended_movie_posters_1[i + j]
google_search_url = f"https://www.google.com/search?q={movie_name}+watch+now"
st.markdown(f'<div class="movie-container"><a href="{google_search_url}" target="_blank"><img src="{movie_poster}" class="movie-poster"></a><div class="movie-title">{movie_name}</div></div>', unsafe_allow_html=True)
st.markdown("""---""")
with col2:
st.markdown('<div class="vertical-divider"></div>', unsafe_allow_html=True)
with col3:
st.markdown('<div class="subheader shaded-box">Some Other Suggestions</div>', unsafe_allow_html=True)
for i in range(0, len(recommended_movie_names_2), 3):
row = st.columns(3)
for j in range(3):
if i + j < len(recommended_movie_names_2):
with row[j]:
movie_name = recommended_movie_names_2[i + j]
movie_poster = recommended_movie_posters_2[i + j]
google_search_url = f"https://www.google.com/search?q={movie_name}+watch+now"
st.markdown(f'<div class="movie-container"><a href="{google_search_url}" target="_blank"><img src="{movie_poster}" class="movie-poster"></a><div class="movie-title">{movie_name}</div></div>', unsafe_allow_html=True)
st.markdown("""---""")