from typing import BinaryIO, Protocol from abc import abstractmethod from glob import glob import json from pathlib import Path from . import SoloTool class SessionManager(Protocol): @abstractmethod def getSessions(self) -> list[str]: raise NotImplementedError @abstractmethod def loadSession(self, key: str, player=None) -> SoloTool: raise NotImplementedError @abstractmethod def saveSession(self, soloTool: SoloTool, key: str) -> None: raise NotImplementedError @abstractmethod def addSong(self, name: str, content: BinaryIO) -> None: raise NotImplementedError class _FileSystemSessionManager(SessionManager): def __init__(self, songPool: str, sessionPath: str): self._songPool = Path(songPool) self._sessionPath = Path(sessionPath) def getSessions(self) -> list[str]: return [Path(f).stem for f in glob(f"{self._sessionPath}/*.json")] def loadSession(self, key: str, player=None) -> SoloTool: with open(self._sessionPath / f"{key}.json", "r") as f: session = json.load(f) st = SoloTool(self._songPool, player=player) for i, entry in enumerate(session): songPath = entry["path"] keyPoints = entry["key_points"] st.addSong(songPath) st._keyPoints[i] = keyPoints return st def saveSession(self, soloTool: SoloTool, key: str) -> None: session = [] for i, song in enumerate(soloTool.songs): entry = { "path": song, "key_points" : soloTool._keyPoints[i] } session.append(entry) with open(self._sessionPath / f"{key}.json", "w") as f: json.dump(session, f) def addSong(self, name: str, content: BinaryIO): from shutil import copyfileobj newSong = self._songPool / name with open(newSong, "wb") as f: copyfileobj(content, f) def getSessionManager(songPool: str, sessionPath: str) -> SessionManager: return _FileSystemSessionManager(songPool, sessionPath)