commit d36add7f35729930a22f3d4b1647d8ad8c848124 Author: Norm Rasmussen Date: Fri Oct 4 19:50:45 2024 -0400 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. diff --git a/.nicegui/storage-user-49b0ee78-be7d-47ba-b563-92a7e4abfd3b.json b/.nicegui/storage-user-49b0ee78-be7d-47ba-b563-92a7e4abfd3b.json new file mode 100644 index 0000000..6775373 --- /dev/null +++ b/.nicegui/storage-user-49b0ee78-be7d-47ba-b563-92a7e4abfd3b.json @@ -0,0 +1 @@ +{"verse1":"awd"} \ No newline at end of file diff --git a/.nicegui/storage-user-dd4c0206-2f4e-4910-ad64-981a2b3a4289.json b/.nicegui/storage-user-dd4c0206-2f4e-4910-ad64-981a2b3a4289.json new file mode 100644 index 0000000..b0b31ba --- /dev/null +++ b/.nicegui/storage-user-dd4c0206-2f4e-4910-ad64-981a2b3a4289.json @@ -0,0 +1 @@ +{"verse1":"verrrerese"} \ No newline at end of file diff --git a/__pycache__/api_router_example.cpython-312.pyc b/__pycache__/api_router_example.cpython-312.pyc new file mode 100644 index 0000000..d492e4c Binary files /dev/null and b/__pycache__/api_router_example.cpython-312.pyc differ diff --git a/__pycache__/class_example.cpython-312.pyc b/__pycache__/class_example.cpython-312.pyc new file mode 100644 index 0000000..70db527 Binary files /dev/null and b/__pycache__/class_example.cpython-312.pyc differ diff --git a/__pycache__/data.cpython-312.pyc b/__pycache__/data.cpython-312.pyc new file mode 100644 index 0000000..03ebb91 Binary files /dev/null and b/__pycache__/data.cpython-312.pyc differ diff --git a/__pycache__/function_example.cpython-312.pyc b/__pycache__/function_example.cpython-312.pyc new file mode 100644 index 0000000..2f0682a Binary files /dev/null and b/__pycache__/function_example.cpython-312.pyc differ diff --git a/__pycache__/home_page.cpython-312.pyc b/__pycache__/home_page.cpython-312.pyc new file mode 100644 index 0000000..d8dd283 Binary files /dev/null and b/__pycache__/home_page.cpython-312.pyc differ diff --git a/__pycache__/homepage.cpython-312.pyc b/__pycache__/homepage.cpython-312.pyc new file mode 100644 index 0000000..1823f9d Binary files /dev/null and b/__pycache__/homepage.cpython-312.pyc differ diff --git a/__pycache__/menu.cpython-312.pyc b/__pycache__/menu.cpython-312.pyc new file mode 100644 index 0000000..946505d Binary files /dev/null and b/__pycache__/menu.cpython-312.pyc differ diff --git a/__pycache__/message.cpython-312.pyc b/__pycache__/message.cpython-312.pyc new file mode 100644 index 0000000..4913ca0 Binary files /dev/null and b/__pycache__/message.cpython-312.pyc differ diff --git a/__pycache__/theme.cpython-312.pyc b/__pycache__/theme.cpython-312.pyc new file mode 100644 index 0000000..f17a4ad Binary files /dev/null and b/__pycache__/theme.cpython-312.pyc differ diff --git a/data.py b/data.py new file mode 100644 index 0000000..cc5a3d3 --- /dev/null +++ b/data.py @@ -0,0 +1,3 @@ +import sqlite3 + +CON = sqlite3.connect("./memorization_tasks.db") diff --git a/homepage_sandbox.py b/homepage_sandbox.py new file mode 100644 index 0000000..1ca7072 --- /dev/null +++ b/homepage_sandbox.py @@ -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("
") + 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") diff --git a/main.py b/main.py new file mode 100644 index 0000000..728cf0f --- /dev/null +++ b/main.py @@ -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') diff --git a/memorization_tasks.db b/memorization_tasks.db new file mode 100644 index 0000000..9f484f4 Binary files /dev/null and b/memorization_tasks.db differ diff --git a/test.py b/test.py new file mode 100644 index 0000000..196c50b --- /dev/null +++ b/test.py @@ -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() diff --git a/theme.py b/theme.py new file mode 100644 index 0000000..c6ca66d --- /dev/null +++ b/theme.py @@ -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