EchoReader / file_handler.py
Kostya-Lolinger's picture
Rename filehandler.py to file_handler.py
936a73f verified
Raw History Blame Contribute Delete
2.94 kB
import os
import chardet
def extract_text(file_path: str) -> str:
ext = os.path.splitext(file_path)[1].lower()
try:
if ext == ".txt":
return _read_txt(file_path)
elif ext == ".pdf":
return _read_pdf(file_path)
elif ext == ".docx":
return _read_docx(file_path)
elif ext == ".epub":
return _read_epub(file_path)
elif ext == ".odt":
return _read_odt(file_path)
elif ext == ".rtf":
return _read_rtf(file_path)
elif ext in (".html", ".htm"):
return _read_html(file_path)
else:
return f"Unsupported format: {ext}"
except Exception as e:
return f"Error reading file: {str(e)}"
def _read_txt(path: str) -> str:
with open(path, "rb") as f:
raw = f.read()
detected = chardet.detect(raw)
encoding = detected.get("encoding", "utf-8") or "utf-8"
return raw.decode(encoding, errors="replace")
def _read_pdf(path: str) -> str:
from PyPDF2 import PdfReader
reader = PdfReader(path)
text = []
for page in reader.pages:
page_text = page.extract_text()
if page_text:
text.append(page_text)
return "\n\n".join(text)
def _read_docx(path: str) -> str:
from docx import Document
doc = Document(path)
return "\n\n".join(p.text for p in doc.paragraphs if p.text.strip())
def _read_epub(path: str) -> str:
import ebooklib
from ebooklib import epub
from bs4 import BeautifulSoup
book = epub.read_epub(path, options={"ignore_ncx": True})
text = []
for item in book.get_items():
if item.get_type() == ebooklib.ITEM_DOCUMENT:
soup = BeautifulSoup(item.get_content(), "html.parser")
item_text = soup.get_text(separator="\n")
if item_text.strip():
text.append(item_text.strip())
return "\n\n".join(text)
def _read_odt(path: str) -> str:
from odf.opendocument import load
from odf.text import P
doc = load(path)
paragraphs = doc.getElementsByType(P)
text = []
for p in paragraphs:
t = ""
for node in p.childNodes:
if hasattr(node, "data"):
t += node.data
elif hasattr(node, "__str__"):
t += str(node)
if t.strip():
text.append(t.strip())
return "\n\n".join(text)
def _read_rtf(path: str) -> str:
from striprtf.striprtf import rtf_to_text
with open(path, "r", errors="replace") as f:
rtf_content = f.read()
return rtf_to_text(rtf_content)
def _read_html(path: str) -> str:
from bs4 import BeautifulSoup
with open(path, "r", encoding="utf-8", errors="replace") as f:
soup = BeautifulSoup(f.read(), "html.parser")
for tag in soup(["script", "style", "nav", "header", "footer"]):
tag.decompose()
return soup.get_text(separator="\n")