diff --git a/app.py b/app.py index 4caae25..96ec326 100644 --- a/app.py +++ b/app.py @@ -6,23 +6,35 @@ import sqlite3 import string # for literals import json # for dictionary import hunspell # for spell checking +import sys -DEBUG = 0 +if "-vvv" in sys.argv: + DEBUG = 3 +elif "-vv" in sys.argv: + DEBUG = 2 +elif "-v" in sys.argv: + DEBUG = 1 +else: + DEBUG = 0 """ -To-do: -Separate dictionary-dictionary for hunsepll -Search phrase alias +Current work prefixed with * +TODO: +Replace send_file with something that loads headers and nav templates +* Return multiple defintiions for each word in phrase +Search phrase alias dictionary Response Bible book reading Search highlighting Styles Bible Reading Plan Bible Reader -Rich:
on each comma -find: handle ending with , +/seq Going backwards (works but is buggy, disabled for now) +/seq Wrap back to Gen 1:1 when you reach the end of Rev +/seq Querying what your UID's next verse is going to be +/seq Purging old UIDs after a certain period of non-use +Separate common functions into own library """ - def dbg(message): if DEBUG >= 1: print(f"\033[91m{message}\033[0m") @@ -42,10 +54,19 @@ dbg("Debug Level 1 Enabled") dbg2("Debug Level 2 Enabled") dbg3("Debug Level 3 Enabled") -dictionary_json = "data/1828_Webster_KJV.json" kjv_cur = sqlite3.connect("data/kjv.db").cursor() -verse_ids = [i[0] for i in kjv_cur.execute("SELECT id FROM fts_kjv;").fetchall()] -book_names = [i[0] for i in kjv_cur.execute("SELECT n FROM key_english").fetchall()] + +cached = { +"verse_ids":[i[0] for i in kjv_cur.execute("SELECT id FROM fts_kjv;").fetchall()], +"book_names":[i[0] for i in kjv_cur.execute("SELECT n FROM key_english").fetchall()], +"json_dictionary":json.load(open("data/1828_Webster_KJV.json", 'r')), +"html_response":open("html/response.html", "r").read(), +"html_navbar":open("html/navbar.html", "r").read(), +"css_response":open("styles/human_readable.css", "r").read(), +"css_collapsible":open("styles/collapsible.css", "r").read(), +"js_collapsible":open("js/collapsible.js", "r").read(), +} + app = Flask(__name__) @@ -189,7 +210,7 @@ def ref_input_cleaning( def search_input_cleaning( - query, valid_chars=string.ascii_letters + string.digits + '+^" ' + query, valid_chars=string.ascii_letters + string.digits + '+^"* ' ): cleaned_query = [] for character in query: @@ -199,7 +220,7 @@ def search_input_cleaning( def ref_parse_book(ref): - for book in reversed(book_names): + for book in reversed(cached['book_names']): if book.startswith(ref): return book return False @@ -210,6 +231,8 @@ def parse_query(): query = request.args.get("kw", None) if not query: return send_file("html/find.html") + if query.endswith(','): + query = query[:-1] result = show() if not hasattr(result, "__len__"): dbg3("parse_query.show = '{}'".format(result)) @@ -217,40 +240,50 @@ def parse_query(): if len(result) > 17: return result - result = "" - if len(query.split()) == 1: - result += "
" - result += define() + "
" - dbg3("parse_query.define = '{}'".format(result)) + result = "" + result += "" + result += "

1828 Webster Definitions

" + split_query = query.replace(",", " ").split(" ") + for word in split_query: + definition = define(word) + if not definition: + continue + result += "" + result += "
" + definition + "
" + dbg3("parse_query.define = '{}'".format(word)) + result += "" + result += "
" result += search() dbg3("parse_query.search = '{}'".format(result)) return result @app.get("/define") -def define(): +def define(word = None): ref = request.args.get("kw", None) + if word: + ref = word if ref: ref = ref.strip() if not ref: return send_file("html/dictionary.html") - with open(dictionary_json, "r") as data: - dictionary = json.load(data) + dictionary = cached['json_dictionary'] ref = ref.lower() if not ref in dictionary.keys(): - h = hunspell.HunSpell("data/kjv.dic", "data/kjv.aff") - suggestions = h.suggest(ref) - return "{} not found, try one of the following: {}".format( - ref, ", ".join(suggestions) - ) + if word: + return False + return "{} not found.".format(ref) + # search suggestions kind of suck + #h = hunspell.HunSpell("data/kjv.dic", "data/kjv.aff") + #suggestions = h.suggest(ref) + #return "{} not found, try one of the following: {}".format( + # ref, ", ".join(suggestions) + #) arg_view = request.args.get("view", None) if arg_view == "plain": response = return_dict_plain(ref, dictionary[ref]) elif arg_view == "rich": - response = return_dict_rich(ref, dictionary[ref]) + response = return_dict_rich(ref, dictionary[ref], simple=word) else: response = jsonify({ref: dictionary[ref]}) return response @@ -263,18 +296,18 @@ def return_dict_plain(ref, defs): return ref.capitalize() + "

" + response + "\n" -def return_dict_rich(ref, defs): - header = open("html/header.html", "r") - css = open("styles/human_readable.css", "r") - response_html = open("html/response.html", "r") +def return_dict_rich(ref, defs, simple): + if simple: + css = "" + else: + css = cached['css_response'] response = "" for e in defs: response += e + "

