pyrekordbox 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl

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 (69) hide show
  1. docs/Makefile +20 -0
  2. docs/make.bat +35 -0
  3. docs/source/_static/images/anlz_beat.svg +53 -0
  4. docs/source/_static/images/anlz_file.svg +204 -0
  5. docs/source/_static/images/anlz_pco2.svg +138 -0
  6. docs/source/_static/images/anlz_pcob.svg +148 -0
  7. docs/source/_static/images/anlz_pcp2.svg +398 -0
  8. docs/source/_static/images/anlz_pcpt.svg +263 -0
  9. docs/source/_static/images/anlz_ppth.svg +123 -0
  10. docs/source/_static/images/anlz_pqt2.svg +324 -0
  11. docs/source/_static/images/anlz_pqt2_2.svg +253 -0
  12. docs/source/_static/images/anlz_pqtz.svg +140 -0
  13. docs/source/_static/images/anlz_pssi.svg +192 -0
  14. docs/source/_static/images/anlz_pssi_entry.svg +191 -0
  15. docs/source/_static/images/anlz_pvbr.svg +125 -0
  16. docs/source/_static/images/anlz_pwav.svg +130 -0
  17. docs/source/_static/images/anlz_pwv3.svg +139 -0
  18. docs/source/_static/images/anlz_pwv4.svg +139 -0
  19. docs/source/_static/images/anlz_pwv5.svg +139 -0
  20. docs/source/_static/images/anlz_pwv5_entry.svg +100 -0
  21. docs/source/_static/images/anlz_pwv6.svg +130 -0
  22. docs/source/_static/images/anlz_pwv7.svg +139 -0
  23. docs/source/_static/images/anlz_pwvc.svg +125 -0
  24. docs/source/_static/images/anlz_tag.svg +110 -0
  25. docs/source/_static/logos/dark/logo_primary.svg +75 -0
  26. docs/source/_static/logos/light/logo_primary.svg +75 -0
  27. docs/source/_static/logos/mid/logo_primary.svg +75 -0
  28. docs/source/_templates/apidoc/module.rst_t +8 -0
  29. docs/source/_templates/apidoc/package.rst_t +57 -0
  30. docs/source/_templates/apidoc/toc.rst_t +7 -0
  31. docs/source/_templates/autosummary/class.rst +32 -0
  32. docs/source/_templates/autosummary/module.rst +55 -0
  33. docs/source/api.md +18 -0
  34. docs/source/conf.py +178 -0
  35. docs/source/development/changes.md +3 -0
  36. docs/source/development/contributing.md +3 -0
  37. docs/source/formats/anlz.md +634 -0
  38. docs/source/formats/db6.md +1233 -0
  39. docs/source/formats/mysetting.md +392 -0
  40. docs/source/formats/xml.md +376 -0
  41. docs/source/index.md +105 -0
  42. docs/source/installation.md +3 -0
  43. docs/source/quickstart.md +185 -0
  44. docs/source/requirements.txt +7 -0
  45. docs/source/tutorial/anlz.md +7 -0
  46. docs/source/tutorial/configuration.md +66 -0
  47. docs/source/tutorial/db6.md +179 -0
  48. docs/source/tutorial/index.md +20 -0
  49. docs/source/tutorial/mysetting.md +124 -0
  50. docs/source/tutorial/xml.md +140 -0
  51. pyrekordbox/__init__.py +1 -1
  52. pyrekordbox/__main__.py +16 -37
  53. pyrekordbox/_version.py +2 -2
  54. pyrekordbox/anlz/file.py +39 -0
  55. pyrekordbox/anlz/structs.py +3 -5
  56. pyrekordbox/config.py +71 -27
  57. pyrekordbox/db6/database.py +290 -61
  58. pyrekordbox/db6/registry.py +24 -0
  59. pyrekordbox/db6/tables.py +501 -340
  60. pyrekordbox/mysettings/file.py +0 -25
  61. pyrekordbox/utils.py +1 -1
  62. {pyrekordbox-0.2.0.dist-info → pyrekordbox-0.2.2.dist-info}/METADATA +42 -20
  63. pyrekordbox-0.2.2.dist-info/RECORD +80 -0
  64. {pyrekordbox-0.2.0.dist-info → pyrekordbox-0.2.2.dist-info}/top_level.txt +1 -0
  65. tests/test_config.py +175 -0
  66. tests/test_db6.py +95 -0
  67. pyrekordbox-0.2.0.dist-info/RECORD +0 -29
  68. {pyrekordbox-0.2.0.dist-info → pyrekordbox-0.2.2.dist-info}/LICENSE +0 -0
  69. {pyrekordbox-0.2.0.dist-info → pyrekordbox-0.2.2.dist-info}/WHEEL +0 -0
