Skip to content

Commit

Permalink
Make second swipe finally work
Browse files Browse the repository at this point in the history
  • Loading branch information
pabera committed Dec 28, 2024
1 parent e7fa13b commit 91e9a72
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 48 deletions.
62 changes: 29 additions & 33 deletions src/jukebox/components/playermpd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def __init__(self):
'replay': self.replay,
'replay_if_stopped': self.replay_if_stopped}
self.second_swipe_action = None
self.decode_2nd_swipe_option()
self.decode_second_swipe_action()

self.end_of_playlist_next_action = utils.get_config_action(cfg,
'playermpd',
Expand Down Expand Up @@ -250,21 +250,20 @@ def exit(self):
def connect(self):
self.mpd_client.connect(self.mpd_host, 6600)

def decode_2nd_swipe_option(self):
cfg_2nd_swipe_action = cfg.setndefault('playermpd', 'second_swipe_action', 'alias', value='none').lower()
if cfg_2nd_swipe_action not in [*self.second_swipe_action_dict.keys(), 'none', 'custom']:
logger.error(f"Config mpd.second_swipe_action must be one of "
f"{[*self.second_swipe_action_dict.keys(), 'none', 'custom']}. Ignore setting.")
if cfg_2nd_swipe_action in self.second_swipe_action_dict.keys():
self.second_swipe_action = self.second_swipe_action_dict[cfg_2nd_swipe_action]
if cfg_2nd_swipe_action == 'custom':
custom_action = utils.decode_rpc_call(cfg.getn('playermpd', 'second_swipe_action', default=None))
self.second_swipe_action = functools.partial(plugs.call_ignore_errors,
custom_action['package'],
custom_action['plugin'],
custom_action['method'],
custom_action['args'],
custom_action['kwargs'])
def decode_second_swipe_action(self):
"""
Decode the second swipe option from the configuration
"""
logger.debug("Decoding second swipe option")
second_swipe_action = cfg.getn('playermpd', 'second_swipe_action', 'none')
logger.debug(f"Second swipe option from config: {second_swipe_action}")

if second_swipe_action in self.second_swipe_action_dict:
self.second_swipe_action = self.second_swipe_action_dict[second_swipe_action]
logger.debug(f"Second swipe action set to: {self.second_swipe_action}")
else:
self.second_swipe_action = None
logger.debug("No valid second swipe action found, setting to None")

def mpd_retry_with_mutex(self, mpd_cmd, *args):
"""
Expand Down Expand Up @@ -570,16 +569,16 @@ def _play_folder_internal(self, folder: str, recursive: bool) -> None:
self.mpd_client.play()

@plugs.tag
def play_content(self, content: Union[str, Dict[str, Any]], content_type: str = 'folder', recursive: bool = False):
def play_content(self, content: Union[str, Dict[str, Any]], content_type: str = 'folder',
recursive: bool = False, preserve_second_swipe: bool = False):
"""
Main entry point for trigger music playing from any source (RFID reader, web UI, etc.).
Does NOT support second swipe - use play_from_reader() for that.
Main entry point for playing content.
:param content: Content identifier:
- For singles/folders: file/folder path as string
- For albums: dict with 'albumartist' and 'album' keys
:param content_type: Type of content ('single', 'album', 'folder')
:param recursive: Add folder recursively (only used for folder type)
Args:
content: Content to play
content_type: Type of content ('folder', 'album', etc.)
recursive: Whether to play recursively
preserve_second_swipe: If True, preserves any existing second_swipe_action
"""
try:
content_type = content_type.lower()
Expand Down Expand Up @@ -612,15 +611,16 @@ def play_content(self, content: Union[str, Dict[str, Any]], content_type: str =
recursive=recursive
)

old_action = self.play_content_handler.second_swipe_action
# Ensure no second swipe for regular content playback
old_action = self.play_content_handler._second_swipe_action
self.play_content_handler._second_swipe_action = None
if not preserve_second_swipe:
self.play_content_handler.second_swipe_action = None

try:
self.play_content_handler.play_content(play_content)
finally:
# Restore previous second swipe action
self.play_content_handler._second_swipe_action = old_action
self.play_content_handler.second_swipe_action = old_action

except Exception as e:
logger.error(f"Error playing content: {e}")
Expand All @@ -643,25 +643,21 @@ def play_from_reader(self, content: Union[str, Dict[str, str]], content_type: st
- 'none': disable second swipe
- One of: 'toggle', 'play', 'skip', 'rewind', 'replay', 'replay_if_stopped'
"""
# Determine second swipe action
if second_swipe is None:
action = self.second_swipe_action
elif second_swipe.lower() == 'none':
action = None
else:
action = self.second_swipe_action_dict.get(second_swipe.lower())
if action is None:
logger.error(f"Unknown second swipe action '{second_swipe}', using default")
action = self.second_swipe_action

# Temporarily set the chosen second swipe action
old_action = self.play_content_handler._second_swipe_action
old_action = self.play_content_handler.second_swipe_action
self.play_content_handler.set_second_swipe_action(action)

try:
self.play_content(content, content_type, recursive)
self.play_content(content, content_type, recursive, preserve_second_swipe=True)
finally:
# Restore previous second swipe action
self.play_content_handler.set_second_swipe_action(old_action)

# The following methods are kept for backward compatibility but now use play_content internally
Expand Down
7 changes: 3 additions & 4 deletions src/jukebox/components/playermpd/play_content_callback.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@

from enum import Enum
from typing import Callable, Generic, TypeVar

from jukebox.callingback import CallbackHandler


class PlayCardState(Enum):
firstSwipe = 0,
secondSwipe = 1
FIRST_SWIPE = 0
SECOND_SWIPE = 1


STATE = TypeVar('STATE', bound=Enum)
Expand All @@ -27,7 +26,7 @@ def register(self, func: Callable[[str, STATE], None]):
.. py:function:: func(folder: str, state: STATE)
:noindex:
:param folder: relativ path to folder to play
:param folder: relative path to folder to play
:param state: indicator of the state inside the calling
"""
super().register(func)
Expand Down
18 changes: 7 additions & 11 deletions src/jukebox/components/playermpd/play_content_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,21 @@ class PlayContentHandler:
def __init__(self, player: PlayerProtocol):
self.player = player
self.last_played_content: Optional[PlayContent] = None
self._second_swipe_action = None
self.second_swipe_action = None
self._instance_id = id(self)

def set_second_swipe_action(self, action: Optional[Callable]) -> None:
"""Set the action to be performed on second swipe"""
self._second_swipe_action = action
self.second_swipe_action = action

def _play_content(self, content: PlayContent) -> None:
"""Internal method to play content based on its type"""
if content.type == PlayContentType.SINGLE:
logger.debug(f"Playing single track: {content.content}")
self.player._play_single_internal(content.content)
elif content.type == PlayContentType.ALBUM:
artist, album = content.content
logger.debug(f"Playing album: {album} by {artist}")
self.player._play_album_internal(artist, album)
elif content.type == PlayContentType.FOLDER:
logger.debug(f"Playing folder: {content.content} (recursive={content.recursive})")
self.player._play_folder_internal(content.content, content.recursive)

def play_content(self, content: PlayContent) -> None:
Expand All @@ -77,20 +75,18 @@ def play_content(self, content: PlayContent) -> None:
and content.content == self.last_played_content.content):
is_second_swipe = True

if self._second_swipe_action is not None and is_second_swipe:
logger.debug('Calling second swipe action')
if self.second_swipe_action is not None and is_second_swipe:
# run callbacks before second_swipe_action is invoked
self.player.play_card_callbacks.run_callbacks(
str(content.content),
PlayCardState.secondSwipe # Use imported PlayCardState directly
PlayCardState.SECOND_SWIPE
)
self._second_swipe_action()
self.second_swipe_action()
else:
logger.debug('Calling first swipe action')
# run callbacks before play_content is invoked
self.player.play_card_callbacks.run_callbacks(
str(content.content),
PlayCardState.firstSwipe # Use imported PlayCardState directly
PlayCardState.FIRST_SWIPE
)
self._play_content(content)

Expand Down

0 comments on commit 91e9a72

Please sign in to comment.