capradeepgujaran commited on
Commit
7101a01
·
verified ·
1 Parent(s): 9fe7ced

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +169 -2
app.py CHANGED
@@ -8,6 +8,13 @@ import tempfile
8
  from typing import List, Dict, Tuple, Optional
9
  from dataclasses import dataclass
10
  import subprocess
 
 
 
 
 
 
 
11
 
12
  @dataclass
13
  class Question:
@@ -21,6 +28,98 @@ class QuizFeedback:
21
  selected: Optional[str]
22
  correct_answer: str
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  class QuizGenerator:
25
  def __init__(self, api_key: str):
26
  self.client = Groq(api_key=api_key)
@@ -421,6 +520,33 @@ class QuizApp:
421
  self.quiz_generator = QuizGenerator(api_key)
422
  self.certificate_generator = CertificateGenerator()
423
  self.current_questions: List[Question] = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
 
425
  def generate_questions(self, text: str, num_questions: int) -> Tuple[bool, List[Question]]:
426
  """
@@ -611,12 +737,27 @@ def create_quiz_interface():
611
  name = gr.Textbox(label="Full Name", placeholder="Enter your full name")
612
  email = gr.Textbox(label="Email", placeholder="Enter your email")
613
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
614
  text_input = gr.Textbox(
615
- label="Learning Content",
616
  placeholder="Enter the text content you want to be assessed on",
617
  lines=10
618
  )
619
-
620
  num_questions = gr.Slider(
621
  minimum=1,
622
  maximum=20,
@@ -700,6 +841,18 @@ def create_quiz_interface():
700
 
701
 
702
  # Helper Functions
 
 
 
 
 
 
 
 
 
 
 
 
703
  def on_generate_questions(text, num_questions):
704
  if not text.strip():
705
  return [
@@ -944,7 +1097,21 @@ def create_quiz_interface():
944
  inputs=[score_display, name, course_name, company_logo, participant_photo],
945
  outputs=certificate_display
946
  )
 
 
 
 
 
 
 
 
 
 
947
 
 
 
 
 
948
  return demo
949
 
950
  if __name__ == "__main__":
 
8
  from typing import List, Dict, Tuple, Optional
9
  from dataclasses import dataclass
10
  import subprocess
11
+ from llama_index import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage
12
+ from llama_index.vector_stores import SimpleVectorStore
13
+ from docx import Document
14
+ import fitz # PyMuPDF
15
+ import shutil
16
+ import tempfile
17
+
18
 
19
  @dataclass
20
  class Question:
 
28
  selected: Optional[str]
29
  correct_answer: str
30
 
31
+ class DocumentProcessor:
32
+ def __init__(self, storage_dir="./storage"):
33
+ self.storage_dir = storage_dir
34
+ self.temp_dir = tempfile.mkdtemp()
35
+ self.index = None
36
+ os.makedirs(storage_dir, exist_ok=True)
37
+
38
+ def process_file(self, file_path: str) -> str:
39
+ """Process uploaded file and save to temp directory"""
40
+ file_ext = os.path.splitext(file_path)[1].lower()
41
+
42
+ if file_ext == '.pdf':
43
+ return self._process_pdf(file_path)
44
+ elif file_ext in ['.doc', '.docx']:
45
+ return self._process_word(file_path)
46
+ else:
47
+ raise ValueError(f"Unsupported file type: {file_ext}")
48
+
49
+ def _process_pdf(self, file_path: str) -> str:
50
+ """Extract text from PDF file"""
51
+ text = ""
52
+ try:
53
+ doc = fitz.open(file_path)
54
+ for page in doc:
55
+ text += page.get_text()
56
+ doc.close()
57
+
58
+ # Save processed text
59
+ output_path = os.path.join(self.temp_dir, "processed.txt")
60
+ with open(output_path, "w", encoding="utf-8") as f:
61
+ f.write(text)
62
+ return output_path
63
+ except Exception as e:
64
+ raise Exception(f"Error processing PDF: {str(e)}")
65
+
66
+ def _process_word(self, file_path: str) -> str:
67
+ """Extract text from Word file"""
68
+ try:
69
+ doc = Document(file_path)
70
+ text = "\n".join([paragraph.text for paragraph in doc.paragraphs])
71
+
72
+ # Save processed text
73
+ output_path = os.path.join(self.temp_dir, "processed.txt")
74
+ with open(output_path, "w", encoding="utf-8") as f:
75
+ f.write(text)
76
+ return output_path
77
+ except Exception as e:
78
+ raise Exception(f"Error processing Word file: {str(e)}")
79
+
80
+ def create_index(self) -> bool:
81
+ """Create vector store index from processed documents"""
82
+ try:
83
+ # Load documents from temp directory
84
+ documents = SimpleDirectoryReader(self.temp_dir).load_data()
85
+
86
+ # Create and save index
87
+ self.index = VectorStoreIndex.from_documents(
88
+ documents,
89
+ storage_context=StorageContext.from_defaults(
90
+ vector_store=SimpleVectorStore(),
91
+ persist_dir=self.storage_dir
92
+ )
93
+ )
94
+ return True
95
+ except Exception as e:
96
+ print(f"Error creating index: {str(e)}")
97
+ return False
98
+
99
+ def clear_index(self):
100
+ """Clear the vector store index and temporary files"""
101
+ try:
102
+ # Clear storage directory
103
+ if os.path.exists(self.storage_dir):
104
+ shutil.rmtree(self.storage_dir)
105
+ os.makedirs(self.storage_dir)
106
+
107
+ # Clear temp directory
108
+ if os.path.exists(self.temp_dir):
109
+ shutil.rmtree(self.temp_dir)
110
+ self.temp_dir = tempfile.mkdtemp()
111
+
112
+ self.index = None
113
+ return "Index cleared successfully"
114
+ except Exception as e:
115
+ return f"Error clearing index: {str(e)}"
116
+
117
+ def cleanup(self):
118
+ """Clean up temporary directory"""
119
+ if os.path.exists(self.temp_dir):
120
+ shutil.rmtree(self.temp_dir)
121
+
122
+
123
  class QuizGenerator:
124
  def __init__(self, api_key: str):
125
  self.client = Groq(api_key=api_key)
 
520
  self.quiz_generator = QuizGenerator(api_key)
521
  self.certificate_generator = CertificateGenerator()
522
  self.current_questions: List[Question] = []
523
+ self.document_processor = DocumentProcessor()
524
+
525
+ # Add this new method
526
+ def process_uploaded_file(self, file_path: str) -> str:
527
+ """Process uploaded file and return status message"""
528
+ try:
529
+ if not file_path:
530
+ return "⚠️ Please upload a file first."
531
+
532
+ self.document_processor.process_file(file_path)
533
+ return "✅ File processed successfully! Click 'Create Index' to continue."
534
+ except Exception as e:
535
+ return f"❌ Error processing file: {str(e)}"
536
+
537
+ # Add this new method
538
+ def create_index(self) -> str:
539
+ """Create vector store index and return status message"""
540
+ success = self.document_processor.create_index()
541
+ if success:
542
+ return "✅ Index created successfully!"
543
+ return "❌ Failed to create index. Please try again."
544
+
545
+ # Add this new method
546
+ def clear_index(self) -> str:
547
+ """Clear vector store index and return status message"""
548
+ return self.document_processor.clear_index()
549
+
550
 
551
  def generate_questions(self, text: str, num_questions: int) -> Tuple[bool, List[Question]]:
552
  """
 
