rekordbox-edit 0.6.0.dev44__tar.gz → 0.6.0.dev48__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.
- rekordbox_edit-0.6.0.dev48/.github/actions/commit-check/action.yml +28 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/actions/install/action.yml +0 -4
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/actions/lint/action.yml +0 -6
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/workflows/ci.yml +15 -1
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/CHANGELOG.md +5 -1
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/CONTRIBUTING.md +12 -3
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/PKG-INFO +17 -13
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/README.md +16 -12
- rekordbox_edit-0.6.0.dev48/docs/api.md +92 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/docs/commands/convert.md +3 -1
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/docs/commands/edit.md +5 -5
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/docs/filtering.md +20 -21
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/mkdocs.yml +1 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/pyproject.toml +2 -2
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/api/convert.py +3 -3
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/models.py +17 -13
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/uv.lock +5 -5
- rekordbox_edit-0.6.0.dev44/docs/api.md +0 -28
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.agent-style/RULES.md +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.agent-style/claude-code.md +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/actions/build-release-notes/action.yml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/actions/commitizen-bump/action.yml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/actions/commitizen-bump/commitizen-bump.sh +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/actions/e2e/action.yml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/actions/test/action.yml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/workflows/cd.yml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/workflows/publish.yml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/workflows/release.yml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.gitignore +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.pre-commit-config.yaml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.python-version +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.readthedocs.yaml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/AGENTS.md +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/CLAUDE.md +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/LICENSE +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/Makefile +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/codecov.yml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/docker-compose.yml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/docs/commands/search.md +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/docs/index.md +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/docs/stylesheets/extra.css +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/__init__.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/_click.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/api/__init__.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/api/_utils.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/api/edit.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/api/search.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/cli/__init__.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/cli/_utils.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/cli/convert.py +2 -2
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/cli/edit.py +2 -2
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/cli/main.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/cli/search.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/display.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/logger.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/query.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/rekordbox_edit/utils.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/renovate.json5 +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/ruff.toml +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/__init__.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/api/__init__.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/api/test_convert.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/api/test_edit.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/api/test_search.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/api/test_utils.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/cli/__init__.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/cli/test_convert.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/cli/test_edit.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/cli/test_main.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/cli/test_search.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/cli/test_utils.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/conftest.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/Dockerfile +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/__init__.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/__snapshots__/test_journey/test_search_full_json_snapshot[macos].json +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/__snapshots__/test_journey/test_search_full_json_snapshot[windows].json +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/__snapshots__/test_journey.ambr +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/conftest.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/01-flac-44_1k-16b.flac +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/02-flac-96k-24b.flac +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/03-alac-44_1k-16b.m4a +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/04-alac-48k-24b.m4a +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/05-aiff-44_1k-16b.aiff +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/06-wav-96k-24b.wav +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/07-mp3-44_1k-320cbr.mp3 +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/08-mp3-44_1k-v0vbr.mp3 +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/09-aac-44_1k-256kbps.m4a +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/audio/10-/303/274/303/261/303/256c/303/266d/303/251-flac-44_1k-16b.flac" +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/macos/master.6.8.6.db +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/windows/master.6.8.6.db +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/test_journey.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/test_display.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/test_logger.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/test_models.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/test_query.py +0 -0
- {rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/test_utils.py +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: "Commit Check"
|
|
2
|
+
description: "Validate commit messages and the PR title against the Conventional Commits schema"
|
|
3
|
+
|
|
4
|
+
runs:
|
|
5
|
+
using: "composite"
|
|
6
|
+
steps:
|
|
7
|
+
- name: Checkout
|
|
8
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
9
|
+
with:
|
|
10
|
+
fetch-depth: 0
|
|
11
|
+
|
|
12
|
+
- name: Setup UV
|
|
13
|
+
uses: ./.github/actions/install
|
|
14
|
+
|
|
15
|
+
- name: Validate commit messages
|
|
16
|
+
shell: bash
|
|
17
|
+
run: |
|
|
18
|
+
uv run cz check --rev-range origin/main..HEAD
|
|
19
|
+
|
|
20
|
+
# The PR title becomes the commit message when a branch is squash-merged,
|
|
21
|
+
# so validate it too. Pass via env to avoid shell injection from the title.
|
|
22
|
+
- name: Validate PR title
|
|
23
|
+
if: ${{ github.event_name == 'pull_request' }}
|
|
24
|
+
shell: bash
|
|
25
|
+
env:
|
|
26
|
+
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
27
|
+
run: |
|
|
28
|
+
uv run cz check --message "$PR_TITLE"
|
{rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/actions/install/action.yml
RENAMED
|
@@ -8,10 +8,6 @@ runs:
|
|
|
8
8
|
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
9
9
|
with:
|
|
10
10
|
enable-cache: true
|
|
11
|
-
|
|
12
|
-
- name: Set up Python
|
|
13
|
-
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
|
|
14
|
-
with:
|
|
15
11
|
python-version: ${{ env.PYTHON }}
|
|
16
12
|
|
|
17
13
|
- name: Install dependencies
|
|
@@ -12,12 +12,6 @@ runs:
|
|
|
12
12
|
- name: Setup UV
|
|
13
13
|
uses: ./.github/actions/install
|
|
14
14
|
|
|
15
|
-
- name: Validate Conventional Commits
|
|
16
|
-
shell: bash
|
|
17
|
-
if: ${{ github.ref != 'refs/heads/main' }}
|
|
18
|
-
run: |
|
|
19
|
-
uv run cz check --rev-range origin/main..HEAD
|
|
20
|
-
|
|
21
15
|
- name: Run lint
|
|
22
16
|
shell: bash
|
|
23
17
|
run: |
|
|
@@ -31,6 +31,19 @@ jobs:
|
|
|
31
31
|
paths_ignore:
|
|
32
32
|
- '**/*.md'
|
|
33
33
|
|
|
34
|
+
commit-check:
|
|
35
|
+
name: 📝 Commits
|
|
36
|
+
if: ${{ github.event_name == 'pull_request' }}
|
|
37
|
+
runs-on: ubuntu-slim
|
|
38
|
+
env:
|
|
39
|
+
PYTHON: "3.14"
|
|
40
|
+
steps:
|
|
41
|
+
- name: Checkout code
|
|
42
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
43
|
+
|
|
44
|
+
- name: Validate commits and PR title
|
|
45
|
+
uses: ./.github/actions/commit-check
|
|
46
|
+
|
|
34
47
|
lint:
|
|
35
48
|
name: 🧺 Lint
|
|
36
49
|
runs-on: ubuntu-latest
|
|
@@ -94,6 +107,7 @@ jobs:
|
|
|
94
107
|
name: ✅ All Green
|
|
95
108
|
if: always()
|
|
96
109
|
needs:
|
|
110
|
+
- commit-check
|
|
97
111
|
- lint
|
|
98
112
|
- unit-tests
|
|
99
113
|
- e2e-tests
|
|
@@ -102,5 +116,5 @@ jobs:
|
|
|
102
116
|
steps:
|
|
103
117
|
- uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1
|
|
104
118
|
with:
|
|
105
|
-
allowed-skips: unit-tests, lint, e2e-tests
|
|
119
|
+
allowed-skips: commit-check, unit-tests, lint, e2e-tests
|
|
106
120
|
jobs: ${{ toJSON(needs) }}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
## v0.6.0.
|
|
1
|
+
## v0.6.0.dev48 (2026-06-12)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
- chore(deps): update dependency mkdocstrings to v1
|
|
5
|
+
- ci: setup python via setup-uv to fix cache key collisions
|
|
6
|
+
- ci: validate conventional commits always, check PR titles
|
|
7
|
+
- docs: clean up documentation
|
|
4
8
|
- chore(deps): update linters to v0.0.45 (#90)
|
|
5
9
|
- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
6
10
|
- refactor: rename CommandArgs types to CommandRequest
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Contributing to Rekordbox Bulk Edit
|
|
2
2
|
|
|
3
|
-
Thanks for your interest in contributing to this project! Python is not my expertise
|
|
3
|
+
Thanks for your interest in contributing to this project! I think I've done a good job thus far, but Python is not my expertise so I'm eager for those more seasoned than I to weigh in. One way or another, I hope you're here as a fellow DJ looking to make managing a RekordBox library easier :)
|
|
4
4
|
|
|
5
5
|
## Development Setup
|
|
6
6
|
|
|
@@ -59,15 +59,24 @@ Thanks for your interest in contributing to this project! Python is not my exper
|
|
|
59
59
|
# Run tests
|
|
60
60
|
make test
|
|
61
61
|
|
|
62
|
+
# Watch tests
|
|
63
|
+
make watch
|
|
64
|
+
|
|
62
65
|
# Run tests with coverage
|
|
63
66
|
make coverage
|
|
64
67
|
|
|
65
|
-
# Run linting
|
|
68
|
+
# Run linting, will auto-fix issues
|
|
66
69
|
make lint
|
|
67
70
|
|
|
71
|
+
# Run type-checking
|
|
72
|
+
make typcheck
|
|
73
|
+
|
|
68
74
|
# Run formatting
|
|
69
75
|
make format
|
|
70
76
|
|
|
77
|
+
# Run the docsite locally
|
|
78
|
+
make docs
|
|
79
|
+
|
|
71
80
|
# Run all pre-commit hooks on all files
|
|
72
81
|
make run-hooks
|
|
73
82
|
```
|
|
@@ -76,7 +85,7 @@ make run-hooks
|
|
|
76
85
|
|
|
77
86
|
This project uses and enforces [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). The allowable types of commits are:
|
|
78
87
|
|
|
79
|
-
- `BREAKING
|
|
88
|
+
- `BREAKING` or `feat!`: introduces breaking changes (major bump)
|
|
80
89
|
- `feat`: introduces new features (minor bump)
|
|
81
90
|
- `fix`: patches a bug, upgrades a dependency (minor bump)
|
|
82
91
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rekordbox-edit
|
|
3
|
-
Version: 0.6.0.
|
|
3
|
+
Version: 0.6.0.dev48
|
|
4
4
|
Summary: Tools for managing and modifying a RekordBox library en-masse
|
|
5
5
|
Project-URL: Homepage, https://github.com/jviall/rekordbox-edit
|
|
6
6
|
Project-URL: Repository, https://github.com/jviall/rekordbox-edit
|
|
@@ -26,13 +26,17 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
[](https://pypi.org/project/rekordbox-edit/)
|
|
27
27
|
[](https://github.com/jviall/rekordbox-edit/blob/main/LICENSE)
|
|
28
28
|
|
|
29
|
-
A command-line tool for bulk operations on your Rekordbox library. Search tracks, edit metadata, and convert audio formats
|
|
29
|
+
A command-line tool for bulk operations on your Rekordbox library. Search tracks, edit metadata, and convert between audio formats with the benefit of database updates that preserve all your cues, analyses, and metadata.
|
|
30
30
|
|
|
31
31
|
> [!CAUTION]
|
|
32
32
|
> This tool can modify your Rekordbox database and audio files. Always back up your data first.
|
|
33
33
|
> No warranty is provided--you assume all risk and liability of data loss in using this.
|
|
34
34
|
> See [Safety and Best Practices](#safety-and-best-practices)
|
|
35
35
|
|
|
36
|
+
> [!WARNING]
|
|
37
|
+
> This project is in active development with no stable version released yet.
|
|
38
|
+
> Breaking changes are likely to occur across version 0 releases until the API and behavior stabilizes.
|
|
39
|
+
|
|
36
40
|
**Full documentation: [rekordbox-edit.readthedocs.io](https://rekordbox-edit.readthedocs.io/)**
|
|
37
41
|
|
|
38
42
|
## Installation
|
|
@@ -58,7 +62,7 @@ rbe search --playlist "House Favorites"
|
|
|
58
62
|
Edit track metadata:
|
|
59
63
|
|
|
60
64
|
```bash
|
|
61
|
-
# Fix a typo across every matching title
|
|
65
|
+
# Fix a typo across every matching track title
|
|
62
66
|
rbe edit --title "Teh" Title --match "Teh" --replace "The" --multi
|
|
63
67
|
```
|
|
64
68
|
|
|
@@ -68,8 +72,8 @@ Convert audio files:
|
|
|
68
72
|
# Preview what would be converted
|
|
69
73
|
rbe convert --artist "Daft Punk" --dry-run
|
|
70
74
|
|
|
71
|
-
# Convert all FLAC or WAV files to AIFF
|
|
72
|
-
rbe convert --format flac --format wav --yes
|
|
75
|
+
# Convert all FLAC or WAV files to AIFF without confirming
|
|
76
|
+
rbe convert --format flac --format wav --format-out aiff --yes
|
|
73
77
|
```
|
|
74
78
|
|
|
75
79
|
See the [documentation](https://rekordbox-edit.readthedocs.io/) for every command, the full filtering language, and scripting recipes.
|
|
@@ -88,21 +92,21 @@ See the [documentation](https://rekordbox-edit.readthedocs.io/) for every comman
|
|
|
88
92
|
|
|
89
93
|
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
94
|
|
|
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.
|
|
95
|
+
And more generally you should 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
96
|
|
|
93
|
-
##
|
|
97
|
+
## Credits
|
|
94
98
|
|
|
95
|
-
|
|
99
|
+
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 interacting with the Rekordbox database.
|
|
96
100
|
|
|
97
|
-
I
|
|
101
|
+
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.
|
|
98
102
|
|
|
99
|
-
|
|
103
|
+
## AI Usage
|
|
100
104
|
|
|
101
|
-
|
|
105
|
+
I believe it's important to be aware of and to disclose AI usage. The way its presence and usage is forced on us from every direction is too often gross and oppressive, and it's used almost exclusively for capitalist profit.
|
|
102
106
|
|
|
103
|
-
|
|
107
|
+
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 goals of completing it. This being said, 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 a stranger on the internet!
|
|
104
108
|
|
|
105
|
-
|
|
109
|
+
p.s. 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. :3
|
|
106
110
|
|
|
107
111
|
## Contributing
|
|
108
112
|
|
|
@@ -6,13 +6,17 @@
|
|
|
6
6
|
[](https://pypi.org/project/rekordbox-edit/)
|
|
7
7
|
[](https://github.com/jviall/rekordbox-edit/blob/main/LICENSE)
|
|
8
8
|
|
|
9
|
-
A command-line tool for bulk operations on your Rekordbox library. Search tracks, edit metadata, and convert audio formats
|
|
9
|
+
A command-line tool for bulk operations on your Rekordbox library. Search tracks, edit metadata, and convert between audio formats with the benefit of database updates that preserve all your cues, analyses, and metadata.
|
|
10
10
|
|
|
11
11
|
> [!CAUTION]
|
|
12
12
|
> This tool can modify your Rekordbox database and audio files. Always back up your data first.
|
|
13
13
|
> No warranty is provided--you assume all risk and liability of data loss in using this.
|
|
14
14
|
> See [Safety and Best Practices](#safety-and-best-practices)
|
|
15
15
|
|
|
16
|
+
> [!WARNING]
|
|
17
|
+
> This project is in active development with no stable version released yet.
|
|
18
|
+
> Breaking changes are likely to occur across version 0 releases until the API and behavior stabilizes.
|
|
19
|
+
|
|
16
20
|
**Full documentation: [rekordbox-edit.readthedocs.io](https://rekordbox-edit.readthedocs.io/)**
|
|
17
21
|
|
|
18
22
|
## Installation
|
|
@@ -38,7 +42,7 @@ rbe search --playlist "House Favorites"
|
|
|
38
42
|
Edit track metadata:
|
|
39
43
|
|
|
40
44
|
```bash
|
|
41
|
-
# Fix a typo across every matching title
|
|
45
|
+
# Fix a typo across every matching track title
|
|
42
46
|
rbe edit --title "Teh" Title --match "Teh" --replace "The" --multi
|
|
43
47
|
```
|
|
44
48
|
|
|
@@ -48,8 +52,8 @@ Convert audio files:
|
|
|
48
52
|
# Preview what would be converted
|
|
49
53
|
rbe convert --artist "Daft Punk" --dry-run
|
|
50
54
|
|
|
51
|
-
# Convert all FLAC or WAV files to AIFF
|
|
52
|
-
rbe convert --format flac --format wav --yes
|
|
55
|
+
# Convert all FLAC or WAV files to AIFF without confirming
|
|
56
|
+
rbe convert --format flac --format wav --format-out aiff --yes
|
|
53
57
|
```
|
|
54
58
|
|
|
55
59
|
See the [documentation](https://rekordbox-edit.readthedocs.io/) for every command, the full filtering language, and scripting recipes.
|
|
@@ -68,21 +72,21 @@ See the [documentation](https://rekordbox-edit.readthedocs.io/) for every comman
|
|
|
68
72
|
|
|
69
73
|
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
74
|
|
|
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.
|
|
75
|
+
And more generally you should 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
76
|
|
|
73
|
-
##
|
|
77
|
+
## Credits
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
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 interacting with the Rekordbox database.
|
|
76
80
|
|
|
77
|
-
I
|
|
81
|
+
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.
|
|
78
82
|
|
|
79
|
-
|
|
83
|
+
## AI Usage
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
I believe it's important to be aware of and to disclose AI usage. The way its presence and usage is forced on us from every direction is too often gross and oppressive, and it's used almost exclusively for capitalist profit.
|
|
82
86
|
|
|
83
|
-
|
|
87
|
+
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 goals of completing it. This being said, 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 a stranger on the internet!
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
p.s. 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. :3
|
|
86
90
|
|
|
87
91
|
## Contributing
|
|
88
92
|
|
|
@@ -0,0 +1,92 @@
|
|
|
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 SearchRequest
|
|
9
|
+
|
|
10
|
+
db = Rekordbox6Database()
|
|
11
|
+
response = search(db, SearchRequest(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
|
+
The models form three layers: the [`FilterArgs`][rekordbox_edit.models.FilterArgs] base that every command shares, the per-command requests and responses, and the lower-level domain types those req/resp models are built from.
|
|
29
|
+
|
|
30
|
+
::: rekordbox_edit.models.FilterArgs
|
|
31
|
+
options:
|
|
32
|
+
heading_level: 3
|
|
33
|
+
|
|
34
|
+
### Search
|
|
35
|
+
|
|
36
|
+
::: rekordbox_edit.models.SearchRequest
|
|
37
|
+
options:
|
|
38
|
+
heading_level: 4
|
|
39
|
+
|
|
40
|
+
::: rekordbox_edit.models.SearchResponse
|
|
41
|
+
options:
|
|
42
|
+
heading_level: 4
|
|
43
|
+
|
|
44
|
+
### Edit
|
|
45
|
+
|
|
46
|
+
::: rekordbox_edit.models.EditRequest
|
|
47
|
+
options:
|
|
48
|
+
heading_level: 4
|
|
49
|
+
|
|
50
|
+
::: rekordbox_edit.models.EditResponse
|
|
51
|
+
options:
|
|
52
|
+
heading_level: 4
|
|
53
|
+
|
|
54
|
+
::: rekordbox_edit.models.EditResult
|
|
55
|
+
options:
|
|
56
|
+
heading_level: 4
|
|
57
|
+
|
|
58
|
+
### Convert
|
|
59
|
+
|
|
60
|
+
::: rekordbox_edit.models.ConvertRequest
|
|
61
|
+
options:
|
|
62
|
+
heading_level: 4
|
|
63
|
+
|
|
64
|
+
::: rekordbox_edit.models.ConvertResponse
|
|
65
|
+
options:
|
|
66
|
+
heading_level: 4
|
|
67
|
+
|
|
68
|
+
::: rekordbox_edit.models.ConvertResult
|
|
69
|
+
options:
|
|
70
|
+
heading_level: 4
|
|
71
|
+
|
|
72
|
+
### Miscellaneous
|
|
73
|
+
|
|
74
|
+
::: rekordbox_edit.models.Track
|
|
75
|
+
options:
|
|
76
|
+
heading_level: 4
|
|
77
|
+
|
|
78
|
+
::: rekordbox_edit.models.EditOp
|
|
79
|
+
options:
|
|
80
|
+
heading_level: 4
|
|
81
|
+
|
|
82
|
+
::: rekordbox_edit.models.ConvertOp
|
|
83
|
+
options:
|
|
84
|
+
heading_level: 4
|
|
85
|
+
|
|
86
|
+
::: rekordbox_edit.models.SkippedTrack
|
|
87
|
+
options:
|
|
88
|
+
heading_level: 4
|
|
89
|
+
|
|
90
|
+
::: rekordbox_edit.models.SkipReason
|
|
91
|
+
options:
|
|
92
|
+
heading_level: 4
|
|
@@ -35,7 +35,9 @@ rbe convert --format-out aiff --format flac --print ids --dry-run
|
|
|
35
35
|
rbe search --artist "Lauryn Hill" --print ids | rbe convert --yes
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
### Guardrails
|
|
39
|
+
- Without flags, `convert` shows every planned change and asks once before applying. `--interactive` confirms each track individually; `--dry-run` previews without writing; `--yes` confirms the default choice for all prompts without asking.
|
|
40
|
+
- Editing while Rekordbox is open risks corrupting your database. By default `convert` warns; in a non-interactive mode (e.g. `--print ids`) it throws an error.
|
|
39
41
|
|
|
40
42
|
## Reference
|
|
41
43
|
|
|
@@ -6,7 +6,7 @@ Bulk-edit a metadata field on tracks in your Rekordbox database.
|
|
|
6
6
|
rbe edit [OPTIONS] [TRACK-IDS]... FIELD
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
`FIELD`
|
|
9
|
+
`FIELD` specifies the [DjmdContent](https://pyrekordbox.readthedocs.io/en/latest/formats/db6.html#djmdcontent) column to change. Currently `Title` is the only editable field; more are planned.
|
|
10
10
|
|
|
11
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
12
|
|
|
@@ -18,11 +18,11 @@ rbe edit --exact-title "Untitled 3" Title --replace "Acid Rain"
|
|
|
18
18
|
rbe edit --title "Teh" Title --match "Teh" --replace "The" --multi
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Guardrails
|
|
22
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`
|
|
24
|
-
- **Single-track by default.** When filters match more than one track, `edit` refuses unless you pass `--multi`. This
|
|
25
|
-
- **Rekordbox running:** editing while Rekordbox is open risks
|
|
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` confirms the default choice for all prompts without asking.
|
|
24
|
+
- **Single-track by default.** When filters match more than one track, `edit` refuses unless you pass `--multi`. This prevents an unintentionally broad filter from making unintended edits across your library.
|
|
25
|
+
- **Rekordbox running:** editing while Rekordbox is open risks corrupting your database. By default `edit` warns; in a non-interactive mode (e.g. `--print ids`) it throws an error.
|
|
26
26
|
|
|
27
27
|
## Examples
|
|
28
28
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Filtering
|
|
2
2
|
|
|
3
|
-
Every command
|
|
3
|
+
Every command supports filtering by all of the [`FilterArgs`][rekordbox_edit.models.FilterArgs]. The filters determine which tracks a command operates on.
|
|
4
4
|
|
|
5
5
|
## Filter Options
|
|
6
6
|
|
|
7
|
-
Repeating a filter, or combining different filters, matches tracks that satisfy *any* of
|
|
7
|
+
Repeating a filter, or combining different filters, matches tracks that satisfy *any* of the provided filters. Pass `--match-all` to require *every* filter to match.
|
|
8
8
|
|
|
9
9
|
| Option | Matches tracks whose... |
|
|
10
10
|
| --- | --- |
|
|
@@ -20,11 +20,17 @@ Repeating a filter, or combining different filters, matches tracks that satisfy
|
|
|
20
20
|
| `--format FMT` | file format is `FMT` (`mp3`, `flac`, `aiff`, `wav`, `m4a`) |
|
|
21
21
|
| `--path TEXT` | file path contains `TEXT` (matched against the folder path, filename, or both) |
|
|
22
22
|
| `--exact-path TEXT` | file path is exactly `TEXT` (resolved to an absolute path before matching) |
|
|
23
|
+
| `--first N` | return only the first N results |
|
|
24
|
+
| `--last N` | return only the last N results |
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
> [!TIP]
|
|
27
|
+
> Filters that are "exact" are case-sensitive (e.g. `--exact-artist 'HOOBASTANK'` won't match "Hoobastank") whereas their counterparts (`--artist`) are case-insensitive and match substrings. Only one of either the `--first` and `--last` filters can be provided at a time as they're mutually exclusive.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Examples
|
|
25
31
|
|
|
26
32
|
```bash
|
|
27
|
-
# Tracks by either artist
|
|
33
|
+
# Tracks by either artist
|
|
28
34
|
rbe search --artist "Daft Punk" --artist "Justice"
|
|
29
35
|
|
|
30
36
|
# Tracks matching artist AND format
|
|
@@ -39,20 +45,13 @@ rbe search --playlist "house" --playlist "disco"
|
|
|
39
45
|
# All the songs in my library that aren't in any playlist
|
|
40
46
|
rbe search --playlist ""
|
|
41
47
|
|
|
42
|
-
#
|
|
43
|
-
rbe search --path "Favorites/" --path "track.wav"
|
|
48
|
+
# The first 10 tracks whose path contains a folder or filename substring
|
|
49
|
+
rbe search --path "Favorites/" --path "track.wav" --first 10
|
|
44
50
|
|
|
45
51
|
# The track at an exact location
|
|
46
52
|
rbe search --exact-path "/Users/djmustard/Music/banger.mp3"
|
|
47
53
|
```
|
|
48
54
|
|
|
49
|
-
## Limiting Results
|
|
50
|
-
|
|
51
|
-
- `--first N`: return only the first N results
|
|
52
|
-
- `--last N`: return only the last N results
|
|
53
|
-
|
|
54
|
-
The two are mutually exclusive. They make a great blast radius limiter while you refine a filter: `rbe convert --artist "Crazy Frog" --first 5 --dry-run`.
|
|
55
|
-
|
|
56
55
|
## Track ID Arguments
|
|
57
56
|
|
|
58
57
|
Any positional argument that is not a defined option is interpreted as one or more track IDs:
|
|
@@ -68,14 +67,14 @@ Track IDs can also arrive on stdin (see [Scripting and Piping](#scripting-and-pi
|
|
|
68
67
|
All commands take `--print [silent|ids|info|debug|json]`:
|
|
69
68
|
|
|
70
69
|
- `info` (default): human-readable output
|
|
71
|
-
- `debug`: adds application state detail; debug logs for every run are also written to a log file (the path is shown in `--help`)
|
|
72
|
-
- `silent`: no output
|
|
73
|
-
- `ids`: print only the matching track IDs, space-separated — designed for piping
|
|
70
|
+
- `debug`: adds application state detail; debug logs for every run are also written to a log file (the path to which is shown in `--help`)
|
|
71
|
+
- `silent`: no output at all
|
|
72
|
+
- `ids`: print only the matching track IDs, space-separated — designed for piping between consecutive `rbe` commands.
|
|
74
73
|
- `json`: dump the full response envelope as JSON — a list of [`Track`][rekordbox_edit.models.Track] records plus a result summary (see the response models in the [API Reference](api.md))
|
|
75
74
|
|
|
76
75
|
!!! note
|
|
77
76
|
|
|
78
|
-
`silent`, `ids`, and `json`
|
|
77
|
+
`silent`, `ids`, and `json` are non-interactive print modes, so they require `--yes` or `--dry-run`.
|
|
79
78
|
|
|
80
79
|
## Scripting and Piping
|
|
81
80
|
|
|
@@ -86,12 +85,12 @@ All commands take `--print [silent|ids|info|debug|json]`:
|
|
|
86
85
|
rbe search --artist "Lauryn Hill" --print ids | rbe convert --yes
|
|
87
86
|
```
|
|
88
87
|
|
|
89
|
-
Piping
|
|
88
|
+
Piping allows you to compose OR and AND logic that a single command could not express by itself:
|
|
90
89
|
|
|
91
90
|
**AND-narrowing** — pipe a broad OR result into a second command with `--match-all` to intersect:
|
|
92
91
|
|
|
93
92
|
```bash
|
|
94
|
-
# (Daft Punk OR Justice) AND flac
|
|
93
|
+
# Search all (Daft Punk OR Justice) AND flac
|
|
95
94
|
rbe search --artist "Daft Punk" --artist "Justice" --print ids \
|
|
96
95
|
| rbe search --format flac --match-all
|
|
97
96
|
```
|
|
@@ -99,10 +98,10 @@ rbe search --artist "Daft Punk" --artist "Justice" --print ids \
|
|
|
99
98
|
**OR between AND-groups** — merge results from two commands using a subshell:
|
|
100
99
|
|
|
101
100
|
```bash
|
|
102
|
-
# (Daft Punk AND flac) OR (Justice AND aiff)
|
|
101
|
+
# Convert all (Daft Punk AND flac) OR (Justice AND aiff)
|
|
103
102
|
{ rbe search --artist "Daft Punk" --format flac --match-all --print ids; \
|
|
104
103
|
rbe search --artist "Justice" --format aiff --match-all --print ids; } \
|
|
105
104
|
| rbe convert --format-out mp3 --dry-run
|
|
106
105
|
```
|
|
107
106
|
|
|
108
|
-
For richer pipelines, `--print json` emits the same selection as structured data for `jq`
|
|
107
|
+
For richer pipelines, `--print json` emits the same selection as structured data for `jq` and other shell tools. Use the [API functions](/api/#functions) if you want to build a more complex python script.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rekordbox-edit"
|
|
7
|
-
version = "0.6.0.
|
|
7
|
+
version = "0.6.0.dev48"
|
|
8
8
|
description = "Tools for managing and modifying a RekordBox library en-masse"
|
|
9
9
|
authors = [{ name = "James Viall", email= "jamesviall@pm.me"}]
|
|
10
10
|
license = "MIT"
|
|
@@ -35,7 +35,7 @@ dev = [
|
|
|
35
35
|
]
|
|
36
36
|
docs = [
|
|
37
37
|
"mkdocs-material>=9.5,<10",
|
|
38
|
-
"mkdocstrings[python]>=
|
|
38
|
+
"mkdocstrings[python]>=1,<2",
|
|
39
39
|
"mkdocs-click>=0.8,<1",
|
|
40
40
|
"markdown-callouts>=0.4,<1",
|
|
41
41
|
"mkdocs-open-in-new-tab>=1.0,<2",
|
|
@@ -14,8 +14,8 @@ from sqlalchemy import select
|
|
|
14
14
|
|
|
15
15
|
from rekordbox_edit.api._utils import _order_tracks_by_op
|
|
16
16
|
from rekordbox_edit.models import (
|
|
17
|
-
ConvertRequest,
|
|
18
17
|
ConvertOp,
|
|
18
|
+
ConvertRequest,
|
|
19
19
|
ConvertResponse,
|
|
20
20
|
ConvertResult,
|
|
21
21
|
SkippedTrack,
|
|
@@ -248,8 +248,8 @@ def convert(
|
|
|
248
248
|
With `dry_run=True`, returns the planned conversions without any ffmpeg or
|
|
249
249
|
DB writes. With `dry_run=False` (default), commits the changes.
|
|
250
250
|
|
|
251
|
-
The rollback block protects only pre-commit work; once commit lands,
|
|
252
|
-
transaction is honoured even if the delete-originals loop or response
|
|
251
|
+
The rollback block protects only pre-commit work; once a database commit lands,
|
|
252
|
+
the transaction is honoured even if the delete-originals loop or response
|
|
253
253
|
re-query later fails.
|
|
254
254
|
"""
|
|
255
255
|
from rekordbox_edit.utils import ffmpeg_in_path, get_ffmpeg_directions
|
|
@@ -4,21 +4,22 @@ Three layers:
|
|
|
4
4
|
|
|
5
5
|
- **Filter base** (`FilterArgs`) declares track-selection criteria shared by all
|
|
6
6
|
commands.
|
|
7
|
-
- **Command
|
|
7
|
+
- **API/Command request models** (`SearchRequest`, `EditRequest`, `ConvertRequest`) extend `FilterArgs`
|
|
8
8
|
with command-specific fields.
|
|
9
|
-
- **
|
|
10
|
-
**response envelopes** (`SearchResponse`, `EditResponse`, `ConvertResponse`)
|
|
9
|
+
- **API/Command response models** (`SearchResponse`, `EditResponse`, `ConvertResponse`)
|
|
11
10
|
describe what each command returns.
|
|
11
|
+
- **Domain types** (`Track`, `EditOp`, `ConvertOp`, `SkippedTrack`)
|
|
12
|
+
which help describe the internals of requests/responses
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
Response semantics:
|
|
14
15
|
|
|
15
16
|
- `tracks` always reflects the **current DB state** at the moment the response
|
|
16
17
|
was built. Pre-execute for dry-runs, post-execute for write runs.
|
|
17
|
-
- `result` summarizes what happened (or would happen in a dry-run).
|
|
18
|
-
|
|
19
|
-
format for convert) so a response is fully self-describing.
|
|
20
|
-
- `tracks` and `result.edits` / `result.converted` align 1:1
|
|
21
|
-
|
|
18
|
+
- `result` summarizes what happened (or would happen in a dry-run). Response
|
|
19
|
+
models should self describe the operation that happened (e.g. the field name
|
|
20
|
+
for edit, the target format for convert) so a response is fully self-describing.
|
|
21
|
+
- `tracks` and `result.edits` / `result.converted` align 1:1 in their contents and
|
|
22
|
+
order by index;
|
|
22
23
|
"""
|
|
23
24
|
|
|
24
25
|
from typing import Literal, TypeAlias
|
|
@@ -89,9 +90,10 @@ class ConvertRequest(FilterArgs):
|
|
|
89
90
|
|
|
90
91
|
class Track(BaseModel):
|
|
91
92
|
"""A Rekordbox track.
|
|
92
|
-
Field names mirror the [DjmdContent](https://pyrekordbox.readthedocs.io/en/latest/formats/db6.html#djmdcontent)
|
|
93
|
-
except where additional derived fields have been added for convenience.
|
|
94
|
-
|
|
93
|
+
Field names mirror the [DjmdContent](https://pyrekordbox.readthedocs.io/en/latest/formats/db6.html#djmdcontent)
|
|
94
|
+
table's column names, except where additional derived fields have been added for convenience.
|
|
95
|
+
What's defined here are just the fields RBE cares about, but all database columns and their raw
|
|
96
|
+
are silently included in each Track instance, and are included in `--print json`.
|
|
95
97
|
"""
|
|
96
98
|
|
|
97
99
|
model_config = ConfigDict(extra="allow")
|
|
@@ -125,7 +127,9 @@ SkipReason: TypeAlias = Literal[
|
|
|
125
127
|
|
|
126
128
|
|
|
127
129
|
class SkippedTrack(BaseModel):
|
|
128
|
-
"""A track the command declined to operate on.
|
|
130
|
+
"""A track the command declined to operate on.
|
|
131
|
+
e.g. A result in a [convert][rekordbox_edit.api.convert] command that is already the target format.
|
|
132
|
+
"""
|
|
129
133
|
|
|
130
134
|
id: str
|
|
131
135
|
reason: SkipReason
|
|
@@ -727,7 +727,7 @@ wheels = [
|
|
|
727
727
|
|
|
728
728
|
[[package]]
|
|
729
729
|
name = "mkdocstrings"
|
|
730
|
-
version = "0.
|
|
730
|
+
version = "1.0.4"
|
|
731
731
|
source = { registry = "https://pypi.org/simple" }
|
|
732
732
|
dependencies = [
|
|
733
733
|
{ name = "jinja2" },
|
|
@@ -737,9 +737,9 @@ dependencies = [
|
|
|
737
737
|
{ name = "mkdocs-autorefs" },
|
|
738
738
|
{ name = "pymdown-extensions" },
|
|
739
739
|
]
|
|
740
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
740
|
+
sdist = { url = "https://files.pythonhosted.org/packages/1d/5d/f888d4d3eb31359b327bc9b17a212d6ef03fe0b0682fbb3fc2cb849fb12b/mkdocstrings-1.0.4.tar.gz", hash = "sha256:3969a6515b77db65fd097b53c1b7aa4ae840bd71a2ee62a6a3e89503446d7172", size = 100088, upload-time = "2026-04-15T09:16:53.376Z" }
|
|
741
741
|
wheels = [
|
|
742
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
742
|
+
{ url = "https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl", hash = "sha256:63464b4b29053514f32a1dbbf604e52876d5e638111b0c295ab7ed3cac73ca9b", size = 35560, upload-time = "2026-04-15T09:16:51.436Z" },
|
|
743
743
|
]
|
|
744
744
|
|
|
745
745
|
[package.optional-dependencies]
|
|
@@ -1268,7 +1268,7 @@ wheels = [
|
|
|
1268
1268
|
|
|
1269
1269
|
[[package]]
|
|
1270
1270
|
name = "rekordbox-edit"
|
|
1271
|
-
version = "0.6.0.
|
|
1271
|
+
version = "0.6.0.dev48"
|
|
1272
1272
|
source = { editable = "." }
|
|
1273
1273
|
dependencies = [
|
|
1274
1274
|
{ name = "click" },
|
|
@@ -1328,7 +1328,7 @@ docs = [
|
|
|
1328
1328
|
{ name = "mkdocs-click", specifier = ">=0.8,<1" },
|
|
1329
1329
|
{ name = "mkdocs-material", specifier = ">=9.5,<10" },
|
|
1330
1330
|
{ name = "mkdocs-open-in-new-tab", specifier = ">=1.0,<2" },
|
|
1331
|
-
{ name = "mkdocstrings", extras = ["python"], specifier = ">=
|
|
1331
|
+
{ name = "mkdocstrings", extras = ["python"], specifier = ">=1,<2" },
|
|
1332
1332
|
]
|
|
1333
1333
|
|
|
1334
1334
|
[[package]]
|
|
@@ -1,28 +0,0 @@
|
|
|
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 SearchRequest
|
|
9
|
-
|
|
10
|
-
db = Rekordbox6Database()
|
|
11
|
-
response = search(db, SearchRequest(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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/.github/actions/commitizen-bump/action.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -37,9 +37,9 @@ logger = logging.getLogger(__name__)
|
|
|
37
37
|
)
|
|
38
38
|
@add_click_options(
|
|
39
39
|
[
|
|
40
|
-
*global_click_filters,
|
|
41
|
-
*global_click_confirmations,
|
|
42
40
|
*convert_click_options,
|
|
41
|
+
*global_click_confirmations,
|
|
42
|
+
*global_click_filters,
|
|
43
43
|
print_option,
|
|
44
44
|
track_ids_argument,
|
|
45
45
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/__snapshots__/test_journey.ambr
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/macos/master.6.8.6.db
RENAMED
|
File without changes
|
{rekordbox_edit-0.6.0.dev44 → rekordbox_edit-0.6.0.dev48}/tests/e2e/fixtures/windows/master.6.8.6.db
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|