3
3
4
4
import asyncio
5
5
import contextlib
6
- from curses import meta
7
6
import dataclasses
8
7
import datetime
9
8
import logging
10
9
11
10
from typing import TYPE_CHECKING
12
11
13
- from nowplaying .exceptions import PluginVerifyError
14
12
from nowplaying .inputs import InputPlugin
15
13
from nowplaying .types import TrackMetadata
16
14
17
15
from nowplaying .vendor .stagelinq .discovery import DiscoveryConfig , discover_stagelinq_devices
16
+ from nowplaying .vendor .stagelinq .device import AsyncDevice
18
17
from nowplaying .vendor .stagelinq .messages import Token
19
18
from nowplaying .vendor .stagelinq .value_names import DeckValueNames
20
19
21
20
if TYPE_CHECKING :
22
21
import nowplaying .config
23
- from nowplaying .vendor .stagelinq .device import AsyncDevice , State
22
+ from nowplaying .vendor .stagelinq .device import State
24
23
from PySide6 .QtWidgets import QWidget
25
24
26
25
@@ -30,7 +29,7 @@ class DeckInfo():
30
29
updated : datetime .datetime
31
30
track : str | None = None
32
31
artist : str | None = None
33
- bpm : int | None = None
32
+ bpm : float | None = None
34
33
playing : bool = False
35
34
36
35
def __post_init__ (self ):
@@ -58,7 +57,7 @@ class StagelinqHandler():
58
57
59
58
def __init__ (self , event : asyncio .Event ):
60
59
"""Initialize the StagelinQ handler.
61
-
60
+
62
61
Args:
63
62
event: Asyncio event used to signal shutdown
64
63
"""
@@ -69,7 +68,7 @@ def __init__(self, event: asyncio.Event):
69
68
70
69
async def get_device (self ):
71
70
"""Discover and connect to a StagelinQ device.
72
-
71
+
73
72
Continuously searches for StagelinQ devices until one is found
74
73
or the event is set to stop searching.
75
74
"""
@@ -89,12 +88,12 @@ async def get_device(self):
89
88
logging .info ("Waiting for devices... (searching)" )
90
89
await asyncio .sleep (2 )
91
90
92
- except Exception as e :
93
- logging .exception ("Discovery error: %s" , e )
91
+ except Exception as err : # pylint: disable=broad-exception-caught
92
+ logging .exception ("Discovery error: %s" , err )
94
93
95
94
async def loop (self ):
96
95
"""Main loop that maintains connection to StagelinQ device and processes updates.
97
-
96
+
98
97
This method handles device discovery, connection management, and subscribes
99
98
to track state updates from all decks. It automatically reconnects if
100
99
the connection is lost.
@@ -152,14 +151,15 @@ async def loop(self):
152
151
if self .event .is_set ():
153
152
return
154
153
155
- except Exception as e :
156
- logging .error ( f "Connection error: { e } " )
154
+ except Exception as err : # pylint: disable=broad-exception-caught
155
+ logging .exception ( "Connection error: %s" , err )
157
156
logging .error ("Retrying connection in 5 seconds..." )
158
157
await asyncio .sleep (5 )
159
158
160
- def process_state_update (self , temp_decks : dict [int , DeckInfo ], state : "State" ):
159
+ @staticmethod
160
+ def process_state_update (temp_decks : dict [int , DeckInfo ], state : "State" ):
161
161
"""Process a state update and update deck information.
162
-
162
+
163
163
Args:
164
164
temp_decks: Dictionary of deck information being built during this update cycle
165
165
state: StagelinQ state object containing updated deck information
@@ -186,7 +186,7 @@ def process_state_update(self, temp_decks: dict[int, DeckInfo], state: "State"):
186
186
187
187
def update_current_tracks (self , temp_decks : dict [int , DeckInfo ]):
188
188
"""Update the current deck states with new information.
189
-
189
+
190
190
Args:
191
191
temp_decks: Dictionary of updated deck information from the latest state updates
192
192
"""
@@ -196,7 +196,7 @@ def update_current_tracks(self, temp_decks: dict[int, DeckInfo]):
196
196
if deck_num not in temp_decks :
197
197
self .decks .pop (deck_num , None )
198
198
continue
199
-
199
+
200
200
if not temp_decks [deck_num ].playing and deck_num in self .decks :
201
201
del self .decks [deck_num ]
202
202
elif self .decks .get (deck_num ) is None :
@@ -219,10 +219,10 @@ async def stop(self):
219
219
220
220
async def get_track (self , mixmode : str ) -> DeckInfo | None :
221
221
"""Get the currently playing track based on the specified mix mode.
222
-
222
+
223
223
Args:
224
224
mixmode: Either "newest" or "oldest" to determine which deck to return
225
-
225
+
226
226
Returns:
227
227
DeckInfo for the selected deck, or None if no decks are playing
228
228
"""
@@ -269,10 +269,10 @@ def validmixmodes(self) -> list[str]: # pylint: disable=no-self-use
269
269
270
270
def setmixmode (self , mixmode : str ) -> str : # pylint: disable=no-self-use, unused-argument
271
271
"""Set the mix mode for determining which deck to use.
272
-
272
+
273
273
Args:
274
274
mixmode: Either "newest" or "oldest"
275
-
275
+
276
276
Returns:
277
277
The validated mix mode that was set
278
278
"""
@@ -290,7 +290,7 @@ def getmixmode(self) -> str: # pylint: disable=no-self-use
290
290
291
291
async def getplayingtrack (self ) -> TrackMetadata | None :
292
292
"""Get the currently playing track metadata.
293
-
293
+
294
294
Returns:
295
295
Dictionary containing track metadata (artist, track, bpm) or None if no handler
296
296
"""
@@ -311,10 +311,10 @@ async def getplayingtrack(self) -> TrackMetadata | None:
311
311
312
312
async def getrandomtrack (self , playlist : str ) -> str | None :
313
313
"""Get a random track from a playlist.
314
-
314
+
315
315
Args:
316
316
playlist: Name of the playlist (not implemented for StagelinQ)
317
-
317
+
318
318
Raises:
319
319
NotImplementedError: This method is not supported for StagelinQ
320
320
"""
0 commit comments