pathananas's picture
app.py
4c63eb9 verified
import gradio as gr
from model import multimodal_analyze
from database import get_history, clear_history_db
# ==============================================
# HISTORY DISPLAY
# ==============================================
def fetch_history():
records = get_history()
if not records:
return "<p>No history yet.</p>"
html = ""
for r in records:
html += f"""
<div class="history-card">
<div class="history-time">πŸ•’ {r.get('timestamp')}</div>
<div class="history-section">
<b>Text:</b> {r.get('text')}
</div>
<div class="history-section">
<b>Image:</b> {r.get('image')}
</div>
<div class="history-section">
<b>Audio Tone:</b> {r.get('audio')}
</div>
<div class="history-section">
<b>Speech:</b> {r.get('transcription')}
</div>
<div class="history-score">
Fusion Score: {r.get('fusion_score')}
</div>
</div>
"""
return html
def show_loader():
return gr.update(value="""
<div class="ai-loader">
<div class="spinner"></div>
AI is analyzing inputs...
</div>
""", visible=True)
def hide_loader():
return gr.update(visible=False)
# ==============================================
# CSS (same styling)
# ==============================================
# ==============================================
# Custom Dark Styling (UNCHANGED)
# ==============================================
custom_css = """
/* =====================================================
FULL DARK BACKGROUND
===================================================== */
html, body {
background-color: #0b1220 !important;
}
.gradio-container {
background-color: #0b1220 !important;
}
/* =====================================================
DARK CARD BLOCKS
===================================================== */
.gradio-container .block {
background-color: #162033 !important;
border: 1px solid #1f2a44 !important;
border-radius: 14px !important;
}
/* =====================================================
INPUT FIELDS
===================================================== */
textarea, input, select {
background-color: #1e293b !important;
border: 1px solid #2a3a55 !important;
color: #e2e8f0 !important;
border-radius: 10px !important;
}
/* =====================================================
TEXT COLORS
===================================================== */
.gradio-container * {
color: #e2e8f0 !important;
}
h1, h2, h3 {
color: #ffffff !important;
}
/* =====================================================
MAIN BUTTON STYLE
===================================================== */
button {
background: linear-gradient(135deg, #14b8a6, #8b5cf6) !important;
border-radius: 10px !important;
font-weight: 600 !important;
color: white !important;
border: none !important;
}
button:hover {
filter: brightness(1.1);
}
/* Remove disabled fade */
button[disabled] {
opacity: 1 !important;
background: linear-gradient(135deg, #14b8a6, #8b5cf6) !important;
color: white !important;
}
/* =====================================================
UPLOAD AREA FIX
===================================================== */
.gr-image > div:first-child,
.gr-audio > div:first-child {
background: transparent !important;
border: none !important;
}
.gr-image .wrap,
.gr-audio .wrap {
background: transparent !important;
}
.gr-image label,
.gr-audio label,
.gr-image button,
.gr-audio button {
display: none !important;
}
.gr-image > div,
.gr-audio > div {
background: linear-gradient(135deg, #14b8a6, #8b5cf6) !important;
border-radius: 14px !important;
}
.gr-file-preview,
.gradio-container div[class*="file"],
.gradio-container div[class*="upload"],
.gradio-container div[class*="progress"] {
background-color: #162033 !important;
color: #e2e8f0 !important;
}
/* =====================================================
SCROLLBAR DARK
===================================================== */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #0b1220;
}
::-webkit-scrollbar-thumb {
background: #2a3a55;
border-radius: 10px;
}
/* =====================================================
OUTPUT BOX STYLING
===================================================== */
#fusion_box {
background: linear-gradient(135deg, #0f172a, #1e293b);
padding: 20px;
border-radius: 16px;
border: 1px solid #1f2a44;
}
#text_box, #image_box, #audio_box {
background-color: #162033;
padding: 16px;
border-radius: 14px;
border: 1px solid #1f2a44;
margin-top: 12px;
}
#history_box {
background-color: #162033;
padding: 16px;
border-radius: 14px;
border: 1px solid #1f2a44;
min-height: 200px;
margin-top: 12px;
}
/* ===========================
HISTORY CHATGPT STYLE
=========================== */
#history_box{
background-color:#162033;
border:1px solid #1f2a44;
border-radius:14px;
padding:16px;
min-height:220px;
max-height:450px;
overflow-y:auto;
}
.history-card{
background:#1e293b;
border:1px solid #2a3a55;
border-radius:12px;
padding:14px;
margin-bottom:12px;
transition:all 0.2s ease;
}
.history-card:hover{
transform:translateY(-2px);
box-shadow:0 8px 20px rgba(0,0,0,0.25);
}
.history-time{
font-size:13px;
opacity:0.7;
margin-bottom:6px;
}
.history-item{
margin-bottom:4px;
}
.history-score{
margin-top:6px;
font-weight:600;
color:#14b8a6;
}
/* HISTORY CARDS */
#history_box{
max-height:450px;
overflow-y:auto;
}
.history-card{
background:#1e293b;
border:1px solid #2a3a55;
padding:16px;
border-radius:12px;
margin-bottom:12px;
}
.history-time{
font-size:13px;
opacity:0.7;
margin-bottom:6px;
}
.history-section{
margin-bottom:4px;
}
.history-score{
margin-top:6px;
font-weight:bold;
color:#14b8a6;
}
.loader{
width:30px;
height:30px;
border:4px solid #2a3a55;
border-top:4px solid #14b8a6;
border-radius:50%;
animation:spin 1s linear infinite;
margin:auto;
}
@keyframes spin{
0%{transform:rotate(0deg);}
100%{transform:rotate(360deg);}
}
.ai-loader{
display:flex;
align-items:center;
gap:10px;
font-size:16px;
}
.spinner{
width:18px;
height:18px;
border:3px solid #2a3a55;
border-top:3px solid #14b8a6;
border-radius:50%;
animation:spin 1s linear infinite;
}
@keyframes spin{
0%{transform:rotate(0deg);}
100%{transform:rotate(360deg);}
}
"""
# ==============================================
# UI
# ==============================================
with gr.Blocks(css=custom_css) as demo:
gr.Markdown("# πŸ€– Advanced Multimodal AI System")
gr.Markdown("Analyze text, image and audio with AI")
with gr.Row():
# LEFT SIDE
with gr.Column():
text_input = gr.Textbox(label="πŸ“ Enter Text")
gr.Markdown("## πŸ–ΌοΈ Upload Image")
image_input = gr.Image(type="pil", show_label=False)
gr.Markdown("## πŸŽΆπŸŽ™οΈ Upload Audio")
audio_input = gr.Audio(type="filepath", show_label=False)
analyze_btn = gr.Button("πŸš€ Run Analysis")
loader = gr.Markdown("", visible=False)
# RIGHT SIDE
with gr.Column():
with gr.Tabs():
with gr.Tab("Results"):
fusion_output = gr.Markdown(elem_id="fusion_box")
text_output = gr.Markdown(elem_id="text_box")
image_output = gr.Markdown(elem_id="image_box")
audio_output = gr.Markdown(elem_id="audio_box")
with gr.Tab("History"):
history_output = gr.Markdown(elem_id="history_box")
clear_btn = gr.Button("πŸ—‘ Clear History")
# ANALYZE
analyze_btn.click(
show_loader,
outputs=loader
).then(
multimodal_analyze,
inputs=[text_input, image_input, audio_input],
outputs=[fusion_output, text_output, image_output, audio_output]
).then(
hide_loader,
outputs=loader
).then(
fetch_history,
outputs=history_output
)
# CLEAR HISTORY
clear_btn.click(
clear_history_db
).then(
fetch_history,
outputs=history_output
)
# LOAD HISTORY WHEN APP STARTS
demo.load(
fetch_history,
outputs=history_output
)
if __name__ == "__main__":
demo.launch(allowed_paths=["saved_images"])