import logging from asyncio import sleep from typing import Optional from email_validator import validate_email, EmailNotValidError from rio import Column, Component, event, Text, TextStyle, TextInput, TextInputChangeEvent, Button from src.ez_lan_manager import ConfigurationService, UserService, MailingService from src.ez_lan_manager.components.MainViewContentBox import MainViewContentBox from src.ez_lan_manager.pages import BasePage MINIMUM_PASSWORD_LENGTH = 6 logger = logging.getLogger(__name__.split(".")[-1]) class RegisterPage(Component): def on_pw_change(self, _: TextInputChangeEvent) -> None: if not (self.pw_1.text == self.pw_2.text) or len(self.pw_1.text) < MINIMUM_PASSWORD_LENGTH: self.pw_1.is_valid = False self.pw_2.is_valid = False return self.pw_1.is_valid = True self.pw_2.is_valid = True def on_email_changed(self, change_event: TextInputChangeEvent) -> None: try: validate_email(change_event.text, check_deliverability=False) self.email_input.is_valid = True except EmailNotValidError: self.email_input.is_valid = False async def on_submit_button_pressed(self) -> None: self.submit_button.is_loading = True await self.submit_button.force_refresh() if len(self.user_name_input.text) < 1: await self.display_save_result_animation(False, optional_text="Nutzername darf nicht leer sein!") self.submit_button.is_loading = False return if not (self.pw_1.text == self.pw_2.text): await self.display_save_result_animation(False, optional_text="Passwörter stimmen nicht überein!") self.submit_button.is_loading = False return if len(self.pw_1.text) < MINIMUM_PASSWORD_LENGTH: await self.display_save_result_animation(False, optional_text=f"Passwort muss mindestens {MINIMUM_PASSWORD_LENGTH} Zeichen lang sein!") self.submit_button.is_loading = False return if not self.email_input.is_valid or len(self.email_input.text) < 3: await self.display_save_result_animation(False, optional_text="E-Mail Adresse ungültig!") self.submit_button.is_loading = False return user_service = self.session[UserService] mailing_service = self.session[MailingService] lan_info = self.session[ConfigurationService].get_lan_info() if user_service.get_user(self.email_input.text) is not None or user_service.get_user(self.user_name_input.text) is not None: await self.display_save_result_animation(False, optional_text="Benutzername oder E-Mail bereits regestriert!") self.submit_button.is_loading = False return try: new_user = user_service.create_user(self.user_name_input.text, self.email_input.text, self.pw_1.text) if not new_user: raise RuntimeError("User could not be created") except Exception as e: logger.error(f"Unknown error during new user registration: {e}") await self.display_save_result_animation(False, optional_text="Es ist ein unbekannter Fehler aufgetreten :(") self.submit_button.is_loading = False return await mailing_service.send_email( subject="Erfolgreiche Registrierung", body=f"Hallo {self.user_name_input.text},\n\n" f"Du hast dich erfolgreich beim EZ-LAN Manager für {lan_info.name} {lan_info.iteration} registriert.\n\n" f"Wenn du dich nicht registriert hast, kontaktiere bitte unser Team über unsere Homepage.\n\n" f"Liebe Grüße\nDein {lan_info.name} - Team", receiver=self.email_input.text ) self.submit_button.is_loading = False await self.display_save_result_animation(True, optional_text="Erfolgreich registriert!") async def display_save_result_animation(self, success: bool, optional_text: Optional[str] = None) -> None: self.info_text.text = "" if success: self.info_text.style = TextStyle( fill=self.session.theme.success_color, font_size=1 ) t = "Gespeichert!" if not optional_text else optional_text for c in t: self.info_text.text = self.info_text.text + c await self.info_text.force_refresh() await sleep(0.04) else: self.info_text.style = TextStyle( fill=self.session.theme.danger_color, font_size=1 ) t = "Fehler!" if not optional_text else optional_text for c in t: self.info_text.text = self.info_text.text + c await self.info_text.force_refresh() await sleep(0.04) @event.on_populate async def on_populate(self) -> None: await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Registrieren") def build(self) -> Component: self.user_name_input = TextInput( label="Benutzername", text="", margin_left=1, margin_right=1, margin_bottom=1, grow_x=True ) self.email_input = TextInput( label="E-Mail Adresse", text="", margin_left=1, margin_right=1, margin_bottom=1, grow_x=True, on_change=self.on_email_changed ) self.pw_1 = TextInput( label="Passwort", text="", margin_left=1, margin_right=1, margin_bottom=1, grow_x=True, is_secret=True, on_change=self.on_pw_change ) self.pw_2 = TextInput( label="Passwort wiederholen", text="", margin_left=1, margin_right=1, margin_bottom=1, grow_x=True, is_secret=True, on_change=self.on_pw_change ) self.submit_button = Button( content=Text( "Registrieren", style=TextStyle(fill=self.session.theme.background_color, font_size=0.9), align_x=0.5 ), grow_x=True, margin_top=2, margin_left=1, margin_right=1, margin_bottom=1, shape="rectangle", style="minor", color=self.session.theme.secondary_color, on_press=self.on_submit_button_pressed ) self.info_text = Text( text="", style=TextStyle( fill=self.session.theme.background_color, font_size=1 ), margin_top=2, margin_left=1, margin_right=1, margin_bottom=2, wrap=True ) return BasePage( content=Column( MainViewContentBox( content=Column( Text( "Neues Konto anlegen", style=TextStyle( fill=self.session.theme.background_color, font_size=1.2 ), margin_top=2, margin_bottom=2, align_x=0.5 ), self.user_name_input, self.email_input, self.pw_1, self.pw_2, self.submit_button, self.info_text ) ), align_y=0, ) )