prerelease of list from serrver-db
This commit is contained in:
@@ -8,6 +8,7 @@ from justgetit.configuration import Configuration
|
|||||||
from justgetit.providekey import ProvideKey
|
from justgetit.providekey import ProvideKey
|
||||||
from justgetit.lists import Lists
|
from justgetit.lists import Lists
|
||||||
from justgetit.backend import BackEnd
|
from justgetit.backend import BackEnd
|
||||||
|
from justgetit.localdata import LocalData
|
||||||
|
|
||||||
class JustEatIt(toga.App):
|
class JustEatIt(toga.App):
|
||||||
login_screen = toga.Box()
|
login_screen = toga.Box()
|
||||||
@@ -34,6 +35,7 @@ class JustEatIt(toga.App):
|
|||||||
|
|
||||||
def startup(self):
|
def startup(self):
|
||||||
self.configuration = Configuration(self)
|
self.configuration = Configuration(self)
|
||||||
|
self.data = LocalData(self)
|
||||||
|
|
||||||
self.login_screen = Login()
|
self.login_screen = Login()
|
||||||
self.register_screen = Register()
|
self.register_screen = Register()
|
||||||
@@ -62,6 +64,7 @@ class JustEatIt(toga.App):
|
|||||||
if self.last_screen_width > 0:
|
if self.last_screen_width > 0:
|
||||||
page.set_screen_width(self.last_screen_width)
|
page.set_screen_width(self.last_screen_width)
|
||||||
self.main_window.content = page
|
self.main_window.content = page
|
||||||
|
page.on_show()
|
||||||
|
|
||||||
def on_resize(self, widget, **kwargs):
|
def on_resize(self, widget, **kwargs):
|
||||||
width = self.main_window.size.width
|
width = self.main_window.size.width
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
from justgetit.constants import *
|
from justgetit.constants import *
|
||||||
import httpx
|
import httpx
|
||||||
import json
|
|
||||||
import toga
|
import toga
|
||||||
|
|
||||||
|
|
||||||
class BackEnd():
|
class BackEnd():
|
||||||
"""
|
"""
|
||||||
This is the interface for the backend.
|
This is the interface for the backend.
|
||||||
@@ -32,7 +30,6 @@ class BackEnd():
|
|||||||
response = await client.post(f"{API}/{endpoint}", data=parameters)
|
response = await client.post(f"{API}/{endpoint}", data=parameters)
|
||||||
self.payload = response.json()
|
self.payload = response.json()
|
||||||
self.status = int(self.payload['status'])
|
self.status = int(self.payload['status'])
|
||||||
print(f" payload {self.payload}")
|
|
||||||
except httpx.RequestError as exc:
|
except httpx.RequestError as exc:
|
||||||
self.status = -2
|
self.status = -2
|
||||||
|
|
||||||
@@ -50,3 +47,24 @@ class BackEnd():
|
|||||||
|
|
||||||
callback(parameters, self.payload)
|
callback(parameters, self.payload)
|
||||||
|
|
||||||
|
def postwait(self, endpoint, parameters):
|
||||||
|
"""
|
||||||
|
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:
|
||||||
|
response = httpx.post(f"{API}/{endpoint}", data=parameters)
|
||||||
|
self.payload = response.json()
|
||||||
|
self.status = int(self.payload['status'])
|
||||||
|
except httpx.RequestError as exc:
|
||||||
|
self.status = -2
|
||||||
|
|
||||||
|
return self.payload
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ class BasePage(toga.Box):
|
|||||||
justify_content=START,
|
justify_content=START,
|
||||||
margin=24,
|
margin=24,
|
||||||
flex=1,
|
flex=1,
|
||||||
background_color="yellow"
|
# background_color="yellow"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -136,6 +136,9 @@ class BasePage(toga.Box):
|
|||||||
if w>0:
|
if w>0:
|
||||||
self.content_box.style.width = w
|
self.content_box.style.width = w
|
||||||
|
|
||||||
|
def on_show(self):
|
||||||
|
print("new page shown")
|
||||||
|
|
||||||
async def display_warning(self, message):
|
async def display_warning(self, message):
|
||||||
self.warningtext.text = message
|
self.warningtext.text = message
|
||||||
self.warning_box = self.warningline_outer
|
self.warning_box = self.warningline_outer
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ class Configuration():
|
|||||||
This class holds persistent configuration:
|
This class holds persistent configuration:
|
||||||
- appkey: the app key, alowing traffic with the backend
|
- appkey: the app key, alowing traffic with the backend
|
||||||
- last_key_validation_date: last date the appkey was validated, should be no more than a week ago otherwise the app will not run
|
- last_key_validation_date: last date the appkey was validated, should be no more than a week ago otherwise the app will not run
|
||||||
- username: the user name
|
- user: the user as a dict
|
||||||
- userpwd: the users pwd
|
|
||||||
- userlang: the users language
|
- userlang: the users language
|
||||||
- lastlogin_date: date of last sucessful login
|
- lastlogin_date: date of last sucessful login
|
||||||
"""
|
"""
|
||||||
@@ -39,7 +38,6 @@ class Configuration():
|
|||||||
def has_valid_app_key(self):
|
def has_valid_app_key(self):
|
||||||
return True
|
return True
|
||||||
if 'appkey' in self.data:
|
if 'appkey' in self.data:
|
||||||
print("found app key {self.data['appkey']}")
|
|
||||||
today = datetime.date.today()
|
today = datetime.date.today()
|
||||||
last_month = today - datetime.timedelta(days=30)
|
last_month = today - datetime.timedelta(days=30)
|
||||||
if self.data['last_key_validation_date'] > last_month:
|
if self.data['last_key_validation_date'] > last_month:
|
||||||
@@ -53,9 +51,9 @@ class Configuration():
|
|||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def user_is_logged_in(self):
|
def user_is_logged_in(self):
|
||||||
return True
|
# return True
|
||||||
if 'username' in self.data:
|
if 'user' in self.data:
|
||||||
print("found user {self.data['username']}")
|
print(f"found user {self.data['user']['name']}")
|
||||||
today = datetime.date.today()
|
today = datetime.date.today()
|
||||||
last_week = today - datetime.timedelta(days=7)
|
last_week = today - datetime.timedelta(days=7)
|
||||||
if self.data['lastlogin_date'] > last_week:
|
if self.data['lastlogin_date'] > last_week:
|
||||||
@@ -63,9 +61,8 @@ class Configuration():
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def store_login(self, user, pwd):
|
def store_login(self, user_dict):
|
||||||
self.data['username'] = user
|
self.data['user'] = user_dict
|
||||||
self.data['userpwd'] = pwd
|
|
||||||
self.data['lastlogin_date'] = datetime.date.today()
|
self.data['lastlogin_date'] = datetime.date.today()
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
@@ -75,7 +72,13 @@ class Configuration():
|
|||||||
self.data['lastlogin_date'] = today
|
self.data['lastlogin_date'] = today
|
||||||
|
|
||||||
def logout_user(self):
|
def logout_user(self):
|
||||||
self.data.pop('username', None)
|
self.data.pop('user', None)
|
||||||
self.data.pop('userpwd', None)
|
|
||||||
self.data.pop('lastlogin_date', None)
|
self.data.pop('lastlogin_date', None)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
def get_userid(self):
|
||||||
|
result = 0
|
||||||
|
if 'user' in self.data:
|
||||||
|
print()
|
||||||
|
result = self.data['user']['id']
|
||||||
|
return result
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
+99
-7
@@ -1,11 +1,90 @@
|
|||||||
import toga
|
import toga
|
||||||
from toga.style import Pack
|
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, JUSTIFY
|
||||||
# from justgetit.constants import SCREENHEIGHT, SCREENWIDTH
|
from toga.sources import ListSource, Listener
|
||||||
import asyncio
|
import datetime
|
||||||
from justgetit.constants import *
|
from justgetit.constants import *
|
||||||
from justgetit.basepage import BasePage
|
from justgetit.basepage import BasePage
|
||||||
|
|
||||||
|
class DatabaseList(toga.Box):
|
||||||
|
def __init__(self, id=None, style=None, children=None, **kwargs):
|
||||||
|
style.direction = COLUMN
|
||||||
|
super().__init__(id, style, children, **kwargs)
|
||||||
|
self.data = ListSource(
|
||||||
|
accessors=["id", "owner_user_id", "name", "is_active"]
|
||||||
|
)
|
||||||
|
self.data.add_listener(DatabaseList.DataListener(self))
|
||||||
|
|
||||||
|
class DataListener(Listener):
|
||||||
|
# listen to the database
|
||||||
|
def __init__(self, parent_widget):
|
||||||
|
print("widget: data-item init")
|
||||||
|
self.parent_widget = parent_widget
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def change(self, item):
|
||||||
|
print("widget: data-item change")
|
||||||
|
return super().change(item)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
print("widget: data-item clear")
|
||||||
|
return super().clear()
|
||||||
|
|
||||||
|
def insert(self, index, item):
|
||||||
|
print("widget: data-item insert")
|
||||||
|
self.parent_widget.add(self.create_row(item.name,"3", "20"))
|
||||||
|
return super().insert(index, item)
|
||||||
|
|
||||||
|
def remove(self, index, item):
|
||||||
|
print("widget: data-item remove")
|
||||||
|
return super().remove(index, item)
|
||||||
|
|
||||||
|
def create_row(self, text, openitems, totalitems):
|
||||||
|
label = toga.Button(
|
||||||
|
text=text,
|
||||||
|
margin_bottom=2,
|
||||||
|
style = Pack(
|
||||||
|
# margin_bottom=2, # scrollig doesnt work, bug?, replaced by margin_bottom in Button
|
||||||
|
# width=250,
|
||||||
|
flex=15,
|
||||||
|
background_color="white", #white
|
||||||
|
font_size=15
|
||||||
|
)
|
||||||
|
)
|
||||||
|
spacer = toga.Box(
|
||||||
|
style = Pack(
|
||||||
|
flex=1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
indicator = toga.Label(
|
||||||
|
text = f"{openitems} / {totalitems}",
|
||||||
|
style = Pack(
|
||||||
|
color="blue",
|
||||||
|
margin=8,
|
||||||
|
flex=2
|
||||||
|
)
|
||||||
|
)
|
||||||
|
listrow_inner = toga.Box(
|
||||||
|
style = Pack(
|
||||||
|
margin_bottom=1,
|
||||||
|
flex=1,
|
||||||
|
background_color="white", #white
|
||||||
|
)
|
||||||
|
)
|
||||||
|
listrow_inner.add(label)
|
||||||
|
listrow_inner.add(spacer)
|
||||||
|
listrow_inner.add(indicator)
|
||||||
|
|
||||||
|
listrow_outer = toga.Box(
|
||||||
|
style = Pack(
|
||||||
|
# flex=1,
|
||||||
|
background_color="#ccc", # ccc
|
||||||
|
)
|
||||||
|
)
|
||||||
|
listrow_outer.add(listrow_inner)
|
||||||
|
|
||||||
|
return(listrow_outer)
|
||||||
|
|
||||||
|
|
||||||
class Lists(BasePage):
|
class Lists(BasePage):
|
||||||
|
|
||||||
@@ -19,6 +98,7 @@ class Lists(BasePage):
|
|||||||
:param args: args for super
|
:param args: args for super
|
||||||
:param kwargs: kwars for super
|
:param kwargs: kwars for super
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# set button and image
|
# set button and image
|
||||||
self.first_menu_button_icon = 'edit3'
|
self.first_menu_button_icon = 'edit3'
|
||||||
self.first_menu_button_callback = self.edit_button_pressed
|
self.first_menu_button_callback = self.edit_button_pressed
|
||||||
@@ -28,14 +108,17 @@ class Lists(BasePage):
|
|||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
# here the list of lists
|
# here the list of lists
|
||||||
listholder = toga.Column(
|
self.listholder = DatabaseList(
|
||||||
style=Pack(
|
style=Pack(
|
||||||
margin_bottom=10,
|
margin_bottom=10,
|
||||||
background_color="#aaa",
|
# background_color="white",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
scrollarea = toga.ScrollContainer(
|
scrollarea = toga.ScrollContainer(
|
||||||
content=listholder,
|
content=self.listholder,
|
||||||
style=Pack(
|
style=Pack(
|
||||||
flex=1,
|
flex=1,
|
||||||
margin=10,
|
margin=10,
|
||||||
@@ -45,8 +128,8 @@ class Lists(BasePage):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
for i in range(30):
|
# for i in range(30):
|
||||||
listholder.add(self.create_row("Supermarkt",f"{i}","30"))
|
# listholder.add(self.create_row("Supermarkt",f"{i}","30"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -75,6 +158,15 @@ class Lists(BasePage):
|
|||||||
self.content_box.add(scrollarea)
|
self.content_box.add(scrollarea)
|
||||||
# self.content_box.add(save_button_box)
|
# self.content_box.add(save_button_box)
|
||||||
|
|
||||||
|
def on_show(self):
|
||||||
|
super().on_show()
|
||||||
|
self.listholder.data.clear()
|
||||||
|
for l in self.app.data.reload_list():
|
||||||
|
print(type(l))
|
||||||
|
self.listholder.data.append(l)
|
||||||
|
|
||||||
|
# self.listholder.data.data = self.app.data.reload_list()
|
||||||
|
|
||||||
def edit_button_pressed(self):
|
def edit_button_pressed(self):
|
||||||
self.app.goto_next_page_by_name(PAGE_EDITLISTS)
|
self.app.goto_next_page_by_name(PAGE_EDITLISTS)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import datetime
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
class ListOfLists():
|
||||||
|
def __init__(self, app):
|
||||||
|
self.app = app
|
||||||
|
# self.listento = widget_to_listen_to
|
||||||
|
self.data = []
|
||||||
|
# self.widget_data = list_source_object
|
||||||
|
# self.reload()
|
||||||
|
|
||||||
|
# self.widget_data.append({"name": "ToDo", "id": 3, "owner_user_id": 3, "is_active": True, "updated_at": datetime.datetime.now() })
|
||||||
|
|
||||||
|
def reload(self, userid):
|
||||||
|
parameters = {}
|
||||||
|
parameters['userid'] = userid
|
||||||
|
result = self.app.backend.postwait('load_lists', parameters)
|
||||||
|
return result['data']
|
||||||
|
|
||||||
|
|
||||||
|
def on_reloaded(self, bla):
|
||||||
|
print("reloaded")
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.data = []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class List():
|
||||||
|
id = 0
|
||||||
|
updated_at = None
|
||||||
|
owner_user_id = 0
|
||||||
|
name = ''
|
||||||
|
is_active = True
|
||||||
|
|
||||||
|
|
||||||
|
class Item():
|
||||||
|
id = 0
|
||||||
|
updated_at = None
|
||||||
|
listofitems_id = 0
|
||||||
|
label = ''
|
||||||
|
quantity = 0
|
||||||
|
unit = ''
|
||||||
|
label_alt1 = ''
|
||||||
|
label_alt2 = ''
|
||||||
|
is_checked = False
|
||||||
|
is_suggestion = False
|
||||||
|
category = ''
|
||||||
|
|
||||||
|
class LocalData():
|
||||||
|
def __init__(self, app):
|
||||||
|
self.app = app
|
||||||
|
self.curent_userid = 0
|
||||||
|
self.current_listid = 0
|
||||||
|
self.lists = ListOfLists(app)
|
||||||
|
|
||||||
|
def set_user(self, userid):
|
||||||
|
if userid != self.curent_userid:
|
||||||
|
self.lists.clear()
|
||||||
|
self.curent_userid = userid
|
||||||
|
|
||||||
|
def reload_list(self):
|
||||||
|
self.curent_userid = self.app.configuration.get_userid()
|
||||||
|
if self.curent_userid > 0:
|
||||||
|
return self.lists.reload(self.curent_userid)
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
class ListItems():
|
|
||||||
id = 0
|
|
||||||
updated_at = None
|
|
||||||
owner_user_id = 0
|
|
||||||
name = ''
|
|
||||||
is_active = True
|
|
||||||
|
|
||||||
|
|
||||||
class Item():
|
|
||||||
id = 0
|
|
||||||
updated_at = db.Column(db.TIMESTAMP, default=datetime.now(), onupdate=datetime.now(), nullable=False)
|
|
||||||
listofitems_id = db.Column(db.Integer, nullable=False)
|
|
||||||
label = db.Column(db.String(40), nullable=False)
|
|
||||||
quantity = db.Column(db.Integer, default=0)
|
|
||||||
unit = db.Column(db.String(10))
|
|
||||||
label_alt1 = db.Column(db.String(40))
|
|
||||||
label_alt2 = db.Column(db.String(40))
|
|
||||||
is_checked = db.Column(db.Boolean, default=False)
|
|
||||||
is_suggestion = db.Column(db.Boolean, default=False)
|
|
||||||
category = db.Column(db.String(20))
|
|
||||||
@@ -60,7 +60,6 @@ class Login(BasePage):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# wrapping up the windows elements
|
# wrapping up the windows elements
|
||||||
self.content_box.add(self.name_input)
|
self.content_box.add(self.name_input)
|
||||||
self.content_box.add(self.password_input)
|
self.content_box.add(self.password_input)
|
||||||
@@ -82,7 +81,8 @@ class Login(BasePage):
|
|||||||
def after_backend_login(self, parameters, return_data):
|
def after_backend_login(self, parameters, return_data):
|
||||||
if return_data['status'] > 0:
|
if return_data['status'] > 0:
|
||||||
# store login etc in config
|
# store login etc in config
|
||||||
self.app.configuration.store_login(parameters['user'], parameters['password'])
|
self.app.configuration.store_login(return_data['data'])
|
||||||
|
print(return_data)
|
||||||
# goto lists screen
|
# goto lists screen
|
||||||
self.app.goto_next_page_by_name(PAGE_LISTS)
|
self.app.goto_next_page_by_name(PAGE_LISTS)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
from toga.sources import ListSource, Listener
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class Ear(Listener):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
print("ear init")
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def change(self, item):
|
||||||
|
print("ear change")
|
||||||
|
return super().change(item)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
print("ear clear")
|
||||||
|
return super().clear(item)
|
||||||
|
|
||||||
|
def insert(self, index, item):
|
||||||
|
print("ear insert")
|
||||||
|
return super().insert(index, item)
|
||||||
|
|
||||||
|
def remove(self, index, item):
|
||||||
|
print("ear remove")
|
||||||
|
return super().remove(index, item)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
source = ListSource(
|
||||||
|
accessors=["id", "updated_at", "owner_user_id", "name", "is_active"],
|
||||||
|
data=[
|
||||||
|
{"name": "Super", "id": 2, "owner_user_id": 3, "is_active": True, "updated_at": datetime.datetime.now() },
|
||||||
|
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
e = Ear()
|
||||||
|
source.add_listener(e)
|
||||||
|
|
||||||
|
|
||||||
|
# Get the first item in the source
|
||||||
|
item = source[0]
|
||||||
|
print(f"Animal's name is {item.name}")
|
||||||
|
print(item)
|
||||||
|
item.name = "more super"
|
||||||
|
print(item)
|
||||||
|
|
||||||
|
# Find an item with a name of "Thylacine"
|
||||||
|
# item = source.find({"name": "Super"})
|
||||||
|
|
||||||
|
# Remove that item from the data
|
||||||
|
source.remove(item)
|
||||||
|
|
||||||
|
# Insert a new item at the start of the data
|
||||||
|
# source.insert(0, {"name": "Bettong", "weight": 1.2})
|
||||||
|
|
||||||
|
source.append({"name": "ToDo", "id": 3, "owner_user_id": 3, "is_active": True, "updated_at": datetime.datetime.now() })
|
||||||
Reference in New Issue
Block a user