OPEN SOURCE
software/src/tui/data_provider.py
Read on this site and download the files you need.
Nichijoyaku was created using AI. A complete review by human biblical-language and biblical-studies specialists has not been established. Read alongside established translations and original-language resources.
← Back to the open-source guide
1"""Data provider for the TUI."""23from __future__ import annotations45import json6from dataclasses import dataclass7from pathlib import Path89from src.data.loader import DataLoader10from src.evaluation.storage import EvaluationStorage11from src.models.evaluation import VerseEvaluation12from src.models.verse import Verse, VerseReference131415@dataclass16class VerseData:17"""Complete data for a verse including sources, translation, and evaluation."""1819book: str20chapter: int21verse: int22# Source texts23greek_text: str | None24kjv_text: str | None25japanese_reference: str | None26glossary_terms: list[str]27# Translation28translation_text: str | None29translation_model: str | None30translation_timestamp: str | None31# Evaluation32evaluation: VerseEvaluation | None333435class TUIDataProvider:36"""Provides data for the TUI from existing storage."""3738def __init__(self, data_dir: Path | str) -> None:39"""Initialize the data provider.4041Args:42data_dir: Path to the data directory.43"""44self.data_dir = Path(data_dir)45self.loader = DataLoader(data_dir)46self.eval_storage = EvaluationStorage(data_dir)47self.output_dir = self.data_dir / "output"4849def get_available_books(self) -> list[str]:50"""Get list of books that have translations.5152Returns:53List of book names.54"""55if not self.output_dir.exists():56return []5758books = []59for book_dir in sorted(self.output_dir.iterdir()):60if book_dir.is_dir():61# Check if there are any chapter files62chapter_files = list(book_dir.glob("chapter_*.json"))63# Filter out evaluation files64chapter_files = [65f for f in chapter_files if not f.stem.endswith("_eval")66]67if chapter_files:68books.append(book_dir.name)69return books7071def get_book_chapters(self, book: str) -> list[int]:72"""Get chapters that have translations for a book.7374Args:75book: Book name.7677Returns:78List of chapter numbers.79"""80book_dir = self.output_dir / book81if not book_dir.exists():82return []8384chapters = []85for chapter_file in sorted(book_dir.glob("chapter_*.json")):86# Skip evaluation files87if chapter_file.stem.endswith("_eval"):88continue89# Extract chapter number from filename (chapter_01.json -> 1)90try:91chapter_num = int(chapter_file.stem.split("_")[1])92chapters.append(chapter_num)93except (IndexError, ValueError):94continue95return sorted(chapters)9697def get_chapter_verses(self, book: str, chapter: int) -> list[int]:98"""Get verse numbers in a translated chapter.99100Args:101book: Book name.102chapter: Chapter number.103104Returns:105List of verse numbers.106"""107chapter_file = self.output_dir / book / f"chapter_{chapter:02d}.json"108if not chapter_file.exists():109return []110111with chapter_file.open("r", encoding="utf-8") as f:112data = json.load(f)113114verses = data.get("verses", {})115return sorted(int(v) for v in verses.keys())116117def get_flagged_verses(self, book: str, chapter: int) -> set[int]:118"""Get set of flagged verse numbers in a chapter.119120Args:121book: Book name.122chapter: Chapter number.123124Returns:125Set of flagged verse numbers.126"""127chapter_eval = self.eval_storage.load_chapter_evaluation(book, chapter)128if not chapter_eval:129return set()130return set(chapter_eval.flagged_verses)131132def is_chapter_evaluated(self, book: str, chapter: int) -> bool:133"""Check if a chapter has been evaluated.134135Args:136book: Book name.137chapter: Chapter number.138139Returns:140True if evaluation exists.141"""142return self.eval_storage.is_chapter_evaluated(book, chapter)143144def get_verse_data(self, book: str, chapter: int, verse: int) -> VerseData:145"""Get complete verse data including sources, translation, and evaluation.146147Args:148book: Book name.149chapter: Chapter number.150verse: Verse number.151152Returns:153VerseData object with all available data.154"""155# Load source texts156ref = VerseReference(book=book, chapter=chapter, verse=verse)157source_verse: Verse = self.loader.load_verse(ref)158159# Load translation160translation_text = None161translation_model = None162translation_timestamp = None163glossary_terms: list[str] = []164165chapter_file = self.output_dir / book / f"chapter_{chapter:02d}.json"166if chapter_file.exists():167with chapter_file.open("r", encoding="utf-8") as f:168data = json.load(f)169verse_data = data.get("verses", {}).get(str(verse), {})170translation_text = verse_data.get("text")171translation_model = verse_data.get("model")172translation_timestamp = verse_data.get("timestamp")173glossary_terms = verse_data.get("glossary_terms_applied", [])174175# Load evaluation176evaluation = None177chapter_eval = self.eval_storage.load_chapter_evaluation(book, chapter)178if chapter_eval and verse in chapter_eval.verses:179evaluation = chapter_eval.verses[verse]180181# Get Japanese reference (prefer Kougo, fallback to Taisho)182japanese_ref = source_verse.japanese_kougo or source_verse.japanese_taisho183184return VerseData(185book=book,186chapter=chapter,187verse=verse,188greek_text=source_verse.greek_text,189kjv_text=source_verse.english_kjv,190japanese_reference=japanese_ref,191glossary_terms=glossary_terms,192translation_text=translation_text,193translation_model=translation_model,194translation_timestamp=translation_timestamp,195evaluation=evaluation,196)197