Update app.py
Browse files
app.py
CHANGED
@@ -1,104 +1,107 @@
|
|
1 |
-
import streamlit as st
|
2 |
-
from api import get_news, NewsRequest
|
3 |
-
from utils import text_to_speech
|
4 |
-
import time
|
5 |
-
import base64
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
st.
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
st.sidebar.
|
34 |
-
|
35 |
-
|
36 |
-
st.markdown(
|
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 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
#
|
68 |
-
#
|
69 |
-
|
70 |
-
audio_file
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
<
|
97 |
-
<
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from api import get_news, NewsRequest
|
3 |
+
from utils import text_to_speech
|
4 |
+
import time
|
5 |
+
import base64
|
6 |
+
|
7 |
+
import nltk
|
8 |
+
nltk.download('punkt')
|
9 |
+
|
10 |
+
# Function to play audio automatically
|
11 |
+
def autoplay_audio(file_path):
|
12 |
+
with open(file_path, "rb") as audio_file:
|
13 |
+
audio_bytes = audio_file.read()
|
14 |
+
b64 = base64.b64encode(audio_bytes).decode()
|
15 |
+
audio_tag = f"""
|
16 |
+
<audio autoplay>
|
17 |
+
<source src="data:audio/mp3;base64,{b64}" type="audio/mp3">
|
18 |
+
</audio>
|
19 |
+
"""
|
20 |
+
st.markdown(audio_tag, unsafe_allow_html=True)
|
21 |
+
|
22 |
+
# UI Function
|
23 |
+
def main():
|
24 |
+
st.set_page_config(page_title="News Sentiment & Summarization", layout="wide")
|
25 |
+
|
26 |
+
# Sidebar
|
27 |
+
st.sidebar.markdown(
|
28 |
+
"<h1 style='color:#00FFAF; text-align:center;'>οΏ½οΏ½οΏ½ News Finder</h1>",
|
29 |
+
unsafe_allow_html=True
|
30 |
+
)
|
31 |
+
st.sidebar.write("Enter a company name below to get the latest summarized news with sentiment analysis:")
|
32 |
+
|
33 |
+
company_name = st.sidebar.text_input("π Company Name:")
|
34 |
+
fetch_button = st.sidebar.button("Fetch News")
|
35 |
+
|
36 |
+
st.sidebar.markdown("---")
|
37 |
+
sentiment_summary_placeholder = st.sidebar.empty()
|
38 |
+
|
39 |
+
st.markdown(
|
40 |
+
"<h1 style='text-align:center; color:#00FFAF;'>π’ News Sentiment & Summarization</h1>",
|
41 |
+
unsafe_allow_html=True
|
42 |
+
)
|
43 |
+
|
44 |
+
if fetch_button and company_name:
|
45 |
+
response = get_news(NewsRequest(company=company_name))
|
46 |
+
articles = response["articles"]
|
47 |
+
|
48 |
+
if not articles:
|
49 |
+
st.warning("No news found for this company.")
|
50 |
+
return
|
51 |
+
|
52 |
+
# Calculate sentiment summary
|
53 |
+
sentiments = [article['sentiment'] for article in articles]
|
54 |
+
positive = sentiments.count("Positive")
|
55 |
+
negative = sentiments.count("Negative")
|
56 |
+
neutral = sentiments.count("Neutral")
|
57 |
+
|
58 |
+
sentiment_summary_placeholder.markdown(f"""
|
59 |
+
<div style='padding:10px; background-color:#222; border-radius:10px; color:white; text-align:center;'>
|
60 |
+
<h3>π Sentiment Summary</h3>
|
61 |
+
<p>β
Positive: <b style="color:lightgreen;">{positive}</b></p>
|
62 |
+
<p>β οΈ Neutral: <b style="color:orange;">{neutral}</b></p>
|
63 |
+
<p>β Negative: <b style="color:#FF4B4B;">{negative}</b></p>
|
64 |
+
</div>
|
65 |
+
""", unsafe_allow_html=True)
|
66 |
+
|
67 |
+
# all_headlines = ". ".join([article['title'] for article in articles])
|
68 |
+
# audio_file = text_to_speech(all_headlines)
|
69 |
+
# if audio_file:
|
70 |
+
# autoplay_audio(audio_file)
|
71 |
+
# Generate numbered headlines for audio
|
72 |
+
all_headlines = ". ".join([f"{idx + 1}. {article['title']}" for idx, article in enumerate(articles)])
|
73 |
+
audio_file = text_to_speech(all_headlines)
|
74 |
+
if audio_file:
|
75 |
+
autoplay_audio(audio_file)
|
76 |
+
|
77 |
+
|
78 |
+
st.write("## Latest News Articles")
|
79 |
+
|
80 |
+
for idx, article in enumerate(articles, start=1):
|
81 |
+
sentiment_color = {
|
82 |
+
"Positive": "#4CAF50",
|
83 |
+
"Neutral": "#FFA500",
|
84 |
+
"Negative": "#FF4B4B"
|
85 |
+
}[article['sentiment']]
|
86 |
+
|
87 |
+
st.markdown(f"""
|
88 |
+
<div style='
|
89 |
+
border-radius: 12px;
|
90 |
+
padding: 20px;
|
91 |
+
margin-bottom: 20px;
|
92 |
+
background: linear-gradient(145deg, #1f1f1f, #292929);
|
93 |
+
box-shadow: rgba(0,0,0,0.4) 0px 5px 15px;
|
94 |
+
color: #f1f1f1;
|
95 |
+
'>
|
96 |
+
<h4 style="color:#00FFAF;">π° {idx}. {article['title']}</h4>
|
97 |
+
<p><b>π Summary:</b> {article['summary']}</p>
|
98 |
+
<p><b>π‘ Sentiment:</b> <span style="color:{sentiment_color}; font-weight:bold;">{article['sentiment']}</span></p>
|
99 |
+
<p><b>π
Published At:</b> {article['published_at']}</p>
|
100 |
+
<a href="{article['link']}" target="_blank" style="color:#00FFAF; text-decoration:none;">π Read Full Article</a>
|
101 |
+
</div>
|
102 |
+
""", unsafe_allow_html=True)
|
103 |
+
elif not fetch_button:
|
104 |
+
st.info("Enter a company name in the sidebar and click 'Fetch News' to begin.")
|
105 |
+
|
106 |
+
if __name__ == "__main__":
|
107 |
+
main()
|