Update app.py
Browse files
app.py
CHANGED
@@ -10,6 +10,7 @@ import logging
|
|
10 |
import requests
|
11 |
import random
|
12 |
import backoff
|
|
|
13 |
|
14 |
# Configure logging
|
15 |
logging.basicConfig(level=logging.INFO)
|
@@ -36,20 +37,20 @@ app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True
|
|
36 |
|
37 |
# Daily messages based on the day of the week (with Bhagavad Gita verses)
|
38 |
DAILY_MESSAGES = {
|
39 |
-
0: {"message": "On Sundays,
|
40 |
-
1: {"message": "Monday
|
41 |
-
2: {"message": "Tuesday
|
42 |
-
3: {"message": "Wednesday
|
43 |
-
4: {"message": "Thursday
|
44 |
-
5: {"message": "Friday
|
45 |
-
6: {"message": "Saturday
|
46 |
}
|
47 |
|
48 |
# Festival messages for specific dates
|
49 |
FESTIVAL_MESSAGES = {
|
50 |
(1, 26): {"message": "Happy Republic Day! Let Dharma guide our nation.", "verse": "Bhagavad Gita 4.7", "special": True},
|
51 |
(8, 19): {"message": "Happy Krishna Janmashtami! Celebrate the divine birth.", "verse": "Bhagavad Gita 4.9", "special": True},
|
52 |
-
(4, 19): {"message": "
|
53 |
}
|
54 |
|
55 |
def parse_huggingface_response(response):
|
@@ -72,16 +73,15 @@ def get_daily_message_and_blessing():
|
|
72 |
"""Retrieve the daily message and blessing based on the current date."""
|
73 |
try:
|
74 |
today = datetime.now()
|
75 |
-
day_of_week = (today.weekday() + 1) % 7
|
76 |
month_day = (today.month, today.day)
|
77 |
|
78 |
-
# Check for festival messages
|
79 |
if month_day in FESTIVAL_MESSAGES:
|
80 |
daily_message = FESTIVAL_MESSAGES[month_day]
|
81 |
else:
|
82 |
daily_message = DAILY_MESSAGES.get(day_of_week,
|
83 |
-
{"message": "Seek the divine
|
84 |
-
"verse": "Bhagavad Gita 6.30"})
|
85 |
daily_message['special'] = False
|
86 |
|
87 |
daily_blessing_index = (today.day - 1) % len(daily_blessings)
|
@@ -96,15 +96,15 @@ def get_daily_message_and_blessing():
|
|
96 |
except Exception as e:
|
97 |
logger.error(f"Error in get_daily_message_and_blessing: {str(e)}")
|
98 |
return {
|
99 |
-
"message": "Seek the divine
|
100 |
"verse": "Bhagavad Gita 6.30",
|
101 |
"is_special": False,
|
102 |
-
"blessing": "Hare Manavi! May Vrindavan’s joy fill your heart
|
103 |
}
|
104 |
|
105 |
@backoff.on_exception(backoff.expo, (requests.exceptions.RequestException, requests.exceptions.HTTPError), max_tries=12, max_time=900)
|
106 |
def make_api_request(url, headers, payload, timeout=180):
|
107 |
-
"""
|
108 |
try:
|
109 |
response = requests.post(url, headers=headers, json=payload, timeout=timeout)
|
110 |
if response.status_code == 200:
|
@@ -117,17 +117,19 @@ def make_api_request(url, headers, payload, timeout=180):
|
|
117 |
raise
|
118 |
|
119 |
def generate_birthday_message():
|
120 |
-
"""Generate a
|
121 |
try:
|
|
|
|
|
|
|
122 |
headers = {
|
123 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
124 |
"Content-Type": "application/json"
|
125 |
}
|
126 |
prompt = (
|
127 |
-
"You are Little Krishna,
|
128 |
-
"Ayush
|
129 |
-
"
|
130 |
-
"Example: 'Happy Birthday, Manavi! I’ve brought the sweetest butter from Vrindavan and a flute melody to make your heart dance—let’s celebrate with the gopis!'"
|
131 |
)
|
132 |
payload = {
|
133 |
"inputs": prompt,
|
@@ -146,28 +148,23 @@ def generate_birthday_message():
|
|
146 |
result = parse_huggingface_response(response)
|
147 |
if result and result.startswith("Happy Birthday, Manavi!"):
|
148 |
return result
|
149 |
-
logger.warning("Invalid API response; returning auto-generated
|
150 |
return auto_generate_birthday_message(include_tease=True)
|
151 |
except Exception as e:
|
152 |
logger.error(f"Error in generate_birthday_message: {str(e)}")
|
153 |
return auto_generate_birthday_message(include_tease=True)
|
154 |
|
155 |
def generate_gift_suggestions():
|
156 |
-
"""Generate personalized gift suggestions for Manavi
|
157 |
try:
|
158 |
headers = {
|
159 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
160 |
"Content-Type": "application/json"
|
161 |
}
|
162 |
prompt = (
|
163 |
-
"You are Little Krishna,
|
164 |
-
"
|
165 |
-
"
|
166 |
-
"Keep each suggestion short (1 sentence) and use Vrindavan imagery. "
|
167 |
-
"Return the suggestions as a numbered list (1., 2., 3.). "
|
168 |
-
"Example: '1. Hare Manavi! A peacock feather paintbrush to create art as vibrant as Vrindavan’s flowers!\n"
|
169 |
-
"2. A lotus-shaped journal to capture your thoughts by the Yamuna’s serene banks!\n"
|
170 |
-
"3. A flute pendant to carry Vrindavan’s spiritual melody close to your heart!'"
|
171 |
)
|
172 |
payload = {
|
173 |
"inputs": prompt,
|
@@ -187,22 +184,22 @@ def generate_gift_suggestions():
|
|
187 |
if result:
|
188 |
suggestions = result.strip().split('\n')
|
189 |
return [s.strip() for s in suggestions if s.strip()]
|
190 |
-
logger.warning("Returning fallback gift suggestions
|
191 |
return [
|
192 |
-
"Hare Manavi! A peacock feather paintbrush
|
193 |
-
"Hare Manavi! A lotus
|
194 |
-
"Hare Manavi! A flute pendant
|
195 |
]
|
196 |
except Exception as e:
|
197 |
logger.error(f"Error in generate_gift_suggestions: {str(e)}")
|
198 |
return [
|
199 |
-
"Hare Manavi! A peacock feather paintbrush
|
200 |
-
"Hare Manavi! A lotus
|
201 |
-
"Hare Manavi! A flute pendant
|
202 |
]
|
203 |
|
204 |
def generate_horoscope():
|
205 |
-
"""Generate a
|
206 |
try:
|
207 |
today = datetime.now().strftime("%B %d, %Y")
|
208 |
headers = {
|
@@ -210,9 +207,9 @@ def generate_horoscope():
|
|
210 |
"Content-Type": "application/json"
|
211 |
}
|
212 |
prompt = (
|
213 |
-
f"You are Little Krishna,
|
214 |
-
"Generate a short
|
215 |
-
"Example: 'Hare Manavi! Today, the Yamuna
|
216 |
)
|
217 |
payload = {
|
218 |
"inputs": prompt,
|
@@ -231,15 +228,15 @@ def generate_horoscope():
|
|
231 |
result = parse_huggingface_response(response)
|
232 |
if result:
|
233 |
return result
|
234 |
-
logger.warning("Returning fallback horoscope
|
235 |
-
return "Hare Manavi! Today, the Yamuna
|
236 |
except Exception as e:
|
237 |
logger.error(f"Error in generate_horoscope: {str(e)}")
|
238 |
-
return "Hare Manavi! Today, the Yamuna
|
239 |
|
240 |
@app.route('/')
|
241 |
def home():
|
242 |
-
"""Render the home page
|
243 |
try:
|
244 |
daily_data = get_daily_message_and_blessing()
|
245 |
countdown_days = get_countdown()
|
@@ -253,15 +250,15 @@ def home():
|
|
253 |
countdown=countdown_days)
|
254 |
except Exception as e:
|
255 |
logger.error(f"Error in / route: {str(e)}")
|
256 |
-
return render_template('error.html', error_message='Failed to load homepage.
|
257 |
|
258 |
@app.route('/chat', methods=['GET', 'POST'])
|
259 |
def chat():
|
260 |
-
"""Handle chat interactions
|
261 |
try:
|
262 |
if request.method == 'POST':
|
263 |
if 'message' not in request.form:
|
264 |
-
logger.error("Missing 'message' in POST request
|
265 |
return jsonify({'error': 'Missing message parameter'}), 400
|
266 |
user_input = escape(request.form['message'].strip())
|
267 |
if not user_input:
|
@@ -276,20 +273,20 @@ def chat():
|
|
276 |
if firebase_enabled:
|
277 |
try:
|
278 |
save_chat_message(user_input, reply)
|
279 |
-
logger.info("
|
280 |
except Exception as e:
|
281 |
-
logger.error(f"Failed to save chat message
|
282 |
return jsonify({'reply': reply})
|
283 |
try:
|
284 |
chat_history = get_chat_history() if firebase_enabled else []
|
285 |
logger.info(f"Retrieved chat history: {len(chat_history)} messages")
|
286 |
except Exception as e:
|
287 |
-
logger.error(f"Failed to retrieve chat history
|
288 |
chat_history = []
|
289 |
return render_template('chat.html', chat_history=chat_history)
|
290 |
except Exception as e:
|
291 |
logger.error(f"Error in /chat route: {str(e)}")
|
292 |
-
return render_template('error.html', error_message='Failed to load chat page.
|
293 |
|
294 |
@app.route('/adventure', methods=['GET', 'POST'])
|
295 |
def adventure():
|
@@ -298,62 +295,56 @@ def adventure():
|
|
298 |
if request.method == 'POST':
|
299 |
choice = request.form.get('choice', '')
|
300 |
current_scene = request.form.get('current_scene', 'start')
|
301 |
-
logger.info(f"Adventure POST
|
302 |
|
303 |
scenes = {
|
304 |
'start': {
|
305 |
'prompt': (
|
306 |
-
"You are Little Krishna,
|
307 |
-
"Start
|
308 |
-
"Example: 'Hare Manavi!
|
309 |
),
|
310 |
'next_scenes': {'Chase peacocks': 'peacocks', 'Sneak butter': 'butter'}
|
311 |
},
|
312 |
'peacocks': {
|
313 |
'prompt': (
|
314 |
-
"
|
315 |
-
"Manavi
|
316 |
-
"Example: 'Hare Manavi! We chased the peacocks through Vrindavan’s fields, their feathers shimmering like rainbows—now, shall we climb the kadamba tree to see them better or play a tune on my flute to call them back? (Choices: Climb tree, Play flute)'"
|
317 |
),
|
318 |
'next_scenes': {'Climb tree': 'tree', 'Play flute': 'flute'}
|
319 |
},
|
320 |
'butter': {
|
321 |
'prompt': (
|
322 |
-
"
|
323 |
-
"Manavi
|
324 |
-
"Example: 'Hare Manavi! We sneaked some butter from the gopis’ pots, giggling as they chased us—shall we hide by the Yamuna to enjoy our treat or share it with the calves? (Choices: Hide by Yamuna, Share with calves)'"
|
325 |
),
|
326 |
'next_scenes': {'Hide by Yamuna': 'yamuna', 'Share with calves': 'calves'}
|
327 |
},
|
328 |
'tree': {
|
329 |
'prompt': (
|
330 |
-
"
|
331 |
-
"Manavi
|
332 |
-
"Example: 'Hare Manavi! We climbed the kadamba tree, watching the peacocks dance below, and I played a flute tune to make them twirl even faster—what a magical Vrindavan day!'"
|
333 |
),
|
334 |
'next_scenes': {}
|
335 |
},
|
336 |
'flute': {
|
337 |
'prompt': (
|
338 |
-
"
|
339 |
-
"
|
340 |
-
"Example: 'Hare Manavi! I played a sweet flute tune, and the peacocks gathered around us, dancing to the melody—what a joyful Vrindavan memory we’ve made!'"
|
341 |
),
|
342 |
'next_scenes': {}
|
343 |
},
|
344 |
'yamuna': {
|
345 |
'prompt': (
|
346 |
-
"
|
347 |
-
"
|
348 |
-
"Example: 'Hare Manavi! We hid by the Yamuna, sharing the butter as the river sparkled, and the gopis laughed when they found us—what a mischievous Vrindavan adventure!'"
|
349 |
),
|
350 |
'next_scenes': {}
|
351 |
},
|
352 |
'calves': {
|
353 |
'prompt': (
|
354 |
-
"
|
355 |
-
"
|
356 |
-
"Example: 'Hare Manavi! We shared the butter with the calves, who mooed happily, and the gopis smiled at our kindness—what a sweet Vrindavan moment!'"
|
357 |
),
|
358 |
'next_scenes': {}
|
359 |
}
|
@@ -380,30 +371,24 @@ def adventure():
|
|
380 |
)
|
381 |
if response and response.status_code == 200:
|
382 |
result = parse_huggingface_response(response)
|
383 |
-
|
384 |
-
if result:
|
385 |
-
story_text = result
|
386 |
-
else:
|
387 |
-
logger.error("Unexpected API response format.")
|
388 |
-
story_text = scene['prompt'].split('Example: ')[1]
|
389 |
else:
|
390 |
-
logger.error("Failed to generate adventure scene
|
391 |
story_text = scene['prompt'].split('Example: ')[1]
|
392 |
|
393 |
-
next_scene = scene['next_scenes'].get(choice
|
394 |
if next_scene:
|
395 |
return jsonify({'scene': story_text, 'current_scene': next_scene, 'choices': list(scene['next_scenes'].keys())})
|
396 |
-
|
397 |
-
return jsonify({'scene': story_text, 'current_scene': None, 'choices': []})
|
398 |
|
399 |
return render_template('adventure.html')
|
400 |
except Exception as e:
|
401 |
logger.error(f"Error in /adventure route: {str(e)}")
|
402 |
-
return render_template('error.html', error_message='Failed to load adventure page.
|
403 |
|
404 |
@app.route('/message')
|
405 |
def message():
|
406 |
-
"""Render the birthday message page
|
407 |
try:
|
408 |
birthday_message = generate_birthday_message()
|
409 |
gift_suggestions = generate_gift_suggestions()
|
@@ -417,11 +402,11 @@ def message():
|
|
417 |
is_birthday=is_birthday)
|
418 |
except Exception as e:
|
419 |
logger.error(f"Error in /message route: {str(e)}")
|
420 |
-
return render_template('error.html', error_message='Failed to load birthday message page.
|
421 |
|
422 |
@app.route('/image', methods=['POST'])
|
423 |
def image():
|
424 |
-
"""Generate a Krishna-themed image
|
425 |
try:
|
426 |
prompt = request.json.get('prompt', '')
|
427 |
if not prompt:
|
@@ -432,7 +417,7 @@ def image():
|
|
432 |
return jsonify({'error': 'Failed to generate image'}), 500
|
433 |
except Exception as e:
|
434 |
logger.error(f"Error in /image route: {str(e)}")
|
435 |
-
return jsonify({'error': 'Internal Server Error
|
436 |
|
437 |
@app.route('/comic', methods=['GET'])
|
438 |
def comic():
|
@@ -442,17 +427,16 @@ def comic():
|
|
442 |
return jsonify({'comic_images': comic_images})
|
443 |
except Exception as e:
|
444 |
logger.error(f"Error in /comic route: {str(e)}")
|
445 |
-
return jsonify({'error': 'Internal Server Error
|
446 |
|
447 |
@app.route('/story', methods=['POST'])
|
448 |
def story():
|
449 |
-
"""Generate a
|
450 |
try:
|
451 |
theme = request.json.get('theme', 'Vrindavan')
|
452 |
prompt = (
|
453 |
-
f"You are Little Krishna,
|
454 |
-
f"
|
455 |
-
f"Example: 'Hare Manavi! One day, I hid the gopis’ butter in a peacock’s nest, and they danced with me to get it back—what a Vrindavan adventure!'"
|
456 |
)
|
457 |
headers = {
|
458 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
@@ -475,15 +459,15 @@ def story():
|
|
475 |
result = parse_huggingface_response(response)
|
476 |
if result:
|
477 |
return jsonify({'story': result})
|
478 |
-
logger.error("Failed to generate story
|
479 |
-
return jsonify({'story': f"Hare Manavi!
|
480 |
except Exception as e:
|
481 |
logger.error(f"Error in /story route: {str(e)}")
|
482 |
-
return jsonify({'error': 'Internal Server Error
|
483 |
|
484 |
@app.route('/story_audio', methods=['POST'])
|
485 |
def story_audio():
|
486 |
-
"""Generate audio narration for a story
|
487 |
try:
|
488 |
story_text = request.json.get('story_text', '')
|
489 |
if not story_text:
|
@@ -492,9 +476,7 @@ def story_audio():
|
|
492 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
493 |
"Content-Type": "application/json"
|
494 |
}
|
495 |
-
payload = {
|
496 |
-
"inputs": story_text
|
497 |
-
}
|
498 |
response = make_api_request(
|
499 |
"https://api-inference.huggingface.co/models/facebook/tts-transformer-en-ljspeech",
|
500 |
headers=headers,
|
@@ -506,25 +488,23 @@ def story_audio():
|
|
506 |
with open(audio_path, "wb") as f:
|
507 |
f.write(response.content)
|
508 |
return jsonify({'audio_url': f"/{audio_path}"})
|
509 |
-
logger.error("Failed to generate story audio
|
510 |
return jsonify({'error': 'Failed to generate audio'}), 500
|
511 |
except Exception as e:
|
512 |
logger.error(f"Error in /story_audio route: {str(e)}")
|
513 |
-
return jsonify({'error': 'Internal Server Error
|
514 |
|
515 |
@app.route('/riddle', methods=['GET'])
|
516 |
def riddle():
|
517 |
-
"""Generate a Krishna-themed riddle
|
518 |
try:
|
519 |
headers = {
|
520 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
521 |
"Content-Type": "application/json"
|
522 |
}
|
523 |
prompt = (
|
524 |
-
"You are Little Krishna, a
|
525 |
-
"
|
526 |
-
"Include the answer in parentheses at the end. "
|
527 |
-
"Example: 'Hare Manavi! I play a tune that makes the gopis dance, but I’m not a drum—what am I? (Answer: Flute)'"
|
528 |
)
|
529 |
payload = {
|
530 |
"inputs": prompt,
|
@@ -543,21 +523,21 @@ def riddle():
|
|
543 |
result = parse_huggingface_response(response)
|
544 |
if result:
|
545 |
return jsonify({'riddle': result})
|
546 |
-
logger.error("Failed to generate riddle
|
547 |
-
return jsonify({'riddle': "Hare Manavi! I play a tune that makes
|
548 |
except Exception as e:
|
549 |
logger.error(f"Error in /riddle route: {str(e)}")
|
550 |
-
return jsonify({'error': 'Internal Server Error
|
551 |
|
552 |
@app.route('/countdown')
|
553 |
def countdown():
|
554 |
-
"""Return
|
555 |
try:
|
556 |
days_left = get_countdown()
|
557 |
return jsonify({'days': days_left})
|
558 |
except Exception as e:
|
559 |
logger.error(f"Error in /countdown route: {str(e)}")
|
560 |
-
return jsonify({'error': 'Internal Server Error
|
561 |
|
562 |
if __name__ == '__main__':
|
563 |
port = int(os.environ.get('PORT', 7860))
|
|
|
10 |
import requests
|
11 |
import random
|
12 |
import backoff
|
13 |
+
from ayush_messages import ayush_surprises
|
14 |
|
15 |
# Configure logging
|
16 |
logging.basicConfig(level=logging.INFO)
|
|
|
37 |
|
38 |
# Daily messages based on the day of the week (with Bhagavad Gita verses)
|
39 |
DAILY_MESSAGES = {
|
40 |
+
0: {"message": "On Sundays, shine like the sun for all!", "verse": "Bhagavad Gita 9.29"},
|
41 |
+
1: {"message": "Monday: Do your duty without attachment.", "verse": "Bhagavad Gita 2.47"},
|
42 |
+
2: {"message": "Tuesday: The soul is eternal, beyond death.", "verse": "Bhagavad Gita 2.20"},
|
43 |
+
3: {"message": "Wednesday: Krishna brings victory!", "verse": "Bhagavad Gita 18.78"},
|
44 |
+
4: {"message": "Thursday: Surrender to the divine will.", "verse": "Bhagavad Gita 18.66"},
|
45 |
+
5: {"message": "Friday: Cultivate compassion.", "verse": "Bhagavad Gita 16.1-3"},
|
46 |
+
6: {"message": "Saturday: Find joy in spiritual practice.", "verse": "Bhagavad Gita 6.17"}
|
47 |
}
|
48 |
|
49 |
# Festival messages for specific dates
|
50 |
FESTIVAL_MESSAGES = {
|
51 |
(1, 26): {"message": "Happy Republic Day! Let Dharma guide our nation.", "verse": "Bhagavad Gita 4.7", "special": True},
|
52 |
(8, 19): {"message": "Happy Krishna Janmashtami! Celebrate the divine birth.", "verse": "Bhagavad Gita 4.9", "special": True},
|
53 |
+
(4, 19): {"message": ayush_surprises["birthday"], "verse": "Bhagavad Gita 2.22", "special": True}
|
54 |
}
|
55 |
|
56 |
def parse_huggingface_response(response):
|
|
|
73 |
"""Retrieve the daily message and blessing based on the current date."""
|
74 |
try:
|
75 |
today = datetime.now()
|
76 |
+
day_of_week = (today.weekday() + 1) % 7
|
77 |
month_day = (today.month, today.day)
|
78 |
|
79 |
+
# Check for festival messages
|
80 |
if month_day in FESTIVAL_MESSAGES:
|
81 |
daily_message = FESTIVAL_MESSAGES[month_day]
|
82 |
else:
|
83 |
daily_message = DAILY_MESSAGES.get(day_of_week,
|
84 |
+
{"message": "Seek the divine today.", "verse": "Bhagavad Gita 6.30"})
|
|
|
85 |
daily_message['special'] = False
|
86 |
|
87 |
daily_blessing_index = (today.day - 1) % len(daily_blessings)
|
|
|
96 |
except Exception as e:
|
97 |
logger.error(f"Error in get_daily_message_and_blessing: {str(e)}")
|
98 |
return {
|
99 |
+
"message": "Seek the divine today.",
|
100 |
"verse": "Bhagavad Gita 6.30",
|
101 |
"is_special": False,
|
102 |
+
"blessing": "Hare Manavi! May Vrindavan’s joy fill your heart!"
|
103 |
}
|
104 |
|
105 |
@backoff.on_exception(backoff.expo, (requests.exceptions.RequestException, requests.exceptions.HTTPError), max_tries=12, max_time=900)
|
106 |
def make_api_request(url, headers, payload, timeout=180):
|
107 |
+
"""Make API requests with exponential backoff."""
|
108 |
try:
|
109 |
response = requests.post(url, headers=headers, json=payload, timeout=timeout)
|
110 |
if response.status_code == 200:
|
|
|
117 |
raise
|
118 |
|
119 |
def generate_birthday_message():
|
120 |
+
"""Generate a birthday message for Manavi."""
|
121 |
try:
|
122 |
+
today = datetime.now()
|
123 |
+
if today.month == 4 and today.day == 19:
|
124 |
+
return ayush_surprises["birthday"]
|
125 |
headers = {
|
126 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
127 |
"Content-Type": "application/json"
|
128 |
}
|
129 |
prompt = (
|
130 |
+
"You are Little Krishna, speaking to Manavi on her birthday, April 19, 2025. "
|
131 |
+
"Ayush created this chatbot as a surprise. Write a short, heartfelt birthday message (1-2 sentences) starting with 'Happy Birthday, Manavi!', using Vrindavan imagery. "
|
132 |
+
"Example: 'Happy Birthday, Manavi! I’ve brought Vrindavan’s sweetest butter and a flute melody to make your heart dance!'"
|
|
|
133 |
)
|
134 |
payload = {
|
135 |
"inputs": prompt,
|
|
|
148 |
result = parse_huggingface_response(response)
|
149 |
if result and result.startswith("Happy Birthday, Manavi!"):
|
150 |
return result
|
151 |
+
logger.warning("Invalid API response; returning auto-generated message.")
|
152 |
return auto_generate_birthday_message(include_tease=True)
|
153 |
except Exception as e:
|
154 |
logger.error(f"Error in generate_birthday_message: {str(e)}")
|
155 |
return auto_generate_birthday_message(include_tease=True)
|
156 |
|
157 |
def generate_gift_suggestions():
|
158 |
+
"""Generate personalized gift suggestions for Manavi."""
|
159 |
try:
|
160 |
headers = {
|
161 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
162 |
"Content-Type": "application/json"
|
163 |
}
|
164 |
prompt = (
|
165 |
+
"You are Little Krishna, speaking to Manavi on her birthday, April 19, 2025. "
|
166 |
+
"Suggest three gifts reflecting her interests in art, nature, and spirituality, in a playful Krishna tone. "
|
167 |
+
"Return as a numbered list (1., 2., 3.). Example: '1. A peacock feather paintbrush for vibrant art!\n2. A lotus journal for serene thoughts!\n3. A flute pendant for spiritual melodies!'"
|
|
|
|
|
|
|
|
|
|
|
168 |
)
|
169 |
payload = {
|
170 |
"inputs": prompt,
|
|
|
184 |
if result:
|
185 |
suggestions = result.strip().split('\n')
|
186 |
return [s.strip() for s in suggestions if s.strip()]
|
187 |
+
logger.warning("Returning fallback gift suggestions.")
|
188 |
return [
|
189 |
+
"Hare Manavi! A peacock feather paintbrush for vibrant art!",
|
190 |
+
"Hare Manavi! A lotus journal for serene thoughts!",
|
191 |
+
"Hare Manavi! A flute pendant for spiritual melodies!"
|
192 |
]
|
193 |
except Exception as e:
|
194 |
logger.error(f"Error in generate_gift_suggestions: {str(e)}")
|
195 |
return [
|
196 |
+
"Hare Manavi! A peacock feather paintbrush for vibrant art!",
|
197 |
+
"Hare Manavi! A lotus journal for serene thoughts!",
|
198 |
+
"Hare Manavi! A flute pendant for spiritual melodies!"
|
199 |
]
|
200 |
|
201 |
def generate_horoscope():
|
202 |
+
"""Generate a daily horoscope for Manavi."""
|
203 |
try:
|
204 |
today = datetime.now().strftime("%B %d, %Y")
|
205 |
headers = {
|
|
|
207 |
"Content-Type": "application/json"
|
208 |
}
|
209 |
prompt = (
|
210 |
+
f"You are Little Krishna, speaking to Manavi on {today}. "
|
211 |
+
"Generate a short daily horoscope (1-2 sentences) for Manavi, reflecting her interests in art, nature, and spirituality, in a playful tone with Vrindavan imagery. "
|
212 |
+
"Example: 'Hare Manavi! Today, the Yamuna inspires your art—paint with Vrindavan’s colors and let your spirit dance!'"
|
213 |
)
|
214 |
payload = {
|
215 |
"inputs": prompt,
|
|
|
228 |
result = parse_huggingface_response(response)
|
229 |
if result:
|
230 |
return result
|
231 |
+
logger.warning("Returning fallback horoscope.")
|
232 |
+
return "Hare Manavi! Today, the Yamuna inspires your art—paint with Vrindavan’s colors and let your spirit dance!"
|
233 |
except Exception as e:
|
234 |
logger.error(f"Error in generate_horoscope: {str(e)}")
|
235 |
+
return "Hare Manavi! Today, the Yamuna inspires your art—paint with Vrindavan’s colors and let your spirit dance!"
|
236 |
|
237 |
@app.route('/')
|
238 |
def home():
|
239 |
+
"""Render the home page."""
|
240 |
try:
|
241 |
daily_data = get_daily_message_and_blessing()
|
242 |
countdown_days = get_countdown()
|
|
|
250 |
countdown=countdown_days)
|
251 |
except Exception as e:
|
252 |
logger.error(f"Error in / route: {str(e)}")
|
253 |
+
return render_template('error.html', error_message='Failed to load homepage.'), 500
|
254 |
|
255 |
@app.route('/chat', methods=['GET', 'POST'])
|
256 |
def chat():
|
257 |
+
"""Handle chat interactions."""
|
258 |
try:
|
259 |
if request.method == 'POST':
|
260 |
if 'message' not in request.form:
|
261 |
+
logger.error("Missing 'message' in POST request.")
|
262 |
return jsonify({'error': 'Missing message parameter'}), 400
|
263 |
user_input = escape(request.form['message'].strip())
|
264 |
if not user_input:
|
|
|
273 |
if firebase_enabled:
|
274 |
try:
|
275 |
save_chat_message(user_input, reply)
|
276 |
+
logger.info("Saved chat message to Firebase.")
|
277 |
except Exception as e:
|
278 |
+
logger.error(f"Failed to save chat message: {str(e)}")
|
279 |
return jsonify({'reply': reply})
|
280 |
try:
|
281 |
chat_history = get_chat_history() if firebase_enabled else []
|
282 |
logger.info(f"Retrieved chat history: {len(chat_history)} messages")
|
283 |
except Exception as e:
|
284 |
+
logger.error(f"Failed to retrieve chat history: {str(e)}")
|
285 |
chat_history = []
|
286 |
return render_template('chat.html', chat_history=chat_history)
|
287 |
except Exception as e:
|
288 |
logger.error(f"Error in /chat route: {str(e)}")
|
289 |
+
return render_template('error.html', error_message='Failed to load chat page.'), 500
|
290 |
|
291 |
@app.route('/adventure', methods=['GET', 'POST'])
|
292 |
def adventure():
|
|
|
295 |
if request.method == 'POST':
|
296 |
choice = request.form.get('choice', '')
|
297 |
current_scene = request.form.get('current_scene', 'start')
|
298 |
+
logger.info(f"Adventure POST: current_scene={current_scene}, choice={choice}")
|
299 |
|
300 |
scenes = {
|
301 |
'start': {
|
302 |
'prompt': (
|
303 |
+
"You are Little Krishna, guiding Manavi on a Vrindavan adventure. "
|
304 |
+
"Start with a short scene (2-3 sentences) and offer two choices. "
|
305 |
+
"Example: 'Hare Manavi! By the Yamuna’s sparkling waters, shall we chase peacocks or sneak butter? (Choices: Chase peacocks, Sneak butter)'"
|
306 |
),
|
307 |
'next_scenes': {'Chase peacocks': 'peacocks', 'Sneak butter': 'butter'}
|
308 |
},
|
309 |
'peacocks': {
|
310 |
'prompt': (
|
311 |
+
"Manavi chose to chase peacocks. Describe a short scene (2-3 sentences) and offer two new choices. "
|
312 |
+
"Example: 'Hare Manavi! We chased peacocks, their feathers shimmering—shall we climb a kadamba tree or play a flute tune? (Choices: Climb tree, Play flute)'"
|
|
|
313 |
),
|
314 |
'next_scenes': {'Climb tree': 'tree', 'Play flute': 'flute'}
|
315 |
},
|
316 |
'butter': {
|
317 |
'prompt': (
|
318 |
+
"Manavi chose to sneak butter. Describe a short scene (2-3 sentences) and offer two new choices. "
|
319 |
+
"Example: 'Hare Manavi! We sneaked butter, giggling—shall we hide by the Yamuna or share with calves? (Choices: Hide by Yamuna, Share with calves)'"
|
|
|
320 |
),
|
321 |
'next_scenes': {'Hide by Yamuna': 'yamuna', 'Share with calves': 'calves'}
|
322 |
},
|
323 |
'tree': {
|
324 |
'prompt': (
|
325 |
+
"Manavi chose to climb the kadamba tree. Describe a short scene (2-3 sentences) and end the story. "
|
326 |
+
"Example: 'Hare Manavi! We climbed the kadamba tree, watching peacocks—what a magical Vrindavan day!'"
|
|
|
327 |
),
|
328 |
'next_scenes': {}
|
329 |
},
|
330 |
'flute': {
|
331 |
'prompt': (
|
332 |
+
"Manavi chose to play the flute. Describe a short scene (2-3 sentences) and end the story. "
|
333 |
+
"Example: 'Hare Manavi! I played a flute tune, and peacocks danced—what a joyful Vrindavan memory!'"
|
|
|
334 |
),
|
335 |
'next_scenes': {}
|
336 |
},
|
337 |
'yamuna': {
|
338 |
'prompt': (
|
339 |
+
"Manavi chose to hide by the Yamuna. Describe a short scene (2-3 sentences) and end the story. "
|
340 |
+
"Example: 'Hare Manavi! We hid by the Yamuna, sharing butter—what a mischievous adventure!'"
|
|
|
341 |
),
|
342 |
'next_scenes': {}
|
343 |
},
|
344 |
'calves': {
|
345 |
'prompt': (
|
346 |
+
"Manavi chose to share butter with calves. Describe a short scene (2-3 sentences) and end the story. "
|
347 |
+
"Example: 'Hare Manavi! We shared butter with calves, who mooed happily—what a sweet moment!'"
|
|
|
348 |
),
|
349 |
'next_scenes': {}
|
350 |
}
|
|
|
371 |
)
|
372 |
if response and response.status_code == 200:
|
373 |
result = parse_huggingface_response(response)
|
374 |
+
story_text = result or scene['prompt'].split('Example: ')[1]
|
|
|
|
|
|
|
|
|
|
|
375 |
else:
|
376 |
+
logger.error("Failed to generate adventure scene.")
|
377 |
story_text = scene['prompt'].split('Example: ')[1]
|
378 |
|
379 |
+
next_scene = scene['next_scenes'].get(choice)
|
380 |
if next_scene:
|
381 |
return jsonify({'scene': story_text, 'current_scene': next_scene, 'choices': list(scene['next_scenes'].keys())})
|
382 |
+
return jsonify({'scene': story_text, 'current_scene': None, 'choices': []})
|
|
|
383 |
|
384 |
return render_template('adventure.html')
|
385 |
except Exception as e:
|
386 |
logger.error(f"Error in /adventure route: {str(e)}")
|
387 |
+
return render_template('error.html', error_message='Failed to load adventure page.'), 500
|
388 |
|
389 |
@app.route('/message')
|
390 |
def message():
|
391 |
+
"""Render the birthday message page."""
|
392 |
try:
|
393 |
birthday_message = generate_birthday_message()
|
394 |
gift_suggestions = generate_gift_suggestions()
|
|
|
402 |
is_birthday=is_birthday)
|
403 |
except Exception as e:
|
404 |
logger.error(f"Error in /message route: {str(e)}")
|
405 |
+
return render_template('error.html', error_message='Failed to load birthday message page.'), 500
|
406 |
|
407 |
@app.route('/image', methods=['POST'])
|
408 |
def image():
|
409 |
+
"""Generate a Krishna-themed image."""
|
410 |
try:
|
411 |
prompt = request.json.get('prompt', '')
|
412 |
if not prompt:
|
|
|
417 |
return jsonify({'error': 'Failed to generate image'}), 500
|
418 |
except Exception as e:
|
419 |
logger.error(f"Error in /image route: {str(e)}")
|
420 |
+
return jsonify({'error': 'Internal Server Error.'}), 500
|
421 |
|
422 |
@app.route('/comic', methods=['GET'])
|
423 |
def comic():
|
|
|
427 |
return jsonify({'comic_images': comic_images})
|
428 |
except Exception as e:
|
429 |
logger.error(f"Error in /comic route: {str(e)}")
|
430 |
+
return jsonify({'error': 'Internal Server Error.'}), 500
|
431 |
|
432 |
@app.route('/story', methods=['POST'])
|
433 |
def story():
|
434 |
+
"""Generate a Krishna story."""
|
435 |
try:
|
436 |
theme = request.json.get('theme', 'Vrindavan')
|
437 |
prompt = (
|
438 |
+
f"You are Little Krishna, telling a short story (2-3 sentences) to Manavi with the theme '{theme}'. "
|
439 |
+
f"Keep it fun and Krishna-like. Example: 'Hare Manavi! I hid the gopis’ butter in a peacock’s nest—what a Vrindavan adventure!'"
|
|
|
440 |
)
|
441 |
headers = {
|
442 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
|
|
459 |
result = parse_huggingface_response(response)
|
460 |
if result:
|
461 |
return jsonify({'story': result})
|
462 |
+
logger.error("Failed to generate story.")
|
463 |
+
return jsonify({'story': f"Hare Manavi! I hid the gopis’ {theme} in a peacock’s nest—what a Vrindavan adventure!'"})
|
464 |
except Exception as e:
|
465 |
logger.error(f"Error in /story route: {str(e)}")
|
466 |
+
return jsonify({'error': 'Internal Server Error.'}), 500
|
467 |
|
468 |
@app.route('/story_audio', methods=['POST'])
|
469 |
def story_audio():
|
470 |
+
"""Generate audio narration for a story."""
|
471 |
try:
|
472 |
story_text = request.json.get('story_text', '')
|
473 |
if not story_text:
|
|
|
476 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
477 |
"Content-Type": "application/json"
|
478 |
}
|
479 |
+
payload = {"inputs": story_text}
|
|
|
|
|
480 |
response = make_api_request(
|
481 |
"https://api-inference.huggingface.co/models/facebook/tts-transformer-en-ljspeech",
|
482 |
headers=headers,
|
|
|
488 |
with open(audio_path, "wb") as f:
|
489 |
f.write(response.content)
|
490 |
return jsonify({'audio_url': f"/{audio_path}"})
|
491 |
+
logger.error("Failed to generate story audio.")
|
492 |
return jsonify({'error': 'Failed to generate audio'}), 500
|
493 |
except Exception as e:
|
494 |
logger.error(f"Error in /story_audio route: {str(e)}")
|
495 |
+
return jsonify({'error': 'Internal Server Error.'}), 500
|
496 |
|
497 |
@app.route('/riddle', methods=['GET'])
|
498 |
def riddle():
|
499 |
+
"""Generate a Krishna-themed riddle."""
|
500 |
try:
|
501 |
headers = {
|
502 |
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}",
|
503 |
"Content-Type": "application/json"
|
504 |
}
|
505 |
prompt = (
|
506 |
+
"You are Little Krishna, speaking to Manavi. Generate a short, Krishna-themed riddle (1-2 sentences) with a playful tone, using Vrindavan imagery. "
|
507 |
+
"Include the answer in parentheses. Example: 'Hare Manavi! I play a tune that makes gopis dance, but I’m not a drum—what am I? (Answer: Flute)'"
|
|
|
|
|
508 |
)
|
509 |
payload = {
|
510 |
"inputs": prompt,
|
|
|
523 |
result = parse_huggingface_response(response)
|
524 |
if result:
|
525 |
return jsonify({'riddle': result})
|
526 |
+
logger.error("Failed to generate riddle.")
|
527 |
+
return jsonify({'riddle': "Hare Manavi! I play a tune that makes gopis dance—what am I? (Answer: Flute)"})
|
528 |
except Exception as e:
|
529 |
logger.error(f"Error in /riddle route: {str(e)}")
|
530 |
+
return jsonify({'error': 'Internal Server Error.'}), 500
|
531 |
|
532 |
@app.route('/countdown')
|
533 |
def countdown():
|
534 |
+
"""Return days until Manavi's birthday."""
|
535 |
try:
|
536 |
days_left = get_countdown()
|
537 |
return jsonify({'days': days_left})
|
538 |
except Exception as e:
|
539 |
logger.error(f"Error in /countdown route: {str(e)}")
|
540 |
+
return jsonify({'error': 'Internal Server Error.'}), 500
|
541 |
|
542 |
if __name__ == '__main__':
|
543 |
port = int(os.environ.get('PORT', 7860))
|