rekordbox-edit 0.6.0.dev14__tar.gz → 0.6.0.dev40__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. rekordbox_edit-0.6.0.dev40/.github/actions/e2e/action.yml +27 -0
  2. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/workflows/ci.yml +26 -1
  3. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.gitignore +3 -0
  4. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.pre-commit-config.yaml +2 -0
  5. rekordbox_edit-0.6.0.dev40/.readthedocs.yaml +22 -0
  6. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/CHANGELOG.md +71 -3
  7. rekordbox_edit-0.6.0.dev40/Makefile +42 -0
  8. rekordbox_edit-0.6.0.dev40/PKG-INFO +109 -0
  9. rekordbox_edit-0.6.0.dev40/README.md +89 -0
  10. rekordbox_edit-0.6.0.dev40/docker-compose.yml +14 -0
  11. rekordbox_edit-0.6.0.dev40/docs/api.md +28 -0
  12. rekordbox_edit-0.6.0.dev40/docs/commands/convert.md +46 -0
  13. rekordbox_edit-0.6.0.dev40/docs/commands/edit.md +48 -0
  14. rekordbox_edit-0.6.0.dev40/docs/commands/search.md +29 -0
  15. rekordbox_edit-0.6.0.dev40/docs/filtering.md +108 -0
  16. rekordbox_edit-0.6.0.dev40/docs/index.md +1 -0
  17. rekordbox_edit-0.6.0.dev40/mkdocs.yml +54 -0
  18. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/pyproject.toml +14 -1
  19. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/_click.py +12 -0
  20. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/cli/_utils.py +14 -1
  21. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/cli/convert.py +2 -1
  22. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/cli/edit.py +2 -1
  23. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/cli/main.py +7 -0
  24. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/cli/search.py +2 -1
  25. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/models.py +9 -1
  26. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/query.py +26 -0
  27. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/cli/test_search.py +48 -0
  28. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/cli/test_utils.py +16 -0
  29. rekordbox_edit-0.6.0.dev40/tests/e2e/Dockerfile +14 -0
  30. rekordbox_edit-0.6.0.dev40/tests/e2e/__init__.py +0 -0
  31. rekordbox_edit-0.6.0.dev40/tests/e2e/__snapshots__/test_journey/test_search_full_json_snapshot[macos].json +824 -0
  32. rekordbox_edit-0.6.0.dev40/tests/e2e/__snapshots__/test_journey/test_search_full_json_snapshot[windows].json +824 -0
  33. rekordbox_edit-0.6.0.dev40/tests/e2e/__snapshots__/test_journey.ambr +13 -0
  34. rekordbox_edit-0.6.0.dev40/tests/e2e/conftest.py +163 -0
  35. rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/macos/master.6.8.6.db +0 -0
  36. rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/windows/master.6.8.6.db +0 -0
  37. rekordbox_edit-0.6.0.dev40/tests/e2e/test_journey.py +213 -0
  38. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/test_models.py +28 -0
  39. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/test_query.py +49 -0
  40. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/uv.lock +317 -1
  41. rekordbox_edit-0.6.0.dev14/Makefile +0 -25
  42. rekordbox_edit-0.6.0.dev14/PKG-INFO +0 -262
  43. rekordbox_edit-0.6.0.dev14/README.md +0 -242
  44. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.agent-style/RULES.md +0 -0
  45. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.agent-style/claude-code.md +0 -0
  46. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/actions/build-release-notes/action.yml +0 -0
  47. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/actions/commitizen-bump/action.yml +0 -0
  48. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/actions/commitizen-bump/commitizen-bump.sh +0 -0
  49. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/actions/install/action.yml +0 -0
  50. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/actions/lint/action.yml +0 -0
  51. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/actions/test/action.yml +0 -0
  52. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/workflows/cd.yml +0 -0
  53. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/workflows/publish.yml +0 -0
  54. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.github/workflows/release.yml +0 -0
  55. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/.python-version +0 -0
  56. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/AGENTS.md +0 -0
  57. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/CLAUDE.md +0 -0
  58. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/CONTRIBUTING.md +0 -0
  59. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/LICENSE +0 -0
  60. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/codecov.yml +0 -0
  61. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/__init__.py +0 -0
  62. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/api/__init__.py +0 -0
  63. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/api/_utils.py +0 -0
  64. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/api/convert.py +0 -0
  65. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/api/edit.py +0 -0
  66. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/api/search.py +0 -0
  67. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/cli/__init__.py +0 -0
  68. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/display.py +0 -0
  69. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/logger.py +0 -0
  70. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/rekordbox_edit/utils.py +0 -0
  71. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/renovate.json5 +0 -0
  72. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/ruff.toml +0 -0
  73. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/__init__.py +0 -0
  74. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/api/__init__.py +0 -0
  75. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/api/test_convert.py +0 -0
  76. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/api/test_edit.py +0 -0
  77. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/api/test_search.py +0 -0
  78. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/api/test_utils.py +0 -0
  79. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/cli/__init__.py +0 -0
  80. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/cli/test_convert.py +0 -0
  81. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/cli/test_edit.py +0 -0
  82. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/cli/test_main.py +0 -0
  83. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/conftest.py +0 -0
  84. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track01.flac → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/01-flac-44_1k-16b.flac +0 -0
  85. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track02.flac → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/02-flac-96k-24b.flac +0 -0
  86. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track03.m4a → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/03-alac-44_1k-16b.m4a +0 -0
  87. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track04.m4a → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/04-alac-48k-24b.m4a +0 -0
  88. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track05.aiff → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/05-aiff-44_1k-16b.aiff +0 -0
  89. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track06.wav → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/06-wav-96k-24b.wav +0 -0
  90. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track07.mp3 → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/07-mp3-44_1k-320cbr.mp3 +0 -0
  91. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track08.mp3 → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/08-mp3-44_1k-v0vbr.mp3 +0 -0
  92. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track09.m4a → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/09-aac-44_1k-256kbps.m4a +0 -0
  93. /rekordbox_edit-0.6.0.dev14/tests/e2e/fixtures/audio/track10.flac → /rekordbox_edit-0.6.0.dev40/tests/e2e/fixtures/audio/10-/303/274/303/261/303/256c/303/266d/303/251-flac-44_1k-16b.flac" +0 -0
  94. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/test_display.py +0 -0
  95. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/test_logger.py +0 -0
  96. {rekordbox_edit-0.6.0.dev14 → rekordbox_edit-0.6.0.dev40}/tests/test_utils.py +0 -0
