End of Day WIP on marker support

This commit is contained in:
Matthew Stratford 2021-04-10 22:56:53 +01:00
parent 6718ddcf2d
commit cc861e2869
4 changed files with 105 additions and 3 deletions

View file

@ -20,7 +20,9 @@
# that we respond with something, FAIL or OKAY. The server doesn't like to be kept waiting.
# Stop the Pygame Hello message.
from logging import exception
import os
from types.marker import Marker
os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "hide"
from queue import Empty
@ -36,7 +38,7 @@ from mutagen.mp3 import MP3
from helpers.myradio_api import MyRadioAPI
from helpers.state_manager import StateManager
from helpers.logging_manager import LoggingManager
from plan import PlanItem
from types.plan import PlanItem
# TODO ENUM
@ -74,6 +76,7 @@ class Player:
"play_on_load": False,
"output": None,
"show_plan": [],
"markers": [],
}
__rate_limited_params = ["pos", "pos_offset", "pos_true", "remaining"]
@ -402,7 +405,48 @@ class Player:
return True
def ended(self):
def set_marker(self, timeslotitemid: int, marker_str: str):
set_loaded = False
success = True
try:
marker = Marker(marker_str)
except Exception as e:
self.logger.log.error("Failed to create Marker instance with {} {}: {}".format(timeslotitemid, marker_str, e))
return False
if timeslotitemid == -1:
set_loaded = True
if not self.isLoaded:
return False
timeslotitemid = self.state.state["loaded_item"]["timeslotitemid"]
for i in range(len(self.state.state["show_plan"])):
plan = self.state.state["show_plan"]
item = plan[i]
if item.timeslotitemid == timeslotitemid:
try:
item = item.set_marker(marker)
self.state.update("show_plan", plan)
except Exception as e:
self.logger.log.error(
"Failed to set marker on item {}: {} with marker \n{}".format(timeslotitemid, e, marker))
success = False
if set_loaded:
try:
self.state.update("loaded_item", self.state.state["show_plan"]["loaded_item"].set_marker(marker))
except Exception as e:
self.logger.log.error(
"Failed to set marker on loaded_item {}: {} with marker \n{}".format(timeslotitemid, e, marker))
success = False
return success
# Helper functions
def _ended(self):
loaded_item = self.state.state["loaded_item"]
# Track has ended
@ -459,7 +503,7 @@ class Player:
and not self.isPlaying
and not self.stopped_manually
):
self.ended()
self._ended()
self.state.update("playing", self.isPlaying)
self.state.update("loaded", self.isLoaded)
@ -656,6 +700,7 @@ class Player:
int(self.last_msg.split(":")[1]))
),
"CLEAR": lambda: self._retMsg(self.clear_channel_plan()),
"SETMARKER": lambda: self._retMsg(self.set_marker(self.last_msg.split(":")[1])),
}
message_type: str = self.last_msg.split(":")[0]

View file

@ -349,6 +349,8 @@ class TestPlayer(unittest.TestCase):
self.assertEquals(item["cue"], None)
self.assertEquals(item["markers"], markers[3:])
# TODO: Now test editing/deleting them
# runs the unit tests in the module
if __name__ == "__main__":

41
types/marker.py Normal file
View file

@ -0,0 +1,41 @@
import json
from typing import Dict, Optional, Union
POSITIONS = ["start", "mid", "end"]
PARAMS = ["name", "time", "position", "section"]
class Marker:
marker: Dict
def __init__(self, marker_str: str):
try:
marker = json.loads(marker_str)
except Exception as e:
raise ValueError("Failed to decode JSON for marker: {}".format(e))
for key in marker.keys():
if key not in PARAMS:
raise ValueError("Key {} is not a valid marker parameter.".format(key))
if not isinstance(marker["name"], str):
raise ValueError("Name is not str.")
self.name = marker["name"]
if not isinstance(marker["time"], Union[int, float]):
raise ValueError("Time is not a float or int")
if marker["position"] not in POSITIONS:
raise ValueError("Position is not in allowed values.")
if not isinstance(marker["section"], Optional[str]):
raise ValueError("Section name is not str or None.")
# If everything checks out, let's save it.
self.marker = marker
def __str__(self):
return json.dumps(self.marker)
def __dict__(self):
return self.marker

View file

@ -12,6 +12,7 @@
November 2020
"""
from types.marker import Marker
from typing import Any, Dict, Optional
import os
@ -90,6 +91,9 @@ class PlanItem:
"name": self.name,
"filename": self.filename,
"length": self.length,
"intro": self.intro,
"cue": self.cue,
"outro": self.outro,
}
def __init__(self, new_item: Dict[str, Any]):
@ -108,9 +112,19 @@ class PlanItem:
self._artist = new_item["artist"] if "artist" in new_item else None
self._length = new_item["length"]
# Edit this to handle markers when MyRadio supports them
self._
# Fix any OS specific / or \'s
if self.filename:
if os.path.sep == "/":
self._filename = self.filename.replace("\\", "/")
else:
self._filename = self.filename.replace("/", "\\")
def set_marker(self, marker: Marker):
if not isinstance(marker, Marker):
raise ValueError("Marker provided is not of type Marker.")
# Return updated item for easy chaining.
return self