From e3672c4b143fcd5a62bf743f50973cfd9488ec35 Mon Sep 17 00:00:00 2001 From: Ignace Date: Fri, 9 Jan 2026 17:30:28 +0100 Subject: [PATCH] back-end communication set up, base screen implemented --- src/justgetit/app.py | 6 ++-- src/justgetit/backend.py | 52 ++++++++++++++++++++++++++++++++++ src/justgetit/basepage.py | 49 ++++++++++++++++++++++++++++---- src/justgetit/login.py | 40 ++++++++++---------------- src/justgetit/providekey.py | 46 ++++++++++-------------------- src/justgetit/register.py | 56 +++++++++++++++++-------------------- 6 files changed, 156 insertions(+), 93 deletions(-) create mode 100644 src/justgetit/backend.py diff --git a/src/justgetit/app.py b/src/justgetit/app.py index 8f6572b..183a412 100644 --- a/src/justgetit/app.py +++ b/src/justgetit/app.py @@ -7,13 +7,14 @@ from justgetit.register import Register from justgetit.configuration import Configuration from justgetit.providekey import ProvideKey from justgetit.lists import Lists - +from justgetit.backend import BackEnd class JustEatIt(toga.App): login_screen = toga.Box() register_screen = toga.Box() providekey_screen = toga.Box() lists_screen = toga.Box() + backend = None configuration = None last_screen_width = SCREENWIDTH @@ -38,6 +39,7 @@ class JustEatIt(toga.App): self.register_screen = Register() self.providekey_screen = ProvideKey() self.lists_screen = Lists() + self.backend = BackEnd(self) self.main_window = toga.MainWindow(title=self.formal_name) @@ -65,7 +67,7 @@ class JustEatIt(toga.App): if width < SCREENWIDTH: # Phone-like: fill available width - elf.last_screen_width = width + self.last_screen_width = width else: self.last_screen_width = SCREENWIDTH # set actie screen to the corre ct width diff --git a/src/justgetit/backend.py b/src/justgetit/backend.py new file mode 100644 index 0000000..12ef4ca --- /dev/null +++ b/src/justgetit/backend.py @@ -0,0 +1,52 @@ +from justgetit.constants import * +import httpx +import json +import toga + + +class BackEnd(): + """ + This is the interface for the backend. + Its a bit over the top to subclass it from a widget, but this way it has access to the app + """ + application = None + + def __init__(self, app): + self.application = app + + + async def post(self, endpoint, parameters, callback): + """ + Call the server, always with a POST, for a specific endpoint and the parameters + in the body + + :param endpoint: the endpoint without /api/ (no slashes) + :param parameters: A dict with the parameters for the call + :param callback: def in the calling function to return to + """ + self.status = 0 + self.payload = None + if len(endpoint)>2: + try: + async with httpx.AsyncClient() as client: + response = await client.post(f"{API}/{endpoint}", data=parameters) + self.payload = response.json() + self.status = int(self.payload['status']) + print(f" payload {self.payload}") + except httpx.RequestError as exc: + self.status = -2 + + # status 2 means we are in offline mode + if self.status == -2: + pass + elif self.status == 0: + await self.application.main_window.dialog( + toga.InfoDialog("Oops", self.payload['message']) + ) + elif self.status == 2: + await self.application.main_window.dialog( + toga.InfoDialog("Thank you", self.payload['message']) + ) + + callback(parameters, self.payload) + diff --git a/src/justgetit/basepage.py b/src/justgetit/basepage.py index 9d778a6..0d4e912 100644 --- a/src/justgetit/basepage.py +++ b/src/justgetit/basepage.py @@ -1,6 +1,6 @@ import toga from toga.style import Pack -from toga.style.pack import COLUMN, ROW, END, START, CENTER, HIDDEN, JUSTIFY +from toga.style.pack import COLUMN, ROW, END, START, CENTER, HIDDEN, VISIBLE, JUSTIFY # from justgetit.constants import SCREENHEIGHT, SCREENWIDTH import asyncio from justgetit.constants import * @@ -67,6 +67,43 @@ class BasePage(toga.Box): ) ) + + # the warning text box + self.warningtext = toga.Label("warning here", + style=Pack(margin=10, + background_color="#eee", + text_align=JUSTIFY) + ) + + warningline_inner = toga.Box( + children = [self.warningtext], + style=Pack( + direction=COLUMN, + justify_content=CENTER, + margin=2, + background_color="#eee" + ) + ) + + self.warningline_outer = toga.Box( + children = [warningline_inner], + style=Pack( + direction=COLUMN, + justify_content=CENTER, + margin=24, + background_color="#ccc", + ) + ) + + self.warning_placeholder = toga.Box( + style=Pack( + height=1, + width=1 + ) + ) + + self.warning_box = self.warning_placeholder + # add image if self.page_pngimage: center_image = toga.Image(f"images/{self.page_pngimage}.png") @@ -79,6 +116,7 @@ class BasePage(toga.Box): # wrapping up the page elements header liner and body self.add(menu_bar_outer) self.add(liner) + self.add(self.warning_box) self.add(self.content_box) self.style=Pack( direction=COLUMN, @@ -95,7 +133,8 @@ class BasePage(toga.Box): """ self.content_box.style.width = w - async def dialog(self, widget, **kwargs): - ask_a_question = toga.InfoDialog( - "Help", - "some text") + async def display_warning(self, message): + self.warningtext.text = message + self.warning_box = self.warningline_outer + await asyncio.sleep(5) + self.warning_box = self.warning_placeholder \ No newline at end of file diff --git a/src/justgetit/login.py b/src/justgetit/login.py index 46beaa5..7422c7e 100644 --- a/src/justgetit/login.py +++ b/src/justgetit/login.py @@ -66,33 +66,23 @@ class Login(BasePage): self.content_box.add(self.password_input) self.content_box.add(save_button_box) + def goto_registration(self, dummy): + self.app.goto_next_page_by_name(PAGE_REGISTER) + async def login_button_pressed(self, widget): - self.result = 0 - self.message = '' user = self.name_input.value pwd = self.password_input.value - if len(user)>0 and len(pwd)>0: - data = {'user': user, 'password': pwd} - try: - async with httpx.AsyncClient() as client: - response = await client.post(API+'/login', data=data) - payload = response.json() - print(payload) - self.result = int(payload['status']) - if 'message' in payload: - self.message = payload['message'] - except httpx.RequestError as exc: - self.result = -2 + if len(user)>1 and len(pwd)>1: + parameters = {} + parameters['user'] = user + parameters['password'] = pwd + await self.app.backend.post('login', parameters, self.after_backend_login) + + def after_backend_login(self, parameters, return_data): + if return_data['status'] > 0: + # store login etc in config + self.app.configuration.store_login(parameters['user'], parameters['password']) + # goto lists screen + self.app.goto_next_page_by_name(PAGE_LISTS) - if self.result == 1: - # store login etc in config - self.app.configuration.store_login(user, pwd) - # goto lists screen - self.app.goto_next_page_by_name(PAGE_LISTS) - else: - await self.app.main_window.dialog( - toga.InfoDialog("Login error", self.message) - ) - def goto_registration(self, dummy): - self.app.goto_next_page_by_name(PAGE_REGISTER) \ No newline at end of file diff --git a/src/justgetit/providekey.py b/src/justgetit/providekey.py index 32d52e9..5fb9d61 100644 --- a/src/justgetit/providekey.py +++ b/src/justgetit/providekey.py @@ -53,40 +53,11 @@ class ProvideKey(BasePage): ) ) - # # the help text box - # self.helptext = toga.Label(HELP_ON_KEY, - # style=Pack(margin=10, - # background_color="#eee", - # text_align=JUSTIFY) - # ) - - # self.helpbox_inner = toga.Box( - # children = [self.helptext], - # style=Pack( - # direction=COLUMN, - # justify_content=CENTER, - # margin=2, - # background_color="#eee" - # ) - # ) - - # self.helpbox = toga.Box( - # children = [self.helpbox_inner], - # style=Pack( - # direction=COLUMN, - # justify_content=CENTER, - # margin=24, - # background_color="#ccc", - # visibility=HIDDEN - # ) - # ) - - # wrapping up the windows elements self.content_box.add(self.app_key) self.content_box.add(save_button_box) - async def save_button_pressed(self, widget): + async def save_button_pressed__(self, widget): self.result = 0 print(self.app_key.value) if len(self.app_key.value)>1: @@ -125,4 +96,17 @@ class ProvideKey(BasePage): if await self.app.main_window.dialog(ask_a_question): print("The user said yes!") else: - print("The user said no.") \ No newline at end of file + print("The user said no.") + + async def save_button_pressed(self, widget): + if len(self.app_key.value)>1: + parameters = {} + parameters['key'] = self.app_key.value + await self.app.backend.post('validate_key', parameters, self.after_backend_validation) + + def after_backend_validation(self, parameters, return_data): + if return_data['status'] > 0: + self.app.configuration.store_app_key(parameters['key']) + # goto login screen + self.app.goto_next_page_by_name(PAGE_LOGIN) + diff --git a/src/justgetit/register.py b/src/justgetit/register.py index 0c0cf2e..66ccc4d 100644 --- a/src/justgetit/register.py +++ b/src/justgetit/register.py @@ -28,7 +28,7 @@ class Register(BasePage): # Name input self.name_input = toga.TextInput( - placeholder="Could be you here", + placeholder="Are you in for this?", style=Pack( width=250, margin_bottom=10 @@ -36,12 +36,21 @@ class Register(BasePage): ) # Password input self.password_input = toga.PasswordInput( - placeholder="Feeling lucky?", + placeholder="Trust me with your secret?", style=Pack( width=250, margin_bottom=20 ) ) + # Password input validation + self.password_input_validation = toga.PasswordInput( + placeholder="...and again?", + style=Pack( + width=250, + margin_bottom=20 + ) + ) + # Save button save_button = toga.Button( icon=toga.Icon("images/save"), @@ -64,43 +73,30 @@ class Register(BasePage): # wrapping up the windows elements self.content_box.add(self.name_input) self.content_box.add(self.password_input) + self.content_box.add(self.password_input_validation) self.content_box.add(save_button_box) + def goto_login(self, dummy): + self.app.goto_next_page_by_name(PAGE_LOGIN) async def register_button_pressed(self, widget): - self.result = 0 - self.message = '' user = self.name_input.value pwd = self.password_input.value - pwd2 = self.password_verify_input.value + pwd2 = self.password_input_validation.value if len(user)>0 and len(pwd)>0 and len(pwd2)>0: if pwd==pwd2: - data = {'user': user, 'password': pwd} - try: - async with httpx.AsyncClient() as client: - response = await client.post(API+'/register', data=data) - payload = response.json() - print(payload) - self.result = int(payload['status']) - if 'message' in payload: - self.message = payload['message'] - except httpx.RequestError as exc: - self.result = -2 - - if self.result == 1: - # store login etc in config - self.app.configuration.store_login(user, pwd) - # goto lists screen - self.app.goto_next_page_by_name(PAGE_LOGIN) - else: - await self.app.main_window.dialog( - toga.InfoDialog("Registration error", self.message) - ) - + parameters = {} + parameters['user'] = user + parameters['password'] = pwd + await self.app.backend.post('register', parameters, self.after_backend_registration) else: await self.app.main_window.dialog( - toga.InfoDialog("Error", "Passwords do not match") + toga.InfoDialog("Error", "Passwords do not match.") ) - def goto_login(self, dummy): - self.app.goto_next_page_by_name(PAGE_LOGIN) \ No newline at end of file + + def after_backend_registration(self, parameters, return_data): + if int(return_data['status']) > 0: + print("registraiton ok") + # self.display_warning("Registration Ok. Awaiting Approval") + self.app.goto_next_page_by_name(PAGE_LOGIN)