mikaelJ46 commited on
Commit
98bb58d
·
verified ·
1 Parent(s): ecc1b2c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -18
app.py CHANGED
@@ -424,9 +424,16 @@ def download_questions_file(questions_list, topic, grade_level, subject=None):
424
  if not questions_list:
425
  return None
426
 
 
 
 
 
427
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
428
- subject_tag = f"_{subject}" if subject else ""
429
- filename = f"questions_{grade_level}{subject_tag}_{topic}_{timestamp}.txt"
 
 
 
430
 
431
  content = f"""UNEB EXAM PRACTICE QUESTIONS
432
  {'='*50}
@@ -453,7 +460,7 @@ INSTRUCTIONS:
453
  Good luck!
454
  """
455
 
456
- filepath = f"downloads/{filename}"
457
  os.makedirs("downloads", exist_ok=True)
458
  with open(filepath, "w", encoding="utf-8") as f:
459
  f.write(content)
@@ -471,10 +478,16 @@ def download_questions_pdf(questions_list, topic, grade_level, subject=None):
471
  except Exception:
472
  return None
473
 
 
 
 
474
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
475
- subject_tag = f"_{subject}" if subject else ""
476
- filename = f"questions_{grade_level}{subject_tag}_{topic}_{timestamp}.pdf"
477
- filepath = f"downloads/{filename}"
 
 
 
478
  os.makedirs("downloads", exist_ok=True)
479
 
480
  doc = SimpleDocTemplate(filepath, pagesize=A4, rightMargin=20*mm, leftMargin=20*mm, topMargin=20*mm, bottomMargin=20*mm)
@@ -506,9 +519,15 @@ def download_feedback_file(feedback_text, topic, grade_level, subject=None):
506
  if not feedback_text:
507
  return None
508
 
 
 
 
509
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
510
- subject_tag = f"_{subject}" if subject else ""
511
- filename = f"feedback_{grade_level}{subject_tag}_{topic}_{timestamp}.txt"
 
 
 
512
 
513
  content = f"""AI CORRECTION & FEEDBACK
514
  {'='*50}
@@ -526,7 +545,7 @@ Review this feedback carefully to understand where you went wrong.
526
  Practice similar questions to strengthen this topic.
527
  """
528
 
529
- filepath = f"downloads/{filename}"
530
  os.makedirs("downloads", exist_ok=True)
531
  with open(filepath, "w", encoding="utf-8") as f:
532
  f.write(content)
