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.
Files changed (335) hide show
  1. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/workflows/tests.yml +3 -1
  2. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.pre-commit-config.yaml +1 -1
  3. pyrekordbox-0.4.3/.testdata/empty.mp3 +0 -0
  4. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/CHANGELOG.md +35 -1
  5. {pyrekordbox-0.4.1/pyrekordbox.egg-info → pyrekordbox-0.4.3}/PKG-INFO +1 -1
  6. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/formats/db6.md +1 -1
  7. pyrekordbox-0.4.3/docs/source/tutorial/anlz.md +88 -0
  8. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/mysetting.md +17 -1
  9. pyrekordbox-0.4.3/py.typed +0 -0
  10. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyproject.toml +43 -0
  11. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/__init__.py +1 -0
  12. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/__main__.py +3 -2
  13. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/_version.py +2 -2
  14. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/anlz/__init__.py +6 -6
  15. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/anlz/file.py +40 -32
  16. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/anlz/tags.py +108 -70
  17. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/config.py +36 -26
  18. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/aux_files.py +40 -14
  19. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/database.py +382 -220
  20. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/registry.py +48 -34
  21. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/smartlist.py +12 -12
  22. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/tables.py +51 -52
  23. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/mysettings/__init__.py +3 -2
  24. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/mysettings/file.py +27 -24
  25. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/rbxml.py +327 -147
  26. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/utils.py +7 -6
  27. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3/pyrekordbox.egg-info}/PKG-INFO +1 -1
  28. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/SOURCES.txt +3 -0
  29. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/requirements.txt +6 -1
  30. pyrekordbox-0.4.3/tests/test_cli.py +31 -0
  31. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/test_db6.py +12 -0
  32. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/test_xml.py +66 -1
  33. pyrekordbox-0.4.1/docs/source/tutorial/anlz.md +0 -7
  34. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  35. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/ISSUE_TEMPLATE/config.yaml +0 -0
  36. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  37. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/workflows/codeql.yml +0 -0
  38. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.github/workflows/pypi-publish.yml +0 -0
  39. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.gitignore +0 -0
  40. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.readthedocs.yaml +0 -0
  41. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/DEVSETTING.DAT +0 -0
  42. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/DJMMYSETTING.DAT +0 -0
  43. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/MYSETTING.DAT +0 -0
  44. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/MYSETTING2.DAT +0 -0
  45. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P016/0000875E/ANLZ0000.2EX +0 -0
  46. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P016/0000875E/ANLZ0000.DAT +0 -0
  47. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P016/0000875E/ANLZ0000.EXT +0 -0
  48. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P017/00009B77/ANLZ0000.2EX +0 -0
  49. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P017/00009B77/ANLZ0000.DAT +0 -0
  50. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P017/00009B77/ANLZ0000.EXT +0 -0
  51. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P019/00020AA9/ANLZ0000.2EX +0 -0
  52. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P019/00020AA9/ANLZ0000.DAT +0 -0
  53. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P019/00020AA9/ANLZ0000.EXT +0 -0
  54. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P021/00006D2B/ANLZ0000.2EX +0 -0
  55. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P021/00006D2B/ANLZ0000.DAT +0 -0
  56. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P021/00006D2B/ANLZ0000.EXT +0 -0
  57. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P043/00011517/ANLZ0000.2EX +0 -0
  58. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P043/00011517/ANLZ0000.DAT +0 -0
  59. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P043/00011517/ANLZ0000.EXT +0 -0
  60. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P053/0001D21F/ANLZ0000.2EX +0 -0
  61. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P053/0001D21F/ANLZ0000.DAT +0 -0
  62. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/USBANLZ/P053/0001D21F/ANLZ0000.EXT +0 -0
  63. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/rekordbox/export.pdb +0 -0
  64. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/export/PIONEER/rekordbox/exportExt.pdb +0 -0
  65. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/DEVSETTING.DAT +0 -0
  66. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/DJMMYSETTING.DAT +0 -0
  67. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/MYSETTING.DAT +0 -0
  68. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/MYSETTING2.DAT +0 -0
  69. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/beat_fx_quantize/off/DJMMYSETTING.DAT +0 -0
  70. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/beat_fx_quantize/on/DJMMYSETTING.DAT +0 -0
  71. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve/linear/DJMMYSETTING.DAT +0 -0
  72. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve/steep_bottom/DJMMYSETTING.DAT +0 -0
  73. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve/steep_top/DJMMYSETTING.DAT +0 -0
  74. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve_long/exponential/DJMMYSETTING.DAT +0 -0
  75. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve_long/linear/DJMMYSETTING.DAT +0 -0
  76. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/channel_fader_curve_long/smooth/DJMMYSETTING.DAT +0 -0
  77. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/cross_fader_curve/constant/DJMMYSETTING.DAT +0 -0
  78. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/cross_fader_curve/fast_cut/DJMMYSETTING.DAT +0 -0
  79. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/cross_fader_curve/slow_cut/DJMMYSETTING.DAT +0 -0
  80. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/five/DJMMYSETTING.DAT +0 -0
  81. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/four/DJMMYSETTING.DAT +0 -0
  82. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/one/DJMMYSETTING.DAT +0 -0
  83. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/three/DJMMYSETTING.DAT +0 -0
  84. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/two/DJMMYSETTING.DAT +0 -0
  85. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/display_brightness/white/DJMMYSETTING.DAT +0 -0
  86. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/headphones_mono_split/mono_split/DJMMYSETTING.DAT +0 -0
  87. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/headphones_mono_split/stereo/DJMMYSETTING.DAT +0 -0
  88. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/headphones_pre_eq/post_eq/DJMMYSETTING.DAT +0 -0
  89. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/headphones_pre_eq/pre_eq/DJMMYSETTING.DAT +0 -0
  90. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/indicator_brightness/one/DJMMYSETTING.DAT +0 -0
  91. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/indicator_brightness/three/DJMMYSETTING.DAT +0 -0
  92. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/indicator_brightness/two/DJMMYSETTING.DAT +0 -0
  93. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/mic_low_cut/off/DJMMYSETTING.DAT +0 -0
  94. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/mic_low_cut/on/DJMMYSETTING.DAT +0 -0
  95. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_button_type/toggle/DJMMYSETTING.DAT +0 -0
  96. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_button_type/trigger/DJMMYSETTING.DAT +0 -0
  97. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/eight/DJMMYSETTING.DAT +0 -0
  98. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/eleven/DJMMYSETTING.DAT +0 -0
  99. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/fifteen/DJMMYSETTING.DAT +0 -0
  100. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/five/DJMMYSETTING.DAT +0 -0
  101. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/four/DJMMYSETTING.DAT +0 -0
  102. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/fourteen/DJMMYSETTING.DAT +0 -0
  103. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/nine/DJMMYSETTING.DAT +0 -0
  104. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/one/DJMMYSETTING.DAT +0 -0
  105. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/seven/DJMMYSETTING.DAT +0 -0
  106. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/six/DJMMYSETTING.DAT +0 -0
  107. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/sixteen/DJMMYSETTING.DAT +0 -0
  108. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/ten/DJMMYSETTING.DAT +0 -0
  109. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/thirteen/DJMMYSETTING.DAT +0 -0
  110. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/three/DJMMYSETTING.DAT +0 -0
  111. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/twelve/DJMMYSETTING.DAT +0 -0
  112. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/midi_channel/two/DJMMYSETTING.DAT +0 -0
  113. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_level/minus_12db/DJMMYSETTING.DAT +0 -0
  114. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_level/minus_18db/DJMMYSETTING.DAT +0 -0
  115. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_level/minus_24db/DJMMYSETTING.DAT +0 -0
  116. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_level/minus_6db/DJMMYSETTING.DAT +0 -0
  117. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_mode/advanced/DJMMYSETTING.DAT +0 -0
  118. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/djmmysetting/talk_over_mode/normal/DJMMYSETTING.DAT +0 -0
  119. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue/off/MYSETTING.DAT +0 -0
  120. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue/on/MYSETTING.DAT +0 -0
  121. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/memory/MYSETTING.DAT +0 -0
  122. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_36db/MYSETTING.DAT +0 -0
  123. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_42db/MYSETTING.DAT +0 -0
  124. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_48db/MYSETTING.DAT +0 -0
  125. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_54db/MYSETTING.DAT +0 -0
  126. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_60db/MYSETTING.DAT +0 -0
  127. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_66db/MYSETTING.DAT +0 -0
  128. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_72db/MYSETTING.DAT +0 -0
  129. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/auto_cue_level/minus_78db/MYSETTING.DAT +0 -0
  130. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/disc_slot_illumination/bright/MYSETTING.DAT +0 -0
  131. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/disc_slot_illumination/dark/MYSETTING.DAT +0 -0
  132. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/disc_slot_illumination/off/MYSETTING.DAT +0 -0
  133. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/eject_lock/lock/MYSETTING.DAT +0 -0
  134. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/eject_lock/unlock/MYSETTING.DAT +0 -0
  135. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_autoload/off/MYSETTING.DAT +0 -0
  136. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_autoload/on/MYSETTING.DAT +0 -0
  137. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_autoload/rekordbox/MYSETTING.DAT +0 -0
  138. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_color/off/MYSETTING.DAT +0 -0
  139. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/hotcue_color/on/MYSETTING.DAT +0 -0
  140. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_mode/cdj/MYSETTING.DAT +0 -0
  141. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_mode/vinyl/MYSETTING.DAT +0 -0
  142. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_brightness/bright/MYSETTING.DAT +0 -0
  143. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_brightness/dark/MYSETTING.DAT +0 -0
  144. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_brightness/off/MYSETTING.DAT +0 -0
  145. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_indicator/off/MYSETTING.DAT +0 -0
  146. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/jog_ring_indicator/on/MYSETTING.DAT +0 -0
  147. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/chinese_simplified/MYSETTING.DAT +0 -0
  148. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/chinese_traditional/MYSETTING.DAT +0 -0
  149. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/czech/MYSETTING.DAT +0 -0
  150. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/danish/MYSETTING.DAT +0 -0
  151. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/dutch/MYSETTING.DAT +0 -0
  152. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/english/MYSETTING.DAT +0 -0
  153. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/french/MYSETTING.DAT +0 -0
  154. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/german/MYSETTING.DAT +0 -0
  155. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/greek/MYSETTING.DAT +0 -0
  156. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/hungarian/MYSETTING.DAT +0 -0
  157. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/italian/MYSETTING.DAT +0 -0
  158. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/japanese/MYSETTING.DAT +0 -0
  159. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/korean/MYSETTING.DAT +0 -0
  160. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/portuguese/MYSETTING.DAT +0 -0
  161. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/russian/MYSETTING.DAT +0 -0
  162. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/spanish/MYSETTING.DAT +0 -0
  163. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/swedish/MYSETTING.DAT +0 -0
  164. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/language/turkish/MYSETTING.DAT +0 -0
  165. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/five/MYSETTING.DAT +0 -0
  166. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/four/MYSETTING.DAT +0 -0
  167. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/one/MYSETTING.DAT +0 -0
  168. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/three/MYSETTING.DAT +0 -0
  169. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/lcd_brightness/two/MYSETTING.DAT +0 -0
  170. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/master_tempo/off/MYSETTING.DAT +0 -0
  171. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/master_tempo/on/MYSETTING.DAT +0 -0
  172. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/needle_lock/lock/MYSETTING.DAT +0 -0
  173. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/needle_lock/unlock/MYSETTING.DAT +0 -0
  174. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/on_air_display/off/MYSETTING.DAT +0 -0
  175. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/on_air_display/on/MYSETTING.DAT +0 -0
  176. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/phase_meter/type1/MYSETTING.DAT +0 -0
  177. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/phase_meter/type2/MYSETTING.DAT +0 -0
  178. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/play_mode/continue_/MYSETTING.DAT +0 -0
  179. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/play_mode/single/MYSETTING.DAT +0 -0
  180. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize/off/MYSETTING.DAT +0 -0
  181. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize/on/MYSETTING.DAT +0 -0
  182. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize_beat_value/eighth/MYSETTING.DAT +0 -0
  183. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize_beat_value/half/MYSETTING.DAT +0 -0
  184. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize_beat_value/one/MYSETTING.DAT +0 -0
  185. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/quantize_beat_value/quarter/MYSETTING.DAT +0 -0
  186. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/slip_flashing/off/MYSETTING.DAT +0 -0
  187. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/slip_flashing/on/MYSETTING.DAT +0 -0
  188. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/sync/off/MYSETTING.DAT +0 -0
  189. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/sync/on/MYSETTING.DAT +0 -0
  190. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/tempo_range/six/MYSETTING.DAT +0 -0
  191. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/tempo_range/sixteen/MYSETTING.DAT +0 -0
  192. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/tempo_range/ten/MYSETTING.DAT +0 -0
  193. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/tempo_range/wide/MYSETTING.DAT +0 -0
  194. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/time_mode/elapsed/MYSETTING.DAT +0 -0
  195. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting/time_mode/remain/MYSETTING.DAT +0 -0
  196. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/eight/MYSETTING2.DAT +0 -0
  197. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/four/MYSETTING2.DAT +0 -0
  198. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/half/MYSETTING2.DAT +0 -0
  199. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/one/MYSETTING2.DAT +0 -0
  200. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/sixteen/MYSETTING2.DAT +0 -0
  201. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/sixtyfour/MYSETTING2.DAT +0 -0
  202. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/thirtytwo/MYSETTING2.DAT +0 -0
  203. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/beat_jump_beat_value/two/MYSETTING2.DAT +0 -0
  204. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_display_mode/artwork/MYSETTING2.DAT +0 -0
  205. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_display_mode/auto/MYSETTING2.DAT +0 -0
  206. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_display_mode/info/MYSETTING2.DAT +0 -0
  207. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_display_mode/simple/MYSETTING2.DAT +0 -0
  208. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/five/MYSETTING2.DAT +0 -0
  209. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/four/MYSETTING2.DAT +0 -0
  210. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/one/MYSETTING2.DAT +0 -0
  211. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/three/MYSETTING2.DAT +0 -0
  212. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/jog_lcd_brightness/two/MYSETTING2.DAT +0 -0
  213. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/pad_button_brightness/four/MYSETTING2.DAT +0 -0
  214. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/pad_button_brightness/one/MYSETTING2.DAT +0 -0
  215. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/pad_button_brightness/three/MYSETTING2.DAT +0 -0
  216. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/pad_button_brightness/two/MYSETTING2.DAT +0 -0
  217. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/vinyl_speed_adjust/release/MYSETTING2.DAT +0 -0
  218. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/vinyl_speed_adjust/touch/MYSETTING2.DAT +0 -0
  219. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/vinyl_speed_adjust/touch_release/MYSETTING2.DAT +0 -0
  220. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/waveform/phase_meter/MYSETTING2.DAT +0 -0
  221. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/waveform/waveform/MYSETTING2.DAT +0 -0
  222. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/waveform_divisions/phrase/MYSETTING2.DAT +0 -0
  223. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/mysettings/mysetting2/waveform_divisions/time_scale/MYSETTING2.DAT +0 -0
  224. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/DEVSETTING.DAT +0 -0
  225. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/ExtData.edb +0 -0
  226. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/MYSETTING.DAT +0 -0
  227. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P002/00009C2E/ANLZ0000.DAT +0 -0
  228. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P002/00009C2E/ANLZ0000.EXT +0 -0
  229. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P02B/00023587/ANLZ0000.DAT +0 -0
  230. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P02B/00023587/ANLZ0000.EXT +0 -0
  231. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P035/00027763/ANLZ0000.DAT +0 -0
  232. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P035/00027763/ANLZ0000.EXT +0 -0
  233. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P038/0002AAA0/ANLZ0000.DAT +0 -0
  234. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P038/0002AAA0/ANLZ0000.EXT +0 -0
  235. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P068/00012CA2/ANLZ0000.DAT +0 -0
  236. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P068/00012CA2/ANLZ0000.EXT +0 -0
  237. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P076/00013B6E/ANLZ0000.DAT +0 -0
  238. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/PIONEER/USBANLZ/P076/00013B6E/ANLZ0000.EXT +0 -0
  239. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/datafile.edb +0 -0
  240. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/backup/masterPlaylists3.xml +0 -0
  241. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/database.xml +0 -0
  242. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 5/datafile.edb +0 -0
  243. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/DEVSETTING.DAT +0 -0
  244. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/DJMMYSETTING.DAT +0 -0
  245. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/MYSETTING.DAT +0 -0
  246. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/MYSETTING2.DAT +0 -0
  247. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/masterPlaylists3.xml +0 -0
  248. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/backup/masterPlaylists6.xml +0 -0
  249. {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
  250. {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
  251. {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
  252. {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
  253. {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
  254. {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
  255. {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
  256. {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
  257. {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
  258. {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
  259. {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
  260. {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
  261. {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
  262. {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
  263. {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
  264. {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
  265. {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
  266. {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
  267. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/database.xml +0 -0
  268. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/masterPlaylists6_template.xml +0 -0
  269. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/master_locked.db +0 -0
  270. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/.testdata/rekordbox 6/master_unlocked.db +0 -0
  271. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/CONTRIBUTING.md +0 -0
  272. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/LICENSE +0 -0
  273. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/README.md +0 -0
  274. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/Makefile +0 -0
  275. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/make.bat +0 -0
  276. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_beat.svg +0 -0
  277. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_file.svg +0 -0
  278. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pco2.svg +0 -0
  279. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pcob.svg +0 -0
  280. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pcp2.svg +0 -0
  281. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pcpt.svg +0 -0
  282. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_ppth.svg +0 -0
  283. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pqt2.svg +0 -0
  284. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pqt2_2.svg +0 -0
  285. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pqtz.svg +0 -0
  286. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pssi.svg +0 -0
  287. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pssi_entry.svg +0 -0
  288. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pvbr.svg +0 -0
  289. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwav.svg +0 -0
  290. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv3.svg +0 -0
  291. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv4.svg +0 -0
  292. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv5.svg +0 -0
  293. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv5_entry.svg +0 -0
  294. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv6.svg +0 -0
  295. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwv7.svg +0 -0
  296. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_pwvc.svg +0 -0
  297. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/anlz_tag.svg +0 -0
  298. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/images/x64dbg_rb_key.png +0 -0
  299. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/logos/dark/logo_primary.svg +0 -0
  300. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/logos/light/logo_primary.svg +0 -0
  301. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_static/logos/mid/logo_primary.svg +0 -0
  302. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/apidoc/module.rst_t +0 -0
  303. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/apidoc/package.rst_t +0 -0
  304. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/apidoc/toc.rst_t +0 -0
  305. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/autosummary/class.rst +0 -0
  306. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/_templates/autosummary/module.rst +0 -0
  307. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/api.md +0 -0
  308. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/conf.py +0 -0
  309. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/development/changes.md +0 -0
  310. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/development/contributing.md +0 -0
  311. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/formats/anlz.md +0 -0
  312. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/formats/mysetting.md +0 -0
  313. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/formats/xml.md +0 -0
  314. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/index.md +0 -0
  315. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/installation.md +0 -0
  316. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/key.md +0 -0
  317. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/quickstart.md +0 -0
  318. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/requirements.txt +0 -0
  319. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/configuration.md +0 -0
  320. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/db6.md +0 -0
  321. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/index.md +0 -0
  322. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/docs/source/tutorial/xml.md +0 -0
  323. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/anlz/structs.py +0 -0
  324. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/db6/__init__.py +0 -0
  325. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/logger.py +0 -0
  326. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox/mysettings/structs.py +0 -0
  327. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/dependency_links.txt +0 -0
  328. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/not-zip-safe +0 -0
  329. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/requires.txt +0 -0
  330. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/pyrekordbox.egg-info/top_level.txt +0 -0
  331. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/setup.cfg +0 -0
  332. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/__init__.py +0 -0
  333. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/test_anlz.py +0 -0
  334. {pyrekordbox-0.4.1 → pyrekordbox-0.4.3}/tests/test_config.py +0 -0
  335. {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@v3
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
@@ -13,7 +13,7 @@ repos:
13
13
  - id: check-yaml
14
14
 
15
15
  - repo: https://github.com/astral-sh/ruff-pre-commit
16
- rev: v0.11.4
16
+ rev: v0.11.9
17
17
  hooks:
18
18
  # Run the linter.
19
19
  - id: ruff
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.1...HEAD
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyrekordbox
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: Inofficial Python package for interacting with the library of Pioneers Rekordbox DJ software.
5
5
  Author-email: Dylan Jones <dylanljones94@gmail.com>
6
6
  License: MIT License
@@ -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. To read any of the four files, use
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]
@@ -2,6 +2,7 @@
2
2
  # Author: Dylan Jones
3
3
  # Date: 2022-04-10
4
4
 
5
+ # mypy: disable-error-code="attr-defined"
5
6
  from .anlz import AnlzFile, get_anlz_paths, read_anlz_files, walk_anlz_paths
6
7
  from .config import get_config, show_config, update_config
7
8
  from .db6 import Rekordbox6Database
@@ -9,7 +9,7 @@ import sys
9
9
  import urllib.request
10
10
  from pathlib import Path
11
11
 
12
- from pyrekordbox.config import _cache_file, write_db6_key_cache
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
- print(f"Found key, updating cache file {_cache_file}")
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.")
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.4.1'
21
- __version_tuple__ = version_tuple = (0, 4, 1)
20
+ __version__ = version = '0.4.3'
21
+ __version_tuple__ = version_tuple = (0, 4, 3)
@@ -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]) -> dict:
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] = "") -> dict:
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
- tag = structs.AnlzTag.parse(tag_data)
151
- len_tag = tag.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)