@@ -0,0 +1,27 @@
1
+ name: "Run E2E Tests"
2
+ description: "Install platform ffmpeg, set up Python, run the e2e journey suite"
3
+
4
+ runs:
5
+ using: "composite"
6
+ steps:
7
+ - name: Setup UV
8
+ uses: ./.github/actions/install
9
+
10
+ - name: Install ffmpeg (macOS)
11
+ if: runner.os == 'macOS'
12
+ shell: bash
13
+ run: brew install ffmpeg
14
+
15
+ - name: Install ffmpeg (Windows)
16
+ if: runner.os == 'Windows'
17
+ shell: pwsh
18
+ run: choco install ffmpeg -y
19
+
20
+ - name: Run e2e suite
21
+ shell: bash
22
+ env:
23
+ RBE_RUN_E2E: "1"
24
+ TZ: "UTC"
25
+ run: |
26
+ : "${RBE_DB_VERSION:?RBE_DB_VERSION must be set by the caller (matrix dimension).}"
27
+ uv run pytest tests/e2e --snapshot-warn-unused
@@ -66,16 +66,41 @@ jobs:
66
66
 
67
67
  - name: Run unit tests
68
68
  uses: ./.github/actions/test
69
+
70
+ e2e-tests:
71
+ name: 🎚️ E2E
72
+ needs: code-change
73
+ if: ${{ needs.code-change.outputs.should_skip != 'true' && !fromJSON(needs.code-change.outputs.paths_result || '{}').code.should_skip }}
74
+ strategy:
75
+ fail-fast: false
76
+ matrix:
77
+ os: ["macos-latest", "windows-latest"]
78
+ python-version: ["3.11", "3.14"]
79
+ rb-version: ["6.8.6"]
80
+ runs-on: ${{ matrix.os }}
81
+ env:
82
+ OS: ${{ matrix.os }}
83
+ PYTHON: ${{ matrix.python-version }}
84
+ RBE_DB_VERSION: ${{ matrix.rb-version }}
85
+
86
+ steps:
87
+ - name: Checkout code
88
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
89
+
90
+ - name: Run e2e tests
91
+ uses: ./.github/actions/e2e
92
+
69
93
  all-green:
70
94
  name: ✅ All Green
71
95
  if: always()
72
96
  needs:
73
97
  - lint
74
98
  - unit-tests
99
+ - e2e-tests
75
100
  runs-on: Ubuntu-latest
76
101
 
77
102
  steps:
78
103
  - uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1
79
104
  with:
80
- allowed-skips: unit-tests, lint
105
+ allowed-skips: unit-tests, lint, e2e-tests
81
106
  jobs: ${{ toJSON(needs) }}