@@ -49,31 +49,6 @@ CRC16_XMODEM_TABLE = [
49
49
  RE_INVALID_KEY = re.compile("[_u][0-9]?", flags=re.IGNORECASE)
50
50
 
51
51
 
52
- def crc16xmodem(data, crc=0):
53
- """Calculates the CRC-CCITT (XModem) variant of the CRC16 checksum.
54
-
55
- Parameters
56
- ----------
57
- data : bytes
58
- The data used for calculating the CRC checksum.
59
- crc : int, optional
60
- The initial value.
61
-
62
- Returns
63
- -------
64
- crc : int
65
- The calculated CRC16-XModem checksum.
66
-
67
-
68
- References
69
- ----------
70
- https://reveng.sourceforge.io/crc-catalogue/all.htm#crc.cat.crc-16-xmodem
71
- """
72
- for byte in data:
73
- crc = ((crc << 8) & 0xFF00) ^ CRC16_XMODEM_TABLE[((crc >> 8) & 0xFF) ^ byte]
74
- return crc & 0xFFFF
75
-
76
-
77
52
  def compute_checksum(data, struct):
78
53
  """Computes the CRC16 XModem checksum for My-Setting files.
79
54
 
pyrekordbox/utils.py CHANGED
@@ -58,8 +58,8 @@ def get_process_id(name: str, raise_exec=False) -> int:
58
58
  23456
59
59
  """
60
60
  for proc in psutil.process_iter():
61
- proc_name = os.path.splitext(proc.name())[0] # needed on Windows (.exe)
62
61
  try:
62
+ proc_name = os.path.splitext(proc.name())[0] # needed on Windows (.exe)
63
63
  if proc_name == name:
64
64
  return proc.pid
65
65
  except (psutil.AccessDenied, psutil.NoSuchProcess):
@@ -1,14 +1,34 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyrekordbox
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Inofficial Python package for interacting with the library of Pioneers Rekordbox DJ software.
5
- Home-page: https://github.com/dylanljones/pyrekordbox
6
- Author: Dylan Jones
7
- Author-email: dylanljones94@gmail.com
8
- License: MIT
5
+ Author-email: Dylan Jones <dylanljones94@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2022-2023, Dylan Jones
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
9
28
  Project-URL: Source, https://github.com/dylanljones/pyrekordbox
10
29
  Project-URL: Documentation, https://pyrekordbox.readthedocs.io/en/stable/
11
30
  Project-URL: Tracker, https://github.com/dylanljones/pyrekordbox/issues
31
+ Platform: any
12
32
  Classifier: Development Status :: 3 - Alpha
13
33
  Classifier: Intended Audience :: Developers
14
34
  Classifier: Intended Audience :: Information Technology
@@ -30,19 +50,14 @@ License-File: LICENSE
30
50
  Requires-Dist: bidict >=0.21.0
31
51
  Requires-Dist: blowfish >=0.6.0
32
52
  Requires-Dist: construct >=2.10.0
33
- Requires-Dist: hypothesis >=6.0.0
34
53
  Requires-Dist: numpy >=1.19.0
35
54
  Requires-Dist: packaging
36
- Requires-Dist: pytest >=6.2.0
37
55
  Requires-Dist: psutil >=5.9.0
38
- Requires-Dist: setuptools >=60.0.0
39
- Requires-Dist: setuptools-scm[toml] >=4
40
- Requires-Dist: sqlalchemy ~=1.4.0
41
- Provides-Extra: build
42
- Requires-Dist: wheel >=0.37.0 ; extra == 'build'
56
+ Requires-Dist: sqlalchemy >=2.0.0
43
57
  Provides-Extra: test
58
+ Requires-Dist: hypothesis >=6.0.0 ; extra == 'test'
59
+ Requires-Dist: pytest >=6.2.0 ; extra == 'test'
44
60
  Requires-Dist: pytest-cov ; extra == 'test'
45
- Requires-Dist: wheel >=0.37.0 ; extra == 'test'
46
61
 
47
62
 
48
63
  <p align="center">
@@ -68,7 +83,7 @@ Pioneers Rekordbox DJ Software. It currently supports
68
83
  - Analysis files (ANLZ)
69
84
  - My-Setting files
70
85
 
71
- Tested Rekordbox versions: ``5.8.6 | 6.5.3``
86
+ Tested Rekordbox versions: ``5.8.6 | 6.5.3 | 6.7.7``
72
87
 
73
88
 
74
89
  |⚠️| This project is still under development and might contain bugs or have breaking API changes in the future. |
@@ -92,12 +107,12 @@ where `VERSION` is a release, tag or branch name.
92
107
 
93
108
  Unlocking the new Rekordbox 6 `master.db` database file requires [SQLCipher][sqlcipher].
94
109
  Pyrekordbox makes no attempt to download/install SQLCipher, as it is a
95
- pure Python package - whereas the SQLCipher/pysqlcipher3 installation is
110
+ pure Python package - whereas the SQLCipher/sqlcipher3 installation is
96
111
  platform-dependent and can not be installed via ``pip``.
97
112
 
98
113
  #### Windows
99
114
 
100
- SQLCipher can be used by building the libary against an amalgamation with [pysqlcipher3].
115
+ SQLCipher can be used by building the libary against an amalgamation with [sqlcipher3].
101
116
  For a detailed instruction, see [INSTALLATION].
102
117
 
103
118
  #### MacOS
@@ -108,12 +123,13 @@ For MacOS follow these steps:
108
123
  2) Install SQLCipher with `brew install SQLCipher`.
109
124
  3) With the python environment you are using to run pyrekordbox active execute the following:
110
125
  ```shell
111
- git clone https://github.com/rigglemania/pysqlcipher3
112
- cd pysqlcipher3
126
+ git clone https://github.com/coleifer/sqlcipher3
127
+ cd sqlcipher3
113
128
  SQLCIPHER_PATH=$(brew info sqlcipher | awk 'NR==4 {print $1; exit}'); C_INCLUDE_PATH="$SQLCIPHER_PATH"/include LIBRARY_PATH="$SQLCIPHER_PATH"/lib python setup.py build
114
129
  SQLCIPHER_PATH=$(brew info sqlcipher | awk 'NR==4 {print $1; exit}'); C_INCLUDE_PATH="$SQLCIPHER_PATH"/include LIBRARY_PATH="$SQLCIPHER_PATH"/lib python setup.py install
115
130
  ```
116
131
  Make sure the `C_INCLUDE` and `LIBRARY_PATH` point to the installed SQLCipher path. It may differ on your machine.
132
+ If you are having issues installing [sqlcipher3] on M1 Macs please refer to [INSTALLATION].
117
133
 
118
134
 
