| import gradio as gr |
| import json |
| from file_utils import extract_text_from_file, call_llm, save_study_guide, fetch_study_guides |
|
|
| def file_study_guide_dashboard(nickname_input): |
| with gr.Column() as panel: |
| file_input = gr.File(label="π€ Upload a File", file_types=[".pdf", ".txt", ".md", ".pptx"]) |
| save_btn = gr.Button("πΎ Save Guide") |
| guide_dropdown = gr.Dropdown(label="π Your Saved Guides", choices=[]) |
| section_output = gr.Column() |
| file_text_state = gr.State("") |
| guide_state = gr.State([]) |
|
|
| def sample_section(): |
| return render_sections([{ |
| "section_title": "Sample Section", |
| "overview": "This is a short summary of the topic.", |
| "explanation": "This is a detailed explanation to show how learning content will look.", |
| "quiz": [ |
| {"question": "What is 2+2?", "options": ["1", "2", "3", "4"], "answer": "4"}, |
| {"question": "Sample Q2?", "options": ["A", "B", "C", "D"], "answer": "B"}, |
| {"question": "Sample Q3?", "options": ["A", "B", "C", "D"], "answer": "C"}, |
| {"question": "Sample Q4?", "options": ["A", "B", "C", "D"], "answer": "D"}, |
| {"question": "Sample Q5?", "options": ["A", "B", "C", "D"], "answer": "A"} |
| ] |
| }]) |
|
|
| |
| pass |
|
|
| def generate_study_guide(file): |
| if file is None: |
| return [gr.Markdown("β No file uploaded.")], "", [] |
|
|
| text = extract_text_from_file(file) |
|
|
| prompt = f""" |
| You are an AI tutor. Divide the following content into 5β6 logical sections. |
| For each section: |
| - Provide a 2β3 line summary (overview) |
| - Write a detailed explanation of the topic |
| - Create 5 multiple choice questions (MCQs), each with: |
| - A question |
| - 4 options |
| - 1 correct answer |
| Return as JSON in this format: |
| [ |
| {{ |
| "section_title": "...", |
| "overview": "...", |
| "explanation": "...", |
| "quiz": [ |
| {{"question": "...", "options": ["A", "B", "C", "D"], "answer": "B"}}, |
| ... |
| ] |
| }}, |
| ... |
| ] |
| |
| Text: |
| {text} |
| """ |
| response = call_llm(prompt) |
| try: |
| guide = json.loads(response) |
| section_output.children = render_sections(guide) |
| return text, guide |
| except: |
| section_output.children = [gr.Markdown("β Failed to parse structured study guide.")] |
| return text, [] |
|
|
| def render_sections(guide_data): |
| blocks = [] |
| for i, sec in enumerate(guide_data): |
| blocks.append(render_section(i + 1, sec)) |
| return blocks |
|
|
| def render_section(index, sec): |
| block = gr.Column() |
| with block: |
| gr.Markdown(f"## π Section {index}: {sec['section_title']}") |
| gr.Markdown(f"**Overview:** {sec['overview']}") |
| gr.Markdown(f"**Explanation:**\n\n{sec['explanation']}") |
|
|
| gr.Markdown("### π§ Quiz") |
| question_area = gr.Column() |
|
|
| def make_question_ui(q_idx): |
| q = sec['quiz'][q_idx] |
| q_box = gr.Markdown(f"**Q{q_idx+1}.** {q['question']}") |
| q_radio = gr.Radio(q['options'], label="Choose an answer") |
|
|
| def grade(choice): |
| correct = q['answer'] |
| return "β
Correct!" if choice == correct else f"β Correct: {correct}" |
|
|
| q_radio.change(fn=grade, inputs=[q_radio], outputs=[feedback_box]) |
| return [q_box, q_radio] |
|
|
| feedback_box = gr.Textbox(label="Answer Feedback", interactive=False) |
| question_area.children = make_question_ui(0) |
|
|
| with gr.Row(): |
| for i in range(5): |
| gr.Button(str(i + 1), size="sm").click(fn=lambda idx=i: make_question_ui(idx), inputs=[], outputs=question_area) |
|
|
| return block |
|
|
| def save_to_user(nickname, filename, guide): |
| if not guide or not filename: |
| return |
| save_study_guide(nickname, filename.name, json.dumps(guide)) |
|
|
| def load_user_guides(user): |
| guides = fetch_study_guides(user) |
| return [f"{g.filename} ({g.timestamp})" for g in guides] |
|
|
| |
| section_output.children = render_sections([{ |
| "section_title": "Sample Section", |
| "overview": "This is a short summary of the topic.", |
| "explanation": "This is a detailed explanation to show how learning content will look.", |
| "quiz": [ |
| {"question": "What is 2+2?", "options": ["1", "2", "3", "4"], "answer": "4"}, |
| {"question": "Sample Q2?", "options": ["A", "B", "C", "D"], "answer": "B"}, |
| {"question": "Sample Q3?", "options": ["A", "B", "C", "D"], "answer": "C"}, |
| {"question": "Sample Q4?", "options": ["A", "B", "C", "D"], "answer": "D"}, |
| {"question": "Sample Q5?", "options": ["A", "B", "C", "D"], "answer": "A"} |
| ] |
| }]) |
|
|
| def show_saved_guide(user, label): |
| guides = fetch_study_guides(user) |
| for g in guides: |
| if label.startswith(g.filename): |
| section_output.children = render_sections(json.loads(g.guide)) |
| return |
| section_output.children = [gr.Markdown("β Guide not found.")] |
|
|
| file_input.change(fn=generate_study_guide, inputs=[file_input], outputs=[file_text_state, guide_state]) |
| save_btn.click(fn=save_to_user, inputs=[nickname_input, file_input, guide_state], outputs=[]) |
| nickname_input.change(fn=load_user_guides, inputs=[nickname_input], outputs=[guide_dropdown]) |
| guide_dropdown.change(fn=show_saved_guide, inputs=[nickname_input, guide_dropdown], outputs=[]) |
|
|
| return panel |