Shortcode backend
This commit is contained in:
@@ -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("/<shortcode>")
|
||||
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,6 +626,41 @@ def sequential_read(start=0, num=1, uid=None, getuid=False):
|
||||
response = jsonify(response_list)
|
||||
|
||||
return response
|
||||
@app.get("/mksc/<query>")
|
||||
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.")
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user