Navya-Sree commited on
Commit
d77f015
Β·
verified Β·
1 Parent(s): b532707

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +304 -122
app.py CHANGED
@@ -1,134 +1,316 @@
1
- # utils.py
2
- from transformers import pipeline
3
- from gtts import gTTS
4
- import speech_recognition as sr
5
- import io
6
- import requests
7
- import json
8
  import os
9
- from datetime import datetime
10
- import streamlit as st
 
 
 
 
 
11
 
12
- # Initialize AI models
13
- @st.cache_resource
14
- def load_ai_models():
15
- return {
16
- "text_gen": pipeline("text-generation", model="gpt2"),
17
- "sentiment": pipeline("sentiment-analysis"),
18
- "summarization": pipeline("summarization", model="facebook/bart-large-cnn")
19
- }
20
 
21
- # Text-to-speech
22
- def text_to_speech(text, lang="en"):
23
- try:
24
- tts = gTTS(text=text, lang=lang)
25
- audio_bytes = io.BytesIO()
26
- tts.write_to_fp(audio_bytes)
27
- audio_bytes.seek(0)
28
- return audio_bytes
29
- except Exception as e:
30
- print(f"Text-to-speech error: {e}")
31
- return None
32
 
33
- # Speech-to-text
34
- def speech_to_text(audio_path):
35
- try:
36
- r = sr.Recognizer()
37
- with sr.AudioFile(audio_path) as source:
38
- audio = r.record(source)
39
- return r.recognize_google(audio)
40
- except Exception as e:
41
- print(f"Speech-to-text error: {e}")
42
- return "Could not understand audio"
 
 
 
 
 
 
 
 
 
43
 
44
- # Weather API (using Open-Meteo)
45
- def get_weather_forecast(date):
46
  try:
47
- # Convert date to string in YYYY-MM-DD format
48
- date_str = date.strftime("%Y-%m-%d")
49
-
50
- # Get latitude and longitude for a central location (New York as default)
51
- latitude = 40.7128
52
- longitude = -74.0060
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
- # Make API request
55
- url = f"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&daily=weathercode,temperature_2m_max,temperature_2m_min&timezone=auto&start_date={date_str}&end_date={date_str}"
56
- response = requests.get(url)
57
- data = response.json()
58
 
59
- # Extract weather data
60
- if "daily" in data:
61
- temp_max = data["daily"]["temperature_2m_max"][0]
62
- temp_min = data["daily"]["temperature_2m_min"][0]
63
- weather_code = data["daily"]["weathercode"][0]
64
 
65
- # Convert weather code to description
66
- weather_descriptions = {
67
- 0: "Clear sky",
68
- 1: "Mainly clear",
69
- 2: "Partly cloudy",
70
- 3: "Overcast",
71
- 45: "Fog",
72
- 48: "Depositing rime fog",
73
- 51: "Light drizzle",
74
- 53: "Moderate drizzle",
75
- 55: "Dense drizzle",
76
- 56: "Light freezing drizzle",
77
- 57: "Dense freezing drizzle",
78
- 61: "Slight rain",
79
- 63: "Moderate rain",
80
- 65: "Heavy rain",
81
- 66: "Light freezing rain",
82
- 67: "Heavy freezing rain",
83
- 71: "Slight snow",
84
- 73: "Moderate snow",
85
- 75: "Heavy snow",
86
- 77: "Snow grains",
87
- 80: "Slight rain showers",
88
- 81: "Moderate rain showers",
89
- 82: "Violent rain showers",
90
- 85: "Slight snow showers",
91
- 86: "Heavy snow showers",
92
- 95: "Thunderstorm",
93
- 96: "Thunderstorm with slight hail",
94
- 99: "Thunderstorm with heavy hail"
95
- }
96
 