119
135
  ## 🚀 Quick-Start
@@ -184,7 +200,7 @@ So far only a few tables support adding or deleting entries:
184
200
  - ``DjmdSongPlaylist``: Songs in a playlist
185
201
 
186
202
  Starting from Rekordbox version ``6.6.5`` Pioneer obfuscated the ``app.asar`` file
187
- contents, breaking the key extraction (see [this issue](https://github.com/dylanljones/pyrekordbox/issues/64) for more details).
203
+ contents, breaking the key extraction (see [this discussion](https://github.com/dylanljones/pyrekordbox/discussions/97) for more details).
188
204
  If you are using a later version of Rekorbox and have no cached key from a previous
189
205
  version, the database can not be unlocked automatically.
190
206
  The command line interface of ``pyrekordbox`` provides a command for downloading
@@ -283,6 +299,8 @@ sync = mysett.get("sync")
283
299
  quant = mysett.get("quantize")
284
300
  ````
285
301
 
302
+ The `DEVSETTING.DAT` file is still not supported
303
+
286
304
 
287
305
  ## 💡 File formats
288
306
 
@@ -302,6 +320,9 @@ If you encounter an issue or want to contribute to pyrekordbox, please feel free
302
320
  `pyrekordbox` and the commit-message style can be found in
303
321
  [CONTRIBUTING].
304
322
 
323
+ For general questions or discussions about Rekordbox, please use [GitHub Discussions][discussions]
324
+ instead of opening an issue.
325
+
305
326
  Pyrekordbox is tested on Windows and MacOS, however some features can't be tested in
306
327
  the CI setup since it requires a working Rekordbox installation.
307
328
 
@@ -353,13 +374,14 @@ the CI setup since it requires a working Rekordbox installation.
353
374
  [mysettings-doc]: https://pyrekordbox.readthedocs.io/en/stable/formats/mysetting.html
354
375
 
355
376
  [new-issue]: https://github.com/dylanljones/pyrekordbox/issues/new/choose
377
+ [discussions]: https://github.com/dylanljones/pyrekordbox/discussions
356
378
  [CONTRIBUTING]: https://github.com/dylanljones/pyrekordbox/blob/master/CONTRIBUTING.md
357
379
  [CHANGELOG]: https://github.com/dylanljones/pyrekordbox/blob/master/CHANGELOG.md
358
380
  [INSTALLATION]: https://github.com/dylanljones/pyrekordbox/blob/master/INSTALLATION.md
359
381
 
360
382
  [repo]: https://github.com/dylanljones/pyrekordbox
361
383
  [sqlcipher]: https://www.zetetic.net/sqlcipher/open-source/
362
- [pysqlcipher3]: https://github.com/rigglemania/pysqlcipher3
384
+ [sqlcipher3]: https://github.com/coleifer/sqlcipher3
363
385
  [rekordcrate]: https://github.com/Holzhaus/rekordcrate
364
386
  [crate-digger]: https://github.com/Deep-Symmetry/crate-digger
365
387
  [supbox]: https://github.com/gabek/supbox
@@ -0,0 +1,80 @@
1
+ docs/Makefile,sha256=4zv3TVkTACm6JBaKgTES3ZI9cETXgM6ULbZkXZP1as8,638
2
+ docs/make.bat,sha256=s8EuuVXNRnn4xmWLWTpk3Z01aqJSJT8ymrmK6ux0zbc,769
3
+ docs/source/api.md,sha256=IKKMeQ2wFSS_ippOWJ63ELtMjfkNe27KjWcFFEdUXnE,276
4
+ docs/source/conf.py,sha256=lPfAJtd0VY7uEDmHrEfHvQzNJg6WN_1seM9pCFc2e6E,6244
5
+ docs/source/index.md,sha256=_73xtwAH2OF0btxHt2Kre4k1cP3N-OhsyDL-Oc7NKCI,2823
6
+ docs/source/installation.md,sha256=RoCHv74LONL5QyBBVKXPOOqRmAN2GUzcvInwnlztM6M,40
7
+ docs/source/quickstart.md,sha256=-v7FE_08KDSUAdbmvrY-7QImKLpR8vA3W6mTFE-uWPs,6299
8
+ docs/source/requirements.txt,sha256=7YYc-tO0BQcBVUa4GvM1r1G5Ma9gkwGZpNbAKlJL97s,117
9
+ docs/source/_static/images/anlz_beat.svg,sha256=cVooi17HFw3mOT39cFNB05tr-cZwbK_Hjmho6eBJNX8,2924
10
+ docs/source/_static/images/anlz_file.svg,sha256=E74hjyTFJRy6tCxyTPfsYoM0GmOKoY1To_eHatpPEjs,12320
11
+ docs/source/_static/images/anlz_pco2.svg,sha256=LAv_EZf72FbslKdHmuBy5ROWy8xKKkkXqp7mSk3WG20,8155
12
+ docs/source/_static/images/anlz_pcob.svg,sha256=w4NRLCj0EMMnQ2i6tnlE-nFxETSiTs8PQF5nxMI3bgo,8682
13
+ docs/source/_static/images/anlz_pcp2.svg,sha256=JDncv7fo6ylorWyaH7kZ6roYB7zryFbJE_HY4IfWG8E,24904
14
+ docs/source/_static/images/anlz_pcpt.svg,sha256=8PcHBFAHXrDnTyC_7rO0TM-5cGy8BfjIXWxDi0zEK8Y,16473
15
+ docs/source/_static/images/anlz_ppth.svg,sha256=-rPlwvBrrsYaL87GNI-WJJBFCYkcZwkWoGwH5NT8bLk,7124
16
+ docs/source/_static/images/anlz_pqt2.svg,sha256=sRvbV-DjoTIWtxwChaw6kBqKFXNqBCF4V9hru9ZtdiE,18386
17
+ docs/source/_static/images/anlz_pqt2_2.svg,sha256=8g3XCJDz8xbH_KK7CvMpmIZjaGrWBKQVlA4k4M3PF50,13774
18
+ docs/source/_static/images/anlz_pqtz.svg,sha256=OPlW76hPkbhOByYgmVQfucTpb5irZXYcASZokfpK3A0,8141
19
+ docs/source/_static/images/anlz_pssi.svg,sha256=zM8fsNshSMd0wDvO_qM7RzsAKVIEN8Y41jY76hBJjyQ,11684
20
+ docs/source/_static/images/anlz_pssi_entry.svg,sha256=YkUg7fXtUst0OBI6vIlhHCK-nzhmR-22UGKFQ0pHxxA,12095
21
+ docs/source/_static/images/anlz_pvbr.svg,sha256=7mA6S__F4AoX-GamftlevellDiTlcIWRWi77A7HZEDg,7284
22
+ docs/source/_static/images/anlz_pwav.svg,sha256=psm3g7ILLVNgPNmPG2Hy7k9-q7qmnMnyQ3_-XYVAW2g,7566
23
+ docs/source/_static/images/anlz_pwv3.svg,sha256=FwZJIiHj5hj-FB-cioNlxrGBeIEuZy2BOLEzSWC57IE,8389
24
+ docs/source/_static/images/anlz_pwv4.svg,sha256=k5GQu2N965zPSG0FQWuml96UMfqBvs8Vy-Emklvn2dI,8173
25
+ docs/source/_static/images/anlz_pwv5.svg,sha256=Ph1TSlji2BgWK3rVI7MvnpGM68wef1s-Hs6OlmC0oQQ,8173
26
+ docs/source/_static/images/anlz_pwv5_entry.svg,sha256=TyNh_6gIsQKuDvS0RO5tmsptzmxiQ-LL1L3DQdIFi4I,5648
27
+ docs/source/_static/images/anlz_pwv6.svg,sha256=J2KvE_bI-NTFSpFp7QsKSsgbWGCyuUAuW_dOgdnv2DY,7577
28
+ docs/source/_static/images/anlz_pwv7.svg,sha256=n5NsTErvfsCw-otWdVXn12lM0tHyh-zQDZsZtQOJf0U,8173
29
+ docs/source/_static/images/anlz_pwvc.svg,sha256=wO_tsxRDVnAbptbSZYK1z7YOH-0vNUqXDB9Udj4ungA,7128
30
+ docs/source/_static/images/anlz_tag.svg,sha256=owPTtrTRDYCkaSg32_UJ-MTZp3K6WlkRQdJHTzdtxqs,6188
31
+ docs/source/_static/logos/dark/logo_primary.svg,sha256=pH4Q28u9JaCA4dVrKB-NDy00PNw2EhDwz7fIYUzezvk,3079
32
+ docs/source/_static/logos/light/logo_primary.svg,sha256=MUbYjowOcWdtoHVnK7pyV9xcTRdm7gS4whw94pVMGSI,3080
33
+ docs/source/_static/logos/mid/logo_primary.svg,sha256=utCWWbXXW5auRRposMMaMO9t_AflsN13rZGo3_Pg2WE,3078
34
+ docs/source/_templates/apidoc/module.rst_t,sha256=keQqb9G8LA-JS5tuytgzfsxRXsADEvuOz3mJjY9qYHU,185
35
+ docs/source/_templates/apidoc/package.rst_t,sha256=Ra-lunZcMyDtrb6vgrfAnBcBW4eFMTEIyg12fSe9h4o,1173
36
+ docs/source/_templates/apidoc/toc.rst_t,sha256=6EfpNwcRXLa8Ae3NcovuSmV5PSBy5gP0t6XfphUYb7M,127
37
+ docs/source/_templates/autosummary/class.rst,sha256=5yRMWkUNDXGvQE1gGm6yisL1bX4BDOsaBPciNUs_6vA,579
38
+ docs/source/_templates/autosummary/module.rst,sha256=xSCcWeBqQdMgpese2OwFlvzSOMsPZKTBCLCwgD3OG4k,789
39
+ docs/source/development/changes.md,sha256=ys1_zvYKQWEak_mBXBUMLpO3CWriHpjSAg1-17mTk04,40
40
+ docs/source/development/contributing.md,sha256=7bERN03kHo2Wf0ZrgHYP4MfBSdFGmE_Kk0CxK0uay2I,43
41
+ docs/source/formats/anlz.md,sha256=P7FrPqbu3i8SlRKVV9IU9cOQajKJHOjLlAWHheDGN7c,21455
42
+ docs/source/formats/db6.md,sha256=fuB1_PaalHV4zRkhXh5_mn1ZgHfPnSu_OzUOYbVls6w,30121
43
+ docs/source/formats/mysetting.md,sha256=OIYIn_B2HJcJtJM0wNjjzPy3xPkyz4raxg_-Y6E3D1k,9746
44
+ docs/source/formats/xml.md,sha256=uL7eWWQfQXsyf55Vydt1iLq7Jzio3kIGbSfjpg5-CRY,8491
45
+ docs/source/tutorial/anlz.md,sha256=JtcQIy44qaSP_GL0aL9VYQYOX8aVju7uFxgN3FPNy9o,145
46
+ docs/source/tutorial/configuration.md,sha256=mqmeFM3I7pDA_ajPQWqVyvc9Y0PWGYXLr3yyojTGsL8,2127
47
+ docs/source/tutorial/db6.md,sha256=wzfHAxSQ5rmYSDs6S0WheDwjkdFYsY3JxM0jGmXJcVU,6730
48
+ docs/source/tutorial/index.md,sha256=zjx5uXESYzHIyeqtL4XjhZUDPOpNiutZ3gkUOeG8R9w,318
49
+ docs/source/tutorial/mysetting.md,sha256=su-WMvEd3DrFF32RDfQBm3TlAUgK5PRPT1n_77BYnvY,3659
50
+ docs/source/tutorial/xml.md,sha256=x_rFvsVzZtUV0upEkPWkgrmr3B-FYjZKWvBuJBLFAu0,6414
51
+ pyrekordbox/__init__.py,sha256=jNxA9t2zA1P6zuOaQ9T_Nc5QW-G_KpUWymLNKOkPf7s,645
52
+ pyrekordbox/__main__.py,sha256=dm9QQMM5xPXzvFsF1ghwBor8ThUvZuC73As8c6kMZrA,6040
53
+ pyrekordbox/_version.py,sha256=RrHB9KG1O3GPm--rbTedqmZbdDrbgeRLXBmT4OBUqqI,411
54
+ pyrekordbox/config.py,sha256=eifT5Wejkk9zbQQ6190h-rF5WiF9foc55SNCHaYJKZk,21848
55
+ pyrekordbox/logger.py,sha256=qCY_3L_3WIMAvNmVKvh7oshGlWrd0T5aIW1bNCIu3Lo,521
56
+ pyrekordbox/utils.py,sha256=sT1xt-rM94Dir-S0OSSqKbquf9kdFbzZvBu3-7q0QDM,4361
57
+ pyrekordbox/xml.py,sha256=0qsKc8SQa54URwWGt6oHTOHBiAQU2S8MbSxDbzKUB7A,38369
58
+ pyrekordbox/anlz/__init__.py,sha256=OSpyl3pmmnt3mG905J9qvNnYchsgrIfathw0QXoOhjo,3156
59
+ pyrekordbox/anlz/file.py,sha256=i6Cnz-XpT47ClGhC3ZCCrgKhlk685NTM0hWyOuATNaE,6949
60
+ pyrekordbox/anlz/structs.py,sha256=Lt4fkb3SAE8w146eWeWGnpgRoP6jhLMWrSMoMwPjG04,7925
61
+ pyrekordbox/anlz/tags.py,sha256=uqneBP9CstYy7a4IpeEC9A5tfI59DQm0ik7yFXk_dNo,14094
62
+ pyrekordbox/db6/__init__.py,sha256=5XbfEIZuribNXIHMn9M4qw91cKHouH82PPJbmODhdgo,849
63
+ pyrekordbox/db6/aux_files.py,sha256=t0SfMCXBHjlCSfgRfpw1RTj0cmV0QY07xSLepjQqMnY,7591
64
+ pyrekordbox/db6/database.py,sha256=FlLeJgTp3-kt63_q5uod9Hzb5u83Z34Vhb9qI_qnYVM,74218
65
+ pyrekordbox/db6/registry.py,sha256=9GwMDKMqtm3-4nZ7mdzbL6XezPcVJUVqjHXGHKG_Jn4,9556
66
+ pyrekordbox/db6/tables.py,sha256=5ijJyO0OERbj1Usc__2QLRc7lPZ6FYluOXbajaEqzqk,65949
67
+ pyrekordbox/mysettings/__init__.py,sha256=rMS6Kknf1-X3PXF_TUxm8xui0H1Ap3R7G_9mqlnQUAM,705
68
+ pyrekordbox/mysettings/file.py,sha256=dQEsdBivpverXCssyVNUeQyUXIooNrOGIIiPLwi_6T4,12669
69
+ pyrekordbox/mysettings/structs.py,sha256=5Y1F3qTmsP1fRB39_BEHpQVxKx2DO9BytEuJUG_RNcY,8472
70
+ tests/__init__.py,sha256=s321RtRiHJsLt0YFq0NRncW7u66uwYHQE-6IjPcg10o,67
71
+ tests/test_anlz.py,sha256=hZAW5GFEJpU8UmmHYLuU5OZlApGrWZyPAR79KtaR0cw,5782
72
+ tests/test_config.py,sha256=wYp4wHRhIk2grhGXhk4z9umrhOWhVvTOm2mHydzLEs8,6157
73
+ tests/test_db6.py,sha256=6GUH_B1UAYfnJtjTK20cdCjP6hz_kDRR4KklvsnuAXg,37488
74
+ tests/test_mysetting.py,sha256=te6B_BErGc6ThgBpAl45n0Nd0hWJcm-X9WTw14bR6MA,5781
75
+ tests/test_xml.py,sha256=CbdzWgVjLwmxdaUqLo58QN4iRRaUdiJe_ni8y37BVfQ,16852
76
+ pyrekordbox-0.2.2.dist-info/LICENSE,sha256=Au8sngdQ79q5JsZXZJVU13j46VDxFbPwC4x6sSz8Jes,1074
77
+ pyrekordbox-0.2.2.dist-info/METADATA,sha256=jihtF6wZM3UKWuzrGLAxL-oOv4HjGyp-mwMbxdXmSB8,16672
78
+ pyrekordbox-0.2.2.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
79
+ pyrekordbox-0.2.2.dist-info/top_level.txt,sha256=Cv8QDfcJ7y8fYUm0Q8D5GoiGxaqb7qt8Z5ntVbj1cLk,23
80
+ pyrekordbox-0.2.2.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
+ docs
1
2
  pyrekordbox
2
3
  tests
tests/test_config.py ADDED
@@ -0,0 +1,175 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Author: Dylan Jones
3
+ # Date: 2023-10-02
4
+
5
+ import pytest
6
+ import json
7
+ from pathlib import Path
8
+ from pyrekordbox.config import update_config, get_config
9
+
10
+ RB_SETTING = """<?xml version="1.0" encoding="UTF-8"?>
11
+ <PROPERTIES><VALUE name="masterDbDirectory" val="{db_dir}"/></PROPERTIES>
12
+ """
13
+
14
+ RB_OPTIONS = {"options": [["db-path", ""]]}
15
+
16
+
17
+ def mock_rekordbox_settings_file(pioneer_app_dir, rb_app_dir):
18
+ db_dir = pioneer_app_dir / "rekordbox"
19
+ text = RB_SETTING.format(db_dir=db_dir)
20
+ file = rb_app_dir / "rekordbox3.settings"
21
+ file.write_text(text)
22
+
23
+
24
+ def mock_rekordbox_options_file(agent_storage_dir, db_path):
25
+ file = agent_storage_dir / "options.json"
26
+ options = RB_OPTIONS.copy()
27
+ options["options"][0][1] = str(db_path)
28
+ with open(file, "w") as fp:
29
+ json.dump(options, fp)
30
+
31
+
32
+ @pytest.fixture(scope="session")
33
+ def pioneer_app_dir(tmp_path_factory):
34
+ root = tmp_path_factory.mktemp("Pioneer")
35
+ rb_dir = root / "rekordbox"
36
+ rb6_dir = root / "rekordbox6"
37
+ agent_storage_dir = root / "rekordboxAgent" / "storage"
38
+ rb_dir.mkdir(parents=True)
39
+ rb6_dir.mkdir(parents=True)
40
+ agent_storage_dir.mkdir(parents=True)
41
+
42
+ # Mock `rekordbox3.settings` files
43
+ mock_rekordbox_settings_file(root, rb_dir)
44
+ mock_rekordbox_settings_file(root, rb6_dir)
45
+
46
+ # Mock database files
47
+ rb5_db = rb_dir / "datafile.edb"
48
+ rb6_db = rb_dir / "master.db"
49
+ rb5_db.touch()
50
+ rb6_db.touch()
51
+
52
+ # Mock `options.json` file (RBv6)
53
+ mock_rekordbox_options_file(agent_storage_dir, rb6_db)
54
+
55
+ return root
56
+
57
+
58
+ @pytest.fixture(scope="session")
59
+ def pioneer_install_dir(tmp_path_factory):
60
+ root = tmp_path_factory.mktemp("Pioneer")
61
+ rb5_dir = root / "rekordbox 5.1.1"
62
+ rb6_dir = root / "rekordbox 6.1.1"
63
+ rb5_dir_alt = root / "rekordbox 5.1.2"
64
+ rb6_dir_alt = root / "rekordbox 6.1.2"
65
+
66
+ rb5_dir.mkdir(parents=True)
67
+ rb6_dir.mkdir(parents=True)
68
+ rb5_dir_alt.mkdir(parents=True)
69
+ rb6_dir_alt.mkdir(parents=True)
70
+ return root
71
+
72
+
73
+ def test_pioneer_config(pioneer_install_dir, pioneer_app_dir):
74
+ update_config(pioneer_install_dir, pioneer_app_dir)
75
+ install_dir = get_config("pioneer", "install_dir")
76
+ app_dir = get_config("pioneer", "app_dir")
77
+
78
+ assert isinstance(install_dir, Path)
79
+ assert isinstance(app_dir, Path)
80
+ assert install_dir == pioneer_install_dir
81
+ assert app_dir == pioneer_app_dir
82
+
83
+
84
+ def test_rb5_config(pioneer_install_dir, pioneer_app_dir):
85
+ update_config(pioneer_install_dir, pioneer_app_dir)
86
+ expected_version = "5.1.2"
87
+
88
+ app_dir = get_config("rekordbox5", "app_dir")
89
+ install_dir = get_config("rekordbox5", "install_dir")
90
+ db_dir = get_config("rekordbox5", "db_dir")
91
+ db_path = get_config("rekordbox5", "db_path")
92
+ version = get_config("rekordbox5", "version")
93
+
94
+ assert isinstance(install_dir, Path)
95
+ assert isinstance(app_dir, Path)
96
+ assert isinstance(db_dir, Path)
97
+ assert isinstance(db_path, Path)
98
+ assert install_dir == (pioneer_install_dir / f"rekordbox {expected_version}")
99
+ assert app_dir == (pioneer_app_dir / "rekordbox")
100
+ assert db_dir == (pioneer_app_dir / "rekordbox")
101
+ assert db_path == (pioneer_app_dir / "rekordbox" / "datafile.edb")
102
+ assert version == expected_version
103
+
104
+
105
+ def test_rb6_config(pioneer_install_dir, pioneer_app_dir):
106
+ update_config(pioneer_install_dir, pioneer_app_dir)
107
+ expected_version = "6.1.2"
108
+
109
+ app_dir = get_config("rekordbox6", "app_dir")
110
+ install_dir = get_config("rekordbox6", "install_dir")
111
+ db_dir = get_config("rekordbox6", "db_dir")
112
+ db_path = get_config("rekordbox6", "db_path")
113
+ version = get_config("rekordbox6", "version")
114
+
115
+ assert isinstance(install_dir, Path)
116
+ assert isinstance(app_dir, Path)
117
+ assert isinstance(db_dir, Path)
118
+ assert isinstance(db_path, Path)
119
+ assert install_dir == (pioneer_install_dir / f"rekordbox {expected_version}")
120
+ assert app_dir == (pioneer_app_dir / "rekordbox6")
121
+ assert db_dir == (pioneer_app_dir / "rekordbox")
122
+ assert db_path == (pioneer_app_dir / "rekordbox" / "master.db")
123
+ assert version == expected_version
124
+
125
+
126
+ def test_rb5_config_alt(pioneer_install_dir, pioneer_app_dir):
127
+ # test default: latest version
128
+ update_config(pioneer_install_dir, pioneer_app_dir)
129
+ expected_version = "5.1.2"
130
+
131
+ app_dir = get_config("rekordbox5", "app_dir")
132
+ install_dir = get_config("rekordbox5", "install_dir")
133
+ version = get_config("rekordbox5", "version")
134
+ assert install_dir == (pioneer_install_dir / f"rekordbox {expected_version}")
135
+ assert app_dir == (pioneer_app_dir / "rekordbox")
136
+ assert version == expected_version
137
+
138
+ # test alternative version
139
+ update_config(
140
+ pioneer_install_dir, pioneer_app_dir, rb5_install_dirname="rekordbox 5.1.1"
141
+ )
142
+ expected_version = "5.1.1"
143
+
144
+ app_dir = get_config("rekordbox5", "app_dir")
145
+ install_dir = get_config("rekordbox5", "install_dir")
146
+ version = get_config("rekordbox5", "version")
147
+ assert install_dir == (pioneer_install_dir / f"rekordbox {expected_version}")
148
+ assert app_dir == (pioneer_app_dir / "rekordbox")
149
+ assert version == expected_version
150
+
151
+
152
+ def test_rb6_config_alt(pioneer_install_dir, pioneer_app_dir):
153
+ # test default: latest version
154
+ update_config(pioneer_install_dir, pioneer_app_dir)
155
+ expected_version = "6.1.2"
156
+
157
+ app_dir = get_config("rekordbox6", "app_dir")
158
+ install_dir = get_config("rekordbox6", "install_dir")
159
+ version = get_config("rekordbox6", "version")
160
+ assert install_dir == (pioneer_install_dir / f"rekordbox {expected_version}")
161
+ assert app_dir == (pioneer_app_dir / "rekordbox6")
162
+ assert version == expected_version
163
+
164
+ # test alternative version
165
+ update_config(
166
+ pioneer_install_dir, pioneer_app_dir, rb6_install_dirname="rekordbox 6.1.1"
167
+ )
168
+ expected_version = "6.1.1"
169
+
170
+ app_dir = get_config("rekordbox6", "app_dir")
171
+ install_dir = get_config("rekordbox6", "install_dir")
172
+ version = get_config("rekordbox6", "version")
173
+ assert install_dir == (pioneer_install_dir / f"rekordbox {expected_version}")
174
+ assert app_dir == (pioneer_app_dir / "rekordbox6")
175
+ assert version == expected_version
tests/test_db6.py CHANGED
@@ -187,6 +187,23 @@ def test_songs_getters(parent_name, key, cls):
187
187
  assert isinstance(query.first(), cls)
188
188
 
189
189
 
190
+ def test_mixer_gain_setters(db):
191
+ for item in db.get_mixer_param():
192
+ # Check Gain setter
193
+ low, high, value = int(item.GainLow), int(item.GainHigh), item.Gain
194
+ item.Gain = value
195
+ db.flush()
196
+ assert item.GainLow == low
197
+ assert item.GainHigh == high
198
+
199
+ # Check Peak setter
200
+ low, high, value = int(item.PeakLow), int(item.PeakHigh), item.Peak
201
+ item.Peak = value
202
+ db.flush()
203
+ assert item.PeakLow == low
204
+ assert item.PeakHigh == high
205
+
206
+
190
207
  @mark.parametrize(
191
208
  "search,ids",
192
209
  [
@@ -981,6 +998,84 @@ def test_rename_playlist(db):
981
998
  assert _check_playlist_xml(db)
982
999
 
983
1000
 
1001
+ def test_add_album(db):
1002
+ old_usn = db.get_local_usn()
1003
+ name = "test"
1004
+ db.add_album(name)
1005
+ db.commit()
1006
+
1007
+ # Check that album was created and USN is incremented
1008
+ instance = db.get_album(Name=name).one()
1009
+ assert instance.Name == name
1010
+ assert instance.rb_local_usn == old_usn + 1
1011
+ assert db.get_local_usn() == old_usn + 1
1012
+
1013
+ # Fail if album with same name is added
1014
+ with pytest.raises(ValueError):
1015
+ db.add_album(name)
1016
+
1017
+ # Add album with album artist by artist
1018
+ artist = db.get_artist().first()
1019
+ album = db.add_album("album 2", artist=artist)
1020
+ assert album.AlbumArtistID == artist.ID
1021
+
1022
+ # Add album with album artist by ID
1023
+ artist = db.get_artist().first()
1024
+ album = db.add_album("album 3", artist=artist.ID)
1025
+ assert album.AlbumArtistID == artist.ID
1026
+
1027
+
1028
+ def test_add_artist(db):
1029
+ old_usn = db.get_local_usn()
1030
+ name = "test"
1031
+ db.add_artist(name)
1032
+ db.commit()
1033
+
1034
+ # Check that album was created and USN is incremented
1035
+ instance = db.get_artist(Name=name).one()
1036
+ assert instance.Name == name
1037
+ assert instance.rb_local_usn == old_usn + 1
1038
+ assert db.get_local_usn() == old_usn + 1
1039
+
1040
+ # Fail if album with same name is added
1041
+ with pytest.raises(ValueError):
1042
+ db.add_artist(name)
1043
+
1044
+
1045
+ def test_add_genre(db):
1046
+ old_usn = db.get_local_usn()
1047
+ name = "test"
1048
+ db.add_genre(name)
1049
+ db.commit()
1050
+
1051
+ # Check that album was created and USN is incremented
1052
+ instance = db.get_genre(Name=name).one()
1053
+ assert instance.Name == name
1054
+ assert instance.rb_local_usn == old_usn + 1
1055
+ assert db.get_local_usn() == old_usn + 1
1056
+
1057
+ # Fail if album with same name is added
1058
+ with pytest.raises(ValueError):
1059
+ db.add_genre(name)
1060
+
1061
+
1062
+ def test_add_label(db):
1063
+ old_usn = db.get_local_usn()
1064
+ name = "test"
1065
+ db.add_label(name)
1066
+ db.commit()
1067
+
1068
+ # Check that album was created and USN is incremented
1069
+ instance = db.get_label(Name=name).one()
1070
+ assert instance.Name == name
1071
+ assert instance.rb_local_usn == old_usn + 1
1072
+ assert db.get_local_usn() == old_usn + 1
1073
+
1074
+ # Fail if album with same name is added
1075
+ with pytest.raises(ValueError):
1076
+ db.add_label(name)
1077
+
1078
+
984
1079
  def test_get_anlz_paths():
985
1080
  content = DB.get_content().first()
986
1081
 
@@ -1,29 +0,0 @@
1
- pyrekordbox/__init__.py,sha256=a9rUhmohVNWukYspPYvzHIiYS65mq1PNvbvB3rVukF4,630
2
- pyrekordbox/__main__.py,sha256=SgfuYFZbimoRlEVWfcbidkpkJHg21a--2y9QB5YOans,6594
3
- pyrekordbox/_version.py,sha256=H-qsvrxCpdhaQzyddR-yajEqI71hPxLa4KxzpP3uS1g,411
4
- pyrekordbox/config.py,sha256=YwFYOMQMGj7iizQUbEXXoVi48mGIjzTCiyyOsQuuMbI,19636
5
- pyrekordbox/logger.py,sha256=qCY_3L_3WIMAvNmVKvh7oshGlWrd0T5aIW1bNCIu3Lo,521
6
- pyrekordbox/utils.py,sha256=-fXDNrHq33GU_4VykSlIMRz1s9d15pvdgsWyO6P216w,4357
7
- pyrekordbox/xml.py,sha256=0qsKc8SQa54URwWGt6oHTOHBiAQU2S8MbSxDbzKUB7A,38369
8
- pyrekordbox/anlz/__init__.py,sha256=OSpyl3pmmnt3mG905J9qvNnYchsgrIfathw0QXoOhjo,3156
9
- pyrekordbox/anlz/file.py,sha256=ns63xok1FFk-tVGkX_sGeTtLkoE63mMpGpBbJqjBqAE,5188
10
- pyrekordbox/anlz/structs.py,sha256=eKQusN4Zjj_K4UUCgEJXIAsJJsCA8-xRGMcsq6rd0iw,7987
11
- pyrekordbox/anlz/tags.py,sha256=uqneBP9CstYy7a4IpeEC9A5tfI59DQm0ik7yFXk_dNo,14094
12
- pyrekordbox/db6/__init__.py,sha256=5XbfEIZuribNXIHMn9M4qw91cKHouH82PPJbmODhdgo,849
13
- pyrekordbox/db6/aux_files.py,sha256=t0SfMCXBHjlCSfgRfpw1RTj0cmV0QY07xSLepjQqMnY,7591
14
- pyrekordbox/db6/database.py,sha256=d-Z6IqU3T2f5twOHoCWK_LEhbBdeVUC__Ejt7lYwE-E,66308
15
- pyrekordbox/db6/registry.py,sha256=qSRk3hWVqYSdqPTBw_pzoKlKSoNd9pHjaqGaAt8zr2M,8940
16
- pyrekordbox/db6/tables.py,sha256=HmgV-7B4BnZoA9Reu9cU3_5INz3Y-tljcPy-2t89ebA,56383
17
- pyrekordbox/mysettings/__init__.py,sha256=rMS6Kknf1-X3PXF_TUxm8xui0H1Ap3R7G_9mqlnQUAM,705
18
- pyrekordbox/mysettings/file.py,sha256=AGD4pho0E-i71UuFJbfehljqjlC9RSHsijjWCiyaCDI,13262
19
- pyrekordbox/mysettings/structs.py,sha256=5Y1F3qTmsP1fRB39_BEHpQVxKx2DO9BytEuJUG_RNcY,8472
20
- tests/__init__.py,sha256=s321RtRiHJsLt0YFq0NRncW7u66uwYHQE-6IjPcg10o,67
21
- tests/test_anlz.py,sha256=hZAW5GFEJpU8UmmHYLuU5OZlApGrWZyPAR79KtaR0cw,5782
22
- tests/test_db6.py,sha256=LGcVb7OedLN2UBclKSflp--7u0F9XTY_nuBWRP9J2G4,34799
23
- tests/test_mysetting.py,sha256=te6B_BErGc6ThgBpAl45n0Nd0hWJcm-X9WTw14bR6MA,5781
24
- tests/test_xml.py,sha256=CbdzWgVjLwmxdaUqLo58QN4iRRaUdiJe_ni8y37BVfQ,16852
25
- pyrekordbox-0.2.0.dist-info/LICENSE,sha256=Au8sngdQ79q5JsZXZJVU13j46VDxFbPwC4x6sSz8Jes,1074
26
- pyrekordbox-0.2.0.dist-info/METADATA,sha256=gmTOQiTyz3jEcyDJ-6ZclXFQw7veSGmLRPAQd0HxKJI,15296
27
- pyrekordbox-0.2.0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
28
- pyrekordbox-0.2.0.dist-info/top_level.txt,sha256=o27yRnMFSCfS7GlJ7LHB4slxcROvsF5285xGW6PZykY,18
29
- pyrekordbox-0.2.0.dist-info/RECORD,,