cryogenic22 commited on
Commit
eca1131
Β·
verified Β·
1 Parent(s): f29d3c2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +106 -283
app.py CHANGED
@@ -1,7 +1,6 @@
1
  import streamlit as st
2
  import os
3
  from datetime import datetime
4
- import json
5
  from crewai import Agent, Task, Crew
6
  from langchain_openai import OpenAI
7
  from openai import OpenAI as OpenAIClient
@@ -12,13 +11,10 @@ import random
12
  from PIL import Image, ImageDraw, ImageFont
13
  from io import BytesIO
14
 
15
- # Set up logging
16
  logging.basicConfig(level=logging.INFO)
17
  logger = logging.getLogger(__name__)
18
 
19
-
20
  def log_message(message, type="info"):
21
- """Add a message to the session state logs with timestamp"""
22
  if 'process_logs' not in st.session_state:
23
  st.session_state.process_logs = []
24
  timestamp = datetime.now().strftime("%H:%M:%S")
@@ -28,44 +24,17 @@ def log_message(message, type="info"):
28
  "type": type
29
  })
30
 
31
-
32
  class SpiritualThemes:
33
- """Diverse spiritual themes for content generation"""
34
-
35
  TRADITIONS = {
36
- "Eastern": [
37
- "Buddhism", "Hinduism", "Taoism", "Zen", "Vedanta",
38
- "Yoga Philosophy", "Jainism", "Sikhism", "Confucianism"
39
- ],
40
- "Western": [
41
- "Christian Mysticism", "Sufi Wisdom", "Kabbalah",
42
- "Greek Philosophy", "Modern Spirituality", "Stoicism"
43
- ],
44
- "Indigenous": [
45
- "Native American Wisdom", "Aboriginal Spirituality",
46
- "African Traditional", "Maori Wisdom"
47
- ],
48
- "Modern": [
49
- "Mindfulness", "Contemporary Philosophy",
50
- "Integrative Spirituality", "Secular Wisdom"
51
- ]
52
  }
53
-
54
- THEMES = [
55
- "Inner Peace", "Mindfulness", "Compassion", "Wisdom",
56
- "Self-Discovery", "Unity", "Balance", "Transformation",
57
- "Enlightenment", "Purpose", "Gratitude", "Presence",
58
- "Love", "Harmony", "Truth", "Liberation", "Service",
59
- "Connection", "Growth", "Awareness"
60
- ]
61
-
62
- QUOTE_STYLES = [
63
- "contemplative", "inspirational", "philosophical",
64
- "practical wisdom", "mystical insight", "ancient teaching",
65
- "modern interpretation", "timeless truth", "daily practice",
66
- "meditation guidance"
67
- ]
68
-
69
 
70
  class ContentGenerator:
71
  def __init__(self, openai_api_key, replicate_api_key):
@@ -74,7 +43,6 @@ class ContentGenerator:
74
  self.replicate_client = replicate.Client(api_token=replicate_api_key)
75
 
76
  def _generate_prompt_variation(self):
77
- """Generate varied prompts for quote generation"""
78
  tradition_category = random.choice(list(SpiritualThemes.TRADITIONS.keys()))
79
  traditions = SpiritualThemes.TRADITIONS[tradition_category]
80
  themes = random.sample(SpiritualThemes.THEMES, 2)
