11"""User interface for the MusicAPi."""
22
33import logging
4- import src .logging_config # noqa: F401
5- from nicegui import ui
4+ import uuid
65
7- from src .ui .theme import apply_theme
8- from src .ui .components import SettingsDrawer , HelpDialog
6+ from nicegui import app , ui
7+ from starlette .requests import Request
8+ from starlette .responses import Response
9+
10+ from src .logging .event_logger import log_event
11+ from src .logging .log_database_connector import LogDatabaseConnector
12+ from src .logging_config import setup_logging , stop_logging
13+ from src .ui .components import HelpDialog , SettingsDrawer
914from src .ui .logic import process_submission
15+ from src .ui .theme import apply_theme
1016
11- logger = logging .getLogger (__name__ )
17+ logger = logging .getLogger ("app.music_api_ui" )
1218logger .setLevel (logging .INFO )
1319
20+ latest_url_value = ""
21+
22+ THRESHOLD = 4
23+
1424
1525class MusicApiApp :
1626 """Class for the MusicAPI user interface."""
1727
18- def __init__ (self ):
28+ def __init__ (self , session_id : str | None = None ):
1929 """Initialize the MusicApiApp."""
2030 apply_theme ()
2131
32+ self .session_id = session_id
33+
2234 self .settings = SettingsDrawer ()
2335 self .help = HelpDialog ()
2436
@@ -31,6 +43,7 @@ def build_header(self):
3143 ui .button (icon = "help" , on_click = self .help .open ).props ("round flat" )
3244 ui .button (icon = "code" , on_click = self .settings .toggle ).props ("round flat" )
3345
46+ # noqa: D401
3447 def build_main_content (self ):
3548 """Build the main content for the MusicAPI user interface."""
3649 with ui .column ().classes (
@@ -54,22 +67,85 @@ def build_main_content(self):
5467 .classes ("mt-2" )
5568 )
5669
57- ui .button ("Submit" , on_click = self .handle_click ).props (
58- "color=#CB69C1"
59- ).classes ("pink-btn w-full h-[50px] font-bold text-lg mt-4" )
70+ # ensure submit handler logs and receives session_id
71+ ui .button (
72+ "Submit" ,
73+ on_click = lambda : self .handle_click (session_id = self .session_id ),
74+ ).props ("color=#CB69C1" ).classes (
75+ "pink-btn w-full h-[50px] font-bold text-lg mt-4"
76+ )
77+
78+ @log_event ("submit.click" )
79+ async def handle_click (self , session_id : str | None = None ):
80+ """Handle a download submission. session_id is passed to logging wrapper.
6081
61- async def handle_click (self ):
62- """Handle a download submission."""
82+ Args:
83+ session_id: The session ID for logging context.
84+
85+ """
6386 await process_submission (
64- self .url_input , self .auto_dl .value , self .settings .audio_format .value
87+ self .url_input ,
88+ self .auto_dl .value ,
89+ self .settings .audio_format .value ,
90+ session_id = session_id ,
6591 )
6692
6793
94+ @log_event ("page.view" )
95+ def _log_page_view (session_id : str | None , user_agent : str , created : bool ):
96+ """Emit a structured page.view event via the log_event wrapper.
97+
98+ Args:
99+ session_id: The session ID for logging context.
100+ user_agent: The client's user agent string.
101+ created: Whether the session was newly created.
102+
103+ Returns:
104+ A dict containing client and session information.
105+
106+ """
107+ return {
108+ "client" : {"user_agent" : user_agent },
109+ "session" : {"id" : session_id , "created" : created },
110+ }
111+
112+
68113@ui .page ("/" )
69- def main_page ():
70- """Start user interface for the MusicAPi."""
71- MusicApiApp ()
114+ def main_page (request : Request , response : Response ) -> None :
115+ """Start user interface for the MusicAPi.
116+
117+ Args:
118+ request: The incoming HTTP request.
119+ response: The HTTP response to be sent.
120+
121+ """
122+ # create or reuse session id cookie
123+ session_id = request .cookies .get ("session_id" )
124+ created = False
125+ if not session_id :
126+ session_id = str (uuid .uuid4 ())
127+ response .set_cookie (
128+ "session_id" ,
129+ session_id ,
130+ httponly = True ,
131+ samesite = "lax" ,
132+ max_age = 400 * 24 * 3600 ,
133+ )
134+ created = True
135+
136+ user_agent = request .headers .get ("user-agent" , "" )
137+
138+ _log_page_view (
139+ session_id = session_id ,
140+ user_agent = user_agent ,
141+ created = created ,
142+ )
143+
144+ MusicApiApp (session_id = session_id )
145+
72146
147+ app .on_shutdown (stop_logging )
73148
74149if __name__ in {"__main__" , "__mp_main__" }:
75- ui .run (host = "0.0.0.0" , port = 8080 , title = "MusicAPI" )
150+ setup_logging (LogDatabaseConnector ())
151+ ui .run (host = "0.0.0.0" , port = 8080 , title = "MusicAPI" , uvicorn_logging_level = "warning" )
0 commit comments