Files
AwanaVerses/main.py

151 lines
7.7 KiB
Python

import data
import dashboard
from nicegui import app, ui
import re
import requests
import theme
# DB columns tasks(person, verse, verse_passage, status, awana_completed, awana_bonus)
db = data.CON
cur = db.cursor()
APIKEY = "Token f562cf2d890151d682065696dacdc0f86938a18e"
HEADERS = { 'Authorization': APIKEY}
card = "card"
@ui.page('/')
def index_page() -> None:
with theme.frame('Homepage'):
with ui.dialog().props('persistent') as addverse:
pass
with ui.grid(columns=1).classes('self-center justify-items-center content-center p-2 m-2 rounded-xl'):
toggle = ui.toggle(["Hannah", "Fiona", "Liam"], clearable=True, on_change=lambda: show_person(toggle))
with ui.row().classes('fixed bottom-0 left-0 p-2 m-2'):
with ui.element('q-fab').props('icon=navigation color=accent'):
ui.element('q-fab-action').props('icon=add color=secondary').on('click', lambda: add_verse(toggle))
ui.element('q-fab-action').props('icon=remove color=negative').on('click', lambda: remove_verse(toggle))
with ui.row().style('justify-content: center') as showperson:
pass
showperson.set_visibility(False)
# FEAT: Allow editing of the verse. Awana will sometimes only give the student part of a verse (i.e 1 John 4:14 is actually 14b).
# FEAT: Find how to pin/bind a verse to a second page
@ui.refreshable
def show_person(person):
showperson.clear()
if person.value is not None:
res = cur.execute(f"select verse,verse_passage,status from tasks where person='{person.value.lower()}'")
dbinfo = res.fetchall()
if dbinfo == []:
showperson.clear()
ui.notify(f"{person.value} doesn't have any verses saved under her name! Start adding some by clicking the green arrow in the bottom left.")
else:
showperson.set_visibility(True) #False if showperson.visible else True)
# showoptions.set_visibility(True)
if person.value == "Hannah":
setcolor = "rgba(0, 255, 0, .5)"
elif person.value == "Fiona":
setcolor = "rgba(255, 0, 0, .5)"
else:
setcolor = "rgba(0, 0, 255, .5)"
with showperson.classes(f'border-8').style(f'border: {setcolor} 1px solid;'):
with ui.grid(columns=5).classes('items-center w-full'):
ui.separator().classes('col-span-5 h-2')
for item in dbinfo:
label_verse = ui.label(text=item[0]).classes('hidden')
label_passage = ui.label(text=item[1]).classes('hidden')
label_status = ui.label(text=item[2]).classes('hidden')
ui.label(label_verse.text).classes('font-bold')
# ui.chip(label_verse.text, icon='ads_click', on_click=lambda: ui.notify(label_passage.text)).classes('border p-1')
ui.label(label_passage.text).classes('text-wrap')
if label_status.text == '0':
ui.chip("Incomplete", selectable=True, icon="add", color="negative", on_selection_change=lambda: toggle_completion(label_verse.text, person, status=1))
else:
ui.chip("Complete", selectable=True, icon="add", color="accent", on_selection_change=lambda: toggle_completion(label_verse.text, person, status=0))
ui.checkbox('Pin Verse')#.bind_visibility_from(card, 'value')
ui.checkbox('Mark as Completed')#.bind_value(item[2])
ui.separator().classes('col-span-5 h-2')
else:
showperson.clear()
def toggle_completion(verse, person, status):
ins = cur.execute(f"update tasks set status = '{status}' where person = '{person.value.lower()}' and verse = '{verse}'")
print(f"update tasks set status = '{status}' where person = '{person.value.lower()}' and verse = '{verse}'")
db.commit()
show_person.refresh
show_person(person)
def add_verse(person):
# TODO: Add check of existing verses so that a user can't add duplicates.
if person.value is None:
ui.notify("Oops! You haven't selected a person")
else:
addverse.open()
with addverse:
with ui.card().classes('flex-wrap items-center'):
result = ui.input(label="Add Verse Here")
with ui.row().classes('justify-content-center'):
ui.button().props('push glossy icon=add_circle color=secondary').on('click', lambda: submit_verse(result, person))
ui.button().props('push glossy icon=cancel color=negative').on('click', lambda: addverse.close())
def submit_verse(result, person):
# Check if Verse is already in db
dbcheck = cur.execute(f"select * from tasks where person = '{person.value.lower()}' and verse = '{result.value}';")
check_for_verse = dbcheck.fetchone()
if check_for_verse is not None:
ui.notify(f"{result.value} already exists for {person.value}! You can't have duplicates")
else:
# Verify the format of a Bible Verse
if not re.match(r'((^\d\s\w{1,}\s|^\w{1,}\s)(\d{1,2}:)(\d{1,2}-\d{1,2}|\d{1,2}))', result.value):
ui.notify("Verse was input incorrectly.")
addverse.clear()
else:
# Split up the string for later
colon = result.value.split(':')
precolon = colon[0].split(' ')[1].strip()
postcolon = colon[1].strip()
if '-' in postcolon:
start = postcolon.split('-')[0]
end = postcolon.split('-')[1]
else:
start = postcolon
# Get Verse Endpoint
url = f"https://api.esv.org/v3/passage/text/?q={result.value}"
response = requests.get(url, headers=HEADERS)
if response.status_code == 200 or response.status_code == 202:
vpass = response.json()
passage = str(vpass["passages"])
# npassage gets rid of any carriage return characters
npassage = passage.replace('\\n', '').strip()
# xpassage removes Footnotes section, if it exists
if 'Footnotes' in npassage:
xpassage = re.sub(r'Footnotes.*', '', npassage)
else:
xpassage = npassage.replace("(ESV)']", '')
# vpassage grabs the actual verses, dropping the title (starting from first verse in result)
print(xpassage)
vpassage = re.search(fr'\[{start}\].*', xpassage).group(0)
# zpassage - remove any parenthesis or brackets references
zpassage = re.sub(r'\[\d+\]|\(\d+\)|\s{2,}', '', vpassage).strip()
if re.match(r'^\', zpassage):
zpassage = f'{zpassage}'
else:
pass
print(zpassage)
else:
print(response.text)
ui.notify("Uh oh. Something went wrong.")
ins = cur.execute(f"replace into tasks values('{person.value.lower()}', '{result.value}', '{zpassage}', 0, 0, 'none');")
db.commit()
show_person(person)
def checked_data() -> None:
datavals = []
ui.run(storage_secret='b601785a-855c-41d1-adeb-68f0330d8186')