@@ -84,58 +52,26 @@ class ContentGenerator:
84
  Ensure the quote is profound yet accessible for social media."""
85
 
86
  def _get_fallback_quote(self):
87
- """Provide a fallback quote when generation fails"""
88
  fallback_quotes = [
89
- {
90
- "text": "Be the change you wish to see in the world.",
91
- "author": "Mahatma Gandhi",
92
- "tradition": "Modern Spirituality",
93
- "theme": "Transformation"
94
- },
95
- {
96
- "text": "Peace comes from within. Do not seek it without.",
97
- "author": "Buddha",
98
- "tradition": "Buddhism",
99
- "theme": "Inner Peace"
100
- },
101
- {
102
- "text": "The journey of a thousand miles begins with one step.",
103
- "author": "Lao Tzu",
104
- "tradition": "Taoism",
105
- "theme": "Growth"
106
- },
107
- {
108
- "text": "Love is the bridge between you and everything.",
109
- "author": "Rumi",
110
- "tradition": "Sufi Wisdom",
111
- "theme": "Love"
112
- }
113
  ]
114
  quote = random.choice(fallback_quotes)
115
- quote["generated_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
116
- quote["source"] = "fallback"
 
 
 
117
  log_message("ℹ️ Using fallback quote system", "info")
118
  return quote
119
 
120
- def _parse_quote_result(self, result):
121
-
122
- try:
123
- return {
124
- "text": result.get('quote', ''),
125
- "author": result.get('author', ''),
126
- "tradition": result.get('tradition', ''),
127
- "theme": result.get('theme', ''),
128
- "generated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
129
- }
130
- except Exception as e:
131
- log_message(f"❌ Error parsing quote result: {str(e)}")
132
- return self._get_fallback_quote()
133
-
134
  def generate_quote(self):
135
  try:
136
  log_message("🎯 Starting quote generation")
137
- prompt_variation = self._generate_prompt_variation()
138
-
139
  response = self.openai_client.chat.completions.create(
140
  model="gpt-4",
141
  messages=[{
@@ -143,49 +79,40 @@ class ContentGenerator:
143
  "content": "Generate spiritual quotes with author, tradition and theme."
144
  }, {
145
  "role": "user",
146
- "content": prompt_variation + "\nProvide quote in this format only:\nQUOTE:\nAUTHOR:\nTRADITION:\nTHEME:"
 
147
  }],
148
  temperature=0.7
149
  )
150
 
151
  text = response.choices[0].message.content
152
- lines = text.strip().split('\n')
153
- result = {}
154
- for line in lines:
155
- if ':' in line:
156
- key, value = line.split(':', 1)
157
- result[key.strip().lower()] = value.strip()
158
- return self._parse_quote_result(result)
159
-
160
  except Exception as e:
161
  log_message(f"❌ Quote generation failed: {str(e)}")
162
  return self._get_fallback_quote()
163
-
164
  def generate_image(self, quote, tradition, theme):
165
- """Generate an image using OpenAI DALL-E with enhanced prompts"""
166
  try:
167
  log_message("🎨 Starting image generation")
168
  style_prompts = {
169
  "Buddhism": "zen minimalism, misty mountains, lotus flowers",
170
  "Hinduism": "mandala patterns, sacred geometry, vibrant cosmos",
171
  "Taoism": "flowing water, yin-yang harmony, natural elements",
172
- "Modern Spirituality": "abstract sacred geometry, cosmic patterns",
173
- "Christian Mysticism": "ethereal light, cathedral aesthetics",
174
- "Sufi Wisdom": "whirling patterns, desert wisdom, geometric art",
175
- "Indigenous": "natural elements, earth tones, tribal patterns",
176
  "default": "serene minimalism, sacred geometry, natural elements"
177
  }
178
  style = style_prompts.get(tradition, style_prompts["default"])
179
  prompt = f"""Create a spiritual and contemplative image inspired by this theme: '{theme}'
180
  Style inspiration: {style}
181
  Mood: serene, inspiring, contemplative
