Spaces:
Sleeping
Sleeping
Upload 3 files
Browse files- app_clean.py +258 -0
app_clean.py
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from gtts import gTTS
|
| 2 |
+
import tempfile
|
| 3 |
+
import json
|
| 4 |
+
import datetime
|
| 5 |
+
import gradio as gr
|
| 6 |
+
import re
|
| 7 |
+
import os
|
| 8 |
+
from openai import OpenAI
|
| 9 |
+
|
| 10 |
+
# OpenAI Configuration
|
| 11 |
+
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "your-api-key-here")
|
| 12 |
+
client = OpenAI(api_key=OPENAI_API_KEY)
|
| 13 |
+
|
| 14 |
+
# System prompt for ChatGPT to act as a compassionate therapist
|
| 15 |
+
SYSTEM_PROMPT = """You are StrongMind Therapist - a compassionate, empathetic AI therapist designed to provide emotional support and mental health guidance.
|
| 16 |
+
Your role is to:
|
| 17 |
+
- Listen actively and validate the person's feelings
|
| 18 |
+
- Provide thoughtful, compassionate responses
|
| 19 |
+
- Offer practical coping strategies and mental health tips when appropriate
|
| 20 |
+
- Be supportive and non-judgmental
|
| 21 |
+
- Encourage them to seek professional help if needed
|
| 22 |
+
- Keep responses conversational and natural, like talking to a caring human counselor
|
| 23 |
+
- Be brief but warm (2-3 sentences typically, unless they ask for more detail)"""
|
| 24 |
+
|
| 25 |
+
# User data
|
| 26 |
+
user_info = {"name": "", "age": "", "gender": "", "language": "english", "Guardian_info": ""}
|
| 27 |
+
chat_history = []
|
| 28 |
+
journal_entries = []
|
| 29 |
+
|
| 30 |
+
calm_tips = [
|
| 31 |
+
"Take 3 deep breaths.", "Listen to nature.", "Stretch your body.",
|
| 32 |
+
"Drink water.", "Think of one good thing today.", "Close your eyes for 1 minute.",
|
| 33 |
+
"Write your feelings.", "Smile at yourself.", "Imagine a peaceful place.",
|
| 34 |
+
"Say a positive affirmation."
|
| 35 |
+
]
|
| 36 |
+
|
| 37 |
+
study_tips = [
|
| 38 |
+
"Use Pomodoro: 25min study, 5min break", "Make a daily to-do list",
|
| 39 |
+
"Avoid multitasking", "Use color-coded notes", "Take 10-min exercise breaks",
|
| 40 |
+
"Sleep 7-9 hrs daily", "Drink water during study", "Use active recall",
|
| 41 |
+
"Study hardest topics first", "Test yourself often"
|
| 42 |
+
]
|
| 43 |
+
|
| 44 |
+
tip_index = {"calm": 0, "study": 0}
|
| 45 |
+
|
| 46 |
+
lang_codes = {
|
| 47 |
+
"english": "en", "hindi": "hi", "marathi": "mr", "bengali": "bn",
|
| 48 |
+
"tamil": "ta", "telugu": "te", "malayalam": "ml", "spanish": "es",
|
| 49 |
+
"french": "fr", "german": "de"
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
harmful_keywords = [
|
| 53 |
+
"abomination", "annihilate", "arson", "assault", "atrocity", "backstab",
|
| 54 |
+
"barbaric", "beast", "belittle", "berserk", "betray", "betrayal", "bigot",
|
| 55 |
+
"blacklist", "blood", "bloodbath", "bloody", "bomb", "brutal", "brute",
|
| 56 |
+
"burn", "butcher", "chaos", "cheater", "cold-blooded", "conman", "corrupt",
|
| 57 |
+
"cowardly", "crash", "crime", "cruel", "cruelty", "damage", "danger",
|
| 58 |
+
"dangerous", "deadly", "deceive", "defame", "defeat", "degenerate", "demon",
|
| 59 |
+
"despise", "destroy", "destruction", "devil", "dirty", "disaster", "dishonor",
|
| 60 |
+
"drunk", "dumbass", "dungeon", "enemy", "enrage", "evil", "exploit",
|
| 61 |
+
"exterminate", "fake", "fanatic", "fascist", "fatal", "fire", "fraud",
|
| 62 |
+
"gang", "gangster", "ghastly", "ghoul", "gory", "grotesque", "gruesome",
|
| 63 |
+
"hag", "halfwit", "harm", "hateful", "havoc", "hell", "hideous", "horrid",
|
| 64 |
+
"horrific", "hostility", "illegal", "illicit", "immoral", "imposter",
|
| 65 |
+
"injure", "insensitive", "intolerant", "irate", "jerky", "joker", "kidnap",
|
| 66 |
+
"liar", "loath", "loathsome", "lowlife", "madness", "malicious", "malign",
|
| 67 |
+
"manipulate", "menace", "monster", "monstrous", "murderous", "mutant",
|
| 68 |
+
"mutiny", "nasty", "nefarious", "neglect", "negative", "offend", "offender",
|
| 69 |
+
"ominous", "oppress", "outrage", "parasite", "penalty", "perish", "pest",
|
| 70 |
+
"plague", "poison", "poisonous", "pollute", "psychopath", "punch", "punish",
|
| 71 |
+
"punishment", "quarrel", "rage", "rat", "rebellion", "reckless", "repel",
|
| 72 |
+
"repulsive", "revolt", "rioter", "rob", "robber", "rotten", "ruin", "savage",
|
| 73 |
+
"scare", "scary", "schemer", "scold", "scorn", "scoundrel", "scream",
|
| 74 |
+
"screwed", "serpent", "shady", "sham", "shameful", "shatter", "shocking",
|
| 75 |
+
"sin", "sinister", "slimy", "smash", "smite", "snob", "spite", "spiteful",
|
| 76 |
+
"stab", "stench", "stink", "strike", "subvert", "suspicious", "target",
|
| 77 |
+
"tease", "terrible", "terrify", "thief", "threat", "threaten", "thug",
|
| 78 |
+
"torment", "torture", "trap", "trick", "trigger", "trouble", "unfair",
|
| 79 |
+
"unjust", "unkind", "usurper", "vandal", "vandalize", "venom", "venomous",
|
| 80 |
+
"villain", "villainous", "vindictive", "violent", "viper", "war",
|
| 81 |
+
"warmonger", "waste", "wicked", "wild", "wound", "wrath", "wreck", "wrong",
|
| 82 |
+
"yell", "zombie", "suicide", "kill myself", "end my life", "harm myself",
|
| 83 |
+
"cut myself", "want to die", "die", "jump off", "self-harm", "give up",
|
| 84 |
+
"not worth it", "ending it all", "self-hate", "suicidal", "tragic", "trauma",
|
| 85 |
+
"pain", "painful", "sorrow", "unworthy", "hurt", "grief", "agony", "doom",
|
| 86 |
+
"doomed"
|
| 87 |
+
]
|
| 88 |
+
|
| 89 |
+
harmful_response = (
|
| 90 |
+
"โ ๏ธ It sounds like you're going through a really tough time.\n\n"
|
| 91 |
+
"Please reach out to a professional:\n\n"
|
| 92 |
+
"๐ฎ๐ณ **India Helplines**\n"
|
| 93 |
+
"๐ง *Dr. Rachna Khanna Singh* โ +91 99103 90559\n"
|
| 94 |
+
"๐ *iCall Helpline* โ +91 9152987821\n"
|
| 95 |
+
"๐ *Vandrevala Foundation* โ 1860 266 2345 or 1800 233 3330\n\n"
|
| 96 |
+
"๐ **International Helplines**\n"
|
| 97 |
+
"๐ *Lifeline (USA)* โ 988\n"
|
| 98 |
+
"๐ *Samaritans (UK)* โ 116 123\n"
|
| 99 |
+
"๐ *Lifeline (Australia)* โ 13 11 14\n\n"
|
| 100 |
+
"You are not alone. There are people who care and want to help ๐"
|
| 101 |
+
)
|
| 102 |
+
|
| 103 |
+
def set_personal_info(name, age, gender, language, Guardian_info):
|
| 104 |
+
user_info.update({"name": name, "age": age, "gender": gender, "language": language, "Guardian_info": Guardian_info})
|
| 105 |
+
return gr.update(visible=True), f"โ
Welcome {name}! Preferences saved."
|
| 106 |
+
|
| 107 |
+
def show_personal_data():
|
| 108 |
+
today = datetime.date.today().strftime("%Y-%m-%d (%A)")
|
| 109 |
+
return f"๐
{today}\n๐ค Name: {user_info['name']}\n๐ Age: {user_info['age']}\nโ Gender: {user_info['gender']}\n๐ Language: {user_info['language']}\n Guardian: {user_info['Guardian_info']}"
|
| 110 |
+
|
| 111 |
+
def generate_reply(input_text):
|
| 112 |
+
text = input_text.lower()
|
| 113 |
+
for word in harmful_keywords:
|
| 114 |
+
pattern = r'\b' + re.escape(word) + r'\b'
|
| 115 |
+
if re.search(pattern, text):
|
| 116 |
+
return harmful_response
|
| 117 |
+
|
| 118 |
+
try:
|
| 119 |
+
response = client.chat.completions.create(
|
| 120 |
+
model="gpt-3.5-turbo",
|
| 121 |
+
messages=[
|
| 122 |
+
{"role": "system", "content": SYSTEM_PROMPT},
|
| 123 |
+
{"role": "user", "content": input_text}
|
| 124 |
+
],
|
| 125 |
+
temperature=0.7,
|
| 126 |
+
max_tokens=200
|
| 127 |
+
)
|
| 128 |
+
return response.choices[0].message.content
|
| 129 |
+
except Exception as e:
|
| 130 |
+
return "I'm having trouble connecting right now, but I'm here to listen. Can you tell me more about what you're feeling?"
|
| 131 |
+
|
| 132 |
+
def chat_function(audio_input, text_input):
|
| 133 |
+
user_text = text_input.strip()
|
| 134 |
+
if not user_text:
|
| 135 |
+
return "Please type something or try again.", None
|
| 136 |
+
try:
|
| 137 |
+
reply = generate_reply(user_text)
|
| 138 |
+
chat_history.append({"user": user_text, "bot": reply})
|
| 139 |
+
lang_code = lang_codes.get(user_info["language"], "en")
|
| 140 |
+
tts = gTTS(reply, lang=lang_code)
|
| 141 |
+
audio_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
|
| 142 |
+
tts.save(audio_file.name)
|
| 143 |
+
return reply, audio_file.name
|
| 144 |
+
except Exception as e:
|
| 145 |
+
return f"Something went wrong: {str(e)}", None
|
| 146 |
+
|
| 147 |
+
def get_chat_history():
|
| 148 |
+
if not chat_history:
|
| 149 |
+
return "No conversations yet."
|
| 150 |
+
return "\n\n".join([f"You: {c['user']}\nBot: {c['bot']}" for c in chat_history])
|
| 151 |
+
|
| 152 |
+
def save_journal(entry):
|
| 153 |
+
if not entry.strip():
|
| 154 |
+
return "โ ๏ธ Please write something before saving."
|
| 155 |
+
try:
|
| 156 |
+
journal_entries.append(entry)
|
| 157 |
+
with open("journal.json", "w") as f:
|
| 158 |
+
json.dump(journal_entries, f, indent=2)
|
| 159 |
+
return "โ
Journal entry saved successfully!"
|
| 160 |
+
except Exception as e:
|
| 161 |
+
return f"โ Error saving journal: {str(e)}"
|
| 162 |
+
|
| 163 |
+
def show_journal_history():
|
| 164 |
+
return "\n---\n".join(journal_entries) if journal_entries else "No journal entries yet."
|
| 165 |
+
|
| 166 |
+
def next_calm_tip():
|
| 167 |
+
tip = calm_tips[tip_index["calm"] % len(calm_tips)]
|
| 168 |
+
tip_index["calm"] += 1
|
| 169 |
+
return tip
|
| 170 |
+
|
| 171 |
+
def next_study_tip():
|
| 172 |
+
tip = study_tips[tip_index["study"] % len(study_tips)]
|
| 173 |
+
tip_index["study"] += 1
|
| 174 |
+
return tip
|
| 175 |
+
|
| 176 |
+
# Gradio App
|
| 177 |
+
with gr.Blocks() as app:
|
| 178 |
+
welcome_screen = gr.Column(visible=True)
|
| 179 |
+
full_app = gr.Tabs(visible=False)
|
| 180 |
+
|
| 181 |
+
with welcome_screen:
|
| 182 |
+
gr.HTML("""
|
| 183 |
+
<style>
|
| 184 |
+
#main-title { text-align: center; font-size: 2.5em; }
|
| 185 |
+
#subtitle { text-align: center; font-size: 1.2em; color: #ccc; margin-bottom: 30px; }
|
| 186 |
+
#start-btn { background-color: #ff69b4; color: white; font-weight: bold; border: none; border-radius: 10px; padding: 14px 45px; font-size: 1.1em; cursor: pointer; display: block; margin: 0 auto; }
|
| 187 |
+
#start-btn:hover { background-color: #ff85c1; }
|
| 188 |
+
</style>
|
| 189 |
+
""")
|
| 190 |
+
gr.Markdown("<h1 id='main-title'>StrongMind Therapist 2.0</h1>")
|
| 191 |
+
gr.Markdown("<h3 id='subtitle'>Your peaceful space to talk, journal, and focus.</h3>")
|
| 192 |
+
start_button = gr.Button("๐ธ Get Started", elem_id="start-btn")
|
| 193 |
+
|
| 194 |
+
def start_app():
|
| 195 |
+
return gr.update(visible=False), gr.update(visible=True)
|
| 196 |
+
|
| 197 |
+
start_button.click(start_app, outputs=[welcome_screen, full_app])
|
| 198 |
+
|
| 199 |
+
with full_app:
|
| 200 |
+
with gr.Tab("1๏ธโฃ Personal Info"):
|
| 201 |
+
name = gr.Textbox(label="Name")
|
| 202 |
+
age = gr.Textbox(label="Age")
|
| 203 |
+
gender = gr.Dropdown(["Male", "Female", "Other"], label="Gender")
|
| 204 |
+
language = gr.Dropdown(list(lang_codes.keys()), label="Preferred Language")
|
| 205 |
+
Guardian_info = gr.Textbox(label="Guardian information")
|
| 206 |
+
btn = gr.Button("Save Info")
|
| 207 |
+
popup = gr.Markdown(visible=False, elem_classes="alert-box")
|
| 208 |
+
btn.click(set_personal_info, [name, age, gender, language, Guardian_info], [popup, popup])
|
| 209 |
+
|
| 210 |
+
with gr.Tab("2๏ธโฃ Personal Info Data"):
|
| 211 |
+
show = gr.Button("Show My Info")
|
| 212 |
+
info_display = gr.Textbox(lines=6)
|
| 213 |
+
show.click(show_personal_data, outputs=info_display)
|
| 214 |
+
|
| 215 |
+
with gr.Tab("3๏ธโฃ Chat"):
|
| 216 |
+
gr.Markdown("๐ฃ๏ธ Describe your day in one word.")
|
| 217 |
+
audio_input = gr.Audio(type="filepath", label="๐ง Say something")
|
| 218 |
+
text_input = gr.Textbox(label="โจ๏ธ Or type here")
|
| 219 |
+
send = gr.Button("Send")
|
| 220 |
+
bot_reply = gr.Textbox(label="๐ง Therapist")
|
| 221 |
+
voice = gr.Audio(label="๐ Voice Reply")
|
| 222 |
+
send.click(chat_function, [audio_input, text_input], [bot_reply, voice])
|
| 223 |
+
|
| 224 |
+
with gr.Tab("4๏ธโฃ Chat History"):
|
| 225 |
+
show_history = gr.Button("๐ Show Chats")
|
| 226 |
+
chat_out = gr.Textbox(lines=20, label="History")
|
| 227 |
+
show_history.click(get_chat_history, outputs=chat_out)
|
| 228 |
+
|
| 229 |
+
with gr.Tab("5๏ธโฃ Journal"):
|
| 230 |
+
journal_input = gr.Textbox(lines=6, label="Write your thoughts")
|
| 231 |
+
save = gr.Button("Save")
|
| 232 |
+
journal_status = gr.Textbox()
|
| 233 |
+
save.click(save_journal, journal_input, journal_status)
|
| 234 |
+
|
| 235 |
+
with gr.Tab("6๏ธโฃ Journal History"):
|
| 236 |
+
view = gr.Button("View Past Entries")
|
| 237 |
+
past = gr.Textbox(lines=15, label="Previous Journals")
|
| 238 |
+
view.click(show_journal_history, outputs=past)
|
| 239 |
+
|
| 240 |
+
with gr.Tab("7๏ธโฃ Calm Space"):
|
| 241 |
+
tip_btn = gr.Button("๐ฟ Give Me a Calm Tip")
|
| 242 |
+
calm_text = gr.Textbox()
|
| 243 |
+
tip_btn.click(next_calm_tip, outputs=calm_text)
|
| 244 |
+
|
| 245 |
+
with gr.Tab("8๏ธโฃ Study Tips"):
|
| 246 |
+
tip_btn2 = gr.Button("๐ Study Tip")
|
| 247 |
+
study_text = gr.Textbox()
|
| 248 |
+
tip_btn2.click(next_study_tip, outputs=study_text)
|
| 249 |
+
|
| 250 |
+
with gr.Tab("9๏ธโฃ Pomodoro"):
|
| 251 |
+
gr.Markdown("โฑ๏ธ Use 25 min study + 5 min break cycles.\n(Use Android timers or JS for real timer)")
|
| 252 |
+
|
| 253 |
+
with gr.Tab("๐ Games"):
|
| 254 |
+
gr.Markdown("๐ฎ Play from the game portal below:")
|
| 255 |
+
gr.HTML('<iframe src="https://www.onlinegames.io/embed/portal/" width="100%" height="600" frameborder="0" allowfullscreen></iframe>')
|
| 256 |
+
|
| 257 |
+
if __name__ == "__main__":
|
| 258 |
+
app.launch()
|