start of showplans

This commit is contained in:
michael-grace 2020-11-15 19:34:13 +00:00
parent 249832e153
commit bd2b5b41a6
4 changed files with 61 additions and 57 deletions

12
plan.py
View file

@ -15,15 +15,16 @@
from typing import Dict from typing import Dict
import os import os
class PlanObject: class PlanObject:
_timeslotitemid: int = 0 _channel_weight: int = 0
_filename: str = "" _filename: str = ""
_title: str = "" _title: str = ""
_artist: str = "" _artist: str = ""
@property @property
def timeslotitemid(self) -> int: def channel_weight(self) -> int:
return self._timeslotitemid return self._channel_weight
@property @property
def filename(self) -> str: def filename(self) -> str:
@ -36,7 +37,7 @@ class PlanObject:
@property @property
def __dict__(self) -> Dict[str, any]: def __dict__(self) -> Dict[str, any]:
return { return {
"timeslotitemid": self.timeslotitemid, "channel_weight": self.channel_weight,
"title": self._title, "title": self._title,
"artist": self._artist, "artist": self._artist,
"name": self.name, "name": self.name,
@ -44,7 +45,7 @@ class PlanObject:
} }
def __init__(self, new_item: Dict[str, any]): def __init__(self, new_item: Dict[str, any]):
self._timeslotitemid = new_item["timeslotitemid"] self._channel_weight = new_item["channel_weight"]
self._filename = new_item["filename"] self._filename = new_item["filename"]
self._title = new_item["title"] self._title = new_item["title"]
self._artist = new_item["artist"] self._artist = new_item["artist"]
@ -54,4 +55,3 @@ class PlanObject:
self._filename = self.filename.replace("\\", '/') self._filename = self.filename.replace("\\", '/')
else: else:
self._filename = self.filename.replace("/", '\\') self._filename = self.filename.replace("/", '\\')

View file