182
- Requirements:
183
- - Suitable for Instagram
184
- - Leave space for text overlay
185
- - Balanced composition
186
- - No text or symbols
187
- - Peaceful and harmonious colors
188
- Make it visually striking yet subtle enough for quote overlay."""
189
  response = self.openai_client.images.generate(
190
  model="dall-e-3",
191
  prompt=prompt,
@@ -203,40 +130,24 @@ class ContentGenerator:
203
  try:
204
  log_message("🎡 Starting audio generation")
205
  music_prompts = {
206
- "Buddhism": {
207
- "Inner Peace": "Tibetan singing bowls and gentle bells with peaceful ambient drones",
208
- "Mindfulness": "Zen flute melodies with soft water sounds",
209
- "default": "Meditation bells with nature sounds"
210
- },
211
- "Hinduism": {
212
- "Devotion": "Indian bansuri flute with gentle tabla rhythms",
213
- "Wisdom": "Gentle sitar melodies with peaceful tanpura drone",
214
- "default": "Sanskrit chants with soft instrumentation"
215
- },
216
- "Modern Spirituality": {
217
- "Awareness": "Ambient synthesizer with crystal bowls",
218
- "Growth": "Uplifting piano melodies with gentle ambient pads",
219
- "default": "Modern meditation music with nature sounds"
220
- },
221
- "default": {
222
- "default": "Peaceful ambient music with gentle bells"
223
- }
224
  }
225
- tradition_prompts = music_prompts.get(tradition, music_prompts["default"])
226
- prompt = tradition_prompts.get(theme, tradition_prompts["default"])
227
  output = self.replicate_client.run(
228
  "meta/musicgen:671ac645ce5e552cc63a54a2bbff63fcf798043055d2dac5fc9e36a837eedcfb",
229
  input={
230
  "prompt": prompt,
231
  "model_version": "stereo-large",
232
  "output_format": "mp3",
233
- "normalization_strategy": "peak",
234
  "duration": 15
235
  }
236
  )
237
- audio_url = output if isinstance(output, str) else str(output)
238
  log_message("✨ Audio generated successfully")
239
- return audio_url
240
  except Exception as e:
241
  log_message(f"❌ Audio generation failed: {str(e)}", "error")
242
  raise
@@ -246,97 +157,38 @@ class ContentGenerator:
246
  response = requests.get(image_url)
247
  img = Image.open(BytesIO(response.content))
248
  width, height = img.size
249
-
250
- # Create blank image with text
251
  txt = Image.new('RGBA', (width, height), (255, 255, 255, 0))
252
  d = ImageDraw.Draw(txt)
253
 
254
- # Semi-transparent background for text
255
- d.rectangle([0, height / 2 - 100, width, height / 2 + 100],
256
- fill=(0, 0, 0, 127))
257
-
258
  try:
259
  quote_font = ImageFont.truetype("DejaVuSans-Bold", 40)
260
  author_font = ImageFont.truetype("DejaVuSans", 30)
261
  except:
262
- quote_font = ImageFont.load_default()
263
- author_font = ImageFont.load_default()
264
 
265
- # Add text
266
- d.text((width / 2, height / 2), quote_text,
267
- font=quote_font, fill=(255, 255, 255, 255), anchor="mm")
268
- d.text((width / 2, height / 2 + 60), f"- {author}",
269
- font=author_font, fill=(255, 255, 255, 255), anchor="mm")
270
 
271
- # Combine images
272
  out = Image.alpha_composite(img.convert('RGBA'), txt)
273
-
274
- # Convert to bytes
275
  buffer = BytesIO()
276
  out.convert('RGB').save(buffer, format='JPEG')
277
  return buffer.getvalue()
278
-
279
  except Exception as e:
280
  log_message(f"Error creating overlay: {str(e)}")
281
  return None
282
 
283
-
284
- def display_debug_logs():
285
- """Display debug logs with enhanced visualization"""
286
- st.markdown("### πŸ” Process Logs")
287
- # Create tabs for different log views
288
- log_tabs = st.tabs(["All Logs", "Errors Only", "Timeline"])
289
- with log_tabs[0]:
290
- for log in st.session_state.process_logs:
291
- if log["type"] == "error":
292
- st.error(f"{log['timestamp']} - {log['message']}")
293
- else:
294
- st.info(f"{log['timestamp']} - {log['message']}")
295
- with log_tabs[1]:
296
- errors = [log for log in st.session_state.process_logs if log["type"] == "error"]
297
- if errors:
298
- for error in errors:
299
- st.error(f"{error['timestamp']} - {error['message']}")
300
- else:
301
- st.success("No errors found! πŸŽ‰")
302
- with log_tabs[2]:
303
- st.markdown("#### Generation Timeline")
304
- for log in st.session_state.process_logs:
305
- with st.expander(f"{log['timestamp']} - {log['message'][:50]}...", expanded=False):
306
- st.text(log['message'])
307
-
308
-
309
- def generate_hashtags(tradition, theme):
310
- """Generate relevant hashtags"""
311
- base_tags = ["#spirituality", "#mindfulness", "#wisdom", "#inspiration", "#meditation"]
312
- tradition_tags = {
313
- "Buddhism": ["#buddhism", "#zen", "#buddhist", "#enlightenment", "#dharma"],
314
- "Hinduism": ["#hinduism", "#vedanta", "#yoga", "#sanskrit", "#consciousness"],
315
- "Taoism": ["#taoism", "#tao", "#balance", "#harmony", "#philosophy"],
316
- "Sufi Wisdom": ["#sufi", "#rumi", "#mysticism", "#spiritualpath", "#divine"],
317
- "Modern Spirituality": ["#spiritual", "#awakening", "#higherconsciousness", "#growth", "#innerpeace"]
318
- }
319
- theme_tags = {
320
- "Inner Peace": ["#peace", "#calm", "#serenity", "#tranquility"],
321
- "Mindfulness": ["#mindful", "#present", "#awareness", "#conscious"],
322
- "Wisdom": ["#wisdom", "#truth", "#knowledge", "#insight"],
323
- "Transformation": ["#transform", "#change", "#evolution", "#journey"]
324
- }
325
- custom_tags = tradition_tags.get(tradition, []) + theme_tags.get(theme, [])
326
- return list(set(base_tags + custom_tags))[:15]
327
-
328
-
329
- def display_debug_logs():
330
- """Display debug logs with enhanced visualization"""
331
  st.markdown("### πŸ” Process Logs")
332
  log_tabs = st.tabs(["All Logs", "Errors Only", "Timeline"])
333
 
334
  with log_tabs[0]:
335
  for log in st.session_state.process_logs:
336
- if log["type"] == "error":
337
- st.error(f"{log['timestamp']} - {log['message']}")
338
- else:
339
- st.info(f"{log['timestamp']} - {log['message']}")
340
 
341
  with log_tabs[1]:
342
  errors = [log for log in st.session_state.process_logs if log["type"] == "error"]
@@ -352,81 +204,65 @@ class ContentGenerator:
352
  with st.expander(f"{log['timestamp']} - {log['message'][:50]}...", expanded=False):
353
  st.text(log['message'])
354
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  def main():
356
- st.set_page_config(
357
- page_title="Spiritual Content Generator",
358
- page_icon="πŸ•‰οΈ",
359
- layout="wide"
360
- )
361
 
362
- # Initialize session state
363
- if 'process_logs' not in st.session_state:
364
- st.session_state.process_logs = []
365
- if 'generated_content' not in st.session_state:
366
- st.session_state.generated_content = None
367
- if 'generated_image' not in st.session_state:
368
- st.session_state.generated_image = None
369
- if 'generated_audio' not in st.session_state:
370
- st.session_state.generated_audio = None
371
 
372
- # Check for API keys
373
- if 'OPENAI_API_KEY' not in st.secrets:
374
- st.error("OpenAI API key not found in secrets!")
375
- st.stop()
376
- if 'REPLICATE_API_TOKEN' not in st.secrets:
377
- st.error("Replicate API token not found in secrets!")
378
  st.stop()
379
 
380
- # Tabs
381
  tab1, tab2, tab3 = st.tabs(["Generate Content", "Instagram Preview", "Debug Log"])
382
 
383
  with tab1:
384
  st.title("πŸ•‰οΈ Spiritual Content Generator")
385
-
386
- if st.button("Generate New Content", key="generate_button"):
387
  try:
388
- with st.spinner("Initializing content generation..."):
389
- generator = ContentGenerator(
390
- st.secrets["OPENAI_API_KEY"],
391
- st.secrets["REPLICATE_API_TOKEN"]
392
- )
393
-
394
- # Generate quote
395
- with st.status("Generating spiritual quote...") as status:
396
- quote_data = generator.generate_quote()
397
- st.session_state.generated_content = quote_data
398
- status.update(label="Quote generated successfully!", state="complete")
399
-
400
- # Generate image
401
- with st.status("Creating visual representation...") as status:
402
- image_url = generator.generate_image(
403
- quote_data["text"],
404
- quote_data["tradition"],
405
- quote_data["theme"]
406
- )
407
- st.session_state.generated_image = image_url
408
- status.update(label="Image generated successfully!", state="complete")
409
-
410
- # Generate audio
411
- with st.status("Composing background music...") as status:
412
- audio_url = generator.generate_audio(
413
- quote_data["tradition"],
414
- quote_data["theme"]
415
- )
416
- st.session_state.generated_audio = audio_url
417
- status.update(label="Audio generated successfully!", state="complete")
418
-
419
- st.success("✨ All content generated successfully!")
420
-
421
  except Exception as e:
422
  st.error(f"Error during generation: {str(e)}")
423
 
424
- # Display generated content
425
  if st.session_state.generated_content:
426
- st.subheader("Generated Content Details")
427
  st.json(st.session_state.generated_content)
428
 
429
- # Replace the tab2 section with:
430
  with tab2:
431
  st.title("Instagram Preview")
432
  if all([st.session_state.generated_content,
@@ -434,14 +270,11 @@ def main():
434
  st.session_state.generated_audio]):
435
 
436
  col1, col2 = st.columns([2, 1])
437
-
438
  with col1:
439
- # Image with quote overlay
 
440
  quote_data = st.session_state.generated_content
441
- generator = ContentGenerator(
442
- st.secrets["OPENAI_API_KEY"],
443
- st.secrets["REPLICATE_API_TOKEN"]
444
- )
445
  final_image = generator.create_image_with_quote(
446
  st.session_state.generated_image,
447
  quote_data['text'],
@@ -449,12 +282,8 @@ def main():
449
  )
450
  if final_image:
451
  st.image(final_image)
452
- st.download_button(
453
- "πŸ“₯ Download Image",
454
- data=final_image,
455
- file_name="spiritual_quote.jpg",
456
- mime="image/jpeg"
457
- )
458
 
459
  with col2:
460
  st.subheader("🎡 Background Music")
@@ -463,17 +292,12 @@ def main():
463
  audio_response = requests.get(st.session_state.generated_audio)
464
  if audio_response.status_code == 200:
465
  st.audio(audio_response.content, format='audio/mp3')
466
- st.download_button(
467
- "πŸ“₯ Download Audio",
468
- data=audio_response.content,
469
- file_name="background_music.mp3",
470
- mime="audio/mp3"
471
- )
472
  st.subheader("πŸ“ Caption")
473
- hashtags = generate_hashtags(
474
- quote_data['tradition'],
475
- quote_data.get('theme', 'Wisdom')
476
- )
477
  caption = f"""✨ Wisdom from {quote_data['tradition']} ✨
