diff --git a/modules/__init__.py b/modules/__init__.py index dcfa4bd..b5b5974 100644 --- a/modules/__init__.py +++ b/modules/__init__.py @@ -11,6 +11,13 @@ class PlayerModule: Called on every track including the ones added by the active modifier, you can check for that comparing the playlists[index] and the track """ pass + def imc(self, imc: 'InterModuleCommunication'): + """ + Receive an IMC object + """ + pass + def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object) -> object: + pass class PlaylistModifierModule: """ Playlist modifier, this type of module allows you to shuffle, or put jingles into your playlist @@ -20,6 +27,7 @@ class PlaylistModifierModule: global_args are playlist global args (see radioPlayer_playlist_file.txt) """ return playlist + # No IMC, as we only run on new playlists class PlaylistAdvisor: """ Only one of a playlist advisor can be loaded. This module picks the playlist file to play, this can be a scheduler or just a static file @@ -34,6 +42,13 @@ class PlaylistAdvisor: Whether to play a new playlist, if this is 1, then the player will refresh, if this is two then the player will refresh quietly """ return 0 + def imc(self, imc: 'InterModuleCommunication'): + """ + Receive an IMC object + """ + pass + def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object) -> object: + pass class ActiveModifier: """ This changes the next song to be played live, which means that this picks the next song, not the playlist, but this is affected by the playlist @@ -53,4 +68,31 @@ class ActiveModifier: """ Same behaviour as the basic module function """ - pass \ No newline at end of file + pass + def imc(self, imc: 'InterModuleCommunication'): + """ + Receive an IMC object + """ + pass + def imc_data(self, source: 'PlayerModule | ActiveModifier | PlaylistAdvisor', data: object) -> object: + pass +class InterModuleCommunication: + def __init__(self, advisor: PlaylistAdvisor, active_modifier: ActiveModifier | None, simple_modules: list[PlayerModule]) -> None: + self.advisor = advisor + self.active_modifier = active_modifier + self.simple_modules = simple_modules + self.names_modules: dict[str, PlaylistAdvisor | ActiveModifier | PlayerModule] = {} + def broadcast(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, data: object) -> None: + """ + Send data to all modules + """ + self.advisor.imc_data(source, data) + if self.active_modifier: self.active_modifier.imc_data(source, data) + for module in self.simple_modules: module.imc_data(source, data) + def register(self, module: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str): + if name in self.names_modules.keys(): return False + self.names_modules[name] = module + return True + def send(self, source: PlaylistAdvisor | ActiveModifier | PlayerModule, name: str, data: object) -> object: + if not name in self.names_modules.keys(): raise Exception + return self.names_modules[name].imc_data(source, data) \ No newline at end of file diff --git a/modules/active_modifier.py b/modules/active_modifier.py index 4e98c68..bb6bcfc 100644 --- a/modules/active_modifier.py +++ b/modules/active_modifier.py @@ -1,3 +1,4 @@ +from modules import InterModuleCommunication from . import ActiveModifier import os, log95 import subprocess @@ -18,10 +19,12 @@ class Module(ActiveModifier): self.originals = [] self.last_track = None self.limit_tracks = True - def arguments(self, arguments: str | None): - if arguments and arguments.startswith("list:"): self.limit_tracks = False + self.imc_class = None def on_new_playlist(self, playlist: list[tuple[str, bool, bool, bool, dict[str, str]]]): self.playlist = playlist + + if not self.imc_class: return + self.limit_tracks = bool(self.imc_class.send(self, "advisor", None)) def play(self, index: int, track: tuple[str, bool, bool, bool, dict[str, str]]): if not self.playlist: return track if not os.path.exists("/tmp/radioPlayer_toplay"): open("/tmp/radioPlayer_toplay", "a").close() @@ -73,5 +76,8 @@ class Module(ActiveModifier): return None, None return self.last_track, False + + def imc(self, imc: InterModuleCommunication): + self.imc_class = imc activemod = Module() \ No newline at end of file diff --git a/modules/advisor.py b/modules/advisor.py index c8a0616..3098910 100644 --- a/modules/advisor.py +++ b/modules/advisor.py @@ -1,3 +1,4 @@ +from modules import ActiveModifier, InterModuleCommunication, PlayerModule from . import PlaylistAdvisor import os, datetime, log95 @@ -48,6 +49,7 @@ class Module(PlaylistAdvisor): self.last_mod_time = 0 self.last_playlist = None self.custom_playlist = None + self.class_imc = None def advise(self, arguments: str | None) -> str: if self.custom_playlist: return self.custom_playlist if arguments and arguments.startswith("list:"): @@ -106,5 +108,10 @@ class Module(PlaylistAdvisor): logger.info("Playlist changed on disc, reloading...") return 1 return 0 + def imc(self, imc: InterModuleCommunication): + self.class_imc = imc + imc.register(self, "advisor") + def imc_data(self, source: PlayerModule | ActiveModifier | PlaylistAdvisor, data: object): + return self.custom_playlist advisor = Module() \ No newline at end of file diff --git a/radioPlayer.py b/radioPlayer.py index ae19e50..33d1fcc 100644 --- a/radioPlayer.py +++ b/radioPlayer.py @@ -290,6 +290,12 @@ def main(): if not playlist_advisor: logger.critical_error("Playlist advisor was not found") exit(1) + + imc = InterModuleCommunication(playlist_advisor, active_modifier, simple_modules) + + playlist_advisor.imc(imc) + if active_modifier: active_modifier.imc(imc) + for module in simple_modules: module.imc(imc) try: arg = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else None