from nicegui import ui, app from datetime import datetime, timedelta from montydb import MontyClient from montydb.types.objectid import ObjectId import locale from pages import manager, user, useredit, index import signal import os import shutil from fastapi.responses import RedirectResponse from fastapi.responses import FileResponse class CallbackHandler: def __init__(self): self.callbacks = {} def register_callback(self, event_name, func): if event_name not in self.callbacks: self.callbacks[event_name] = [] self.callbacks[event_name].append(func) def execute_callbacks(self, event_name, *args, **kwargs): if event_name in self.callbacks: for callback in self.callbacks[event_name][:]: try: callback(*args, **kwargs) except Exception as e: print(f"Error executing callback {callback}: {e}") self.callbacks[event_name].remove(callback) handler = CallbackHandler() passwords = {'admin': [0,'sw1ng3rs',0, "Matteo Benedetto"], 'user': [1,'pass',1, "Pippo"]} # Set the locale to Italian locale.setlocale(locale.LC_ALL, 'it_IT.utf8') def styling(): ui.colors(primary='black', secondary="lightgray") ui.query('body').style(f'font-family: sans-serif') ui.add_head_html('') def login_check(): if not app.storage.user.get('authenticated', False): return False else: return True # Create a connection conn = MontyClient("db") # Access your database db = conn.letsswing # Routes @ui.page('/manager/{sede}/{livello}', title="Let's Swing Admin", favicon="assets/favicon.ico") def manager_page(sede:int, livello:int) -> None: if not login_check(): return RedirectResponse('/login') styling() manage = manager.Manager(handler) manage.main(db, sede, livello) # Routes app.add_static_files('/static', 'static') @ui.page('/', title="Let's Swing Admin", favicon="assets/favicon.ico") def index_page() -> None: if not login_check(): return RedirectResponse('/login') styling() index.main(db) @ui.page('/user/{userid}', title="Let's Swing Admin", favicon="assets/favicon.ico") def user_page(userid: str) -> None: if not login_check(): return RedirectResponse('/login') styling() user.main(userid, db, handler) @ui.page('/edit/{userid}/{sede}/{livello}', title="Let's Swing Admin", favicon="assets/favicon.ico") def useredit_page(userid: str, sede: int, livello: int) -> None: if not login_check(): return RedirectResponse('/login') styling() useredit.main(userid, sede, livello, db, handler) @ui.page('/backup/{password}') def api_backup(password: str) -> None: if password != "1337swing": return {'msg':'password errata'} # Percorso completo del file zip filename = "backup_db_" +datetime.now().strftime('%Y%m%d%H%M%S') zip_path = os.path.join('backup', filename) # Crea il file zip shutil.make_archive(zip_path, 'zip', "db") return FileResponse(path=zip_path + '.zip', media_type='application/octet-stream', filename=filename+".zip") @ui.page('/login',title="Let's Swing Admin", favicon="assets/favicon.ico") def page_login() -> None: styling() def try_login() -> None: # local function to avoid passing username and password as arguments if passwords.get(username.value)[1] == password.value: app.storage.user.update({'username': username.value, 'authenticated': True, 'id' : passwords.get(username.value)[0], "level": passwords.get(username.value)[2], "name": passwords.get(username.value)[3]}) ui.open('/') else: ui.notify('username o password errata', color='negative') if app.storage.user.get('authenticated', False): return RedirectResponse('/') ui.add_head_html(''' ''') ui.add_body_html(''' ''') async def install(): await ui.run_javascript(''' // Show the prompt if(!deferredPrompt) alert("Browser non compatibile"); deferredPrompt.prompt(); // Wait for the user to respond to the prompt deferredPrompt.userChoice.then((choiceResult) => { if (choiceResult.outcome === 'accepted') { console.log('User accepted the A2HS prompt'); } else { console.log('User dismissed the A2HS prompt'); } deferredPrompt = null; });''', respond=False) async def installable(btn): response = await ui.run_javascript(''' return (deferredPrompt ? true : false); ''') if response: btn.classes("hbtn visible") with ui.card().classes('absolute-center items-center'): install_btn =ui.button('Installa App', on_click=install,icon="install_mobile").classes("hbtn").props("outline") ui.timer(1, lambda: installable(install_btn), once=True) ui.image('assets/logo.svg') ui.label('Let\'s Swing Admin').classes('text-2xl').style("text-align:center") username = ui.input('Username').on('keydown.enter', try_login).classes('w-full') password = ui.input('Password', password=True, password_toggle_button=True).on('keydown.enter', try_login) ui.button('Log in', on_click=try_login) ui.add_body_html('''''') # PWA conversion @ui.page('/manifest.json') def manifest_json() -> None: return FileResponse(path='assets/site.webmanifest', filename="site.webmanifest") # Run main loop ui.run(host="0.0.0.0", port=9999, storage_secret='5w1ng4ndn0th1ngm0r3',language="it")