@@ -49,3 +49,6 @@ Thumbs.db
49
49
 
50
50
  .claude
51
51
  docs/superpowers
52
+
53
+ # MkDocs build output
54
+ site/
@@ -7,7 +7,9 @@ repos:
7
7
  rev: v6.0.0
8
8
  hooks:
9
9
  - id: trailing-whitespace
10
+ exclude: '^tests/e2e/__snapshots__/'
10
11
  - id: end-of-file-fixer
12
+ exclude: '^tests/e2e/__snapshots__/'
11
13
  - id: check-yaml
12
14
  - id: check-added-large-files
13
15
  args: [--maxkb=1024]
@@ -0,0 +1,22 @@
1
+ # Read the Docs configuration file
2
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3
+
4
+ version: 2
5
+
6
+ build:
7
+ os: ubuntu-24.04
8
+ tools:
9
+ python: "3.13"
10
+ jobs:
11
+ create_environment:
12
+ - asdf plugin add uv
13
+ - asdf install uv latest
14
+ - asdf global uv latest
15
+ install:
16
+ - uv sync --frozen --group docs
17
+ build:
18
+ html:
19
+ - uv run --group docs mkdocs build --strict --site-dir $READTHEDOCS_OUTPUT/html
20
+
21
+ mkdocs:
22
+ configuration: mkdocs.yml
@@ -1,6 +1,74 @@
1
- ## v0.6.0.dev14 (2026-06-09)
2
-
3
-
1
+ ## v0.6.0.dev40 (2026-06-11)
2
+
3
+
4
+ - docs: add api reference page
5
+ - docs: add convert command page
6
+ - docs: add edit command page
7
+ - docs: add search command page
8
+ - docs: add filtering page
9
+ - docs: configure read the docs build
10
+ - docs: scaffold mkdocs material site
11
+ - docs: trim README to overview and quick start
12
+ - chore: add docs dependency group
13
+ - feat: add --last filter to return only the last N results
14
+ - feat: add --first filter to return only the first N results
15
+ - test(e2e): update windows snapshot with unicode representation
16
+ - test(e2e): force utf-8 encoding of stdout
17
+ - test(e2e): align TZ to UTC
18
+ - test(ci): parameterize the db version as an env var
19
+ - ci(e2e): add windows-latest to the e2e matrix
20
+ - test: add windows snapshots for e2e journey
21
+ - test(e2e): parameterize snapshots by fixture DB
22
+ - Routes the two contract snapshots through SNAPSHOT_KEY (macos/windows)
23
+ so the Windows fixture can land its own snapshot alongside the macOS
24
+ one. Docker reuses the macOS DB and therefore the macos key.
25
+ Renames the existing snapshot entries to the [macos] variant.
26
+ - test: adds 6.8.6 db fixture for windows
27
+ - test(e2e): pretty-print JSON snapshots via JSONSnapshotExtension
28
+ - The single-line raw CLI output made snapshot diffs unreadable when a contract
29
+ field changed. Use syrupy's JSONSnapshotExtension for the search-json test:
30
+ the parsed payload is dumped as indented JSON to its own .json file under
31
+ __snapshots__/test_journey/, so post-update diffs land per-field.
32
+ - The IDs snapshot stays on AmberExtension; it's already one short line.
33
+ - ci(e2e): add macos-latest e2e job to the matrix and require it
34
+ - Adds a new e2e-tests job to ci.yml matrix'd over macos-latest × Python
35
+ {3.11, 3.14}, wiring it into the all-green aggregate so branch protection
36
+ gates on it. Windows joins in a follow-up PR once a windows master.db
37
+ fixture exists.
38
+ - The composite action at .github/actions/e2e/ installs ffmpeg on the runner,
39
+ sets RBE_RUN_E2E=1, and runs pytest against tests/e2e directly.
40
+ - test(e2e): add docker leg and make targets
41
+ - Local e2e validation runs through a Linux container; the conftest refuses to
42
+ run on bare macOS/Windows. `make test-e2e-docker` builds the image (Python
43
+ 3.14 + ffmpeg + uv-synced project) and runs the journey suite;
44
+ `make test-e2e-snapshot-update` regenerates snapshots inside the container so
45
+ the host's working tree picks them up via the volume mount.
46
+ - `make test-e2e` runs the suite directly with uv; useful inside the container
47
+ itself or in CI runners where the platform check passes.
48
+ - test(e2e): add journey suite, conftest, and macOS snapshots
49
+ - A single ordered file walks search → edit → convert against the committed
50
+ macOS master.6.8.6.db, exercising filter narrowing, dry-run safety, stdin-pipe
51
+ edits, unicode metadata, and the convert row-swap. Snapshots lock the JSON
52
+ and IDs print contracts for `search`.
53
+ - The conftest gates the suite behind RBE_RUN_E2E=1 and refuses to run on
54
+ macOS/Windows outside CI, pointing local users at the Docker leg. The
55
+ canonical staging path is /private/tmp/rbedit-e2e/music — macOS resolves
56
+ /tmp through that symlink, so the DB stores the canonical form.
57
+ - Excludes tests/e2e/__snapshots__/ from the trailing-whitespace and
58
+ end-of-file pre-commit hooks; syrupy-generated whitespace is meaningful.
59
+ - test(e2e): register marker, exclude from default collection, add syrupy
60
+ - Adds the `e2e` pytest marker, sets `norecursedirs` so default `make test` runs
61
+ do not collect the suite, and pins syrupy>=5 for snapshot assertions.
62
+ - test: add macos 6.8.6 db fixture
63
+ - test(e2e): rename audio fixtures to property-encoded scheme
64
+ - Filenames now describe the audio's discriminating properties
65
+ (NN-<codec>-<rate>-<depth-or-bitrate>[-encmode].<ext>) so each file's purpose
66
+ is obvious in a directory listing and in test code. Codec stays in the name
67
+ even for unambiguous extensions to keep the convention uniform and to
68
+ disambiguate ALAC vs AAC inside .m4a.
69
+ - Required before Phase 3 (Rekordbox import) so master.db references the new
70
+ paths. Generator script and library table updated in gist
71
+ https://gist.github.com/jviall/18107ca35e0e7f38cf02ba50e3b9cc77
4
72
  - test(e2e): add 10-track audio fixture for end-to-end suite
