rekordbox-edit 0.12.0.dev17__tar.gz → 0.13.0.dev7__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.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/CHANGELOG.md +24 -1
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/PKG-INFO +1 -1
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/commands/edit.md +27 -1
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/pyproject.toml +1 -1
- rekordbox_edit-0.13.0.dev7/rekordbox_edit/_tag_fields.py +88 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/api/_edit.py +10 -2
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/api/_field_handlers.py +101 -65
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/api/_import.py +24 -49
- rekordbox_edit-0.13.0.dev7/rekordbox_edit/api/_relations.py +239 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/api/_remove.py +4 -114
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/api/_utils.py +5 -3
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/display.py +21 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/models.py +6 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/test_edit.py +50 -1
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/test_field_handlers.py +222 -155
- rekordbox_edit-0.13.0.dev7/tests/api/test_relations.py +49 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/test_remove.py +0 -43
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/conftest.py +5 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/__snapshots__/test_journey/test_search_full_json_snapshot[macos].json +49 -9
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/__snapshots__/test_journey/test_search_full_json_snapshot[windows].json +49 -9
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/conftest.py +54 -21
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/macos/master.6.8.6.db +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/windows/master.6.8.6.db +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/test_edit_fields.py +131 -15
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/test_import.py +4 -44
- rekordbox_edit-0.13.0.dev7/tests/e2e/test_remove.py +300 -0
- rekordbox_edit-0.13.0.dev7/tests/test_tag_fields.py +73 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/uv.lock +1 -1
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.agent-style/RULES.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.agent-style/claude-code.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/actions/build-release-notes/action.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/actions/build-release-notes/build_release_notes.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/actions/commit-check/action.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/actions/commitizen-bump/action.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/actions/commitizen-bump/commitizen-bump.sh +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/actions/e2e/action.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/actions/install/action.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/actions/lint/action.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/actions/test/action.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/workflows/cd.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/workflows/ci.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/workflows/publish.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.github/workflows/release.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.gitignore +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.pre-commit-config.yaml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.python-version +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/.readthedocs.yaml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/AGENTS.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/CLAUDE.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/CONTRIBUTING.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/LICENSE +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/Makefile +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/README.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/codecov.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docker-compose.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/api.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/commands/convert.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/commands/import.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/commands/remove.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/commands/search.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/faqs.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/filtering.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/index.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/docs/stylesheets/extra.css +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/mkdocs.yml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/__init__.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/api/__init__.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/api/_convert.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/api/_search.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/__init__.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/_click.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/_progress.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/_utils.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/convert.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/edit.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/import_.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/main.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/remove.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/cli/search.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/errors.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/locking.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/logger.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/query.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/tags.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/utils.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/renovate.json5 +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/README.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/convert-export-impact-test-plan.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/convert-export-impact.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r1-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r1-10-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r1-20-postexport.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r1-21-postexport-full.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r2-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r2b-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r2b-10-deviceedit.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r2b-30-postsync.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r3-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r3-10-deviceedit.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r3-40-resync.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/export-r3-41-reexport-full.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-11317782-r3-20-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-11317782-r3-30-postsync.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-121715696-r1-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-121715696-r1-10-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-121715696-r1-20-postexport.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-121715696-r2-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-121715696-r2b-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-121715696-r2b-00-lib.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-121715696-r2b-20-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-121715696-r2b-30-postsync.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-140193439-r3-20-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-140193439-r3-30-postsync.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-258421826-r1-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-258421826-r1-10-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-258421826-r1-20-postexport.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-258421826-r2-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-258421826-r2b-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-258421826-r2b-00-lib.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-258421826-r2b-20-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-258421826-r2b-30-postsync.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-268012584-r3-20-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-268012584-r3-30-postsync.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-53013048-r1-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-53013048-r1-10-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-53013048-r1-20-postexport.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-53013048-r2-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-53013048-r2b-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-53013048-r2b-00-lib.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-53013048-r2b-20-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-53013048-r2b-30-postsync.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-54793376-r1-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-54793376-r1-10-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-54793376-r1-20-postexport.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-54793376-r2-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-54793376-r2b-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-54793376-r2b-20-postconvert.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/evidence/subject-54793376-r2b-30-postsync.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/scripts/export_diff.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-export-impact/scripts/export_snapshot.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/convert-anlz-cue-impact-experiment2-plan.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/convert-anlz-cue-impact-experiment2.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/convert-anlz-cue-impact-test-plan.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/convert-anlz-cue-impact-verification.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/convert-anlz-cue-impact.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/decisions/convert-and-reanalysis-impact.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/decisions/convert-helper-structure.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/01-inventory.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/02-cue-schema.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/03-cue-fields-by-format.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/04-anlz-deep.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/05-census.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/06-content-columns.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/07-analysis-flags.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/exp2-00-pvb2-origin.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-00-zero.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-dyn-high-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-dyn-high-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-dyn-high-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-dyn-normal-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-dyn-normal-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-dyn-normal-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-high-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-high-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-high-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-high-04.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-high-05.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-high-auto-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-high-auto-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-high-auto-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-normal-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-normal-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-normal-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-normal-04.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-normal-05.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-normal-06.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-normal-then-high.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-normal-unlocked-ref.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-174954387-nth-mid-normal.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205157376-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205157376-aiff-postanalyze.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205157376-aiff-postconv.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205157376-combined-ctrl-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205157376-combined-ctrl-postanalyze.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205157376-combined-ctrl-postanalyze2.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-aiff-postanalyze.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-aiff-postconv.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-aiff-postopen.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-flac-ctrl-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-flac-ctrl-postanalyze.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-flac-ctrl-postanalyze2.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-flac-postconv.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-mp3-postanalyze.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-205795680-mp3-postconv.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-230928195-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-230928195-mp3-locked.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-230928195-mp3-postconv.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-230928195-mp3-unlocked-reanalyze.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-230928195-postlock.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-230928195-prelock.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-231283665-iso-rate-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-231283665-iso-rate-postanalyze.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-231283665-iso-rate-postconv.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-00-zero.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-dyn-high-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-dyn-high-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-dyn-high-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-dyn-normal-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-dyn-normal-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-dyn-normal-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-high-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-high-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-high-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-high-04.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-high-05.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-high-auto-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-high-auto-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-high-auto-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-normal-01.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-normal-02.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-normal-03.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-normal-04.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-normal-05.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-normal-06.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-normal-locked.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-normal-then-high.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-27790898-nth-mid-normal.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-34178159-iso-depth-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-34178159-iso-depth-postanalyze.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-34178159-iso-depth-postconv.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-7691309-pvb2-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-7691309-pvb2-postanalyze.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/evidence/subject-7691309-pvb2-postconv.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/README.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/analysis_flags.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/anlz_census.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/anlz_deep.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/content_columns.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/cue_fields_by_format.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/cue_schema.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/grid_drift.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/inventory.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/pvb2_origin.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/reset_fresh_to_zero.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/restore_fixtures.sh +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-reanalysis-impact/scripts/row_snapshot.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-thread-scaling/convert-thread-scaling.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-thread-scaling/evidence/thread-scaling.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-thread-scaling/scripts/_sources.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-thread-scaling/scripts/format_scaling.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-thread-scaling/scripts/shipped_path_scaling.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/convert-thread-scaling/scripts/write_cost.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/database-concurrency.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/evidence/plan-apply-probes.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/evidence/usn-spikes.txt +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/plan-apply-window.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/scripts/block_reservation.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/scripts/concurrent_increment.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/scripts/identity_probe.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/scripts/membership_probe.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/scripts/snapshot_probe.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/scripts/wal_snapshot.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/database-concurrency/usn-maintenance.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/decisions/edit-field-handlers.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/edit-relational-fields-test-plan.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/edit-relational-fields.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-112264610-e2-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-112264610-e2-10-reuse.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-141833798-e3b-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-141833798-e3b-10-newalbum.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-145166719-e0-census.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-176388182-e1-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-176388182-e1-10-reuse.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-183309432-e4-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-183309432-e4-10-orphaned.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-47413782-v-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-47413782-v-10-reuse.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-50395296-v-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-50395296-v-10-reuse.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-57701453-e3-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-57701453-e3-10-diffartist.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-71974950-v-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/evidence/rel-71974950-v-10-reuse.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/scripts/relational_diff.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/edit-relational-fields/scripts/relational_snapshot.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/file-types/README.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/file-types/decisions/unknown-file-types.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/decisions/commit-semantics-and-usn.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/evidence/column-coverage-gig.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/evidence/datecreated-source-gig.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/evidence/filetype-searchstr-gig.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/evidence/filetype-searchstr-local.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/evidence/import-row-shape-gig.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/evidence/tag-key-mapping-gig.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/import-track-row-shape.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/scripts/column_coverage.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/scripts/datecreated_source.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/scripts/filetype_and_searchstr.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/scripts/import_row_shape.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/import-track-row-shape/scripts/tag_key_mapping.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/decisions/remove-command-behavior.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-109570093-r8-00-imported.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-109570093-r8-10-analyzed.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-114745319-r1-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-114745319-r1-10-removed.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-120331280-f6-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-120331280-f6-10-control.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-137975518-f3-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-137975518-f3-10-control.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-139425629-r6-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-139425629-r6-10-removed.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-14241481-r5-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-14241481-r5-10-removed.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-143461275-r7-01-folder-art.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-265892207-r3-00-baseline.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-265892207-r3-10-removed.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-265892207-r4-10-playlist-only.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-36337051-r7-00-folder-art.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-74039842-r8-00-imported.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/evidence/rm-74039842-r8-10-analyzed.json +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/remove-track-impact-test-plan.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/remove-track-impact.md +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/scripts/build_fixtures.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/scripts/removal_diff.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/scripts/removal_snapshot.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/remove-track-impact/scripts/restore.sh +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/shared/scripts/subject_diff.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/research/shared/scripts/subject_snapshot.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/ruff.toml +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/__init__.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/__init__.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/conftest.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/test_convert.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/test_import.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/test_package.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/test_search.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/api/test_utils.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/__init__.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/test_convert.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/test_edit.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/test_import.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/test_locking.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/test_main.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/test_progress.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/test_remove.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/test_search.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/cli/test_utils.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/Dockerfile +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/__init__.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/__snapshots__/test_journey.ambr +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/audio/01-flac-44_1k-16b.flac +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/audio/02-flac-96k-24b.flac +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/audio/03-alac-44_1k-16b.m4a +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/audio/04-alac-48k-24b.m4a +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/audio/05-aiff-44_1k-16b.aiff +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/audio/06-wav-96k-24b.wav +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/audio/07-mp3-44_1k-320cbr.mp3 +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/audio/08-mp3-44_1k-v0vbr.mp3 +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/fixtures/audio/09-aac-44_1k-256kbps.m4a +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/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.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/e2e/test_journey.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/test_display.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/test_locking.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/test_logger.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/test_models.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/test_query.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/test_tags.py +0 -0
- {rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/tests/test_utils.py +0 -0
|
@@ -1,4 +1,27 @@
|
|
|
1
|
-
## v0.
|
|
1
|
+
## v0.13.0.dev7 (2026-09-08)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
- fix(edit): give the records an edit creates and collects their USNs
|
|
5
|
+
- An edit that reassigned a relational field left the record it created
|
|
6
|
+
unstamped and the one it collected outside the counter, so a syncing peer
|
|
7
|
+
never learned about either. import and remove already did both.
|
|
8
|
+
- feat(edit): support the remaining audio-tag columns
|
|
9
|
+
- Adds Genre, Label, ComposerName, ISRC, TrackNo, DiscNo, and ReleaseYear,
|
|
10
|
+
built from the tag registry so edit and import cover the same set. Key is
|
|
11
|
+
left out: Rekordbox derives it from analysis.
|
|
12
|
+
- refactor: name the audio tags import reads in one registry
|
|
13
|
+
- Which column a tag lands in was spread across _resolve_relations and the
|
|
14
|
+
add_content call; edit needs the same mapping to stay in step with import.
|
|
15
|
+
- refactor(api): gather shared-record handling behind _relations
|
|
16
|
+
- edit, import, and remove each carried their own copy of which table holds a
|
|
17
|
+
kind, which columns count as a reference to it, and how a new one is made.
|
|
18
|
+
- test(e2e): cover the remove command
|
|
19
|
+
- test(e2e): give the fixture rows a Rekordbox-shaped ImagePath
|
|
20
|
+
- The fixture audio carries no embedded art, so analysis left every row with
|
|
21
|
+
an empty ImagePath and no e2e case could reach the artwork cleanup.
|
|
22
|
+
- test(e2e): share the private-DB fixtures through conftest
|
|
23
|
+
|
|
24
|
+
## v0.12.0 (2026-09-07)
|
|
2
25
|
|
|
3
26
|
|
|
4
27
|
- refactor(api)!: gather the public surface behind rekordbox_edit.api
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: rekordbox-edit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0.dev7
|
|
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
|
|
@@ -6,7 +6,33 @@ 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` specifies the [DjmdContent](https://pyrekordbox.readthedocs.io/en/latest/formats/db6.html#djmdcontent) column to change
|
|
9
|
+
`FIELD` specifies the [DjmdContent](https://pyrekordbox.readthedocs.io/en/latest/formats/db6.html#djmdcontent) column to change:
|
|
10
|
+
|
|
11
|
+
| Field | What it changes |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `Title` | The track title. |
|
|
14
|
+
| `Comment` | The comment column (`Commnt`). |
|
|
15
|
+
| `ArtistName` | The artist, through the shared `DjmdArtist` record. |
|
|
16
|
+
| `AlbumName` | The album, through the shared `DjmdAlbum` record. |
|
|
17
|
+
| `ComposerName` | The composer, which shares the `DjmdArtist` table with the artist. |
|
|
18
|
+
| `Genre` | The genre, through the shared `DjmdGenre` record. |
|
|
19
|
+
| `Label` | The record label, through the shared `DjmdLabel` record. |
|
|
20
|
+
| `ISRC` | The recording's ISRC. |
|
|
21
|
+
| `TrackNo` | The track number. |
|
|
22
|
+
| `DiscNo` | The disc number. |
|
|
23
|
+
| `ReleaseYear` | The release year. `ReleaseDate` is left as it is. |
|
|
24
|
+
| `Rating` | The 0-5 star rating. |
|
|
25
|
+
| `FolderPath` | The audio file the track points at. See [FolderPath](#folderpath). |
|
|
26
|
+
|
|
27
|
+
Every field above except `Rating` and `FolderPath` also comes from an audio tag, and [`import`](import.md) reads the same set. Musical key is the one tag `edit` does not offer: Rekordbox derives it from its own analysis, which would overwrite whatever you set.
|
|
28
|
+
|
|
29
|
+
`Rating`, `TrackNo`, `DiscNo`, and `ReleaseYear` hold numbers, so `--match` does not apply to them; passing it warns and sets the value directly.
|
|
30
|
+
|
|
31
|
+
## Relational fields
|
|
32
|
+
|
|
33
|
+
`ArtistName`, `AlbumName`, `ComposerName`, `Genre`, and `Label` do not live on the track's own row. Each names a record in a shared table that many tracks point at, so editing one works the way it does in Rekordbox: the track is reassigned to a record with the new name, reusing an existing one or creating it, and every other track keeps the record it had. `--replace ""` clears the field. A record nothing references any more is deleted, again matching Rekordbox.
|
|
34
|
+
|
|
35
|
+
One deliberate difference: reusing an existing album leaves that album's album-artist alone, where Rekordbox blanks it for every track on the album.
|
|
10
36
|
|
|
11
37
|
`--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
38
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rekordbox-edit"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.13.0.dev7"
|
|
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"
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""The audio tags Rekordbox reads, and the columns they land in.
|
|
2
|
+
|
|
3
|
+
`import` writes these columns from a file's tags and `edit` changes them
|
|
4
|
+
afterward, so both commands read the mapping from here. Adding a tag to
|
|
5
|
+
`tags.TrackTags` without adding it here (or the reverse) fails the parity
|
|
6
|
+
test in tests/test_tag_fields.py.
|
|
7
|
+
|
|
8
|
+
Which mutagen key holds a tag is a separate, format-specific concern and
|
|
9
|
+
stays in `tags.py`.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class TagField:
|
|
17
|
+
"""One audio tag, the DjmdContent column it lands in, and how each
|
|
18
|
+
command reaches it."""
|
|
19
|
+
|
|
20
|
+
tag: str
|
|
21
|
+
"""The `tags.TrackTags` key holding the value read off the file."""
|
|
22
|
+
column: str
|
|
23
|
+
"""The DjmdContent column storing it: the value itself for a scalar tag,
|
|
24
|
+
or the foreign key for a relational one."""
|
|
25
|
+
relation: str | None = None
|
|
26
|
+
"""The `api._relations.RELATIONS` kind `column` points at, or None where
|
|
27
|
+
the column holds the value directly."""
|
|
28
|
+
proxy: str | None = None
|
|
29
|
+
"""The DjmdContent attribute reading the related record's name. Set for a
|
|
30
|
+
relational tag only."""
|
|
31
|
+
edit_field: str | None = None
|
|
32
|
+
"""The `edit` command's name for this field, or None where the column is
|
|
33
|
+
not editable."""
|
|
34
|
+
default: str | int = ""
|
|
35
|
+
"""What `import` writes when the file carries no such tag."""
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
#: Every tag both commands know about, in the order `import` reads them.
|
|
39
|
+
#:
|
|
40
|
+
#: `key` is deliberately not editable: Rekordbox derives KeyID from its own
|
|
41
|
+
#: analysis, so a user-supplied key would be overwritten the next time the
|
|
42
|
+
#: track is analyzed.
|
|
43
|
+
TAG_FIELDS: tuple[TagField, ...] = (
|
|
44
|
+
TagField(tag="title", column="Title", edit_field="Title"),
|
|
45
|
+
TagField(
|
|
46
|
+
tag="artist",
|
|
47
|
+
column="ArtistID",
|
|
48
|
+
relation="artist",
|
|
49
|
+
proxy="ArtistName",
|
|
50
|
+
edit_field="ArtistName",
|
|
51
|
+
),
|
|
52
|
+
TagField(
|
|
53
|
+
tag="album",
|
|
54
|
+
column="AlbumID",
|
|
55
|
+
relation="album",
|
|
56
|
+
proxy="AlbumName",
|
|
57
|
+
edit_field="AlbumName",
|
|
58
|
+
),
|
|
59
|
+
TagField(
|
|
60
|
+
tag="genre",
|
|
61
|
+
column="GenreID",
|
|
62
|
+
relation="genre",
|
|
63
|
+
proxy="GenreName",
|
|
64
|
+
edit_field="Genre",
|
|
65
|
+
),
|
|
66
|
+
TagField(
|
|
67
|
+
tag="label",
|
|
68
|
+
column="LabelID",
|
|
69
|
+
relation="label",
|
|
70
|
+
proxy="LabelName",
|
|
71
|
+
edit_field="Label",
|
|
72
|
+
),
|
|
73
|
+
TagField(
|
|
74
|
+
tag="composer",
|
|
75
|
+
column="ComposerID",
|
|
76
|
+
relation="artist",
|
|
77
|
+
proxy="ComposerName",
|
|
78
|
+
edit_field="ComposerName",
|
|
79
|
+
),
|
|
80
|
+
TagField(tag="key", column="KeyID", relation="key", proxy="KeyName"),
|
|
81
|
+
TagField(tag="comment", column="Commnt", edit_field="Comment"),
|
|
82
|
+
TagField(tag="isrc", column="ISRC", edit_field="ISRC"),
|
|
83
|
+
TagField(tag="track_no", column="TrackNo", edit_field="TrackNo", default=0),
|
|
84
|
+
TagField(tag="disc_no", column="DiscNo", edit_field="DiscNo", default=0),
|
|
85
|
+
TagField(
|
|
86
|
+
tag="release_year", column="ReleaseYear", edit_field="ReleaseYear", default=0
|
|
87
|
+
),
|
|
88
|
+
)
|
|
@@ -5,6 +5,7 @@ import logging
|
|
|
5
5
|
from pyrekordbox import Rekordbox6Database
|
|
6
6
|
|
|
7
7
|
from rekordbox_edit.api._utils import (
|
|
8
|
+
reserve_usns,
|
|
8
9
|
stamp_usns,
|
|
9
10
|
track_from_content,
|
|
10
11
|
writing,
|
|
@@ -141,12 +142,19 @@ def edit(
|
|
|
141
142
|
old_values: dict[str, str | None] = {}
|
|
142
143
|
edited = []
|
|
143
144
|
with writing(db, "edit"):
|
|
145
|
+
# Shared records the edit creates or collects along the way each take a
|
|
146
|
+
# USN too, the same as the tracks themselves.
|
|
147
|
+
created: list = []
|
|
148
|
+
collected = 0
|
|
144
149
|
for content in contents:
|
|
145
150
|
if str(content.ID) in new_values:
|
|
146
151
|
old_values[str(content.ID)] = handler.current_value(content)
|
|
147
|
-
handler.apply(db, content, new_values[str(content.ID)])
|
|
152
|
+
incidental = handler.apply(db, content, new_values[str(content.ID)])
|
|
153
|
+
created.extend(incidental.created)
|
|
154
|
+
collected += incidental.deleted
|
|
148
155
|
edited.append(content)
|
|
149
|
-
stamp_usns(db, edited)
|
|
156
|
+
stamp_usns(db, [*edited, *created])
|
|
157
|
+
reserve_usns(db, collected)
|
|
150
158
|
db.session.commit()
|
|
151
159
|
_logger.debug(f"edit committed {len(ops)} change(s) on field={args.field}")
|
|
152
160
|
|
{rekordbox_edit-0.12.0.dev17 → rekordbox_edit-0.13.0.dev7}/rekordbox_edit/api/_field_handlers.py
RENAMED
|
@@ -8,11 +8,17 @@ own encoding or relational lookup.
|
|
|
8
8
|
|
|
9
9
|
import logging
|
|
10
10
|
import os
|
|
11
|
+
from typing import NamedTuple
|
|
11
12
|
|
|
12
13
|
from pyrekordbox import Rekordbox6Database
|
|
13
14
|
from pyrekordbox.db6 import tables as tb
|
|
14
|
-
from sqlalchemy import or_
|
|
15
15
|
|
|
16
|
+
from rekordbox_edit._tag_fields import TAG_FIELDS, TagField
|
|
17
|
+
from rekordbox_edit.api._relations import (
|
|
18
|
+
RELATIONS,
|
|
19
|
+
delete_if_orphaned,
|
|
20
|
+
get_or_create,
|
|
21
|
+
)
|
|
16
22
|
from rekordbox_edit.api._utils import _sync_audio_columns, _update_anlz_paths
|
|
17
23
|
from rekordbox_edit.errors import DependencyMissingError
|
|
18
24
|
from rekordbox_edit.models import EditRequest, SkipReason
|
|
@@ -28,6 +34,22 @@ from rekordbox_edit.utils import (
|
|
|
28
34
|
_logger = logging.getLogger(__name__)
|
|
29
35
|
|
|
30
36
|
|
|
37
|
+
class IncidentalRows(NamedTuple):
|
|
38
|
+
"""Rows a write touched besides the track itself.
|
|
39
|
+
|
|
40
|
+
Rekordbox gives every row it writes a USN, so the caller stamps `created`
|
|
41
|
+
and reserves one USN per row in `deleted`, which no longer exists to carry
|
|
42
|
+
a stamp of its own.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
created: tuple = ()
|
|
46
|
+
deleted: int = 0
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
#: What a handler writing nothing but the track's own row returns.
|
|
50
|
+
NO_INCIDENTAL_ROWS = IncidentalRows()
|
|
51
|
+
|
|
52
|
+
|
|
31
53
|
class FieldHandler:
|
|
32
54
|
"""Read, compute, validate, and apply one editable field."""
|
|
33
55
|
|
|
@@ -59,7 +81,9 @@ class FieldHandler:
|
|
|
59
81
|
"""New value as a string, or None to signal no change / skip."""
|
|
60
82
|
raise NotImplementedError # pragma: no cover
|
|
61
83
|
|
|
62
|
-
def apply(self, db: Rekordbox6Database, content, new_value: str) ->
|
|
84
|
+
def apply(self, db: Rekordbox6Database, content, new_value: str) -> IncidentalRows:
|
|
85
|
+
"""Write the new value, returning the rows the write added or removed
|
|
86
|
+
alongside the track's own."""
|
|
63
87
|
raise NotImplementedError # pragma: no cover
|
|
64
88
|
|
|
65
89
|
def post_commit(
|
|
@@ -99,6 +123,7 @@ class StringField(FieldHandler):
|
|
|
99
123
|
|
|
100
124
|
def apply(self, db, content, new_value):
|
|
101
125
|
setattr(content, self.column, new_value)
|
|
126
|
+
return NO_INCIDENTAL_ROWS
|
|
102
127
|
|
|
103
128
|
|
|
104
129
|
class RatingField(FieldHandler):
|
|
@@ -123,21 +148,55 @@ class RatingField(FieldHandler):
|
|
|
123
148
|
|
|
124
149
|
def apply(self, db, content, new_value):
|
|
125
150
|
content.Rating = star_rating_to_stored(int(new_value))
|
|
151
|
+
return NO_INCIDENTAL_ROWS
|
|
126
152
|
|
|
127
153
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
154
|
+
class IntegerField(FieldHandler):
|
|
155
|
+
"""A whole-number column: track number, disc number, or release year.
|
|
156
|
+
|
|
157
|
+
`--match` does not apply, so the value is validated once per request
|
|
158
|
+
rather than per track. A cleared value writes 0, the value an import
|
|
159
|
+
stores for a tag the file does not carry.
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
supports_match = False
|
|
163
|
+
|
|
164
|
+
def __init__(self, name: str, column: str):
|
|
165
|
+
self.name = name
|
|
166
|
+
self.column = column
|
|
167
|
+
|
|
168
|
+
def validate_request(self, args):
|
|
169
|
+
if args.match_pattern is not None:
|
|
170
|
+
_logger.warning(
|
|
171
|
+
f"--match does not apply to {self.name}; setting the value directly"
|
|
172
|
+
)
|
|
173
|
+
self._parse(args.replace_value) # raises ValueError on bad input
|
|
174
|
+
|
|
175
|
+
def _parse(self, value: str) -> int:
|
|
176
|
+
if value == "":
|
|
177
|
+
return 0
|
|
178
|
+
try:
|
|
179
|
+
return int(value)
|
|
180
|
+
except ValueError:
|
|
181
|
+
raise ValueError(
|
|
182
|
+
f"{self.name} must be a whole number, got {value!r}"
|
|
183
|
+
) from None
|
|
184
|
+
|
|
185
|
+
def current_value(self, content):
|
|
186
|
+
stored = getattr(content, self.column)
|
|
187
|
+
return None if stored is None else str(stored)
|
|
188
|
+
|
|
189
|
+
def compute_new_value(self, current, args):
|
|
190
|
+
return str(self._parse(args.replace_value))
|
|
191
|
+
|
|
192
|
+
def apply(self, db, content, new_value):
|
|
193
|
+
setattr(content, self.column, int(new_value))
|
|
194
|
+
return NO_INCIDENTAL_ROWS
|
|
137
195
|
|
|
138
196
|
|
|
139
197
|
class RelationalField(FieldHandler):
|
|
140
|
-
"""
|
|
198
|
+
"""A shared record reached through a foreign key: artist, album, genre, or
|
|
199
|
+
label.
|
|
141
200
|
|
|
142
201
|
Setting the value reuses an existing record with the same name or creates
|
|
143
202
|
one, then repoints the track. A record left with no references is deleted,
|
|
@@ -161,59 +220,15 @@ class RelationalField(FieldHandler):
|
|
|
161
220
|
|
|
162
221
|
def apply(self, db, content, new_value):
|
|
163
222
|
old_id = getattr(content, self.fk_column)
|
|
223
|
+
created: list = []
|
|
164
224
|
if new_value == "":
|
|
165
|
-
setattr(content, self.fk_column,
|
|
225
|
+
setattr(content, self.fk_column, RELATIONS[self.kind].empty_value)
|
|
166
226
|
else:
|
|
167
|
-
record =
|
|
227
|
+
record = get_or_create(db, self.kind, new_value, created)
|
|
168
228
|
setattr(content, self.fk_column, record.ID)
|
|
169
229
|
db.session.flush()
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
def _get_or_create(self, db, name):
|
|
173
|
-
if self.kind == "artist":
|
|
174
|
-
existing = (
|
|
175
|
-
db.session.query(tb.DjmdArtist)
|
|
176
|
-
.filter_by(Name=name)
|
|
177
|
-
.order_by(tb.DjmdArtist.ID)
|
|
178
|
-
.first()
|
|
179
|
-
)
|
|
180
|
-
return existing or db.add_artist(name)
|
|
181
|
-
existing = (
|
|
182
|
-
db.session.query(tb.DjmdAlbum)
|
|
183
|
-
.filter_by(Name=name)
|
|
184
|
-
.order_by(tb.DjmdAlbum.ID)
|
|
185
|
-
.first()
|
|
186
|
-
)
|
|
187
|
-
return existing or db.add_album(name)
|
|
188
|
-
|
|
189
|
-
def _delete_if_orphaned(self, db, old_id):
|
|
190
|
-
if old_id in (None, ""):
|
|
191
|
-
return
|
|
192
|
-
if self.kind == "artist":
|
|
193
|
-
in_content = (
|
|
194
|
-
db.session.query(tb.DjmdContent)
|
|
195
|
-
.filter(or_(*(col == old_id for col in _ARTIST_ROLE_COLUMNS)))
|
|
196
|
-
.first()
|
|
197
|
-
)
|
|
198
|
-
in_album = (
|
|
199
|
-
db.session.query(tb.DjmdAlbum)
|
|
200
|
-
.filter(tb.DjmdAlbum.AlbumArtistID == old_id)
|
|
201
|
-
.first()
|
|
202
|
-
)
|
|
203
|
-
if in_content is None and in_album is None:
|
|
204
|
-
row = db.get_artist(ID=old_id)
|
|
205
|
-
if row is not None:
|
|
206
|
-
db.delete(row)
|
|
207
|
-
else:
|
|
208
|
-
in_content = (
|
|
209
|
-
db.session.query(tb.DjmdContent)
|
|
210
|
-
.filter(tb.DjmdContent.AlbumID == old_id)
|
|
211
|
-
.first()
|
|
212
|
-
)
|
|
213
|
-
if in_content is None:
|
|
214
|
-
row = db.get_album(ID=old_id)
|
|
215
|
-
if row is not None:
|
|
216
|
-
db.delete(row)
|
|
230
|
+
collected = delete_if_orphaned(db, self.kind, old_id)
|
|
231
|
+
return IncidentalRows(tuple(created), collected)
|
|
217
232
|
|
|
218
233
|
|
|
219
234
|
class FolderPathField(FieldHandler):
|
|
@@ -304,6 +319,12 @@ class FolderPathField(FieldHandler):
|
|
|
304
319
|
content.OrgFolderPath = new_value
|
|
305
320
|
content.FolderPath = new_value
|
|
306
321
|
content.FileNameL = new_value.rsplit("/", 1)[-1]
|
|
322
|
+
self._sync_from_file(content, new_value)
|
|
323
|
+
return NO_INCIDENTAL_ROWS
|
|
324
|
+
|
|
325
|
+
def _sync_from_file(self, content, new_value) -> None:
|
|
326
|
+
"""Rewrite the columns describing the audio file, when there is a
|
|
327
|
+
changed file to read them from."""
|
|
307
328
|
if not os.path.exists(new_value):
|
|
308
329
|
return
|
|
309
330
|
file_size = os.path.getsize(new_value)
|
|
@@ -337,13 +358,28 @@ class FolderPathField(FieldHandler):
|
|
|
337
358
|
return cue is not None
|
|
338
359
|
|
|
339
360
|
|
|
361
|
+
def _handler_for(tag_field: TagField) -> FieldHandler:
|
|
362
|
+
"""The handler for one editable tag, chosen by how its column stores the
|
|
363
|
+
value: through a foreign key, as a number, or as text."""
|
|
364
|
+
name = tag_field.edit_field
|
|
365
|
+
assert name is not None and tag_field.column is not None
|
|
366
|
+
if tag_field.relation is not None:
|
|
367
|
+
assert tag_field.proxy is not None
|
|
368
|
+
return RelationalField(
|
|
369
|
+
name, tag_field.column, tag_field.proxy, tag_field.relation
|
|
370
|
+
)
|
|
371
|
+
if isinstance(tag_field.default, int):
|
|
372
|
+
return IntegerField(name, tag_field.column)
|
|
373
|
+
return StringField(name, tag_field.column)
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
#: Every field `edit` can change. The tag-backed ones come from TAG_FIELDS so
|
|
377
|
+
#: `edit` and `import` cannot drift apart; Rating and FolderPath are not audio
|
|
378
|
+
#: tags and are declared here.
|
|
340
379
|
FIELD_HANDLERS: dict[str, FieldHandler] = {
|
|
341
380
|
handler.name: handler
|
|
342
381
|
for handler in (
|
|
343
|
-
|
|
344
|
-
StringField("Comment", "Commnt"),
|
|
345
|
-
RelationalField("ArtistName", "ArtistID", "ArtistName", "artist"),
|
|
346
|
-
RelationalField("AlbumName", "AlbumID", "AlbumName", "album"),
|
|
382
|
+
*(_handler_for(f) for f in TAG_FIELDS if f.edit_field is not None),
|
|
347
383
|
RatingField(),
|
|
348
384
|
FolderPathField(),
|
|
349
385
|
)
|
|
@@ -9,6 +9,8 @@ from typing import NamedTuple, cast
|
|
|
9
9
|
from pyrekordbox import Rekordbox6Database
|
|
10
10
|
from pyrekordbox.db6 import tables as tb
|
|
11
11
|
|
|
12
|
+
from rekordbox_edit._tag_fields import TAG_FIELDS
|
|
13
|
+
from rekordbox_edit.api._relations import RELATIONS, find_by_name, get_or_create
|
|
12
14
|
from rekordbox_edit.api._utils import stamp_usns, track_from_content, writing
|
|
13
15
|
from rekordbox_edit.errors import (
|
|
14
16
|
DirectoryConfirmationRequired,
|
|
@@ -162,60 +164,38 @@ IMPORT_DEFAULTS: dict[str, object] = {
|
|
|
162
164
|
}
|
|
163
165
|
|
|
164
166
|
|
|
165
|
-
def _get_or_create(db, table, name: str, factory, created: list | None = None):
|
|
166
|
-
"""Reuse a row matching by name, else create one.
|
|
167
|
-
|
|
168
|
-
Same query shape as RelationalField._get_or_create in api/field_handlers.py,
|
|
169
|
-
generalized over a table and factory so one function covers all five
|
|
170
|
-
relational columns instead of a per-kind branch.
|
|
171
|
-
|
|
172
|
-
New rows are appended to `created` when given: add_content flushes,
|
|
173
|
-
which moves them out of session.new before they can be found again.
|
|
174
|
-
"""
|
|
175
|
-
existing = db.session.query(table).filter_by(Name=name).order_by(table.ID).first()
|
|
176
|
-
if existing is not None:
|
|
177
|
-
return existing
|
|
178
|
-
row = factory(name)
|
|
179
|
-
if created is not None:
|
|
180
|
-
created.append(row)
|
|
181
|
-
return row
|
|
182
|
-
|
|
183
|
-
|
|
184
167
|
def _resolve_relations(
|
|
185
168
|
db: Rekordbox6Database, tags: TrackTags, created: list | None = None
|
|
186
169
|
) -> dict[str, str]:
|
|
187
170
|
"""Foreign keys for a track's tags, creating shared rows as needed.
|
|
188
171
|
|
|
189
172
|
A tag that is absent yields no key, leaving the column at add_content's
|
|
190
|
-
default.
|
|
191
|
-
|
|
173
|
+
default. A closed relation is the exception: DjmdKey cannot be added to,
|
|
174
|
+
so an unmatched key falls back to Rekordbox's '0' sentinel.
|
|
192
175
|
"""
|
|
193
|
-
session = require_session(db)
|
|
194
176
|
relations: dict[str, str] = {}
|
|
195
|
-
for
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
relations[column] =
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
row = (
|
|
208
|
-
session.query(tb.DjmdKey)
|
|
209
|
-
.filter_by(ScaleName=key)
|
|
210
|
-
.order_by(tb.DjmdKey.ID)
|
|
211
|
-
.first()
|
|
212
|
-
if key
|
|
213
|
-
else None
|
|
214
|
-
)
|
|
215
|
-
relations["KeyID"] = row.ID if row else "0"
|
|
177
|
+
for tag_field in TAG_FIELDS:
|
|
178
|
+
if tag_field.relation is None:
|
|
179
|
+
continue
|
|
180
|
+
value = tags.get(tag_field.tag)
|
|
181
|
+
relation = RELATIONS[tag_field.relation]
|
|
182
|
+
if not relation.sweepable:
|
|
183
|
+
row = find_by_name(db, tag_field.relation, value) if value else None
|
|
184
|
+
relations[tag_field.column] = row.ID if row else relation.empty_value
|
|
185
|
+
elif value:
|
|
186
|
+
relations[tag_field.column] = get_or_create(
|
|
187
|
+
db, tag_field.relation, value, created
|
|
188
|
+
).ID
|
|
216
189
|
return relations
|
|
217
190
|
|
|
218
191
|
|
|
192
|
+
def _scalar_columns(tags: TrackTags) -> dict[str, str | int]:
|
|
193
|
+
"""Column values for the tags stored on the DjmdContent row itself."""
|
|
194
|
+
return {
|
|
195
|
+
f.column: tags.get(f.tag) or f.default for f in TAG_FIELDS if f.relation is None
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
|
|
219
199
|
def _created_date(path: str) -> str:
|
|
220
200
|
"""The file's creation date, as Rekordbox records DateCreated.
|
|
221
201
|
|
|
@@ -244,12 +224,7 @@ def _build_content(
|
|
|
244
224
|
candidate.stored,
|
|
245
225
|
**IMPORT_DEFAULTS,
|
|
246
226
|
**_resolve_relations(db, tags, created),
|
|
247
|
-
|
|
248
|
-
Commnt=tags["comment"] or "",
|
|
249
|
-
ISRC=tags["isrc"] or "",
|
|
250
|
-
TrackNo=tags["track_no"] or 0,
|
|
251
|
-
DiscNo=tags["disc_no"] or 0,
|
|
252
|
-
ReleaseYear=tags["release_year"] or 0,
|
|
227
|
+
**_scalar_columns(tags),
|
|
253
228
|
Length=tags["length"] or 0,
|
|
254
229
|
)
|
|
255
230
|
# add_content types by extension, mapping every .m4a to AAC, and stamps
|