ankban commited on
Commit
b13d2bd
Β·
verified Β·
1 Parent(s): 32606b2

Update file_viewer_panel.py

Browse files
Files changed (1) hide show
  1. file_viewer_panel.py +58 -116
file_viewer_panel.py CHANGED
@@ -1,136 +1,78 @@
1
  import gradio as gr
2
  import os
3
- import shutil
4
  import json
5
- import tempfile
6
- import uuid
7
- from pdf2image import convert_from_path
8
- from file_utils import extract_text_from_file, call_llm, save_user_file, fetch_user_files
9
-
10
- def make_public_file(img_path):
11
- public_dir = "/tmp/gradio-public"
12
- os.makedirs(public_dir, exist_ok=True)
13
- filename = f"{uuid.uuid4()}.png"
14
- public_path = os.path.join(public_dir, filename)
15
- shutil.copy(img_path, public_path)
16
- return public_path
17
-
18
- def file_viewer_dashboard(nickname):
19
  with gr.Column(scale=4, elem_id="main-column") as file_panel:
20
- with gr.Row():
21
- with gr.Column(scale=3):
22
- file_upload = gr.File(label="πŸ“‚ Upload a File", file_types=[".pdf", ".txt", ".md", ".pptx"])
23
- image_viewer = gr.HTML(label="πŸ“„ PDF Viewer")
24
- load_more_btn = gr.Button("βž• Load More Pages", visible=False)
25
-
26
- with gr.Column(scale=2):
27
- generate_quiz_btn = gr.Button("🧠 Practice Questions")
28
- quiz_container = gr.Column(visible=False)
29
- chat_output = gr.Chatbot(label="Ask a question about the file")
30
- chat_input = gr.Textbox(label="", placeholder="Ask ChatEDU a question...")
31
 
32
  file_text_state = gr.State("")
33
- chat_state = gr.State([])
34
- all_image_paths = gr.State([])
35
- loaded_page_count = gr.State(0)
36
 
37
- def prepare_pdf_images(file):
38
- if not file or not nickname:
39
- return "", [], 0, gr.update(visible=False)
 
 
40
 
41
- filename = os.path.basename(file.name)
42
- saved_path = f"/tmp/{filename}"
43
- shutil.copy(file.name, saved_path)
44
- save_user_file(nickname.value, filename, saved_path)
45
 
 
 
 
46
  text = extract_text_from_file(file)
 
 
 
 
 
 
 
 
 
47
 
48
- ext = os.path.splitext(filename)[1].lower()
49
- if ext != ".pdf":
50
- html = f"<pre style='padding:12px; background:#f9f9f9; white-space:pre-wrap;'>{text}</pre>"
51
- return html, [], 0, gr.update(visible=False)
52
-
53
- temp_dir = tempfile.mkdtemp()
54
- images = convert_from_path(saved_path, dpi=150, fmt="png", output_folder=temp_dir)
55
-
56
- paths = []
57
- for i, img in enumerate(images):
58
- img_path = os.path.join(temp_dir, f"page_{i}.png")
59
- img.save(img_path, "PNG")
60
- public_path = make_public_file(img_path)
61
- paths.append(public_path)
62
-
63
- initial_html = "".join([
64
- f"<img src='file={paths[i]}' style='width:100%; margin-bottom:12px; border-radius:8px;'/>"
65
- for i in range(min(3, len(paths)))
66
- ])
67
- return initial_html, paths, min(3, len(paths)), gr.update(visible=(len(paths) > 3))
68
-
69
- def load_more_pages(paths, current_count):
70
- next_count = current_count + 3
71
- total = len(paths)
72
-
73
- new_html = "".join([
74
- f"<img src='file={paths[i]}' style='width:100%; margin-bottom:12px; border-radius:8px;'/>"
75
- for i in range(current_count, min(next_count, total))
76
- ])
77
-
78
- show_more = next_count < total
79
- return gr.update(value=new_html, append=True), next_count, gr.update(visible=show_more)
80
-
81
- def ask_question(user_input, text, history):
82
- if not user_input.strip():
83
- return history, history
84
- messages = [
85
- {"role": "system", "content": "You are a tutor. Only use the document below."},
86
- {"role": "user", "content": f"Document:\n{text}"}
87
- ]
88
- for user_msg, bot_reply in history:
89
- messages.append({"role": "user", "content": user_msg})
90
- messages.append({"role": "assistant", "content": bot_reply})
91
- messages.append({"role": "user", "content": user_input})
92
- response = call_llm(messages=messages)
93
- history.append((user_input, response))
94
- return history, history
95
 
96
  def generate_quiz(text):
97
- prompt = (
98
- "Generate 5 multiple choice questions from the document. "
99
- "Each question should have:\n- question\n- options (list)\n- answer (string). Return JSON."
100
- )
101
  try:
