diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-24 02:09:03 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-24 16:45:37 +0200 |
| commit | 1ba95852f4365d166411f8e6db175db84ec06ec1 (patch) | |
| tree | 726fe2a1b1f98b71522ad4b45adf8cd1cc8a7476 | |
| parent | 57737c05fbf7c482ba436ca8001e7a4b3097b434 (diff) | |
| download | meshbay-1ba95852f4365d166411f8e6db175db84ec06ec1.tar.gz | |
refactor(node): move the MusicBrainz switch to the Music mixin
An operator op that exists for one app lives with that app.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 files changed, 41 insertions, 39 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport.js b/packages/meshbay-hub/src/meshbay_hub/static/transport.js index 79cd8e1..fb698e8 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/transport.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/transport.js @@ -1763,7 +1763,7 @@ class MeshBayTransport { if (msg.type === 'error') throw new Error(msg.detail); if (msg.type === 'admin_challenge') { // Python's f"{bool}" is "True"/"False", not JS's lowercase — must - // match webrtc_server.py _do_musicbrainz_enabled byte-for-byte. + // match apps/music.py _do_musicbrainz_enabled byte-for-byte. const subject = enabled ? 'True' : 'False'; return this._authorizeAdminOp(msg, 'musicbrainz_enabled', subject, signFn); } diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/apps/music.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/apps/music.py index acd4187..f2b6fa5 100644 --- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/apps/music.py +++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/apps/music.py @@ -6,8 +6,10 @@ from pathlib import Path import blake3 from meshbay_common import MNP_VERSION +from meshbay_common.adminop import OP_MUSICBRAINZ_ENABLED from meshbay_common.protocol import MNP +from meshbay_node import ops from meshbay_node.roots import off_disk from meshbay_node.transport.webrtc.disk import _locate from meshbay_node.transport.webrtc.media_tools import _transcode_audio_to_aac @@ -205,3 +207,41 @@ class MusicMixin: "cover_thumb_hash": cover_thumb_hash, "confidence": meta.get("confidence", 1.0), }) + + def _do_musicbrainz_enabled(self, msg: dict) -> None: + """ + Whether MusicBrainz lookups run for this group at all. Per-group + from the start (docs/MESHBAY_DESIGN.md §9.8) — signed like + tmdb_enabled: it decides whether this group's members' + Music tab ever makes outbound MusicBrainz traffic. + """ + enabled = msg.get("enabled") + if not isinstance(enabled, bool): + self._send({"type": "error", "detail": "Missing or invalid 'enabled'"}) + return + if not self._has_admin_authority(): + self._send({"type": "error", "detail": "No authorized key for this"}) + return + self._issue_admin_challenge(OP_MUSICBRAINZ_ENABLED, str(enabled)) + + async def _admin_exec_musicbrainz_enabled( + self, pending: dict, transcript: bytes, sig: bytes, + ) -> None: + enabled = pending["subject"] == "True" + if not await self._verify_admin_sig(transcript, sig): + self._send({"type": "error", "detail": "Signature verification failed"}) + self._audit("admin_auth_failed", f"musicbrainz_enabled:{pending['subject']}") + return + try: + await self._run_op(ops.set_musicbrainz_enabled, self._group_id or "", enabled) + except ops.OpError as e: + self._send({"type": "error", "detail": e.message}) + return + self._audit("musicbrainz_enabled", pending["subject"]) + + notice = {"type": MNP.MUSICBRAINZ_ENABLED_ACK, "v": MNP_VERSION, "enabled": enabled} + for uid, session in list(self._peer_registry().items()): + try: + session._send(notice) + except Exception: + pass diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py index 5c4d76f..9afb06c 100644 --- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py +++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py @@ -2734,44 +2734,6 @@ class WebRTCPeerSession(MusicMixin, SubtitlesMixin): except Exception: pass - def _do_musicbrainz_enabled(self, msg: dict) -> None: - """ - Whether MusicBrainz lookups run for this group at all. Per-group - from the start (docs/MESHBAY_DESIGN.md §9.8) — signed like - tmdb_enabled: it decides whether this group's members' - Music tab ever makes outbound MusicBrainz traffic. - """ - enabled = msg.get("enabled") - if not isinstance(enabled, bool): - self._send({"type": "error", "detail": "Missing or invalid 'enabled'"}) - return - if not self._has_admin_authority(): - self._send({"type": "error", "detail": "No authorized key for this"}) - return - self._issue_admin_challenge(OP_MUSICBRAINZ_ENABLED, str(enabled)) - - async def _admin_exec_musicbrainz_enabled( - self, pending: dict, transcript: bytes, sig: bytes, - ) -> None: - enabled = pending["subject"] == "True" - if not await self._verify_admin_sig(transcript, sig): - self._send({"type": "error", "detail": "Signature verification failed"}) - self._audit("admin_auth_failed", f"musicbrainz_enabled:{pending['subject']}") - return - try: - await self._run_op(ops.set_musicbrainz_enabled, self._group_id or "", enabled) - except ops.OpError as e: - self._send({"type": "error", "detail": e.message}) - return - self._audit("musicbrainz_enabled", pending["subject"]) - - notice = {"type": MNP.MUSICBRAINZ_ENABLED_ACK, "v": MNP_VERSION, "enabled": enabled} - for uid, session in list(self._peer_registry().items()): - try: - session._send(notice) - except Exception: - pass - # Reconcile's backstop and the watchdog debounce (indexer.py # DirectoryIndexer) — how hard the node works on the operator's own # disk, not a member-facing permission. Signed for the same reason as |