"""Parse uploaded course material into plain text. Supports PDF, PPTX, DOCX, and plain text files. """ import io def parse_pdf(data): """Extract text from PDF bytes using PyMuPDF.""" import fitz # PyMuPDF text_parts = [] with fitz.open(stream=data, filetype="pdf") as document: for page in document: text_parts.append(page.get_text()) return "\n".join(text_parts) def parse_pptx(data): """Extract text from PPTX bytes, slide by slide.""" from pptx import Presentation presentation = Presentation(io.BytesIO(data)) text_parts = [] for index, slide in enumerate(presentation.slides, start=1): text_parts.append(f"[Slide {index}]") for shape in slide.shapes: if shape.has_text_frame: for paragraph in shape.text_frame.paragraphs: line = "".join(run.text for run in paragraph.runs) if line.strip(): text_parts.append(line) return "\n".join(text_parts) def parse_docx(data): """Extract text from DOCX bytes.""" from docx import Document document = Document(io.BytesIO(data)) return "\n".join(p.text for p in document.paragraphs if p.text.strip()) def parse_material(filename, data): """Pick the right parser based on file extension and return plain text.""" lower = filename.lower() if lower.endswith(".pdf"): return parse_pdf(data) if lower.endswith(".pptx"): return parse_pptx(data) if lower.endswith(".docx"): return parse_docx(data) if lower.endswith(".txt") or lower.endswith(".md"): return data.decode("utf-8", errors="ignore") raise ValueError(f"Unsupported file type: {filename}") def clean_text(text): """Strip extra whitespace and blank lines.""" lines = [line.strip() for line in text.splitlines()] non_empty = [line for line in lines if line] return "\n".join(non_empty)