Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ results/

# OS
.DS_Store
Thumbs.db
Thumbs.db
22 changes: 12 additions & 10 deletions src/pageindex/pdf/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,18 @@ def get_page_tokens(
else:
raise ValueError(f"Invalid PDF path: {pdf_path}")

page_list = []
for page in doc:
page_text = page.get_text() or ""
if config:
token_length = count_tokens(config, page_text)
else:
token_length = len(page_text) // 4
page_list.append((page_text, token_length))
doc.close()
return page_list
try:
page_list = []
for page in doc:
page_text = page.get_text() or ""
if config:
token_length = count_tokens(config, page_text)
else:
token_length = len(page_text) // 4
page_list.append((page_text, token_length))
return page_list
finally:
doc.close()

else:
raise ValueError(f"Unsupported PDF parser: {pdf_parser}")
Expand Down
26 changes: 20 additions & 6 deletions src/pageindex/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,31 @@ def get_pdf_name(pdf_path: str | Path | BytesIO) -> str:
return Path(pdf_path).name
elif isinstance(pdf_path, BytesIO):
pdf_reader = PyPDF2.PdfReader(pdf_path)
meta = pdf_reader.metadata
pdf_name = meta.title if meta and meta.title else "Untitled"
return sanitize_filename(pdf_name)
try:
meta = pdf_reader.metadata
pdf_name = meta.title if meta and meta.title else "Untitled"
return sanitize_filename(pdf_name)
finally:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hasattr(pdf_reader, "stream") pattern relies on PyPDF2 internals. The with open() approach you used on lines 86-89 is cleaner. Consider using that consistently.

if hasattr(pdf_reader, "stream") and hasattr(pdf_reader.stream, "close"):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closing pdf_reader.stream here will close the caller's BytesIO. They won't be able to reuse it after calling this function. Better to let the caller own the lifecycle.

pdf_reader.stream.close()
return "Unknown"


def get_pdf_title(pdf_path: str | Path) -> str:
"""Extract PDF title from metadata."""
pdf_reader = PyPDF2.PdfReader(str(pdf_path))
meta = pdf_reader.metadata
return meta.title if meta and meta.title else "Untitled"
if isinstance(pdf_path, (str, Path)):
with open(pdf_path, "rb") as f:
pdf_reader = PyPDF2.PdfReader(f)
meta = pdf_reader.metadata
return meta.title if meta and meta.title else "Untitled"
else:
pdf_reader = PyPDF2.PdfReader(str(pdf_path))
try:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This else branch is unreachable. The type hint is str | Path, so the isinstance check above always passes. Safe to remove.

meta = pdf_reader.metadata
return meta.title if meta and meta.title else "Untitled"
finally:
if hasattr(pdf_reader, "stream") and hasattr(pdf_reader.stream, "close"):
pdf_reader.stream.close()


def convert_physical_index_to_int(data: Any) -> Any:
Expand Down
Loading