478
 
479
  "{quote_data['text']}"
@@ -481,16 +305,15 @@ def main():
481
 
482
  {' '.join(hashtags)}"""
483
  st.text_area("Instagram Caption", caption, height=200)
484
- else:
485
- st.error("Failed to load audio preview")
486
  except Exception as e:
487
  st.error(f"Error playing audio: {str(e)}")
488
  else:
489
  st.info("Generate content first to see the Instagram preview")
490
 
491
  with tab3:
492
- display_debug_logs()
493
-
 
494
 
495
  if __name__ == "__main__":
496
- main()
 
1
  import streamlit as st
2
  import os
3
  from datetime import datetime
 
4
  from crewai import Agent, Task, Crew
5
  from langchain_openai import OpenAI
6
  from openai import OpenAI as OpenAIClient
 
11
  from PIL import Image, ImageDraw, ImageFont
12
  from io import BytesIO
13
 
 
14
  logging.basicConfig(level=logging.INFO)
15
  logger = logging.getLogger(__name__)
16
 
 
17
  def log_message(message, type="info"):
 
18
  if 'process_logs' not in st.session_state:
19
  st.session_state.process_logs = []
20
  timestamp = datetime.now().strftime("%H:%M:%S")
 
24
  "type": type
25
  })
26
 
 
27
  class SpiritualThemes:
 
 
28
  TRADITIONS = {
29
+ "Eastern": ["Buddhism", "Hinduism", "Taoism", "Zen", "Vedanta", "Yoga Philosophy"],
30
+ "Western": ["Christian Mysticism", "Sufi Wisdom", "Kabbalah", "Greek Philosophy"],
31
+ "Indigenous": ["Native American Wisdom", "Aboriginal Spirituality", "African Traditional"],
32
+ "Modern": ["Mindfulness", "Contemporary Philosophy", "Integrative Spirituality"]
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
34
+ THEMES = ["Inner Peace", "Mindfulness", "Compassion", "Wisdom", "Self-Discovery",
35
+ "Unity", "Balance", "Transformation", "Enlightenment", "Purpose"]
36
+ QUOTE_STYLES = ["contemplative", "inspirational", "philosophical", "practical wisdom",
37
+ "mystical insight", "ancient teaching", "modern interpretation"]
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  class ContentGenerator:
40
  def __init__(self, openai_api_key, replicate_api_key):
 
43
  self.replicate_client = replicate.Client(api_token=replicate_api_key)
44
 
45
  def _generate_prompt_variation(self):
 
46
  tradition_category = random.choice(list(SpiritualThemes.TRADITIONS.keys()))
47
  traditions = SpiritualThemes.TRADITIONS[tradition_category]
48
  themes = random.sample(SpiritualThemes.THEMES, 2)
 
52
  Ensure the quote is profound yet accessible for social media."""
