2024-10-04 19:50:45 -04:00
|
|
|
import data
|
2024-10-07 13:31:17 -04:00
|
|
|
import dashboard
|
2024-10-09 17:03:32 -04:00
|
|
|
from nicegui import ui
|
2024-10-04 19:50:45 -04:00
|
|
|
import re
|
|
|
|
|
import requests
|
|
|
|
|
import theme
|
2024-10-07 15:17:24 -04:00
|
|
|
from utils import Utils
|
2024-10-04 19:50:45 -04:00
|
|
|
|
2024-10-09 17:03:32 -04:00
|
|
|
# DB columns tasks(person, verse, verse_passage, status, awana_completed, awana_bonus, spark )
|
2024-10-04 19:50:45 -04:00
|
|
|
db = data.CON
|
|
|
|
|
cur = db.cursor()
|
|
|
|
|
APIKEY = "Token f562cf2d890151d682065696dacdc0f86938a18e"
|
2024-10-08 17:35:04 -04:00
|
|
|
HEADERS = {"Authorization": APIKEY}
|
2024-10-04 19:50:45 -04:00
|
|
|
|
2024-10-09 17:03:32 -04:00
|
|
|
@ui.page("/", dark=False)
|
2024-10-04 19:50:45 -04:00
|
|
|
def index_page() -> None:
|
2024-10-08 17:35:04 -04:00
|
|
|
with theme.frame("Homepage"):
|
|
|
|
|
firstload = Utils.get_unique_people()
|
|
|
|
|
if firstload is None:
|
|
|
|
|
with ui.dialog() as first_dialog, ui.card().classes("items-center"):
|
|
|
|
|
first_dialog.open()
|
|
|
|
|
ui.label(
|
|
|
|
|
"Looks like this is your first time! \n\n Please click the button below to add your first Awana club member."
|
|
|
|
|
).classes("text-center font-bold text-xl")
|
|
|
|
|
ui.button().props("push glossy icon=person_add color=secondary").on(
|
|
|
|
|
"click", lambda: addchild.open()
|
|
|
|
|
)
|
|
|
|
|
else:
|
2024-10-07 18:14:27 -04:00
|
|
|
pass
|
2024-10-04 19:50:45 -04:00
|
|
|
|
2024-10-08 17:35:04 -04:00
|
|
|
with ui.dialog().props("persistent") as addverse:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
with ui.dialog().props("persistent") as editverse:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
with ui.dialog() as addchild, ui.card().classes("items-center"):
|
2024-10-09 17:03:32 -04:00
|
|
|
result1 = ui.input(label="Clubber's Name")
|
|
|
|
|
result2 = ui.input(label="Awana Club")
|
2024-10-08 17:35:04 -04:00
|
|
|
ui.button().props("push glossy icon=add_circle color=secondary").on(
|
2024-10-09 17:03:32 -04:00
|
|
|
"click", lambda: add_person(result1, result2)
|
2024-10-08 17:35:04 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with ui.grid(columns=1).classes(
|
|
|
|
|
"self-center justify-items-center content-center p-2 m-2 rounded-xl"
|
2024-10-09 17:03:32 -04:00
|
|
|
) as pplrow:
|
2024-10-07 15:17:24 -04:00
|
|
|
users = Utils.get_unique_people()
|
|
|
|
|
for ppl in users:
|
|
|
|
|
pers = str(ppl)[2:-3].title()
|
2024-10-08 17:35:04 -04:00
|
|
|
users = [pers if x == ppl else x for x in users]
|
2024-10-07 15:17:24 -04:00
|
|
|
toggle = ui.toggle(users, clearable=True, on_change=lambda: show_person(toggle))
|
|
|
|
|
|
2024-10-08 17:35:04 -04:00
|
|
|
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)
|
|
|
|
|
)
|
|
|
|
|
ui.element("q-fab-action").props("icon=person_add color=positive").on(
|
|
|
|
|
"click", lambda: addchild.open()
|
|
|
|
|
)
|
|
|
|
|
ui.element("q-fab-action").props("icon=person_remove color=accent").on(
|
|
|
|
|
"click", lambda: ui.notify("Removing person is not set up yet")
|
|
|
|
|
)
|
2024-10-04 19:50:45 -04:00
|
|
|
|
2024-10-08 17:35:04 -04:00
|
|
|
with ui.row().style("justify-content: center") as showperson:
|
2024-10-04 19:50:45 -04:00
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
showperson.set_visibility(False)
|
|
|
|
|
|
|
|
|
|
@ui.refreshable
|
|
|
|
|
def show_person(person):
|
2024-10-05 16:39:30 -04:00
|
|
|
showperson.clear()
|
2024-10-08 17:35:04 -04:00
|
|
|
showperson.set_visibility(False)
|
2024-10-04 19:50:45 -04:00
|
|
|
if person.value is not None:
|
2024-10-07 15:17:24 -04:00
|
|
|
dbinfo = Utils.get_specific_person(person)
|
2024-10-04 19:50:45 -04:00
|
|
|
if dbinfo == []:
|
|
|
|
|
showperson.clear()
|
2024-10-08 17:35:04 -04:00
|
|
|
ui.notify(
|
|
|
|
|
f"{person.value} doesn't have any verses saved under their name! Start adding some by clicking the arrow in the bottom left."
|
|
|
|
|
)
|
|
|
|
|
elif dbinfo[0][1] == None:
|
|
|
|
|
pass
|
2024-10-04 19:50:45 -04:00
|
|
|
else:
|
2024-10-07 15:17:24 -04:00
|
|
|
showperson.set_visibility(True)
|
2024-10-07 13:31:17 -04:00
|
|
|
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)"
|
2024-10-09 17:03:32 -04:00
|
|
|
with showperson.classes("border-8").style(
|
2024-10-08 17:35:04 -04:00
|
|
|
f"border: {setcolor} 1px solid;"
|
|
|
|
|
):
|
|
|
|
|
with ui.grid(columns=5).classes(
|
|
|
|
|
"items-center w-full"
|
|
|
|
|
) as persontoggle:
|
|
|
|
|
ui.separator().classes("col-span-5 h-2")
|
2024-10-04 19:50:45 -04:00
|
|
|
for item in dbinfo:
|
2024-10-08 17:35:04 -04:00
|
|
|
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")
|
2024-10-09 17:03:32 -04:00
|
|
|
verssage = ui.label(text=f"{label_verse.text} - {label_passage.text}").classes("hidden")
|
2024-10-08 17:35:04 -04:00
|
|
|
ui.label(label_verse.text).classes("font-bold text-center")
|
2024-10-07 15:17:24 -04:00
|
|
|
with ui.row():
|
2024-10-08 17:35:04 -04:00
|
|
|
ui.label(label_passage.text).classes("text-wrap")
|
|
|
|
|
if label_status.text == "1":
|
|
|
|
|
ui.chip(
|
|
|
|
|
"Complete",
|
|
|
|
|
selectable=True,
|
|
|
|
|
icon="add",
|
|
|
|
|
color="tnt",
|
|
|
|
|
on_selection_change=lambda label_verse=label_verse: Utils.toggle_completion(
|
|
|
|
|
label_verse.text, person, status=0
|
|
|
|
|
),
|
|
|
|
|
on_click=lambda: show_person(person),
|
|
|
|
|
).classes("text-white")
|
2024-10-04 19:50:45 -04:00
|
|
|
else:
|
2024-10-08 17:35:04 -04:00
|
|
|
ui.chip(
|
|
|
|
|
"Incomplete",
|
|
|
|
|
selectable=True,
|
|
|
|
|
icon="add",
|
|
|
|
|
color="sparks",
|
|
|
|
|
on_selection_change=lambda label_verse=label_verse: Utils.toggle_completion(
|
|
|
|
|
label_verse.text, person, status=1
|
|
|
|
|
),
|
|
|
|
|
on_click=lambda: show_person(person),
|
|
|
|
|
).classes("text-white")
|
|
|
|
|
ui.chip(
|
|
|
|
|
"Edit Verse",
|
|
|
|
|
selectable=True,
|
|
|
|
|
icon="edit",
|
|
|
|
|
color="cubbies",
|
2024-10-09 17:03:32 -04:00
|
|
|
on_selection_change=lambda verssage=verssage: edit_verse(
|
|
|
|
|
verssage, person
|
2024-10-08 17:35:04 -04:00
|
|
|
),
|
|
|
|
|
).classes("text-white")
|
|
|
|
|
ui.chip(
|
|
|
|
|
"Delete Verse",
|
|
|
|
|
selectable=True,
|
|
|
|
|
color="red",
|
|
|
|
|
icon="delete",
|
|
|
|
|
on_selection_change=lambda label_verse=label_verse: Utils.delete_verse(
|
|
|
|
|
label_verse.text, person
|
|
|
|
|
),
|
|
|
|
|
on_click=lambda: show_person(person),
|
|
|
|
|
).classes("text-white").style('color: white;')
|
|
|
|
|
ui.separator().classes("col-span-5 h-2")
|
2024-10-04 19:50:45 -04:00
|
|
|
else:
|
|
|
|
|
showperson.clear()
|
2024-10-07 18:14:27 -04:00
|
|
|
addverse.close()
|
2024-10-04 19:50:45 -04:00
|
|
|
|
2024-10-09 17:03:32 -04:00
|
|
|
def remove_verse():
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def edit_verse(verssage, person):
|
|
|
|
|
editverse.clear()
|
2024-10-07 18:14:27 -04:00
|
|
|
editverse.open()
|
2024-10-09 17:03:32 -04:00
|
|
|
verse = verssage.text.split('-')[0].strip()
|
|
|
|
|
passage = verssage.text.split('-')[1]
|
2024-10-07 18:14:27 -04:00
|
|
|
with editverse:
|
2024-10-08 17:35:04 -04:00
|
|
|
with ui.card().classes("flex-wrap items-center"):
|
|
|
|
|
ui.label("Here's the verse for easier copy & paste:")
|
2024-10-09 17:03:32 -04:00
|
|
|
ui.label(passage).classes('text-center')
|
|
|
|
|
ui.label(verse)
|
|
|
|
|
editing = ui.textarea(label="Edit below").classes('center')
|
2024-10-08 17:35:04 -04:00
|
|
|
with ui.row().classes("justify-content-center"):
|
|
|
|
|
ui.button().props("push glossy icon=add_circle color=secondary").on(
|
|
|
|
|
"click", lambda: edit_submit_verse(person, editing, verse)
|
|
|
|
|
)
|
2024-10-09 17:03:32 -04:00
|
|
|
ui.button().props("push glossy icon=cancel color=sparks").on('click', lambda: editverse.close())
|
|
|
|
|
|
|
|
|
|
def edit_submit_verse(person, passage, verse):
|
|
|
|
|
Utils.edit_verse(person, verse, passage)
|
|
|
|
|
editverse.close()
|
|
|
|
|
show_person(person)
|
2024-10-04 19:50:45 -04:00
|
|
|
|
|
|
|
|
def add_verse(person):
|
|
|
|
|
if person.value is None:
|
|
|
|
|
ui.notify("Oops! You haven't selected a person")
|
|
|
|
|
else:
|
2024-10-05 16:39:30 -04:00
|
|
|
addverse.open()
|
2024-10-04 19:50:45 -04:00
|
|
|
with addverse:
|
2024-10-08 17:35:04 -04:00
|
|
|
with ui.card().classes("flex-wrap items-center"):
|
2024-10-05 16:39:30 -04:00
|
|
|
result = ui.input(label="Add Verse Here")
|
2024-10-08 17:35:04 -04:00
|
|
|
with ui.row().classes("justify-content-center"):
|
|
|
|
|
ui.button().props(
|
|
|
|
|
"push glossy icon=add_circle color=secondary"
|
2024-10-09 17:03:32 -04:00
|
|
|
).on("click", lambda: (submit_verse(result, person), addverse.close()))
|
2024-10-08 17:35:04 -04:00
|
|
|
ui.button().props("push glossy icon=cancel color=negative").on(
|
|
|
|
|
"click", lambda: addverse.close()
|
|
|
|
|
)
|
|
|
|
|
|
2024-10-04 19:50:45 -04:00
|
|
|
|
|
|
|
|
def submit_verse(result, person):
|
2024-10-07 13:31:17 -04:00
|
|
|
# Check if Verse is already in db
|
2024-10-08 17:35:04 -04:00
|
|
|
dbcheck = cur.execute(
|
|
|
|
|
f"select * from tasks where person = '{person.value}' and verse = '{result.value}';"
|
|
|
|
|
)
|
2024-10-07 13:31:17 -04:00
|
|
|
check_for_verse = dbcheck.fetchone()
|
|
|
|
|
if check_for_verse is not None:
|
2024-10-08 17:35:04 -04:00
|
|
|
ui.notify(
|
|
|
|
|
f"{result.value} already exists for {person.value}! You can't have duplicates"
|
|
|
|
|
)
|
2024-10-04 19:50:45 -04:00
|
|
|
else:
|
2024-10-07 13:31:17 -04:00
|
|
|
# Verify the format of a Bible Verse
|
2024-10-08 17:35:04 -04:00
|
|
|
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,
|
|
|
|
|
):
|
2024-10-07 13:31:17 -04:00
|
|
|
ui.notify("Verse was input incorrectly.")
|
2024-10-07 18:14:27 -04:00
|
|
|
addverse.close()
|
2024-10-04 19:50:45 -04:00
|
|
|
else:
|
2024-10-07 13:31:17 -04:00
|
|
|
# Split up the string for later
|
2024-10-08 17:35:04 -04:00
|
|
|
colon = result.value.split(":")
|
|
|
|
|
precolon = colon[0].split(" ")[1].strip()
|
2024-10-07 13:31:17 -04:00
|
|
|
postcolon = colon[1].strip()
|
2024-10-08 17:35:04 -04:00
|
|
|
if "-" in postcolon:
|
|
|
|
|
start = postcolon.split("-")[0]
|
|
|
|
|
end = postcolon.split("-")[1]
|
2024-10-04 19:50:45 -04:00
|
|
|
else:
|
2024-10-07 13:31:17 -04:00
|
|
|
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
|
2024-10-08 17:35:04 -04:00
|
|
|
npassage = passage.replace("\\n", "").strip()
|
2024-10-07 13:31:17 -04:00
|
|
|
# xpassage removes Footnotes section, if it exists
|
2024-10-08 17:35:04 -04:00
|
|
|
if "Footnotes" in npassage:
|
|
|
|
|
xpassage = re.sub(r"Footnotes.*", "", npassage)
|
2024-10-07 13:31:17 -04:00
|
|
|
else:
|
2024-10-08 17:35:04 -04:00
|
|
|
xpassage = npassage.replace("(ESV)']", "")
|
2024-10-07 13:31:17 -04:00
|
|
|
# vpassage grabs the actual verses, dropping the title (starting from first verse in result)
|
2024-10-08 17:35:04 -04:00
|
|
|
vpassage = re.search(rf"\[{start}\].*", xpassage).group(0)
|
2024-10-07 13:31:17 -04:00
|
|
|
# zpassage - remove any parenthesis or brackets references
|
2024-10-08 17:35:04 -04:00
|
|
|
zpassage = re.sub(r"\[\d+\]|\(\d+\)|\s{2,}", "", vpassage).strip()
|
|
|
|
|
if re.match(r"^\“", zpassage):
|
|
|
|
|
zpassage = f"{zpassage}”"
|
2024-10-07 13:31:17 -04:00
|
|
|
else:
|
|
|
|
|
pass
|
2024-10-04 19:50:45 -04:00
|
|
|
else:
|
2024-10-07 13:31:17 -04:00
|
|
|
ui.notify("Uh oh. Something went wrong.")
|
2024-10-04 19:50:45 -04:00
|
|
|
|
2024-10-09 17:03:32 -04:00
|
|
|
Utils.add_verse(person, result, zpassage)
|
2024-10-07 13:31:17 -04:00
|
|
|
show_person(person)
|
2024-10-04 19:50:45 -04:00
|
|
|
|
2024-10-09 17:03:32 -04:00
|
|
|
def add_person(person, club):
|
2024-10-08 17:35:04 -04:00
|
|
|
check_person = Utils.get_specific_person(person)
|
|
|
|
|
if check_person == []:
|
2024-10-09 17:03:32 -04:00
|
|
|
Utils.add_person(person, club)
|
2024-10-08 17:35:04 -04:00
|
|
|
addchild.close()
|
|
|
|
|
else:
|
|
|
|
|
ui.notify(
|
|
|
|
|
f"The name {person.value} already exists. Please add someone else"
|
|
|
|
|
)
|
2024-10-09 17:03:32 -04:00
|
|
|
show_person(person)
|
2024-10-04 19:50:45 -04:00
|
|
|
|
2024-10-08 17:35:04 -04:00
|
|
|
ui.run(storage_secret="b601785a-855c-41d1-adeb-68f0330d8186")
|