CommTutor / file_module.py
ankban's picture
Update file_module.py
fb9d374 verified
Raw
History Blame
6.95 kB
import gradio as gr
import os
import json
from file_utils import (
extract_text_from_file,
call_llm
)
def file_dashboard():
with gr.Blocks(elem_id="file-learning-layout") as file_panel:
uploaded_files = gr.State([])
file_sections = gr.State({})
file_texts = gr.State({})
chat_history = gr.State({})
quiz_data = gr.State({})
total_score = gr.State({})
with gr.Row():
with gr.Column(scale=1, min_width=220):
gr.Markdown("### πŸŽ“ Educare", elem_id="sidebar-title")
gr.Markdown("---")
with gr.Accordion("🧭 Learning Modes", open=True):
btn_spoken = gr.Button("πŸ—£ Spoken Communication")
btn_written = gr.Button("✍️ Written Communication")
with gr.Accordion("πŸ“„ File-Based Learning", open=True):
btn_study_guides = gr.Button("πŸ“˜ Study Guides")
file_guide_list = gr.Radio(label="Your Study Guides", choices=[], interactive=True)
btn_file_view = gr.Button("πŸ“ Files")
gr.Markdown("---")
gr.Markdown("""Ankush Bansal""", elem_id="sidebar-user")
with gr.Column(scale=4, elem_id="main-column") as main_content:
mode_view = gr.State("upload")
file_upload = gr.File(label="πŸ“€ Upload File", file_types=[".pdf", ".txt", ".md", ".pptx"])
study_guide_output = gr.Markdown("Upload a file to generate a study guide.")
file_chat_output = gr.Row(visible=False)
with file_chat_output:
file_preview = gr.Textbox(label="πŸ“„ File Content Preview", lines=15, interactive=False)
chat_output = gr.Chatbot(label="πŸ’¬ Chat with Document")
chat_input = gr.Textbox(label="Ask something about this file")
generate_quiz_btn = gr.Button("🧠 Generate Quiz from File")
quiz_display = gr.Column(visible=False)
quiz_score = gr.Textbox(label="Your Score", interactive=False, visible=False)
def store_file_and_generate_guide(file, current_files, section_map, text_map):
if file is None:
return current_files, section_map, text_map, "No file uploaded.", gr.update(choices=[])
text = extract_text_from_file(file)
filename = os.path.basename(file.name)
prompt = f"Break the content into 4–6 logical learning sections. Format: 'Section Title: Short summary'\n\n{text}"
response = call_llm(prompt, system_message="You are a helpful assistant for students studying documents.")
updated_files = current_files + [filename] if filename not in current_files else current_files
section_map[filename] = response
text_map[filename] = text
return updated_files, section_map, text_map, f"### {filename} Study Guide\n\n{response}", gr.update(choices=updated_files)
def load_study_guide(selected_filename, section_map):
if not selected_filename or selected_filename not in section_map:
return "No study guide available."
return f"### {selected_filename} Study Guide\n\n{section_map[selected_filename]}"
def open_file_viewer(selected_file, text_map):
content = text_map.get(selected_file, "No file content available.")
return gr.update(visible=True), content, []
def chat_with_file(question, selected_file, text_map, history_map):
if not selected_file or selected_file not in text_map:
return [], history_map
text = text_map[selected_file]
history = history_map.get(selected_file, [])
prompt = f"You are a helpful tutor. Answer this question using the document content below.\n\n{text}\n\nQuestion: {question}"
answer = call_llm(prompt)
new_history = history + [(question, answer)]
history_map[selected_file] = new_history
return new_history, history_map
def generate_quiz(selected_file, text_map):
if not selected_file or selected_file not in text_map:
return gr.update(visible=True), [], {}, gr.update(visible=True, value="")
text = text_map[selected_file]
prompt = f"Create 5 multiple-choice questions based on the content below.\nReturn as JSON list with 'question', 'options' (list), and 'answer'.\n\n{text}"
response = call_llm(prompt)
try:
questions = json.loads(response)
score_state = {"score": 0, "total": len(questions)}
with quiz_display:
for i, q in enumerate(questions):
q_text = gr.Markdown(f"**Q{i+1}. {q['question']}**")
q_radio = gr.Radio(choices=q['options'], label="Select an answer")
q_feedback = gr.Textbox(label="Result", interactive=False)
def handle_answer(choice, ans=q['answer'], score_state=score_state):
if choice == ans:
score_state["score"] += 1
return "βœ… Correct!"
return f"❌ Incorrect. Correct answer: {ans}"
q_radio.change(handle_answer, inputs=[q_radio], outputs=[q_feedback])
return gr.update(visible=True), questions, {selected_file: questions}, gr.update(visible=True, value="Score: 0/5")
except:
return gr.update(visible=True), [], {}, gr.update(visible=True, value="Error generating quiz.")
file_upload.change(
fn=store_file_and_generate_guide,
inputs=[file_upload, uploaded_files, file_sections, file_texts],
outputs=[uploaded_files, file_sections, file_texts, study_guide_output, file_guide_list],
show_progress="minimal"
)
file_guide_list.change(
fn=load_study_guide,
inputs=[file_guide_list, file_sections],
outputs=[study_guide_output],
show_progress="minimal"
)
btn_file_view.click(
fn=open_file_viewer,
inputs=[file_guide_list, file_texts],
outputs=[file_chat_output, file_preview, chat_output]
)
chat_input.submit(
fn=chat_with_file,
inputs=[chat_input, file_guide_list, file_texts, chat_history],
outputs=[chat_output, chat_history],
show_progress="minimal"
)
generate_quiz_btn.click(
fn=generate_quiz,
inputs=[file_guide_list, file_texts],
outputs=[quiz_display, quiz_display, quiz_data, quiz_score],
show_progress="minimal"
)
return file_panel