import streamlit as st # --- CRITICAL: set_page_config MUST BE THE FIRST STREAMLIT COMMAND --- st.set_page_config( page_title="భారత్ పల్స్ (BharatPulse) - వార్తలు", page_icon="📰", layout="wide", initial_sidebar_state="expanded" ) # --- Remaining Imports (after set_page_config) --- import feedparser import requests from bs4 import BeautifulSoup from newspaper import Article # Make sure newspaper3k and lxml_html_clean are installed # Removed torch, transformers imports for now to simplify import time # Removed geocoder import for now to simplify import json import datetime # --- Configuration --- TELUGU_CATEGORIES = { "జాతీయ వార్తలు": "National", "రాష్ట్ర వార్తలు": "State", "క్రైం": "Crime", "రాజకీయాలు": "Politics", "వ్యాపారం": "Business", "క్రీడలు": "Sports", "వినోదం": "Entertainment", "ఉద్యోగాలు": "Jobs", "వాతావరణం": "Weather", "వైరల్": "Viral", } # --- RSS Feed URLs --- # IMPORTANT: These URLs might be outdated or not provide full content. # You might need to find current, active RSS feeds for Telugu news sources. # Many news sites change their RSS feeds frequently or don't offer comprehensive ones. RSS_FEEDS = { "Sakshi": "https://www.sakshi.com/tags/rss", # Check if this still provides full content "Eenadu": "https://www.eenadu.net/telugu-news/rss", # This URL from search might be old/unofficial. # Add more reliable Telugu news RSS feeds here if the above don't work well # Example: "MyNewSource": "http://mynewsource.com/rss_feed_link", } # --- OpenWeatherMap API Configuration (for Realtime Weather) --- # YOUR ACTUAL API KEY IS SET HERE: OPENWEATHERMAP_API_KEY = "52f888dddede635f9b1d8a08141b5c49" OPENWEATHERMAP_API_URL = "http://api.openweathermap.org/data/2.5/weather" # --- Dummy Translation Function (Translation is temporarily disabled) --- def translate_en_to_te(text): return text # Just return the original text # --- RSS Feed Fetching and Parsing (Cached for performance) --- @st.cache_data(ttl=3600) # Cache for 1 hour to reduce API calls to news sites def get_news_from_rss(url): try: feed = feedparser.parse(url) articles = [] for entry in feed.entries: title = entry.title if hasattr(entry, 'title') else "" link = entry.link if hasattr(entry, 'link') else "#" summary = entry.summary if hasattr(entry, 'summary') and entry.summary.strip() else "" published = entry.published if hasattr(entry, 'published') else "N/A" image_url = None # Attempt to find image from media_content (common in some RSS feeds) if hasattr(entry, 'media_content') and entry.media_content: for media in entry.media_content: if 'url' in media and media.get('type', '').startswith('image'): image_url = media['url'] break # Attempt to find image from description HTML (common in others) elif hasattr(entry, 'description'): soup = BeautifulSoup(entry.description, 'html.parser') img_tag = soup.find('img') if img_tag and 'src' in img_tag.attrs: image_url = img_tag['src'] # Fallback to newspaper3k for better image/summary extraction from the article link if link and "http" in link and link != "#" and (not image_url or not summary): try: article_parser = Article(link) article_parser.download() article_parser.parse() if not image_url and article_parser.top_image: image_url = article_parser.top_image if not summary and article_parser.text: summary = article_parser.text[:200] + "..." if len(article_parser.text) > 200 else article_parser.text except Exception as e: pass # Silently fail if newspaper3k can't extract if title.strip() and link.strip() != "#": articles.append({ "title": title, "link": link, "summary": summary, "published": published, "image_url": image_url, "translated_title": None # Placeholder, will just be original title }) return articles except Exception as e: st.error(f"Error fetching news from {url}: {e}") return [] # --- Voice Search (Placeholder - requires a separate library/API) --- def voice_search_widget(): st.write("### 🎙️ వాయిస్ సెర్చ్ (Voice Search)") st.warning("Voice search integration with Whisper requires external setup (e.g., a local Whisper model, an API, or a custom Streamlit component). This is a placeholder.") audio_file = st.file_uploader("Upload an audio file (e.g., .wav, .mp3) for transcription:", type=["wav", "mp3"]) if audio_file: st.audio(audio_file, format="audio/wav") st.info("Transcribing audio... (This is a mock transcription)") st.write("ట్రాన్స్క్రిప్షన్: ఇది వాయిస్ సెర్చ్ కోసం ఒక నకిలీ ట్రాన్స్క్రిప్షన్ (Transcription: This is a mock transcription for voice search)") # --- Hardcoded Location (Bypasses ipinfo.io issues) --- @st.cache_data(ttl=3600) def get_user_location(): return "Hyderabad", "Telangana", "India" # --- Weather Integration --- @st.cache_data(ttl=600) def get_current_weather(city_name, api_key): if not api_key: # Check if API key is empty or None return None params = { 'q': city_name, 'appid': api_key, 'units': 'metric', 'lang': 'te' } try: response = requests.get(OPENWEATHERMAP_API_URL, params=params) response.raise_for_status() weather_data = response.json() main_weather = weather_data['weather'][0]['description'] if weather_data.get('weather') else "N/A" temperature = weather_data['main']['temp'] feels_like = weather_data['main']['feels_like'] humidity = weather_data['main']['humidity'] wind_speed = weather_data['wind']['speed'] weather_info = { "description": main_weather.capitalize(), "temperature": temperature, "feels_like": feels_like, "humidity": humidity, "wind_speed": wind_speed } return weather_info except requests.exceptions.RequestException as e: st.error(f"Error fetching weather for {city_name}: {e}. This might be due to an invalid city name or network issues.") return None except json.JSONDecodeError: st.error(f"Error decoding weather data for {city_name}. Invalid response from API.") return None except KeyError as e: st.error(f"Missing key in weather data for {city_name}: {e}. API response might be incomplete or unexpected.") return None # --- Custom CSS for card-like appearance, horizontal scrolling (no background color) --- st.markdown(""" """, unsafe_allow_html=True) st.title("భారత్ పల్స్ (BharatPulse) 🇮🇳") st.markdown("మీ స్థానిక మరియు జాతీయ వార్తల వన్-స్టాప్ మూలం (Your one-stop source for local and national news)") # Add "User Profile" to the main tabs main_tabs = st.tabs(["📰 Headlines", "📍 My Location", "🔍 Search City", "🎙️ Voice Search", "👤 User Profile"]) # Initialize session state variables for user profile details if 'user_name' not in st.session_state: st.session_state.user_name = "" if 'user_email' not in st.session_state: st.session_state.user_email = "" if 'user_location' not in st.session_state: st.session_state.user_location = "" if 'account_creation_date' not in st.session_state: st.session_state.account_creation_date = "N/A" # --- Tab 1: Headlines --- with main_tabs[0]: st.header("ప్రధాన వార్తలు (Headlines)") # Category selection for filtering st.markdown("##### వార్తల విభాగాలు (News Categories)") selected_category_tl = st.radio( "విభాగం ఎంచుకోండి (Select Category):", options=list(TELUGU_CATEGORIES.keys()), index=0, horizontal=True, key="headlines_category_select" ) st.markdown(f"**ఎంచుకున్న విభాగం:** {selected_category_tl}") st.markdown("---") all_articles = [] with st.spinner("వార్తలను లోడ్ చేస్తోంది... (Loading news...)"): for source_name, rss_url in RSS_FEEDS.items(): st.markdown(f"**{source_name} నుండి వార్తలు**") articles = get_news_from_rss(rss_url) for article in articles: # Since translation is disabled, translated_title is just the original title article['translated_title'] = article['title'] all_articles.extend(articles) if not all_articles: st.warning("వార్తలు లోడ్ చేయబడలేదు. దయచేసి మీ RSS ఫీడ్ URLలను తనిఖి చేయండి లేదా ఇంటర్నెట్ కనెక్షన్\u200cని తనిఖి చేయండి. (No news loaded. Please check your RSS feed URLs or internet connection.)") if all_articles: num_cols = 3 rows = [] for i in range(0, len(all_articles), num_cols): rows.append(all_articles[i:i + num_cols]) for row_articles in rows: cols = st.columns(num_cols) for i, article in enumerate(row_articles): with cols[i]: with st.container(): st.markdown(f'
', unsafe_allow_html=True) if article['image_url']: st.image(article['image_url'], use_column_width="always", caption="") st.markdown(f"### {article['title']}") # Always display original title st.markdown(f"