" return ( - response_html.read().format( + cached['html_response'].format( chapter=ref.split(":")[0], passage=ref.capitalize(), text=response - ) - + css.read() + ) + css ) @@ -334,7 +367,9 @@ def show(kw=None, get_start_verse_id=False): verse_results.append(result) response_list = response_multi(verse_results) arg_view = request.args.get("view", None) - if arg_view == "plain" or arg_view == "rich": + if arg_view == "plain": + response = "
".join(response_list) + elif arg_view == "rich": response = "
".join(response_list) else: response = jsonify(response_list) @@ -361,8 +396,6 @@ def response_text(scripture): def response_rich(scripture): - css = open("styles/human_readable.css", "r") - response_html = open("html/response.html", "r") # (passage, text) is the html formatting arguments bookname = lookup_bookname(scripture[idx_book]) chapter = str(scripture[idx_chapter]) @@ -370,10 +403,9 @@ def response_rich(scripture): text = str(scripture[idx_text]) passage = bookname + " " + chapter + ":" + verse return ( - response_html.read().format( + cached['html_response'].format( chapter=passage.split(":")[0], passage=passage, text=text ) - + css.read() ) @@ -384,8 +416,7 @@ def response_single(scripture): if arg_view == "plain": return response_text(scripture) elif arg_view == "rich": - header = open("html/header.html", "r") - return header.read() + response_rich(scripture) + return cached['html_navbar'].format(query=request.args.get("kw", "")) + cached['css_response'] + response_rich(scripture) else: response = response_dict(scripture) return jsonify(response) @@ -399,7 +430,8 @@ def response_multi(scriptures): for scripture in scriptures: response.append(response_text(scripture)) elif arg_view == "rich": - response.append(open("html/header.html", "r").read()) + response.append(cached['css_response']) + response.append(cached['html_navbar'].format(query=request.args.get("kw", ""))) for scripture in scriptures: response.append(response_rich(scripture)) else: @@ -430,19 +462,20 @@ def salvation(): @app.get("/t/random", defaults={"view": "plain"}) @app.get("/random") def random_verse(): - rand_id = random.SystemRandom().choice(verse_ids) + rand_id = random.SystemRandom().choice(cached['verse_ids']) scripture = lookup_one_verse(rand_id) return response_single(scripture) # backwards-compatibility +# plain takes 38ms -TODO can we cache this? @app.get("/t/votd", defaults={"view": "plain"}) @app.get("/votd") def verse_of_the_day(): today = int(str(date.today()).replace("-", "")) # this is deterministic because of today's date being used as the seed random.seed(today) - scripture = lookup_one_verse(random.choice(verse_ids)) + scripture = lookup_one_verse(random.choice(cached['verse_ids'])) return response_single(scripture) @@ -465,7 +498,9 @@ def search(): ) response_list = response_multi(results) arg_view = request.args.get("view", None) - if arg_view == "plain" or arg_view == "rich": + if arg_view == "plain": + response = "
".join(response_list) + elif arg_view == "rich": response = "
".join(response_list) else: response = jsonify(response_list) @@ -518,7 +553,7 @@ def sequential_read(start=0, num=1, uid=None, getuid=False): if start: - start = verse_ids.index(int(show(kw=start, get_start_verse_id=True))) + start = cached['verse_ids'].index(int(show(kw=start, get_start_verse_id=True))) uid = str(uuid.uuid4()) try: seq_cur.execute( @@ -540,12 +575,12 @@ def sequential_read(start=0, num=1, uid=None, getuid=False): except TypeError: dbg2("Invalid UID {}".format(uid)) return jsonify({"error": "UID Invalid or purged"}) - if len(verse_ids) < (nextverse + num): + if len(cached['verse_ids']) < (nextverse + num): # Correct our range to go to ceiling to prevent IndexError - diff = len(verse_ids) - (nextverse + num) + diff = len(cached['verse_ids']) - (nextverse + num) num = diff - num - start_verse = verse_ids[nextverse] - end_verse = verse_ids[nextverse + num] + start_verse = cached['verse_ids'][nextverse] + end_verse = cached['verse_ids'][nextverse + num] result_list = lookup_by_verse_id(start_verse, end_verse) response_list = response_multi(result_list) diff --git a/html/header.html b/html/navbar.html similarity index 51% rename from html/header.html rename to html/navbar.html index 242b420..a95a410 100644 --- a/html/header.html +++ b/html/navbar.html @@ -1,4 +1,9 @@
+
+ + + + Home | Quick Search | Random Verse | Verse of the Day
diff --git a/html/response.html b/html/response.html index 4fc1b5c..854a404 100644 --- a/html/response.html +++ b/html/response.html @@ -1,9 +1 @@ -

- - -{passage} - - -
-{text} -

+

{passage}
{text}

diff --git a/kjv-api-test.sh b/kjv-api-test.sh index 0146a4d..89e2588 100755 --- a/kjv-api-test.sh +++ b/kjv-api-test.sh @@ -2,8 +2,9 @@ # run from current directory only FILE=app.py if test -f "$FILE"; then - uwsgi_python3 --http-socket 0.0.0.0:1612 --wsgi-file app.py --callable app + uwsgi_python3 --http-socket 0.0.0.0:1612 --wsgi-file app.py --callable app --pyargv "-vvv" else cd /opt/kjv-api - uwsgi_python3 --http-socket 0.0.0.0:1612 --wsgi-file /opt/kjv-api/app.py --callable app + echo "WARNING: RUNNING FROM /opt/kjv-api" + uwsgi_python3 --http-socket 0.0.0.0:1612 --wsgi-file /opt/kjv-api/app.py --callable app --pyargv "-vvv" fi