Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from .service import StudyService | |
| def _sources_md(result) -> str: | |
| return ("**Sources** (open the files below to verify at the exact slide/page)\n\n" + result.sources_md) \ | |
| if result.sources_md else "" | |
| def build_app(service: StudyService, title: str = "StudyHub"): | |
| import gradio as gr | |
| with gr.Blocks(title=title) as demo: | |
| gr.Markdown( | |
| f"# {title}\nBrowse by topic or ask freely. Answers are grounded in the course materials, " | |
| "cite the exact file + slide/page, and reply in your language β even when the source is in " | |
| "Italian. Short snippets go to a no-training model provider to generate answers." | |
| ) | |
| with gr.Tab("Topics"): | |
| gr.Markdown("Pick a module β a topic. Answers draw on **all** of that topic's sources " | |
| "(slides, notes, transcripts), each cited.") | |
| module_dd = gr.Dropdown( | |
| choices=[(f"{m['title']} Β· {m['lecturer']}".strip(" Β·"), m["id"]) for m in service.modules()], | |
| label="Module", | |
| ) | |
| topic_dd = gr.Dropdown(choices=[], label="Topic") | |
| t_sources = gr.Markdown() | |
| sum_btn = gr.Button("Generate summary") | |
| t_summary = gr.Markdown() | |
| t_sum_files = gr.File(label="Summary sources β download the cited files", file_count="multiple") | |
| gr.Markdown("β") | |
| with gr.Row(): | |
| t_q = gr.Textbox(label="Ask about this topic (any language)", lines=1, scale=4) | |
| t_ask = gr.Button("Ask", variant="primary", scale=1) | |
| t_ans = gr.Markdown() | |
| t_ans_src = gr.Markdown() | |
| t_files = gr.File(label="Cited sources", file_count="multiple") | |
| def _topic_src_md(tid): | |
| srcs = service.topic_sources(tid) if tid else [] | |
| if not srcs: | |
| return "_No sources linked to this topic yet._" | |
| return "**Sources:** " + " Β· ".join(f"`{s['type']}` {s['file'].split('/')[-1]}" for s in srcs) | |
| def _on_module(mid): | |
| choices = [(t["title"], t["id"]) for t in service.topics(mid)] if mid else [] | |
| return gr.update(choices=choices, value=None), "" | |
| def _summarize(tid): | |
| if not tid: | |
| return "Pick a topic first.", [] | |
| r = service.topic_summary(tid) | |
| return (r.answer + (("\n\n" + _sources_md(r)) if r.sources_md else "")), service.cited_files(r) | |
| def _topic_ask(tid, q): | |
| if not tid: | |
| return "Pick a topic first.", "", [] | |
| r = service.topic_ask(tid, q or "") | |
| return r.answer, _sources_md(r), service.cited_files(r) | |
| module_dd.change(_on_module, inputs=module_dd, outputs=[topic_dd, t_sources]) | |
| topic_dd.change(_topic_src_md, inputs=topic_dd, outputs=t_sources) | |
| sum_btn.click(_summarize, inputs=topic_dd, outputs=[t_summary, t_sum_files]) | |
| t_ask.click(_topic_ask, inputs=[topic_dd, t_q], outputs=[t_ans, t_ans_src, t_files]) | |
| with gr.Tab("Ask"): | |
| q = gr.Textbox(label="Your question (Italian or English)", lines=2) | |
| ask = gr.Button("Ask", variant="primary") | |
| a_ans = gr.Markdown() | |
| a_src = gr.Markdown() | |
| a_files = gr.File(label="Cited sources β click to open/download", file_count="multiple") | |
| def _ask(query): | |
| r = service.ask(query or "") | |
| return r.answer, _sources_md(r), service.cited_files(r) | |
| ask.click(_ask, inputs=q, outputs=[a_ans, a_src, a_files]) | |
| with gr.Tab("Summaries"): | |
| doc = gr.Dropdown(choices=service.list_files(), label="Document") | |
| sbtn = gr.Button("Summarize", variant="primary") | |
| s_out = gr.Markdown() | |
| s_src = gr.Markdown() | |
| s_files = gr.File(label="Cited sources β click to open/download", file_count="multiple") | |
| def _sum(file): | |
| if not file: | |
| return "Pick a document first.", "", [] | |
| r = service.summarize(file) | |
| return r.answer, _sources_md(r), service.cited_files(r) | |
| sbtn.click(_sum, inputs=doc, outputs=[s_out, s_src, s_files]) | |
| with gr.Tab("Quiz"): | |
| topic = gr.Textbox(label="Topic") | |
| n = gr.Slider(1, 10, value=5, step=1, label="Number of questions") | |
| qbtn = gr.Button("Generate quiz", variant="primary") | |
| q_out = gr.Markdown() | |
| q_src = gr.Markdown() | |
| q_files = gr.File(label="Cited sources β click to open/download", file_count="multiple") | |
| def _quiz(t, num): | |
| r = service.quiz(t or "", int(num)) | |
| return r.answer, _sources_md(r), service.cited_files(r) | |
| qbtn.click(_quiz, inputs=[topic, n], outputs=[q_out, q_src, q_files]) | |
| with gr.Tab("Browse & Download"): | |
| mat = gr.Dropdown(choices=service.list_files(), label="Material") | |
| dbtn = gr.Button("Get file") | |
| dfile = gr.File(label="Download") | |
| def _dl(file): | |
| return service.download_path(file) if file else None | |
| dbtn.click(_dl, inputs=mat, outputs=dfile) | |
| return demo | |