@ -42,7 +42,6 @@ from helpers.state_manager import StateManager
from helpers.logging_manager import LoggingManager from helpers.logging_manager import LoggingManager
class Player(): class Player():
state = None state = None
running = False running = False
@ -63,7 +62,7 @@ class Player():
"remaining": 0, "remaining": 0,
"length": 0, "length": 0,
"auto_advance": True, "auto_advance": True,
"repeat": "NONE", #NONE, ONE or ALL "repeat": "NONE", # NONE, ONE or ALL
"play_on_load": False, "play_on_load": False,
"output": None, "output": None,
"show_plan": [] "show_plan": []
@ -134,7 +133,7 @@ class Player():
res = json.dumps(state) res = json.dumps(state)
return res return res
### Audio Playout Related Methods # Audio Playout Related Methods
def play(self, pos=0): def play(self, pos=0):
try: try:
@ -197,7 +196,7 @@ class Player():
def set_auto_advance(self, message: int) -> bool: def set_auto_advance(self, message: int) -> bool:
if message == 0: if message == 0:
self.state.update("auto_advance", False) self.state.update("auto_advance", False)
return True # It did it return True # It did it
elif message == 1: elif message == 1:
self.state.update("auto_advance", True) self.state.update("auto_advance", True)
return True return True
@ -214,23 +213,23 @@ class Player():
def set_play_on_load(self, message: int) -> bool: def set_play_on_load(self, message: int) -> bool:
if message == 0: if message == 0:
self.state.update("play_on_load", False) self.state.update("play_on_load", False)
return True # It did it return True # It did it
elif message == 1: elif message == 1:
self.state.update("play_on_load", True) self.state.update("play_on_load", True)
return True return True
else: else:
return False return False
### Show Plan Related Methods # Show Plan Related Methods
def add_to_plan(self, new_item: Dict[str, any]) -> bool: def add_to_plan(self, new_item: Dict[str, any]) -> bool:
self.state.update("show_plan", self.state.state["show_plan"] + [PlanObject(new_item)]) self.state.update("show_plan", self.state.state["show_plan"] + [PlanObject(new_item)])
return True return True
def remove_from_plan(self, timeslotitemid: int) -> bool: def remove_from_plan(self, channel_weight: int) -> bool:
plan_copy = copy.copy(self.state.state["show_plan"]) plan_copy = copy.copy(self.state.state["show_plan"])
for i in range(len(plan_copy)): for i in range(len(plan_copy)):
if plan_copy[i].timeslotitemid == timeslotitemid: if plan_copy[i].channel_weight == channel_weight:
plan_copy.remove(i) plan_copy.remove(i)
self.state.update("show_plan", plan_copy) self.state.update("show_plan", plan_copy)
return True return True
@ -240,25 +239,24 @@ class Player():
self.state.update("show_plan", []) self.state.update("show_plan", [])
return True return True
def load(self, timeslotitemid: int): def load(self, channel_weight: int):
if not self.isPlaying: if not self.isPlaying:
self.unload() self.unload()
updated: bool = False updated: bool = False
for i in range(len(self.state.state["show_plan"])): for i in range(len(self.state.state["show_plan"])):
if self.state.state["show_plan"][i].timeslotitemid == timeslotitemid: if self.state.state["show_plan"][i].channel_weight == channel_weight:
self.state.update("loaded_item", self.state.state["show_plan"][i]) self.state.update("loaded_item", self.state.state["show_plan"][i])
updated = True updated = True
break break
if not updated: if not updated:
print("Failed to find timeslotitemid:", timeslotitemid) print("Failed to find channel_weight:", channel_weight)
return False return False
filename: str = self.state.state["loaded_item"].filename filename: str = self.state.state["loaded_item"].filename
try: try:
self.logger.log.info("Loading file: " + str(filename)) self.logger.log.info("Loading file: " + str(filename))
mixer.music.load(filename) mixer.music.load(filename)
@ -313,7 +311,7 @@ class Player():
loadedItem = self.state.state["loaded_item"] loadedItem = self.state.state["loaded_item"]
if (loadedItem): if (loadedItem):
self.load(loadedItem.timeslotitemid) self.load(loadedItem.channel_weight)
if wasPlaying: if wasPlaying:
self.unpause() self.unpause()
@ -331,8 +329,6 @@ class Player():
self.state.update("playing", self.isPlaying) self.state.update("playing", self.isPlaying)
self.state.update("loaded", self.isLoaded) self.state.update("loaded", self.isLoaded)
self.state.update("pos_true", self.state.state["pos"] + self.state.state["pos_offset"]) self.state.update("pos_true", self.state.state["pos"] + self.state.state["pos_offset"])
self.state.update("remaining", self.state.state["length"] - self.state.state["pos_true"]) self.state.update("remaining", self.state.state["length"] - self.state.state["pos_true"])
@ -348,20 +344,19 @@ class Player():
# Auto Advance # Auto Advance
elif self.state.state["auto_advance"]: elif self.state.state["auto_advance"]:
for i in range(len(self.state.state["show_plan"])): for i in range(len(self.state.state["show_plan"])):
if self.state.state["show_plan"][i].timeslotitemid == self.state.state["loaded_item"].timeslotitemid: if self.state.state["show_plan"][i].channel_weight == self.state.state["loaded_item"].channel_weight:
if len(self.state.state["show_plan"]) > i+1: if len(self.state.state["show_plan"]) > i+1:
self.load(self.state.state["show_plan"][i+1].timeslotitemid) self.load(self.state.state["show_plan"][i+1].channel_weight)
break break
# Repeat All # Repeat All
elif self.state.state["repeat"] == "ALL": elif self.state.state["repeat"] == "ALL":
self.load(self.state.state["show_plan"][0].timeslotitemid) self.load(self.state.state["show_plan"][0].channel_weight)
# Play on Load # Play on Load
if self.state.state["play_on_load"]: if self.state.state["play_on_load"]:
self.play() self.play()
def _retMsg(self, msg, okay_str=False): def _retMsg(self, msg, okay_str=False):
response = self.last_msg + ":" response = self.last_msg + ":"
if msg == True: if msg == True:
@ -387,7 +382,8 @@ class Player():
self.logger = LoggingManager("channel" + str(channel)) self.logger = LoggingManager("channel" + str(channel))
self.state = StateManager("channel" + str(channel), self.logger, self.__default_state, self.__rate_limited_params) self.state = StateManager("channel" + str(channel), self.logger,
self.__default_state, self.__rate_limited_params)
self.state.update("channel", channel) self.state.update("channel", channel)
loaded_state = copy.copy(self.state.state) loaded_state = copy.copy(self.state.state)
@ -401,7 +397,7 @@ class Player():
if loaded_state["loaded_item"]: if loaded_state["loaded_item"]:
self.logger.log.info("Loading filename: " + loaded_state["loaded_item"].filename) self.logger.log.info("Loading filename: " + loaded_state["loaded_item"].filename)
self.load(loaded_state["loaded_item"].timeslotitemid) self.load(loaded_state["loaded_item"].channel_weight)
if loaded_state["pos_true"] != 0: if loaded_state["pos_true"] != 0:
self.logger.log.info("Seeking to pos_true: " + str(loaded_state["pos_true"])) self.logger.log.info("Seeking to pos_true: " + str(loaded_state["pos_true"]))
@ -434,26 +430,26 @@ class Player():
elif self.isInit: elif self.isInit:
message_types: Dict[str, Callable[any, bool]] = { # TODO Check Types message_types: Dict[str, Callable[any, bool]] = { # TODO Check Types
"STATUS": lambda: self._retMsg(self.status, True), "STATUS": lambda: self._retMsg(self.status, True),
# Audio Playout # Audio Playout
"PLAY": lambda: self._retMsg(self.play()), "PLAY": lambda: self._retMsg(self.play()),
"PAUSE": lambda: self._retMsg(self.pause()), "PAUSE": lambda: self._retMsg(self.pause()),
"UNPAUSE": lambda: self._retMsg(self.unpause()), "UNPAUSE": lambda: self._retMsg(self.unpause()),
"STOP": lambda: self._retMsg(self.stop()), "STOP": lambda: self._retMsg(self.stop()),
"SEEK": lambda: self._retMsg(self.seek(float(self.last_msg.split(":")[1]))), "SEEK": lambda: self._retMsg(self.seek(float(self.last_msg.split(":")[1]))),
"AUTOADVANCE": lambda: self._retMsg(self.set_auto_advance(int(self.last_msg.split(":")[1]))), "AUTOADVANCE": lambda: self._retMsg(self.set_auto_advance(int(self.last_msg.split(":")[1]))),
"REPEAT": lambda: self._retMsg(self.set_repeat(self.last_msg.split(":")[1])), "REPEAT": lambda: self._retMsg(self.set_repeat(self.last_msg.split(":")[1])),
"PLAYONLOAD": lambda: self._retMsg(self.set_play_on_load(int(self.last_msg.split(":")[1]))), "PLAYONLOAD": lambda: self._retMsg(self.set_play_on_load(int(self.last_msg.split(":")[1]))),
# Show Plan Items # Show Plan Items
"LOAD": lambda: self._retMsg(self.load(int(self.last_msg.split(":")[1]))), "LOAD": lambda: self._retMsg(self.load(int(self.last_msg.split(":")[1]))),
"LOADED?": lambda: self._retMsg(self.isLoaded), "LOADED?": lambda: self._retMsg(self.isLoaded),
"UNLOAD": lambda: self._retMsg(self.unload()), "UNLOAD": lambda: self._retMsg(self.unload()),
"ADD": lambda: self._retMsg(self.add_to_plan(json.loads(":".join(self.last_msg.split(":")[1:])))), "ADD": lambda: self._retMsg(self.add_to_plan(json.loads(":".join(self.last_msg.split(":")[1:])))),
"REMOVE": lambda: self._retMsg(self.remove_from_plan(int(self.last_msg.split(":")[1]))), "REMOVE": lambda: self._retMsg(self.remove_from_plan(int(self.last_msg.split(":")[1]))),
"CLEAR": lambda: self._retMsg(self.clear_channel_plan()) "CLEAR": lambda: self._retMsg(self.clear_channel_plan())
} }
message_type: str = self.last_msg.split(":")[0] message_type: str = self.last_msg.split(":")[0]