737
  name = gr.Textbox(label="Full Name", placeholder="Enter your full name")
738
  email = gr.Textbox(label="Email", placeholder="Enter your email")
739
 
740
+ # Add file upload section
741
+ with gr.Row():
742
+ file_upload = gr.File(
743
+ label="Upload PDF or Word Document",
744
+ file_types=[".pdf", ".doc", ".docx"],
745
+ type="filepath"
746
+ )
747
+ file_status = gr.Markdown("")
748
+
749
+ with gr.Row():
750
+ process_btn = gr.Button("Process File", variant="secondary", size="sm")
751
+ index_btn = gr.Button("Create Index", variant="secondary", size="sm")
752
+ clear_index_btn = gr.Button("Clear Index", variant="secondary", size="sm")
753
+
754
+ # Or use text input
755
  text_input = gr.Textbox(
756
+ label="Or Enter Learning Content Directly",
757
  placeholder="Enter the text content you want to be assessed on",
758
  lines=10
759
  )
760
+
761
  num_questions = gr.Slider(
762
  minimum=1,
763
  maximum=20,
 
841
 
842
 
843
  # Helper Functions
844
+
845
+ def process_file(file_path):
846
+ if not file_path:
847
+ return "⚠️ Please upload a file first."
848
+ return quiz_app.process_uploaded_file(file_path)
849
+
850
+ def create_index():
851
+ return quiz_app.create_index()
852
+
853
+ def clear_index():
854
+ return quiz_app.clear_index()
855
+
856
  def on_generate_questions(text, num_questions):
857
  if not text.strip():
858
  return [
 
1097
  inputs=[score_display, name, course_name, company_logo, participant_photo],
1098
  outputs=certificate_display
1099
  )
1100
+ process_btn.click(
1101
+ fn=process_file,
1102
+ inputs=[file_upload],
1103
+ outputs=[file_status]
1104
+ )
1105
+
1106
+ index_btn.click(
1107
+ fn=create_index,
1108
+ outputs=[file_status]
1109
+ )
1110
 
1111
+ clear_index_btn.click(
1112
+ fn=clear_index,
1113
+ outputs=[file_status]
1114
+ )
1115
  return demo
1116
 
1117
  if __name__ == "__main__":