5
73
  - Synthesized sine-wave audio covering FLAC (16/24-bit), ALAC, AIFF, WAV,
6
74
  MP3 (CBR + VBR), AAC, and a unicode-tagged FLAC. Used by the e2e journey
@@ -0,0 +1,42 @@
1
+ .PHONY: test test-e2e test-e2e-docker test-e2e-snapshot-update coverage lint format typecheck install-hooks run-hooks docs docs-build
2
+
3
+ test:
4
+ uv run pytest tests
5
+
6
+ RBE_DB_VERSION ?= 6.8.6
7
+
8
+ test-e2e:
9
+ RBE_DB_VERSION=$(RBE_DB_VERSION) uv run pytest tests/e2e --snapshot-warn-unused
10
+
11
+ test-e2e-docker:
12
+ RBE_DB_VERSION=$(RBE_DB_VERSION) docker compose run --rm e2e
13
+
14
+ test-e2e-snapshot-update:
15
+ RBE_DB_VERSION=$(RBE_DB_VERSION) docker compose run --rm e2e uv run pytest tests/e2e --snapshot-update
16
+
17
+ watch:
18
+ uv run ptw .
19
+
20
+ coverage:
21
+ uv run pytest tests --cov=rekordbox_edit --junitxml=.coverage/junit.xml --cov-report=term-missing --cov-report=html --cov-report=xml
22
+
23
+ lint:
24
+ uv run ruff check --fix
25
+
26
+ format:
27
+ uv run ruff format
28
+
29
+ typecheck:
30
+ uv run ty check
31
+
32
+ install-hooks:
33
+ uv run pre-commit install --hook-type pre-commit --hook-type commit-msg
34
+
35
+ run-hooks:
36
+ uv run pre-commit run --all-files
37
+
38
+ docs:
39
+ uv run --group docs mkdocs serve
40
+
41
+ docs-build:
42
+ uv run --group docs mkdocs build --strict
@@ -0,0 +1,109 @@
1
+ Metadata-Version: 2.4
2
+ Name: rekordbox-edit
3
+ Version: 0.6.0.dev40
4
+ Summary: Tools for managing and modifying a RekordBox library en-masse
5
+ Project-URL: Homepage, https://github.com/jviall/rekordbox-edit
6
+ Project-URL: Repository, https://github.com/jviall/rekordbox-edit
7
+ Project-URL: Issues, https://github.com/jviall/rekordbox-edit/issues
8
+ Author-email: James Viall <jamesviall@pm.me>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: bulk,convert,database,dj,edit,music,rekordbox
12
+ Requires-Python: >=3.11
13
+ Requires-Dist: click<=9.0.0,>=8.0.0
14
+ Requires-Dist: ffmpeg-python>=0.2.0
15
+ Requires-Dist: platformdirs<5.0.0,>=4.3.8
16
+ Requires-Dist: pydantic<3,>=2.0
17
+ Requires-Dist: pyrekordbox==0.4.4
18
+ Requires-Dist: rich<15.1.0,>=15.0.0
19
+ Description-Content-Type: text/markdown
20
+
21
+ # rekordbox-edit
22
+
23
+ [![Build](https://img.shields.io/github/actions/workflow/status/jviall/rekordbox-edit/cd.yml?branch=main&logo=github&style=flat)](https://github.com/jviall/rekordbox-edit/blob/main/.github/workflows/cd.yml)
24
+ [![Coverage](https://codecov.io/gh/jviall/rekordbox-edit/graph/badge.svg?token=ILZ1XHE61V)](https://codecov.io/gh/jviall/rekordbox-edit)
25
+ [![Version](https://img.shields.io/pypi/v/rekordbox-edit?style=flat)](https://pypi.org/project/rekordbox-edit/)
26
+ [![Platforms](https://img.shields.io/badge/platform-win%20%7C%20osx-blue?style=flat)](https://pypi.org/project/rekordbox-edit/)
27
+ [![License](https://img.shields.io/pypi/l/rekordbox-edit?color=lightgrey)](https://github.com/jviall/rekordbox-edit/blob/main/LICENSE)
28
+
29
+ A command-line tool for bulk operations on your Rekordbox library. Search tracks, edit metadata, and convert audio formats — updating your database while preserving all your cues, analysis, and metadata.
30
+
31
+ > [!CAUTION]
32
+ > This tool can modify your Rekordbox database and audio files. Always back up your data first.
33
+ > No warranty is provided--you assume all risk and liability of data loss in using this.
34
+ > See [Safety and Best Practices](#safety-and-best-practices)
35
+
36
+ **Full documentation: [rekordbox-edit.readthedocs.io](https://rekordbox-edit.readthedocs.io/)**
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ pip install rekordbox-edit
42
+ ```
43
+
44
+ **Requirements:**
45
+
46
+ - Python 3.11+
47
+ - FFmpeg (for audio conversion)
48
+
49
+ ## Quick Start
50
+
51
+ Search your library:
52
+
53
+ ```bash
54
+ rbe search --artist "Daft Punk" --format flac
55
+ rbe search --playlist "House Favorites"
56
+ ```
57
+
58
+ Edit track metadata:
59
+
60
+ ```bash
61
+ # Fix a typo across every matching title (previews and confirms first)
62
+ rbe edit --title "Teh" Title --match "Teh" --replace "The" --multi
63
+ ```
64
+
65
+ Convert audio files:
66
+
67
+ ```bash
68
+ # Preview what would be converted
69
+ rbe convert --artist "Daft Punk" --dry-run
70
+
71
+ # Convert all FLAC or WAV files to AIFF (default output format)
72
+ rbe convert --format flac --format wav --yes
73
+ ```
74
+
75
+ See the [documentation](https://rekordbox-edit.readthedocs.io/) for every command, the full filtering language, and scripting recipes.
76
+
77
+ ## Safety and Best Practices
78
+
79
+ **Before using this tool:**
80
+
81
+ 1. **Back up your Rekordbox database**
82
+
83
+ Rekordbox already keeps multiple backups. But every time you close it, it creates a fresh one and deletes the oldest, so repetitive exits will quickly make those backups fairly useless.
84
+
85
+ You should make manual copies of RB's database backups before using this. You can usually find them in `~/Library/Pioneer/rekordbox/` on macOS or `%APPDATA%\Pioneer\rekordbox\` on Windows.
86
+
87
+ 2. **Back up your music library**
88
+
89
+ If you don't have a back up already it's a very worthwhile investment, even if you don't plan to use this tool! Find yourself a cheap external drive, you won't regret it.
90
+
91
+ And generally limit the potential impact of a mistake by using filters to target a few tracks at a time e.g. `--artist "Crazy Frog" --first 5` before targeting a larger set, and always run with `--dry-run` first.
92
+
93
+ ## AI Usage
94
+
95
+ I believe it's important to be aware of and to disclose AI usage. In many ways it's being forced upon us without us having much choice in the matter, and it's a gross and oppressive experience. While it has lots of potential to benefit the common good, mostly it's only furthered capitalist greed.
96
+
97
+ I'm mostly attempting to thoughtfully disclose that generative AI _has_ been a significant tool in building out this project. I don't personally enjoy too much coding in my personal time, but I feel passionate about making `rekordbox-edit`--AI has admittedly helped me bridge that gap between my capacity and my vision. I'm a career professional software engineer who takes pride in their work, and I don't want to produce a vibe coded mess any more than you want to experience it. Please validate the quality of this project yourself--at the end of the day it's just code written by some stranger.
98
+
99
+ If it's any consolation, my main test subject has been my own 10,000+ track RekordBox library--a risk I do not take lightly!
100
+
101
+ ## Credits
102
+
103
+ This project exists thanks to [@dylanjones](https://github.com/dylanjones), the creator of [pyrekordbox](https://github.com/dylanljones/pyrekordbox), which provides the Python API for Rekordbox databases.
104
+
105
+ I built this tool to help correct my own bad habits and missteps in managing and organizing my rekordbox library. If it helps you too, great! If you find issues or have ideas, contributions are welcome.
106
+
107
+ ## Contributing
108
+
109
+ See [CONTRIBUTING.md](https://github.com/jviall/rekordbox-edit/blob/main/CONTRIBUTING.md) for development setup, testing, and contribution guidelines.
@@ -0,0 +1,89 @@
1
+ # rekordbox-edit
2
+
3
+ [![Build](https://img.shields.io/github/actions/workflow/status/jviall/rekordbox-edit/cd.yml?branch=main&logo=github&style=flat)](https://github.com/jviall/rekordbox-edit/blob/main/.github/workflows/cd.yml)
4
+ [![Coverage](https://codecov.io/gh/jviall/rekordbox-edit/graph/badge.svg?token=ILZ1XHE61V)](https://codecov.io/gh/jviall/rekordbox-edit)
5
+ [![Version](https://img.shields.io/pypi/v/rekordbox-edit?style=flat)](https://pypi.org/project/rekordbox-edit/)
6
+ [![Platforms](https://img.shields.io/badge/platform-win%20%7C%20osx-blue?style=flat)](https://pypi.org/project/rekordbox-edit/)
7
+ [![License](https://img.shields.io/pypi/l/rekordbox-edit?color=lightgrey)](https://github.com/jviall/rekordbox-edit/blob/main/LICENSE)
8
+
9
+ A command-line tool for bulk operations on your Rekordbox library. Search tracks, edit metadata, and convert audio formats — updating your database while preserving all your cues, analysis, and metadata.
10
+
11
+ > [!CAUTION]
12
+ > This tool can modify your Rekordbox database and audio files. Always back up your data first.
13
+ > No warranty is provided--you assume all risk and liability of data loss in using this.
14
+ > See [Safety and Best Practices](#safety-and-best-practices)
15
+
16
+ **Full documentation: [rekordbox-edit.readthedocs.io](https://rekordbox-edit.readthedocs.io/)**
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install rekordbox-edit
22
+ ```
23
+
24
+ **Requirements:**
25
+
26
+ - Python 3.11+
27
+ - FFmpeg (for audio conversion)
28
+
29
+ ## Quick Start
30
+
31
+ Search your library:
32
+
33
+ ```bash
34
+ rbe search --artist "Daft Punk" --format flac
35
+ rbe search --playlist "House Favorites"
36
+ ```
37
+
38
+ Edit track metadata:
39
+
40
+ ```bash
41
+ # Fix a typo across every matching title (previews and confirms first)
42
+ rbe edit --title "Teh" Title --match "Teh" --replace "The" --multi
43
+ ```
44
+
45
+ Convert audio files:
46
+
47
+ ```bash
48
+ # Preview what would be converted
49
+ rbe convert --artist "Daft Punk" --dry-run
50
+
51
+ # Convert all FLAC or WAV files to AIFF (default output format)
52
+ rbe convert --format flac --format wav --yes
53
+ ```
54
+
55
+ See the [documentation](https://rekordbox-edit.readthedocs.io/) for every command, the full filtering language, and scripting recipes.
56
+
57
+ ## Safety and Best Practices
58
+
59
+ **Before using this tool:**
60
+
61
+ 1. **Back up your Rekordbox database**
62
+
63
+ Rekordbox already keeps multiple backups. But every time you close it, it creates a fresh one and deletes the oldest, so repetitive exits will quickly make those backups fairly useless.
64
+
65
+ You should make manual copies of RB's database backups before using this. You can usually find them in `~/Library/Pioneer/rekordbox/` on macOS or `%APPDATA%\Pioneer\rekordbox\` on Windows.
66
+
67
+ 2. **Back up your music library**
68
+
69
+ If you don't have a back up already it's a very worthwhile investment, even if you don't plan to use this tool! Find yourself a cheap external drive, you won't regret it.
70
+
71
+ And generally limit the potential impact of a mistake by using filters to target a few tracks at a time e.g. `--artist "Crazy Frog" --first 5` before targeting a larger set, and always run with `--dry-run` first.
72
+
73
+ ## AI Usage
74
+
75
+ I believe it's important to be aware of and to disclose AI usage. In many ways it's being forced upon us without us having much choice in the matter, and it's a gross and oppressive experience. While it has lots of potential to benefit the common good, mostly it's only furthered capitalist greed.
76
+
77
+ I'm mostly attempting to thoughtfully disclose that generative AI _has_ been a significant tool in building out this project. I don't personally enjoy too much coding in my personal time, but I feel passionate about making `rekordbox-edit`--AI has admittedly helped me bridge that gap between my capacity and my vision. I'm a career professional software engineer who takes pride in their work, and I don't want to produce a vibe coded mess any more than you want to experience it. Please validate the quality of this project yourself--at the end of the day it's just code written by some stranger.
78
+
79
+ If it's any consolation, my main test subject has been my own 10,000+ track RekordBox library--a risk I do not take lightly!
80
+
81
+ ## Credits
82
+
83
+ This project exists thanks to [@dylanjones](https://github.com/dylanjones), the creator of [pyrekordbox](https://github.com/dylanljones/pyrekordbox), which provides the Python API for Rekordbox databases.
84
+
85
+ I built this tool to help correct my own bad habits and missteps in managing and organizing my rekordbox library. If it helps you too, great! If you find issues or have ideas, contributions are welcome.
86
+
87
+ ## Contributing
88
+
89
+ See [CONTRIBUTING.md](https://github.com/jviall/rekordbox-edit/blob/main/CONTRIBUTING.md) for development setup, testing, and contribution guidelines.
@@ -0,0 +1,14 @@
1
+ services:
2
+ e2e:
3
+ build:
4
+ context: .
5
+ dockerfile: tests/e2e/Dockerfile
6
+ environment:
7
+ RBE_RUN_E2E: "1"
8
+ RBE_DB_VERSION: "${RBE_DB_VERSION:?RBE_DB_VERSION must be set (e.g. 6.8.6)}"
9
+ TZ: "UTC"
10
+ volumes:
11
+ # Mount the source tree so generated snapshots flow back to the host;
12
+ # uv.lock is read from the image's pre-built .venv at /app/.venv.
13
+ - .:/app
14
+ - /app/.venv
@@ -0,0 +1,28 @@
1
+ # API Reference
2
+
3
+ Everything the CLI does is available from Python. The public surface is the three functions in `rekordbox_edit.api` and the Pydantic models in `rekordbox_edit.models` that describe their inputs and outputs.
4
+
5
+ ```python
6
+ from pyrekordbox import Rekordbox6Database
7
+ from rekordbox_edit.api import search
8
+ from rekordbox_edit.models import SearchArgs
9
+
10
+ db = Rekordbox6Database()
11
+ response = search(db, SearchArgs(artist=["Daft Punk"], format=["flac"], match_all=True))
12
+ for track in response.tracks:
13
+ print(track.ID, track.Title)
14
+ ```
15
+
16
+ `--print json` on any CLI command emits exactly these response envelopes, so the models below also document the JSON you get when scripting.
17
+
18
+ ## Functions
19
+
20
+ ::: rekordbox_edit.api.search
21
+
22
+ ::: rekordbox_edit.api.edit
23
+
24
+ ::: rekordbox_edit.api.convert
25
+
26
+ ## Models
27
+
28
+ ::: rekordbox_edit.models
@@ -0,0 +1,46 @@
1
+ # convert
2
+
3
+ Convert audio files between formats and update the Rekordbox database to point at the new files. Your cues, analysis, beatgrids, and all metadata are preserved.
4
+
5
+ ## Supported Formats
6
+
7
+ - **Input:** FLAC, AIFF, WAV (lossless only — lossy sources are skipped)
8
+ - **Output:** AIFF (default), FLAC, WAV, ALAC, or MP3 (320kbps CBR)
9
+
10
+ Tracks already in the target format are skipped, as are tracks whose output file already exists (override with `--overwrite`).
11
+
12
+ ## Originals: Delete or Keep
13
+
14
+ After a successful conversion the original file is **deleted** for lossless output (you can always convert back) and **kept** for MP3 output (the quality loss is one-way). Override either default with `--delete` or `--keep`.
15
+
16
+ ## Examples
17
+
18
+ ```bash
19
+ # Preview conversion
20
+ rbe convert --format-out aiff --format flac --dry-run
21
+
22
+ # Convert and skip confirmation
23
+ rbe convert --format-out wav --artist "Burial" --yes
24
+
25
+ # Convert to MP3 but delete originals
26
+ rbe convert --format-out mp3 --playlist "Export" --yes --delete
27
+
28
+ # Keep originals when converting to AIFF
29
+ rbe convert --format-out aiff --format flac --yes --keep
30
+
31
+ # Get just the IDs of files that would be converted
32
+ rbe convert --format-out aiff --format flac --print ids --dry-run
33
+
34
+ # Convert everything a search finds
35
+ rbe search --artist "Lauryn Hill" --print ids | rbe convert --yes
36
+ ```
37
+
38
+ `--interactive` confirms each file individually; like `edit`, converting while Rekordbox is open triggers a warning (or a refusal in scripting modes). See [Filtering](../filtering.md) for the full filter language.
39
+
40
+ ## Reference
41
+
42
+ ::: mkdocs-click
43
+ :module: rekordbox_edit.cli.convert
44
+ :command: convert_command
45
+ :prog_name: rbe convert
46
+ :depth: 1
@@ -0,0 +1,48 @@
1
+ # edit
2
+
3
+ Bulk-edit a metadata field on tracks in your Rekordbox database.
4
+
5
+ ```bash
6
+ rbe edit [OPTIONS] [TRACK-IDS]... FIELD
7
+ ```
8
+
9
+ `FIELD` names the metadata field to change. Currently `Title` is the only editable field; more are planned.
10
+
11
+ `--replace` supplies the new value. On its own it overwrites the whole field; add `--match PATTERN` to find that literal text within the field and replace only that portion:
12
+
13
+ ```bash
14
+ # Rename one track outright
15
+ rbe edit --exact-title "Untitled 3" Title --replace "Acid Rain"
16
+
17
+ # Fix a typo across many titles (substring replacement)
18
+ rbe edit --title "Teh" Title --match "Teh" --replace "The" --multi
19
+ ```
20
+
21
+ ## Safety Rails
22
+
23
+ - **Preview and confirm by default.** Without flags, `edit` shows every planned change and asks once before applying. `--interactive` confirms each track individually; `--dry-run` previews without writing; `--yes` skips the prompt.
24
+ - **Single-track by default.** When filters match more than one track, `edit` refuses unless you pass `--multi`. This keeps a too-broad filter from rewriting your whole library.
25
+ - **Rekordbox running:** editing while Rekordbox is open risks conflicts, so `edit` warns (or refuses, in scripting modes).
26
+
27
+ ## Examples
28
+
29
+ ```bash
30
+ # Preview a cleanup without touching the database
31
+ rbe edit --title "(Original Mix)" Title --match " (Original Mix)" --replace "" --multi --dry-run
32
+
33
+ # Apply it, confirming each track
34
+ rbe edit --title "(Original Mix)" Title --match " (Original Mix)" --replace "" --multi --interactive
35
+
36
+ # Pipe a search result in and edit those exact tracks
37
+ rbe search --playlist "Mislabeled" --print ids | rbe edit Title --match " " --replace " " --multi --yes
38
+ ```
39
+
40
+ See [Filtering](../filtering.md) for the full filter language.
41
+
42
+ ## Reference
43
+
44
+ ::: mkdocs-click
45
+ :module: rekordbox_edit.cli.edit
46
+ :command: edit_command
47
+ :prog_name: rbe edit
48
+ :depth: 1
@@ -0,0 +1,29 @@
1
+ # search
2
+
3
+ Find and display tracks in your Rekordbox database. `search` is read-only: it never modifies the database or your files, which makes it the safe way to rehearse a [filter](../filtering.md) before handing it to `edit` or `convert`.
4
+
5
+ ## Examples
6
+
7
+ ```bash
8
+ # Show all FLAC tracks by an artist
9
+ rbe search --artist "Aphex Twin" --format flac
10
+
11
+ # Get all the track IDs in a playlist
12
+ rbe search --playlist "Techno" --print ids
13
+
14
+ # Find tracks matching ALL filters (AND logic)
15
+ rbe search --artist "Burial" --album "Untrue" --match-all
16
+
17
+ # Feed results to another command
18
+ rbe search --artist "Lauryn Hill" --print ids | rbe convert --yes
19
+ ```
20
+
21
+ See [Filtering](../filtering.md) for the full filter language and piping recipes.
22
+
23
+ ## Reference
24
+
25
+ ::: mkdocs-click
26
+ :module: rekordbox_edit.cli.search
27
+ :command: search_command
28
+ :prog_name: rbe search
29
+ :depth: 1