diff --git a/app/playlistmodel.py b/app/playlistmodel.py index afa3c35..8bbdefb 100644 --- a/app/playlistmodel.py +++ b/app/playlistmodel.py @@ -1,3 +1,5 @@ +import obsws_python as obs # type: ignore +import re from dataclasses import dataclass from datetime import datetime, timedelta from enum import auto, Enum @@ -35,6 +37,7 @@ from models import Playdates, PlaylistRows, Tracks HEADER_NOTES_COLUMN = 1 +scene_change_re = re.compile(r"SetScene=\[([^[\]]*)\]") class Col(Enum): @@ -234,6 +237,7 @@ class PlaylistModel(QAbstractTableModel): Actions required: - sanity check + - change OBS scene if needed - update display - update track times - update Playdates in database @@ -256,6 +260,9 @@ class PlaylistModel(QAbstractTableModel): ) return + # Check for OBS scene change + self.obs_scene_change(row_number) + # Update Playdates in database with Session() as session: Playdates(session, track_sequence.now.track_id) @@ -660,7 +667,9 @@ class PlaylistModel(QAbstractTableModel): Return True if row is a header row, else False """ - return self.playlist_rows[row_number].path == "" + if row_number in self.playlist_rows: + return self.playlist_rows[row_number].path == "" + return False def is_played_row(self, row_number: int) -> bool: """ @@ -893,6 +902,39 @@ class PlaylistModel(QAbstractTableModel): self.add_track_to_header(header_row_number, existing_prd.track_id, note) self.delete_rows([existing_prd.plr_rownum]) + def obs_scene_change(self, row_number: int) -> None: + """ + Check this row and any preceding headers for OBS scene change command + and execute any found + """ + + # Check any headers before this row + idx = row_number - 1 + while self.is_header_row(idx): + idx -= 1 + # Step through headers in row order and finish with this row + for chkrow in range(idx + 1, row_number + 1): + match_obj = scene_change_re.search(self.playlist_rows[chkrow].note) + if match_obj: + scene_name = match_obj.group(1) + if scene_name: + try: + cl = obs.ReqClient( + host=Config.OBS_HOST, + port=Config.OBS_PORT, + password=Config.OBS_PASSWORD, + ) + except ConnectionRefusedError: + log.error("OBS connection refused") + return + try: + cl.set_current_program_scene(scene_name) + log.info(f"OBS scene changed to '{scene_name}'") + continue + except obs.error.OBSSDKError as e: + log.error(f"OBS SDK error ({e})") + return + def open_in_audacity(self, row_number: int) -> None: """ Open track at passed row number in Audacity