@@ -642,7 +661,7 @@ with gr.Blocks(title="UNEB Exam Prep - Primary 6 & 7", theme=gr.themes.Soft(), c
642
  num_questions_input = gr.Slider(minimum=1, maximum=100, step=1, value=20, label="Number of Questions")
643
  generate_btn = gr.Button(" Generate Questions", variant="primary", size="lg")
644
 
645
- questions_output = gr.Markdown(
646
  value="",
647
  elem_classes="question-display"
648
  )
@@ -660,24 +679,25 @@ with gr.Blocks(title="UNEB Exam Prep - Primary 6 & 7", theme=gr.themes.Soft(), c
660
  # Generate questions handler
661
  def generate_and_display(grade, subject, topic, num_questions):
662
  questions_list, formatted_text = generate_practice_questions(grade, subject, topic, num_questions=num_questions)
663
-
664
  if questions_list is None:
665
- return "", formatted_text, questions_state.value, " Generation failed"
666
-
667
  session.current_questions = questions_list
668
  session.current_grade = grade
669
  session.current_topic = topic
670
  # Also store subject
671
  session.current_subject = subject
672
-
673
- # For Markdown display, keep spacing and simple formatting
674
- md_text = "\n\n".join([f"**{i+1}.** {q.split('.',1)[1].strip() if '.' in q else q}" for i, q in enumerate(questions_list)])
675
- return md_text, md_text, questions_list, f" Generated {len(questions_list)} {subject} questions on {topic}"
 
676
 
677
  generate_btn.click(
678
  fn=generate_and_display,
679
  inputs=[grade_input, subject_input, topic_input, num_questions_input],
680
- outputs=[questions_output, questions_output, questions_state, status_output]
681
  )
682
  # Download handler - returns file path for gr.DownloadButton
683
  def download_qns():
 
424
  if not questions_list:
425
  return None
426
 
427
+ def sanitize_filename(name: str) -> str:
428
+ # Replace unsafe characters with underscore
429
+ return re.sub(r"[^A-Za-z0-9_.()-]", "_", str(name))
430
+
431
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
432
+ safe_grade = sanitize_filename(grade_level)
433
+ safe_topic = sanitize_filename(topic)
434
+ safe_subject = sanitize_filename(subject) if subject else ""
435
+ subject_tag = f"_{safe_subject}" if safe_subject else ""
436
+ filename = f"questions_{safe_grade}{subject_tag}_{safe_topic}_{timestamp}.txt"
437
 
438
  content = f"""UNEB EXAM PRACTICE QUESTIONS
439
  {'='*50}
 
460
  Good luck!
461
  """
462
 
463
+ filepath = os.path.join("downloads", filename)
464
  os.makedirs("downloads", exist_ok=True)
465
  with open(filepath, "w", encoding="utf-8") as f:
466
  f.write(content)
 
478
  except Exception:
479
  return None
480
 
481
+ def sanitize_filename(name: str) -> str:
482
+ return re.sub(r"[^A-Za-z0-9_.()-]", "_", str(name))
483
+
484
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
485
+ safe_grade = sanitize_filename(grade_level)
486
+ safe_topic = sanitize_filename(topic)
487
+ safe_subject = sanitize_filename(subject) if subject else ""
488
+ subject_tag = f"_{safe_subject}" if safe_subject else ""
489
+ filename = f"questions_{safe_grade}{subject_tag}_{safe_topic}_{timestamp}.pdf"
490
+ filepath = os.path.join("downloads", filename)
491
  os.makedirs("downloads", exist_ok=True)
492
 
493
  doc = SimpleDocTemplate(filepath, pagesize=A4, rightMargin=20*mm, leftMargin=20*mm, topMargin=20*mm, bottomMargin=20*mm)
 
519
  if not feedback_text:
520
  return None
521
 
522
+ def sanitize_filename(name: str) -> str:
523
+ return re.sub(r"[^A-Za-z0-9_.()-]", "_", str(name))
524
+
525
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
526
+ safe_grade = sanitize_filename(grade_level)
527
+ safe_topic = sanitize_filename(topic)
528
+ safe_subject = sanitize_filename(subject) if subject else ""
529
+ subject_tag = f"_{safe_subject}" if safe_subject else ""
530
+ filename = f"feedback_{safe_grade}{subject_tag}_{safe_topic}_{timestamp}.txt"
531
 
532
  content = f"""AI CORRECTION & FEEDBACK
533
  {'='*50}
 
545
  Practice similar questions to strengthen this topic.
546
  """
547
 
548
+ filepath = os.path.join("downloads", filename)
549
  os.makedirs("downloads", exist_ok=True)
550
  with open(filepath, "w", encoding="utf-8") as f:
551
  f.write(content)
 
661
  num_questions_input = gr.Slider(minimum=1, maximum=100, step=1, value=20, label="Number of Questions")
662
  generate_btn = gr.Button(" Generate Questions", variant="primary", size="lg")
663
 
664
+ questions_output = gr.HTML(
665
  value="",
666
  elem_classes="question-display"
667
  )
 
679
  # Generate questions handler
680
  def generate_and_display(grade, subject, topic, num_questions):
681
  questions_list, formatted_text = generate_practice_questions(grade, subject, topic, num_questions=num_questions)
682
+
683
  if questions_list is None:
684
+ return "", questions_state.value, " Generation failed"
685
+
686
  session.current_questions = questions_list
687
  session.current_grade = grade
688
  session.current_topic = topic
689
  # Also store subject
690
  session.current_subject = subject
691
+
692
+ # Build accessible HTML list for better rendering on iPad/Safari
693
+ items_html = "".join([f"<li>{q.split('.',1)[1].strip() if '.' in q else q}</li>" for q in questions_list])
694
+ html = f"<div><ol style='margin:0 0 0 1.2rem;padding:0'>{items_html}</ol></div>"
695
+ return html, questions_list, f" Generated {len(questions_list)} {subject} questions on {topic}"
696
 
697
  generate_btn.click(
698
  fn=generate_and_display,
699
  inputs=[grade_input, subject_input, topic_input, num_questions_input],
700
+ outputs=[questions_output, questions_state, status_output]
701
  )
702
  # Download handler - returns file path for gr.DownloadButton
703
  def download_qns():