refactor: move package from karaoke_maker to songtrace

This commit is contained in:
2026-07-27 18:14:23 -07:00
parent a3078bb2fc
commit 322f8eb98b
48 changed files with 62 additions and 62 deletions
+2 -2
View File
@@ -26,7 +26,7 @@ dependencies = [
dev = ["pytest", "playwright"]
[project.scripts]
karaoke-maker = "karaoke_maker.cli:main"
karaoke-maker = "songtrace.cli:main"
[build-system]
requires = ["setuptools>=68"]
@@ -36,7 +36,7 @@ build-backend = "setuptools.build_meta"
where = ["src"]
[tool.setuptools.package-data]
karaoke_maker = ["static/*", "static/fonts/*"]
songtrace = ["static/*", "static/fonts/*"]
[tool.pytest.ini_options]
testpaths = ["tests"]
+3 -3
View File
@@ -15,9 +15,9 @@ import httpx
import uvicorn
from playwright.sync_api import sync_playwright
from karaoke_maker.config import Config
from karaoke_maker.pipeline import PipelineError, PipelineResult
from karaoke_maker.web import create_app
from songtrace.config import Config
from songtrace.pipeline import PipelineError, PipelineResult
from songtrace.web import create_app
REPO_ROOT = Path(__file__).resolve().parent.parent
OUT_IMAGE = REPO_ROOT / "docs" / "images" / "webui.png"
+5 -5
View File
@@ -1,8 +1,8 @@
import json
from pathlib import Path
from karaoke_maker.config import Config
from karaoke_maker.pipeline import Ctx, SongInput
from karaoke_maker.stages import acquire
from songtrace.config import Config
from songtrace.pipeline import Ctx, SongInput
from songtrace.stages import acquire
def make_ctx(tmp_path, **kw):
inp = SongInput(title="T", artist="A", lyrics_text="x", **kw)
@@ -46,7 +46,7 @@ def test_outputs_are_meta_and_audio(tmp_path):
def test_requires_exactly_one_source(tmp_path):
import pytest
from karaoke_maker.pipeline import PipelineError
from songtrace.pipeline import PipelineError
ctx = make_ctx(tmp_path)
with pytest.raises(PipelineError):
acquire.acquire_stage().run(ctx)
@@ -73,7 +73,7 @@ def test_classify_no_thumbnail(tmp_path):
def test_classify_no_video_raises(tmp_path):
import pytest
from karaoke_maker.pipeline import PipelineError
from songtrace.pipeline import PipelineError
(tmp_path / "source_video.jpg").write_bytes(b"t")
with pytest.raises(PipelineError):
acquire._classify_downloads(tmp_path)
+4 -4
View File
@@ -2,10 +2,10 @@ import json
import pytest
from karaoke_maker.config import Config
from karaoke_maker.lyrics import normalize_lyrics
from karaoke_maker.pipeline import Ctx, PipelineError, SongInput
from karaoke_maker.stages import align
from songtrace.config import Config
from songtrace.lyrics import normalize_lyrics
from songtrace.pipeline import Ctx, PipelineError, SongInput
from songtrace.stages import align
LYRICS = "it's one two three\nfour five six seven eight"
+1 -1
View File
@@ -1,7 +1,7 @@
import numpy as np
import soundfile as sf
from karaoke_maker.audio_io import load_wav
from songtrace.audio_io import load_wav
def test_load_wav_mono(tmp_path):
+1 -1
View File
@@ -1,4 +1,4 @@
from karaoke_maker.cli import main
from songtrace.cli import main
def test_version(capsys):
assert main(["--version"]) == 0
+3 -3
View File
@@ -2,9 +2,9 @@ import os
import pytest
import karaoke_maker.cli as cli
from karaoke_maker.config import Config
from karaoke_maker.pipeline import PipelineError, PipelineResult
import songtrace.cli as cli
from songtrace.config import Config
from songtrace.pipeline import PipelineError, PipelineResult
def setup_cfg(monkeypatch, tmp_path):
+1 -1
View File
@@ -1,6 +1,6 @@
import pytest
from pathlib import Path
from karaoke_maker.config import Config, load_config
from songtrace.config import Config, load_config
def test_load_minimal(tmp_path):
+3 -3
View File
@@ -9,8 +9,8 @@ requires_full = pytest.mark.skipif(
@requires_full
def test_full_pipeline(tmp_path):
from karaoke_maker.config import load_config
from karaoke_maker.pipeline import SongInput, run_pipeline
from songtrace.config import load_config
from songtrace.pipeline import SongInput, run_pipeline
assert shutil.which("ffmpeg"), "ffmpeg required"
cfg = load_config()
cfg.output_dir = tmp_path / "out"
@@ -24,7 +24,7 @@ def test_full_pipeline(tmp_path):
result = run_pipeline(inp, cfg)
txts = list(result.output_dir.glob("*.txt"))
assert len(txts) == 1
from karaoke_maker.ultrastar import get_header, parse_ultrastar
from songtrace.ultrastar import get_header, parse_ultrastar
song = parse_ultrastar(txts[0].read_text(encoding="utf-8"))
assert get_header(song, "BPM") and get_header(song, "GAP")
assert len(song.body) > 20
+5 -5
View File
@@ -2,11 +2,11 @@ import json
import numpy as np
import pytest
from karaoke_maker.config import Config
from karaoke_maker.grid import scale_bpm, to_ultrastar
from karaoke_maker.pipeline import Ctx, PipelineError, SongInput
from karaoke_maker.stages import all_stages, grid as grid_stage_mod
from karaoke_maker.ultrastar import (
from songtrace.config import Config
from songtrace.grid import scale_bpm, to_ultrastar
from songtrace.pipeline import Ctx, PipelineError, SongInput
from songtrace.stages import all_stages, grid as grid_stage_mod
from songtrace.ultrastar import (
LineBreak, Note, get_header, parse_ultrastar,
)
+1 -1
View File
@@ -1,4 +1,4 @@
from karaoke_maker.lyrics import normalize_lyrics, alignment_token
from songtrace.lyrics import normalize_lyrics, alignment_token
RAW = """[Verse 1]
It's one two three
+4 -4
View File
@@ -2,13 +2,13 @@ import json
import numpy as np
import pytest
from karaoke_maker.config import Config
from karaoke_maker.notes import (
from songtrace.config import Config
from songtrace.notes import (
MIN_NOTE_SEC, TimedNote, build_notes, hz_to_ultrastar, segment_span,
syllabify,
)
from karaoke_maker.pipeline import Ctx, SongInput
from karaoke_maker.stages import all_stages, notes as notes_stage_mod
from songtrace.pipeline import Ctx, SongInput
from songtrace.stages import all_stages, notes as notes_stage_mod
def flat_pitch(duration=10.0, hz=261.63): # C4
+4 -4
View File
@@ -4,12 +4,12 @@ from pathlib import Path
import pytest
from PIL import Image
from karaoke_maker.config import Config
from karaoke_maker.pipeline import (
from songtrace.config import Config
from songtrace.pipeline import (
STAGE_ORDER, Ctx, PipelineError, SongInput, run_pipeline, song_slug,
)
from karaoke_maker.stages import all_stages, package
from karaoke_maker.ultrastar import get_header, parse_ultrastar
from songtrace.stages import all_stages, package
from songtrace.ultrastar import get_header, parse_ultrastar
SONG_TXT = ("#TITLE:T\n#ARTIST:A\n#MP3:A - T.mp3\n#COVER:A - T.jpg\n"
"#VIDEO:A - T.webm\n#BPM:200\n#GAP:0\n: 0 1 0 la\nE\n")
+2 -2
View File
@@ -1,7 +1,7 @@
import json
from pathlib import Path
from karaoke_maker.config import Config
from karaoke_maker.pipeline import SongInput, Stage, run_pipeline, song_slug
from songtrace.config import Config
from songtrace.pipeline import SongInput, Stage, run_pipeline, song_slug
def make_cfg(tmp_path):
return Config(whisper_url="http://x/v1", output_dir=tmp_path / "out",
+3 -3
View File
@@ -1,7 +1,7 @@
import numpy as np
from karaoke_maker.config import Config
from karaoke_maker.pipeline import Ctx, SongInput
from karaoke_maker.stages import pitch
from songtrace.config import Config
from songtrace.pipeline import Ctx, SongInput
from songtrace.stages import pitch
def test_pitch_stage_writes_npz(tmp_path, monkeypatch):
+3 -3
View File
@@ -3,9 +3,9 @@ from pathlib import Path
import pytest
from karaoke_maker.config import Config
from karaoke_maker.pipeline import STAGE_ORDER, PipelineError, SongInput
from karaoke_maker.rebuild import (FIELD_STAGE, changed_fields, plan,
from songtrace.config import Config
from songtrace.pipeline import STAGE_ORDER, PipelineError, SongInput
from songtrace.rebuild import (FIELD_STAGE, changed_fields, plan,
relocate_work, superseded_output)
+3 -3
View File
@@ -1,9 +1,9 @@
import numpy as np
import soundfile as sf
import torch
from karaoke_maker.config import Config
from karaoke_maker.pipeline import Ctx, SongInput
from karaoke_maker.stages import separate
from songtrace.config import Config
from songtrace.pipeline import Ctx, SongInput
from songtrace.stages import separate
def test_separate_writes_stems(tmp_path, monkeypatch):
+3 -3
View File
@@ -1,6 +1,6 @@
from karaoke_maker.lyrics import normalize_lyrics
from karaoke_maker.whisper_client import TranscriptSegment
from karaoke_maker.stages.transcribe import lyrics_similarity, vocal_sections
from songtrace.lyrics import normalize_lyrics
from songtrace.whisper_client import TranscriptSegment
from songtrace.stages.transcribe import lyrics_similarity, vocal_sections
def seg(s, e, t=""):
return TranscriptSegment(start=s, end=e, text=t)
+1 -1
View File
@@ -1,5 +1,5 @@
from pathlib import Path
from karaoke_maker.ultrastar import (
from songtrace.ultrastar import (
Note, LineBreak, parse_ultrastar, serialize_ultrastar,
get_header, format_bpm, parse_bpm,
)
+8 -8
View File
@@ -6,9 +6,9 @@ import time
import pytest
from fastapi.testclient import TestClient
from karaoke_maker.config import Config
from karaoke_maker.pipeline import STAGE_ORDER, PipelineError, PipelineResult, song_slug
from karaoke_maker.web import STAGE_LINE, create_app
from songtrace.config import Config
from songtrace.pipeline import STAGE_ORDER, PipelineError, PipelineResult, song_slug
from songtrace.web import STAGE_LINE, create_app
def make_client(tmp_path, runner):
@@ -190,7 +190,7 @@ def test_cover_upload_kept_after_success(tmp_path):
def test_cleanup_uploads_removes_an_inherited_upload_dir(tmp_path):
"""A rebuild's video may live under its parent's id, not its own."""
from karaoke_maker.web import _cleanup_uploads
from songtrace.web import _cleanup_uploads
cfg = Config(whisper_url="u", work_dir=tmp_path / "work",
output_dir=tmp_path / "out")
parent = cfg.work_dir / "uploads" / "parent"
@@ -201,7 +201,7 @@ def test_cleanup_uploads_removes_an_inherited_upload_dir(tmp_path):
def test_cleanup_uploads_ignores_paths_outside_the_upload_root(tmp_path):
from karaoke_maker.web import _cleanup_uploads
from songtrace.web import _cleanup_uploads
cfg = Config(whisper_url="u", work_dir=tmp_path / "work",
output_dir=tmp_path / "out")
outside = tmp_path / "somewhere" / "keep.mp4"
@@ -212,7 +212,7 @@ def test_cleanup_uploads_ignores_paths_outside_the_upload_root(tmp_path):
def test_cleanup_uploads_tolerates_a_missing_file(tmp_path):
from karaoke_maker.web import _cleanup_uploads
from songtrace.web import _cleanup_uploads
cfg = Config(whisper_url="u", work_dir=tmp_path / "work",
output_dir=tmp_path / "out")
_cleanup_uploads(cfg, "child", cfg.work_dir / "uploads" / "child" / "gone.mp4")
@@ -340,13 +340,13 @@ def test_fonts_are_served(tmp_path):
def test_font_licence_is_bundled():
from karaoke_maker.web import STATIC
from songtrace.web import STATIC
licence = (STATIC / "fonts" / "OFL.txt").read_text(encoding="utf-8", errors="replace")
assert "SIL OPEN FONT LICENSE" in licence.upper()
def _index_html():
from karaoke_maker.web import STATIC
from songtrace.web import STATIC
return (STATIC / "index.html").read_text(encoding="utf-8")
+2 -2
View File
@@ -1,7 +1,7 @@
import httpx
from pathlib import Path
from karaoke_maker.config import Config
from karaoke_maker.whisper_client import TranscriptSegment, transcribe
from songtrace.config import Config
from songtrace.whisper_client import TranscriptSegment, transcribe
def test_transcribe_parses_segments(tmp_path):
audio = tmp_path / "v.wav"