aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md11
-rwxr-xr-xcli.py34
-rw-r--r--config.py4
-rw-r--r--pyble.py112
4 files changed, 161 insertions, 0 deletions
diff --git a/README.md b/README.md
index 6d44631..b113532 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,17 @@ You're going to need one or several translations. One possibility is to [get the
$ ./cli.py load --type=biblehub bibles.txt
$ rm bibles.zip bibles.txt
+## Usage
+
+See `./cli.py --help` for general instructions and `./cli.py command --help` for command specific instructions.
+
+## Examples
+
+ $ ./cli.py read 'John 1:1-3' --nl
+ 1:1 In the beginning was the Word, and the Word was with God, and the Word was God.
+ 2 The same was in the beginning with God.
+ 3 All things were made through him; and without him was not anything made that hath been made.
+
## To do
Add a table for cross references, and a script to read in the database from [OpenBible.info][openbibledb].
diff --git a/cli.py b/cli.py
index f1647e0..e9345c3 100755
--- a/cli.py
+++ b/cli.py
@@ -30,6 +30,39 @@ def init():
setup_fill_alternative_book_names(db)
click.echo('Done.')
+@cli.command()
+@click.option('--nl/--no-nl', default=False,
+ help='Output every verse on a new line (default: false)')
+@click.option('--vn/--no-vn', default=True,
+ help='Output verse and chapter numbers (default: true)')
+@click.option('-t', '--translation', metavar='name',
+ help='Use a specific translation (default: config.py)')
+@click.argument('reference', metavar='reference')
+def read(nl, vn, translation, reference):
+ """Read a part of the Bible
+
+ Examples:
+
+ \b
+ cli.py read 'Genesis 1:1'
+ cli.py read 'Genesis 1:1' -t 'King James Bible'
+ cli.py read 'Gen 1:1-3' --no-vn
+ cli.py read 'Is 52:13-53:12' --nl
+ """
+ passage = Passage.parse(reference)
+ chap = 0
+ for v in passage.verses():
+ if vn:
+ if chap != v.chapter:
+ chap = v.chapter
+ click.secho(str(chap) + ':', fg='yellow', nl=False)
+ click.secho(str(v.nr) + ' ', fg='cyan', nl=False)
+
+ click.echo(str(v.get_translated(translation)) + ' ', nl=nl)
+
+ if not nl:
+ click.echo()
+
def load_biblehub_line(columns, line):
"""Split a line from a Bible Hub dump into a usable dictionary
@@ -105,5 +138,6 @@ def load(type, filename):
click.secho('I don\'t know a type ' + type, fg='red')
if __name__ == '__main__':
+ db = setup_database()
cli()
diff --git a/config.py b/config.py
index a64f54a..cc1c75f 100644
--- a/config.py
+++ b/config.py
@@ -6,3 +6,7 @@ DATABASES = {
}
}
+PYBLE_SETTINGS = {
+ 'default_translation': 'American Standard Version'
+ }
+
diff --git a/pyble.py b/pyble.py
index 187b4ca..480277d 100644
--- a/pyble.py
+++ b/pyble.py
@@ -1,39 +1,151 @@
import csv
+
from orator import DatabaseManager, Model, Schema
+from orator.exceptions.orm import ModelNotFound
+
+import re
+
+from config import *
class Part(Model):
__timestamps__ = False
__fillable__ = ['name']
+ __primary_key__ = 'name'
class Book(Model):
__timestamps__ = False
__fillable__ = ['canonical_name']
+ __primary_key__ = 'canonical_name'
class AlternativeBookName(Model):
__timestamps__ = False
__fillable__ = ['book', 'name']
+ __primary_key__ = 'name'
class Verse(Model):
__timestamps__ = False
__fillable__ = ['book', 'chapter', 'nr']
+ def __repr__(self):
+ return self.book + ' ' + str(self.chapter) + ':' + str(self.nr)
+
+ def __str__(self):
+ return str(self.get_translated())
+
+ def get_translated(self, translation=None):
+ """Get the TranslatedVerse of this Verse and a Translation
+
+ translation -- may be None, a string, or a Translation object
+ When None, the default (as in config.py) is used.
+ """
+ if translation == None:
+ translation = PYBLE_SETTINGS['default_translation']
+ tv = TranslatedVerse.where(
+ {'translation': str(translation),
+ 'book': self.book,
+ 'chapter': self.chapter,
+ 'nr': self.nr }).first()
+ return tv
+
class Translation(Model):
__timestamps__ = False
__fillable__ = ['name']
+ __primary_key__ = 'name'
+
+ def __str__(self):
+ return self.name
class TranslatedVerse(Model):
__timestamps__ = False
__table__ = 'translated_verses'
__fillable__ = ['translation', 'book', 'chapter', 'nr', 'text']
+ def __repr__(self):
+ return book + ' ' + str(chapter) + ' ' + str(nr) + ' in ' + translation
+
+ def __str__(self):
+ return self.text
+
class Passage(Model):
__timestamps__ = False
__fillable__ = ['fst', 'snd']
+ def __repr__(self):
+ return repr(self.fst) + ' - ' + repr(self.snd)
+
+ def __str__(self):
+ return ' '.join([str(v) for v in self.verses()])
+
+ def verses(self):
+ """An ordered list of the verses in this passage"""
+ vs = []
+ book = self.fst.book
+ for c in range(self.fst.chapter, self.snd.chapter + 1):
+ vs_new = Verse.where({'book': book, 'chapter': c})
+ if c == self.fst.chapter:
+ vs_new = vs_new.where('nr', '>=', self.fst.nr)
+ if c == self.snd.chapter:
+ vs_new = vs_new.where('nr', '<=', self.snd.nr)
+ vs = vs + list(vs_new.get())
+ return vs
+
+ @staticmethod
+ def parse(ref):
+ """Parse a Bible reference into a Passage object"""
+ rgx = re.compile(r"^([\s\w]+?[a-z]\b)(?:\s+"
+ "(\d+)(?::(\d+)(?:\-(\d+)(?::(\d+))?)?)?)?", re.I)
+ m = rgx.match(ref)
+ book, chap1, verse1, n1, n2 = m.groups()
+ chap1 = int(chap1)
+
+ try:
+ book = AlternativeBookName.find_or_fail(book).book
+ except ModelNotFound:
+ return None
+
+ p = Passage()
+ if verse1 == None:
+ try:
+ p.fst = Verse.where(
+ {'book': book,
+ 'chapter': chap1,
+ 'nr': 1}).first()
+ p.snd = Verse.where({'book': book, 'chapter': chap1})\
+ .order_by('nr', 'desc').first()
+ except ModelNotFound:
+ return None
+ else:
+ chap1 = int(chap1)
+ try:
+ p.fst = Verse.where(
+ {'book': book,
+ 'chapter': chap1,
+ 'nr': verse1}).first()
+ if n1 == None:
+ p.snd = p.fst
+ elif n2 == None:
+ n1 = int(n1)
+ p.snd = Verse.where(
+ {'book': book,
+ 'chapter': chap1,
+ 'nr': n1}).first()
+ else:
+ n1 = int(n1)
+ n2 = int(n2)
+ p.snd = Verse.where(
+ {'book': book,
+ 'chapter': n1,
+ 'nr': n2}).first()
+ except ModelNotFound:
+ return None
+
+ return p
+
class CrossReference(Model):
__fillable__ = ['passage_id1', 'passage_id2', 'relevance']
def setup_fill_alternative_book_names(db):
+ """Fill the database with alternative book names from a CSV file"""
with open('alternative_book_names.csv', 'r') as csvfile:
reader = csv.reader(csvfile, delimiter=',', quotechar='"')
db.begin_transaction()