From cf4f3137bd457e627f363ea600bdfa53b2a1ec8a Mon Sep 17 00:00:00 2001 From: Kuba <132459354+KubaPro010@users.noreply.github.com> Date: Sat, 11 Oct 2025 17:29:56 +0200 Subject: [PATCH] modularize playlist change --- modules/rds.py | 2 +- modules/shuffler.py | 13 +++++++++ modules/write_playlists.py | 4 +-- radioPlayer.py | 50 ++++++++++++++++++++--------------- radioPlayer_playlist_file.txt | 6 +---- 5 files changed, 46 insertions(+), 29 deletions(-) create mode 100644 modules/shuffler.py diff --git a/modules/rds.py b/modules/rds.py index 84e7071..fc2c5fc 100644 --- a/modules/rds.py +++ b/modules/rds.py @@ -1,5 +1,5 @@ class PlayerModule: - def on_new_playlist(self, playlist: list[tuple[str, bool, bool, bool]]): + def on_new_playlist(self, playlist: list[tuple[str, bool, bool, bool, dict]]): pass def on_new_track(self, index: int, track: str, to_fade_in: bool, to_fade_out: bool, official: bool): pass diff --git a/modules/shuffler.py b/modules/shuffler.py new file mode 100644 index 0000000..f3fdd89 --- /dev/null +++ b/modules/shuffler.py @@ -0,0 +1,13 @@ +import random + +class PlaylistModifierModule: + def modify(self, global_args: dict, playlist: list[tuple[str, bool, bool, bool, dict]]): + return playlist + +class Module(PlaylistModifierModule): + def modify(self, global_args: dict, playlist: list[tuple[str, bool, bool, bool, dict]]): + if int(global_args.get("no_shuffle", 0)) == 0: + random.shuffle(playlist) + return playlist + +playlistmod = (Module(), 0) \ No newline at end of file diff --git a/modules/write_playlists.py b/modules/write_playlists.py index 3aa7659..ba85a63 100644 --- a/modules/write_playlists.py +++ b/modules/write_playlists.py @@ -1,5 +1,5 @@ class PlayerModule: - def on_new_playlist(self, playlist: list[tuple[str, bool, bool, bool]]): + def on_new_playlist(self, playlist: list[tuple[str, bool, bool, bool, dict]]): pass def on_new_track(self, index: int, track: str, to_fade_in: bool, to_fade_out: bool, official: bool): pass @@ -7,7 +7,7 @@ class PlayerModule: class Module(PlayerModule): def __init__(self) -> None: self.playlist = [] - def on_new_playlist(self, playlist: list[tuple[str, bool, bool, bool]]): + def on_new_playlist(self, playlist: list[tuple[str, bool, bool, bool, dict]]): self.playlist = [t[0] for t in playlist] def on_new_track(self, index: int, track: str, to_fade_in: bool, to_fade_out: bool, official: bool): lines = self.playlist[:index] + [f"> {self.playlist[index]}"] + self.playlist[index+1:] diff --git a/radioPlayer.py b/radioPlayer.py index 05df6cc..e1ea5d1 100644 --- a/radioPlayer.py +++ b/radioPlayer.py @@ -10,12 +10,16 @@ import log95, copy from pathlib import Path class PlayerModule: - def on_new_playlist(self, playlist: list[tuple[str, bool, bool, bool]]): + def on_new_playlist(self, playlist: list[tuple[str, bool, bool, bool, dict]]): pass def on_new_track(self, index: int, track: str, to_fade_in: bool, to_fade_out: bool, official: bool): pass +class PlaylistModifierModule: + def modify(self, global_args: dict, playlist: list[tuple[str, bool, bool, bool, dict]]): + return playlist simple_modules: list[PlayerModule] = [] +playlist_modifier_modules: list[PlaylistModifierModule] = [] SCRIPT_DIR = Path(__file__).resolve().parent MODULES_DIR = SCRIPT_DIR / "modules" @@ -222,34 +226,33 @@ def play_playlist(playlist_path, custom_playlist: bool=False): logger.info(f"Exception while parsing playlist, retrying in 15 seconds...") time.sleep(15) return - lines_args = copy.deepcopy(parsed) - lines = [] - for (lns, args) in lines_args: + + playlist: list[tuple[str, bool, bool, bool, dict]] = [] # name, fade in, fade out, official, args + for (lns, args) in parsed: lns: list[str] args: dict[str, str] + for line in lns: playlist.append((line, True, True, True, args)) - for i in range(int(args.get("multiplier", 1))): lines.extend(lns) - - cross_fade = int(global_args.get("crossfade", 5)) - if int(global_args.get("no_shuffle", 0)) == 0: random.shuffle(lines) - - playlist: list[tuple[str, bool, bool, bool]] = [] # name, fade in, fade out, official - last_jingiel = True - for line in lines: - if not last_jingiel and random.choice([False, True, False, False]) and JINGIEL_FILE: - playlist.append((line, True, False, True)) - playlist.append((JINGIEL_FILE, False, False, False)) - last_jingiel = True - else: - playlist.append((line, True, True, True)) - last_jingiel = False - del last_jingiel + for module in playlist_modifier_modules: playlist = module.modify(global_args, playlist) + + # last_jingiel = True + # for line in lines: + # if not last_jingiel and random.choice([False, True, False, False]) and JINGIEL_FILE: + # playlist.append((line, True, False, True)) + # playlist.append((JINGIEL_FILE, False, False, False)) + # last_jingiel = True + # else: + # playlist.append((line, True, True, True)) + # last_jingiel = False + # del last_jingiel for module in simple_modules: module.on_new_playlist(playlist) return_pending = False + + cross_fade = int(global_args.get("crossfade", 5)) - for i, (track, to_fade_in, to_fade_out, official) in enumerate(playlist): + for i, (track, to_fade_in, to_fade_out, official, args) in enumerate(playlist): if return_pending: logger.info("Return reached, next song will reload the playlist.") procman.wait_all() @@ -332,6 +335,11 @@ def main(): if md := getattr(module, "module", None): simple_modules.append(md) + elif md := getattr(module, "playlistmod", None): + if isinstance(md, tuple): + md, index = md + playlist_modifier_modules.insert(index, md) + else: playlist_modifier_modules.append(md) try: while True: diff --git a/radioPlayer_playlist_file.txt b/radioPlayer_playlist_file.txt index b95462d..164d15b 100644 --- a/radioPlayer_playlist_file.txt +++ b/radioPlayer_playlist_file.txt @@ -13,8 +13,4 @@ The files are parsed with glob, thus you can add such entries as `/home/user/mix Each lines starting with `@` is taken as a import, meaning after the `@` a file path to a text file with the same format is expected (yes, you can import in imports too) Lines which start with `;` are considered comments and will not be processed Lines containing `|` will be split into two parts, the first part will be treated as the file itself, and the argument part will be treated as arguments for that file, if the file name is empty then those arguments will be treated as global -The arguments shall have a `a=b` format, multiple arguments are seperated with a `;`, example: `a=b;c=d` - -As of now these arguments are defined: -`no_shuffle` - Global argument, does not shuffle the playlist if it is 0 -`multiplier` - File argument, integer which duplicates the file(s) \ No newline at end of file +The arguments shall have a `a=b` format, multiple arguments are seperated with a `;`, example: `a=b;c=d` \ No newline at end of file