diff --git a/python/ebook_search/ingest.py b/python/ebook_search/ingest.py index eec235f..516735d 100644 --- a/python/ebook_search/ingest.py +++ b/python/ebook_search/ingest.py @@ -91,60 +91,65 @@ def ingest_configured_paths(session: Session, config: EbookSearchConfig) -> int: def ingest_file(session: Session, path: Path, config: EbookSearchConfig) -> bool: """Ingest one EPUB file. Return True when the database changed.""" - resolved_path = path.expanduser().resolve() - logger.info("ebook_ingest_file_start path=%s", resolved_path) - file_hash = sha256_file(resolved_path) - existing = find_existing_source(session, resolved_path, file_hash) - if existing is not None and existing.file_sha256 == file_hash: + try: + resolved_path = path.expanduser().resolve() + logger.info("ebook_ingest_file_start path=%s", resolved_path) + file_hash = sha256_file(resolved_path) + existing = find_existing_source(session, resolved_path, file_hash) + if existing is not None and existing.file_sha256 == file_hash: + stat = resolved_path.stat() + existing.file_path = str(resolved_path) + existing.file_mtime = datetime.fromtimestamp(stat.st_mtime, tz=UTC) + existing.file_size = stat.st_size + session.flush() + logger.info("ebook_ingest_file_unchanged source_id=%s path=%s", existing.id, resolved_path) + return False + if existing is not None: + logger.info("ebook_ingest_file_replacing source_id=%s path=%s", existing.id, resolved_path) + session.delete(existing) + session.flush() + stat = resolved_path.stat() - existing.file_path = str(resolved_path) - existing.file_mtime = datetime.fromtimestamp(stat.st_mtime, tz=UTC) - existing.file_size = stat.st_size - session.flush() - logger.info("ebook_ingest_file_unchanged source_id=%s path=%s", existing.id, resolved_path) - return False - if existing is not None: - logger.info("ebook_ingest_file_replacing source_id=%s path=%s", existing.id, resolved_path) - session.delete(existing) - session.flush() - - stat = resolved_path.stat() - parsed = parse_epub(resolved_path) - source = EbookSource( - title=parsed.title, - author=parsed.author, - language=parsed.language, - publisher=parsed.publisher, - identifier=parsed.identifier, - file_path=str(resolved_path), - file_sha256=file_hash, - file_mtime=datetime.fromtimestamp(stat.st_mtime, tz=UTC), - file_size=stat.st_size, - ) - session.add(source) - session.flush() - - chunk_index = 0 - for spine_index, parsed_chapter in enumerate(parsed.chapters): - chapter = EbookChapter( - source_id=source.id, - spine_index=spine_index, - title=parsed_chapter.title, - href=parsed_chapter.href, + parsed = parse_epub(resolved_path) + source = EbookSource( + title=parsed.title, + author=parsed.author, + language=parsed.language, + publisher=parsed.publisher, + identifier=parsed.identifier, + file_path=str(resolved_path), + file_sha256=file_hash, + file_mtime=datetime.fromtimestamp(stat.st_mtime, tz=UTC), + file_size=stat.st_size, ) - session.add(chapter) + session.add(source) session.flush() - chunk_index = add_chapter_chunks(session, source, chapter, parsed_chapter, chunk_index, config) - session.flush() - logger.info( - "ebook_ingest_file_complete source_id=%s path=%s chapters=%s chunks=%s", - source.id, - resolved_path, - len(parsed.chapters), - chunk_index, - ) - return True + chunk_index = 0 + for spine_index, parsed_chapter in enumerate(parsed.chapters): + chapter = EbookChapter( + source_id=source.id, + spine_index=spine_index, + title=parsed_chapter.title, + href=parsed_chapter.href, + ) + session.add(chapter) + session.flush() + chunk_index = add_chapter_chunks(session, source, chapter, parsed_chapter, chunk_index, config) + + session.commit() + logger.info( + "ebook_ingest_file_complete source_id=%s path=%s chapters=%s chunks=%s", + source.id, + resolved_path, + len(parsed.chapters), + chunk_index, + ) + except Exception: + logger.exception(f"ebook_ingest_file_error path={path}") + return False + else: + return True def find_existing_source(session: Session, path: Path, file_hash: str) -> EbookSource | None: