Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions clients/desktop/PlayPalace.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# -*- mode: python ; coding: utf-8 -*-

a = Analysis(
['client.py'],
pathex=[],
binaries=[],
datas=[('sounds', 'sounds')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)

exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='PlayPalace',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='PlayPalace',
)
app = BUNDLE(
coll,
name='PlayPalace.app',
icon=None,
bundle_identifier=None,
)
16 changes: 15 additions & 1 deletion clients/desktop/sound_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@

import logging
import os
import sys
import threading
import time
from pathlib import Path
from sound_cacher import SoundCacher

LOG = logging.getLogger(__name__)


def _default_sounds_folder() -> str:
"""Return the bundled sounds folder for source and PyInstaller runs."""
if getattr(sys, "frozen", False):
bundle_root = getattr(sys, "_MEIPASS", None)
if bundle_root:
candidate = Path(bundle_root) / "sounds"
if candidate.is_dir():
return str(candidate)
return str(Path(sys.executable).resolve().parent / "sounds")
return str(Path(__file__).resolve().parent / "sounds")


class AudioPlaylist:
"""Represents a playlist that can play either sounds or music tracks."""

Expand Down Expand Up @@ -326,7 +340,7 @@ def __init__(self):
self.current_music = None
self.current_music_name = None
self.music_volume = 0.2
self.sounds_folder = "sounds"
self.sounds_folder = _default_sounds_folder()

# Configurable menu sounds (can be changed by server)
self.menuclick_sound = "menuclick.ogg"
Expand Down
47 changes: 47 additions & 0 deletions clients/desktop/tests/test_sound_manager.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import os

import pytest

import sound_manager as sm_mod
Expand Down Expand Up @@ -41,6 +43,51 @@ def make_manager(tmp_path):
return manager


def test_default_sounds_folder_is_absolute():
manager = SoundManager()

assert manager.sounds_folder.endswith("sounds")
assert os.path.isabs(manager.sounds_folder)


def test_default_sounds_folder_uses_pyinstaller_meipass(monkeypatch, tmp_path):
bundle_root = tmp_path / "bundle"
(bundle_root / "sounds").mkdir(parents=True)
executable = tmp_path / "PlayPalace.app" / "Contents" / "MacOS" / "PlayPalace"

monkeypatch.setattr(sm_mod.sys, "frozen", True, raising=False)
monkeypatch.setattr(sm_mod.sys, "_MEIPASS", str(bundle_root), raising=False)
monkeypatch.setattr(sm_mod.sys, "executable", str(executable))

assert sm_mod._default_sounds_folder() == str(bundle_root / "sounds")


def test_default_sounds_folder_falls_back_when_meipass_sounds_missing(
monkeypatch, tmp_path
):
bundle_root = tmp_path / "_internal"
bundle_root.mkdir()
executable = tmp_path / "PlayPalace" / "PlayPalace.exe"

monkeypatch.setattr(sm_mod.sys, "frozen", True, raising=False)
monkeypatch.setattr(sm_mod.sys, "_MEIPASS", str(bundle_root), raising=False)
monkeypatch.setattr(sm_mod.sys, "executable", str(executable))

assert sm_mod._default_sounds_folder() == str(executable.parent / "sounds")


def test_default_sounds_folder_uses_frozen_executable_without_meipass(
monkeypatch, tmp_path
):
executable = tmp_path / "PlayPalace.app" / "Contents" / "MacOS" / "PlayPalace"

monkeypatch.setattr(sm_mod.sys, "frozen", True, raising=False)
monkeypatch.delattr(sm_mod.sys, "_MEIPASS", raising=False)
monkeypatch.setattr(sm_mod.sys, "executable", str(executable))

assert sm_mod._default_sounds_folder() == str(executable.parent / "sounds")


def test_play_passes_full_path(tmp_path):
(tmp_path / "click.ogg").write_bytes(b"123")
manager = make_manager(tmp_path)
Expand Down
Loading