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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Environment variables:
| Variable | Effect |
|---|---|
| `HYPERWALL_WEB=1` | Enable web remote on port 8585 (off by default) |
| `HYPERWALL_SERVER_URL` | Per-launch Emby endpoint override; leaves `config.ini` unchanged (use for LAN/public A/B) |
| `HYPERWALL_STATS=1` | Enable per-cell playback stats |
| `HYPERWALL_HWDEC` | Override hardware decoder (nvdec, d3d11va, etc.) |
| `HYPERWALL_VO` | Override video output (gpu-next, gpu) |
Expand Down
11 changes: 8 additions & 3 deletions hyperwall/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
)

from . import __version__, runtime_banner
from .config import HyperwallConfig, ConfigMissingError
from .config import HyperwallConfig, ConfigMissingError, effective_server_url
from .constants import (
CONFIG_FILE,
LOG_FILE,
Expand Down Expand Up @@ -275,8 +275,13 @@ def main() -> None:
sys.exit(1)

# 7. Emby client
server_url = effective_server_url(
cfg.server_url, os.environ.get("HYPERWALL_SERVER_URL")
)
if server_url != cfg.server_url:
logger.info("Endpoint override active for this launch: %s", server_url)
client = EmbyClient(
cfg.server_url, cfg.username, cfg.password, verify_ssl=cfg.verify_ssl,
server_url, cfg.username, cfg.password, verify_ssl=cfg.verify_ssl,
backend=resolve_backend(cfg.backend),
)
if not cfg.verify_ssl:
Expand All @@ -289,7 +294,7 @@ def main() -> None:
if not client.test_connection():
_show_error_dialog(
"Connection Error",
f"Cannot reach Emby server at:\n{cfg.server_url}",
f"Cannot reach Emby server at:\n{server_url}",
)
sys.exit(1)

Expand Down
10 changes: 10 additions & 0 deletions hyperwall/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
from .constants import CONFIG_FILE


def effective_server_url(configured: str, override: str | None = None) -> str:
"""Return a per-launch endpoint override without changing config.ini.

This supports controlled LAN-vs-public delivery tests while leaving the
user's normal configured endpoint and credentials untouched.
"""
candidate = (override or "").strip()
return candidate or configured


@dataclass(frozen=True)
class HyperwallConfig:
"""Immutable configuration loaded from config.ini."""
Expand Down
1 change: 1 addition & 0 deletions tests/run_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"test_platform",
"test_soak_telemetry",
"test_macos_playback_performance",
"test_endpoint_override",
]


Expand Down
42 changes: 42 additions & 0 deletions tests/test_endpoint_override.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Regression contract for ephemeral Hyperwall endpoint overrides.

A macOS playback A/B must be able to use Greg's LAN Emby endpoint without
rewriting a configured public endpoint or exposing credentials in commands.
"""
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from hyperwall.config import effective_server_url # noqa: E402


def test_endpoint_override_wins_without_mutating_default():
configured = "https://mb.perseus.observer"
override = "http://10.168.168.29:8096"
assert effective_server_url(configured, override) == override
assert configured == "https://mb.perseus.observer"


def test_blank_override_keeps_configured_endpoint():
assert effective_server_url("http://emby:8096", " ") == "http://emby:8096"
assert effective_server_url("http://emby:8096", None) == "http://emby:8096"


def run_all() -> int:
tests = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
passed = failed = 0
for test in tests:
try:
test()
passed += 1
print(f" PASS {test.__name__}")
except Exception as e: # noqa: BLE001
failed += 1
print(f" FAIL {test.__name__}: {e}")
print(f"\n{passed} passed, {failed} failed out of {len(tests)} tests.")
return failed


if __name__ == "__main__":
raise SystemExit(1 if run_all() else 0)
Loading