GHarshasri commited on
Commit
3040126
Β·
verified Β·
1 Parent(s): 6f0bb08

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +240 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,242 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ from PIL import Image
3
+ import os
4
+ import wikipedia
5
+ import csv
6
+ from datetime import datetime
7
 
8
+ # ====== Setup ======
9
+ USERS = {}
10
+ UPLOAD_FOLDER = "/tmp/uploads"
11
+ MEDIA_FOLDER = os.path.join(UPLOAD_FOLDER, "feedback_media")
12
+ FEEDBACK_FILE = os.path.join(UPLOAD_FOLDER, "feedback.csv")
13
+
14
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
15
+ os.makedirs(MEDIA_FOLDER, exist_ok=True)
16
+
17
+ STATES = {
18
+ "Telangana": ["Hyderabad", "Warangal", "Nizamabad", "Karimnagar", "Khammam"],
19
+ "Maharashtra": ["Mumbai", "Pune", "Nagpur", "Nashik", "Aurangabad"],
20
+ "Tamil Nadu": ["Chennai", "Coimbatore", "Madurai", "Tiruchirappalli", "Salem"],
21
+ "Karnataka": ["Bangalore", "Mysore", "Mangalore", "Hubli", "Belgaum"],
22
+ "Uttar Pradesh": ["Lucknow", "Varanasi", "Agra", "Kanpur", "Allahabad"],
23
+ "West Bengal": ["Kolkata", "Darjeeling", "Durgapur", "Siliguri", "Asansol"],
24
+ "Rajasthan": ["Jaipur", "Udaipur", "Jodhpur", "Bikaner", "Ajmer"],
25
+ "Gujarat": ["Ahmedabad", "Surat", "Vadodara", "Rajkot", "Bhavnagar"],
26
+ "Andhra Pradesh": ["Visakhapatnam", "Vijayawada", "Guntur", "Tirupati", "Kurnool"],
27
+ }
28
+
29
+ for key, default in {
30
+ "logged_in": False,
31
+ "email": "",
32
+ "otp_sent_to": None,
33
+ "otp_verified": False,
34
+ "login_email": None,
35
+ "place_image": None,
36
+ }.items():
37
+ if key not in st.session_state:
38
+ st.session_state[key] = default
39
+
40
+ # ====== Helper Functions ======
41
+
42
+ def send_otp(email):
43
+ st.session_state.otp_sent_to = email
44
+ st.session_state.otp_verified = False
45
+ return "1234"
46
+
47
+ def verify_otp(entered_otp):
48
+ if st.session_state.otp_sent_to and entered_otp == "1234":
49
+ st.session_state.logged_in = True
50
+ st.session_state.email = st.session_state.otp_sent_to
51
+ st.session_state.otp_verified = True
52
+ st.session_state.login_email = None
53
+ return True
54
+ return False
55
+
56
+ def logout():
57
+ for key in ["logged_in", "email", "otp_sent_to", "otp_verified", "login_email", "place_image"]:
58
+ st.session_state[key] = False if isinstance(st.session_state.get(key), bool) else None
59
+
60
+ def fetch_wikipedia_summary(title, lang="en"):
61
+ try:
62
+ wikipedia.set_lang(lang)
63
+ return wikipedia.summary(title, sentences=4)
64
+ except wikipedia.exceptions.DisambiguationError as e:
65
+ return f"Multiple results found for '{title}': {e.options}"
66
+ except wikipedia.exceptions.PageError:
67
+ return f"No Wikipedia page found for '{title}' in selected language."
68
+ except Exception as e:
69
+ return f"Error fetching summary: {str(e)}"
70
+
71
+ def save_temp_file(uploaded_file, filetype):
72
+ if uploaded_file:
73
+ filename = f"{filetype}_{datetime.now().strftime('%Y%m%d%H%M%S')}_{uploaded_file.name}"
74
+ filepath = os.path.join(MEDIA_FOLDER, filename)
75
+ with open(filepath, "wb") as f:
76
+ f.write(uploaded_file.read())
77
+ return filepath
78
+ return ""
79
+
80
+ def save_feedback(email, place, state, district, text, img_path="", audio_path="", video_path=""):
81
+ if not os.path.exists(FEEDBACK_FILE):
82
+ with open(FEEDBACK_FILE, 'w', newline='', encoding='utf-8') as f:
83
+ writer = csv.writer(f)
84
+ writer.writerow([
85
+ "user_email", "place_name", "state", "district", "feedback_text",
86
+ "image_file", "audio_file", "video_file", "timestamp"
87
+ ])
88
+
89
+ with open(FEEDBACK_FILE, 'a', newline='', encoding='utf-8') as f:
90
+ writer = csv.writer(f)
91
+ writer.writerow([
92
+ email, place, state, district, text,
93
+ img_path, audio_path, video_path, datetime.now().isoformat()
94
+ ])
95
+
96
+ # ====== Pages ======
97
+
98
+ def signup_page():
99
+ st.header("πŸš€ Signup")
100
+ name = st.text_input("Name")
101
+ email = st.text_input("Email (Gmail)")
102
+ contact = st.text_input("Contact Number")
103
+ if st.button("Sign Up"):
104
+ if email in USERS:
105
+ st.error("User already exists, please login.")
106
+ elif not email or not name:
107
+ st.error("Please enter name and email.")
108
+ else:
109
+ USERS[email] = {"name": name, "email": email, "contact": contact}
110
+ send_otp(email)
111
+ st.success(f"User {name} registered! OTP sent to {email} (simulated). Please verify OTP on Login page.")
112
+ st.session_state.login_email = email
113
+
114
+ def login_page():
115
+ st.header("πŸ” Login")
116
+ email = st.text_input("Email", key="login_email_input")
117
+ if st.button("Send OTP"):
118
+ if email in USERS:
119
+ send_otp(email)
120
+ st.success(f"OTP sent to {email} (simulated). Please enter OTP below.")
121
+ st.session_state.login_email = email
122
+ else:
123
+ st.error("Email not found. Please sign up first.")
124
+ if st.session_state.login_email == email:
125
+ otp = st.text_input("Enter OTP (use 1234 for demo)", type="password")
126
+ if st.button("Verify OTP"):
127
+ if verify_otp(otp):
128
+ st.success("OTP verified! Logged in successfully.")
129
+ else:
130
+ st.error("Incorrect OTP or no OTP sent.")
131
+
132
+ def main_app():
133
+ st.sidebar.success(f"Logged in as {st.session_state.email}")
134
+ if st.sidebar.button("Logout"):
135
+ logout()
136
+ st.experimental_rerun()
137
+
138
+ st.sidebar.markdown("---")
139
+ st.sidebar.subheader("πŸ“ Give Feedback")
140
+ feedback_text = st.sidebar.text_area("Your thoughts about this place", height=100)
141
+ feedback_image = st.sidebar.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
142
+ feedback_audio = st.sidebar.file_uploader("Upload audio", type=["mp3", "wav", "m4a"])
143
+ feedback_video = st.sidebar.file_uploader("Upload video", type=["mp4", "mov", "avi"])
144
+
145
+ if feedback_image:
146
+ st.sidebar.image(feedback_image, caption="Your uploaded image", use_container_width=True)
147
+ if feedback_audio:
148
+ st.sidebar.audio(feedback_audio, format=feedback_audio.type)
149
+ if feedback_video:
150
+ st.sidebar.video(feedback_video)
151
+
152
+ st.title("πŸ“š Gyana Vedika - Cultural Explorer")
153
+
154
+ state = st.selectbox("Select State", list(STATES.keys()))
155
+ district = st.selectbox("Select District", STATES[state])
156
+ st.subheader(f"Explore {district}, {state}")
157
+
158
+ uploaded_image = st.file_uploader("Upload a cultural/historical place image", type=["png", "jpg", "jpeg"])
159
+ if uploaded_image:
160
+ st.session_state["place_image"] = uploaded_image
161
+
162
+ place_to_search = None
163
+
164
+ if st.session_state["place_image"]:
165
+ st.image(st.session_state["place_image"], caption="Uploaded Image", use_container_width=True)
166
+ filename = st.session_state["place_image"].name.lower()
167
+ keywords_map = {
168
+ "charminar": "Charminar", "golconda": "Golconda Fort", "qutubshahi": "Qutb Shahi Tombs",
169
+ "birla": "Birla Mandir", "salarjung": "Salar Jung Museum", "warangal": "Warangal Fort",
170
+ "ramappa": "Ramappa Temple", "bhadrakali": "Bhadra Kali Temple", "kakatiya": "Kakatiya Kala Thoranam",
171
+ "pakhal": "Pakhal Lake", "medak": "Medak Cathedral", "nagarjuna": "Nagarjuna Sagar Dam",
172
+ "taj": "Taj Mahal", "gateway": "Gateway of India", "qutub": "Qutub Minar", "mysore": "Mysore Palace",
173
+ "hampi": "Hampi", "konark": "Konark Sun Temple", "varanasi": "Varanasi", "madurai": "Meenakshi Temple",
174
+ "ajanta": "Ajanta Caves", "ellora": "Ellora Caves",
175
+ }
176
+ for kw, place in keywords_map.items():
177
+ if kw in filename:
178
+ place_to_search = place
179
+ st.success(f"Recognized Place: {place_to_search}")
180
+ break
181
+ if not place_to_search:
182
+ st.warning("Could not recognize place. Try renaming the image file with landmark name.")
183
+
184
+ manual_place = st.text_input("Or manually enter place name to search info")
185
+ if manual_place.strip():
186
+ place_to_search = manual_place.strip()
187
+
188
+ if place_to_search:
189
+ language = st.selectbox("Select Wikipedia summary language", ["English", "Hindi", "Telugu", "Tamil", "Marathi", "Bengali"])
190
+ lang_codes = {"English": "en", "Hindi": "hi", "Telugu": "te", "Tamil": "ta", "Marathi": "mr", "Bengali": "bn"}
191
+ lang_code = lang_codes.get(language, "en")
192
+ if st.button(f"Get info about {place_to_search}"):
193
+ with st.spinner(f"Fetching Wikipedia summary for {place_to_search}..."):
194
+ summary = fetch_wikipedia_summary(place_to_search, lang=lang_code)
195
+ st.markdown(f"### Summary of {place_to_search}")
196
+ st.write(summary)
197
+
198
+ if st.sidebar.button("Submit Feedback"):
199
+ if feedback_text.strip():
200
+ img_path = save_temp_file(feedback_image, "img")
201
+ audio_path = save_temp_file(feedback_audio, "audio")
202
+ video_path = save_temp_file(feedback_video, "video")
203
+
204
+ save_feedback(
205
+ email=st.session_state.email,
206
+ place=place_to_search or "Unknown",
207
+ state=state,
208
+ district=district,
209
+ text=feedback_text.strip(),
210
+ img_path=img_path,
211
+ audio_path=audio_path,
212
+ video_path=video_path
213
+ )
214
+ st.sidebar.success("Thank you! Feedback submitted.")
215
+ else:
216
+ st.sidebar.warning("Please enter your feedback text.")
217
+
218
+ # ====== UI Styling ======
219
+ st.set_page_config(page_title="Gyana Vedika", layout="wide")
220
+ st.markdown("""
221
+ <style>
222
+ .stButton>button {
223
+ background-color: #008080; color: white; font-weight: bold; border-radius: 10px;
224
+ }
225
+ .stTextInput>div>input, .stSelectbox>div>div>select, .stTextArea>div>textarea {
226
+ border: 2px solid #008080 !important; border-radius: 8px !important;
227
+ }
228
+ h1, h2, h3, h4, h5, h6 {
229
+ color: #004d4d;
230
+ }
231
+ </style>
232
+ """, unsafe_allow_html=True)
233
+
234
+ # ====== Main Routing ======
235
+ if not st.session_state.logged_in:
236
+ page = st.sidebar.radio("Choose Option", ["Signup", "Login"])
237
+ if page == "Signup":
238
+ signup_page()
239
+ elif page == "Login":
240
+ login_page()
241
+ else:
242
+ main_app()