pyrekordbox 0.3.1__py3-none-any.whl → 0.4.0__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 (84) hide show
  1. pyrekordbox/__init__.py +8 -8
  2. pyrekordbox/__main__.py +3 -2
  3. pyrekordbox/_version.py +2 -2
  4. pyrekordbox/anlz/__init__.py +3 -2
  5. pyrekordbox/anlz/file.py +4 -2
  6. pyrekordbox/anlz/tags.py +3 -1
  7. pyrekordbox/config.py +79 -23
  8. pyrekordbox/db6/__init__.py +2 -2
  9. pyrekordbox/db6/aux_files.py +3 -2
  10. pyrekordbox/db6/database.py +227 -143
  11. pyrekordbox/db6/registry.py +1 -0
  12. pyrekordbox/db6/smartlist.py +375 -0
  13. pyrekordbox/db6/tables.py +81 -20
  14. pyrekordbox/logger.py +0 -1
  15. pyrekordbox/mysettings/__init__.py +5 -4
  16. pyrekordbox/mysettings/file.py +3 -1
  17. pyrekordbox/rbxml.py +5 -3
  18. pyrekordbox/utils.py +4 -3
  19. {pyrekordbox-0.3.1.dist-info → pyrekordbox-0.4.0.dist-info}/LICENSE +1 -1
  20. {pyrekordbox-0.3.1.dist-info → pyrekordbox-0.4.0.dist-info}/METADATA +26 -42
  21. pyrekordbox-0.4.0.dist-info/RECORD +25 -0
  22. {pyrekordbox-0.3.1.dist-info → pyrekordbox-0.4.0.dist-info}/WHEEL +1 -1
  23. {pyrekordbox-0.3.1.dist-info → pyrekordbox-0.4.0.dist-info}/top_level.txt +0 -2
  24. docs/Makefile +0 -20
  25. docs/make.bat +0 -35
  26. docs/source/_static/images/anlz_beat.svg +0 -53
  27. docs/source/_static/images/anlz_file.svg +0 -204
  28. docs/source/_static/images/anlz_pco2.svg +0 -138
  29. docs/source/_static/images/anlz_pcob.svg +0 -148
  30. docs/source/_static/images/anlz_pcp2.svg +0 -398
  31. docs/source/_static/images/anlz_pcpt.svg +0 -263
  32. docs/source/_static/images/anlz_ppth.svg +0 -123
  33. docs/source/_static/images/anlz_pqt2.svg +0 -324
  34. docs/source/_static/images/anlz_pqt2_2.svg +0 -253
  35. docs/source/_static/images/anlz_pqtz.svg +0 -140
  36. docs/source/_static/images/anlz_pssi.svg +0 -192
  37. docs/source/_static/images/anlz_pssi_entry.svg +0 -191
  38. docs/source/_static/images/anlz_pvbr.svg +0 -125
  39. docs/source/_static/images/anlz_pwav.svg +0 -130
  40. docs/source/_static/images/anlz_pwv3.svg +0 -139
  41. docs/source/_static/images/anlz_pwv4.svg +0 -139
  42. docs/source/_static/images/anlz_pwv5.svg +0 -139
  43. docs/source/_static/images/anlz_pwv5_entry.svg +0 -100
  44. docs/source/_static/images/anlz_pwv6.svg +0 -130
  45. docs/source/_static/images/anlz_pwv7.svg +0 -139
  46. docs/source/_static/images/anlz_pwvc.svg +0 -125
  47. docs/source/_static/images/anlz_tag.svg +0 -110
  48. docs/source/_static/images/x64dbg_rb_key.png +0 -0
  49. docs/source/_static/logos/dark/logo_primary.svg +0 -75
  50. docs/source/_static/logos/light/logo_primary.svg +0 -75
  51. docs/source/_static/logos/mid/logo_primary.svg +0 -75
  52. docs/source/_templates/apidoc/module.rst_t +0 -8
  53. docs/source/_templates/apidoc/package.rst_t +0 -57
  54. docs/source/_templates/apidoc/toc.rst_t +0 -7
  55. docs/source/_templates/autosummary/class.rst +0 -32
  56. docs/source/_templates/autosummary/module.rst +0 -55
  57. docs/source/api.md +0 -18
  58. docs/source/conf.py +0 -178
  59. docs/source/development/changes.md +0 -3
  60. docs/source/development/contributing.md +0 -3
  61. docs/source/formats/anlz.md +0 -634
  62. docs/source/formats/db6.md +0 -1233
  63. docs/source/formats/mysetting.md +0 -392
  64. docs/source/formats/xml.md +0 -376
  65. docs/source/index.md +0 -103
  66. docs/source/installation.md +0 -271
  67. docs/source/key.md +0 -103
  68. docs/source/quickstart.md +0 -185
  69. docs/source/requirements.txt +0 -7
  70. docs/source/tutorial/anlz.md +0 -7
  71. docs/source/tutorial/configuration.md +0 -66
  72. docs/source/tutorial/db6.md +0 -178
  73. docs/source/tutorial/index.md +0 -20
  74. docs/source/tutorial/mysetting.md +0 -124
  75. docs/source/tutorial/xml.md +0 -140
  76. pyrekordbox/db6/smart_playlist.py +0 -333
  77. pyrekordbox/xml.py +0 -8
  78. pyrekordbox-0.3.1.dist-info/RECORD +0 -84
  79. tests/__init__.py +0 -3
  80. tests/test_anlz.py +0 -206
  81. tests/test_config.py +0 -175
  82. tests/test_db6.py +0 -1115
  83. tests/test_mysetting.py +0 -203
  84. tests/test_xml.py +0 -629
