pyrekordbox 0.4.1__tar.gz → 0.4.3__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.
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/workflows/tests.yml +3 -1
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.pre-commit-config.yaml +1 -1
- pyrekordbox-0.4.3/.testdata/empty.mp3 +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/CHANGELOG.md +35 -1
- {pyrekordbox-0.4.1/pyrekordbox.egg-info → pyrekordbox-0.4.3}/PKG-INFO +1 -1
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/formats/db6.md +1 -1
- pyrekordbox-0.4.3/docs/source/tutorial/anlz.md +88 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/mysetting.md +17 -1
- pyrekordbox-0.4.3/py.typed +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyproject.toml +43 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/__init__.py +1 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/__main__.py +3 -2
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/_version.py +2 -2
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/anlz/__init__.py +6 -6
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/anlz/file.py +40 -32
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/anlz/tags.py +108 -70
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/config.py +36 -26
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/aux_files.py +40 -14
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/database.py +382 -220
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/registry.py +48 -34
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/smartlist.py +12 -12
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/tables.py +51 -52
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/mysettings/__init__.py +3 -2
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/mysettings/file.py +27 -24
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/rbxml.py +327 -147
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/utils.py +7 -6
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3/pyrekordbox.egg-info}/PKG-INFO +1 -1
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/SOURCES.txt +3 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/requirements.txt +6 -1
- pyrekordbox-0.4.3/tests/test_cli.py +31 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/test_db6.py +12 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/test_xml.py +66 -1
- pyrekordbox-0.4.1/docs/source/tutorial/anlz.md +0 -7
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/ISSUE_TEMPLATE/config.yaml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/workflows/codeql.yml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/workflows/pypi-publish.yml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.gitignore +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.readthedocs.yaml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/DEVSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P016/0000875E/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P016/0000875E/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P016/0000875E/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P017/00009B77/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P017/00009B77/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P017/00009B77/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P019/00020AA9/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P019/00020AA9/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P019/00020AA9/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P021/00006D2B/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P021/00006D2B/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P021/00006D2B/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P043/00011517/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P043/00011517/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P043/00011517/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P053/0001D21F/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P053/0001D21F/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P053/0001D21F/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/rekordbox/export.pdb +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/rekordbox/exportExt.pdb +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/DEVSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/beat_fx_quantize/off/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/beat_fx_quantize/on/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve/linear/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve/steep_bottom/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve/steep_top/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve_long/exponential/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve_long/linear/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve_long/smooth/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/cross_fader_curve/constant/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/cross_fader_curve/fast_cut/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/cross_fader_curve/slow_cut/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/five/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/four/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/one/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/three/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/two/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/white/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/headphones_mono_split/mono_split/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/headphones_mono_split/stereo/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/headphones_pre_eq/post_eq/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/headphones_pre_eq/pre_eq/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/indicator_brightness/one/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/indicator_brightness/three/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/indicator_brightness/two/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/mic_low_cut/off/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/mic_low_cut/on/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_button_type/toggle/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_button_type/trigger/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/eight/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/eleven/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/fifteen/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/five/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/four/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/fourteen/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/nine/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/one/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/seven/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/six/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/sixteen/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/ten/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/thirteen/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/three/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/twelve/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/two/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_level/minus_12db/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_level/minus_18db/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_level/minus_24db/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_level/minus_6db/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_mode/advanced/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_mode/normal/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue/on/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/memory/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_36db/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_42db/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_48db/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_54db/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_60db/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_66db/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_72db/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_78db/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/disc_slot_illumination/bright/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/disc_slot_illumination/dark/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/disc_slot_illumination/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/eject_lock/lock/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/eject_lock/unlock/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_autoload/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_autoload/on/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_autoload/rekordbox/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_color/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_color/on/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_mode/cdj/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_mode/vinyl/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_brightness/bright/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_brightness/dark/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_brightness/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_indicator/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_indicator/on/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/chinese_simplified/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/chinese_traditional/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/czech/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/danish/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/dutch/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/english/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/french/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/german/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/greek/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/hungarian/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/italian/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/japanese/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/korean/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/portuguese/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/russian/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/spanish/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/swedish/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/turkish/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/five/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/four/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/one/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/three/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/two/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/master_tempo/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/master_tempo/on/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/needle_lock/lock/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/needle_lock/unlock/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/on_air_display/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/on_air_display/on/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/phase_meter/type1/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/phase_meter/type2/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/play_mode/continue_/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/play_mode/single/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize/on/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize_beat_value/eighth/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize_beat_value/half/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize_beat_value/one/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize_beat_value/quarter/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/slip_flashing/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/slip_flashing/on/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/sync/off/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/sync/on/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/tempo_range/six/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/tempo_range/sixteen/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/tempo_range/ten/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/tempo_range/wide/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/time_mode/elapsed/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/time_mode/remain/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/eight/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/four/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/half/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/one/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/sixteen/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/sixtyfour/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/thirtytwo/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/two/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_display_mode/artwork/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_display_mode/auto/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_display_mode/info/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_display_mode/simple/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/five/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/four/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/one/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/three/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/two/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/pad_button_brightness/four/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/pad_button_brightness/one/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/pad_button_brightness/three/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/pad_button_brightness/two/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/vinyl_speed_adjust/release/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/vinyl_speed_adjust/touch/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/vinyl_speed_adjust/touch_release/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/waveform/phase_meter/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/waveform/waveform/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/waveform_divisions/phrase/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/waveform_divisions/time_scale/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/DEVSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/ExtData.edb +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P002/00009C2E/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P002/00009C2E/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P02B/00023587/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P02B/00023587/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P035/00027763/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P035/00027763/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P038/0002AAA0/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P038/0002AAA0/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P068/00012CA2/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P068/00012CA2/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P076/00013B6E/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P076/00013B6E/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/datafile.edb +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/masterPlaylists3.xml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/database.xml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/datafile.edb +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/DEVSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/DJMMYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/MYSETTING.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/MYSETTING2.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/masterPlaylists3.xml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/masterPlaylists6.xml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/003/c9538-33bc-4ca7-b6c7-e63ebf9a96f8/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/003/c9538-33bc-4ca7-b6c7-e63ebf9a96f8/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/003/c9538-33bc-4ca7-b6c7-e63ebf9a96f8/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/104/c82cc-661c-4f30-ab60-51ce1effeeed/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/104/c82cc-661c-4f30-ab60-51ce1effeeed/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/104/c82cc-661c-4f30-ab60-51ce1effeeed/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/36d/ad2b4-5d4e-4b94-9a5d-a5bb241aee4b/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/36d/ad2b4-5d4e-4b94-9a5d-a5bb241aee4b/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/36d/ad2b4-5d4e-4b94-9a5d-a5bb241aee4b/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/731/0104f-53cb-453e-8b83-e0dfd5cff825/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/731/0104f-53cb-453e-8b83-e0dfd5cff825/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/731/0104f-53cb-453e-8b83-e0dfd5cff825/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/c8b/ac74a-bbfc-4fce-8fb8-50aa4e974273/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/c8b/ac74a-bbfc-4fce-8fb8-50aa4e974273/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/c8b/ac74a-bbfc-4fce-8fb8-50aa4e974273/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/e35/fa187-3f34-47e2-9880-2b33cb8d1304/ANLZ0000.2EX +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/e35/fa187-3f34-47e2-9880-2b33cb8d1304/ANLZ0000.DAT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/share/PIONEER/USBANLZ/e35/fa187-3f34-47e2-9880-2b33cb8d1304/ANLZ0000.EXT +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/database.xml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/masterPlaylists6_template.xml +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/master_locked.db +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/master_unlocked.db +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/CONTRIBUTING.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/LICENSE +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/README.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/Makefile +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/make.bat +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_beat.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_file.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pco2.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pcob.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pcp2.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pcpt.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_ppth.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pqt2.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pqt2_2.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pqtz.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pssi.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pssi_entry.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pvbr.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwav.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv3.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv4.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv5.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv5_entry.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv6.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv7.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwvc.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_tag.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/x64dbg_rb_key.png +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/logos/dark/logo_primary.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/logos/light/logo_primary.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/logos/mid/logo_primary.svg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/apidoc/module.rst_t +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/apidoc/package.rst_t +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/apidoc/toc.rst_t +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/autosummary/class.rst +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/autosummary/module.rst +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/api.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/conf.py +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/development/changes.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/development/contributing.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/formats/anlz.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/formats/mysetting.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/formats/xml.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/index.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/installation.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/key.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/quickstart.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/requirements.txt +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/configuration.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/db6.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/index.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/xml.md +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/anlz/structs.py +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/__init__.py +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/logger.py +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/mysettings/structs.py +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/dependency_links.txt +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/not-zip-safe +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/requires.txt +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/top_level.txt +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/setup.cfg +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/__init__.py +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/test_anlz.py +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/test_config.py +0 -0
- {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/test_mysetting.py +0 -0
@@ -74,7 +74,9 @@ jobs:
|
|
74
74
|
pytest tests/ --cov=pyrekordbox --cov-report=xml -v
|
75
75
|
|
76
76
|
- name: Upload coverage to Codecov
|
77
|
-
uses: codecov/codecov-action@
|
77
|
+
uses: codecov/codecov-action@v4
|
78
|
+
env:
|
79
|
+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
78
80
|
with:
|
79
81
|
env_vars: OS,PYTHON
|
80
82
|
verbose: True
|
Binary file
|
@@ -1,5 +1,37 @@
|
|
1
1
|
# What's New
|
2
2
|
|
3
|
+
<a name="v0.4.3"></a>
|
4
|
+
## [v0.4.3] - 2025-05-14
|
5
|
+
|
6
|
+
This release adds type annotations across the codebase and fixes various bugs.
|
7
|
+
|
8
|
+
### Improvements/Bug Fixes
|
9
|
+
|
10
|
+
- **db:** **add type checks for deleting playlists and playlist songs ([#169](https://github.com/dylanljones/pyrekordbox/issues/169))**
|
11
|
+
This prevents deleting a content instead of a playlist song by accident.
|
12
|
+
- **db:** **fix timezone issue when setting datetimes ([#168](https://github.com/dylanljones/pyrekordbox/issues/168))**
|
13
|
+
Datetime fields are now set with UTC which is the same format that Rekordbox uses.
|
14
|
+
Timezone agnostic dates or dates with another timezone are converted accordingly.
|
15
|
+
- **xml:** **fix issue with pretty-formatting xml string ([#164](https://github.com/dylanljones/pyrekordbox/issues/164))**
|
16
|
+
For Python>3.8 the built-in indentation is used, for Python3.8 the XML string is returned unformatted if minidom fails
|
17
|
+
- **add type hints across the codebase and use mypy for static type checking**
|
18
|
+
|
19
|
+
|
20
|
+
<a name="v0.4.2"></a>
|
21
|
+
## [v0.4.2] - 2025-04-21
|
22
|
+
|
23
|
+
This release contains bug fixes for the command-line interface and XML handling.
|
24
|
+
|
25
|
+
### Improvements/Bug Fixes
|
26
|
+
|
27
|
+
- **cli:** **fix import error when downloading db key via CLI ([#162](https://github.com/dylanljones/pyrekordbox/pull/162))**
|
28
|
+
- **xml:** **fix get_track method to accept Location parameter**
|
29
|
+
|
30
|
+
### Documentation
|
31
|
+
|
32
|
+
- **anlz:** **add simple tutorial for ANLZ files**
|
33
|
+
- **db:** **add ActiveLoop description**
|
34
|
+
|
3
35
|
|
4
36
|
<a name="v0.4.1"></a>
|
5
37
|
## [v0.4.1] - 2025-04-20
|
@@ -634,7 +666,9 @@ This release contains documentation fixes.
|
|
634
666
|
- **add missing djmd tables to `master.db` database documentation**
|
635
667
|
|
636
668
|
|
637
|
-
[Unreleased]: https://github.com/dylanljones/pyrekordbox/compare/v0.4.
|
669
|
+
[Unreleased]: https://github.com/dylanljones/pyrekordbox/compare/v0.4.3...HEAD
|
670
|
+
[v0.4.3]: https://github.com/dylanljones/pyrekordbox/compare/v0.4.2...v0.4.3
|
671
|
+
[v0.4.2]: https://github.com/dylanljones/pyrekordbox/compare/v0.4.1...v0.4.2
|
638
672
|
[v0.4.1]: https://github.com/dylanljones/pyrekordbox/compare/v0.4.0...v0.4.1
|
639
673
|
[v0.4.0]: https://github.com/dylanljones/pyrekordbox/compare/v0.3.2...v0.4.0
|
640
674
|
[v0.3.2]: https://github.com/dylanljones/pyrekordbox/compare/v0.3.1...v0.3.2
|
@@ -497,7 +497,7 @@ around 1/75th of a second (13.333ms) per frame, i.e. about half the granularity
|
|
497
497
|
- ?
|
498
498
|
-
|
499
499
|
* - `ActiveLoop`
|
500
|
-
-
|
500
|
+
- Should the loop start active when reaching the point in playback
|
501
501
|
-
|
502
502
|
* - `Comment`
|
503
503
|
- Name of comment of cue point
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# Analysis Files
|
2
|
+
|
3
|
+
Rekordbox stores analysis information of the tracks in the collection in specific files,
|
4
|
+
which also get exported to decives used by Pioneer professional DJ equipment. The files
|
5
|
+
have names like `ANLZ0000` and come with the extensions `.DAT`, `.EXT` or `.2EX`.
|
6
|
+
They include waveforms, beat grids (information about the precise time at which
|
7
|
+
each beat occurs), time indices to allow efficient seeking to specific positions
|
8
|
+
inside variable bit-rate audio streams, and lists of memory cues and loop points.
|
9
|
+
|
10
|
+
```{seealso}
|
11
|
+
See the {ref}`Analysis Files Format<Analysis Files Format>` documentation for more information.
|
12
|
+
```
|
13
|
+
|
14
|
+
## Reading and writing ANLZ Files
|
15
|
+
|
16
|
+
To read an ANLZ file, you can use the `AnlzFile.parse_file` method:
|
17
|
+
|
18
|
+
```python
|
19
|
+
from pyrekordbox import AnlzFile
|
20
|
+
|
21
|
+
# Read a single ANLZ file
|
22
|
+
anlz = AnlzFile.parse_file("path/to/ANLZXXXX.DAT")
|
23
|
+
```
|
24
|
+
|
25
|
+
You can also read multiple ANLZ files for a single track using the `read_anlz_files` function.
|
26
|
+
It takes the root directory of the files as argument:
|
27
|
+
|
28
|
+
```python
|
29
|
+
from pyrekordbox import read_anlz_files
|
30
|
+
|
31
|
+
# Read all ANLZ files for a track
|
32
|
+
files = read_anlz_files("path/to/anlz_directory")
|
33
|
+
```
|
34
|
+
|
35
|
+
After modifiying the contents of a ANLZ file, it can be saved via
|
36
|
+
```python
|
37
|
+
# Save the ANLZ file contents
|
38
|
+
anlz.save("path/to/ANLZXXXX.DAT")
|
39
|
+
```
|
40
|
+
|
41
|
+
|
42
|
+
To find the ANLZ files corresponding to a specific track in the Rekordbox collection,
|
43
|
+
the database handler includes a method that returnes the directory containing the ANLZ files:
|
44
|
+
```python
|
45
|
+
>>> from pyrekordbox import Rekordbox6Database
|
46
|
+
>>> db = Rekordbox6Database()
|
47
|
+
>>> content = db.get_content().first()
|
48
|
+
>>> db.get_anlz_dir(content)
|
49
|
+
C:\Users\user\AppData\Roaming\Pioneer\rekordbox\share\PIONEER\USBANLZ\0e8\0d4cc-06a6-4574-ba18-1c2301ea9924
|
50
|
+
```
|
51
|
+
|
52
|
+
Alternatively, a dictionary containing the paths of the ANLZ files can be found via
|
53
|
+
```python
|
54
|
+
>>> db.get_anlz_paths(content)
|
55
|
+
{
|
56
|
+
'DAT': 'C:/Users/user/AppData/Roaming/Pioneer/rekordbox/share/PIONEER/USBANLZ/0e8/0d4cc-06a6-4574-ba18-1c2301ea9924/ANLZ0000.DAT',
|
57
|
+
'EXT': 'C:/Users/user/AppData/Roaming/Pioneer/rekordbox/share/PIONEER/USBANLZ/0e8/0d4cc-06a6-4574-ba18-1c2301ea9924/ANLZ0000.EXT',
|
58
|
+
'2EX': None
|
59
|
+
}
|
60
|
+
```
|
61
|
+
In this example, the analysis data of the track is stored in only two ANLZ files, `ANLZ0000.DAT` and `ANLZ0000.EXT`.
|
62
|
+
Instead of returning the paths of the analysis files, they can also be read directly via
|
63
|
+
```python
|
64
|
+
db.read_anlz_files(content)
|
65
|
+
```
|
66
|
+
|
67
|
+
|
68
|
+
## Accessing ANLZ Data
|
69
|
+
|
70
|
+
The `AnlzFile` object implements a dictionary-like interface. You can access tags by their type code or name:
|
71
|
+
|
72
|
+
```python
|
73
|
+
# Check if a tag exists
|
74
|
+
if "beat_grid" in anlz:
|
75
|
+
print("Beat grid found")
|
76
|
+
|
77
|
+
# Get the first tag of a specific type
|
78
|
+
beat_grid = anlz.get_tag("PQTZ")
|
79
|
+
# or by name
|
80
|
+
beat_grid = anlz.get_tag("beat_grid")
|
81
|
+
|
82
|
+
# Get all tags of a specific type
|
83
|
+
all_cues = anlz.getall_tags("PCOB")
|
84
|
+
```
|
85
|
+
|
86
|
+
```{note}
|
87
|
+
More coming soon!
|
88
|
+
```
|
@@ -13,7 +13,8 @@ DJ equipment.
|
|
13
13
|
See the {ref}`My-Setting Files Format<My-Setting Files Format>` documentation for more information.
|
14
14
|
```
|
15
15
|
|
16
|
-
Pyrekordbox includes a file handler for each of the four My-Settings files.
|
16
|
+
Pyrekordbox includes a file handler for each of the four My-Settings files.
|
17
|
+
To read any of the four files, use
|
17
18
|
````python
|
18
19
|
from pyrekordbox import read_mysetting_file
|
19
20
|
|
@@ -30,6 +31,21 @@ file3 = DjmMySettingFile.parse_file("DJMMYSETTING.DAT")
|
|
30
31
|
file4 = DevSettingFile.parse_file("DEVSETTING.DAT")
|
31
32
|
````
|
32
33
|
|
34
|
+
To find the My-Settings files, the database handler includes a method that returnes the
|
35
|
+
paths of all four files:
|
36
|
+
````python
|
37
|
+
>>> from pyrekordbox import Rekordbox6Database
|
38
|
+
>>> db = Rekordbox6Database()
|
39
|
+
>>> db.get_mysetting_paths()
|
40
|
+
[
|
41
|
+
'C:/Users/user/AppData/Roaming/Pioneer/rekordbox/DEVSETTING.DAT',
|
42
|
+
'C:/Users/user/AppData/Roaming/Pioneer/rekordbox/DJMMYSETTING.DAT',
|
43
|
+
'C:/Users/user/AppData/Roaming/Pioneer/rekordbox/MYSETTING.DAT',
|
44
|
+
'C:/Users/user/AppData/Roaming/Pioneer/rekordbox/MYSETTING2.DAT'
|
45
|
+
]
|
46
|
+
````
|
47
|
+
|
48
|
+
|
33
49
|
After parsing a My-Setting file, the settings can be accessed as dictionary:
|
34
50
|
````python
|
35
51
|
>>> file = read_mysetting_file("MYSETTING.DAT")
|
File without changes
|
@@ -78,6 +78,9 @@ include = ["pyrekordbox", "pyrekordbox.*"]
|
|
78
78
|
write_to = "pyrekordbox/_version.py"
|
79
79
|
git_describe_command = "git describe --dirty --tags --long --match * --first-parent"
|
80
80
|
|
81
|
+
[tool.setuptools.package-data]
|
82
|
+
pyrekordbox = ["py.typed"]
|
83
|
+
|
81
84
|
|
82
85
|
# -- Ruff ------------------------------------------------------------------------------
|
83
86
|
|
@@ -105,6 +108,7 @@ select = [
|
|
105
108
|
"NPY", # Numpy
|
106
109
|
"N", # pep8-naming
|
107
110
|
"D", # pydocstyle
|
111
|
+
"ANN", # types-annotations
|
108
112
|
]
|
109
113
|
ignore = [
|
110
114
|
"E203", # Whitespace before ':'
|
@@ -124,12 +128,21 @@ ignore = [
|
|
124
128
|
"N813", # Camelcase imported as lowercase
|
125
129
|
#"N815", # Variable in class scope should not be mixedCase
|
126
130
|
"N818", # Exception name should be named with an Error suffix
|
131
|
+
"ANN001", # Missing type annotation for obj in method
|
132
|
+
"ANN002", # Missing type annotation for args in method
|
133
|
+
"ANN003", # Missing type annotation for kwargs in method
|
134
|
+
"ANN101", # Missing type annotation for self in method
|
135
|
+
"ANN102", # Missing type annotation for cls in classmethod
|
136
|
+
"ANN204", # Missing return type for __init__
|
137
|
+
"ANN401", # Dynamically typed expressions (typing.Any) are disallowed
|
127
138
|
]
|
128
139
|
fixable = ["ALL"] # Allow fix for all enabled rules (when `--fix`) is provided.
|
129
140
|
unfixable = []
|
130
141
|
|
131
142
|
[tool.ruff.lint.per-file-ignores]
|
132
143
|
"*__init__.py" = ["F401"]
|
144
|
+
"*__main__.py" = ["ANN"]
|
145
|
+
"tests/*" = ["ANN"]
|
133
146
|
"rbxml.py" = ["N803"]
|
134
147
|
"tables.py" = ["N802", "N815"]
|
135
148
|
|
@@ -148,6 +161,36 @@ skip-magic-trailing-comma = false
|
|
148
161
|
line-ending = "auto"
|
149
162
|
|
150
163
|
|
164
|
+
# -- Mypy ------------------------------------------------------------------------------
|
165
|
+
|
166
|
+
[tool.mypy]
|
167
|
+
|
168
|
+
strict = true
|
169
|
+
ignore_missing_imports = true # Ignore missing type hints for third-party librarie
|
170
|
+
show_error_codes = true # Show error codes in the output
|
171
|
+
|
172
|
+
exclude = [
|
173
|
+
"__main__.py",
|
174
|
+
'tools',
|
175
|
+
'agent'
|
176
|
+
]
|
177
|
+
|
178
|
+
# Useful fine-tuning overrides to 'strict'
|
179
|
+
warn_unused_configs = true
|
180
|
+
warn_return_any = true
|
181
|
+
no_implicit_optional = false
|
182
|
+
warn_unused_ignores = true
|
183
|
+
disallow_untyped_defs = true
|
184
|
+
disallow_incomplete_defs = true
|
185
|
+
disallow_untyped_calls = false # often useful to allow
|
186
|
+
disallow_untyped_decorators = false # decorators are often tricky
|
187
|
+
check_untyped_defs = true
|
188
|
+
|
189
|
+
plugins = [
|
190
|
+
"numpy.typing.mypy_plugin",
|
191
|
+
"sqlalchemy.ext.mypy.plugin",
|
192
|
+
]
|
193
|
+
|
151
194
|
# -- Coverage --------------------------------------------------------------------------
|
152
195
|
|
153
196
|
[tool.coverage.run]
|
@@ -9,7 +9,7 @@ import sys
|
|
9
9
|
import urllib.request
|
10
10
|
from pathlib import Path
|
11
11
|
|
12
|
-
from pyrekordbox.config import
|
12
|
+
from pyrekordbox.config import get_cache_file, write_db6_key_cache
|
13
13
|
|
14
14
|
KEY_SOURCES = [
|
15
15
|
{
|
@@ -144,7 +144,8 @@ def download_db6_key():
|
|
144
144
|
dp = match.group("dp")
|
145
145
|
break
|
146
146
|
if dp:
|
147
|
-
|
147
|
+
cache_file = get_cache_file()
|
148
|
+
print(f"Found key, updating cache file {cache_file}")
|
148
149
|
write_db6_key_cache(dp)
|
149
150
|
else:
|
150
151
|
print("No key found in the online sources.")
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
import re
|
6
6
|
from pathlib import Path
|
7
|
-
from typing import Union
|
7
|
+
from typing import Dict, Iterator, Tuple, Union
|
8
8
|
|
9
9
|
from . import structs
|
10
10
|
from .file import AnlzFile
|
@@ -42,7 +42,7 @@ def is_anlz_file(path: Union[str, Path]) -> bool:
|
|
42
42
|
return bool(RE_ANLZ.match(path.name))
|
43
43
|
|
44
44
|
|
45
|
-
def get_anlz_paths(root: Union[str, Path]) ->
|
45
|
+
def get_anlz_paths(root: Union[str, Path]) -> Dict[str, Union[Path, None]]:
|
46
46
|
"""Returns the paths of all existing ANLZ files in a directory.
|
47
47
|
|
48
48
|
Parameters
|
@@ -62,14 +62,14 @@ def get_anlz_paths(root: Union[str, Path]) -> dict:
|
|
62
62
|
>>> p["DAT"]
|
63
63
|
directory/ANLZ0000.DAT
|
64
64
|
"""
|
65
|
-
paths = {"DAT": None, "EXT": None, "2EX": None}
|
65
|
+
paths: Dict[str, Union[Path, None]] = {"DAT": None, "EXT": None, "2EX": None}
|
66
66
|
for path in Path(root).iterdir():
|
67
67
|
if RE_ANLZ.match(path.name):
|
68
68
|
paths[path.suffix[1:].upper()] = path
|
69
69
|
return paths
|
70
70
|
|
71
71
|
|
72
|
-
def walk_anlz_dirs(root_dir: Union[str, Path]):
|
72
|
+
def walk_anlz_dirs(root_dir: Union[str, Path]) -> Iterator[Path]:
|
73
73
|
"""Finds all ANLZ directory paths recursively.
|
74
74
|
|
75
75
|
Parameters
|
@@ -88,7 +88,7 @@ def walk_anlz_dirs(root_dir: Union[str, Path]):
|
|
88
88
|
yield path
|
89
89
|
|
90
90
|
|
91
|
-
def walk_anlz_paths(root_dir: Union[str, Path]):
|
91
|
+
def walk_anlz_paths(root_dir: Union[str, Path]) -> Iterator[Tuple[Path, Dict[str, Path]]]:
|
92
92
|
"""Finds all ANLZ directory paths and the containing file paths recursively.
|
93
93
|
|
94
94
|
Parameters
|
@@ -110,7 +110,7 @@ def walk_anlz_paths(root_dir: Union[str, Path]):
|
|
110
110
|
yield anlz_dir, files
|
111
111
|
|
112
112
|
|
113
|
-
def read_anlz_files(root: Union[str, Path] = "") ->
|
113
|
+
def read_anlz_files(root: Union[str, Path] = "") -> Dict[Path, AnlzFile]:
|
114
114
|
"""Open all ANLZ files in the given root directory.
|
115
115
|
|
116
116
|
Parameters
|
@@ -5,12 +5,12 @@
|
|
5
5
|
import logging
|
6
6
|
from collections import abc
|
7
7
|
from pathlib import Path
|
8
|
-
from typing import Union
|
8
|
+
from typing import Any, Iterator, List, Union
|
9
9
|
|
10
|
-
from construct import Int16ub
|
10
|
+
from construct import Int16ub, Struct
|
11
11
|
|
12
12
|
from . import structs
|
13
|
-
from .tags import TAGS
|
13
|
+
from .tags import TAGS, AbstractAnlzTag, StructNotInitializedError
|
14
14
|
|
15
15
|
logger = logging.getLogger(__name__)
|
16
16
|
|
@@ -18,35 +18,35 @@ XOR_MASK = bytearray.fromhex("CB E1 EE FA E5 EE AD EE E9 D2 E9 EB E1 E9 F3 E8 E9
|
|
18
18
|
|
19
19
|
|
20
20
|
class BuildFileLengthError(Exception):
|
21
|
-
def __init__(self, struct, len_data):
|
21
|
+
def __init__(self, struct: Struct, len_data: int) -> None:
|
22
22
|
super().__init__(
|
23
23
|
f"`len_file` ({struct.len_file}) of '{struct.type}' does not "
|
24
24
|
f"match the data-length ({len_data})!"
|
25
25
|
)
|
26
26
|
|
27
27
|
|
28
|
-
class AnlzFile(abc.Mapping):
|
28
|
+
class AnlzFile(abc.Mapping): # type: ignore[type-arg]
|
29
29
|
"""Rekordbox `ANLZnnnn.xxx` binary file handler."""
|
30
30
|
|
31
|
-
def __init__(self):
|
32
|
-
self._path = ""
|
33
|
-
self.file_header = None
|
34
|
-
self.tags = list()
|
31
|
+
def __init__(self) -> None:
|
32
|
+
self._path: str = ""
|
33
|
+
self.file_header: Union[Struct, None] = None
|
34
|
+
self.tags: List[AbstractAnlzTag] = list()
|
35
35
|
|
36
36
|
@property
|
37
|
-
def num_tags(self):
|
37
|
+
def num_tags(self) -> int:
|
38
38
|
return len(self.tags)
|
39
39
|
|
40
40
|
@property
|
41
|
-
def tag_types(self):
|
41
|
+
def tag_types(self) -> List[str]:
|
42
42
|
return [tag.type for tag in self.tags]
|
43
43
|
|
44
44
|
@property
|
45
|
-
def path(self):
|
45
|
+
def path(self) -> str:
|
46
46
|
return self._path
|
47
47
|
|
48
48
|
@classmethod
|
49
|
-
def parse(cls, data: bytes):
|
49
|
+
def parse(cls, data: bytes) -> "AnlzFile":
|
50
50
|
"""Parses the in-memory data of a Rekordbox analysis binary file.
|
51
51
|
|
52
52
|
Parameters
|
@@ -64,7 +64,7 @@ class AnlzFile(abc.Mapping):
|
|
64
64
|
return self
|
65
65
|
|
66
66
|
@classmethod
|
67
|
-
def parse_file(cls, path: Union[str, Path]):
|
67
|
+
def parse_file(cls, path: Union[str, Path]) -> "AnlzFile":
|
68
68
|
"""Reads and parses a Rekordbox analysis binary file.
|
69
69
|
|
70
70
|
Parameters
|
@@ -92,10 +92,10 @@ class AnlzFile(abc.Mapping):
|
|
92
92
|
data = fh.read()
|
93
93
|
|
94
94
|
self = cls.parse(data)
|
95
|
-
self._path = path
|
95
|
+
self._path = str(path)
|
96
96
|
return self
|
97
97
|
|
98
|
-
def _parse(self, data: bytes):
|
98
|
+
def _parse(self, data: bytes) -> None:
|
99
99
|
file_header = structs.AnlzFileHeader.parse(data)
|
100
100
|
tag_type = file_header.type
|
101
101
|
assert tag_type == "PMAI"
|
@@ -136,6 +136,8 @@ class AnlzFile(abc.Mapping):
|
|
136
136
|
try:
|
137
137
|
# Parse the struct
|
138
138
|
tag = TAGS[tag_type](tag_data)
|
139
|
+
if tag.struct is None:
|
140
|
+
raise StructNotInitializedError()
|
139
141
|
tags.append(tag)
|
140
142
|
len_header = tag.struct.len_header
|
141
143
|
len_tag = tag.struct.len_tag
|
@@ -147,28 +149,34 @@ class AnlzFile(abc.Mapping):
|
|
147
149
|
)
|
148
150
|
except KeyError:
|
149
151
|
logger.warning("Tag '%s' not supported!", tag_type)
|
150
|
-
|
151
|
-
len_tag =
|
152
|
+
tag_struct = structs.AnlzTag.parse(tag_data)
|
153
|
+
len_tag = tag_struct.len_tag
|
152
154
|
i += len_tag
|
153
155
|
|
154
156
|
self.file_header = file_header
|
155
157
|
self.tags = tags
|
156
158
|
|
157
|
-
def update_len(self):
|
159
|
+
def update_len(self) -> None:
|
158
160
|
# Update struct lengths
|
161
|
+
if self.file_header is None:
|
162
|
+
raise StructNotInitializedError()
|
159
163
|
tags_len = 0
|
160
164
|
for tag in self.tags:
|
165
|
+
if tag.struct is None:
|
166
|
+
raise StructNotInitializedError()
|
161
167
|
tag.update_len()
|
162
168
|
tags_len += tag.struct.len_tag
|
163
169
|
# Update file length
|
164
170
|
len_file = self.file_header.len_header + tags_len
|
165
171
|
self.file_header.len_file = len_file
|
166
172
|
|
167
|
-
def build(self):
|
173
|
+
def build(self) -> bytes:
|
174
|
+
if self.file_header is None:
|
175
|
+
raise StructNotInitializedError()
|
168
176
|
self.update_len()
|
169
177
|
header_data = structs.AnlzFileHeader.build(self.file_header)
|
170
178
|
section_data = b"".join(tag.build() for tag in self.tags)
|
171
|
-
data = header_data + section_data
|
179
|
+
data: bytes = header_data + section_data
|
172
180
|
# Check `len_file`
|
173
181
|
len_file = self.file_header.len_file
|
174
182
|
len_data = len(data)
|
@@ -177,38 +185,38 @@ class AnlzFile(abc.Mapping):
|
|
177
185
|
|
178
186
|
return data
|
179
187
|
|
180
|
-
def save(self, path=""):
|
188
|
+
def save(self, path: Union[str, Path] = "") -> None:
|
181
189
|
path = path or self._path
|
182
190
|
|
183
191
|
data = self.build()
|
184
192
|
with open(path, "wb") as fh:
|
185
193
|
fh.write(data)
|
186
194
|
|
187
|
-
def get_tag(self, key):
|
195
|
+
def get_tag(self, key: str) -> AbstractAnlzTag:
|
188
196
|
return self.__getitem__(key)[0]
|
189
197
|
|
190
|
-
def getall_tags(self, key):
|
198
|
+
def getall_tags(self, key: str) -> List[AbstractAnlzTag]:
|
191
199
|
return self.__getitem__(key)
|
192
200
|
|
193
|
-
def get(self, key):
|
201
|
+
def get(self, key: str) -> Any: # type: ignore[override]
|
194
202
|
return self.__getitem__(key)[0].get()
|
195
203
|
|
196
|
-
def getall(self, key):
|
204
|
+
def getall(self, key: str) -> List[Any]:
|
197
205
|
return [tag.get() for tag in self.__getitem__(key)]
|
198
206
|
|
199
|
-
def __len__(self):
|
207
|
+
def __len__(self) -> int:
|
200
208
|
return len(self.keys())
|
201
209
|
|
202
|
-
def __iter__(self):
|
210
|
+
def __iter__(self) -> Iterator[str]:
|
203
211
|
return iter(set(tag.type for tag in self.tags))
|
204
212
|
|
205
|
-
def __getitem__(self, item):
|
213
|
+
def __getitem__(self, item: str) -> List[AbstractAnlzTag]:
|
206
214
|
if item.isupper() and len(item) == 4:
|
207
215
|
return [tag for tag in self.tags if tag.type == item]
|
208
216
|
else:
|
209
217
|
return [tag for tag in self.tags if tag.name == item]
|
210
218
|
|
211
|
-
def __contains__(self, item):
|
219
|
+
def __contains__(self, item: str) -> bool: # type: ignore[override]
|
212
220
|
if item.isupper() and len(item) == 4:
|
213
221
|
for tag in self.tags:
|
214
222
|
if item == tag.type:
|
@@ -219,9 +227,9 @@ class AnlzFile(abc.Mapping):
|
|
219
227
|
return True
|
220
228
|
return False
|
221
229
|
|
222
|
-
def __repr__(self):
|
230
|
+
def __repr__(self) -> str:
|
223
231
|
return f"{self.__class__.__name__}({self.tag_types})"
|
224
232
|
|
225
|
-
def set_path(self, path):
|
233
|
+
def set_path(self, path: Union[Path, str]) -> None:
|
226
234
|
tag = self.get_tag("PPTH")
|
227
235
|
tag.set(path)
|