Update app.py
Browse files
app.py
CHANGED
@@ -440,381 +440,69 @@ def process_text_with_members(text, selected_members):
|
|
440 |
return f"Error processing text with members: {str(e)}"
|
441 |
|
442 |
# Create Gradio interface
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
margin-bottom: 0.5rem;
|
507 |
-
font-weight: 600;
|
508 |
-
}
|
509 |
-
|
510 |
-
.header p {
|
511 |
-
color: #000000;
|
512 |
-
font-size: 1.1rem;
|
513 |
-
}
|
514 |
-
|
515 |
-
/* Tab styling */
|
516 |
-
.tabs {
|
517 |
-
background: none !important;
|
518 |
-
border: none !important;
|
519 |
-
}
|
520 |
-
|
521 |
-
.tab-nav {
|
522 |
-
background: none !important;
|
523 |
-
border-bottom: 1px solid #eee !important;
|
524 |
-
padding: 0 !important;
|
525 |
-
margin-bottom: 2rem !important;
|
526 |
-
}
|
527 |
-
|
528 |
-
.tab-nav button {
|
529 |
-
padding: 1rem 2rem !important;
|
530 |
-
margin-right: 1rem !important;
|
531 |
-
border-radius: 8px 8px 0 0 !important;
|
532 |
-
border: none !important;
|
533 |
-
background: #f8f8f8 !important;
|
534 |
-
color: #000000 !important;
|
535 |
-
font-weight: 500 !important;
|
536 |
-
}
|
537 |
-
|
538 |
-
.tab-nav button.selected {
|
539 |
-
background: #e8e8e8 !important;
|
540 |
-
color: #000000 !important;
|
541 |
-
font-weight: 600 !important;
|
542 |
-
}
|
543 |
-
|
544 |
-
/* Input container styling */
|
545 |
-
.input-container {
|
546 |
-
background: #fafafa;
|
547 |
-
border-radius: 12px;
|
548 |
-
padding: 2rem;
|
549 |
-
margin-bottom: 2rem;
|
550 |
-
border: 1px solid #eee;
|
551 |
-
}
|
552 |
-
|
553 |
-
/* Form elements */
|
554 |
-
.input-container label {
|
555 |
-
color: #000000;
|
556 |
-
font-weight: 500;
|
557 |
-
margin-bottom: 0.5rem;
|
558 |
-
}
|
559 |
-
|
560 |
-
.textbox textarea {
|
561 |
-
border: 1px solid #eee !important;
|
562 |
-
border-radius: 8px !important;
|
563 |
-
padding: 1rem !important;
|
564 |
-
font-size: 1rem !important;
|
565 |
-
color: #000000 !important;
|
566 |
-
background: #ffffff !important;
|
567 |
-
}
|
568 |
-
|
569 |
-
.textbox textarea:focus {
|
570 |
-
border-color: #000000 !important;
|
571 |
-
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1) !important;
|
572 |
-
}
|
573 |
-
|
574 |
-
/* Dropdown styling */
|
575 |
-
.dropdown select {
|
576 |
-
background-color: white !important;
|
577 |
-
border: 1px solid #eee !important;
|
578 |
-
border-radius: 8px !important;
|
579 |
-
padding: 0.8rem !important;
|
580 |
-
color: #000000 !important;
|
581 |
-
}
|
582 |
-
|
583 |
-
/* Style the selected options in dropdown */
|
584 |
-
.selected-options {
|
585 |
-
color: #000000 !important;
|
586 |
-
background: white !important;
|
587 |
-
padding: 4px 8px !important;
|
588 |
-
border-radius: 4px !important;
|
589 |
-
margin: 2px !important;
|
590 |
-
}
|
591 |
-
|
592 |
-
/* Style the dropdown options */
|
593 |
-
.dropdown-option {
|
594 |
-
color: #ffffff !important;
|
595 |
-
background: white !important;
|
596 |
-
padding: 8px !important;
|
597 |
-
}
|
598 |
-
|
599 |
-
/* Style the dropdown container */
|
600 |
-
.dropdown-container {
|
601 |
-
background: white !important;
|
602 |
-
border: 1px solid #eee !important;
|
603 |
-
border-radius: 8px !important;
|
604 |
-
}
|
605 |
-
|
606 |
-
/* Style the dropdown arrow */
|
607 |
-
.dropdown-arrow {
|
608 |
-
color: #000000 !important;
|
609 |
-
}
|
610 |
-
|
611 |
-
/* Button styling */
|
612 |
-
.primary {
|
613 |
-
background: #000000 !important;
|
614 |
-
color: white !important;
|
615 |
-
padding: 0.8rem 1.5rem !important;
|
616 |
-
border-radius: 8px !important;
|
617 |
-
font-weight: 500 !important;
|
618 |
-
font-size: 1rem !important;
|
619 |
-
border: none !important;
|
620 |
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
|
621 |
-
transition: all 0.2s ease !important;
|
622 |
-
}
|
623 |
-
|
624 |
-
.primary:hover {
|
625 |
-
background: #333333 !important;
|
626 |
-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1) !important;
|
627 |
-
}
|
628 |
-
|
629 |
-
/* Audio component */
|
630 |
-
.audio-component {
|
631 |
-
background: #ffffff;
|
632 |
-
border: 1px solid #eee;
|
633 |
-
border-radius: 12px;
|
634 |
-
padding: 1.5rem;
|
635 |
-
margin-bottom: 1.5rem;
|
636 |
-
}
|
637 |
-
|
638 |
-
/* Output styling */
|
639 |
-
.output-markdown {
|
640 |
-
background: #ffffff;
|
641 |
-
border-radius: 12px;
|
642 |
-
padding: 2rem;
|
643 |
-
margin-top: 2rem;
|
644 |
-
border: 1px solid #eee;
|
645 |
-
color: #000000;
|
646 |
-
max-height: 400px !important; /* Fixed height */
|
647 |
-
overflow-y: auto !important; /* Enable vertical scrolling */
|
648 |
-
}
|
649 |
-
|
650 |
-
/* Style the output content */
|
651 |
-
.output-markdown p {
|
652 |
-
margin: 0.5rem 0;
|
653 |
-
line-height: 1.5;
|
654 |
-
}
|
655 |
-
|
656 |
-
.output-markdown pre {
|
657 |
-
white-space: pre-wrap;
|
658 |
-
word-wrap: break-word;
|
659 |
-
padding: 1rem;
|
660 |
-
background: #f8f8f8;
|
661 |
-
border-radius: 8px;
|
662 |
-
margin: 0.5rem 0;
|
663 |
-
}
|
664 |
-
|
665 |
-
/* Add custom scrollbar for output */
|
666 |
-
.output-markdown::-webkit-scrollbar {
|
667 |
-
width: 6px;
|
668 |
-
}
|
669 |
-
|
670 |
-
.output-markdown::-webkit-scrollbar-track {
|
671 |
-
background: #f8f8f8;
|
672 |
-
border-radius: 3px;
|
673 |
-
}
|
674 |
-
|
675 |
-
.output-markdown::-webkit-scrollbar-thumb {
|
676 |
-
background: #000000;
|
677 |
-
border-radius: 3px;
|
678 |
-
}
|
679 |
-
|
680 |
-
/* Custom scrollbar */
|
681 |
-
::-webkit-scrollbar {
|
682 |
-
width: 6px;
|
683 |
-
}
|
684 |
-
|
685 |
-
::-webkit-scrollbar-track {
|
686 |
-
background: #f8f8f8;
|
687 |
-
}
|
688 |
-
|
689 |
-
::-webkit-scrollbar-thumb {
|
690 |
-
background: #000000;
|
691 |
-
border-radius: 3px;
|
692 |
-
}
|
693 |
-
|
694 |
-
/* Remove Gradio branding */
|
695 |
-
.gr-interface {
|
696 |
-
background: none !important;
|
697 |
-
border: none !important;
|
698 |
-
box-shadow: none !important;
|
699 |
-
}
|
700 |
-
|
701 |
-
.footer {
|
702 |
-
border-top: 1px solid #eee;
|
703 |
-
margin-top: 3rem;
|
704 |
-
padding-top: 1.5rem;
|
705 |
-
text-align: center;
|
706 |
-
color: #000000;
|
707 |
-
}
|
708 |
-
|
709 |
-
/* Tips section */
|
710 |
-
.tips-section {
|
711 |
-
color: #000000 !important;
|
712 |
-
font-size: 0.9rem !important;
|
713 |
-
}
|
714 |
-
|
715 |
-
.tips-section ul {
|
716 |
-
margin-left: 1.2rem;
|
717 |
-
}
|
718 |
-
|
719 |
-
/* Make all text black */
|
720 |
-
* {
|
721 |
-
color: #000000;
|
722 |
-
}
|
723 |
-
"""
|
724 |
-
) as interface:
|
725 |
-
with gr.Column(elem_id="custom-container"):
|
726 |
-
with gr.Column(elem_classes="main-content"):
|
727 |
-
gr.Markdown(
|
728 |
-
"""
|
729 |
-
<div class='header'>
|
730 |
-
<h1>🎙️ TaskWhisper</h1>
|
731 |
-
<p>Transform your voice or text into structured tasks</p>
|
732 |
-
</div>
|
733 |
-
"""
|
734 |
-
)
|
735 |
-
|
736 |
-
# Get Trello members for the dropdown
|
737 |
-
members = get_trello_members()
|
738 |
-
|
739 |
-
with gr.Tab("Voice Input"):
|
740 |
-
with gr.Column(elem_classes="input-container"):
|
741 |
-
audio_input = gr.Audio(
|
742 |
-
label="Record or Upload Audio",
|
743 |
-
sources=["microphone", "upload"],
|
744 |
-
type="filepath",
|
745 |
-
format="wav",
|
746 |
-
interactive=True
|
747 |
-
)
|
748 |
-
gr.Markdown(
|
749 |
-
"""
|
750 |
-
<div class='tips-section'>
|
751 |
-
<p><strong>Tips for best results:</strong></p>
|
752 |
-
<ul>
|
753 |
-
<li>Speak clearly and at a normal pace</li>
|
754 |
-
<li>Use a quiet environment</li>
|
755 |
-
<li>Include key details like deadlines or priority</li>
|
756 |
-
</ul>
|
757 |
-
</div>
|
758 |
-
"""
|
759 |
-
)
|
760 |
-
member_dropdown_audio = gr.Dropdown(
|
761 |
-
choices=list(members.keys()),
|
762 |
-
multiselect=True,
|
763 |
-
label="Assign Task To",
|
764 |
-
info="Select team members",
|
765 |
-
value=[],
|
766 |
-
elem_classes="dropdown"
|
767 |
-
)
|
768 |
-
audio_button = gr.Button("Create Task", elem_classes="primary")
|
769 |
-
|
770 |
-
with gr.Tab("Text Input"):
|
771 |
-
with gr.Column(elem_classes="input-container"):
|
772 |
-
text_input = gr.Textbox(
|
773 |
-
lines=3,
|
774 |
-
placeholder="Describe your task here (e.g., 'Need to prepare quarterly report with sales data by next Friday')",
|
775 |
-
label="Task Description",
|
776 |
-
elem_classes="textbox"
|
777 |
-
)
|
778 |
-
member_dropdown_text = gr.Dropdown(
|
779 |
-
choices=list(members.keys()),
|
780 |
-
multiselect=True,
|
781 |
-
label="Assign Task To",
|
782 |
-
info="Select team members",
|
783 |
-
value=[],
|
784 |
-
elem_classes="dropdown"
|
785 |
-
)
|
786 |
-
text_button = gr.Button("Create Task", elem_classes="primary")
|
787 |
-
|
788 |
-
with gr.Column(elem_classes="output-markdown"):
|
789 |
-
output = gr.Markdown(
|
790 |
-
label="Task Details",
|
791 |
-
value="Task details will appear here..."
|
792 |
-
)
|
793 |
-
|
794 |
-
# Set up event handlers
|
795 |
-
audio_button.click(
|
796 |
-
fn=process_audio_with_members,
|
797 |
-
inputs=[audio_input, member_dropdown_audio],
|
798 |
-
outputs=output
|
799 |
-
)
|
800 |
-
|
801 |
-
text_button.click(
|
802 |
-
fn=process_text_with_members,
|
803 |
-
inputs=[text_input, member_dropdown_text],
|
804 |
-
outputs=output
|
805 |
-
)
|
806 |
-
|
807 |
-
gr.Markdown(
|
808 |
-
"""
|
809 |
-
<div class='footer'>
|
810 |
-
<p>TaskWhisper © 2024 | Powered by AI</p>
|
811 |
-
</div>
|
812 |
-
"""
|
813 |
-
)
|
814 |
|
815 |
if __name__ == "__main__":
|
816 |
-
interface.launch(
|
817 |
-
show_api=False, # Hide API docs
|
818 |
-
share=True,
|
819 |
-
favicon_path="🎙️" # Custom favicon
|
820 |
-
)
|
|
|
440 |
return f"Error processing text with members: {str(e)}"
|
441 |
|
442 |
# Create Gradio interface
|
443 |
+
with gr.Blocks(title="TaskWhisper - Smart Task Manager") as interface:
|
444 |
+
gr.Markdown("# 🎙️ TaskWhisper - Smart Task Manager")
|
445 |
+
gr.Markdown("Record audio or type your task. The AI will help improve and structure your task description.")
|
446 |
+
|
447 |
+
# Get Trello members for the dropdown
|
448 |
+
members = get_trello_members()
|
449 |
+
|
450 |
+
with gr.Tab("Audio Input"):
|
451 |
+
audio_input = gr.Audio(
|
452 |
+
label="Record or Upload Audio",
|
453 |
+
sources=["microphone", "upload"],
|
454 |
+
type="filepath",
|
455 |
+
format="wav",
|
456 |
+
interactive=True
|
457 |
+
)
|
458 |
+
gr.Markdown("""
|
459 |
+
*Instructions:*
|
460 |
+
- Use microphone to record directly
|
461 |
+
- Or upload an audio file (WAV format)
|
462 |
+
- Speak clearly for better results
|
463 |
+
- Keep background noise minimal
|
464 |
+
""")
|
465 |
+
member_dropdown_audio = gr.Dropdown(
|
466 |
+
choices=list(members.keys()),
|
467 |
+
multiselect=True,
|
468 |
+
label="Assign to Members",
|
469 |
+
info="Select one or more members to assign the task",
|
470 |
+
value=[]
|
471 |
+
)
|
472 |
+
audio_button = gr.Button("Process Audio")
|
473 |
+
|
474 |
+
with gr.Tab("Text Input"):
|
475 |
+
text_input = gr.Textbox(
|
476 |
+
lines=3,
|
477 |
+
placeholder="Type your task here (e.g., 'Need to prepare quarterly report with sales data by next Friday')",
|
478 |
+
label="Text Input"
|
479 |
+
)
|
480 |
+
member_dropdown_text = gr.Dropdown(
|
481 |
+
choices=list(members.keys()),
|
482 |
+
multiselect=True,
|
483 |
+
label="Assign to Members",
|
484 |
+
info="Select one or more members to assign the task",
|
485 |
+
value=[] # Initialize with empty selection
|
486 |
+
)
|
487 |
+
text_button = gr.Button("Process Text")
|
488 |
+
|
489 |
+
output = gr.Textbox(
|
490 |
+
label="Task Details",
|
491 |
+
lines=15
|
492 |
+
)
|
493 |
+
|
494 |
+
# Set up event handlers
|
495 |
+
audio_button.click(
|
496 |
+
fn=process_audio_with_members,
|
497 |
+
inputs=[audio_input, member_dropdown_audio],
|
498 |
+
outputs=output
|
499 |
+
)
|
500 |
+
|
501 |
+
text_button.click(
|
502 |
+
fn=process_text_with_members,
|
503 |
+
inputs=[text_input, member_dropdown_text],
|
504 |
+
outputs=output
|
505 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
506 |
|
507 |
if __name__ == "__main__":
|
508 |
+
interface.launch(share=True)
|
|
|
|
|
|
|
|