I feel like I have a good portion of the basic functionality of what I need so far include reading the db, updating db values, calling crossway's API for verses and parsing that payload. Styling leaves a lot to be desired still.
This commit is contained in:
@ -0,0 +1 @@
|
|||||||
|
{"verse1":"awd"}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
{"verse1":"verrrerese"}
|
||||||
BIN
__pycache__/api_router_example.cpython-312.pyc
Normal file
BIN
__pycache__/api_router_example.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/class_example.cpython-312.pyc
Normal file
BIN
__pycache__/class_example.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/data.cpython-312.pyc
Normal file
BIN
__pycache__/data.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/function_example.cpython-312.pyc
Normal file
BIN
__pycache__/function_example.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/home_page.cpython-312.pyc
Normal file
BIN
__pycache__/home_page.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/homepage.cpython-312.pyc
Normal file
BIN
__pycache__/homepage.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/menu.cpython-312.pyc
Normal file
BIN
__pycache__/menu.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/message.cpython-312.pyc
Normal file
BIN
__pycache__/message.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/theme.cpython-312.pyc
Normal file
BIN
__pycache__/theme.cpython-312.pyc
Normal file
Binary file not shown.
3
data.py
Normal file
3
data.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import sqlite3
|
||||||
|
|
||||||
|
CON = sqlite3.connect("./memorization_tasks.db")
|
||||||
55
homepage_sandbox.py
Normal file
55
homepage_sandbox.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
from nicegui import app,ui
|
||||||
|
import data
|
||||||
|
|
||||||
|
data = data.CON
|
||||||
|
cur = data.cursor()
|
||||||
|
|
||||||
|
def content() -> None:
|
||||||
|
with ui.grid(columns=1).classes('translate-x-5 p-2 m-2'):
|
||||||
|
toggle = ui.toggle(["Hannah", "Fiona", "Liam"], clearable=True, on_change=lambda: show_person(toggle)).props('vertical')
|
||||||
|
tog = ui.button('Hannah', on_click=lambda: show_person(tog)).props('vertical')
|
||||||
|
tog2 = ui.button('Fiona', on_click=lambda: show_person(tog2)).props('vertical')
|
||||||
|
tog3 = ui.button('Liam', on_click=lambda: show_person(tog3)).props('vertical')
|
||||||
|
with ui.row().classes('absolute bottom-0 left-0 p-2 m-2'):
|
||||||
|
with ui.element('q-fab').props('icon=navigation color=green'):
|
||||||
|
ui.element('q-fab-action').props('icon=add color=blue-5').on('click', lambda: add_verse(toggle))
|
||||||
|
ui.element('q-fab-action').props('icon=remove color=red-3').on('click', lambda: remove_verse(toggle))
|
||||||
|
with ui.row() as addverse:
|
||||||
|
ui.row()
|
||||||
|
|
||||||
|
def add_verse(toggle):
|
||||||
|
if toggle.value is None:
|
||||||
|
ui.notify("Oops! You haven't selected a person")
|
||||||
|
else:
|
||||||
|
with addverse:
|
||||||
|
with toggle:
|
||||||
|
ui.input(label="Add Verse Here")
|
||||||
|
result = ui.label()
|
||||||
|
ui.button().props('icon=book color=grey-5').on('click', lambda: submit_verse(result))
|
||||||
|
|
||||||
|
def submit_verse(result):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove_verse(toggle):
|
||||||
|
with ui.dialog() as dialog, ui.card():
|
||||||
|
ui.label('What verse would you like to add?')
|
||||||
|
|
||||||
|
def show_person(person):
|
||||||
|
ui.add_body_html("<div class=mainmain></div>")
|
||||||
|
if person.text is not None:
|
||||||
|
res = cur.execute(f"select verse,verse_passage,status from tasks where person='{person.text.lower()}'")
|
||||||
|
dbinfo = res.fetchall()
|
||||||
|
person.clear()
|
||||||
|
with ui.element('div').classes('flex-start'):
|
||||||
|
with person:
|
||||||
|
for item in dbinfo:
|
||||||
|
with ui.grid(columns=2):
|
||||||
|
ui.chip(item[0], icon='ads_click', on_click=lambda: ui.notify(item[1]))
|
||||||
|
ui.chip(item[2], selectable=True, icon="checkmark", color="green")
|
||||||
|
else:
|
||||||
|
person.clear()
|
||||||
|
|
||||||
|
# with addcard():
|
||||||
|
# verse = ui.input(label="Verse", placeholder="Verse")
|
||||||
|
# ui.button("Add")
|
||||||
|
# ui.button("Delete")
|
||||||
127
main.py
Normal file
127
main.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
import data
|
||||||
|
import homepage
|
||||||
|
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}
|
||||||
|
|
||||||
|
@ui.page('/')
|
||||||
|
def index_page() -> None:
|
||||||
|
with theme.frame('Homepage'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
with ui.grid(columns=1).classes('self-center justify-items-center content-center p-2 m-2'):
|
||||||
|
toggle = ui.toggle(["Hannah", "Fiona", "Liam"], clearable=True, on_change=lambda: show_person(toggle))
|
||||||
|
with ui.row().classes('absolute bottom-0 left-0 p-2 m-2'):
|
||||||
|
with ui.element('q-fab').props('icon=navigation color=green'):
|
||||||
|
ui.element('q-fab-action').props('icon=add color=blue-5').on('click', lambda: add_verse(toggle))
|
||||||
|
ui.element('q-fab-action').props('icon=remove color=red-3').on('click', lambda: remove_verse(toggle))
|
||||||
|
|
||||||
|
with ui.row().style('justify-content: center') as showperson:
|
||||||
|
pass
|
||||||
|
with ui.grid(columns=1).classes('grid gap-4 place-items-stretch') as showoptions:
|
||||||
|
optionstoggle = ui.toggle(["Completed", "Pin Verse"], clearable=True)
|
||||||
|
|
||||||
|
with ui.card().style('border: orange solid 3px').classes('flex self-center justify-self-auto') as addverse:
|
||||||
|
pass
|
||||||
|
|
||||||
|
showperson.set_visibility(False)
|
||||||
|
showoptions.set_visibility(False)
|
||||||
|
addverse.set_visibility(False)
|
||||||
|
|
||||||
|
@ui.refreshable
|
||||||
|
def show_person(person):
|
||||||
|
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)
|
||||||
|
with showperson:
|
||||||
|
with ui.grid(columns=3):
|
||||||
|
for item in dbinfo:
|
||||||
|
ui.chip(item[0], icon='ads_click', on_click=lambda: ui.notify(item[1]))
|
||||||
|
ui.label(item[1].title()).classes('text-wrap')
|
||||||
|
if item[2] == 0:
|
||||||
|
ui.chip("Incomplete", selectable=True, icon="add", color="orange", on_selection_change=lambda: toggle_completion(item[0], person, status=1))
|
||||||
|
else:
|
||||||
|
ui.chip("Complete", selectable=True, icon="add", color="green", on_selection_change=lambda: toggle_completion(item[0], person, status=0)).props('dark')
|
||||||
|
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}'")
|
||||||
|
# values('{person.value.lower()}', '{result.value}', '{zpassage}', 'incomplete', 'incomplete', 'none');")
|
||||||
|
db.commit()
|
||||||
|
# show_person(person)
|
||||||
|
|
||||||
|
|
||||||
|
def add_verse(person):
|
||||||
|
if person.value is None:
|
||||||
|
ui.notify("Oops! You haven't selected a person")
|
||||||
|
else:
|
||||||
|
addverse.set_visibility(True)
|
||||||
|
with addverse:
|
||||||
|
result = ui.input(label="Add Verse Here")
|
||||||
|
ui.button().props('icon=book color=grey-5').on('click', lambda: submit_verse(result, person))
|
||||||
|
|
||||||
|
def submit_verse(result, person):
|
||||||
|
# addverse.set_visibility(False)
|
||||||
|
print(result)
|
||||||
|
# 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"insert into tasks values('{person.value.lower()}', '{result.value}', '{zpassage}', 0, 0, 'none');")
|
||||||
|
db.commit()
|
||||||
|
show_person(person)
|
||||||
|
|
||||||
|
|
||||||
|
ui.run(storage_secret='b601785a-855c-41d1-adeb-68f0330d8186')
|
||||||
BIN
memorization_tasks.db
Normal file
BIN
memorization_tasks.db
Normal file
Binary file not shown.
13
test.py
Normal file
13
test.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from nicegui import ui
|
||||||
|
|
||||||
|
with ui.grid():
|
||||||
|
data = ui.button("Text")
|
||||||
|
#, on_click=lambda: show_element(data))
|
||||||
|
|
||||||
|
def show_element(data):
|
||||||
|
with ui.row():
|
||||||
|
ui.input(label="Add Text")
|
||||||
|
|
||||||
|
data.on_click(lambda: show_element(data))
|
||||||
|
|
||||||
|
ui.run()
|
||||||
17
theme.py
Normal file
17
theme.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from contextlib import contextmanager
|
||||||
|
from nicegui import ui
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def frame(navigation_title: str):
|
||||||
|
"""Custom page frame to share the same styling and behavior across all pages"""
|
||||||
|
ui.colors(primary='#6E93D6', secondary='#53B689', accent='#111B1E', positive='#53B689')
|
||||||
|
with ui.header():
|
||||||
|
ui.label('Awana Verse Practice').classes('font-bold')
|
||||||
|
ui.space()
|
||||||
|
ui.space()
|
||||||
|
ui.space()
|
||||||
|
ui.space()
|
||||||
|
ui.label(navigation_title)
|
||||||
|
with ui.column().classes('absolute-center items-center'):
|
||||||
|
yield
|
||||||
Reference in New Issue
Block a user