Collections¶
The Traktor service implements the standard collection interfaces that are common across all plistsync services. By inheriting from the base classes and conforming to the established protocols.
Locate you traktor library¶
plistsync reads Traktor’s NML library/playlist files (usually named collection.nml).
Common default locations (may vary by Traktor version and your settings):
macOS
~/Music/Traktor/collection.nml~/Documents/Native Instruments/Traktor */collection.nml
Windows
C:\Users\<you>\Documents\Native Instruments\Traktor *\collection.nml
If you’re unsure, search your disk for collection.nml.
Option A: Use your live Traktor library file (recommended)¶
Point plistsync at your existing collection.nml. Always make a backup before writing.
Option B: Export an NML from Traktor¶
If you don’t want to touch your live library, export a playlist/collection from Traktor to an .nml file and use that exported file as input.
Library¶
The NMLLibrary represents the Traktor library stored in an NML file. It provides:
Streaming access to all tracks in the Traktor collection (
.tracks)Lookup by local identifiers (currently: file path) via
LocalLookupAccess to playlists contained in the NML via
.playlists/.get_playlist(...)
from plistsync.services.traktor import NMLLibrary
library = NMLLibrary(path="/Users/paul/Music/Traktor/collection.nml")
Note
To persist changes to disk, make sure to call the library.write() method on the associated NMLLibrary.
Track Lookup¶
The Traktor library collections implements the LocalLookup protocol, allowing you to search for tracks in a *.nml collection. Currently, we only support lookup by path (because id’s that can be used well for syncing, like isrcs are not stored in the nml, and we have not built file-based lookup yet).
Note that in the example we use PurePaths, because the traktor library does not need (or do) any actual filesystem access. You can also use Path objects, but our api will usually return PurePath.
from pathlib import PurePath, PurePosixPath, PureWindowsPath
path: PurePath = PureWindowsPath(
r"D:\SYNC\library\Amoss, Fre4knc\Watermark Volume 2\04 Dragger [1028kbps].flac"
)
path = PurePosixPath(
r"/Volumes/Traktor/clean/Amoss, Fre4knc/Watermark Volume 2/04 Dragger [1028kbps].flac"
)
if track1 := library.find_by_local_ids({"file_path": path}):
print(track1)
Playlist¶
Before creating playlists, note that you manually have to write your library to make changes persistent, as shown at the end of the notebook.
The NMLPlaylist represents a playlist in the traktor collection.
Retrieving playlists¶
You can retrieve all playlists saved in a collection using the library’s NMLLibrary.playlists property.
playlists = library.playlists
for playlist in playlists:
print(f"Playlist: {playlist.name} ({len(playlist)} tracks)")
If you just want a specific playlist, you can use the library’s NMLLibrary.get_playlist method to retrieve a playlist.
pl = library.get_playlist(
name="plistsync"
# uuid = "6868ecd66b354d37a33b965dae7a82e7"
)
if pl is not None:
print(f"Found playlist: {pl.name} ({len(pl)} tracks)")
else:
print("Playlist not found.")
Found playlist: plistsync (5 tracks)
Note
This method supports lookup by name= or uuid=.
Creating playlists¶
Use {py.class}NMLPlaylist <plistsync.services.traktor.NMLPlaylist> to model a playlist locally. For now, plistsync needs every traktor playlist to be associate with an nml collection.
pl = library.create_playlist(
name="New playlist",
description="Created with plistsync",
)
Updating a playlist¶
For updating a playlist, you should use the playlist’s NMLPlaylist.edit context manager. This ensures that all changes are properly saved back to Tidal when you exit the context. This also minifies changes and therefore reduces API calls.
# Updating a playlist description/name
with pl.edit():
pl.description = "Updated description"
pl.description
You can add tracks to a playlist using the same context manager, again this will add the tracks when you exit the context.
from plistsync.services.traktor import NMLPlaylistTrack
# Add a track to the playlist
new_track = library.find_by_local_ids({"file_path": path})
assert new_track is not None
with pl.edit():
# TODO: We should reevaluate the type hierarchy here.
# for now, we have to manually cast PlaylistTrack to NMLPlaylistTrack.
# this will become more convenient, eventually.
pl.tracks.append(NMLPlaylistTrack.from_track(new_track))
pl.tracks.append(NMLPlaylistTrack.from_track(new_track))
To reorder tracks in a playlist, you can change the order of the NMLPlaylist.tracks list within the context manager.
with pl.edit():
pl.tracks.insert(0, pl.tracks.pop())
As an alternative to the with pl.edit() context manager, you can also use the NMLPlaylist.update method to update the playlist in the collection with the current state.
pl.update()
Deleting a playlist¶
Similarly to delete a playlist in the collection you can call the NMLPlaylist.delete method to update the playlist in the collection with the current state or create it if it does not exist yet.
Do not keep using the pl object after calling its delete method, as this will lead to unpredictable behaviour.
pl.delete()
OfflinePlaylist(name='plistsync', tracks=5)
Persisting Changes¶
Because Traktor’s library is just an xml file on disk, you have to call NMLLibrary.write to make any of the above changes take effect.
We deliberately decided to make this a manual step to provide you with control when to commit.
Note that the method has a backup option. By default we read it from your config, but you can set it manually:
library.write(backup=True)