Materials
materials
¶
RESULT_PAGE_SIZE
¶
MATERIAL
¶
Responsible for the data for the main area of the page.
See
Source code in modules/materials.py
class MATERIAL:
"""Responsible for the data for the main area of the page.
See
* [{Material}][material]
* [∈ book][elem-book],
* [∈ chapter][elem-chapter],
* [∈ page][elem-page],
"""
def __init__(self, Record, Word, Query, Note):
self.Record = Record
self.Word = Word
self.Query = Query
self.Note = Note
def page(self):
Check = current.Check
Record = self.Record
mr = Check.field("material", "", "mr")
qw = Check.field("material", "", "qw")
vr = Check.field("material", "", "version")
bk = Check.field("material", "", "book")
ch = Check.field("material", "", "chapter")
tp = Check.field("material", "", "tp")
tr = Check.field("material", "", "tr")
lang = Check.field("material", "", "lang")
iidRep = Check.field("material", "", "iid")
page = Check.field("material", "", "page")
(authorized, msg) = Record.authRead(mr, qw, iidRep)
if not authorized:
return dict(
version=vr,
mr=mr,
qw=qw,
msg=msg,
hits=0,
results=0,
pages=0,
page=0,
pagelist=json.dumps([]),
material=None,
slots=json.dumps([]),
)
return self.get(vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang)
def getPassage(self, vr, bk, ch):
Caching = current.Caching
return Caching.get(
f"passage_{vr}_{bk}_{ch}",
lambda: self.getPassage_c(vr, bk, ch),
ALWAYS,
)
def getPassage_c(self, vr, bookname, chapternum):
PASSAGE_DBS = current.PASSAGE_DBS
if bookname is None or chapternum is None or vr not in PASSAGE_DBS:
return ({}, {})
bookrecords = PASSAGE_DBS[vr].executesql(
dedent(
f"""
select * from book where name = '{bookname}'
;
"""
),
as_dict=True,
)
book = bookrecords[0] if bookrecords else {}
if book and "id" in book:
chapterrecords = PASSAGE_DBS[vr].executesql(
dedent(
f"""
select * from chapter
where chapter_num = {chapternum} and book_id = {book["id"]}
;
"""
),
as_dict=True,
)
chapter = chapterrecords[0] if chapterrecords else {}
else:
chapter = {}
return (book, chapter)
def get(self, vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang):
Caching = current.Caching
mrrep = "m" if mr == "m" else qw
book = bk if mr == "m" else iidRep
chapter = ch if mr == "m" else page
return Caching.get(
f"verses_{vr}_{mrrep}_{book}_{chapter}_{tp}_{tr}_{lang}_",
lambda: self.get_c(vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang),
ONE_HOUR,
)
def get_c(self, vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang):
Word = self.Word
Query = self.Query
Note = self.Note
if mr == "m":
(book, chapter) = self.getPassage(vr, bk, ch)
material = (
VERSESCONTENT(vr, mr, chapter=chapter["id"], tp=tp, tr=tr, lang=lang)
if chapter
else None
)
result = dict(
mr=mr,
qw=qw,
hits=0,
msg=f"{bk} {ch} does not exist" if not chapter else None,
results=len(material.verses) if material else 0,
pages=1,
material=material,
slots=json.dumps([]),
)
elif mr == "r":
(iid, keywords) = (None, None)
if iidRep is not None:
(iid, keywords) = iDecode(qw, iidRep)
if iid is None:
kind = "query" if qw == "q" else "word" if qw == "w" else "note set"
msg = f"No {kind} selected"
result = dict(
mr=mr,
qw=qw,
msg=msg,
hits=0,
results=0,
pages=0,
page=0,
pagelist=json.dumps([]),
material=None,
slots=json.dumps([]),
)
else:
(nSlots, slotSets) = (
Query.read(vr, iid)
if qw == "q"
else Word.read(vr, iid)
if qw == "w"
else Note.read(vr, iid, keywords)
)
(nresults, npages, verses, slots) = self.getPagination(
vr, page, slotSets
)
material = VERSESCONTENT(vr, mr, verses, tp=tp, tr=tr, lang=lang)
result = dict(
mr=mr,
qw=qw,
msg=None,
hits=nSlots,
results=nresults,
pages=npages,
page=page,
pagelist=json.dumps(pagelist(page, npages, 10)),
material=material,
slots=json.dumps(slots),
)
else:
result = dict()
return result
def getPagination(self, vr, p, slotSets):
Caching = current.Caching
PASSAGE_DBS = current.PASSAGE_DBS
verseBoundaries = (
Caching.get(
f"verse_boundaries_{vr}_",
lambda: PASSAGE_DBS[vr].executesql(
dedent(
"""
select first_m, last_m from verse order by id
;
"""
)
),
ALWAYS,
)
if vr in PASSAGE_DBS
else []
)
m = 0 # slot range index, walking through slotSets
v = 0 # verse id, walking through verseBoundaries
nvp = 0 # number of verses added to current page
nvt = 0 # number of verses added in total
nM = len(slotSets)
nV = len(verseBoundaries)
curPage = 1 # current page
verseIds = []
verseSlots = set()
lastVerse = -1
while m < nM and v < nV:
if nvp == RESULT_PAGE_SIZE:
nvp = 0
curPage += 1
(vB, vE) = verseBoundaries[v]
(mB, mE) = slotSets[m]
if vE < mB:
v += 1
continue
if mE < vB:
m += 1
continue
# now vE >= mB and mE >= vB so one of the following holds
# vvvvvv
# mmmmm
# mmmmmmmmmmmmmmm
# mmm
# mmmmmmmmmmmmm
# so (vB, vE) and (mB, mE) overlap
# so add v to the result pages and go to the next verse
# and add p to the highlight list if on the selected page
if v != lastVerse:
if curPage == p:
verseIds.append(v)
lastVerse = v
nvp += 1
nvt += 1
if lastVerse == v:
clippedSLots = set(range(max(vB, mB), min(vE, mE) + 1))
verseSlots |= clippedSLots
if curPage != p:
v += 1
else:
if mE < vE:
m += 1
else:
v += 1
if nvp == 0:
# no verses on last current page, so it is empty, so discard it
curPage -= 1
verses = verseIds if p <= curPage and len(verseIds) else None
return (nvt, curPage if nvt else 0, verses, list(verseSlots))
__init__(self, Record, Word, Query, Note)
special
¶
Source code in modules/materials.py
def __init__(self, Record, Word, Query, Note):
self.Record = Record
self.Word = Word
self.Query = Query
self.Note = Note
page(self)
¶
Source code in modules/materials.py
def page(self):
Check = current.Check
Record = self.Record
mr = Check.field("material", "", "mr")
qw = Check.field("material", "", "qw")
vr = Check.field("material", "", "version")
bk = Check.field("material", "", "book")
ch = Check.field("material", "", "chapter")
tp = Check.field("material", "", "tp")
tr = Check.field("material", "", "tr")
lang = Check.field("material", "", "lang")
iidRep = Check.field("material", "", "iid")
page = Check.field("material", "", "page")
(authorized, msg) = Record.authRead(mr, qw, iidRep)
if not authorized:
return dict(
version=vr,
mr=mr,
qw=qw,
msg=msg,
hits=0,
results=0,
pages=0,
page=0,
pagelist=json.dumps([]),
material=None,
slots=json.dumps([]),
)
return self.get(vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang)
getPassage(self, vr, bk, ch)
¶
Source code in modules/materials.py
def getPassage(self, vr, bk, ch):
Caching = current.Caching
return Caching.get(
f"passage_{vr}_{bk}_{ch}",
lambda: self.getPassage_c(vr, bk, ch),
ALWAYS,
)
getPassage_c(self, vr, bookname, chapternum)
¶
Source code in modules/materials.py
def getPassage_c(self, vr, bookname, chapternum):
PASSAGE_DBS = current.PASSAGE_DBS
if bookname is None or chapternum is None or vr not in PASSAGE_DBS:
return ({}, {})
bookrecords = PASSAGE_DBS[vr].executesql(
dedent(
f"""
select * from book where name = '{bookname}'
;
"""
),
as_dict=True,
)
book = bookrecords[0] if bookrecords else {}
if book and "id" in book:
chapterrecords = PASSAGE_DBS[vr].executesql(
dedent(
f"""
select * from chapter
where chapter_num = {chapternum} and book_id = {book["id"]}
;
"""
),
as_dict=True,
)
chapter = chapterrecords[0] if chapterrecords else {}
else:
chapter = {}
return (book, chapter)
get(self, vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang)
¶
Source code in modules/materials.py
def get(self, vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang):
Caching = current.Caching
mrrep = "m" if mr == "m" else qw
book = bk if mr == "m" else iidRep
chapter = ch if mr == "m" else page
return Caching.get(
f"verses_{vr}_{mrrep}_{book}_{chapter}_{tp}_{tr}_{lang}_",
lambda: self.get_c(vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang),
ONE_HOUR,
)
get_c(self, vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang)
¶
Source code in modules/materials.py
def get_c(self, vr, mr, qw, bk, iidRep, ch, page, tp, tr, lang):
Word = self.Word
Query = self.Query
Note = self.Note
if mr == "m":
(book, chapter) = self.getPassage(vr, bk, ch)
material = (
VERSESCONTENT(vr, mr, chapter=chapter["id"], tp=tp, tr=tr, lang=lang)
if chapter
else None
)
result = dict(
mr=mr,
qw=qw,
hits=0,
msg=f"{bk} {ch} does not exist" if not chapter else None,
results=len(material.verses) if material else 0,
pages=1,
material=material,
slots=json.dumps([]),
)
elif mr == "r":
(iid, keywords) = (None, None)
if iidRep is not None:
(iid, keywords) = iDecode(qw, iidRep)
if iid is None:
kind = "query" if qw == "q" else "word" if qw == "w" else "note set"
msg = f"No {kind} selected"
result = dict(
mr=mr,
qw=qw,
msg=msg,
hits=0,
results=0,
pages=0,
page=0,
pagelist=json.dumps([]),
material=None,
slots=json.dumps([]),
)
else:
(nSlots, slotSets) = (
Query.read(vr, iid)
if qw == "q"
else Word.read(vr, iid)
if qw == "w"
else Note.read(vr, iid, keywords)
)
(nresults, npages, verses, slots) = self.getPagination(
vr, page, slotSets
)
material = VERSESCONTENT(vr, mr, verses, tp=tp, tr=tr, lang=lang)
result = dict(
mr=mr,
qw=qw,
msg=None,
hits=nSlots,
results=nresults,
pages=npages,
page=page,
pagelist=json.dumps(pagelist(page, npages, 10)),
material=material,
slots=json.dumps(slots),
)
else:
result = dict()
return result
getPagination(self, vr, p, slotSets)
¶
Source code in modules/materials.py
def getPagination(self, vr, p, slotSets):
Caching = current.Caching
PASSAGE_DBS = current.PASSAGE_DBS
verseBoundaries = (
Caching.get(
f"verse_boundaries_{vr}_",
lambda: PASSAGE_DBS[vr].executesql(
dedent(
"""
select first_m, last_m from verse order by id
;
"""
)
),
ALWAYS,
)
if vr in PASSAGE_DBS
else []
)
m = 0 # slot range index, walking through slotSets
v = 0 # verse id, walking through verseBoundaries
nvp = 0 # number of verses added to current page
nvt = 0 # number of verses added in total
nM = len(slotSets)
nV = len(verseBoundaries)
curPage = 1 # current page
verseIds = []
verseSlots = set()
lastVerse = -1
while m < nM and v < nV:
if nvp == RESULT_PAGE_SIZE:
nvp = 0
curPage += 1
(vB, vE) = verseBoundaries[v]
(mB, mE) = slotSets[m]
if vE < mB:
v += 1
continue
if mE < vB:
m += 1
continue
# now vE >= mB and mE >= vB so one of the following holds
# vvvvvv
# mmmmm
# mmmmmmmmmmmmmmm
# mmm
# mmmmmmmmmmmmm
# so (vB, vE) and (mB, mE) overlap
# so add v to the result pages and go to the next verse
# and add p to the highlight list if on the selected page
if v != lastVerse:
if curPage == p:
verseIds.append(v)
lastVerse = v
nvp += 1
nvt += 1
if lastVerse == v:
clippedSLots = set(range(max(vB, mB), min(vE, mE) + 1))
verseSlots |= clippedSLots
if curPage != p:
v += 1
else:
if mE < vE:
m += 1
else:
v += 1
if nvp == 0:
# no verses on last current page, so it is empty, so discard it
curPage -= 1
verses = verseIds if p <= curPage and len(verseIds) else None
return (nvt, curPage if nvt else 0, verses, list(verseSlots))