Spaces:
Sleeping
Sleeping
| 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"]) |