diff --git a/app.py b/app.py index 9d566c0..fd4dcfc 100644 --- a/app.py +++ b/app.py @@ -1,5 +1,5 @@ # app.py -from flask import Flask, request, jsonify, send_file, render_template +from flask import Flask, request, jsonify, send_file, render_template, redirect import random from datetime import date, datetime, timedelta # used for daily verse import sqlite3 @@ -40,6 +40,7 @@ Bible Reading Plan /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 https://docs.python.org/3/library/sqlite3.html#sqlite3-placeholders +URL Shortener for sharing groups of scripture. """ if __name__ == "__main__": @@ -74,12 +75,11 @@ cached: dict = { ] cached["chapter_list"].sort() -def int32_to_id(n): - if n==0: return "0" +def generate_short_id(): + remain = random.randrange(614_656,17_210_367) # resolves to length of 5 chars="0123456789ACEFHJKLMNPRTUVWXY" length=len(chars) result="" - remain=n while remain>0: pos = remain % length remain = remain // length @@ -187,8 +187,9 @@ def ref_input_cleaning( else: return "".join(cleaned_ref) def search_input_cleaning( - query, valid_chars=string.ascii_letters + string.digits + '+^"* ' + query, valid_chars=string.ascii_letters + string.digits + '+^* ' ): + # should protect against SQL injection, maybe. Should have another person review. cleaned_query = [] for character in query: if character in valid_chars: @@ -200,8 +201,10 @@ def ref_parse_book(ref): return book return False @app.get("/find") -def parse_query(): +def parse_query(query_override:str = None): query = request.args.get("kw", None) + if query_override: + query = query_override if query: query = query.strip() logging.info(f"Query: {query}") @@ -423,9 +426,12 @@ def page_not_found(e): } return jsonify(message) @app.get("/") -def idx(): +@app.get("/") +def idx(shortcode=''): if not sanity: return("There is an issue with permissions. Check log, or please notify tyler@dinsmoor.us") + if shortcode: + return resolve_shortcode(shortcode) logging.info("Index Served") return send_file("html/index.html") @app.get("/salvation") @@ -572,7 +578,7 @@ def sequential_read(start=0, num=1, uid=None, getuid=False): start = cached["verse_ids"].index( int(show(kw=start, get_start_verse_id=True)) ) - uid = int32_to_id(random.randrange(614_656,17_210_367)) # range returns a 5 digit id + uid = generate_short_id() # range returns a 5 digit id try: seq_cur.execute( f"INSERT INTO reading_tracker VALUES('{uid}', {start}, '{last_used}')" @@ -620,7 +626,42 @@ def sequential_read(start=0, num=1, uid=None, getuid=False): response = jsonify(response_list) return response +@app.get("/mksc/") +def generate_shortcode(query: str = ""): + query = search_input_cleaning(query) + if not query: + return("Empty query.") + 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() + short_cur.execute("CREATE TABLE IF NOT EXISTS shortcodes (shortcode TEXT PRIMARY KEY, query TEXT UNIQUE, creation_date TEXT)") + short_conn.commit() + 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}')" + ) + short_conn.commit() + short_cur.close() + logging.info(f"Generated Shortcode {shortcode} for query '{query}'") + return shortcode +def resolve_shortcode(shortcode: str = ""): + shortcode = search_input_cleaning(shortcode, valid_chars="0123456789ACEFHJKLMNPRTUVWXY") + if not shortcode: + return("Empty shortcode.") + 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() + query = short_cur.execute(f"SELECT query FROM shortcodes WHERE shortcode = '{shortcode}'").fetchone()[0] + short_cur.close() + logging.info(f"Resolved Shortcode {shortcode} for query '{query}'") + return redirect(f"/find?kw={query}&view=rich") + if __name__ == "__main__": print("You must run this program within a uwsgi environment if you are running this for multiple users.") print("Otherwise, you may end up with database corruption if multiple writes happen.") diff --git a/tools/sanity_check.py b/tools/sanity_check.py index 88676d7..9d4ab6e 100644 --- a/tools/sanity_check.py +++ b/tools/sanity_check.py @@ -6,7 +6,7 @@ from os import stat, getuid def check_sanity(): - dependancies = ['data/seq.db'] + dependancies = ['data/seq.db', "data/shortcodes.db"] current_uid = getuid() for dependancy in dependancies: if stat(dependancy).st_uid != current_uid: