Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| from PIL import Image | |
| import wikipedia | |
| import csv | |
| from datetime import datetime | |
| import os | |
| # ====== Setup ====== | |
| USERS = {} | |
| UPLOAD_FOLDER = "uploads" | |
| MEDIA_FOLDER = os.path.join(UPLOAD_FOLDER, "feedback_media") | |
| FEEDBACK_FILE = os.path.join(UPLOAD_FOLDER, "feedback.csv") | |
| # Create folders if not exist | |
| os.makedirs(MEDIA_FOLDER, exist_ok=True) | |
| STATES = { | |
| "Telangana": ["Hyderabad", "Warangal", "Nizamabad", "Karimnagar", "Khammam"], | |
| "Maharashtra": ["Mumbai", "Pune", "Nagpur", "Nashik", "Aurangabad"], | |
| "Tamil Nadu": ["Chennai", "Coimbatore", "Madurai", "Tiruchirappalli", "Salem"], | |
| "Karnataka": ["Bangalore", "Mysore", "Mangalore", "Hubli", "Belgaum"], | |
| "Uttar Pradesh": ["Lucknow", "Varanasi", "Agra", "Kanpur", "Allahabad"], | |
| "West Bengal": ["Kolkata", "Darjeeling", "Durgapur", "Siliguri", "Asansol"], | |
| "Rajasthan": ["Jaipur", "Udaipur", "Jodhpur", "Bikaner", "Ajmer"], | |
| "Gujarat": ["Ahmedabad", "Surat", "Vadodara", "Rajkot", "Bhavnagar"], | |
| "Andhra Pradesh": ["Visakhapatnam", "Vijayawada", "Guntur", "Tirupati", "Kurnool"], | |
| } | |
| # ====== Session State Initialization ====== | |
| for key, default in { | |
| "logged_in": False, | |
| "email": "", | |
| "otp_sent_to": None, | |
| "otp_verified": False, | |
| "login_email": None, | |
| }.items(): | |
| if key not in st.session_state: | |
| st.session_state[key] = default | |
| # ====== Helper Functions ====== | |
| def send_otp(email): | |
| st.session_state.otp_sent_to = email | |
| st.session_state.otp_verified = False | |
| return "1234" | |
| def verify_otp(entered_otp): | |
| if st.session_state.otp_sent_to and entered_otp == "1234": | |
| st.session_state.logged_in = True | |
| st.session_state.email = st.session_state.otp_sent_to | |
| st.session_state.otp_verified = True | |
| st.session_state.login_email = None | |
| return True | |
| return False | |
| def logout(): | |
| for key in ["logged_in", "email", "otp_sent_to", "otp_verified", "login_email"]: | |
| st.session_state[key] = False if isinstance(st.session_state.get(key), bool) else None | |
| def fetch_wikipedia_summary(title, lang="en"): | |
| try: | |
| wikipedia.set_lang(lang) | |
| return wikipedia.summary(title, sentences=4) | |
| except wikipedia.exceptions.DisambiguationError as e: | |
| return f"Multiple results found for '{title}': {e.options}" | |
| except wikipedia.exceptions.PageError: | |
| return f"No Wikipedia page found for '{title}' in selected language." | |
| except Exception as e: | |
| return f"Error fetching summary: {str(e)}" | |
| def save_temp_file(uploaded_file, filetype): | |
| if uploaded_file: | |
| filename = f"{filetype}_{datetime.now().strftime('%Y%m%d%H%M%S')}_{uploaded_file.name}" | |
| filepath = os.path.join(MEDIA_FOLDER, filename) | |
| with open(filepath, "wb") as f: | |
| f.write(uploaded_file.getbuffer()) | |
| return filepath | |
| return "" | |
| def save_feedback(email, place, state, district, text, img_path="", audio_path="", video_path=""): | |
| if not os.path.exists(FEEDBACK_FILE): | |
| with open(FEEDBACK_FILE, 'w', newline='', encoding='utf-8') as f: | |
| writer = csv.writer(f) | |
| writer.writerow([ | |
| "user_email", "place_name", "state", "district", "feedback_text", | |
| "image_file", "audio_file", "video_file", "timestamp" | |
| ]) | |
| with open(FEEDBACK_FILE, 'a', newline='', encoding='utf-8') as f: | |
| writer = csv.writer(f) | |
| writer.writerow([ | |
| email, place, state, district, text, | |
| img_path, audio_path, video_path, datetime.now().isoformat() | |
| ]) | |
| # ====== Pages ====== | |
| def signup_page(): | |
| st.header("π Signup") | |
| name = st.text_input("Name") | |
| email = st.text_input("Email (Gmail)") | |
| contact = st.text_input("Contact Number") | |
| if st.button("Sign Up"): | |
| if email in USERS: | |
| st.error("User already exists, please login.") | |
| elif not email or not name: | |
| st.error("Please enter name and email.") | |
| else: | |
| USERS[email] = {"name": name, "email": email, "contact": contact} | |
| send_otp(email) | |
| st.success(f"User {name} registered! OTP sent to {email} (simulated). Please verify OTP on Login page.") | |
| st.session_state.login_email = email | |
| def login_page(): | |
| st.header("π Login") | |
| email = st.text_input("Email", key="login_email_input") | |
| if st.button("Send OTP"): | |
| if email in USERS: | |
| send_otp(email) | |
| st.success(f"OTP sent to {email} (simulated). Please enter OTP below.") | |
| st.session_state.login_email = email | |
| else: | |
| st.error("Email not found. Please sign up first.") | |
| if st.session_state.login_email == email: | |
| otp = st.text_input("Enter OTP (use 1234 for demo)", type="password") | |
| if st.button("Verify OTP"): | |
| if verify_otp(otp): | |
| st.success("OTP verified! Logged in successfully.") | |
| else: | |
| st.error("Incorrect OTP or no OTP sent.") | |
| def main_app(): | |
| st.sidebar.success(f"Logged in as {st.session_state.email}") | |
| if st.sidebar.button("Logout"): | |
| logout() | |
| st.experimental_rerun() | |
| # Feedback inputs on left sidebar | |
| st.sidebar.markdown("---") | |
| st.sidebar.subheader("π Give Feedback") | |
| feedback_text = st.sidebar.text_area("Your thoughts about this place", height=100) | |
| feedback_image = st.sidebar.file_uploader("Upload an image", type=["jpg", "jpeg", "png"]) | |
| feedback_audio = st.sidebar.file_uploader("Upload audio", type=["mp3", "wav", "m4a"]) | |
| feedback_video = st.sidebar.file_uploader("Upload video", type=["mp4", "mov", "avi"]) | |
| if feedback_image: | |
| st.sidebar.image(feedback_image, caption="Your uploaded image", use_container_width=True) | |
| if feedback_audio: | |
| st.sidebar.audio(feedback_audio, format=feedback_audio.type) | |
| if feedback_video: | |
| st.sidebar.video(feedback_video) | |
| st.title("π Gyana Vedika - Cultural Explorer") | |
| state = st.selectbox("Select State", list(STATES.keys())) | |
| district = st.selectbox("Select District", STATES[state]) | |
| st.subheader(f"Explore {district}, {state}") | |
| uploaded_image = st.file_uploader("Upload a cultural/historical place image", type=["png", "jpg", "jpeg"]) | |
| place_to_search = None | |
| if uploaded_image: | |
| st.image(uploaded_image, caption="Uploaded Image", use_container_width=True) | |
| filename = uploaded_image.name.lower() | |
| keywords_map = { | |
| "Charminar": "Charminar", | |
| "Golconda Fort": "Golconda Fort", | |
| "Qutb Shahi Tombs": "Qutb Shahi Tombs", | |
| "Birla Mandir": "Birla Mandir", | |
| "Salar Jung Museum": "Salar Jung Museum", | |
| "Warangal Fort": "Warangal Fort", | |
| "Ramappa Temple": "Ramappa Temple", | |
| "Bhadra Kali Temple": "Bhadra Kali Temple", | |
| "Kakatiya Kala Thoranam": "Kakatiya Kala Thoranam", | |
| "Pakhal Lake": "Pakhal Lake", | |
| "Medak Cathedral": "Medak Cathedral", | |
| "Nagarjuna Sagar Dam": "Nagarjuna Sagar Dam", | |
| "Alampur Jogulamba Temple": "Alampur Jogulamba Temple", | |
| "Kulpakji Jain Temple": "Kulpakji Jain Temple", | |
| "Chowmahalla Palace": "Chowmahalla Palace", | |
| "Falaknuma Palace": "Falaknuma Palace", | |
| "Osman Sagar": "Osman Sagar", | |
| "Bhadradri Temple": "Bhadradri Temple", | |
| "Nizamabad Fort": "Nizamabad Fort", | |
| "Paigah Tombs": "Paigah Tombs", | |
| "Mahbubnagar Fort": "Mahbubnagar Fort", | |
| "Kuntala Waterfall": "Kuntala Waterfall", | |
| "Ujjaini Mahakali Temple": "Ujjaini Mahakali Temple", | |
| "Basara Saraswathi Temple": "Basara Saraswathi Temple", | |
| "Yadagirigutta Temple": "Yadagirigutta Temple", | |
| "Kaleshwaram Temple": "Kaleshwaram Temple" | |
| } | |
| for kw, place in keywords_map.items(): | |
| if kw in filename: | |
| place_to_search = place | |
| st.success(f"Recognized Place: {place_to_search}") | |
| break | |
| if not place_to_search: | |
| st.warning("Could not recognize place. Try renaming the image file with landmark name.") | |
| manual_place = st.text_input("Or manually enter place name to search info") | |
| if manual_place.strip(): | |
| place_to_search = manual_place.strip() | |
| if place_to_search: | |
| language = st.selectbox("Select Wikipedia summary language", ["English", "Hindi", "Telugu", "Tamil", "Marathi", "Bengali"]) | |
| lang_codes = {"English": "en", "Hindi": "hi", "Telugu": "te", "Tamil": "ta", "Marathi": "mr", "Bengali": "bn"} | |
| lang_code = lang_codes.get(language, "en") | |
| if st.button(f"Get info about {place_to_search}"): | |
| with st.spinner(f"Fetching Wikipedia summary for {place_to_search}..."): | |
| summary = fetch_wikipedia_summary(place_to_search, lang=lang_code) | |
| st.markdown(f"### Summary of {place_to_search}") | |
| st.write(summary) | |
| if st.sidebar.button("Submit Feedback"): | |
| if feedback_text.strip(): | |
| img_path = save_temp_file(feedback_image, "img") | |
| audio_path = save_temp_file(feedback_audio, "audio") | |
| video_path = save_temp_file(feedback_video, "video") | |
| save_feedback( | |
| email=st.session_state.email, | |
| place=place_to_search or "Unknown", | |
| state=state, | |
| district=district, | |
| text=feedback_text.strip(), | |
| img_path=img_path, | |
| audio_path=audio_path, | |
| video_path=video_path | |
| ) | |
| st.sidebar.success("Thank you! Feedback submitted.") | |
| else: | |
| st.sidebar.warning("Please enter your feedback text.") | |
| # ====== UI Styling ====== | |
| st.set_page_config(page_title="Gyana Vedika", layout="wide") | |
| st.markdown(""" | |
| <style> | |
| .stButton>button { | |
| background-color: #008080; color: white; font-weight: bold; border-radius: 10px; | |
| } | |
| .stTextInput>div>input, .stSelectbox>div>div>select, .stTextArea>div>textarea { | |
| border: 2px solid #008080 !important; border-radius: 8px !important; | |
| } | |
| h1, h2, h3, h4, h5, h6 { | |
| color: #004d4d; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| if not st.session_state.logged_in: | |
| page = st.sidebar.radio("Choose Option", ["Signup", "Login"]) | |
| if page == "Signup": | |
| signup_page() | |
| elif page == "Login": | |
| login_page() | |
| else: | |
| main_app() | |