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.
- pyrekordbox/__init__.py +8 -8
- pyrekordbox/__main__.py +3 -2
- pyrekordbox/_version.py +2 -2
- pyrekordbox/anlz/__init__.py +3 -2
- pyrekordbox/anlz/file.py +4 -2
- pyrekordbox/anlz/tags.py +3 -1
- pyrekordbox/config.py +79 -23
- pyrekordbox/db6/__init__.py +2 -2
- pyrekordbox/db6/aux_files.py +3 -2
- pyrekordbox/db6/database.py +227 -143
- pyrekordbox/db6/registry.py +1 -0
- pyrekordbox/db6/smartlist.py +375 -0
- pyrekordbox/db6/tables.py +81 -20
- pyrekordbox/logger.py +0 -1
- pyrekordbox/mysettings/__init__.py +5 -4
- pyrekordbox/mysettings/file.py +3 -1
- pyrekordbox/rbxml.py +5 -3
- pyrekordbox/utils.py +4 -3
- {pyrekordbox-0.3.1.dist-info → pyrekordbox-0.4.0.dist-info}/LICENSE +1 -1
- {pyrekordbox-0.3.1.dist-info → pyrekordbox-0.4.0.dist-info}/METADATA +26 -42
- pyrekordbox-0.4.0.dist-info/RECORD +25 -0
- {pyrekordbox-0.3.1.dist-info → pyrekordbox-0.4.0.dist-info}/WHEEL +1 -1
- {pyrekordbox-0.3.1.dist-info → pyrekordbox-0.4.0.dist-info}/top_level.txt +0 -2
- docs/Makefile +0 -20
- docs/make.bat +0 -35
- docs/source/_static/images/anlz_beat.svg +0 -53
- docs/source/_static/images/anlz_file.svg +0 -204
- docs/source/_static/images/anlz_pco2.svg +0 -138
- docs/source/_static/images/anlz_pcob.svg +0 -148
- docs/source/_static/images/anlz_pcp2.svg +0 -398
- docs/source/_static/images/anlz_pcpt.svg +0 -263
- docs/source/_static/images/anlz_ppth.svg +0 -123
- docs/source/_static/images/anlz_pqt2.svg +0 -324
- docs/source/_static/images/anlz_pqt2_2.svg +0 -253
- docs/source/_static/images/anlz_pqtz.svg +0 -140
- docs/source/_static/images/anlz_pssi.svg +0 -192
- docs/source/_static/images/anlz_pssi_entry.svg +0 -191
- docs/source/_static/images/anlz_pvbr.svg +0 -125
- docs/source/_static/images/anlz_pwav.svg +0 -130
- docs/source/_static/images/anlz_pwv3.svg +0 -139
- docs/source/_static/images/anlz_pwv4.svg +0 -139
- docs/source/_static/images/anlz_pwv5.svg +0 -139
- docs/source/_static/images/anlz_pwv5_entry.svg +0 -100
- docs/source/_static/images/anlz_pwv6.svg +0 -130
- docs/source/_static/images/anlz_pwv7.svg +0 -139
- docs/source/_static/images/anlz_pwvc.svg +0 -125
- docs/source/_static/images/anlz_tag.svg +0 -110
- docs/source/_static/images/x64dbg_rb_key.png +0 -0
- docs/source/_static/logos/dark/logo_primary.svg +0 -75
- docs/source/_static/logos/light/logo_primary.svg +0 -75
- docs/source/_static/logos/mid/logo_primary.svg +0 -75
- docs/source/_templates/apidoc/module.rst_t +0 -8
- docs/source/_templates/apidoc/package.rst_t +0 -57
- docs/source/_templates/apidoc/toc.rst_t +0 -7
- docs/source/_templates/autosummary/class.rst +0 -32
- docs/source/_templates/autosummary/module.rst +0 -55
- docs/source/api.md +0 -18
- docs/source/conf.py +0 -178
- docs/source/development/changes.md +0 -3
- docs/source/development/contributing.md +0 -3
- docs/source/formats/anlz.md +0 -634
- docs/source/formats/db6.md +0 -1233
- docs/source/formats/mysetting.md +0 -392
- docs/source/formats/xml.md +0 -376
- docs/source/index.md +0 -103
- docs/source/installation.md +0 -271
- docs/source/key.md +0 -103
- docs/source/quickstart.md +0 -185
- docs/source/requirements.txt +0 -7
- docs/source/tutorial/anlz.md +0 -7
- docs/source/tutorial/configuration.md +0 -66
- docs/source/tutorial/db6.md +0 -178
- docs/source/tutorial/index.md +0 -20
- docs/source/tutorial/mysetting.md +0 -124
- docs/source/tutorial/xml.md +0 -140
- pyrekordbox/db6/smart_playlist.py +0 -333
- pyrekordbox/xml.py +0 -8
- pyrekordbox-0.3.1.dist-info/RECORD +0 -84
- tests/__init__.py +0 -3
- tests/test_anlz.py +0 -206
- tests/test_config.py +0 -175
- tests/test_db6.py +0 -1115
- tests/test_mysetting.py +0 -203
- tests/test_xml.py +0 -629
tests/test_db6.py
DELETED
@@ -1,1115 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
# Author: Dylan Jones
|
3
|
-
# Date: 2023-02-01
|
4
|
-
|
5
|
-
import os
|
6
|
-
import pytest
|
7
|
-
from pytest import mark
|
8
|
-
from pathlib import Path
|
9
|
-
import shutil
|
10
|
-
import tempfile
|
11
|
-
from sqlalchemy.orm.query import Query
|
12
|
-
from pyrekordbox import Rekordbox6Database, open_rekordbox_database
|
13
|
-
from pyrekordbox.db6 import tables
|
14
|
-
|
15
|
-
TEST_ROOT = Path(__file__).parent.parent / ".testdata"
|
16
|
-
LOCKED = TEST_ROOT / "rekordbox 6" / "master_locked.db"
|
17
|
-
UNLOCKED = TEST_ROOT / "rekordbox 6" / "master_unlocked.db"
|
18
|
-
UNLOCKED_COPY = TEST_ROOT / "rekordbox 6" / "master_unlocked_copy.db"
|
19
|
-
UNLOCKED_OUT = TEST_ROOT / "rekordbox 6" / "master_unlocked_out.db"
|
20
|
-
MASTER_PLAYLIST_SRC = TEST_ROOT / "rekordbox 6" / "masterPlaylists6_template.xml"
|
21
|
-
MASTER_PLAYLIST_DST = TEST_ROOT / "rekordbox 6" / "masterPlaylists6.xml"
|
22
|
-
# Create a copy of the masterPlaylists6.xml file
|
23
|
-
shutil.copy(MASTER_PLAYLIST_SRC, MASTER_PLAYLIST_DST)
|
24
|
-
|
25
|
-
DB = Rekordbox6Database(UNLOCKED, unlock=False)
|
26
|
-
|
27
|
-
# Content IDs
|
28
|
-
CID1 = 178162577 # Demo Track 1
|
29
|
-
CID2 = 66382436 # Demo Track 2
|
30
|
-
CID3 = 181094952 # HORN
|
31
|
-
CID4 = 24401986 # NOISE
|
32
|
-
|
33
|
-
# Playlist ID
|
34
|
-
PID1 = 2602250856 # Trial playlist - Cloud Library Sync
|
35
|
-
|
36
|
-
|
37
|
-
@pytest.fixture
|
38
|
-
def db():
|
39
|
-
"""Return a clean Rekordbox v6 database instance and close it after tests."""
|
40
|
-
shutil.copy(UNLOCKED, UNLOCKED_COPY)
|
41
|
-
shutil.copy(MASTER_PLAYLIST_SRC, MASTER_PLAYLIST_DST)
|
42
|
-
db = Rekordbox6Database(UNLOCKED_COPY, unlock=False)
|
43
|
-
yield db
|
44
|
-
db.close()
|
45
|
-
|
46
|
-
|
47
|
-
def test_open_rekordbox_database():
|
48
|
-
con = open_rekordbox_database(UNLOCKED, unlock=False)
|
49
|
-
con.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
50
|
-
con.close()
|
51
|
-
|
52
|
-
|
53
|
-
def test_close_open():
|
54
|
-
db = Rekordbox6Database(UNLOCKED, unlock=False)
|
55
|
-
db.close()
|
56
|
-
db.open()
|
57
|
-
_ = db.get_content()[0] # Try to query the database
|
58
|
-
db.close()
|
59
|
-
|
60
|
-
|
61
|
-
@mark.parametrize(
|
62
|
-
"name,cls",
|
63
|
-
[
|
64
|
-
("get_active_censor", tables.DjmdActiveCensor),
|
65
|
-
("get_album", tables.DjmdAlbum),
|
66
|
-
("get_artist", tables.DjmdArtist),
|
67
|
-
("get_category", tables.DjmdCategory),
|
68
|
-
("get_color", tables.DjmdColor),
|
69
|
-
("get_content", tables.DjmdContent),
|
70
|
-
("get_cue", tables.DjmdCue),
|
71
|
-
("get_device", tables.DjmdDevice),
|
72
|
-
("get_genre", tables.DjmdGenre),
|
73
|
-
("get_history", tables.DjmdHistory),
|
74
|
-
("get_hot_cue_banklist", tables.DjmdHotCueBanklist),
|
75
|
-
("get_key", tables.DjmdKey),
|
76
|
-
("get_label", tables.DjmdLabel),
|
77
|
-
("get_menu_items", tables.DjmdMenuItems),
|
78
|
-
("get_mixer_param", tables.DjmdMixerParam),
|
79
|
-
("get_my_tag", tables.DjmdMyTag),
|
80
|
-
("get_playlist", tables.DjmdPlaylist),
|
81
|
-
("get_property", tables.DjmdProperty),
|
82
|
-
("get_related_tracks", tables.DjmdRelatedTracks),
|
83
|
-
("get_sampler", tables.DjmdSampler),
|
84
|
-
("get_sort", tables.DjmdSort),
|
85
|
-
("get_agent_registry", tables.AgentRegistry),
|
86
|
-
("get_cloud_agent_registry", tables.CloudAgentRegistry),
|
87
|
-
("get_content_active_censor", tables.ContentActiveCensor),
|
88
|
-
("get_content_cue", tables.ContentCue),
|
89
|
-
("get_content_file", tables.ContentFile),
|
90
|
-
("get_hot_cue_banklist_cue", tables.HotCueBanklistCue),
|
91
|
-
("get_image_file", tables.ImageFile),
|
92
|
-
("get_setting_file", tables.SettingFile),
|
93
|
-
("get_uuid_map", tables.UuidIDMap),
|
94
|
-
],
|
95
|
-
)
|
96
|
-
def test_getter(name, cls):
|
97
|
-
getter = getattr(DB, name)
|
98
|
-
# Test return is query
|
99
|
-
query = getter()
|
100
|
-
assert isinstance(query, Query)
|
101
|
-
assert query.column_descriptions[0]["type"] == cls
|
102
|
-
|
103
|
-
# Test type of query result is the right table class
|
104
|
-
res = query.first()
|
105
|
-
assert res is None or isinstance(res, cls)
|
106
|
-
|
107
|
-
|
108
|
-
@mark.parametrize(
|
109
|
-
"name,cls",
|
110
|
-
[
|
111
|
-
("get_active_censor", tables.DjmdActiveCensor),
|
112
|
-
("get_album", tables.DjmdAlbum),
|
113
|
-
("get_artist", tables.DjmdArtist),
|
114
|
-
("get_category", tables.DjmdCategory),
|
115
|
-
("get_color", tables.DjmdColor),
|
116
|
-
("get_content", tables.DjmdContent),
|
117
|
-
("get_cue", tables.DjmdCue),
|
118
|
-
("get_device", tables.DjmdDevice),
|
119
|
-
("get_genre", tables.DjmdGenre),
|
120
|
-
("get_history", tables.DjmdHistory),
|
121
|
-
("get_hot_cue_banklist", tables.DjmdHotCueBanklist),
|
122
|
-
("get_key", tables.DjmdKey),
|
123
|
-
("get_label", tables.DjmdLabel),
|
124
|
-
("get_menu_items", tables.DjmdMenuItems),
|
125
|
-
("get_mixer_param", tables.DjmdMixerParam),
|
126
|
-
("get_my_tag", tables.DjmdMyTag),
|
127
|
-
("get_playlist", tables.DjmdPlaylist),
|
128
|
-
# ("get_property", tables.DjmdProperty),
|
129
|
-
("get_related_tracks", tables.DjmdRelatedTracks),
|
130
|
-
("get_sampler", tables.DjmdSampler),
|
131
|
-
("get_sort", tables.DjmdSort),
|
132
|
-
# ("get_agent_registry", tables.AgentRegistry),
|
133
|
-
("get_cloud_agent_registry", tables.CloudAgentRegistry),
|
134
|
-
("get_content_active_censor", tables.ContentActiveCensor),
|
135
|
-
("get_content_cue", tables.ContentCue),
|
136
|
-
("get_content_file", tables.ContentFile),
|
137
|
-
("get_hot_cue_banklist_cue", tables.HotCueBanklistCue),
|
138
|
-
("get_image_file", tables.ImageFile),
|
139
|
-
("get_setting_file", tables.SettingFile),
|
140
|
-
("get_uuid_map", tables.UuidIDMap),
|
141
|
-
],
|
142
|
-
)
|
143
|
-
def test_getter_by_id(name, cls):
|
144
|
-
# Get method from class
|
145
|
-
getter = getattr(DB, name)
|
146
|
-
|
147
|
-
# Try to get a valid ID
|
148
|
-
item = getter().first()
|
149
|
-
if item is None:
|
150
|
-
return
|
151
|
-
id_ = item.ID
|
152
|
-
|
153
|
-
# Test type of result is a table class, not the query
|
154
|
-
res = getter(ID=id_)
|
155
|
-
assert res is None or isinstance(res, cls)
|
156
|
-
|
157
|
-
|
158
|
-
@mark.parametrize(
|
159
|
-
"parent_name,key,cls",
|
160
|
-
[
|
161
|
-
("get_history", "HistoryID", tables.DjmdSongHistory),
|
162
|
-
("get_hot_cue_banklist", "HotCueBanklistID", tables.DjmdSongHotCueBanklist),
|
163
|
-
("get_my_tag", "MyTagID", tables.DjmdSongMyTag),
|
164
|
-
("get_playlist", "PlaylistID", tables.DjmdSongPlaylist),
|
165
|
-
("get_related_tracks", "RelatedTracksID", tables.DjmdSongPlaylist),
|
166
|
-
("get_sampler", "SamplerID", tables.DjmdSongPlaylist),
|
167
|
-
],
|
168
|
-
)
|
169
|
-
def test_songs_getters(parent_name, key, cls):
|
170
|
-
# Get list (containing songs) getter
|
171
|
-
getter = getattr(DB, parent_name)
|
172
|
-
# Try to get a valid list ID
|
173
|
-
query = getter()
|
174
|
-
if not query.count():
|
175
|
-
return # No data to check...
|
176
|
-
|
177
|
-
item = query.first()
|
178
|
-
id_ = item.ID
|
179
|
-
|
180
|
-
# Get list songs getter
|
181
|
-
getter = getattr(DB, f"{parent_name}_songs")
|
182
|
-
# Get song items
|
183
|
-
query = getter(**{key: id_})
|
184
|
-
if not query.count():
|
185
|
-
return # No data to check...
|
186
|
-
|
187
|
-
assert isinstance(query.first(), cls)
|
188
|
-
|
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
|
-
|
207
|
-
@mark.parametrize(
|
208
|
-
"search,ids",
|
209
|
-
[
|
210
|
-
("Demo Track 1", [CID1]), # Title
|
211
|
-
("Demo Track 2", [CID2]), # Title
|
212
|
-
("Loopmasters", [CID1, CID2]), # Label/Artist Name
|
213
|
-
("Noise", [CID4]), # lowercase
|
214
|
-
("NOIS", [CID4]), # incomplete
|
215
|
-
],
|
216
|
-
)
|
217
|
-
def test_search_content(search, ids):
|
218
|
-
results = DB.search_content(search)
|
219
|
-
for id_, res in zip(ids, results):
|
220
|
-
assert int(res.ID) == id_
|
221
|
-
|
222
|
-
|
223
|
-
def test_increment_local_usn(db):
|
224
|
-
old = db.get_local_usn()
|
225
|
-
db.increment_local_usn()
|
226
|
-
assert db.get_local_usn() == old + 1
|
227
|
-
|
228
|
-
db.increment_local_usn(1)
|
229
|
-
assert db.get_local_usn() == old + 2
|
230
|
-
|
231
|
-
db.increment_local_usn(2)
|
232
|
-
assert db.get_local_usn() == old + 4
|
233
|
-
|
234
|
-
with pytest.raises(ValueError):
|
235
|
-
db.increment_local_usn(0)
|
236
|
-
|
237
|
-
with pytest.raises(ValueError):
|
238
|
-
db.increment_local_usn(-1)
|
239
|
-
|
240
|
-
|
241
|
-
def test_autoincrement_local_usn(db):
|
242
|
-
old_usn = db.get_local_usn() # store USN before changes
|
243
|
-
track1 = db.get_content(ID=CID1)
|
244
|
-
track2 = db.get_content(ID=CID2)
|
245
|
-
track3 = db.get_content(ID=CID3)
|
246
|
-
playlist = db.get_playlist(ID=PID1)
|
247
|
-
with db.session.no_autoflush:
|
248
|
-
# Change one field in first track (+1)
|
249
|
-
track1.Title = "New title 1"
|
250
|
-
# Change two fields in second track (+2)
|
251
|
-
track2.Title = "New title 2"
|
252
|
-
track2.BPM = 12900
|
253
|
-
# Delete row from table )+1)
|
254
|
-
db.delete(track3)
|
255
|
-
# Change name of playlist (+1)
|
256
|
-
playlist.Name = "New name"
|
257
|
-
|
258
|
-
# Auto-increment USN
|
259
|
-
new_usn = db.autoincrement_usn()
|
260
|
-
|
261
|
-
# Check local Rekordbox USN and instance USN's
|
262
|
-
assert new_usn == old_usn + 5
|
263
|
-
assert track1.rb_local_usn == old_usn + 1
|
264
|
-
assert track2.rb_local_usn == old_usn + 3
|
265
|
-
# USN of deleted rows obviously don't get updated
|
266
|
-
assert playlist.rb_local_usn == new_usn
|
267
|
-
|
268
|
-
|
269
|
-
def _check_playlist_xml(db):
|
270
|
-
# Check that playlist is in XML and update time is correct
|
271
|
-
for pl in db.get_playlist():
|
272
|
-
plxml = db.playlist_xml.get(pl.ID)
|
273
|
-
ts = plxml["Timestamp"]
|
274
|
-
diff = pl.updated_at - ts
|
275
|
-
if abs(diff.total_seconds()) > 1:
|
276
|
-
return False
|
277
|
-
return True
|
278
|
-
|
279
|
-
|
280
|
-
def _check_playlist_xml_delete(db):
|
281
|
-
# Check that there are no items in the XML that are not in the db
|
282
|
-
for plxml in db.playlist_xml.get_playlists():
|
283
|
-
if plxml["Lib_Type"] != 0:
|
284
|
-
continue
|
285
|
-
pid = int(plxml["Id"], 16)
|
286
|
-
if db.query(tables.DjmdPlaylist).filter_by(ID=pid).count() != 1:
|
287
|
-
return False
|
288
|
-
return True
|
289
|
-
|
290
|
-
|
291
|
-
def test_add_song_to_playlist(db):
|
292
|
-
usn_old = db.get_local_usn()
|
293
|
-
mtime_old = db.get_playlist(ID=PID1).updated_at
|
294
|
-
|
295
|
-
# test adding song to playlist
|
296
|
-
song = db.add_to_playlist(PID1, CID1)
|
297
|
-
db.commit()
|
298
|
-
|
299
|
-
pl = db.get_playlist(ID=PID1)
|
300
|
-
assert len(pl.Songs) == 1
|
301
|
-
assert pl.Songs[0].ContentID == str(CID1)
|
302
|
-
assert song.TrackNo == 1
|
303
|
-
|
304
|
-
# Test USN and update time are correct
|
305
|
-
assert pl.updated_at == mtime_old
|
306
|
-
assert song.rb_local_usn == usn_old + 1
|
307
|
-
assert db.get_local_usn() == usn_old + 1
|
308
|
-
|
309
|
-
# test raising error when adding song to playlist with wrong TrackNo
|
310
|
-
with pytest.raises(ValueError):
|
311
|
-
db.add_to_playlist(PID1, CID2, track_no=0)
|
312
|
-
with pytest.raises(ValueError):
|
313
|
-
db.add_to_playlist(PID1, CID2, track_no=3)
|
314
|
-
|
315
|
-
assert _check_playlist_xml(db)
|
316
|
-
|
317
|
-
|
318
|
-
def test_add_song_to_playlist_trackno_end(db):
|
319
|
-
old_usn = db.get_local_usn()
|
320
|
-
song1 = db.add_to_playlist(PID1, CID1)
|
321
|
-
song2 = db.add_to_playlist(PID1, CID2)
|
322
|
-
song3 = db.add_to_playlist(PID1, CID3)
|
323
|
-
db.commit()
|
324
|
-
assert song1.TrackNo == 1
|
325
|
-
assert song2.TrackNo == 2
|
326
|
-
assert song3.TrackNo == 3
|
327
|
-
assert db.get_local_usn() == old_usn + 3
|
328
|
-
|
329
|
-
assert _check_playlist_xml(db)
|
330
|
-
|
331
|
-
|
332
|
-
def test_add_song_to_playlist_trackno_middle(db):
|
333
|
-
song1 = db.add_to_playlist(PID1, CID1)
|
334
|
-
song2 = db.add_to_playlist(PID1, CID2)
|
335
|
-
assert song1.TrackNo == 1
|
336
|
-
assert song2.TrackNo == 2
|
337
|
-
db.commit()
|
338
|
-
|
339
|
-
usn_old = db.get_local_usn()
|
340
|
-
mtime_old = db.get_playlist(ID=PID1).updated_at
|
341
|
-
|
342
|
-
# Insert song in the middle
|
343
|
-
song3 = db.add_to_playlist(PID1, CID3, track_no=2)
|
344
|
-
db.commit()
|
345
|
-
assert song3.TrackNo == 2
|
346
|
-
|
347
|
-
pl = db.get_playlist(ID=PID1)
|
348
|
-
songs = sorted(pl.Songs, key=lambda x: int(x.TrackNo))
|
349
|
-
assert len(songs) == 3
|
350
|
-
assert songs[0].ContentID == str(CID1)
|
351
|
-
assert songs[0].TrackNo == 1
|
352
|
-
assert songs[1].ContentID == str(CID3)
|
353
|
-
assert songs[1].TrackNo == 2
|
354
|
-
assert songs[2].ContentID == str(CID2)
|
355
|
-
assert songs[2].TrackNo == 3
|
356
|
-
|
357
|
-
# Test USN and update time are correct
|
358
|
-
# First USN increment is for adding song, second for updating track no
|
359
|
-
# of other songs in playlist
|
360
|
-
assert pl.updated_at == mtime_old
|
361
|
-
assert songs[1].rb_local_usn == usn_old + 2
|
362
|
-
assert songs[2].rb_local_usn == usn_old + 2
|
363
|
-
assert db.get_local_usn() == usn_old + 2
|
364
|
-
|
365
|
-
assert _check_playlist_xml(db)
|
366
|
-
|
367
|
-
|
368
|
-
def test_remove_song_from_playlist_end(db):
|
369
|
-
# Add songs to playlist
|
370
|
-
db.add_to_playlist(PID1, CID1, track_no=1)
|
371
|
-
db.add_to_playlist(PID1, CID2, track_no=2)
|
372
|
-
song3 = db.add_to_playlist(PID1, CID3, track_no=3)
|
373
|
-
sid3 = song3.ID
|
374
|
-
db.commit()
|
375
|
-
|
376
|
-
usn_old = db.get_local_usn()
|
377
|
-
mtime_old = db.get_playlist(ID=PID1).updated_at
|
378
|
-
|
379
|
-
# test removing song from playlist
|
380
|
-
db.remove_from_playlist(PID1, sid3)
|
381
|
-
db.commit()
|
382
|
-
|
383
|
-
pl = db.get_playlist(ID=PID1)
|
384
|
-
songs = sorted(pl.Songs, key=lambda x: x.TrackNo)
|
385
|
-
assert len(songs) == 2
|
386
|
-
assert songs[0].ContentID == str(CID1)
|
387
|
-
assert songs[0].TrackNo == 1
|
388
|
-
assert songs[1].ContentID == str(CID2)
|
389
|
-
assert songs[1].TrackNo == 2
|
390
|
-
pl = db.get_playlist(ID=PID1)
|
391
|
-
# Test USN and update time are correct
|
392
|
-
assert pl.updated_at == mtime_old
|
393
|
-
assert db.get_local_usn() == usn_old + 1
|
394
|
-
|
395
|
-
assert _check_playlist_xml(db)
|
396
|
-
|
397
|
-
|
398
|
-
def test_remove_song_from_playlist_middle(db):
|
399
|
-
# Add songs to playlist
|
400
|
-
db.add_to_playlist(PID1, CID1, track_no=1)
|
401
|
-
song2 = db.add_to_playlist(PID1, CID2, track_no=2)
|
402
|
-
db.add_to_playlist(PID1, CID3, track_no=3)
|
403
|
-
sid2 = song2.ID
|
404
|
-
db.commit()
|
405
|
-
usn_old = db.get_local_usn()
|
406
|
-
|
407
|
-
# test removing song from playlist
|
408
|
-
db.remove_from_playlist(PID1, sid2)
|
409
|
-
db.commit()
|
410
|
-
|
411
|
-
pl = db.get_playlist(ID=PID1)
|
412
|
-
songs = sorted(pl.Songs, key=lambda x: x.TrackNo)
|
413
|
-
assert len(songs) == 2
|
414
|
-
assert songs[0].ContentID == str(CID1)
|
415
|
-
assert songs[0].TrackNo == 1
|
416
|
-
assert songs[1].ContentID == str(CID3)
|
417
|
-
assert songs[1].TrackNo == 2
|
418
|
-
|
419
|
-
# Check USN is correct
|
420
|
-
assert db.get_local_usn() == usn_old + 2
|
421
|
-
assert songs[1].rb_local_usn == usn_old + 2
|
422
|
-
|
423
|
-
assert _check_playlist_xml(db)
|
424
|
-
|
425
|
-
|
426
|
-
def test_move_in_playlist_forward(db):
|
427
|
-
# Add songs to playlist
|
428
|
-
s1 = db.add_to_playlist(PID1, CID1)
|
429
|
-
s2 = db.add_to_playlist(PID1, CID2)
|
430
|
-
s3 = db.add_to_playlist(PID1, CID3)
|
431
|
-
s4 = db.add_to_playlist(PID1, CID4)
|
432
|
-
db.commit()
|
433
|
-
pl = db.get_playlist(ID=PID1)
|
434
|
-
songs = sorted(pl.Songs, key=lambda x: x.TrackNo)
|
435
|
-
assert [int(s.ContentID) for s in songs] == [CID1, CID2, CID3, CID4]
|
436
|
-
usn_old = db.get_local_usn()
|
437
|
-
|
438
|
-
# Move song forward
|
439
|
-
db.move_song_in_playlist(PID1, s3, 1)
|
440
|
-
db.commit()
|
441
|
-
pl = db.get_playlist(ID=PID1)
|
442
|
-
songs = sorted(pl.Songs, key=lambda x: x.TrackNo)
|
443
|
-
assert [int(s.ContentID) for s in songs] == [CID3, CID1, CID2, CID4]
|
444
|
-
|
445
|
-
# Check USN
|
446
|
-
expected_usn = usn_old + 1
|
447
|
-
assert db.get_local_usn() == expected_usn
|
448
|
-
assert s1.rb_local_usn == expected_usn
|
449
|
-
assert s2.rb_local_usn == expected_usn
|
450
|
-
assert s3.rb_local_usn == expected_usn
|
451
|
-
assert s4.rb_local_usn == usn_old
|
452
|
-
|
453
|
-
assert _check_playlist_xml(db)
|
454
|
-
|
455
|
-
|
456
|
-
def test_move_in_playlist_backward(db):
|
457
|
-
# Add songs to playlist
|
458
|
-
s1 = db.add_to_playlist(PID1, CID1)
|
459
|
-
s2 = db.add_to_playlist(PID1, CID2)
|
460
|
-
s3 = db.add_to_playlist(PID1, CID3)
|
461
|
-
s4 = db.add_to_playlist(PID1, CID4)
|
462
|
-
db.commit()
|
463
|
-
pl = db.get_playlist(ID=PID1)
|
464
|
-
songs = sorted(pl.Songs, key=lambda x: x.TrackNo)
|
465
|
-
assert [int(s.ContentID) for s in songs] == [CID1, CID2, CID3, CID4]
|
466
|
-
usn_old = db.get_local_usn()
|
467
|
-
|
468
|
-
# Move song backward
|
469
|
-
db.move_song_in_playlist(PID1, s1, 3)
|
470
|
-
db.commit()
|
471
|
-
pl = db.get_playlist(ID=PID1)
|
472
|
-
songs = sorted(pl.Songs, key=lambda x: x.TrackNo)
|
473
|
-
assert [int(s.ContentID) for s in songs] == [CID2, CID3, CID1, CID4]
|
474
|
-
|
475
|
-
# Check USN
|
476
|
-
expected_usn = usn_old + 1
|
477
|
-
assert db.get_local_usn() == expected_usn
|
478
|
-
assert s1.rb_local_usn == expected_usn
|
479
|
-
assert s2.rb_local_usn == expected_usn
|
480
|
-
assert s3.rb_local_usn == expected_usn
|
481
|
-
assert s4.rb_local_usn == usn_old
|
482
|
-
|
483
|
-
assert _check_playlist_xml(db)
|
484
|
-
|
485
|
-
|
486
|
-
def test_create_playlist(db):
|
487
|
-
seqs = [pl.Seq for pl in db.get_playlist()]
|
488
|
-
assert max(seqs) == 2
|
489
|
-
old_usn = db.get_local_usn()
|
490
|
-
|
491
|
-
# Create playlist
|
492
|
-
pl = db.create_playlist("Test playlist")
|
493
|
-
pid = pl.ID
|
494
|
-
db.commit()
|
495
|
-
|
496
|
-
# Check if playlist was created correctly
|
497
|
-
pl = db.get_playlist(ID=pid)
|
498
|
-
assert pl.Name == "Test playlist"
|
499
|
-
assert pl.Seq == 3
|
500
|
-
assert pl.Attribute == 0
|
501
|
-
assert pl.Songs == []
|
502
|
-
assert pl.ParentID == "root"
|
503
|
-
assert pl.Children == []
|
504
|
-
|
505
|
-
# Check USN is correct (+1 for creating, +1 for renaming)
|
506
|
-
assert pl.rb_local_usn == old_usn + 2
|
507
|
-
assert db.get_local_usn() == old_usn + 2
|
508
|
-
|
509
|
-
# Try to add song to playlist
|
510
|
-
db.add_to_playlist(pl, CID1)
|
511
|
-
db.commit()
|
512
|
-
|
513
|
-
pl = db.get_playlist(ID=pid)
|
514
|
-
assert len(pl.Songs) == 1
|
515
|
-
|
516
|
-
# Check if playlist was added to xml
|
517
|
-
plxml = db.playlist_xml.get(pl.ID)
|
518
|
-
assert plxml is not None
|
519
|
-
assert _check_playlist_xml(db)
|
520
|
-
|
521
|
-
|
522
|
-
def test_create_playlist_seq_middle(db):
|
523
|
-
seqs = [pl.Seq for pl in db.get_playlist()]
|
524
|
-
assert max(seqs) == 2
|
525
|
-
old_usn = db.get_local_usn()
|
526
|
-
|
527
|
-
# Create playlist
|
528
|
-
pl = db.create_playlist("playlist1")
|
529
|
-
pid1 = pl.ID
|
530
|
-
assert pl.Seq == 3
|
531
|
-
db.commit()
|
532
|
-
# Check USN is correct (+1 for creating, +1 for renaming)
|
533
|
-
assert pl.rb_local_usn == old_usn + 2
|
534
|
-
assert db.get_local_usn() == old_usn + 2
|
535
|
-
|
536
|
-
old_usn = db.get_local_usn()
|
537
|
-
pl = db.create_playlist("playlist2", seq=3)
|
538
|
-
pid2 = pl.ID
|
539
|
-
db.commit()
|
540
|
-
|
541
|
-
pl1 = db.get_playlist(ID=pid1)
|
542
|
-
pl2 = db.get_playlist(ID=pid2)
|
543
|
-
assert pl1.Seq == 4
|
544
|
-
assert pl2.Seq == 3
|
545
|
-
# Check USN is correct
|
546
|
-
assert db.get_local_usn() == old_usn + 3 # +2 for creating, +1 for moving others
|
547
|
-
assert pl1.rb_local_usn == old_usn + 1
|
548
|
-
assert pl2.rb_local_usn == old_usn + 3
|
549
|
-
|
550
|
-
assert _check_playlist_xml(db)
|
551
|
-
|
552
|
-
|
553
|
-
def test_create_playlist_folder(db):
|
554
|
-
seqs = [pl.Seq for pl in db.get_playlist()]
|
555
|
-
assert max(seqs) == 2
|
556
|
-
usn_old = db.get_local_usn()
|
557
|
-
|
558
|
-
# Create playlist
|
559
|
-
pl = db.create_playlist_folder("Test playlist folder")
|
560
|
-
pid = pl.ID
|
561
|
-
db.commit()
|
562
|
-
|
563
|
-
# Check if playlist folder was created correctly
|
564
|
-
pl = db.get_playlist(ID=pid)
|
565
|
-
assert pl.Name == "Test playlist folder"
|
566
|
-
assert pl.Seq == 3
|
567
|
-
assert pl.Attribute == 1
|
568
|
-
assert pl.Songs == []
|
569
|
-
assert pl.ParentID == "root"
|
570
|
-
assert pl.Children == []
|
571
|
-
# Check USN is correct (+1 for creating, +1 for renaming)
|
572
|
-
assert db.get_local_usn() == usn_old + 2
|
573
|
-
assert pl.rb_local_usn == usn_old + 2
|
574
|
-
|
575
|
-
# Try to add sub-playlist to playlist folder
|
576
|
-
db.create_playlist("Test playlist", parent=pl)
|
577
|
-
db.commit()
|
578
|
-
|
579
|
-
pl = db.get_playlist(ID=pid)
|
580
|
-
assert len(pl.Children) == 1
|
581
|
-
|
582
|
-
assert _check_playlist_xml(db)
|
583
|
-
|
584
|
-
|
585
|
-
def test_delete_playlist_empty_end(db):
|
586
|
-
# Create playlist structure
|
587
|
-
folder = db.create_playlist_folder("folder")
|
588
|
-
pl1 = db.create_playlist("sub playlist 1", parent=folder.ID)
|
589
|
-
pl2 = db.create_playlist("sub playlist 2", parent=folder.ID)
|
590
|
-
pl3 = db.create_playlist("sub playlist 3", parent=folder.ID)
|
591
|
-
assert pl1.Seq == 1 and pl2.Seq == 2 and pl3.Seq == 3
|
592
|
-
db.commit()
|
593
|
-
usn_old = db.get_local_usn()
|
594
|
-
|
595
|
-
# Delete playlist
|
596
|
-
pl = db.get_playlist(Name="sub playlist 3").one()
|
597
|
-
pid = pl.ID
|
598
|
-
db.delete_playlist(pl)
|
599
|
-
db.commit()
|
600
|
-
|
601
|
-
# Check if playlist was deleted
|
602
|
-
pl = db.get_playlist(ID=pid)
|
603
|
-
assert pl is None
|
604
|
-
# Check if playlist was deleted from xml
|
605
|
-
plxml = db.playlist_xml.get(pid)
|
606
|
-
assert plxml is None
|
607
|
-
# Check USN is correct (+1 for deleting)
|
608
|
-
assert db.get_local_usn() == usn_old + 1
|
609
|
-
|
610
|
-
assert _check_playlist_xml(db)
|
611
|
-
assert _check_playlist_xml_delete(db)
|
612
|
-
|
613
|
-
|
614
|
-
def test_delete_playlist_empty(db):
|
615
|
-
# Create playlist structure
|
616
|
-
folder = db.create_playlist_folder("folder")
|
617
|
-
pl1 = db.create_playlist("sub playlist 1", parent=folder.ID)
|
618
|
-
pl2 = db.create_playlist("sub playlist 2", parent=folder.ID)
|
619
|
-
pl3 = db.create_playlist("sub playlist 3", parent=folder.ID)
|
620
|
-
assert pl1.Seq == 1 and pl2.Seq == 2 and pl3.Seq == 3
|
621
|
-
db.commit()
|
622
|
-
usn_old = db.get_local_usn()
|
623
|
-
|
624
|
-
# Delete playlist
|
625
|
-
pl = db.get_playlist(Name="sub playlist 2").one()
|
626
|
-
pid = pl.ID
|
627
|
-
db.delete_playlist(pl)
|
628
|
-
db.commit()
|
629
|
-
|
630
|
-
# Check if playlist was deleted
|
631
|
-
pl = db.get_playlist(ID=pid)
|
632
|
-
assert pl is None
|
633
|
-
# Check if playlist was deleted from xml
|
634
|
-
plxml = db.playlist_xml.get(pid)
|
635
|
-
assert plxml is None
|
636
|
-
# Check USN is correct (+1 for deleting, all moved playlists get same USN)
|
637
|
-
assert db.get_local_usn() == usn_old + 1
|
638
|
-
# Check if seq numbers in parent were updated
|
639
|
-
pl = db.get_playlist(Name="sub playlist 3").one()
|
640
|
-
assert pl.Seq == 2
|
641
|
-
assert pl.rb_local_usn == usn_old + 1
|
642
|
-
|
643
|
-
assert _check_playlist_xml(db)
|
644
|
-
assert _check_playlist_xml_delete(db)
|
645
|
-
|
646
|
-
|
647
|
-
def test_delete_playlist_folder_empty(db):
|
648
|
-
# Create playlist structure
|
649
|
-
folder = db.create_playlist_folder("folder")
|
650
|
-
pl1 = db.create_playlist("sub playlist 1", parent=folder.ID)
|
651
|
-
pl2 = db.create_playlist_folder("sub playlist folder", parent=folder.ID)
|
652
|
-
pl3 = db.create_playlist("sub playlist 3", parent=folder.ID)
|
653
|
-
assert pl1.Seq == 1 and pl2.Seq == 2 and pl3.Seq == 3
|
654
|
-
db.commit()
|
655
|
-
usn_old = db.get_local_usn()
|
656
|
-
|
657
|
-
# Delete playlist
|
658
|
-
pl = db.get_playlist(Name="sub playlist folder").one()
|
659
|
-
pid = pl.ID
|
660
|
-
db.delete_playlist(pl)
|
661
|
-
db.commit()
|
662
|
-
|
663
|
-
# Check if playlist was deleted
|
664
|
-
pl = db.get_playlist(ID=pid)
|
665
|
-
assert pl is None
|
666
|
-
# Check if playlist was deleted from xml
|
667
|
-
plxml = db.playlist_xml.get(pid)
|
668
|
-
assert plxml is None
|
669
|
-
# Check if seq numbers in parent were updated
|
670
|
-
pl = db.get_playlist(Name="sub playlist 3").one()
|
671
|
-
assert pl.Seq == 2
|
672
|
-
# Check USN is correct (+1 for deleting)
|
673
|
-
assert db.get_local_usn() == usn_old + 1
|
674
|
-
assert pl.rb_local_usn == usn_old + 1
|
675
|
-
|
676
|
-
assert _check_playlist_xml(db)
|
677
|
-
assert _check_playlist_xml_delete(db)
|
678
|
-
|
679
|
-
|
680
|
-
def test_delete_playlist_non_empty(db):
|
681
|
-
# Create playlist structure
|
682
|
-
folder = db.create_playlist_folder("folder")
|
683
|
-
pl1 = db.create_playlist("sub playlist 1", parent=folder.ID)
|
684
|
-
pl2 = db.create_playlist("sub playlist 2", parent=folder.ID)
|
685
|
-
pl3 = db.create_playlist("sub playlist 3", parent=folder.ID)
|
686
|
-
# Add songs to playlists
|
687
|
-
sid1 = db.add_to_playlist(pl1, CID1).ID
|
688
|
-
sid2 = db.add_to_playlist(pl2, CID2).ID
|
689
|
-
sid3 = db.add_to_playlist(pl2, CID3).ID
|
690
|
-
sid4 = db.add_to_playlist(pl3, CID4).ID
|
691
|
-
db.commit()
|
692
|
-
usn_old = db.get_local_usn()
|
693
|
-
|
694
|
-
assert db.query(tables.DjmdSongPlaylist).count() == 4
|
695
|
-
|
696
|
-
# Delete playlist
|
697
|
-
pl = db.get_playlist(Name="sub playlist 2").one()
|
698
|
-
pid = pl.ID
|
699
|
-
db.delete_playlist(pl)
|
700
|
-
db.commit()
|
701
|
-
|
702
|
-
# Check if playlist was deleted
|
703
|
-
pl = db.get_playlist(ID=pid)
|
704
|
-
assert pl is None
|
705
|
-
# Check if songs in playlist were deleted
|
706
|
-
assert db.query(tables.DjmdSongPlaylist).count() == 2
|
707
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid1).count() == 1
|
708
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid2).count() == 0
|
709
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid3).count() == 0
|
710
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid4).count() == 1
|
711
|
-
# Check if USN is correct (+1 for deleting with contents)
|
712
|
-
assert db.get_local_usn() == usn_old + 1
|
713
|
-
|
714
|
-
assert _check_playlist_xml(db)
|
715
|
-
assert _check_playlist_xml_delete(db)
|
716
|
-
|
717
|
-
|
718
|
-
def test_delete_playlist_folder_non_empty(db):
|
719
|
-
# Create playlist structure
|
720
|
-
folder = db.create_playlist_folder("folder")
|
721
|
-
pl1 = db.create_playlist("sub playlist 1", parent=folder.ID)
|
722
|
-
folder2 = db.create_playlist_folder("sub playlist folder", parent=folder.ID)
|
723
|
-
pl2 = db.create_playlist("sub sub playlist", parent=folder2.ID)
|
724
|
-
pl3 = db.create_playlist("sub playlist 3", parent=folder.ID)
|
725
|
-
# Add songs to playlists
|
726
|
-
sid1 = db.add_to_playlist(pl1, CID1).ID
|
727
|
-
sid2 = db.add_to_playlist(pl2, CID2).ID
|
728
|
-
sid3 = db.add_to_playlist(pl2, CID3).ID
|
729
|
-
sid4 = db.add_to_playlist(pl3, CID4).ID
|
730
|
-
db.commit()
|
731
|
-
usn_old = db.get_local_usn()
|
732
|
-
|
733
|
-
assert db.query(tables.DjmdSongPlaylist).count() == 4
|
734
|
-
|
735
|
-
# Delete playlist
|
736
|
-
pl = db.get_playlist(Name="sub playlist folder").one()
|
737
|
-
pid = pl.ID
|
738
|
-
|
739
|
-
pid2 = db.get_playlist(Name="sub sub playlist").one().ID
|
740
|
-
|
741
|
-
db.delete_playlist(pl)
|
742
|
-
db.commit()
|
743
|
-
|
744
|
-
# Check if playlists were deleted
|
745
|
-
pl = db.get_playlist(ID=pid)
|
746
|
-
assert pl is None
|
747
|
-
pl = db.get_playlist(ID=pid2)
|
748
|
-
assert pl is None
|
749
|
-
# Check if songs in playlist were deleted
|
750
|
-
assert db.query(tables.DjmdSongPlaylist).count() == 2
|
751
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid1).count() == 1
|
752
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid2).count() == 0
|
753
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid3).count() == 0
|
754
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid4).count() == 1
|
755
|
-
|
756
|
-
# Check if USN is correct (+1 for deleting with Seq update, +1 for children)
|
757
|
-
assert db.get_local_usn() == usn_old + 2
|
758
|
-
|
759
|
-
assert _check_playlist_xml(db)
|
760
|
-
assert _check_playlist_xml_delete(db)
|
761
|
-
|
762
|
-
|
763
|
-
def test_delete_playlist_folder_chained(db):
|
764
|
-
# Create playlist structure
|
765
|
-
folder = db.create_playlist_folder("folder")
|
766
|
-
subfolder1 = db.create_playlist_folder("subfolder", parent=folder.ID)
|
767
|
-
subfolder2 = db.create_playlist_folder("subsubfolder", parent=subfolder1.ID)
|
768
|
-
subfolder3 = db.create_playlist_folder("subsubsubfolder", parent=subfolder2.ID)
|
769
|
-
pl1 = db.create_playlist("sub playlist 1", parent=subfolder2.ID)
|
770
|
-
pl2 = db.create_playlist("sub playlist 2", parent=subfolder3.ID)
|
771
|
-
|
772
|
-
pid1 = folder.ID
|
773
|
-
pid2 = subfolder1.ID
|
774
|
-
pid3 = subfolder2.ID
|
775
|
-
pid4 = subfolder3.ID
|
776
|
-
pid5 = pl1.ID
|
777
|
-
pid6 = pl2.ID
|
778
|
-
|
779
|
-
# Add songs to playlists
|
780
|
-
sid1 = db.add_to_playlist(pl1, CID1).ID
|
781
|
-
sid2 = db.add_to_playlist(pl1, CID2).ID
|
782
|
-
sid3 = db.add_to_playlist(pl2, CID3).ID
|
783
|
-
sid4 = db.add_to_playlist(pl2, CID4).ID
|
784
|
-
|
785
|
-
db.commit()
|
786
|
-
usn_old = db.get_local_usn()
|
787
|
-
|
788
|
-
db.delete_playlist(folder)
|
789
|
-
db.commit()
|
790
|
-
|
791
|
-
# Check if all playlists and songs were deleted
|
792
|
-
assert db.get_playlist(ID=pid1) is None
|
793
|
-
assert db.get_playlist(ID=pid2) is None
|
794
|
-
assert db.get_playlist(ID=pid3) is None
|
795
|
-
assert db.get_playlist(ID=pid5) is None
|
796
|
-
assert db.get_playlist(ID=pid4) is None
|
797
|
-
assert db.get_playlist(ID=pid6) is None
|
798
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid1).count() == 0
|
799
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid2).count() == 0
|
800
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid3).count() == 0
|
801
|
-
assert db.query(tables.DjmdSongPlaylist).filter_by(ID=sid4).count() == 0
|
802
|
-
|
803
|
-
# Check all the corresponding xml entries were deleted
|
804
|
-
assert db.playlist_xml.get(pid1) is None
|
805
|
-
assert db.playlist_xml.get(pid2) is None
|
806
|
-
assert db.playlist_xml.get(pid3) is None
|
807
|
-
assert db.playlist_xml.get(pid4) is None
|
808
|
-
assert db.playlist_xml.get(pid5) is None
|
809
|
-
assert db.playlist_xml.get(pid6) is None
|
810
|
-
|
811
|
-
# Check if USN is correct (+1 for deleting with Seq update, +1 for children)
|
812
|
-
assert db.get_local_usn() == usn_old + 2
|
813
|
-
|
814
|
-
assert _check_playlist_xml(db)
|
815
|
-
assert _check_playlist_xml_delete(db)
|
816
|
-
|
817
|
-
|
818
|
-
def test_move_playlist_seq(db):
|
819
|
-
# Create playlist structure
|
820
|
-
folder = db.create_playlist_folder("folder")
|
821
|
-
f1 = db.create_playlist_folder("f 1", parent=folder)
|
822
|
-
_ = db.create_playlist_folder("f 2", parent=folder)
|
823
|
-
db.create_playlist("pl 1", parent=folder)
|
824
|
-
db.create_playlist("pl 2", parent=folder)
|
825
|
-
db.create_playlist("pl 3", parent=folder)
|
826
|
-
db.create_playlist("pl 4", parent=folder)
|
827
|
-
db.create_playlist("sub pl 1", parent=f1)
|
828
|
-
db.create_playlist("sub pl 2", parent=f1)
|
829
|
-
db.create_playlist("sub pl 3", parent=f1)
|
830
|
-
db.create_playlist("sub pl 4", parent=f1)
|
831
|
-
db.commit()
|
832
|
-
|
833
|
-
playlists = db.get_playlist(ParentID=folder.ID).order_by(tables.DjmdPlaylist.Seq)
|
834
|
-
expected = ["f 1", "f 2", "pl 1", "pl 2", "pl 3", "pl 4"]
|
835
|
-
assert [p.Name for p in playlists] == expected
|
836
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4, 5, 6]
|
837
|
-
|
838
|
-
playlists = db.get_playlist(ParentID=f1.ID).order_by(tables.DjmdPlaylist.Seq)
|
839
|
-
expected = ["sub pl 1", "sub pl 2", "sub pl 3", "sub pl 4"]
|
840
|
-
assert [p.Name for p in playlists] == expected
|
841
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4]
|
842
|
-
|
843
|
-
usn_old = db.get_local_usn()
|
844
|
-
# Move playlist 1 to position 5
|
845
|
-
pl = db.get_playlist(Name="pl 1").one()
|
846
|
-
mtime_old = pl.updated_at
|
847
|
-
db.move_playlist(pl, seq=5)
|
848
|
-
db.commit()
|
849
|
-
|
850
|
-
playlists = db.get_playlist(ParentID=folder.ID).order_by(tables.DjmdPlaylist.Seq)
|
851
|
-
expected = ["f 1", "f 2", "pl 2", "pl 3", "pl 1", "pl 4"]
|
852
|
-
assert [p.Name for p in playlists] == expected
|
853
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4, 5, 6]
|
854
|
-
# Check that the usn and update time was updated correctly
|
855
|
-
# First the moved playlist USN is set, then the other updated playlists
|
856
|
-
# in the seq order
|
857
|
-
pl1 = db.get_playlist(Name="pl 1").one()
|
858
|
-
pl2 = db.get_playlist(Name="pl 2").one()
|
859
|
-
pl3 = db.get_playlist(Name="pl 3").one()
|
860
|
-
assert db.get_local_usn() == usn_old + 3
|
861
|
-
assert pl1.rb_local_usn == usn_old + 1
|
862
|
-
assert pl2.rb_local_usn == usn_old + 2
|
863
|
-
assert pl3.rb_local_usn == usn_old + 3
|
864
|
-
assert pl1.updated_at > mtime_old
|
865
|
-
assert pl2.updated_at > mtime_old
|
866
|
-
assert pl3.updated_at > mtime_old
|
867
|
-
|
868
|
-
usn_old = db.get_local_usn()
|
869
|
-
# Move playlist 3 to position 2
|
870
|
-
pl = db.get_playlist(Name="pl 3").one()
|
871
|
-
mtime_old = pl.updated_at
|
872
|
-
db.move_playlist(pl, seq=2)
|
873
|
-
db.commit()
|
874
|
-
|
875
|
-
playlists = db.get_playlist(ParentID=folder.ID).order_by(tables.DjmdPlaylist.Seq)
|
876
|
-
expected = ["f 1", "pl 3", "f 2", "pl 2", "pl 1", "pl 4"]
|
877
|
-
assert [p.Name for p in playlists] == expected
|
878
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4, 5, 6]
|
879
|
-
# Check that the usn and update time was updated correctly
|
880
|
-
# First the moved playlist USN is set, then the other updated playlists
|
881
|
-
# in the seq order
|
882
|
-
pl2 = db.get_playlist(Name="pl 2").one()
|
883
|
-
pl3 = db.get_playlist(Name="pl 3").one()
|
884
|
-
f2 = db.get_playlist(Name="f 2").one()
|
885
|
-
assert db.get_local_usn() == usn_old + 3
|
886
|
-
assert pl3.rb_local_usn == usn_old + 1
|
887
|
-
assert f2.rb_local_usn == usn_old + 2
|
888
|
-
assert pl2.rb_local_usn == usn_old + 3
|
889
|
-
assert pl2.updated_at > mtime_old
|
890
|
-
assert pl3.updated_at > mtime_old
|
891
|
-
assert f2.updated_at > mtime_old
|
892
|
-
|
893
|
-
assert _check_playlist_xml(db)
|
894
|
-
|
895
|
-
|
896
|
-
def test_move_playlist_parent(db):
|
897
|
-
# Create playlist structure
|
898
|
-
folder = db.create_playlist_folder("folder")
|
899
|
-
f1 = db.create_playlist_folder("f 1", parent=folder)
|
900
|
-
_ = db.create_playlist_folder("f 2", parent=folder)
|
901
|
-
db.create_playlist("pl 1", parent=folder)
|
902
|
-
db.create_playlist("pl 2", parent=folder)
|
903
|
-
db.create_playlist("pl 3", parent=folder)
|
904
|
-
db.create_playlist("pl 4", parent=folder)
|
905
|
-
db.create_playlist("sub pl 1", parent=f1)
|
906
|
-
db.create_playlist("sub pl 2", parent=f1)
|
907
|
-
db.create_playlist("sub pl 3", parent=f1)
|
908
|
-
db.create_playlist("sub pl 4", parent=f1)
|
909
|
-
db.commit()
|
910
|
-
|
911
|
-
playlists = db.get_playlist(ParentID=folder.ID).order_by(tables.DjmdPlaylist.Seq)
|
912
|
-
expected = ["f 1", "f 2", "pl 1", "pl 2", "pl 3", "pl 4"]
|
913
|
-
assert [p.Name for p in playlists] == expected
|
914
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4, 5, 6]
|
915
|
-
|
916
|
-
playlists = db.get_playlist(ParentID=f1.ID).order_by(tables.DjmdPlaylist.Seq)
|
917
|
-
expected = ["sub pl 1", "sub pl 2", "sub pl 3", "sub pl 4"]
|
918
|
-
assert [p.Name for p in playlists] == expected
|
919
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4]
|
920
|
-
|
921
|
-
# Move playlist 1 to sub playlist (at the end)
|
922
|
-
old_usn = db.get_local_usn()
|
923
|
-
pl = db.get_playlist(Name="pl 1").one()
|
924
|
-
old_mtime = pl.updated_at
|
925
|
-
db.move_playlist(pl, parent=f1)
|
926
|
-
db.commit()
|
927
|
-
|
928
|
-
playlists = db.get_playlist(ParentID=folder.ID).order_by(tables.DjmdPlaylist.Seq)
|
929
|
-
expected = ["f 1", "f 2", "pl 2", "pl 3", "pl 4"]
|
930
|
-
assert [p.Name for p in playlists] == expected
|
931
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4, 5]
|
932
|
-
playlists = db.get_playlist(ParentID=f1.ID).order_by(tables.DjmdPlaylist.Seq)
|
933
|
-
expected = ["sub pl 1", "sub pl 2", "sub pl 3", "sub pl 4", "pl 1"]
|
934
|
-
assert [p.Name for p in playlists] == expected
|
935
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4, 5]
|
936
|
-
|
937
|
-
# Check that the usn and update time was updated correctly
|
938
|
-
pl = db.get_playlist(Name="pl 1").one()
|
939
|
-
assert db.get_local_usn() == old_usn + 1
|
940
|
-
assert pl.rb_local_usn == old_usn + 1
|
941
|
-
assert pl.updated_at > old_mtime
|
942
|
-
|
943
|
-
# Move playlist 2 to sub playlist
|
944
|
-
old_usn = db.get_local_usn()
|
945
|
-
pl = db.get_playlist(Name="pl 2").one()
|
946
|
-
old_mtime = pl.updated_at
|
947
|
-
db.move_playlist(pl, seq=2, parent=f1)
|
948
|
-
db.commit()
|
949
|
-
|
950
|
-
playlists = db.get_playlist(ParentID=folder.ID).order_by(tables.DjmdPlaylist.Seq)
|
951
|
-
expected = ["f 1", "f 2", "pl 3", "pl 4"]
|
952
|
-
assert [p.Name for p in playlists] == expected
|
953
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4]
|
954
|
-
playlists = db.get_playlist(ParentID=f1.ID).order_by(tables.DjmdPlaylist.Seq)
|
955
|
-
expected = ["sub pl 1", "pl 2", "sub pl 2", "sub pl 3", "sub pl 4", "pl 1"]
|
956
|
-
assert [p.Name for p in playlists] == expected
|
957
|
-
assert [pl.Seq for pl in playlists] == [1, 2, 3, 4, 5, 6]
|
958
|
-
# Check that the usn and update time was updated correctly
|
959
|
-
_ = db.get_playlist(Name="sub pl 1").one()
|
960
|
-
subpl2 = db.get_playlist(Name="sub pl 2").one()
|
961
|
-
subpl3 = db.get_playlist(Name="sub pl 3").one()
|
962
|
-
subpl4 = db.get_playlist(Name="sub pl 4").one()
|
963
|
-
pl1 = db.get_playlist(Name="pl 1").one()
|
964
|
-
pl = db.get_playlist(Name="pl 2").one()
|
965
|
-
assert db.get_local_usn() == old_usn + 5
|
966
|
-
assert pl.rb_local_usn == old_usn + 1
|
967
|
-
assert pl.updated_at > old_mtime
|
968
|
-
assert subpl2.rb_local_usn == old_usn + 2
|
969
|
-
assert subpl3.rb_local_usn == old_usn + 3
|
970
|
-
assert subpl4.rb_local_usn == old_usn + 4
|
971
|
-
assert pl1.rb_local_usn == old_usn + 5
|
972
|
-
|
973
|
-
assert _check_playlist_xml(db)
|
974
|
-
|
975
|
-
|
976
|
-
def test_rename_playlist(db):
|
977
|
-
# Create playlist structure
|
978
|
-
folder = db.create_playlist_folder("folder")
|
979
|
-
db.create_playlist("pl 1", parent=folder)
|
980
|
-
db.create_playlist("pl 2", parent=folder)
|
981
|
-
db.commit()
|
982
|
-
|
983
|
-
pl = db.get_playlist(Name="pl 1").one()
|
984
|
-
pid = pl.ID
|
985
|
-
mtime_old = pl.updated_at
|
986
|
-
usn_old = db.get_local_usn()
|
987
|
-
|
988
|
-
# Rename playlist
|
989
|
-
db.rename_playlist(pl, "pl 1 new")
|
990
|
-
db.commit()
|
991
|
-
|
992
|
-
pl = db.get_playlist(ID=pid)
|
993
|
-
assert pl.Name == "pl 1 new"
|
994
|
-
assert pl.updated_at > mtime_old
|
995
|
-
assert db.get_local_usn() == usn_old + 1
|
996
|
-
assert pl.rb_local_usn == usn_old + 1
|
997
|
-
|
998
|
-
assert _check_playlist_xml(db)
|
999
|
-
|
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
|
-
|
1079
|
-
def test_get_anlz_paths():
|
1080
|
-
content = DB.get_content().first()
|
1081
|
-
|
1082
|
-
anlz_dir = str(DB.get_anlz_dir(content)).replace("\\", "/")
|
1083
|
-
expected = r"share/PIONEER/USBANLZ/735/e8b81-e69b-41ad-80f8-9c0d7613b96d"
|
1084
|
-
assert anlz_dir.endswith(expected)
|
1085
|
-
|
1086
|
-
|
1087
|
-
def test_to_json():
|
1088
|
-
# Check if saving to json works
|
1089
|
-
|
1090
|
-
tmp = tempfile.NamedTemporaryFile(delete=False)
|
1091
|
-
try:
|
1092
|
-
DB.to_json(tmp.name)
|
1093
|
-
finally:
|
1094
|
-
tmp.close()
|
1095
|
-
os.remove(tmp.name)
|
1096
|
-
|
1097
|
-
|
1098
|
-
def test_copy_unlocked():
|
1099
|
-
db = Rekordbox6Database(UNLOCKED, unlock=False)
|
1100
|
-
db.copy_unlocked(UNLOCKED_OUT)
|
1101
|
-
|
1102
|
-
db2 = Rekordbox6Database(UNLOCKED_OUT, unlock=False)
|
1103
|
-
# Check everything got copied
|
1104
|
-
for name in tables.TABLES:
|
1105
|
-
table = getattr(tables, name)
|
1106
|
-
for row in db.query(table):
|
1107
|
-
data = row.to_dict()
|
1108
|
-
if name == "AgentRegistry":
|
1109
|
-
query = db2.query(table).filter_by(registry_id=row.registry_id)
|
1110
|
-
elif name == "DjmdProperty":
|
1111
|
-
query = db2.query(table).filter_by(DBID=row.DBID)
|
1112
|
-
else:
|
1113
|
-
query = db2.query(table).filter_by(ID=row.ID)
|
1114
|
-
data2 = query.one().to_dict()
|
1115
|
-
assert data == data2
|