@@ -1,178 +0,0 @@
1
- # Rekordbox 6 Database
2
-
3
- Pyrekordbox uses [SQLALchemy](https://www.sqlalchemy.org/) as ORM-Framework to handle the
4
- Rekordbox v6 database file (``master.db``). The table declarations can be found in
5
- ``pyrekordbox.db6.tables``.
6
-
7
- ```{seealso}
8
- See the {ref}`Rekordbox 6 Database Format <Rekordbox 6 Database Format>` documentation for more information.
9
- ```
10
-
11
- Since the Rekordbox v6 database handler automatically finds the ``master.db`` database file
12
- (see configuration), it can be initialized without any arguments:
13
- ````python
14
- from pyrekordbox import Rekordbox6Database
15
-
16
- db = Rekordbox6Database()
17
- ````
18
-
19
- If the automatic key extraction fails the command line interface of ``pyrekordbox``
20
- provides a command for downloading the key from known sources and writing it to the
21
- cache file:
22
- ````shell
23
- python -m pyrekordbox download-key
24
- ````
25
- Once the key is cached the database can be opened without providing the key.
26
- If you obtained the key from another source, you can also pass it to the database handler
27
- ````python
28
- db = Rekordbox6Database(key="<insert key here>")
29
- ````
30
- or write it to the cache file manually:
31
- ````python
32
- from pyrekordbox.config import write_db6_key_cache
33
-
34
- write_db6_key_cache("<insert key here>") # call once
35
- db = Rekordbox6Database()
36
- ````
37
- The key can be found in some other projects (see issue
38
- [#77](https://github.com/dylanljones/pyrekordbox/issues/77)), for example [here][rb6-key].
39
-
40
-
41
- ## Querying the database
42
-
43
- A query can be executed on any table by calling the ``query()`` method. The result is
44
- a SQLAlchemy query object, which can be used to filter and sort the results.
45
- ````python
46
- from pyrekordbox.db6 import tables
47
-
48
- query = db.query(tables.DjmdContent)
49
- results = query.filter(tables.DjmdContent.Title == "My Song").all()
50
- ````
51
-
52
- To simplify querying the database, the ``Rekordbox6Database`` class provides simple
53
- getters for executing queries on all the tables. The parameters of the getters are
54
- passed to the ``query.filter_by()`` method. If the query is filtered by a *unique* key
55
- (e.g. ``ID``), the query will be executed using the ``query.one()`` method, returning the
56
- table instance directly:
57
- ````python
58
- # Return specific entry in DjmDContent table
59
- content = db.get_content(ID=0)
60
- ````
61
-
62
- In all other cases the query is returned, allowing to further filter and sort the results:
63
- ````python
64
- # Query and sort entries in DjmdHistory table
65
- for history in db.get_history().order_by(tables.DjmdHistory.DateCreated):
66
- print(history)
67
- ````
68
-
69
- This allows the user to make use of the full power of SQLAlchemy queries.
70
-
71
- ### Relationships
72
-
73
- Some values of table entries are linked to other tables and can not be updated
74
- directly. For example, the [djmdContent table][djmdContent-table] contains an
75
- ``ArtistID`` column, which links to the [djmdArtist table][djmdArtist-table].
76
- The table declarations provide relationships to access the linked values.
77
- The artist of a song can be accessed as follows:
78
- ````python
79
- content = db.get_content(ID=0)
80
- artist = content.Artist
81
- ````
82
- A full list of linked tables can be found in the [](db6-format) documentation.
83
-
84
-
85
- ## Updating the database
86
-
87
- Many values in the Rekordbox database can be updated by simply changing the corresponding
88
- attribute of the table instance and calling the ``db.commit()`` method:
89
- ````python
90
- content = db.get_content().first()
91
- content.Title = "New title"
92
- db.commit()
93
- ````
94
-
95
- Since some values of table entries are linked to other tables these values can not
96
- be updated directly. Also, many values depend on other values on the table and have to
97
- be updated accordingly to ensure consistency of the database, for example the ``TrackNo``
98
- of songs in playlists.
99
-
100
- To simplify updating the database, the ``Rekordbox6Database`` class provides a set of
101
- high level methods for updating the database. These methods take care of updating all
102
- linked values and metadata.
103
-
104
- ### Playlists
105
-
106
- A new playlist can be created by calling the ``db.create_playlist()`` method:
107
- ````python
108
- playlist = db.create_playlist("My Playlist")
109
- ````
110
- It creates a new [DjmdPlaylist] instance and adds it to the [djmdPlaylist table][djmdPlaylist-table].
111
- By default, the playlist is inserted as last element of the parent playlist folder.
112
- Alternatively, the sequence number of the new playlist can be specified:
113
- ````python
114
- playlist = db.create_playlist("My Playlist", seq=2)
115
- ````
116
- To add the playlist to a specific playlist folder, the ``parent`` parameter can be used
117
- to pass a playlist folder instance or ID:
118
- ````python
119
- folder = db.get_playlist(Name="My Folder").one() # Query for unique playlist folder
120
- playlist = db.create_playlist("My Playlist", parent=folder)
121
- ````
122
-
123
- Playlist folders can also be created , which are also stored in the [djmdPlaylist table][djmdPlaylist-table].
124
- The method accepts the same parameters as the ``db.create_playlist()`` method:
125
- ````python
126
- folder = db.create_playlist_folder("My Folder")
127
- ````
128
-
129
- Playlists and playlist folders can also be deleted:
130
- ````python
131
- playlist = db.get_playlist(Name="My Playlist").one()
132
- db.delete_playlist(playlist)
133
-
134
- folder = db.get_playlist(Name="My Folder").one()
135
- db.delete_playlist(folder)
136
- ````
137
-
138
- ```{caution}
139
- When deleting a playlist or playlist folder, all children are deleted as well.
140
- Deleting a playlist removes all songs from the playlist before deleting it. Similarly,
141
- deleting a playlist folder removes all playlists and playlist folders in the folder,
142
- including all songs in the sub-playlists.
143
- ```
144
-
145
- Adding tracks to a playlist is done by calling the ``db.add_to_playlist()`` method.
146
- It accepts a [DjmdContent] instance or corresponding ID and creates a new entry in
147
- the [djmdSongPlaylist table][djmdSongPlaylist-table], which stores the contents of playlists:
148
- ````python
149
- content = db.get_content(ID=0)
150
- playlist = db.get_playlist(Name="My Playlist").one()
151
- song = db.add_to_playlist(playlist, content)
152
- ````
153
-
154
- To delete a song from a playlist, the [DjmdSongPlaylist] instance or ID has to be passed,
155
- since a track can be contained in a plalyist more than once:
156
- ````python
157
- playlist = db.get_playlist(Name="My Playlist").one()
158
- song = playlist.Songs[0]
159
-
160
- db.remove_from_playlist(playlist, song)
161
- ````
162
-
163
- ```{note}
164
- More coming soon!
165
- ```
166
-
167
-
168
-
169
- [db-format]: #db6-format
170
- [djmdArtist-table]: #djmdArtist
171
- [DjmdArtist]: pyrekordbox.db6.tables.DjmdArtist
172
- [djmdContent-table]: #djmdContent
173
- [DjmdContent]: pyrekordbox.db6.tables.DjmdContent
174
- [djmdPlaylist-table]: #djmdPlaylist
175
- [DjmdPlaylist]: pyrekordbox.db6.tables.DjmdPlaylist
176
- [djmdSongPlaylist-table]: #djmdSongPlaylist
177
- [DjmdSongPlaylist]: pyrekordbox.db6.tables.DjmdSongPlaylist
178
- [rb6-key]: https://github.com/mganss/CueGen/blob/19878e6eb3f586dee0eb3eb4f2ce3ef18309de9d/CueGen/Generator.cs#L31
@@ -1,20 +0,0 @@
1
- # Tutorial
2
-
3
- ```{attention}
4
- Please make sure to back up your Rekordbox collection before making
5
- any changes with pyrekordbox or developing/testing new features.
6
-
7
- The backup dialog can be found under "File" > "Library" > "Backup Library"
8
- ```
9
-
10
- ````{toctree}
11
- ---
12
- maxdepth: 3
13
- ---
14
-
15
- configuration
16
- db6
17
- xml
18
- anlz
19
- mysetting
20
- ````
@@ -1,124 +0,0 @@
1
- # My-Settings
2
-
3
-
4
- Rekordbox stores the user settings in ``*SETTING.DAT`` files, which get exported
5
- to USB devices. These files are located in the ``PIONEER`` directory of a USB drive
6
- (device exports), but are also present on local installations of Rekordbox 6.
7
- The setting files store the settings found on the "DJ System" > "My Settings" page
8
- of the Rekordbox preferences. These include language, LCD brightness,
9
- tempo fader range, crossfader curve and other settings for Pioneer professional
10
- DJ equipment.
11
-
12
- ```{seealso}
13
- See the {ref}`My-Setting Files Format<My-Setting Files Format>` documentation for more information.
14
- ```
15
-
16
- Pyrekordbox includes a file handler for each of the four My-Settings files. To read any of the four files, use
17
- ````python
18
- from pyrekordbox import read_mysetting_file
19
-
20
- file = read_mysetting_file("MYSETTING.DAT")
21
- ````
22
-
23
- My-Settings files can also be parsed manually:
24
- ````python
25
- from pyrekordbox import MySettingFile, MySetting2File, DjmMySettingFile, DevSettingFile
26
-
27
- file1 = MySettingFile.parse_file("MYSETTING.DAT")
28
- file2 = MySetting2File.parse_file("MYSETTING2.DAT")
29
- file3 = DjmMySettingFile.parse_file("DJMMYSETTING.DAT")
30
- file4 = DevSettingFile.parse_file("DEVSETTING.DAT")
31
- ````
32
-
33
- After parsing a My-Setting file, the settings can be accessed as dictionary:
34
- ````python
35
- >>> file = read_mysetting_file("MYSETTING.DAT")
36
- >>> file["quantize"]
37
- on
38
-
39
- >>> file["quantize"] = "off"
40
- ````
41
-
42
- To save the updated contents of a My-Settings file, use
43
- ````python
44
- >>> file.save("MYSETTING.DAT")
45
- ````
46
-
47
- ## MySetting Files
48
-
49
- The ``MYSETTING.DAT`` files store the main settings for Pioneers CDJ players.
50
-
51
- ````python
52
- >>> file = read_mysetting_file("MYSETTING.DAT")
53
- >>> for setting, value in file.items():
54
- ... print(f"{setting:<25} {value}")
55
- auto_cue on
56
- auto_cue_level memory
57
- disc_slot_illumination bright
58
- eject_lock unlock
59
- hotcue_autoload on
60
- hotcue_color off
61
- jog_mode vinyl
62
- jog_ring_brightness bright
63
- jog_ring_indicator on
64
- language english
65
- lcd_brightness three
66
- master_tempo off
67
- needle_lock lock
68
- on_air_display on
69
- phase_meter type1
70
- play_mode single
71
- quantize on
72
- quantize_beat_value one
73
- slip_flashing on
74
- sync off
75
- tempo_range ten
76
- time_mode remain
77
- ````
78
-
79
-
80
- ## MySetting2 Files
81
-
82
- The ``MYSETTING2.DAT`` files store additional settings for Pioneers CDJ players.
83
-
84
- ````python
85
- >>> file = read_mysetting_file("MYSETTING2.DAT")
86
- >>> for setting, value in file.items():
87
- ... print(f"{setting:<25} {value}")
88
- vinyl_speed_adjust touch
89
- jog_display_mode auto
90
- pad_button_brightness three
91
- jog_lcd_brightness three
92
- waveform_divisions phrase
93
- waveform waveform
94
- beat_jump_beat_value sixteen
95
- ````
96
-
97
-
98
- ## DjmMySetting Files
99
-
100
- The ``DJMMYSETTING.DAT`` files store the settings for Pioneers DJMD mixers.
101
-
102
- ````python
103
- >>> file = read_mysetting_file("DJMMYSETTING.DAT")
104
- >>> for setting, value in file.items():
105
- ... print(f"{setting:<25} {value}")
106
- channel_fader_curve linear
107
- cross_fader_curve fast_cut
108
- headphones_pre_eq post_eq
109
- headphones_mono_split stereo
110
- beat_fx_quantize on
111
- mic_low_cut on
112
- talk_over_mode advanced
113
- talk_over_level minus_18db
114
- midi_channel one
115
- midi_button_type toggle
116
- display_brightness five
117
- indicator_brightness three
118
- channel_fader_curve_long exponential
119
- ````
120
-
121
-
122
- ## DevSetting Files
123
-
124
- The ``DEVSETTING.DAT`` files are not supported.
@@ -1,140 +0,0 @@
1
- # XML Database
2
-
3
- We will use the Rekordbox 6 database from the test data as an example:
4
-
5
- ```python
6
- import os
7
- path = os.path.join(".testdata", "rekordbox 5", "database.xml")
8
- ```
9
-
10
- An existing XML database can be parsed by passing the file path to the ``RekordboxXml``
11
- constructor:
12
- ```python
13
- from pyrekordbox import RekordboxXml
14
- xml = RekordboxXml(path)
15
- print(xml.tostring())
16
- ```
17
-
18
- Printing the contents results in the following output:
19
- ```xml
20
- <?xml version="1.0" encoding="utf-8"?>
21
- <DJ_PLAYLISTS Version="1.0.0">
22
- <PRODUCT Name="rekordbox" Version="6.6.2" Company="AlphaTheta"/>
23
- <COLLECTION Entries="6">
24
- <TRACK TrackID="253529738" Name="Demo Track 1" Artist="Loopmasters" Composer="" Album="" Grouping="" Genre="" Kind="Mp3-Datei " Size="6899624" TotalTime="172" DiscNumber="0" TrackNumber="0" Year="0" AverageBpm="128.00" DateAdded="2022-04-09" BitRate="320" SampleRate="44100" Comments="Tracks by www.loopmasters.com" PlayCount="0" Rating="0" Location="file://localhost/C:/Music/PioneerDJ/Demo%20Tracks/Demo%20Track%201.mp3" Remixer="" Tonality="Fm" Label="Loopmasters" Mix="">
25
- <TEMPO Inizio="0.025" Bpm="128.00" Metro="4/4" Battito="1"/>
26
- </TRACK>
27
- <TRACK TrackID="17109519" Name="Demo Track 2" Artist="Loopmasters" Composer="" Album="" Grouping="" Genre="" Kind="Mp3-Datei " Size="5124342" TotalTime="128" DiscNumber="0" TrackNumber="0" Year="0" AverageBpm="120.00" DateAdded="2022-04-09" BitRate="320" SampleRate="44100" Comments="Tracks by www.loopmasters.com" PlayCount="0" Rating="0" Location="file://localhost/C:/Music/PioneerDJ/Demo%20Tracks/Demo%20Track%202.mp3" Remixer="" Tonality="Fm" Label="Loopmasters" Mix="">
28
- <TEMPO Inizio="0.025" Bpm="120.00" Metro="4/4" Battito="1"/>
29
- <TEMPO Inizio="48.026" Bpm="120.00" Metro="4/4" Battito="1"/>
30
- <TEMPO Inizio="48.525" Bpm="120.00" Metro="4/4" Battito="2"/>
31
- <TEMPO Inizio="49.026" Bpm="120.00" Metro="4/4" Battito="3"/>
32
- <TEMPO Inizio="49.525" Bpm="120.00" Metro="4/4" Battito="4"/>
33
- <TEMPO Inizio="50.026" Bpm="120.00" Metro="4/4" Battito="1"/>
34
- <TEMPO Inizio="50.525" Bpm="120.00" Metro="4/4" Battito="2"/>
35
- <TEMPO Inizio="51.026" Bpm="120.00" Metro="4/4" Battito="3"/>
36
- <TEMPO Inizio="51.525" Bpm="120.00" Metro="4/4" Battito="4"/>
37
- <TEMPO Inizio="52.026" Bpm="120.00" Metro="4/4" Battito="1"/>
38
- </TRACK>
39
- <TRACK TrackID="49557014" Name="HORN" Artist="" Composer="" Album="" Grouping="" Genre="" Kind="Wav-Datei " Size="2010816" TotalTime="7" DiscNumber="0" TrackNumber="0" Year="0" AverageBpm="0.00" DateAdded="2022-04-09" BitRate="2116" SampleRate="44100" Comments="" PlayCount="0" Rating="0" Location="file://localhost/C:/Music/PioneerDJ/Sampler/OSC_SAMPLER/PRESET%20ONESHOT/HORN.wav" Remixer="" Tonality="" Label="" Mix=""/>
40
- <TRACK TrackID="209873516" Name="NOISE" Artist="" Composer="" Album="" Grouping="" Genre="" Kind="Wav-Datei " Size="1382226" TotalTime="5" DiscNumber="0" TrackNumber="0" Year="0" AverageBpm="0.00" DateAdded="2022-04-09" BitRate="2116" SampleRate="44100" Comments="" PlayCount="0" Rating="0" Location="file://localhost/C:/Music/PioneerDJ/Sampler/OSC_SAMPLER/PRESET%20ONESHOT/NOISE.wav" Remixer="" Tonality="" Label="" Mix=""/>
41
- <TRACK TrackID="55231398" Name="SINEWAVE" Artist="" Composer="" Album="" Grouping="" Genre="" Kind="Wav-Datei " Size="1515258" TotalTime="5" DiscNumber="0" TrackNumber="0" Year="0" AverageBpm="0.00" DateAdded="2022-04-09" BitRate="2116" SampleRate="44100" Comments="" PlayCount="0" Rating="0" Location="file://localhost/C:/Music/PioneerDJ/Sampler/OSC_SAMPLER/PRESET%20ONESHOT/SINEWAVE.wav" Remixer="" Tonality="" Label="" Mix=""/>
42
- <TRACK TrackID="92396897" Name="SIREN" Artist="" Composer="" Album="" Grouping="" Genre="" Kind="Wav-Datei " Size="1941204" TotalTime="7" DiscNumber="0" TrackNumber="0" Year="0" AverageBpm="0.00" DateAdded="2022-04-09" BitRate="2116" SampleRate="44100" Comments="" PlayCount="0" Rating="0" Location="file://localhost/C:/Music/PioneerDJ/Sampler/OSC_SAMPLER/PRESET%20ONESHOT/SIREN.wav" Remixer="" Tonality="" Label="" Mix=""/>
43
- </COLLECTION>
44
- <PLAYLISTS>
45
- <NODE Type="0" Name="ROOT" Count="1">
46
- <NODE Name="Trial playlist - Cloud Library Sync" Type="1" KeyType="0" Entries="0"/>
47
- </NODE>
48
- </PLAYLISTS>
49
- </DJ_PLAYLISTS>
50
- ```
51
-
52
- ## Tracks
53
-
54
- Individual tracks in the collection can be fetched by supplying an index
55
- ````
56
- >>> xml.get_track(0)
57
- <Track(Location=C:\Music\PioneerDJ\Demo Tracks\Demo Track 1.mp3)>
58
- ````
59
- or the `TrackID`:
60
- ````
61
- >>> xml.get_track(TrackID=253529738)
62
- <Track(Location=C:\Music\PioneerDJ\Demo Tracks\Demo Track 1.mp3)>
63
- ````
64
-
65
- All items in the collection can be fetched via
66
- ````
67
- >>> tracks = xml.get_tracks()
68
- >>> tracks[0]
69
- <Track(Location=C:\Music\PioneerDJ\Demo Tracks\Demo Track 1.mp3)>
70
- ````
71
-
72
- The XML attributes of a `Track` element are accessable as an attribute of the ``Track``
73
- object or via a dict-interface:
74
- ````python
75
- >>> track = xml.get_track(0)
76
- >>> track.Name
77
- Demo Track 1
78
-
79
- >>> track["Name"]
80
- Demo Track 1
81
- ````
82
-
83
- Each track can contain a ``Tempo`` or ``PositionMark`` element. The ``Tempo`` element
84
- stores the beat grid information:
85
- ````python
86
- >>> track = xml.get_track(0)
87
- >>> tempo = track.tempos[0]
88
- >>> tempo.Bpm
89
- 128.0
90
- ````
91
-
92
- and the ``PositionMark`` element stores the cue points of a track (not included in the XML example above):
93
- ````python
94
- >>> track = xml.get_track(0)
95
- >>> mark = track.marks[0]
96
- >>> mark.Type
97
- cue
98
-
99
- >>> mark.Start
100
- 0.0
101
-
102
- >>> mark.Num
103
- -1
104
- ````
105
-
106
- ```{seealso}
107
- See the {ref}`XML Database Format<XML Database Format>` documentation for a list of valid
108
- attributes. All XML attributes start with a capital letter.
109
- ```
110
-
111
-
112
- ## Playlists
113
-
114
- Playlists or playlist folders can be accessed by supplying the path:
115
- ````python
116
- folder = xml.get_playlist("Folder")
117
- paylist = xml.get_playlist("Folder", "Sub Playlist")
118
- ````
119
- Content in a playlist is stored as a key, which can either be the ``TrackID`` or the
120
- ``Location`` (file path):
121
- ````python
122
- >>> playlist.key_type
123
- TrackID
124
- ````
125
-
126
- The keys can be retrieved by calling
127
- ````python
128
- keys = playlist.get_tracks()
129
- ````
130
-
131
- A new track can be added to a playlist by specifying the corresponding key:
132
- ````python
133
- playlist.add_track(track_key)
134
- ````
135
-
136
- A new sub-folder or -playlist can be added by supplying the name:
137
- ````python
138
- folder.add_playlist("Playlist")
139
- folder.add_playlist_folder("Folder")
140
- ````