{article['summary']}

", unsafe_allow_html=True) st.markdown(f"[పూర్తిగా చదవండి (Read More)]({article['link']})", unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) # --- Tab 2: My Location --- with main_tabs[1]: st.header("📍 నా స్థానం (My Location)") user_city, user_state, user_country = get_user_location() st.write(f"మీ ప్రస్తుత స్థానం: **{user_city}, {user_state}, {user_country}**") st.subheader("నిజ-సమయ వాతావరణం + హెచ్చరికలు (Real-time Weather + Alerts)") weather_data = get_current_weather(user_city, OPENWEATHERMAP_API_KEY) if weather_data: st.metric(label="ఉష్ణోగ్రత (Temperature)", value=f"{weather_data['temperature']:.1f}°C", delta=f"Feels like {weather_data['feels_like']:.1f}°C") st.write(f"**పరిస్థితి (Condition):** {weather_data['description']}") st.write(f"**తేమ (Humidity):** {weather_data['humidity']}%") st.write(f"**గాలి వేగం (Wind Speed):** {weather_data['wind_speed']:.1f} m/s") st.info(f"'{user_city}' కోసం ప్రస్తుత వాతావరణం. (Current weather for '{user_city}').") else: st.info(f"'{user_city}' కోసం వాతావరణ డేటా అందుబాటులో లేదు. (Weather data not available for '{user_city}').") st.subheader("స్థానిక వార్తలు (Local News)") st.info(f"'{user_city}' కు సంబంధించిన స్థానిక వార్తలు ఇక్కడ ప్రదర్శించబడతాయి. (Local news for '{user_city}' will be displayed here.)") st.subheader("అలర్ట్స్ (Alerts)") st.info("స్థానిక హెచ్చరికలు ఇక్కడ ప్రదర్శించబడతాయి. (Local alerts will be displayed here.)") # --- Tab 3: Search City --- with main_tabs[2]: st.header("🔍 నగరాన్ని శోధించండి (Search City)") search_city = st.text_input("నగరం లేదా జిల్లా పేరును నమోదు చేయండి (Enter City or District Name):", "హైదరాబాద్", key="city_search_input") if st.button("వార్తలు శోధించండి (Search News)", key="search_city_button"): st.write(f"**'{search_city}'** కోసం వార్తలు లోడ్ అవుతున్నాయి... (Loading news for '{search_city}')...") st.subheader(f"వాతావరణం: {search_city} (Weather: {search_city})") weather_data_search = get_current_weather(search_city, OPENWEATHERMAP_API_KEY) if weather_data_search: st.metric(label="ఉష్ణోగ్రత (Temperature)", value=f"{weather_data_search['temperature']:.1f}°C", delta=f"Feels like {weather_data_search['feels_like']:.1f}°C") st.write(f"**పరిస్థితి (Condition):** {weather_data_search['description']}") st.write(f"**తేమ (Humidity):** {weather_data_search['humidity']}%") st.write(f"**గాలి వేగం (Wind Speed):** {weather_data_search['wind_speed']:.1f} m/s") else: st.info(f"'{search_city}' కోసం వాతావరణ డేటా అందుబాటులో లేదు. (Weather data not available for '{search_city}').") st.subheader(f"స్థానిక వార్తలు: {search_city} (Local News: {search_city})") st.warning("ఈ ఫీచర్ కోసం స్థానిక వార్తా వనరులను అనుసంధానించడం అవసరం. (This feature requires integration with local news sources.)") st.info(f"'{search_city}' కు సంబంధించిన వార్తలు ఇక్కడ ప్రదర్శించబడతాయి. (News for '{search_city}' will be displayed here.)") # --- Tab 4: Voice Search --- with main_tabs[3]: voice_search_widget() # --- Tab 5: User Profile (New Tab) --- with main_tabs[4]: st.header("👤 యూజర్ ప్రొఫైల్ (User Profile)") st.markdown("మీ ప్రొఫైల్ వివరాలు మరియు యాప్ వినియోగ విశ్లేషణలు (Your profile details and app usage analytics)") # User Input for Personal Details st.subheader("వ్యక్తిగత వివరాలు (Personal Details)") st.session_state.user_name = st.text_input( "పేరు (Name):", value=st.session_state.user_name, placeholder="మీ పేరు నమోదు చేయండి (Enter your name)", key="profile_name" ) st.session_state.user_email = st.text_input( "ఇమెయిల్ (Email):", value=st.session_state.user_email, placeholder="మీ ఇమెయిల్ నమోదు చేయండి (Enter your email)", key="profile_email" ) st.session_state.user_location = st.text_input( "స్థానం (Location):", value=st.session_state.user_location, placeholder="మీ స్థానం నమోదు చేయండి (Enter your location)", key="profile_location" ) if st.session_state.account_creation_date == "N/A" and st.session_state.user_name: st.session_state.account_creation_date = datetime.date.today().strftime("%B %d, %Y") st.write(f"**ఖాతా సృష్టించిన తేదీ (Account Created On):** {st.session_state.account_creation_date}") st.markdown("---") st.subheader("యాప్ వినియోగం (App Usage)") st.markdown("###### మీ వీక్షణలు (Your Views):") st.info("ఈ విభాగానికి వాస్తవ వినియోగదారు డేటా నిల్వ అవసరం. ఇవి ఉదాహరణ పాయింట్లు. (This section requires actual user data storage. These are example points.)") st.markdown(""" """, unsafe_allow_html=True) st.markdown("---") st.subheader("ప్రాధాన్యతలు (Preferences)") st.write("వార్తల వర్గం ప్రాధాన్యతలు (Preferred News Categories):") preferred_categories = st.multiselect( "మీ ప్రాధాన్యత గల వర్గాలను ఎంచుకోండి (Select your preferred categories):", options=list(TELUGU_CATEGORIES.keys()), default=["జాతీయ వార్తలు", "రాష్ట్ర వార్తలు", "వ్యాపారం"] ) st.write(f"మీరు ఎంచుకున్నవి: {', '.join(preferred_categories)}") st.write("వార్తా మూలాల ప్రాధాన్యతలు (Preferred News Sources):") preferred_sources = st.multiselect( "మీ ప్రాధాన్యత గల వార్తా మూలాలను ఎంచుకోండి (Select your preferred news sources):", options=list(RSS_FEEDS.keys()), default=["Sakshi"] ) st.write(f"మీరు ఎంచుకున్నవి: {', '.join(preferred_sources)}") st.info("ఈ ప్రాధాన్యతలు భవిష్యత్తులో మీ వార్తల ఫీడ్‌ను వ్యక్తిగతీకరించడానికి ఉపయోగించబడతాయి. (These preferences will be used to personalize your news feed in the future.)") st.sidebar.title("భారత్ పల్స్ - సెట్టింగ్‌లు") st.sidebar.info("ఇక్కడ మీరు యాప్ సెట్టింగ్‌లను కాన్ఫిగర్ చేయవచ్చు. (Here you can configure app settings.)") if st.sidebar.button("రీఫ్రెష్ వార్తలు", key="refresh_news_button"): st.cache_data.clear() # Clear all data caches (news, location, weather) # st.cache_resource.clear() # Commented out as translation model is removed st.rerun() # Rerun the app to load fresh data st.sidebar.success("వార్తలు రీఫ్రెష్ చేయబడ్డాయి!") st.sidebar.markdown("---") st.sidebar.markdown("© 2025 భారత్ పల్స్")