53
 
54
  def _get_fallback_quote(self):
 
55
  fallback_quotes = [
56
+ {"text": "Be the change you wish to see in the world.",
57
+ "author": "Mahatma Gandhi", "tradition": "Modern Spirituality"},
58
+ {"text": "Peace comes from within. Do not seek it without.",
59
+ "author": "Buddha", "tradition": "Buddhism"},
60
+ {"text": "Love is the bridge between you and everything.",
61
+ "author": "Rumi", "tradition": "Sufi Wisdom"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  ]
63
  quote = random.choice(fallback_quotes)
64
+ quote.update({
65
+ "theme": random.choice(SpiritualThemes.THEMES),
66
+ "generated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
67
+ "source": "fallback"
68
+ })
69
  log_message("ℹ️ Using fallback quote system", "info")
70
  return quote
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  def generate_quote(self):
73
  try:
74
  log_message("🎯 Starting quote generation")
 
 
75
  response = self.openai_client.chat.completions.create(
76
  model="gpt-4",
77
  messages=[{
 
79
  "content": "Generate spiritual quotes with author, tradition and theme."
80
  }, {
81
  "role": "user",
82
+ "content": self._generate_prompt_variation() +
83
+ "\nProvide quote in this format only:\nQUOTE:\nAUTHOR:\nTRADITION:\nTHEME:"
84
  }],
85
  temperature=0.7
86
  )
87
 
88
  text = response.choices[0].message.content
89
+ result = dict(line.split(':', 1) for line in text.strip().split('\n') if ':' in line)
90
+ return {
91
+ "text": result.get('quote', '').strip(),
92
+ "author": result.get('author', '').strip(),
93
+ "tradition": result.get('tradition', '').strip(),
94
+ "theme": result.get('theme', '').strip(),
95
+ "generated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
96
+ }
97
  except Exception as e:
98
  log_message(f"❌ Quote generation failed: {str(e)}")
99
  return self._get_fallback_quote()
100
+
101
  def generate_image(self, quote, tradition, theme):
 
102
  try:
103
  log_message("🎨 Starting image generation")
104
  style_prompts = {
105
  "Buddhism": "zen minimalism, misty mountains, lotus flowers",
106
  "Hinduism": "mandala patterns, sacred geometry, vibrant cosmos",
107
  "Taoism": "flowing water, yin-yang harmony, natural elements",
 
 
 
 
108
  "default": "serene minimalism, sacred geometry, natural elements"
109
  }
110
  style = style_prompts.get(tradition, style_prompts["default"])
111
  prompt = f"""Create a spiritual and contemplative image inspired by this theme: '{theme}'
112
  Style inspiration: {style}
113
  Mood: serene, inspiring, contemplative
114
+ Requirements: Suitable for Instagram, space for text overlay, balanced composition"""
115
+
 
 
 
 
 
116
  response = self.openai_client.images.generate(
117
  model="dall-e-3",
118
  prompt=prompt,
 
130
  try:
131
  log_message("🎡 Starting audio generation")
132
  music_prompts = {
133
+ "Buddhism": "Tibetan singing bowls and gentle bells with peaceful ambient drones",
134
+ "Hinduism": "Indian bansuri flute with gentle tabla rhythms",
135
+ "Modern Spirituality": "Ambient synthesizer with crystal bowls",
136
+ "default": "Peaceful ambient music with gentle bells"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  }
138
+ prompt = music_prompts.get(tradition, music_prompts["default"])
139
+
140
  output = self.replicate_client.run(
141
  "meta/musicgen:671ac645ce5e552cc63a54a2bbff63fcf798043055d2dac5fc9e36a837eedcfb",
142
  input={
143
  "prompt": prompt,
144
  "model_version": "stereo-large",
145
  "output_format": "mp3",
 
146
  "duration": 15
147
  }
148
  )
 
149
  log_message("✨ Audio generated successfully")
150
+ return output if isinstance(output, str) else str(output)
151
  except Exception as e:
152
  log_message(f"❌ Audio generation failed: {str(e)}", "error")
153
  raise
 
157
  response = requests.get(image_url)
158
  img = Image.open(BytesIO(response.content))
159
  width, height = img.size
 
 
160
  txt = Image.new('RGBA', (width, height), (255, 255, 255, 0))
161
  d = ImageDraw.Draw(txt)
162
 
163
+ d.rectangle([0, height/2 - 100, width, height/2 + 100], fill=(0, 0, 0, 127))
164
+
 
 
165
  try:
166
  quote_font = ImageFont.truetype("DejaVuSans-Bold", 40)
167
  author_font = ImageFont.truetype("DejaVuSans", 30)
168
  except:
169
+ quote_font = author_font = ImageFont.load_default()
 
170
 
171
+ d.text((width/2, height/2), quote_text, font=quote_font,
172
+ fill=(255, 255, 255, 255), anchor="mm")
173
+ d.text((width/2, height/2 + 60), f"- {author}", font=author_font,
174
+ fill=(255, 255, 255, 255), anchor="mm")
 
175
 
 
176
  out = Image.alpha_composite(img.convert('RGBA'), txt)
 
 
177
  buffer = BytesIO()
178
  out.convert('RGB').save(buffer, format='JPEG')
179
  return buffer.getvalue()
 
180
  except Exception as e:
181
  log_message(f"Error creating overlay: {str(e)}")
182
  return None
183
 
184
+ def display_debug_logs(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  st.markdown("### πŸ” Process Logs")
186
  log_tabs = st.tabs(["All Logs", "Errors Only", "Timeline"])
187
 
188
  with log_tabs[0]:
189
  for log in st.session_state.process_logs:
190
+ st.info(f"{log['timestamp']} - {log['message']}" if log["type"] != "error"
191
+ else st.error(f"{log['timestamp']} - {log['message']}"))
 
 
192
 
193
  with log_tabs[1]:
194
  errors = [log for log in st.session_state.process_logs if log["type"] == "error"]
 
204
  with st.expander(f"{log['timestamp']} - {log['message'][:50]}...", expanded=False):
205
  st.text(log['message'])
206
 
207
+ def generate_hashtags(tradition, theme):
208
+ base_tags = ["#spirituality", "#mindfulness", "#wisdom", "#inspiration"]
209
+ tradition_tags = {
210
+ "Buddhism": ["#buddhism", "#zen", "#buddhist"],
211
+ "Hinduism": ["#hinduism", "#vedanta", "#yoga"],
212
+ "Taoism": ["#taoism", "#tao", "#balance"],
213
+ "Modern Spirituality": ["#spiritual", "#awakening", "#growth"]
214
+ }
215
+ theme_tags = {
216
+ "Inner Peace": ["#peace", "#calm", "#serenity"],
217
+ "Mindfulness": ["#mindful", "#present", "#awareness"],
218
+ "Wisdom": ["#wisdom", "#truth", "#knowledge"]
219
+ }
220
+ custom_tags = tradition_tags.get(tradition, []) + theme_tags.get(theme, [])
221
+ return list(set(base_tags + custom_tags))[:10]
222
+
223
  def main():
224
+ st.set_page_config(page_title="Spiritual Content Generator", page_icon="πŸ•‰οΈ", layout="wide")
 
 
 
 
225
 
226
+ for state_var in ['process_logs', 'generated_content', 'generated_image', 'generated_audio']:
227
+ if state_var not in st.session_state:
228
+ st.session_state[state_var] = None
 
 
 
 
 
 
229
 
230
+ if not all(key in st.secrets for key in ['OPENAI_API_KEY', 'REPLICATE_API_TOKEN']):
231
+ st.error("Missing API keys in secrets!")
 
 
 
 
232
  st.stop()
233
 
 
234
  tab1, tab2, tab3 = st.tabs(["Generate Content", "Instagram Preview", "Debug Log"])
235
 
236
  with tab1:
237
  st.title("πŸ•‰οΈ Spiritual Content Generator")
238
+
239
+ if st.button("Generate New Content"):
240
  try:
241
+ generator = ContentGenerator(st.secrets["OPENAI_API_KEY"],
242
+ st.secrets["REPLICATE_API_TOKEN"])
243
+
244
+ with st.spinner("Generating content..."):
245
+ quote_data = generator.generate_quote()
246
+ st.session_state.generated_content = quote_data
247
+
248
+ image_url = generator.generate_image(quote_data["text"],
249
+ quote_data["tradition"],
250
+ quote_data["theme"])
251
+ st.session_state.generated_image = image_url
252
+
253
+ audio_url = generator.generate_audio(quote_data["tradition"],
254
+ quote_data["theme"])
255
+ st.session_state.generated_audio = audio_url
256
+
257
+ st.success("✨ Content generated successfully!")
258
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  except Exception as e:
260
  st.error(f"Error during generation: {str(e)}")
261
 
 
262
  if st.session_state.generated_content:
263
+ st.subheader("Generated Content")
264
  st.json(st.session_state.generated_content)
265
 
 
266
  with tab2:
267
  st.title("Instagram Preview")
268
  if all([st.session_state.generated_content,
 
270
  st.session_state.generated_audio]):
271
 
272
  col1, col2 = st.columns([2, 1])
273
+
274
  with col1:
275
+ generator = ContentGenerator(st.secrets["OPENAI_API_KEY"],
276
+ st.secrets["REPLICATE_API_TOKEN"])
277
  quote_data = st.session_state.generated_content
 
 
 
 
278
  final_image = generator.create_image_with_quote(
279
  st.session_state.generated_image,
280
  quote_data['text'],
 
282
  )
283
  if final_image:
284
  st.image(final_image)
285
+ st.download_button("πŸ“₯ Download Image", final_image,
286
+ "spiritual_quote.jpg", "image/jpeg")
 
 
 
 
287
 
288
  with col2:
289
  st.subheader("🎡 Background Music")
 
292
  audio_response = requests.get(st.session_state.generated_audio)
293
  if audio_response.status_code == 200:
294
  st.audio(audio_response.content, format='audio/mp3')
295
+ st.download_button("πŸ“₯ Download Audio", audio_response.content,
296
+ "background_music.mp3", "audio/mp3")
297
+
 
 
 
298
  st.subheader("πŸ“ Caption")
299
+ hashtags = generate_hashtags(quote_data['tradition'],
300
+ quote_data.get('theme', 'Wisdom'))
 
 
301
  caption = f"""✨ Wisdom from {quote_data['tradition']} ✨
302
 
303
  "{quote_data['text']}"
 
305
 
306
  {' '.join(hashtags)}"""
307
  st.text_area("Instagram Caption", caption, height=200)
 
 
308
  except Exception as e:
309
  st.error(f"Error playing audio: {str(e)}")
310
  else:
311
  st.info("Generate content first to see the Instagram preview")
312
 
313
  with tab3:
314
+ generator = ContentGenerator(st.secrets["OPENAI_API_KEY"],
315
+ st.secrets["REPLICATE_API_TOKEN"])
316
+ generator.display_debug_logs()
317
 
318
  if __name__ == "__main__":
319
+ main()