Commit Graph

9 Commits

Author SHA1 Message Date
user
ba1af461de fix: use gitleaks CLI instead of licensed action, fix lint errors
Some checks failed
CI / gitleaks (push) Failing after 10s
CI / lint (push) Successful in 18s
CI / test (3.11) (push) Failing after 19s
CI / test (3.12) (push) Failing after 20s
CI / test (3.13) (push) Failing after 20s
CI / build (push) Has been skipped
- Replace gitleaks-action (requires paid license) with direct CLI
  invocation -- same engine, no license needed
- Fix ruff I001 import sorting in voice.py and test_llm.py
- Remove unused imports: _chat_request (test_llm), Path (test_music)
- Remove unused assignment: original_spawn (test_voice)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 05:58:10 +01:00
user
c493583a71 feat: add !seek command and persist volume across restarts
Seek to absolute or relative positions mid-track via !seek. Supports
M:SS and plain seconds with +/- prefixes. Volume is now saved to
bot.state and restored on connect.
2026-02-22 03:31:35 +01:00
user
df20c154ca feat: download audio before playback, add !keep and !kept commands
Audio is now downloaded to data/music/ before playback begins,
eliminating CDN hiccups mid-stream. Falls back to streaming on
download failure. Files are deleted after playback unless marked
with !keep. stream_audio detects local files and uses a direct
ffmpeg pipeline (no yt-dlp).
2026-02-22 02:52:51 +01:00
user
ec55c2aef1 feat: auto-resume music on reconnect, sorcerer tier, cert auth
Auto-resume: save playback position on stream errors and cancellation,
restore automatically after reconnect or container restart once the
channel is silent. Plugin lifecycle hook (on_connected) ensures the
reconnect watcher starts without waiting for user commands.

Sorcerer tier: new permission level between oper and admin. Configured
via [mumble] sorcerers list in derp.toml.

Mumble cert auth: pass certfile/keyfile to pymumble for client
certificate authentication.

Fixes: stream_audio now re-raises CancelledError and Exception so
_play_loop detects failures correctly. Subprocess cleanup uses 3s
timeout. Graceful shutdown cancels background tasks before stopping
pymumble. Safe getattr for _opers in core plugin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 02:14:43 +01:00
user
f899241d73 feat: support relative volume adjustment (+N/-N)
!volume +10 increases by 10, !volume -5 decreases by 5.
Out-of-range results (below 0 or above 100) are rejected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 00:18:43 +01:00
user
f189cbd290 feat: add !resume to continue playback from last interruption
Tracks playback position via frame counting in stream_audio().
On stop/skip, saves URL + elapsed time to bot.state (SQLite).
!resume reloads the track and seeks to the saved position via
ffmpeg -ss. State persists across bot restarts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 00:15:39 +01:00
user
e4e1e219f0 feat: add YouTube search to !play and fix NA URL fallback
Non-URL input (e.g. !play classical music) searches YouTube for 10
results and picks one randomly. Also fixes --flat-playlist returning
"NA" as the URL for single videos by falling back to the original
input URL.
2026-02-21 23:52:01 +01:00
user
c5c61e63cc feat: expand YouTube playlists into individual queue tracks
_resolve_title replaced with _resolve_tracks using --flat-playlist to
enumerate playlist entries. cmd_play enqueues each track individually,
with truncation when the queue is nearly full. Single-video behavior
unchanged.
2026-02-21 23:32:16 +01:00
user
47b13c3f1f feat: add Mumble music playback with Opus streaming
ctypes libopus encoder (src/derp/opus.py), voice varint/packet builder
and stream_audio method on MumbleBot (src/derp/mumble.py), music plugin
with play/stop/skip/queue/np/volume commands (plugins/music.py).
Audio pipeline: yt-dlp|ffmpeg subprocess -> PCM -> Opus -> UDPTunnel.
67 new tests (1561 total).
2026-02-21 21:42:28 +01:00