Skip to content

Commit 91eb92e

Browse files
committed
added json and raw html API endpoints
1 parent 87b9696 commit 91eb92e

8 files changed

+63
-35
lines changed

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
# https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/
4848
setup(
4949
name=package,
50-
version="0.1.35",
50+
version="0.1.36",
5151
python_requires=">=3.8, <3.13",
5252
description=f"UniqueBible App is a cross-platform & offline bible application, integrated with high-quality resources and unique features. Developers: Eliran Wong and Oliver Tseng",
5353
long_description=long_description,

uniquebible/db/ToolsSqlite.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from uniquebible import config
22
from uniquebible.util.BibleBooks import BibleBooks
33
from uniquebible.util.CatalogUtil import CatalogUtil
4+
from uniquebible.util.RegexSearch import RegexSearch
45

56
if __name__ == "__main__":
67
from uniquebible.util.ConfigUtil import ConfigUtil
@@ -738,7 +739,7 @@ def getMenu(self, command):
738739
else:
739740
return "INVALID_COMMAND_ENTERED"
740741

741-
def getContent(self, verse):
742+
def getContent(self, verse, fullVerseList=[]):
742743
if self.text in self.getCommentaryList():
743744
b, c, v, *_ = verse
744745
if c > 0:
@@ -750,9 +751,25 @@ def getContent(self, verse):
750751
scripture = self.cursor.fetchone()
751752
if scripture:
752753
data = scripture[0]
754+
if fullVerseList:
755+
fullVerseList = [f'<vid id="v{b}.{c}.{v}"' for b, c, v, *_ in fullVerseList]
756+
757+
pattern = '(<vid id="v[0-9]+?.[0-9]+?.[0-9]+?"></vid>)<hr>'
758+
searchReplaceItems = ((pattern, r"<hr>\1"),)
759+
chapterCommentary = RegexSearch.deepReplace(data, pattern, searchReplaceItems)
760+
verseCommentaries = chapterCommentary.split("<hr>")
761+
762+
loaded = []
763+
for i in verseCommentaries:
764+
for ii in fullVerseList:
765+
if i.strip() and not i in loaded and ii in i:
766+
loaded.append(i)
767+
data = "<hr>".join(loaded)
753768
if c == 0:
754769
data = data.replace("<b>0:0</b>", "")
755770
data = data.replace("<u><b>0</b></u>", "")
771+
if config.rawOutput:
772+
return data
756773
if config.theme in ("dark", "night"):
757774
data = data.replace('color:#000080;', 'color:gray;')
758775
chapter += re.sub(r'onclick="luV\(([0-9]+?)\)"', r'onclick="luV(\1)" onmouseover="qV(\1)" ondblclick="mV(\1)"', data)

uniquebible/gui/MainWindow.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4543,7 +4543,7 @@ def passRunTextCommand(self, textCommand, addRecord=True, source="main", forceEx
45434543
elif view:
45444544
views[view].setHtml(html, baseUrl)
45454545

4546-
if view == "instant" and (config.instantMode == 0 or (config.iModeSplitterSizes[-1] == 0 and not config.instantMode > 0)):
4546+
if hasattr(config, "iModeSplitterSizes") and view == "instant" and (config.instantMode == 0 or (config.iModeSplitterSizes[-1] == 0 and not config.instantMode > 0)):
45474547
self.showFlotableInstantView(html)
45484548

45494549
if addRecord:

uniquebible/latest_changes.txt

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
PIP package:
22

3+
0.1.36
4+
5+
* improved commentary output for terminal and stream mode
6+
7+
* added API endpoints `/html` and `/json`, in addition to `/plain`
8+
9+
See the differences:
10+
11+
http://bible.gospelchurch.uk/html?cmd=Commentary:::John%202:4-7
12+
13+
http://bible.gospelchurch.uk/json?cmd=Commentary:::John%202:4-7
14+
15+
http://bible.gospelchurch.uk/plain?cmd=Commentary:::John%202:4-7
16+
317
0.1.35
418

519
* refine commentary output via api endpoint

uniquebible/startup/nonGui.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def run_terminal_mode():
177177
command = ".menu"
178178
config.mainWindow.printRunningCommand(command)
179179
content = config.mainWindow.getContent(command)
180-
if content.strip():
180+
if content is not None and content.strip():
181181
config.mainWindow.displayOutputOnTerminal(content)
182182
else:
183183
command = ".latestbible"

uniquebible/util/ConfigUtil.py

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def setup(noQt=None, cli=None, enableCli=None, enableApiServer=None, enableHttpS
7575

7676
# Temporary configurations
7777
# Their values are not saved on exit.
78+
config.rawOutput = True if config.runMode == "stream" else False
7879
config.controlPanel = False
7980
config.miniControl = False
8081
config.tempRecord = ""

uniquebible/util/RemoteHttpHandler.py

+20-30
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from uniquebible.util.TextCommandParser import TextCommandParser
2020
from uniquebible.util.RemoteCliMainWindow import RemoteCliMainWindow
2121
from uniquebible.util.TextUtil import TextUtil
22-
from uniquebible.util.RegexSearch import RegexSearch
2322
from urllib.parse import urlparse, parse_qs
2423
from uniquebible.util.FileUtil import FileUtil
2524
from uniquebible.util.LanguageUtil import LanguageUtil
@@ -245,11 +244,11 @@ def runStartupPlugins(self):
245244
def execPythonFile(self, script):
246245
self.textCommandParser.parent.execPythonFile(script)
247246

248-
def updateData(self, plainOutput=False, allowPrivateData=False):
249-
if plainOutput:
247+
def updateData(self, rawOutput=False, allowPrivateData=False):
248+
if rawOutput:
250249
config.displayLanguage = "en_GB"
251250
config.standardAbbreviation = "ENG"
252-
self.path = re.sub("^/plain", "/index.html", self.path)
251+
self.path = re.sub("^/(html|json|plain)", "/index.html", self.path)
253252
config.webHomePage = "{0}.html".format(config.webPrivateHomePage) if allowPrivateData else "index.html"
254253
# Check language
255254
# Traditional Chinese
@@ -321,21 +320,6 @@ def handleBadRequests(self):
321320
else:
322321
self.blankPage()
323322

324-
def getCommentaryContent(self, chapterCommentary, fullVerseList):
325-
pattern = '(<vid id="v[0-9]+?.[0-9]+?.[0-9]+?"></vid>)<hr>'
326-
searchReplaceItems = ((pattern, r"<hr>\1"),)
327-
chapterCommentary = RegexSearch.deepReplace(chapterCommentary, pattern, searchReplaceItems)
328-
verseCommentaries = chapterCommentary.split("<hr>")
329-
330-
fullVerseList = [f'<vid id="v{b}.{c}.{v}"' for b, c, v, *_ in fullVerseList]
331-
332-
loaded = []
333-
for i in verseCommentaries:
334-
for ii in fullVerseList:
335-
if i.strip() and not i in loaded and ii in i:
336-
loaded.append(i)
337-
return "<hr>".join(loaded)
338-
339323
def do_GET(self):
340324
try:
341325
self.clientIP = self.client_address[0]
@@ -356,11 +340,12 @@ def do_GET(self):
356340
query_components = parse_qs(urlparse(self.path).query)
357341
private = query_components.get("private", [])
358342
allowPrivateData = True if private and private[0].strip() == config.webPrivateHomePage else False
359-
plainOutput = True if self.path.startswith("/plain?") else False
343+
config.rawOutput = True if re.search(r"^/(html|json|plain)\?", self.path) else False
344+
api = re.sub(r"^/(html|json|plain)\?.*?$", r"\1", self.path) if config.rawOutput else ""
360345
# update resource path
361-
self.updateData(plainOutput=plainOutput, allowPrivateData=allowPrivateData)
346+
self.updateData(rawOutput=config.rawOutput, allowPrivateData=allowPrivateData)
362347

363-
if plainOutput:
348+
if config.rawOutput:
364349
cmd = query_components.get("cmd", [])
365350
if cmd:
366351
self.command = query_components["cmd"][0].strip()
@@ -373,15 +358,20 @@ def do_GET(self):
373358
# output
374359
self.commonHeader()
375360
_, content, _ = self.textCommandParser.parser(self.command, "http")
376-
# refine commentary output
377-
if content and self.command.strip().lower().startswith("commentary:::"):
378-
verseList = self.parser.extractAllReferences(self.command)
379-
if verseList:
380-
fullVerseList = Bible(text="KJV").getEverySingleVerseList(verseList[:1])
381-
content = self.getCommentaryContent(content, fullVerseList)
382361
content = content.replace("<u><b>", "<u><b># ")
383-
plainText = TextUtil.htmlToPlainText(content).strip()
384-
self.wfile.write(bytes(plainText, "utf8"))
362+
# convert to plain text for plain endpoint
363+
if api in ("json", "plain"):
364+
content = TextUtil.htmlToPlainText(content).strip()
365+
if api == "json":
366+
output = {}
367+
for index, item in enumerate(self.command.split(":::")):
368+
if index == 0:
369+
output["keyword"] = item.strip()
370+
else:
371+
output[f"parameter_{index}"] = item.strip()
372+
output["content"] = content
373+
content = json.dumps(output)
374+
self.wfile.write(bytes(content, "utf8"))
385375
# restore user config
386376
config.addFavouriteToMultiRef = addFavouriteToMultiRef
387377
elif self.ignoreCommand(self.path):

uniquebible/util/TextCommandParser.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,8 @@ def textPlainBible(self, verseList, text):
14181418
return verses
14191419

14201420
def textFormattedBible(self, verse, text, source=""):
1421+
if config.rawOutput:
1422+
return self.textPlainBible([verse], text)
14211423
formattedBiblesFolder = os.path.join(config.marvelData, "bibles")
14221424
formattedBibles = [f[:-6] for f in os.listdir(formattedBiblesFolder) if os.path.isfile(os.path.join(formattedBiblesFolder, f)) and f.endswith(".bible") and not re.search(r"^[\._]", f)]
14231425
#marvelBibles = ("MOB", "MIB", "MAB", "MPB", "MTB", "LXX1", "LXX1i", "LXX2", "LXX2i")
@@ -3403,7 +3405,11 @@ def textCommentary(self, command, source):
34033405
config.mainB, config.mainC, config.mainV, *_ = bcvTuple
34043406
module = commandList[0]
34053407
commentary = Commentary(module)
3406-
content = commentary.getContent(bcvTuple)
3408+
fullVerseList = Bible("KJV").getEverySingleVerseList((bcvTuple,))
3409+
if config.runMode == "terminal" or config.rawOutput:
3410+
content = commentary.getContent(bcvTuple, fullVerseList=fullVerseList)
3411+
else:
3412+
content = commentary.getContent(bcvTuple)
34073413
if not content == "INVALID_COMMAND_ENTERED":
34083414
self.setCommentaryVerse(module, bcvTuple)
34093415
return ("study", content, {'tab_title':'Com:' + module})

0 commit comments

Comments
 (0)