From 141c30d2a2b5c48211dfdd4a0959985e8195f1fc Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Mon, 26 May 2025 15:23:04 -0400 Subject: [PATCH] ratio. --- kjvstudy_org/kjv.py | 76 ++++++++++++++++++++++++++++++++++++++---- kjvstudy_org/server.py | 6 ++-- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/kjvstudy_org/kjv.py b/kjvstudy_org/kjv.py index f774b59..221bb88 100644 --- a/kjvstudy_org/kjv.py +++ b/kjvstudy_org/kjv.py @@ -1,5 +1,6 @@ from pydantic import BaseModel from pathlib import Path +from functools import lru_cache import json @@ -20,6 +21,7 @@ class Bible: with open(self.fname, "r") as f: self.verses = json.load(f) + @lru_cache(maxsize=1024) def __getitem__(self, verse): """Returns the text of the verse.""" @@ -51,29 +53,45 @@ class Bible: text=text, ) - def iter_books(self): - """Iterates over the books in the Bible.""" - + @lru_cache(maxsize=1) + def get_books(self): + """Returns a list of all books in the Bible.""" yielded = set() + books = [] for verse in self.verses: verse_ref = VerseReference.from_string(verse) if verse_ref.book in yielded: continue yielded.add(verse_ref.book) - yield verse_ref.book + books.append(verse_ref.book) + + return books - def iter_chapters(self): - """Iterates over the chapters in the Bible.""" + def iter_books(self): + """Iterates over the books in the Bible.""" + for book in self.get_books(): + yield book + @lru_cache(maxsize=1) + def get_chapters(self): + """Returns a list of all chapters in the Bible.""" yielded = set() + chapters = [] for verse in self.verses: verse_ref = VerseReference.from_string(verse) if (verse_ref.book, verse_ref.chapter) in yielded: continue yielded.add((verse_ref.book, verse_ref.chapter)) - yield verse_ref.book, verse_ref.chapter + chapters.append((verse_ref.book, verse_ref.chapter)) + + return chapters + + def iter_chapters(self): + """Iterates over the chapters in the Bible.""" + for book, chapter in self.get_chapters(): + yield book, chapter def iter_chapters_by_book(self): """Iterates over the chapters in the Bible, grouped by book.""" @@ -107,6 +125,7 @@ class VerseReference(BaseModel): verse: int @classmethod + @lru_cache(maxsize=2048) def from_string(cls, s: str): """ Parses a string in the format "Book Chapter:Verse" and returns a VerseReference object. @@ -131,6 +150,49 @@ class VerseReference(BaseModel): return cls(book=book, chapter=int(chapter), verse=int(verse)) +class @lru_cache(maxsize=256) + def get_verses_by_book_chapter(self, book, chapter): + """Returns a list of verses for a specific book and chapter.""" + verses = [] + for verse in self.verses: + verse_ref = VerseReference.from_string(verse) + if verse_ref.book == book and verse_ref.chapter == chapter: + # Clean up the text + text = self.verses[verse] + text = text.replace("# ", "").replace("[", "").replace("]", "") + verses.append(Verse( + book=verse_ref.book, + chapter=verse_ref.chapter, + verse=verse_ref.verse, + text=text, + )) + return sorted(verses, key=lambda v: v.verse) + + @lru_cache(maxsize=128) + def get_chapters_for_book(self, book): + """Returns a list of chapter numbers for a specific book.""" + chapters = set() + for verse in self.verses: + verse_ref = VerseReference.from_string(verse) + if verse_ref.book == book: + chapters.add(verse_ref.chapter) + return sorted(list(chapters)) + + @lru_cache(maxsize=2048) + def get_verse_text(self, book, chapter, verse_num): + """Returns the text for a specific verse.""" + verse_key = f"{book} {chapter}:{verse_num}" + if verse_key in self.verses: + text = self.verses[verse_key] + return text.replace("# ", "").replace("[", "").replace("]", "") + return None + + @lru_cache(maxsize=1) + def get_verse_count(self): + """Returns the total number of verses in the Bible.""" + return len(self.verses) + + # Create an instance of the Bible class. bible = Bible() diff --git a/kjvstudy_org/server.py b/kjvstudy_org/server.py index 0685f9a..9ddc826 100644 --- a/kjvstudy_org/server.py +++ b/kjvstudy_org/server.py @@ -16,9 +16,9 @@ from .kjv import bible def get_verse_text(book, chapter, verse): """Get the actual text of a specific verse""" try: - verses = [v for v in bible.iter_verses() if v.book == book and v.chapter == chapter and v.verse == verse] - if verses: - return verses[0].text + text = bible.get_verse_text(book, chapter, verse) + if text: + return text return f"{book} {chapter}:{verse} text not found" except: return f"{book} {chapter}:{verse}"