update rio and fix broken user sessions #5
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@ -11,6 +11,7 @@ from from_root import from_root
|
||||
from src.ez_lan_manager import pages, init_services
|
||||
from src.ez_lan_manager.helpers.LoggedInGuard import logged_in_guard, not_logged_in_guard, team_guard
|
||||
from src.ez_lan_manager.services.DatabaseService import NoDatabaseConnectionError
|
||||
from src.ez_lan_manager.services.LocalDataService import LocalData
|
||||
from src.ez_lan_manager.types.SessionStorage import SessionStorage
|
||||
|
||||
logger = logging.getLogger("EzLanManager")
|
||||
@ -29,16 +30,17 @@ if __name__ == "__main__":
|
||||
corner_radius_large=0,
|
||||
font=Font(from_root("src/ez_lan_manager/assets/fonts/joystix.otf"))
|
||||
)
|
||||
services = init_services()
|
||||
default_attachments = [LocalData()]
|
||||
default_attachments.extend(init_services())
|
||||
|
||||
lan_info = services[2].get_lan_info()
|
||||
lan_info = default_attachments[3].get_lan_info()
|
||||
|
||||
async def on_session_start(session: Session) -> None:
|
||||
await session.set_title(lan_info.name)
|
||||
session.attach(SessionStorage())
|
||||
|
||||
async def on_app_start(a: App) -> None:
|
||||
init_result = await a.default_attachments[3].init_db_pool()
|
||||
init_result = await a.default_attachments[4].init_db_pool()
|
||||
if not init_result:
|
||||
logger.fatal("Could not connect to database, exiting...")
|
||||
sys.exit(1)
|
||||
@ -163,7 +165,7 @@ if __name__ == "__main__":
|
||||
],
|
||||
theme=theme,
|
||||
assets_dir=Path(__file__).parent / "assets",
|
||||
default_attachments=services,
|
||||
default_attachments=default_attachments,
|
||||
on_session_start=on_session_start,
|
||||
on_app_start=on_app_start,
|
||||
icon=from_root("src/ez_lan_manager/assets/img/favicon.png"),
|
||||
|
||||
@ -7,6 +7,7 @@ from src.ez_lan_manager.services.AccountingService import AccountingService
|
||||
from src.ez_lan_manager.services.CateringService import CateringService
|
||||
from src.ez_lan_manager.services.ConfigurationService import ConfigurationService
|
||||
from src.ez_lan_manager.services.DatabaseService import DatabaseService
|
||||
from src.ez_lan_manager.services.LocalDataService import LocalDataService
|
||||
from src.ez_lan_manager.services.MailingService import MailingService
|
||||
from src.ez_lan_manager.services.NewsService import NewsService
|
||||
from src.ez_lan_manager.services.SeatingService import SeatingService
|
||||
@ -15,7 +16,7 @@ from src.ez_lan_manager.services.UserService import UserService
|
||||
from src.ez_lan_manager.types import *
|
||||
|
||||
# Inits services in the correct order
|
||||
def init_services() -> tuple[AccountingService, CateringService, ConfigurationService, DatabaseService, MailingService, NewsService, SeatingService, TicketingService, UserService]:
|
||||
def init_services() -> tuple[AccountingService, CateringService, ConfigurationService, DatabaseService, MailingService, NewsService, SeatingService, TicketingService, UserService, LocalDataService]:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
configuration_service = ConfigurationService(from_root("config.toml"))
|
||||
db_service = DatabaseService(configuration_service.get_database_configuration())
|
||||
@ -26,5 +27,6 @@ def init_services() -> tuple[AccountingService, CateringService, ConfigurationSe
|
||||
ticketing_service = TicketingService(configuration_service.get_ticket_info(), db_service, accounting_service)
|
||||
seating_service = SeatingService(configuration_service.get_seating_configuration(), configuration_service.get_lan_info(), db_service, ticketing_service)
|
||||
catering_service = CateringService(db_service, accounting_service, user_service)
|
||||
local_data_service = LocalDataService()
|
||||
|
||||
return accounting_service, catering_service, configuration_service, db_service, mailing_service, news_service, seating_service, ticketing_service, user_service
|
||||
return accounting_service, catering_service, configuration_service, db_service, mailing_service, news_service, seating_service, ticketing_service, user_service, local_data_service
|
||||
|
||||
@ -21,7 +21,7 @@ class AnimatedText(Component):
|
||||
)
|
||||
for c in text:
|
||||
self.text_comp.text = self.text_comp.text + c
|
||||
await self.text_comp.force_refresh()
|
||||
self.text_comp.force_refresh()
|
||||
await sleep(speed)
|
||||
else:
|
||||
self.text_comp.style = TextStyle(
|
||||
@ -30,7 +30,7 @@ class AnimatedText(Component):
|
||||
)
|
||||
for c in text:
|
||||
self.text_comp.text = self.text_comp.text + c
|
||||
await self.text_comp.force_refresh()
|
||||
self.text_comp.force_refresh()
|
||||
await sleep(speed)
|
||||
self._display_printing[0] = False
|
||||
|
||||
|
||||
@ -1,21 +1,38 @@
|
||||
from copy import copy, deepcopy
|
||||
from typing import Optional
|
||||
from typing import Optional, Callable
|
||||
|
||||
from rio import *
|
||||
|
||||
from src.ez_lan_manager import ConfigurationService, UserService
|
||||
from src.ez_lan_manager import ConfigurationService, UserService, LocalDataService
|
||||
from src.ez_lan_manager.components.DesktopNavigationButton import DesktopNavigationButton
|
||||
from src.ez_lan_manager.components.UserInfoAndLoginBox import UserInfoAndLoginBox
|
||||
from src.ez_lan_manager.services.LocalDataService import LocalData
|
||||
from src.ez_lan_manager.types.SessionStorage import SessionStorage
|
||||
from src.ez_lan_manager.types.User import User
|
||||
|
||||
|
||||
class DesktopNavigation(Component):
|
||||
user: Optional[User] = None
|
||||
force_login_box_refresh: list[Callable] = []
|
||||
|
||||
@event.on_populate
|
||||
async def async_init(self) -> None:
|
||||
self.session[SessionStorage].subscribe_to_logged_in_or_out_event(str(self.__class__), self.async_init)
|
||||
local_data = self.session[LocalData]
|
||||
if local_data.stored_session_token:
|
||||
session_ = self.session[LocalDataService].verify_token(local_data.stored_session_token)
|
||||
if session_:
|
||||
self.session.detach(SessionStorage)
|
||||
self.session.attach(session_)
|
||||
self.user = await self.session[UserService].get_user(session_.user_id)
|
||||
try:
|
||||
# Hack-around, maybe fix in the future
|
||||
self.force_login_box_refresh[-1]()
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
return
|
||||
|
||||
if self.session[SessionStorage].user_id:
|
||||
self.user = await self.session[UserService].get_user(self.session[SessionStorage].user_id)
|
||||
else:
|
||||
@ -23,6 +40,8 @@ class DesktopNavigation(Component):
|
||||
|
||||
def build(self) -> Component:
|
||||
lan_info = self.session[ConfigurationService].get_lan_info()
|
||||
user_info_and_login_box = UserInfoAndLoginBox()
|
||||
self.force_login_box_refresh.append(user_info_and_login_box.force_refresh)
|
||||
user_navigation = [
|
||||
DesktopNavigationButton("News", "./news"),
|
||||
Spacer(min_height=1),
|
||||
@ -62,7 +81,7 @@ class DesktopNavigation(Component):
|
||||
Column(
|
||||
Text(lan_info.name, align_x=0.5, margin_top=0.3, style=TextStyle(fill=self.session.theme.hud_color, font_size=2.5)),
|
||||
Text(f"Edition {lan_info.iteration}", align_x=0.5, style=TextStyle(fill=self.session.theme.hud_color, font_size=1.2), margin_top=0.3, margin_bottom=2),
|
||||
UserInfoAndLoginBox(),
|
||||
user_info_and_login_box,
|
||||
*nav_to_use,
|
||||
align_y=0
|
||||
),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
from rio import Component, TextStyle, Color, TextInput, Button, Text, Rectangle, Column, Row, Spacer, \
|
||||
EventHandler
|
||||
|
||||
from src.ez_lan_manager.services.LocalDataService import LocalDataService, LocalData
|
||||
from src.ez_lan_manager.services.UserService import UserService
|
||||
from src.ez_lan_manager.types.SessionStorage import SessionStorage
|
||||
from src.ez_lan_manager.types.User import User
|
||||
@ -27,13 +28,16 @@ class LoginBox(Component):
|
||||
self.login_button_is_loading = False
|
||||
self.is_account_locked = False
|
||||
await self.session[SessionStorage].set_user_id_and_team_member_flag(user.user_id, user.is_team_member)
|
||||
await self.status_change_cb()
|
||||
token = self.session[LocalDataService].set_session(self.session[SessionStorage])
|
||||
self.session[LocalData].stored_session_token = token
|
||||
self.session.attach(self.session[LocalData])
|
||||
self.status_change_cb()
|
||||
else:
|
||||
self.user_name_input_is_valid = False
|
||||
self.password_input_is_valid = False
|
||||
self.login_button_is_loading = False
|
||||
self.is_account_locked = False
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
def build(self) -> Component:
|
||||
user_name_input = TextInput(
|
||||
|
||||
@ -33,11 +33,11 @@ class ShoppingCartAndOrders(Component):
|
||||
except IndexError:
|
||||
return
|
||||
catering_service.save_cart(user_id, cart)
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
async def on_empty_cart_pressed(self) -> None:
|
||||
self.session[CateringService].save_cart(self.session[SessionStorage].user_id, [])
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
async def on_add_item(self, article_id: int) -> None:
|
||||
catering_service = self.session[CateringService]
|
||||
@ -48,20 +48,20 @@ class ShoppingCartAndOrders(Component):
|
||||
item_to_add = await catering_service.get_menu_item_by_id(article_id)
|
||||
cart.append(item_to_add)
|
||||
catering_service.save_cart(user_id, cart)
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
async def show_popup(self, text: str, is_error: bool) -> None:
|
||||
self.popup_is_error = is_error
|
||||
self.popup_message = text
|
||||
self.popup_is_shown = True
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
await sleep(POPUP_CLOSE_TIMEOUT_SECONDS)
|
||||
self.popup_is_shown = False
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
async def on_order_pressed(self) -> None:
|
||||
self.order_button_loading = True
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
user_id = self.session[SessionStorage].user_id
|
||||
cart = self.session[CateringService].get_cart(user_id)
|
||||
|
||||
@ -4,6 +4,7 @@ from typing import Optional
|
||||
from rio import Component, TextStyle, Color, Button, Text, Rectangle, Column, Row, Spacer, Link, event, EventHandler
|
||||
|
||||
from src.ez_lan_manager.components.UserInfoBoxButton import UserInfoBoxButton
|
||||
from src.ez_lan_manager.services.LocalDataService import LocalData, LocalDataService
|
||||
from src.ez_lan_manager.services.UserService import UserService
|
||||
from src.ez_lan_manager.services.AccountingService import AccountingService
|
||||
from src.ez_lan_manager.services.TicketingService import TicketingService
|
||||
@ -52,7 +53,10 @@ class UserInfoBox(Component):
|
||||
async def logout(self) -> None:
|
||||
await self.session[SessionStorage].clear()
|
||||
self.user = None
|
||||
await self.status_change_cb()
|
||||
self.session[LocalDataService].del_session(self.session[LocalData].stored_session_token)
|
||||
self.session[LocalData].stored_session_token = None
|
||||
self.session.attach(self.session[LocalData])
|
||||
self.status_change_cb()
|
||||
self.session.navigate_to("/")
|
||||
|
||||
@event.on_populate
|
||||
|
||||
@ -18,7 +18,7 @@ class BasePage(Component):
|
||||
|
||||
@event.on_window_size_change
|
||||
async def on_window_size_change(self):
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
def build(self) -> Component:
|
||||
content = Card(
|
||||
|
||||
@ -38,7 +38,7 @@ class BuyTicketPage(Component):
|
||||
if not self.user:
|
||||
return
|
||||
self.is_buying_enabled = False
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
try:
|
||||
t_s = self.session[TicketingService]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from typing import Optional
|
||||
from typing import Optional, Callable
|
||||
|
||||
from rio import Column, Component, event, TextStyle, Text, Spacer, Revealer, SwitcherBar, SwitcherBarChangeEvent, ProgressCircle
|
||||
|
||||
@ -24,7 +24,7 @@ class CateringPage(Component):
|
||||
self.all_menu_items = await self.session[CateringService].get_menu()
|
||||
|
||||
async def on_user_logged_in_status_changed(self) -> None:
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
async def on_switcher_bar_changed(self, _: SwitcherBarChangeEvent) -> None:
|
||||
await self.shopping_cart_and_orders[0].switch()
|
||||
|
||||
@ -28,7 +28,7 @@ class ContactPage(Component):
|
||||
async def on_send_pressed(self) -> None:
|
||||
error_msg = ""
|
||||
self.submit_button.is_loading = True
|
||||
await self.submit_button.force_refresh()
|
||||
self.submit_button.force_refresh()
|
||||
now = datetime.now()
|
||||
if not self.email_input.text:
|
||||
error_msg = "E-Mail darf nicht leer sein!"
|
||||
|
||||
@ -13,7 +13,7 @@ from src.ez_lan_manager.components.MainViewContentBox import MainViewContentBox
|
||||
class DbErrorPage(Component):
|
||||
@event.on_window_size_change
|
||||
async def on_window_size_change(self) -> None:
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
@event.on_mount
|
||||
async def retry_db_connect(self) -> None:
|
||||
|
||||
@ -20,7 +20,7 @@ class ForgotPasswordPage(Component):
|
||||
|
||||
async def on_submit_button_pressed(self) -> None:
|
||||
self.submit_button.is_loading = True
|
||||
await self.submit_button.force_refresh()
|
||||
self.submit_button.force_refresh()
|
||||
lan_info = self.session[ConfigurationService].get_lan_info()
|
||||
user_service = self.session[UserService]
|
||||
mailing_service = self.session[MailingService]
|
||||
|
||||
@ -38,10 +38,10 @@ class ManageNewsPage(Component):
|
||||
))
|
||||
self.news_posts = (await self.session[NewsService].get_news())[:8]
|
||||
self.show_success_message = True
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
await sleep(3)
|
||||
self.show_success_message = False
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
|
||||
async def on_news_post_changed(self, post: EditableNewsPost) -> None:
|
||||
author = await self.session[UserService].get_user(post.author)
|
||||
|
||||
@ -35,7 +35,7 @@ class RegisterPage(Component):
|
||||
|
||||
async def on_submit_button_pressed(self) -> None:
|
||||
self.submit_button.is_loading = True
|
||||
await self.submit_button.force_refresh()
|
||||
self.submit_button.force_refresh()
|
||||
|
||||
if len(self.user_name_input.text) < 1:
|
||||
await self.animated_text.display_text(False, "Nutzername darf nicht leer sein!")
|
||||
|
||||
@ -75,7 +75,7 @@ class SeatingPlanPage(Component):
|
||||
|
||||
async def on_purchase_confirmed(self) -> None:
|
||||
self.purchase_box_loading = True
|
||||
await self.force_refresh()
|
||||
self.force_refresh()
|
||||
await sleep(0.5)
|
||||
try:
|
||||
await self.session[SeatingService].seat_user(self.user.user_id, self.current_seat_id)
|
||||
|
||||
25
src/ez_lan_manager/services/LocalDataService.py
Normal file
25
src/ez_lan_manager/services/LocalDataService.py
Normal file
@ -0,0 +1,25 @@
|
||||
import secrets
|
||||
from typing import Optional
|
||||
|
||||
from rio import UserSettings
|
||||
|
||||
from src.ez_lan_manager.types.SessionStorage import SessionStorage
|
||||
|
||||
|
||||
class LocalData(UserSettings):
|
||||
stored_session_token: Optional[str] = None
|
||||
|
||||
class LocalDataService:
|
||||
def __init__(self) -> None:
|
||||
self._session: dict[str, SessionStorage] = {}
|
||||
|
||||
def verify_token(self, token: str) -> Optional[SessionStorage]:
|
||||
return self._session.get(token)
|
||||
|
||||
def set_session(self, session: SessionStorage) -> str:
|
||||
key = secrets.token_hex(32)
|
||||
self._session[key] = session
|
||||
return key
|
||||
|
||||
def del_session(self, token: str) -> None:
|
||||
self._session.pop(token, None)
|
||||
Loading…
Reference in New Issue
Block a user