102
- result = call_llm(prompt=prompt)
103
- questions = json.loads(result)
104
- components = []
105
- for idx, q in enumerate(questions):
106
- q_md = gr.Markdown(f"**Q{idx+1}. {q['question']}**")
107
- radio = gr.Radio(choices=q["options"], label="Choose an answer")
108
- feedback = gr.Textbox(interactive=False)
109
-
110
- def check(ans, correct=q["answer"]):
111
- return "βœ… Correct!" if ans == correct else f"❌ Correct answer: {correct}"
112
-
113
- radio.change(fn=check, inputs=[radio], outputs=[feedback])
114
- components.extend([q_md, radio, feedback])
115
- return gr.update(visible=True), components
116
- except:
117
- return gr.update(visible=False), []
118
 
119
- file_upload.change(
120
- fn=prepare_pdf_images,
121
- inputs=[file_upload],
122
- outputs=[image_viewer, all_image_paths, loaded_page_count, load_more_btn]
123
- )
124
 
125
- load_more_btn.click(
126
- fn=load_more_pages,
127
- inputs=[all_image_paths, loaded_page_count],
128
- outputs=[image_viewer, loaded_page_count, load_more_btn]
129
- )
130
 
131
- chat_input.submit(fn=ask_question, inputs=[chat_input, file_text_state, chat_state],
132
- outputs=[chat_output, chat_state])
 
 
 
 
133
 
134
- generate_quiz_btn.click(fn=generate_quiz, inputs=[file_text_state], outputs=[quiz_container])
 
 
 
135
 
136
  return file_panel
 
1
  import gradio as gr
2
  import os
 
3
  import json
4
+ from file_utils import extract_text_from_file, call_llm
5
+
6
+ def file_viewer_dashboard(nickname_input):
 
 
 
 
 
 
 
 
 
 
 
7
  with gr.Column(scale=4, elem_id="main-column") as file_panel:
8
+ file_upload = gr.File(label="πŸ“‚ Upload a File", file_types=[".pdf", ".txt", ".md", ".pptx"])
9
+ preview = gr.Textbox(label="πŸ“„ File Content Preview", lines=10, interactive=False)
 
 
 
 
 
 
 
 
 
10
 
11
  file_text_state = gr.State("")
 
 
 
12
 
13
+ chat_input = gr.Textbox(label="πŸ” Ask about the file")
14
+ chat_output = gr.Chatbot()
15
+
16
+ btn_accessible = gr.Button("♿️ Improve Accessibility")
17
+ accessible_box = gr.Textbox(label="🌍 Easier-to-Read Version", lines=15, interactive=False)
18
 
19
+ quiz_box = gr.Column(visible=False)
20
+ quiz_score = gr.Textbox(label="Your Score", interactive=False, visible=False)
 
 
21
 
22
+ def load_and_preview(file):
23
+ if not file:
24
+ return "", ""
25
  text = extract_text_from_file(file)
26
+ return text, text
27
+
28
+ def handle_chat(query, text):
29
+ prompt = f"Use this document to answer:
30
+
31
+ {text}
32
+
33
+ Question: {query}"
34
+ return [(query, call_llm(prompt))]
35
 
36
+ def make_accessible_version(text):
37
+ prompt = f"""
38
+ You are an expert in reading accessibility.
39
+
40
+ Reformat the following content to improve readability and make it easier to follow:
41
+ - Use simple language
42
+ - Break long paragraphs
43
+ - Use bullet points or headings when appropriate
44
+ - Preserve the meaning clearly
45
+
46
+ Text:
47
+ {text}
48
+ """
49
+ return call_llm(prompt)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  def generate_quiz(text):
52
+ prompt = "Create 5 multiple-choice questions from this text. Return JSON list."
53
+ response = call_llm(prompt)
 
 
54
  try:
55
+ questions = json.loads(response)
56
+ elements = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
+ for i, q in enumerate(questions):
59
+ q_md = gr.Markdown(f"**Q{i+1}. {q['question']}**")
60
+ q_radio = gr.Radio(q["options"], label="Select an answer")
61
+ q_feedback = gr.Textbox(label="Result", interactive=False)
 
62
 
63
+ def grade(choice, correct=q["answer"]):
64
+ return "βœ… Correct!" if choice == correct else f"❌ Correct: {correct}"
 
 
 
65
 
66
+ q_radio.change(fn=grade, inputs=[q_radio], outputs=[q_feedback])
67
+ elements.extend([q_md, q_radio, q_feedback])
68
+
69
+ return gr.update(visible=True), elements, gr.update(visible=True, value="Score: 0/5")
70
+ except:
71
+ return gr.update(visible=False), [], gr.update(visible=True, value="Error generating quiz.")
72
 
73
+ file_upload.change(fn=load_and_preview, inputs=[file_upload], outputs=[preview, file_text_state])
74
+ chat_input.submit(fn=handle_chat, inputs=[chat_input, file_text_state], outputs=[chat_output])
75
+ btn_accessible.click(fn=make_accessible_version, inputs=[file_text_state], outputs=[accessible_box])
76
+ gr.Button("🧠 Generate Quiz").click(fn=generate_quiz, inputs=[file_text_state], outputs=[quiz_box, quiz_box, quiz_score])
77
 
78
  return file_panel