5
0

adds getBible class to select scripture.

This commit is contained in:
Llewellyn van der Merwe 2023-11-13 08:18:25 +02:00
parent 6fd36e5467
commit 25e720788a
Signed by: Llewellyn
GPG Key ID: A9201372263741E7
10 changed files with 397 additions and 6 deletions

View File

@ -4,6 +4,7 @@ The `getBible Librarian` package is a Python library designed for efficiently re
## Features ## Features
- [Get Scripture](https://git.vdm.dev/getBible/librarian/src/branch/master/docs/getbible_scripture.md)
- [Get Reference](https://git.vdm.dev/getBible/librarian/src/branch/master/docs/getbible_reference.md) - [Get Reference](https://git.vdm.dev/getBible/librarian/src/branch/master/docs/getbible_reference.md)
- [Get Book Number](https://git.vdm.dev/getBible/librarian/src/branch/master/docs/getbible_book_number.md) - [Get Book Number](https://git.vdm.dev/getBible/librarian/src/branch/master/docs/getbible_book_number.md)

View File

@ -10,7 +10,11 @@ The `GetBibleBookNumber` package is a Python library designed for efficiently re
- Provides functionality to dump Trie data into a JSON file for review. - Provides functionality to dump Trie data into a JSON file for review.
- Fallback search mechanisms for comprehensive reference coverage. - Fallback search mechanisms for comprehensive reference coverage.
## Installation ## Installation (pip)
To install the package using pip, see [the documentation](https://git.vdm.dev/getBible/-/packages/pypi/getbible-librarian).
## Installation (git)
To install `GetBibleBookNumber`, you need to clone the repository and install the package manually. Ensure you have Python 3.7 or higher installed. To install `GetBibleBookNumber`, you need to clone the repository and install the package manually. Ensure you have Python 3.7 or higher installed.
@ -84,4 +88,3 @@ Contributions to the `GetBibleBookNumber` class is welcome. Please ensure to fol
## License ## License
This project is licensed under the GNU GPL v2.0. See the LICENSE file for more details. This project is licensed under the GNU GPL v2.0. See the LICENSE file for more details.

View File

@ -0,0 +1,79 @@
# Guide to Building and Deploying a GetBible Package to Our Gitea's PyPI Package Registry
This guide focuses on building your Python package and deploying it to your Gitea system's PyPI package registry. The provided documentation gives a clear outline of the requirements and steps needed.
## Prerequisites
- Python and necessary build tools installed.
- `pip` for package installation.
- `twine` for package uploading.
## Step 1: Building the Python Package
### 1.1 Create a Source Distribution
Navigate to your package directory and run:
```bash
python setup.py sdist
```
This creates a source distribution in the `dist/` folder.
### 1.2 Create a Wheel Distribution
For a wheel (`.whl`) distribution:
```bash
python setup.py bdist_wheel
```
This places a wheel file in the `dist/` folder.
## Step 2: Configuring the Package Registry
### 2.1 Edit `~/.pypirc`
Add the following to your `~/.pypirc` file:
```ini
[distutils]
index-servers = getbible
[getbible]
repository = https://git.vdm.dev/api/packages/getbible/pypi
username = {username}
password = {token}
```
Replace `{owner}`, `{username}`, and `{token}` with your Gitea details.
For more information on the PyPI registry, [see the documentation](https://docs.gitea.com/usage/packages/pypi/).
## Step 3: Publish the Package
### 3.1 Upload Package
Run the following command to upload your package:
```bash
python3 -m twine upload --repository getbible dist/*
```
This uploads all files in the `dist/` directory (`.tar.gz` and `.whl`).
**Note:** You cannot publish a package if a package of the same name and version already exists.
## Step 4: Install the Package
### 4.1 Install Using pip
To install a package from the Gitea package registry:
```bash
pip install --index-url https://git.vdm.dev/api/packages/getBible/pypi/simple/ getBible-librarian
```
## Conclusion
You now have a straightforward process for building and deploying a Python package to your Gitea system's PyPI package registry. This setup ensures a seamless workflow for managing and distributing Python packages within your organization or for personal use.

View File

@ -6,7 +6,11 @@ The `GetBibleReference` package is a Python library designed for efficiently ret
- Returns well formed book-number, chatper-number, and verse array when given any scripture text reference. - Returns well formed book-number, chatper-number, and verse array when given any scripture text reference.
## Installation ## Installation (pip)
To install the package using pip, see [the documentation](https://git.vdm.dev/getBible/-/packages/pypi/getbible-librarian).
## Installation (git)
To install `GetBibleReference`, you need to clone the repository and install the package manually. Ensure you have Python 3.7 or higher installed. To install `GetBibleReference`, you need to clone the repository and install the package manually. Ensure you have Python 3.7 or higher installed.
@ -66,4 +70,3 @@ Contributions to the `GetBibleReference` class is welcome. Please ensure to foll
## License ## License
This project is licensed under the GNU GPL v2.0. See the LICENSE file for more details. This project is licensed under the GNU GPL v2.0. See the LICENSE file for more details.

View File

@ -0,0 +1,84 @@
# GetBible Scripture
The `GetBible` package is a Python library designed for efficiently retrieving scripture across various translations.
## Features
- Returns a selected range of referenced scripture passages.
## Installation (pip)
To install the package using pip, see [the documentation](https://git.vdm.dev/getBible/-/packages/pypi/getbible-librarian).
## Installation (git)
To install `GetBible`, you need to clone the repository and install the package manually. Ensure you have Python 3.7 or higher installed.
```bash
git clone https://git.vdm.dev/getBible/librarian.git
cd librarian
pip install .
```
## Usage
### Basic Usage
```python
import json
from getbible import GetBible
# Initialize the class
getbible = GetBible()
# Get the scripture as JSON
scripture_json = getbible.scripture("Genesis 1:1")
print(scripture_json) # Outputs the JSON scripture as a string.
# Get the scripture as dictionary
scripture_dict = getbible.select("Genesis 1:1")
print(json.dumps(scripture_dict, indent=4)) # Pretty-prints the dictionary.
```
### Using Translation Abbreviations
When utilizing the `GetBible` class to look up a reference, you can use the lowercase abbreviations of the target translation:
```python
import json
from getbible import GetBible
# Initialize the class
getbible = GetBible()
scripture = getbible.select("Genesis 1:1-5", 'aov')
print(json.dumps(scripture, indent=4)) # Pretty-prints the dictionary.
```
In this code snippet, `"aov"` is used as the abbreviation for the Afrikaans Ou Vertaaling.
## Development and Testing
To contribute or run tests, clone the repository and set up a virtual environment:
```bash
git clone https://git.vdm.dev/getBible/librarian.git
cd reference
python -m venv venv
source venv/bin/activate # On Windows use `venv\Scripts\activate`
pip install -e .
```
Run tests using the standard unittest framework:
```bash
python -m unittest tests.test_getbible
```
## Contributing
Contributions to the `GetBible` class is welcome. Please ensure to follow the coding standards and write tests for new features.
## License
This project is licensed under the GNU GPL v2.0. See the LICENSE file for more details.

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
requests~=2.31.0
setuptools>=65.5.1

View File

@ -1,8 +1,11 @@
from setuptools import setup, find_packages from setuptools import setup, find_packages
with open('requirements.txt') as f:
required = f.read().splitlines()
setup( setup(
name="getBible-librarian", name="getBible-librarian",
version="0.1.0", version="0.2.0",
author="Llewellyn van der Merwe", author="Llewellyn van der Merwe",
author_email="getbible@vdm.io", author_email="getbible@vdm.io",
description="A Python package to retrieving Bible references with ease.", description="A Python package to retrieving Bible references with ease.",
@ -13,7 +16,7 @@ setup(
packages=find_packages(where="src"), packages=find_packages(where="src"),
package_data={"getbible": ["data/*.json"]}, package_data={"getbible": ["data/*.json"]},
include_package_data=True, include_package_data=True,
install_requires=[], install_requires=required,
classifiers=[ classifiers=[
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",

View File

@ -1,3 +1,4 @@
from .getbible_book_number import GetBibleBookNumber from .getbible_book_number import GetBibleBookNumber
from .getbible_reference import GetBibleReference from .getbible_reference import GetBibleReference
from .getbible_reference import BookReference from .getbible_reference import BookReference
from .getbible import GetBible

144
src/getbible/getbible.py Normal file
View File

@ -0,0 +1,144 @@
import os
import json
import requests
from getbible import GetBibleReference
class GetBible:
def __init__(self, repo_path="https://api.getbible.net", version='v2'):
"""
Initialize the GetBible class.
:param repo_path: The repository path, which can be a URL or a local file path.
:param version: The version of the Bible repository.
"""
self.__get = GetBibleReference()
self.__repo_path = repo_path
self.__repo_version = version
self.__books_cache = {}
self.__chapters_cache = {}
# Determine if the repository path is a URL
self.__repo_path_url = self.__repo_path.startswith("http://") or self.__repo_path.startswith("https://")
def select(self, reference, abbreviation='kjv'):
"""
Select and return Bible verses based on the reference and abbreviation.
:param reference: The Bible reference (e.g., John 3:16).
:param abbreviation: The abbreviation for the Bible translation.
:return: dictionary of the selected Bible verses.
"""
self.__check_translation(abbreviation)
result = {}
references = reference.split(';')
for ref in references:
try:
reference = self.__get.ref(ref, abbreviation)
except ValueError:
raise ValueError(f"Invalid reference format.")
for verse in reference.verses:
self.__set_verse(abbreviation, reference.book, reference.chapter, verse, result)
return result
def scripture(self, reference, abbreviation='kjv'):
"""
Select and return Bible verses based on the reference and abbreviation.
:param reference: The Bible reference (e.g., John 3:16).
:param abbreviation: The abbreviation for the Bible translation.
:return: JSON string of the selected Bible verses.
"""
return json.dumps(self.select(reference, abbreviation))
def __set_verse(self, abbreviation, book, chapter, verse, result):
"""
Set verse information into the result JSON.
:param abbreviation: Bible translation abbreviation.
:param book: The book of the Bible.
:param chapter: The chapter number.
:param verse: The verse number.
:param result: The dictionary to store verse information.
"""
cache_key = f"{abbreviation}_{book}_{chapter}"
if cache_key not in self.__chapters_cache:
self.__chapters_cache[cache_key] = self.__retrieve_chapter_data(abbreviation, book, chapter)
chapter_data = self.__chapters_cache[cache_key]
verse_info = [v for v in chapter_data.get("verses", []) if str(v.get("verse")) == str(verse)]
if not verse_info:
raise ValueError(f"Verse {verse} not found in book {book}, chapter {chapter}.")
if cache_key in result:
existing_verses = {str(v["verse"]) for v in result[cache_key].get("verses", [])}
new_verses = [v for v in verse_info if str(v["verse"]) not in existing_verses]
result[cache_key]["verses"].extend(new_verses)
else:
verse_data = chapter_data.copy()
verse_data["verses"] = verse_info
result[cache_key] = verse_data
def __check_translation(self, abbreviation):
"""
Check if the given translation is available.
:param abbreviation: The abbreviation of the Bible translation to check.
:raises FileNotFoundError: If the translation is not found.
"""
path = self.__generate_path(abbreviation, "books.json")
if abbreviation not in self.__books_cache:
self.__books_cache[abbreviation] = self.__fetch_data(path)
if self.__books_cache[abbreviation] is None:
raise FileNotFoundError(f"Translation ({abbreviation}) not found in this API.")
def __generate_path(self, abbreviation, file_name):
"""
Generate the path or URL for a given file.
:param abbreviation: Bible translation abbreviation.
:param file_name: Name of the file to fetch.
:return: Full path or URL to the file.
"""
if self.__repo_path_url:
return f"{self.__repo_path}/{self.__repo_version}/{abbreviation}/{file_name}"
else:
return os.path.join(self.__repo_path, self.__repo_version, abbreviation, file_name)
def __fetch_data(self, path):
"""
Fetch data from either a URL or a local file path.
:param path: The path or URL to fetch data from.
:return: The fetched data, or None if an error occurs.
"""
if self.__repo_path_url:
response = requests.get(path)
if response.status_code == 200:
return response.json()
else:
return None
else:
if os.path.isfile(path):
with open(path, 'r') as file:
return json.load(file)
else:
return None
def __retrieve_chapter_data(self, abbreviation, book, chapter):
"""
Retrieve chapter data for a given book and chapter.
:param abbreviation: Bible translation abbreviation.
:param book: The book of the Bible.
:param chapter: The chapter number.
:return: Chapter data.
:raises FileNotFoundError: If the chapter data is not found.
"""
chapter_file = f"{str(book)}/{chapter}.json" if self.__repo_path_url else os.path.join(str(book),
f"{chapter}.json")
chapter_data = self.__fetch_data(self.__generate_path(abbreviation, chapter_file))
if chapter_data is None:
raise FileNotFoundError(f"File {abbreviation}/{book}/{chapter}.json does not exist.")
return chapter_data

71
tests/test_getbible.py Normal file
View File

@ -0,0 +1,71 @@
import unittest
import json
from getbible import GetBible
class TestGetBible(unittest.TestCase):
def setUp(self):
self.getbible = GetBible()
def test_valid_reference(self):
actual_result = json.loads(self.getbible.scripture('Gen 1:2-7', 'kjv'))
expected_result = {
"kjv_1_1": {"translation": "King James Version", "abbreviation": "kjv", "lang": "en", "language": "English",
"direction": "LTR", "encoding": "UTF-8", "book_nr": 1, "book_name": "Genesis", "chapter": 1,
"name": "Genesis 1", "verses": [{"chapter": 1, "verse": 2, "name": "Genesis 1:2",
"text": "And the earth was without form and void; and darkness was upon the face of the deep. And the Spirit of God moved upon the face of the waters."},
{"chapter": 1, "verse": 3, "name": "Genesis 1:3",
"text": "And God said, Let there be light: and there was light."},
{"chapter": 1, "verse": 4, "name": "Genesis 1:4",
"text": "And God saw the light, that it was good: and God divided the light from the darkness."},
{"chapter": 1, "verse": 5, "name": "Genesis 1:5",
"text": "And God called the light Day, and the darkness he called Night. And the evening and the morning were the first day."},
{"chapter": 1, "verse": 6, "name": "Genesis 1:6",
"text": "And God said, Let there be a firmament in the midst of the waters, and let it divide the waters from the waters."},
{"chapter": 1, "verse": 7, "name": "Genesis 1:7",
"text": "And God made the firmament, and divided the waters which were under the firmament from the waters which were above the firmament: and it was so."}]}}
self.assertEqual(actual_result, expected_result, "Failed to find 'Gen 1:2-7' scripture.")
def test_valid_reference_cns(self):
actual_result = json.loads(self.getbible.scripture('创世记1:2-7', 'cns'))
expected_result = {
"cns_1_1": {"translation": "NCV Simplified", "abbreviation": "cns", "lang": "zh-Hans",
"language": "Chinese",
"direction": "LTR", "encoding": "UTF-8", "book_nr": 1, "book_name": "\ufeff\u521b\u4e16\u8bb0",
"chapter": 1, "name": "\ufeff\u521b\u4e16\u8bb0 1", "verses": [
{"chapter": 1, "verse": 2, "name": "\ufeff\u521b\u4e16\u8bb0 1:2",
"text": "\u5730\u662f\u7a7a\u865a\u6df7\u6c8c\uff1b\u6df1\u6e0a\u4e0a\u4e00\u7247\u9ed1\u6697\uff1b\u3000\u795e\u7684\u7075\u8fd0\u884c\u5728\u6c34\u9762\u4e0a\u3002 "},
{"chapter": 1, "verse": 3, "name": "\ufeff\u521b\u4e16\u8bb0 1:3",
"text": "\u795e\u8bf4\uff1a\u201c\u8981\u6709\u5149\uff01\u201d\u5c31\u6709\u4e86\u5149\u3002 "},
{"chapter": 1, "verse": 4, "name": "\ufeff\u521b\u4e16\u8bb0 1:4",
"text": "\u795e\u770b\u5149\u662f\u597d\u7684\uff0c\u4ed6\u5c31\u628a\u5149\u6697\u5206\u5f00\u4e86\u3002 "},
{"chapter": 1, "verse": 5, "name": "\ufeff\u521b\u4e16\u8bb0 1:5",
"text": "\u795e\u79f0\u5149\u4e3a\u663c\uff0c\u79f0\u6697\u4e3a\u591c\u3002\u6709\u665a\u4e0a\uff0c\u6709\u65e9\u6668\uff1b\u8fd9\u662f\u7b2c\u4e00\u65e5\u3002 "},
{"chapter": 1, "verse": 6, "name": "\ufeff\u521b\u4e16\u8bb0 1:6",
"text": "\u795e\u8bf4\uff1a\u201c\u4f17\u6c34\u4e4b\u95f4\u8981\u6709\u7a79\u82cd\uff0c\u628a\u6c34\u548c\u6c34\u5206\u5f00\uff01\u201d\u4e8b\u5c31\u8fd9\u6837\u6210\u4e86\u3002 "},
{"chapter": 1, "verse": 7, "name": "\ufeff\u521b\u4e16\u8bb0 1:7",
"text": "\u795e\u9020\u4e86\u7a79\u82cd\uff0c\u628a\u7a79\u82cd\u4ee5\u4e0b\u7684\u6c34\u548c\u7a79\u82cd\u4ee5\u4e0a\u7684\u6c34\u5206\u5f00\u4e86\u3002 "}]}}
self.assertEqual(actual_result, expected_result, "Failed to find '创世记1:2-7' scripture.")
def test_valid_multiple_reference_aov(self):
actual_result = json.loads(self.getbible.scripture('Ge1:1;Jn1:1;1Jn1:1', 'aov'))
expected_result = {
"aov_1_1": {"translation": "Ou Vertaling", "abbreviation": "aov", "lang": "af", "language": "Afrikaans",
"direction": "LTR", "encoding": "UTF-8", "book_nr": 1, "book_name": "Genesis", "chapter": 1,
"name": "Genesis 1", "verses": [{"chapter": 1, "verse": 1, "name": "Genesis 1:1",
"text": "In die begin het God die hemel en die aarde geskape. "}]},
"aov_43_1": {"translation": "Ou Vertaling", "abbreviation": "aov", "lang": "af", "language": "Afrikaans",
"direction": "LTR", "encoding": "UTF-8", "book_nr": 43, "book_name": "Johannes", "chapter": 1,
"name": "Johannes 1", "verses": [{"chapter": 1, "verse": 1, "name": "Johannes 1:1",
"text": "In die begin was die Woord, en die Woord was by God, en die Woord was God. "}]},
"aov_62_1": {"translation": "Ou Vertaling", "abbreviation": "aov", "lang": "af", "language": "Afrikaans",
"direction": "LTR", "encoding": "UTF-8", "book_nr": 62, "book_name": "1 Johannes",
"chapter": 1, "name": "1 Johannes 1", "verses": [
{"chapter": 1, "verse": 1, "name": "1 Johannes 1:1",
"text": "Wat van die begin af was, wat ons gehoor het, wat ons met ons o\u00eb gesien het, wat ons aanskou het en ons hande getas het aangaande die Woord van die lewe \u2014 "}]}}
self.assertEqual(actual_result, expected_result, "Failed to find 'Ge1:1;Jn1:1;1Jn1:1' scripture.")
if __name__ == '__main__':
unittest.main()