yusiff commited on
Commit
408c522
·
verified ·
1 Parent(s): c3ad080

Update app4.py

Browse files
Files changed (1) hide show
  1. app4.py +184 -178
app4.py CHANGED
@@ -1,178 +1,184 @@
1
- import pickle
2
- import streamlit as st
3
- import requests
4
- from datetime import datetime
5
-
6
- # -------------------- General Settings --------------------
7
- st.set_page_config(page_title="🎬 Movie Recommender", page_icon="🎞️", layout="wide")
8
-
9
- st.markdown("""
10
- <style>
11
- .movie-title {
12
- text-align: center;
13
- font-weight: bold;
14
- font-size: 22px;
15
- }
16
- .footer {
17
- text-align: center;
18
- font-size: 12px;
19
- color: grey;
20
- margin-top: 50px;
21
- }
22
- </style>
23
- """, unsafe_allow_html=True)
24
-
25
- # -------------------- Load Data --------------------
26
- try:
27
- movies = pickle.load(open('saved model/movie_list.pkl', 'rb'))
28
- similarity = pickle.load(open('saved model/similarity.pkl', 'rb'))
29
- except FileNotFoundError:
30
- st.error("❌ Required data files (movie_list.pkl and similarity.pkl) not found.")
31
- st.stop()
32
-
33
- # -------------------- Helper Functions --------------------
34
- def fetch_poster(movie_id):
35
- try:
36
- url = f"https://api.themoviedb.org/3/movie/{movie_id}?api_key=8265bd1679663a7ea12ac168da84d2e8&language=en-US"
37
- response = requests.get(url)
38
- data = response.json()
39
- poster_path = data.get('poster_path')
40
- return f"https://image.tmdb.org/t/p/w500/{poster_path}" if poster_path else "https://via.placeholder.com/500x750?text=No+Image"
41
- except:
42
- return "https://via.placeholder.com/500x750?text=Error"
43
-
44
- def fetch_movie_details(movie_id):
45
- try:
46
- url = f"https://api.themoviedb.org/3/movie/{movie_id}?api_key=8265bd1679663a7ea12ac168da84d2e8&language=en-US"
47
- response = requests.get(url)
48
- data = response.json()
49
- overview = data.get('overview', 'No overview available.')
50
- rating = data.get('vote_average', 'No rating')
51
- release_date = data.get('release_date', 'No release date')
52
- genres = ', '.join([genre['name'] for genre in data.get('genres', [])])
53
- return overview, rating, release_date, genres
54
- except:
55
- return "No details available.", "No rating", "No release date", "No genres"
56
-
57
- def recommend(movie):
58
- if movie not in movies['title'].values:
59
- return [], [], []
60
- index = movies[movies['title'] == movie].index[0]
61
- distances = sorted(list(enumerate(similarity[index])), reverse=True, key=lambda x: x[1])
62
- recommended_names = []
63
- recommended_posters = []
64
- recommended_ids = []
65
- for i in distances[1:6]:
66
- movie_id = movies.iloc[i[0]].movie_id
67
- recommended_names.append(movies.iloc[i[0]].title)
68
- recommended_posters.append(fetch_poster(movie_id))
69
- recommended_ids.append(movie_id) # حفظ الـ movie_id لتفاصيل الفيلم
70
- return recommended_names, recommended_posters, recommended_ids
71
-
72
- # -------------------- Page 1: Welcome --------------------
73
- def page_1():
74
- st.markdown("<h1 style='text-align: center;'>🎬 Movie Recommender</h1>", unsafe_allow_html=True)
75
- st.markdown("<hr>", unsafe_allow_html=True)
76
-
77
- hour = datetime.now().hour
78
- greeting_time = "Good Morning ☀️" if hour < 12 else "Good Evening 🌙" if hour >= 18 else "Good Afternoon 🌤️"
79
- st.markdown(f"### {greeting_time}")
80
-
81
- user_name = st.text_input("👤 Enter your name:")
82
- if st.button("Continue to Movie Selection"):
83
- if user_name:
84
- st.session_state.name = user_name
85
- st.session_state.page = "select_movie"
86
- else:
87
- st.warning("Please enter your name first 😊")
88
-
89
- # -------------------- Page 2: All-In-One (Select, Rate, Recommend, Details) --------------------
90
- def page_2():
91
- st.markdown(f"### Hello, {st.session_state.name} 👋", unsafe_allow_html=True)
92
-
93
- movie_list = movies['title'].values
94
- selected_movie = st.selectbox("🎥 Select a Movie", movie_list)
95
-
96
- rating = st.slider("⭐ Your Rating", 1, 10, 1)
97
- st.write(f" Your rating: {rating} stars")
98
-
99
- # تهيئة المتغيرات في الجلسة
100
- if "show_recommendations" not in st.session_state:
101
- st.session_state.show_recommendations = False
102
- if "show_details" not in st.session_state:
103
- st.session_state.show_details = {}
104
-
105
- # أزرار التبديل
106
- if st.button("🎯 Recommendations"):
107
- st.session_state.show_recommendations = not st.session_state.show_recommendations
108
-
109
- # عرض التوصيات إذا تم التفعيل
110
- if st.session_state.show_recommendations:
111
- with st.spinner("⏳ Fetching recommendations..."):
112
- names, posters, ids = recommend(selected_movie)
113
- if names:
114
- st.markdown(f"### ✅ Recommended Movies Similar to {selected_movie}:")
115
- cols = st.columns(5)
116
- for i in range(5):
117
- with cols[i]:
118
- details_key = f"details_{i}"
119
- if details_key not in st.session_state.show_details:
120
- st.session_state.show_details[details_key] = False
121
-
122
- if st.button(f"Show {names[i]} Details", key=details_key):
123
- st.session_state.show_details[details_key] = not st.session_state.show_details[details_key]
124
-
125
- if st.session_state.show_details.get(details_key, False):
126
- movie_id = ids[i]
127
- overview, vote_avg, release_date, genres = fetch_movie_details(movie_id)
128
- st.markdown(f"### 📖 Movie Details, {names[i]}:")
129
- st.markdown(f"**Overview**: {overview}")
130
- st.markdown(f"**Rating**: {vote_avg}/10")
131
- st.markdown(f"**Release Date**: {release_date}")
132
- st.markdown(f"**Genres**: {genres}")
133
-
134
- st.image(posters[i], use_container_width=True)
135
- st.markdown(f"<div class='movie-title'>{names[i]}</div>", unsafe_allow_html=True)
136
-
137
- else:
138
- st.warning("⚠️ No recommendations found.")
139
-
140
- # تهيئة حالة إظهار التفاصيل إن لم تكن موجودة
141
- if "show_selected_details" not in st.session_state:
142
- st.session_state.show_selected_details = False
143
-
144
- # زر التبديل بين عرض/إخفاء التفاصيل
145
- if st.button(f"📖 Show Details of {selected_movie}"):
146
- st.session_state.show_selected_details = not st.session_state.show_selected_details
147
-
148
- # عرض التفاصيل إذا كانت الحالة مفعّلة
149
- if st.session_state.show_selected_details:
150
- movie_id = movies[movies['title'] == selected_movie].movie_id.iloc[0]
151
- overview, vote_avg, release_date, genres = fetch_movie_details(movie_id)
152
- st.markdown(f"### 📖 Movie Details, {selected_movie}:")
153
- st.markdown(f"**Overview**: {overview}")
154
- st.markdown(f"**Rating**: {vote_avg}/10")
155
- st.markdown(f"**Release Date**: {release_date}")
156
- st.markdown(f"**Genres**: {genres}")
157
-
158
-
159
-
160
- if st.button("🔙 Back"):
161
- st.session_state.page = "welcome"
162
-
163
- # -------------------- Page Navigation --------------------
164
- if 'page' not in st.session_state:
165
- st.session_state.page = "welcome"
166
-
167
- if st.session_state.page == "welcome":
168
- page_1()
169
- elif st.session_state.page == "select_movie":
170
- page_2()
171
-
172
- # -------------------- Footer --------------------
173
- st.markdown("<hr>", unsafe_allow_html=True)
174
- st.markdown("<div class='footer'>© 2025 • by Youssef • Powered by TMDB API</div>", unsafe_allow_html=True)
175
-
176
-
177
-
178
-
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ # تعيين مسار جديد لمجلد .streamlit
4
+ os.environ['STREAMLIT_CONFIG_DIR'] = './.streamlit'
5
+
6
+
7
+ import pickle
8
+ import streamlit as st
9
+ import requests
10
+ from datetime import datetime
11
+
12
+ # -------------------- General Settings --------------------
13
+ st.set_page_config(page_title="🎬 Movie Recommender", page_icon="🎞️", layout="wide")
14
+
15
+ st.markdown("""
16
+ <style>
17
+ .movie-title {
18
+ text-align: center;
19
+ font-weight: bold;
20
+ font-size: 22px;
21
+ }
22
+ .footer {
23
+ text-align: center;
24
+ font-size: 12px;
25
+ color: grey;
26
+ margin-top: 50px;
27
+ }
28
+ </style>
29
+ """, unsafe_allow_html=True)
30
+
31
+ # -------------------- Load Data --------------------
32
+ try:
33
+ movies = pickle.load(open('saved model/movie_list.pkl', 'rb'))
34
+ similarity = pickle.load(open('saved model/similarity.pkl', 'rb'))
35
+ except FileNotFoundError:
36
+ st.error("❌ Required data files (movie_list.pkl and similarity.pkl) not found.")
37
+ st.stop()
38
+
39
+ # -------------------- Helper Functions --------------------
40
+ def fetch_poster(movie_id):
41
+ try:
42
+ url = f"https://api.themoviedb.org/3/movie/{movie_id}?api_key=8265bd1679663a7ea12ac168da84d2e8&language=en-US"
43
+ response = requests.get(url)
44
+ data = response.json()
45
+ poster_path = data.get('poster_path')
46
+ return f"https://image.tmdb.org/t/p/w500/{poster_path}" if poster_path else "https://via.placeholder.com/500x750?text=No+Image"
47
+ except:
48
+ return "https://via.placeholder.com/500x750?text=Error"
49
+
50
+ def fetch_movie_details(movie_id):
51
+ try:
52
+ url = f"https://api.themoviedb.org/3/movie/{movie_id}?api_key=8265bd1679663a7ea12ac168da84d2e8&language=en-US"
53
+ response = requests.get(url)
54
+ data = response.json()
55
+ overview = data.get('overview', 'No overview available.')
56
+ rating = data.get('vote_average', 'No rating')
57
+ release_date = data.get('release_date', 'No release date')
58
+ genres = ', '.join([genre['name'] for genre in data.get('genres', [])])
59
+ return overview, rating, release_date, genres
60
+ except:
61
+ return "No details available.", "No rating", "No release date", "No genres"
62
+
63
+ def recommend(movie):
64
+ if movie not in movies['title'].values:
65
+ return [], [], []
66
+ index = movies[movies['title'] == movie].index[0]
67
+ distances = sorted(list(enumerate(similarity[index])), reverse=True, key=lambda x: x[1])
68
+ recommended_names = []
69
+ recommended_posters = []
70
+ recommended_ids = []
71
+ for i in distances[1:6]:
72
+ movie_id = movies.iloc[i[0]].movie_id
73
+ recommended_names.append(movies.iloc[i[0]].title)
74
+ recommended_posters.append(fetch_poster(movie_id))
75
+ recommended_ids.append(movie_id) # حفظ الـ movie_id لتفاصيل الفيلم
76
+ return recommended_names, recommended_posters, recommended_ids
77
+
78
+ # -------------------- Page 1: Welcome --------------------
79
+ def page_1():
80
+ st.markdown("<h1 style='text-align: center;'>🎬 Movie Recommender</h1>", unsafe_allow_html=True)
81
+ st.markdown("<hr>", unsafe_allow_html=True)
82
+
83
+ hour = datetime.now().hour
84
+ greeting_time = "Good Morning ☀️" if hour < 12 else "Good Evening 🌙" if hour >= 18 else "Good Afternoon 🌤️"
85
+ st.markdown(f"### {greeting_time}")
86
+
87
+ user_name = st.text_input("👤 Enter your name:")
88
+ if st.button("Continue to Movie Selection"):
89
+ if user_name:
90
+ st.session_state.name = user_name
91
+ st.session_state.page = "select_movie"
92
+ else:
93
+ st.warning("Please enter your name first 😊")
94
+
95
+ # -------------------- Page 2: All-In-One (Select, Rate, Recommend, Details) --------------------
96
+ def page_2():
97
+ st.markdown(f"### Hello, {st.session_state.name} 👋", unsafe_allow_html=True)
98
+
99
+ movie_list = movies['title'].values
100
+ selected_movie = st.selectbox("🎥 Select a Movie", movie_list)
101
+
102
+ rating = st.slider("⭐ Your Rating", 1, 10, 1)
103
+ st.write(f"✅ Your rating: {rating} stars")
104
+
105
+ # تهيئة المتغيرات في الجلسة
106
+ if "show_recommendations" not in st.session_state:
107
+ st.session_state.show_recommendations = False
108
+ if "show_details" not in st.session_state:
109
+ st.session_state.show_details = {}
110
+
111
+ # أزرار التبديل
112
+ if st.button("🎯 Recommendations"):
113
+ st.session_state.show_recommendations = not st.session_state.show_recommendations
114
+
115
+ # عرض التوصيات إذا تم التفعيل
116
+ if st.session_state.show_recommendations:
117
+ with st.spinner("⏳ Fetching recommendations..."):
118
+ names, posters, ids = recommend(selected_movie)
119
+ if names:
120
+ st.markdown(f"### Recommended Movies Similar to {selected_movie}:")
121
+ cols = st.columns(5)
122
+ for i in range(5):
123
+ with cols[i]:
124
+ details_key = f"details_{i}"
125
+ if details_key not in st.session_state.show_details:
126
+ st.session_state.show_details[details_key] = False
127
+
128
+ if st.button(f"Show {names[i]} Details", key=details_key):
129
+ st.session_state.show_details[details_key] = not st.session_state.show_details[details_key]
130
+
131
+ if st.session_state.show_details.get(details_key, False):
132
+ movie_id = ids[i]
133
+ overview, vote_avg, release_date, genres = fetch_movie_details(movie_id)
134
+ st.markdown(f"### 📖 Movie Details, {names[i]}:")
135
+ st.markdown(f"**Overview**: {overview}")
136
+ st.markdown(f"**Rating**: {vote_avg}/10")
137
+ st.markdown(f"**Release Date**: {release_date}")
138
+ st.markdown(f"**Genres**: {genres}")
139
+
140
+ st.image(posters[i], use_container_width=True)
141
+ st.markdown(f"<div class='movie-title'>{names[i]}</div>", unsafe_allow_html=True)
142
+
143
+ else:
144
+ st.warning("⚠️ No recommendations found.")
145
+
146
+ # تهيئة حالة إظهار التفاصيل إن لم تكن موجودة
147
+ if "show_selected_details" not in st.session_state:
148
+ st.session_state.show_selected_details = False
149
+
150
+ # زر التبديل بين عرض/إخفاء التفاصيل
151
+ if st.button(f"📖 Show Details of {selected_movie}"):
152
+ st.session_state.show_selected_details = not st.session_state.show_selected_details
153
+
154
+ # عرض التفاصيل إذا كانت الحالة مفعّلة
155
+ if st.session_state.show_selected_details:
156
+ movie_id = movies[movies['title'] == selected_movie].movie_id.iloc[0]
157
+ overview, vote_avg, release_date, genres = fetch_movie_details(movie_id)
158
+ st.markdown(f"### 📖 Movie Details, {selected_movie}:")
159
+ st.markdown(f"**Overview**: {overview}")
160
+ st.markdown(f"**Rating**: {vote_avg}/10")
161
+ st.markdown(f"**Release Date**: {release_date}")
162
+ st.markdown(f"**Genres**: {genres}")
163
+
164
+
165
+
166
+ if st.button("🔙 Back"):
167
+ st.session_state.page = "welcome"
168
+
169
+ # -------------------- Page Navigation --------------------
170
+ if 'page' not in st.session_state:
171
+ st.session_state.page = "welcome"
172
+
173
+ if st.session_state.page == "welcome":
174
+ page_1()
175
+ elif st.session_state.page == "select_movie":
176
+ page_2()
177
+
178
+ # -------------------- Footer --------------------
179
+ st.markdown("<hr>", unsafe_allow_html=True)
180
+ st.markdown("<div class='footer'>© 2025 • by Youssef • Powered by TMDB API</div>", unsafe_allow_html=True)
181
+
182
+
183
+
184
+