From 6f721ce182488e1f0b658f16297702f617029c87 Mon Sep 17 00:00:00 2001 From: Tyler Date: Tue, 6 Jun 2023 20:09:38 -0700 Subject: [PATCH 1/5] Documentation update --- INSTALL.txt | 5 +++-- README.txt | 18 +++++++++++++----- data/seq.db | Bin 0 -> 12288 bytes data/shortcodes.db | Bin 0 -> 16384 bytes media/kjv_background.jpg | Bin 14859 -> 0 bytes 5 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 data/seq.db create mode 100644 data/shortcodes.db delete mode 100644 media/kjv_background.jpg diff --git a/INSTALL.txt b/INSTALL.txt index 0788982..06d1346 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -9,11 +9,12 @@ python3-hunspell:0.5.5-2build6 uwsgi-core:2.0.20-4 uwsgi-plugin-python3:2.0.20-4 apache2:2.4.52-1ubuntu4.2 +python3-requests:2.25.1+dfsg-2 Installation ====== -This software expects to be installed at /opt/kjv-api/ +This software expects to be installed at /opt/kjv-api/ (for uwsgi use on a reverse proxy) This installation method is intended to play nice among other Virtual Hosts 0. Install dependancies listed at the head of this document. @@ -43,4 +44,4 @@ This installation method is intended to play nice among other Virtual Hosts - It is up to you to use https or not, but if you know nginx or haproxy you should be able to set up local proxying to the WSGI server that runs the flask. - There are WSGI modules for apache avaliable, which may be better for larger scaled - deployments, but http proxying to the local uwsgi served flask works fine. + deployments, but http proxying to the local uwsgi served flask works fine for smaller uses. diff --git a/README.txt b/README.txt index 128573a..94edee0 100644 --- a/README.txt +++ b/README.txt @@ -41,32 +41,37 @@ CONTENTS │   ├── kjv.aff - KJV Spellchecking Description file (hunspell) │   ├── kjv.db - KJV sqlite3 database │   └── kjv.dic - KJV Spellchecking dictionary file (hunspell) +│   └── seq.db - Sqlite3 Database with user's ids for sequenced scripture +│   └── shortcodes.db - Sqlite3 Database with saved shortcodes for scripture groups. ├── favicon.ico ├── html │   ├── dictionary.html - dictionary search landing page /define │   ├── find.html - unified search bar landing page /find -│   ├── header.html - navigation bar added programatically to rich results +│   ├── navbar.html - navigation bar added programatically to rich results │   ├── heaven.html - Bible way to heaven, static page /salvation +│   ├── on_reading_bible.html - Introduction on good reading practices │   ├── index.html - / landing page with unified search bar │   ├── reader.html - not yet implemented Bible browser end point │   ├── reading_plan.html - not yet implemented Bible reading plan generator │   ├── response.html - Template for rich verse responses │   ├── search.html - Bible keyword search landing page /search +│   ├── search_bar.html - Unused │   ├── show.html - Bible verse search landing page /show +│   ├── seq.html - Bible sequential verse landing page /seq │   └── votd.html - Matty's test VOTD rich landing page ├── install │   ├── apache.site.conf.example - example installation configuration │   └── kjv-api.service - example systemd service file ├── INSTALL.txt - installation instructions +├── logs - log folder (populated at runtime - there is NO log rotation) ├── js │   └── collapsible.js - js for the definition drop-down menu used in unified search -├── kjv-api.sh - runs flask app on port 1611 -├── kjv-api-test.sh - runs flask app on port 1612 -├── media -│   └── kjv_background.jpg - Matty's test rich media +├── kjv-api.sh - runs uwsgi flask app on port 1611 +├── kjv-api-test.sh - runs uwsgi flask app on port 1612 ├── README.txt - This document ├── styles │   ├── collapsible.css +│   ├── header.css │   ├── fonts │   │   ├── Arizonia-Regular.ttf │   │   └── Parisienne-Regular.ttf @@ -75,6 +80,9 @@ CONTENTS │   └── votd.css └── tools └── av1611_dictionary_scraper.py - builds a dictionary json for the 1828 dictionary + └── sanity_check.py - Integrated during runtime and also as endpoint testing when run alone. + └── search_keywords.txt - endpoint testing queries + └── sanity_results.txt - results of running sanity_check.py as a standalone AUTHOR ====== diff --git a/data/seq.db b/data/seq.db new file mode 100644 index 0000000000000000000000000000000000000000..aaa187e30563e9c522366f2660f1f52ccd4a5618 GIT binary patch literal 12288 zcmeI$&oA^q7zgl~YFLEf)awWmvTQotqMAsQl=vA|6P%j9@0OHBbi3l>;N3v5UPBh1rDJ?55EN7>57^AOHafKmY;|fB*y_009Uzm%tfq z)3RB5E|TD1DU8FQ7#;5VNgVv&597K}nJu`E=W@@PS$28dARnqkMeey<9$zagtT=^j zzT|F?@RKkuhkRkxbLZW{2rmWY#IKaYx76V&rBz$cQW6~&!_)F{NuJ{UppqO_W4~?+ zU(|J^=lV?Q*~RYV+5D2QYj)Xr`>nFqT>k~DfdB*`009U<00IzzKywJFSHG|hRs6yv zm;wS2_z8i5jH*#*%+k%ZyrCQUQGIOGu(&R4Q`p92&J;oyX1}6p87FVe8P@wG-L!?7 z(*kQ*nbp=uwb;Z}(%ryX^+|dGc>uL5$RF)wu!`|5Ix>qp|0SG_<0uX=z1Rwwb2tWV=5coZTXS%KBa`dGd zdA*Sc@BAR@`vVasnNn@rmSc0rI&IiIndkd)&K>*4;g{{&h1KrzbGw`8lc@-vmh+uv zt<|yfydMZJ8v0{*;K>SnzU07Ex3seyCByMRJcg5zEX`eS8u^Q{8-G7^jU-Q*$`2PE zCX42^{mxu9ErYUmB0CxcAOHafKmY;|fB*y_009U<00MtTAg`pftmQQIx)X?p!0*Y^ z1w%K?f__vmPPnd@b+cSLE|v^=nR{|ylzkA{(I5Z;2tWV=5P$##AOHafKmY;|*eHQr wRild&0%ckM&j_1s)CRE`2tWV=5P$##AOHafKmY;|fWSW&NUK>I{}`Zr0g=~lb^rhX literal 0 HcmV?d00001 diff --git a/media/kjv_background.jpg b/media/kjv_background.jpg deleted file mode 100644 index 63958c862692b7e16c02b3688a8be0c6eb0f79c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14859 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 -- 2.34.1 From a97f27c77f7679b2582f9f0435adaffa780b5538 Mon Sep 17 00:00:00 2001 From: Tyler Date: Fri, 23 Jun 2023 16:33:34 -0700 Subject: [PATCH 2/5] Fixed revelation not showing --- app.py | 68 +++++++++++++++++++++++--------------- html/shortcode_report.html | 14 ++++++++ 2 files changed, 56 insertions(+), 26 deletions(-) create mode 100644 html/shortcode_report.html diff --git a/app.py b/app.py index fc81a5e..dd25ca4 100644 --- a/app.py +++ b/app.py @@ -88,7 +88,7 @@ cached: dict = { if int(str(chap)[:-3]) not in cached["chapter_list"] ] cached["chapter_list"].sort() -for book in range(1, 66): +for book in range(1, 67): cached["books_chapter_lengths"][book] = kjv_cur.execute( "SELECT c FROM fts_kjv where b = ? ORDER BY id DESC LIMIT 1;", (book,) ).fetchone()[0] @@ -108,8 +108,7 @@ def generate_short_id(): def lookup_bookname(book_id): result = kjv_cur.execute( - f"SELECT n FROM key_english WHERE b = {book_id};" - ).fetchone() + "SELECT n FROM key_english WHERE b = ?;",(book_id,)).fetchone() if result: result = result[0] return result @@ -117,8 +116,7 @@ def lookup_bookname(book_id): def lookup_book_id(bookname) -> int: result = kjv_cur.execute( - f"SELECT b FROM key_english WHERE n = '{bookname}';" - ).fetchone() + "SELECT b FROM key_english WHERE n = ?;",(bookname,)).fetchone() if result: result = result[0] return result @@ -126,10 +124,11 @@ def lookup_book_id(bookname) -> int: def lookup_fts(kwds): logging.debug(f"lookup_fts.kwds = '{kwds}'") - return kjv_cur.execute(f"SELECT * FROM fts_kjv('{kwds}')").fetchall() + return kjv_cur.execute("SELECT * FROM fts_kjv(?)", (kwds,)).fetchall() -def lookup_by_verse_id(start_verse, end_verse=None): +def lookup_by_verse_id(start_verse, end_verse=None) -> list: + # This is an internal function - we don't use placeholders because SQL injection should be impossible here if not end_verse: results = kjv_cur.execute( f"SELECT * FROM fts_kjv WHERE id = {start_verse};" @@ -191,7 +190,8 @@ def ref_input_cleaning( logging.debug(f"ref_input_cleaning({ref})") ref = ref.replace(" ", "") if ref.count(":") != 1 and ref_search: - logging.debug("ref_input_cleaning: Assuming user wanted entire chapter") + if len(ref) == 0: + return "Invalid Query" if ref[-1] in string.digits: ref += ":-" else: @@ -227,8 +227,9 @@ def ref_input_cleaning( def search_input_cleaning( - query, valid_chars=string.ascii_letters + string.digits + "+^* " + query, valid_chars=string.ascii_letters + string.digits + "+^* ", extra_chars='' ): + valid_chars += extra_chars # should protect against SQL injection, maybe. Should have another person review. cleaned_query = [] for character in query: @@ -294,7 +295,7 @@ def parse_query(query_override: str = None): result += "" result += "
" # result += search() - logging.debug(f"parse_query.search = '{result}'") + #logging.debug(f"parse_query.search = '{result}'") return result @@ -357,13 +358,13 @@ def return_dict_rich(ref, defs, simple): def show(kw=None, get_start_verse_id=False, human_readable=False): ref: str = request.args.get("kw", None) get_chapter: bool = request.args.get("all", False) - if ref.endswith(","): - ref = ref[:-1] if kw: ref = kw - if ref is None: + if not ref: return send_file("html/show.html") logging.debug(f"show({ref})") + if ref.endswith(","): + ref = ref[:-1] refs: list = [] for r in ref.split(","): r_ = ref_input_cleaning(r.strip()) @@ -374,6 +375,8 @@ def show(kw=None, get_start_verse_id=False, human_readable=False): verse_results: list = [] # check if the search is for multiple refs for ref in refs: + if len(ref) < 2: + continue logging.debug(f"show.reference({ref})") maybe_chapter: str = ref.split(":")[0][3:] ref_chapter: str = "" @@ -410,7 +413,7 @@ def show(kw=None, get_start_verse_id=False, human_readable=False): logging.debug(f"show.start_verse_id({start_verse_id})") logging.debug(f"show.end_verse_id({end_verse_id})") results = lookup_by_verse_id(start_verse_id, end_verse_id) - logging.debug(f"show.results(len({results}))") + logging.debug(f"show.results len({len(results)})") for result in results: verse_results.append(result) response_list = scripture_response(verse_results, human_readable) @@ -507,10 +510,11 @@ def page_not_found(e): @app.get("/") def idx(shortcode=""): if not sanity: - return "Sanity check failed. Check log, or please notify tyler@dinsmoor.us" + return "Sanity check failed. Check database ownership or please notify tyler@dinsmoor.us" if shortcode: + logging.info(f"/{shortcode}") return resolve_shortcode(shortcode) - logging.info("Index Served") + logging.info(f"/{shortcode}") return send_file("html/index.html") @@ -533,7 +537,7 @@ def random_verse(): response = "
".join(response_list) else: response = jsonify(response_list) - logging.debug(f"Search Response: {response}") + #logging.debug(f"Search Response: {response}") return response @@ -554,7 +558,7 @@ def verse_of_the_day(): response = "
".join(response_list) else: response = jsonify(response_list) - logging.debug(f"Search Response: {response}") + #logging.debug(f"Search Response: {response}") return response @@ -595,7 +599,7 @@ def search(): response = "
".join(response_list) else: response = jsonify(response_list) - logging.debug(f"Search Response: {response}") + #logging.debug(f"Search Response: {response}") return response @@ -640,6 +644,18 @@ def sequential_report(uid=None): uids = seq_cur.execute("select * from reading_tracker").fetchall() return render_template("seq_report.html", uids=uids) +@app.get("/screport") +def shortcode_report(shortcode=None): + if usermode == "Single": + short_conn = sqlite3.connect("data/shortcodes.db", check_same_thread=False) + else: + short_conn = sqlite3.connect("data/shortcodes.db") + short_cur = short_conn.cursor() + shortcodes = short_cur.execute( + "SELECT * FROM shortcodes" + ).fetchall() + return render_template("shortcode_report.html", shortcodes=shortcodes) + def sequential_purge(): if usermode == "Single": @@ -655,7 +671,7 @@ def sequential_purge(): since_use: timedelta = evaluate_datetime - last_used if since_use > sequential_purge_delta: logging.info(f"Purging UID: {uid[0]}") - seq_cur.execute(f"DELETE FROM reading_tracker WHERE uid = '{uid[0]}'") + seq_cur.execute("DELETE FROM reading_tracker WHERE uid = ?", (uid[0],)) seq_conn.commit() seq_cur.close() @@ -693,7 +709,7 @@ def sequential_read(start=0, num=1, uid=None, getuid=False): uid = generate_short_id() # range returns a 5 digit id try: seq_cur.execute( - f"INSERT INTO reading_tracker VALUES('{uid}', {start}, '{last_used}')" + "INSERT INTO reading_tracker VALUES(?, ?, ?)", (uid, start, last_used) ) except sqlite3.OperationalError as e: logging.error( @@ -710,7 +726,7 @@ def sequential_read(start=0, num=1, uid=None, getuid=False): uid = ref_input_cleaning(uid, ref_search=False) try: nextverse = seq_cur.execute( - f"SELECT verse FROM reading_tracker WHERE uid = '{uid}'" + "SELECT verse FROM reading_tracker WHERE uid = ?", (uid,) ).fetchone()[0] logging.debug(f"Queried UID {uid} on verse {nextverse}") sequential_purge() @@ -728,7 +744,7 @@ def sequential_read(start=0, num=1, uid=None, getuid=False): logging.info(f"Served {num+1} verses to UID {uid}") seq_cur.execute( - f"REPLACE INTO reading_tracker (uid, verse, last_used) VALUES('{uid}', {nextverse+num+1}, '{last_used}')" + "REPLACE INTO reading_tracker (uid, verse, last_used) VALUES(?, ?, ?)", (uid, (nextverse+num+1), last_used) ) # Doing REPLACE INTO instead of UPDATE will make the updated row at the end of the table, making the purging # only look at a small set of the oldest unused entries. @@ -744,7 +760,7 @@ def sequential_read(start=0, num=1, uid=None, getuid=False): @app.get("/mksc/") def generate_shortcode(query: str = ""): - query = search_input_cleaning(query) + query = search_input_cleaning(query, extra_chars=":-,") if not query: return "Empty query." if usermode == "Single": @@ -759,7 +775,7 @@ def generate_shortcode(query: str = ""): creation_date = str(datetime.now()) shortcode = generate_short_id() short_cur.execute( - f"REPLACE INTO shortcodes(shortcode,query,creation_date) VALUES('{shortcode}', '{query}', '{creation_date}')" + "REPLACE INTO shortcodes(shortcode,query,creation_date) VALUES(?, ?, ?)", (shortcode, query, creation_date) ) short_conn.commit() short_cur.close() @@ -779,7 +795,7 @@ def resolve_shortcode(shortcode: str = ""): short_conn = sqlite3.connect("data/shortcodes.db") short_cur = short_conn.cursor() query = short_cur.execute( - f"SELECT query FROM shortcodes WHERE shortcode = '{shortcode}'" + "SELECT query FROM shortcodes WHERE shortcode = ?", (shortcode,) ).fetchone()[0] short_cur.close() logging.info(f"Resolved Shortcode {shortcode} for query '{query}'") diff --git a/html/shortcode_report.html b/html/shortcode_report.html new file mode 100644 index 0000000..2862337 --- /dev/null +++ b/html/shortcode_report.html @@ -0,0 +1,14 @@ + + + + + + + {% for code in shortcodes %} + + + + + + {% endfor %} +
shortcode |query |creation_date
{{ code[0] }} |{{ code[1] }} |{{ code[2] }}
\ No newline at end of file -- 2.34.1 From 1e2b4d1c6df2fa59f4c0747259aba15a3b75ebd7 Mon Sep 17 00:00:00 2001 From: Tyler Date: Mon, 26 Jun 2023 13:33:42 -0700 Subject: [PATCH 3/5] Added button and js for shortcode generation --- app.py | 2 +- html/navbar.html | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index dd25ca4..b6479ba 100644 --- a/app.py +++ b/app.py @@ -23,7 +23,7 @@ timestamp_runtime: datetime = datetime.now().strftime("%d%b%y-%H:%M") logging.basicConfig( filename=f"logs/kjv-api_{datetime.now().strftime('%d%b%y')}.log", encoding="utf-8", - level=logging.DEBUG, + level=logging.INFO, ) logging.info(f"Started: {timestamp_runtime}") diff --git a/html/navbar.html b/html/navbar.html index 8945159..42d8482 100644 --- a/html/navbar.html +++ b/html/navbar.html @@ -13,10 +13,23 @@ + + +
{prev_chapter_name} | {current_chapter_name} | {next_chapter_name} → + \ No newline at end of file -- 2.34.1 From af4e3600bd39d36aa19a2ac7890c3f84c8060953 Mon Sep 17 00:00:00 2001 From: Tyler Date: Tue, 12 Sep 2023 14:55:26 -0700 Subject: [PATCH 4/5] Preparing for templates --- html/find.html | 24 ------------------------ html/old_find.html | 24 ++++++++++++++++++++++++ tools/transcript_parse.py | 12 ++++++++++++ 3 files changed, 36 insertions(+), 24 deletions(-) create mode 100644 html/old_find.html create mode 100644 tools/transcript_parse.py diff --git a/html/find.html b/html/find.html index 243dbba..e69de29 100644 --- a/html/find.html +++ b/html/find.html @@ -1,24 +0,0 @@ -
-Home | Quick Search | -Random Verse | -Verse of the Day
-

Quick Search

-
-
-

- -
- - - - - diff --git a/html/old_find.html b/html/old_find.html new file mode 100644 index 0000000..243dbba --- /dev/null +++ b/html/old_find.html @@ -0,0 +1,24 @@ +
+Home | Quick Search | +Random Verse | +Verse of the Day
+

Quick Search

+ +
+

+ +
+ + + + + diff --git a/tools/transcript_parse.py b/tools/transcript_parse.py new file mode 100644 index 0000000..b8565c2 --- /dev/null +++ b/tools/transcript_parse.py @@ -0,0 +1,12 @@ +#Here we will take the transcript of a sermon, extract references to scripture and store in +# a sqlite database by scripture UID per what's in the kjv.db +# This will write to a new db, sermons.db, with the following table +# key, verse_id, sermon_name, sermon_preacher, sermon_denomination, sermon_link, sermon_timestamp + +# Need to do a study of how scripture is transcoded, as in, is it "matthew fifeteen seven" or "Matthew 15:7" and account +# for those differences. +# This tool is only for populating the database when given + +usage = """Transcript Parser by Tyler Dinsmoor +Usage: python3 transcript_parse.py sermon_transcript.txt [../data/sermons.db] +""" \ No newline at end of file -- 2.34.1 From 6e6acc15231cc1beffe3946dfb331cb2221306fa Mon Sep 17 00:00:00 2001 From: Tyler Date: Wed, 7 Feb 2024 23:29:58 -0800 Subject: [PATCH 5/5] Revert "Preparing for templates" This reverts commit af4e3600bd39d36aa19a2ac7890c3f84c8060953. --- html/find.html | 24 ++++++++++++++++++++++++ html/old_find.html | 24 ------------------------ tools/transcript_parse.py | 12 ------------ 3 files changed, 24 insertions(+), 36 deletions(-) delete mode 100644 html/old_find.html delete mode 100644 tools/transcript_parse.py diff --git a/html/find.html b/html/find.html index e69de29..243dbba 100644 --- a/html/find.html +++ b/html/find.html @@ -0,0 +1,24 @@ +
+Home | Quick Search | +Random Verse | +Verse of the Day
+

Quick Search

+ +
+

+ +
+ + + + + diff --git a/html/old_find.html b/html/old_find.html deleted file mode 100644 index 243dbba..0000000 --- a/html/old_find.html +++ /dev/null @@ -1,24 +0,0 @@ -
-Home | Quick Search | -Random Verse | -Verse of the Day
-

Quick Search

- -
-

- -
- - - - - diff --git a/tools/transcript_parse.py b/tools/transcript_parse.py deleted file mode 100644 index b8565c2..0000000 --- a/tools/transcript_parse.py +++ /dev/null @@ -1,12 +0,0 @@ -#Here we will take the transcript of a sermon, extract references to scripture and store in -# a sqlite database by scripture UID per what's in the kjv.db -# This will write to a new db, sermons.db, with the following table -# key, verse_id, sermon_name, sermon_preacher, sermon_denomination, sermon_link, sermon_timestamp - -# Need to do a study of how scripture is transcoded, as in, is it "matthew fifeteen seven" or "Matthew 15:7" and account -# for those differences. -# This tool is only for populating the database when given - -usage = """Transcript Parser by Tyler Dinsmoor -Usage: python3 transcript_parse.py sermon_transcript.txt [../data/sermons.db] -""" \ No newline at end of file -- 2.34.1