97
- weather_desc = weather_descriptions.get(weather_code, "Unknown")
98
- return f"{weather_desc}, High: {temp_max}Β°C, Low: {temp_min}Β°C"
99
-
100
- return "Weather data unavailable"
101
- except Exception as e:
102
- print(f"Weather API error: {e}")
103
- return "Weather service unavailable"
104
-
105
- # AI analysis
106
- def generate_ai_response(prompt):
107
- try:
108
- models = load_ai_models()
109
-
110
- # Generate insights
111
- insights = models["text_gen"](
112
- f"Analyze this reminder and provide helpful suggestions: {prompt}",
113
- max_length=200,
114
- num_return_sequences=1
115
- )[0]['generated_text']
116
-
117
- # Sentiment analysis
118
- sentiment = models["sentiment"](prompt[:512])[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
- # Summarization
121
- summary = models["summarization"](
122
- insights,
123
- max_length=100,
124
- min_length=30,
125
- do_sample=False
126
- )[0]['summary_text']
127
 
128
- # Format final response
129
- return (f"**AI Summary**: {summary}\n\n"
130
- f"**Sentiment**: {sentiment['label']} (confidence: {sentiment['score']:.0%})\n\n"
131
- f"**Detailed Analysis**:\n{insights}")
132
- except Exception as e:
133
- print(f"AI analysis error: {e}")
134
- return "AI insights unavailable at this time"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
+ # Fix Hugging Face Spaces permissions - Comprehensive solution
3
+ os.environ['STREAMLIT_GLOBAL_METRICS'] = '0'
4
+ os.environ['STREAMLIT_SERVER_ENABLE_STATIC_SERVE'] = '1'
5
+ os.environ['STREAMLIT_GLOBAL_DEVELOPMENT_MODE'] = '0'
6
+ os.environ['STREAMLIT_GLOBAL_CONFIG_DIR'] = '/tmp' # Redirect config directory
7
+ os.environ['STREAMLIT_GLOBAL_DATA_DIR'] = '/tmp' # Redirect data directory
8
+ os.environ['HOME'] = '/tmp' # Redirect home directory
9
 
10
+ # Prevent Streamlit from writing to protected directories
11
+ import streamlit.runtime.metrics_util
12
+ def patched_get_machine_id_v4():
13
+ return "anonymous-id"
14
+ streamlit.runtime.metrics_util._get_machine_id_v4 = patched_get_machine_id_v4
 
 
 
15
 
16
+ import streamlit
17
+ import json
18
+ import time
19
+ import base64
20
+ import threading
21
+ from datetime import datetime, timedelta
22
+ from utils import text_to_speech, speech_to_text, generate_ai_response, get_weather_forecast
23
+ from streamlit_mic_recorder import mic_recorder
 
 
 
24
 
25
+ # Create data directories
26
+ DATA_DIR = "data"
27
+ os.makedirs(DATA_DIR, exist_ok=True)
28
+ VOICE_DIR = os.path.join(DATA_DIR, "voice_notes")
29
+ os.makedirs(VOICE_DIR, exist_ok=True)
30
+ DATA_FILE = os.path.join(DATA_DIR, "reminders.json")
31
+
32
+ # Initialize session state
33
+ def init_session():
34
+ if "reminders" not in st.session_state:
35
+ st.session_state.reminders = load_reminders()
36
+ if "ai_enabled" not in st.session_state:
37
+ st.session_state.ai_enabled = True
38
+ if "weather_enabled" not in st.session_state:
39
+ st.session_state.weather_enabled = True
40
+ if "voice_notes" not in st.session_state:
41
+ st.session_state.voice_notes = {}
42
+ if "notifications" not in st.session_state:
43
+ st.session_state.notifications = []
44
 
45
+ # Data management
46
+ def load_reminders():
47
  try:
48
+ if os.path.exists(DATA_FILE):
49
+ with open(DATA_FILE, "r") as f:
50
+ return json.load(f)
51
+ return []
52
+ except json.JSONDecodeError:
53
+ return []
54
+
55
+ def save_reminders():
56
+ with open(DATA_FILE, "w") as f:
57
+ json.dump(st.session_state.reminders, f)
58
+
59
+ # Voice functions
60
+ def save_voice_note(audio_bytes, reminder_id):
61
+ filename = f"{VOICE_DIR}/{reminder_id}_{int(time.time())}.wav"
62
+ with open(filename, "wb") as f:
63
+ f.write(audio_bytes)
64
+ return filename
65
+
66
+ def play_voice_note(path):
67
+ if os.path.exists(path):
68
+ with open(path, "rb") as f:
69
+ audio_bytes = f.read()
70
+ st.audio(audio_bytes, format="audio/wav")
71
+ else:
72
+ st.warning("Voice note file not found")
73
+
74
+ # Notification system
75
+ def check_reminders():
76
+ while True:
77
+ now = datetime.now()
78
+ for reminder in st.session_state.reminders:
79
+ if not reminder.get('completed') and not reminder.get('notification_sent'):
80
+ try:
81
+ due_time = datetime.strptime(reminder['due_time'], "%H:%M:%S.%f").time() if '.' in reminder['due_time'] else datetime.strptime(reminder['due_time'], "%H:%M:%S").time()
82
+ due_date = datetime.strptime(reminder['due_date'], "%Y-%m-%d").date()
83
+
84
+ if due_date == now.date() and due_time.hour == now.hour and due_time.minute == now.minute:
85
+ # Create notification
86
+ notification = {
87
+ "id": int(time.time() * 1000),
88
+ "reminder_id": reminder['id'],
89
+ "title": reminder['title'],
90
+ "time": str(now),
91
+ "dismissed": False
92
+ }
93
+
94
+ st.session_state.notifications.append(notification)
95
+ reminder['notification_sent'] = True
96
+ save_reminders()
97
+
98
+ # Play notification
99
+ if reminder.get('voice_note') and os.path.exists(reminder['voice_note']):
100
+ threading.Thread(target=play_voice_note, args=(reminder['voice_note'],)).start()
101
+ else:
102
+ threading.Thread(
103
+ target=lambda: st.toast(f"πŸ”” Reminder: {reminder['title']}"),
104
+ daemon=True
105
+ ).start()
106
+ except Exception as e:
107
+ print(f"Notification error: {e}")
108
+ time.sleep(60) # Check every minute
109
+
110
+ # Start notification thread
111
+ if "notification_thread" not in st.session_state:
112
+ st.session_state.notification_thread = threading.Thread(target=check_reminders, daemon=True)
113
+ st.session_state.notification_thread.start()
114
+
115
+ # Main app
116
+ def main():
117
+ st.set_page_config(
118
+ page_title="AI-Powered Reminder System",
119
+ layout="wide",
120
+ page_icon="⏰"
121
+ )
122
+ init_session()
123
+
124
+ # Sidebar
125
+ with st.sidebar:
126
+ st.header("βš™οΈ System Settings")
127
+ st.session_state.ai_enabled = st.checkbox("Enable AI Insights", value=True)
128
+ st.session_state.weather_enabled = st.checkbox("Show Weather Forecast", value=True)
129
 
130
+ st.divider()
 
 
 
131
 
132
+ st.header("πŸ“ Add New Reminder")
133
+ with st.form("new_reminder", clear_on_submit=True):
134
+ title = st.text_input("Title*", placeholder="What to remember?")
135
+ description = st.text_area("Description", placeholder="Details...")
 
136
 
137
+ col1, col2 = st.columns(2)
138
+ due_date = col1.date_input("Date*", min_value=datetime.today())
139
+ due_time = col2.time_input("Time*", value=datetime.now().time())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
+ priority = st.select_slider("Priority", ["Low", "Medium", "High"], value="Medium")
142
+ voice_note = st.checkbox("Add Voice Reminder")
143
+
144
+ # Voice recorder
145
+ audio_bytes = None
146
+ if voice_note:
147
+ audio = mic_recorder(
148
+ start_prompt="⏺️ Start Recording",
149
+ stop_prompt="⏹️ Stop Recording",
150
+ key=f"recorder_{int(time.time())}"
151
+ )
152
+ if audio and 'bytes' in audio:
153
+ audio_bytes = audio['bytes']
154
+ if audio_bytes:
155
+ st.audio(audio_bytes, format="audio/wav")
156
+
157
+ submitted = st.form_submit_button("Create Reminder")
158
+ if submitted and title:
159
+ new_reminder = {
160
+ "id": int(time.time() * 1000),
161
+ "title": title,
162
+ "description": description,
163
+ "due_date": str(due_date),
164
+ "due_time": str(due_time),
165
+ "priority": priority,
166
+ "created_at": str(datetime.now()),
167
+ "completed": False,
168
+ "voice_note": ""
169
+ }
170
+
171
+ if voice_note and audio_bytes:
172
+ voice_path = save_voice_note(audio_bytes, new_reminder["id"])
173
+ new_reminder["voice_note"] = voice_path
174
+
175
+ if st.session_state.ai_enabled:
176
+ with st.spinner("Generating AI insights..."):
177
+ new_reminder["ai_insights"] = generate_ai_response(
178
+ f"Reminder: {title}. Description: {description}. "
179
+ f"Due: {due_date} at {due_time}. Priority: {priority}"
180
+ )
181
+
182
+ st.session_state.reminders.append(new_reminder)
183
+ save_reminders()
184
+ st.success("Reminder created successfully!")
185
+ st.experimental_rerun()
186
+
187
+ # Main interface
188
+ st.title("⏰ AI-Powered Reminder System")
189
+
190
+ # Dashboard
191
+ col1, col2, col3 = st.columns(3)
192
+ pending = sum(1 for r in st.session_state.reminders if not r.get('completed', False))
193
+ high_priority = sum(1 for r in st.session_state.reminders if not r.get('completed', False) and r.get('priority') == "High")
194
+
195
+ with col1:
196
+ st.metric("Total Reminders", len(st.session_state.reminders))
197
+ with col2:
198
+ st.metric("Pending Tasks", pending)
199
+ with col3:
200
+ st.metric("High Priority", high_priority)
201
+
202
+ # Notifications
203
+ if st.session_state.notifications:
204
+ with st.expander("πŸ”” Active Notifications", expanded=True):
205
+ for notification in st.session_state.notifications[:]:
206
+ if not notification.get('dismissed', False):
207
+ st.warning(f"{notification['title']} - {notification['time'][11:16]}")
208
+ if st.button("Dismiss", key=f"dismiss_{notification['id']}"):
209
+ notification['dismissed'] = True
210
+ # Update the original reminder
211
+ for reminder in st.session_state.reminders:
212
+ if reminder['id'] == notification['reminder_id']:
213
+ reminder['notification_sent'] = False
214
+ st.experimental_rerun()
215
+
216
+ # Calendar view
217
+ with st.expander("πŸ“… Calendar View", expanded=True):
218
+ selected_date = st.date_input("View reminders for", value=datetime.today(), key="calendar_date")
219
+ date_reminders = [r for r in st.session_state.reminders
220
+ if datetime.strptime(r["due_date"], "%Y-%m-%d").date() == selected_date]
221
 
222
+ if st.session_state.weather_enabled:
223
+ try:
224
+ weather = get_weather_forecast(selected_date)
225
+ st.info(f"🌀️ Weather Forecast: {weather}")
226
+ except:
227
+ st.warning("Weather service unavailable")
 
228
 
229
+ if not date_reminders:
230
+ st.info("No reminders for selected date")
231
+ else:
232
+ for r in date_reminders:
233
+ with st.container(border=True):
234
+ cols = st.columns([0.7, 3, 1])
235
+ cols[0].checkbox(
236
+ f"Done {r['id']}",
237
+ value=r.get("completed", False),
238
+ key=f"completed_{r['id']}",
239
+ on_change=lambda id=r['id']: update_completion(id)
240
+ )
241
+
242
+ with cols[1]:
243
+ st.subheader(r["title"])
244
+ st.caption(f"⏰ {r['due_time'][:5]} | {r['priority']} priority")
245
+
246
+ if r.get("description"):
247
+ st.write(r["description"])
248
+
249
+ if r.get("voice_note"):
250
+ st.write("Voice Reminder:")
251
+ play_voice_note(r["voice_note"])
252
+
253
+ if st.session_state.ai_enabled and r.get("ai_insights"):
254
+ with st.expander("πŸ€– AI Insights"):
255
+ st.write(r["ai_insights"])
256
+
257
+ with cols[2]:
258
+ if st.button("πŸ—‘οΈ", key=f"delete_{r['id']}"):
259
+ delete_reminder(r["id"])
260
+
261
+ # Upcoming reminders
262
+ st.subheader("🚨 Upcoming Alerts (Next 7 Days)")
263
+ today = datetime.today().date()
264
+ next_week = today + timedelta(days=7)
265
+
266
+ upcoming = sorted(
267
+ [r for r in st.session_state.reminders
268
+ if not r.get('completed', False) and
269
+ today <= datetime.strptime(r["due_date"], "%Y-%m-%d").date() <= next_week],
270
+ key=lambda x: (x["due_date"], x["due_time"])
271
+ )
272
+
273
+ if not upcoming:
274
+ st.info("No upcoming reminders in the next week")
275
+ else:
276
+ for r in upcoming:
277
+ due_date = datetime.strptime(r["due_date"], "%Y-%m-%d").date()
278
+ days_left = (due_date - today).days
279
+ days_text = "today" if days_left == 0 else f"in {days_left} days"
280
+
281
+ with st.container(border=True):
282
+ cols = st.columns([3, 1])
283
+ cols[0].subheader(r["title"])
284
+ cols[0].caption(f"πŸ“… {r['due_date']} at {r['due_time'][:5]} ({days_text}) | {r['priority']} priority")
285
+
286
+ if r.get("description"):
287
+ cols[0].write(r["description"])
288
+
289
+ with cols[1]:
290
+ if st.button("Complete", key=f"complete_{r['id']}"):
291
+ complete_reminder(r['id'])
292
+ st.experimental_rerun()
293
+
294
+ # Helper functions
295
+ def update_completion(reminder_id):
296
+ for r in st.session_state.reminders:
297
+ if r["id"] == reminder_id:
298
+ r["completed"] = st.session_state[f"completed_{reminder_id}"]
299
+ if r['completed']:
300
+ r['completion_time'] = str(datetime.now())
301
+ save_reminders()
302
+
303
+ def complete_reminder(reminder_id):
304
+ for r in st.session_state.reminders:
305
+ if r["id"] == reminder_id:
306
+ r["completed"] = True
307
+ r['completion_time'] = str(datetime.now())
308
+ save_reminders()
309
+
310
+ def delete_reminder(reminder_id):
311
+ st.session_state.reminders = [r for r in st.session_state.reminders if r["id"] != reminder_id]
312
+ save_reminders()
313
+ st.experimental_rerun()
314
+
315
+ if __name__ == "__main__":
316
+ main()