File size: 5,559 Bytes
5df380a
bbc5824
46fcda1
bbc5824
46fcda1
 
e91ce40
bbc5824
46fcda1
 
e91ce40
46fcda1
e91ce40
bbc5824
 
e91ce40
569d0ae
bbc5824
 
e91ce40
bbc5824
 
 
 
46fcda1
e91ce40
bbc5824
e91ce40
bbc5824
 
46fcda1
 
 
e1e334a
bbc5824
e91ce40
60744d4
e91ce40
46fcda1
60744d4
e91ce40
46fcda1
 
bbc5824
46fcda1
 
e91ce40
46fcda1
 
e91ce40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46fcda1
75db4f2
bbc5824
e91ce40
 
 
 
8656728
75db4f2
bbc5824
e91ce40
 
 
 
 
46fcda1
 
bbc5824
 
46fcda1
354be17
618fc98
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import os
from groq import Groq
import gradio as gr
from gtts import gTTS
import re

groq_key = os.environ.get("GROQ_API_KEY")
client = Groq(api_key=groq_key)

def generate_story(age, theme, language):
    system_msg = {"role": "system", "content": "You write age-appropriate stories with complete endings and a moral."}
    age_i = int(age)
    length = "300 words" if age_i <= 6 else "600 words" if age_i <= 9 else "1000 words"
    user_msg = {
        "role": "user",
        "content": f"Write a complete story for a {age}-year-old child. Theme: {theme}. Language: {language}. Length about {length}. End with a clear moral of the story."
    }
    response = client.chat.completions.create(
        messages=[system_msg, user_msg],
        model="openai/gpt-oss-20b",
        max_tokens=2000,
        temperature=0.8
    )
    return response.choices[0].message.content.strip()

def story_to_speech(story, language_code='en'):
    tts = gTTS(text=story, lang=language_code)
    filename = "/tmp/story.mp3"
    tts.save(filename)
    return filename

def create_story_interface(age, theme, language, tts_option):
    story = generate_story(age, theme, language)
    story = re.sub(r'[*_#`~]', '', story)
    lines = story.split("\n", 1)
    title, rest_of_story = (lines[0], lines[1]) if len(lines) > 1 else (lines[0], "")
    if language.lower().startswith("u"):
        story_html = f'<div style="text-align:center; font-size:1.3em; direction:rtl; margin-bottom:5px;">{title}</div><div style="font-size:1.2em; direction:rtl; text-align:right;">{rest_of_story}</div>'
        lang_code = "ur"
    else:
        story_html = f'<div style="text-align:center; font-size:1.3em; direction:ltr; margin-bottom:5px;">{title}</div><div style="font-size:1.2em; direction:ltr; text-align:left;">{rest_of_story}</div>'
        lang_code = "en"
    audio_file = story_to_speech(story, lang_code) if tts_option else None
    return story_html, audio_file

age_options = [str(i) for i in range(3, 13)]
theme_options = ["Adventure","Animals","Fantasy","Educational","Friendship","Magic","Science","Mystery","Space","Nature","Kindness","Courage"]
language_options = ["English", "Urdu"]

# -----------------------------------------------
# GRADIO APP
# -----------------------------------------------
with gr.Blocks() as iface:
    gr.HTML("""<style>
    @import url('https://fonts.googleapis.com/css2?family=Comic+Neue:wght@400;700&display=swap');
    .gradio-container { font-family: 'Comic Neue', cursive !important; background: linear-gradient(135deg, #ffafbd, #ffc3a0) !important; padding-top: 10px !important; margin-top: -70px !important;}
    .main-header { text-align: center; font-weight: bold !important; font-size: 3.2em !important; margin-top: 40px !important; margin-bottom: 20px !important; text-shadow: 2px 2px 4px rgba(0,0,0,0.1); color: #12979B;}
    .story-container { background:#fff5ee; border-radius: 20px; padding: 25px; border: 5px solid #FFD166; box-shadow: 0 8px 25px rgba(0,0,0,0.1); min-height: 400px; margin-top: -20px !important;}
    .control-panel { background: #fff5ee; border-radius: 15px; padding: 20px; border: 3px dashed #4ECDC4; font-size: 1.2em !important; font-weight: 600; margin-top: -20px !important;}
    .generate-btn { background: linear-gradient(45deg, #FF6B6B, #FF9E7D) !important; border: none !important; border-radius: 50px !important; padding: 10px 22px !important; font-size: 1em !important; font-weight: bold !important; color: white !important; margin-top: 20px !important;}
    .generate-btn:hover { transform: scale(1.05); box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4);}
    .dropdown, .checkbox { background: white !important; border-radius: 10px !important; border: 2px solid #96CEB4 !important;}
    .audio-player { border-radius: 15px !important; margin-top: 20px;}
    .subtitle { text-align: left; font-size: 1.5em !important; font-weight: 600; color: white; margin-top: -10px !important; margin-bottom: 20px; text-shadow: 1px 1px 2px rgba(0,0,0,0.1);}
    .footer { text-align: center; margin-top: 20px; color: #666; font-style: italic; font-size: 1.5em !important;}
    </style>
    """)

    
    gr.HTML("""<div class="main-header">🌈 StoryTime AI🎪</div>""")
    gr.HTML("""<div class="subtitle">🎯 Create amazing stories that spark imagination and teach valuable lessons!</div>""")
    
    with gr.Row():
        with gr.Column(scale=1, min_width=300):
            with gr.Group(elem_classes="control-panel"):
                age_input = gr.Dropdown(age_options, label="👶 Child's Age", value="5")
                theme_input = gr.Dropdown(theme_options, label="🎭 Story Theme", value="Adventure")
                language_input = gr.Dropdown(language_options, label="🌍 Language", value="English")
                tts_input = gr.Checkbox(label="🎵 Include Audio Story", value=True)
                generate_btn = gr.Button("✨ Create Magical Story! ✨", elem_classes="generate-btn")
        with gr.Column(scale=2):
            with gr.Group(elem_classes="story-container"):
                story_output = gr.Markdown("Your story will appear here!", show_label=False)
            audio_output = gr.Audio(label="Audio Story", elem_classes="audio-player")
    
    gr.HTML("""<div class="footer">Made with ❤️ for young readers everywhere! | Watch your stories come to life! ✨</div>""")
    
    generate_btn.click(
        create_story_interface,
        [age_input, theme_input, language_input, tts_input],
        [story_output, audio_output]
    )

iface.launch(ssr_mode=False)