import threading import time class Action: action_types = [ 'command', 'pause', 'play', 'seek', 'stop', 'stop_all_actions', 'unpause', 'volume', 'wait', ] def __init__(self, action, key, **kwargs): if action in self.action_types: self.action = action else: raise Exception("Unknown action {}".format(action)) self.key = key self.mapping = key.parent self.arguments = kwargs self.sleep_event = None def ready(self): if 'music' in self.arguments: return self.arguments['music'].check_is_loaded() else: return True def run(self): print(self.description()) getattr(self, self.action)(**self.arguments) def description(self): return getattr(self, self.action + "_print")(**self.arguments) def interrupt(self): if getattr(self, self.action + "_interrupt", None): return getattr(self, self.action + "_interrupt")(**self.arguments) def music_list(self, music): if music is not None: return [music] else: return self.mapping.open_files.values() # Actions def command(self, command = "", **kwargs): # FIXME: todo pass def pause(self, music = None, **kwargs): for music in self.music_list(music): if music.is_loaded_playing(): music.pause() def unpause(self, music = None, **kwargs): for music in self.music_list(music): if music.is_loaded_paused(): music.unpause() def play(self, music = None, fade_in = 0, start_at = 0, restart_if_running = False, volume = 100, loop = 0, **kwargs): for music in self.music_list(music): if restart_if_running: if music.is_not_stopped(): music.stop() music.play(volume = volume, fade_in = fade_in, start_at = start_at, loop = loop) else: if not music.is_not_stopped(): music.play(volume = volume, fade_in = fade_in, start_at = start_at, loop = loop) def seek(self, music = None, value = 0, delta = False, **kwargs): for music in self.music_list(music): music.seek(value = value, delta = delta) def stop(self, music = None, fade_out = 0, wait = False, **kwargs): previous = None for music in self.music_list(music): if music.is_loaded_paused() or music.is_loaded_playing(): if previous is not None: previous.stop(fade_out = fade_out) previous = music if previous is not None: previous.stop(fade_out = fade_out, wait = wait) def stop_all_actions(self, **kwargs): self.mapping.stop_all_running() def volume(self, music = None, value = 100, delta = False, **kwargs): if music is not None: music.set_volume(value, delta = delta) else: self.mapping.set_master_volume(value, delta = delta) def wait(self, duration = 0, music = None, **kwargs): self.sleep_event = threading.Event() if music is not None: music.wait_end() threading.Timer(duration, self.sleep_event.set).start() self.sleep_event.wait() # Action messages def command_print(self, command = "", **kwargs): return "running command {}".format(command) def pause_print(self, music = None, **kwargs): if music is not None: return "pausing « {} »".format(music.name) else: return "pausing all musics" def unpause_print(self, music = None, **kwargs): if music is not None: return "unpausing « {} »".format(music.name) else: return "unpausing all musics" def play_print(self, music = None, fade_in = 0, start_at = 0, restart_if_running = False, volume = 100, loop = 0, **kwargs): message = "starting " if music is not None: message += "« {} »".format(music.name) else: message += "all musics" if start_at != 0: message += " at {}s".format(start_at) if fade_in != 0: message += " with {}s fade_in".format(fade_in) message += " at volume {}%".format(volume) if loop > 0: message += " {} times".format(loop + 1) elif loop < 0: message += " in loop" if restart_if_running: message += " (restarting if already running)" return message def stop_print(self, music = None, fade_out = 0, wait = False, **kwargs): message = "stopping " if music is not None: message += "music « {} »".format(music.name) else: message += "all musics" if fade_out > 0: message += " with {}s fadeout".format(fade_out) if wait: message += " (waiting the end of fadeout)" return message def stop_all_actions_print(self, **kwargs): return "stopping all actions" def seek_print(self, music = None, value = 0, delta = False, **kwargs): if delta: if music is not None: return "moving music « {} » by {:+d}s".format(music.name, value) else: return "moving all musics by {:+d}s".format(value) else: if music is not None: return "moving music « {} » to position {}s".format(music.name, value) else: return "moving all musics to position {}s".format(value) def volume_print(self, music = None, value = 100, delta = False, **kwargs): if delta: if music is not None: return "{:+d}% to volume of « {} »".format(value, music.name) else: return "{:+d}% to volume".format(value) else: if music is not None: return "setting volume of « {} » to {}%".format(music.name, value) else: return "setting volume to {}%".format(value) def wait_print(self, duration = 0, music = None, **kwargs): if music is None: return "waiting {}s".format(duration) elif duration == 0: return "waiting the end of « {} »".format(music.name) else: return "waiting the end of « {} » + {}s".format(music.name, duration) # Interruptions def wait_interrupt(self, duration = 0, music = None, **kwargs): if self.sleep_event is not None: self.sleep_event.set() if music is not None: music.wait_event.set()