View file

@ -229,9 +229,9 @@ def playonload(channel: int, state: int):
# Channel Items # Channel Items
@app.route("/player/<int:channel>/load/<int:timeslotitemid>") @app.route("/player/<int:channel>/load/<int:channel_weight>")
def load(channel: int, timeslotitemid: int): def load(channel: int, channel_weight: int):
channel_to_q[channel].put("LOAD:" + str(timeslotitemid)) channel_to_q[channel].put("LOAD:" + str(channel_weight))
return ui_status() return ui_status()
@ -246,7 +246,7 @@ def unload(channel):
@app.route("/player/<int:channel>/add", methods=["POST"]) @app.route("/player/<int:channel>/add", methods=["POST"])
def add_to_plan(channel: int): def add_to_plan(channel: int):
new_item: Dict[str, any] = { new_item: Dict[str, any] = {
"timeslotitemid": int(request.form["timeslotitemid"]), "channel_weight": int(request.form["channel_weight"]),
"filename": request.form["filename"], "filename": request.form["filename"],
"title": request.form["title"], "title": request.form["title"],
"artist": request.form["artist"], "artist": request.form["artist"],
@ -257,17 +257,17 @@ def add_to_plan(channel: int):
return new_item return new_item
@app.route("/player/<int:channel>/move/<int:timeslotitemid>/<int:position>") @app.route("/player/<int:channel>/move/<int:channel_weight>/<int:position>")
def move_plan(channel: int, timeslotitemid: int, position: int): def move_plan(channel: int, channel_weight: int, position: int):
channel_to_q[channel].put("MOVE:" + json.dumps({"timeslotitemid": timeslotitemid, "position": position})) channel_to_q[channel].put("MOVE:" + json.dumps({"channel_weight": channel_weight, "position": position}))
# TODO Return # TODO Return
return True return True
@app.route("/player/<int:channel>/remove/<int:timeslotitemid>") @app.route("/player/<int:channel>/remove/<int:channel_weight>")
def remove_plan(channel: int, timeslotitemid: int): def remove_plan(channel: int, channel_weight: int):
channel_to_q[channel].put("REMOVE:" + timeslotitemid) channel_to_q[channel].put("REMOVE:" + channel_weight)
# TODO Return # TODO Return
return True return True
@ -385,7 +385,7 @@ def startServer():
text_to_speach.runAndWait() text_to_speach.runAndWait()
new_item: Dict[str, any] = { new_item: Dict[str, any] = {
"timeslotitemid": 0, "channel_weight": 0,
"filename": "dev/welcome.mp3", "filename": "dev/welcome.mp3",
"title": "Welcome to BAPSicle", "title": "Welcome to BAPSicle",
"artist": "University Radio York", "artist": "University Radio York",

View file

@ -28,15 +28,23 @@ async def websocket_handler(websocket, path):
elif data["command"] == "SEEK": elif data["command"] == "SEEK":
channel_to_q[channel].put("SEEK:" + str(data["time"])) channel_to_q[channel].put("SEEK:" + str(data["time"]))
elif data["command"] == "LOAD": elif data["command"] == "LOAD":
pass channel_to_q[channel].put("LOAD:" + str(data["weight"]))
elif data["command"] == "ADD":
new_item: Dict[str, any] = {
"channel_weight": int(data["weight"]),
"filename": "dev\\test.mp3",
"title": data["title"],
"artist": None
}
channel_to_q[channel].put("ADD:" + json.dumps(new_item))
asyncio.wait([await conn.send(message) for conn in baps_clients]) await asyncio.wait([conn.send(message) for conn in baps_clients])
except websockets.exceptions.ConnectionClosedError: except websockets.exceptions.ConnectionClosedError:
print("RIP {}".format(websocket)) print("RIP {}".format(websocket))
except Exception as e: except Exception as e:
print(e) print("Exception", e)
finally: finally:
baps_clients.remove(websocket) baps_clients.remove(websocket)