Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
08658ed
Added PlaylistIds dict and adjusted docstring
semohr Apr 3, 2026
53b4cb7
Added offlineplaylist class (seems to be quite simple now).
semohr Apr 3, 2026
ffc9cf4
Redefining abstraction for service level playlists.
semohr Apr 3, 2026
e130c08
Adjusted core playlist tests for new hierarchy.
semohr Apr 4, 2026
1bbbb5f
Migrated spotify to use new abstraction.
semohr Apr 4, 2026
351cfe6
Migrated tidal to use new abstraction.
semohr Apr 4, 2026
8bbe869
Migrated plex to use new abstraction.
semohr Apr 4, 2026
5fafb7f
Migrated traktor playlist.
semohr Apr 4, 2026
551ebe3
Fixed plex tests.
semohr Apr 4, 2026
5f8bf1c
Fixed traktor tests.
semohr Apr 4, 2026
fc0e4b6
Fixed/Aligned spotify tests
semohr Apr 4, 2026
32fa64b
Fixed tidal tests.
semohr Apr 4, 2026
f8ca416
Fixed mock playlists.
semohr Apr 4, 2026
a3bd36d
Left some comments, pretty neat overall!
pSpitzner Apr 5, 2026
6fb1fee
Left some responses to the comments.
semohr Apr 5, 2026
c169d1c
Renamed:
semohr Apr 5, 2026
d72f917
Fixed circular import.
semohr Apr 6, 2026
b273d97
Fixed tests.
semohr Apr 6, 2026
078d25e
fix for spotify playlist length and lazy track loading
pSpitzner Apr 7, 2026
e1ffbee
Renaming: Removed `Collection` Suffix from Spotify Library and Playlist
pSpitzner Apr 7, 2026
f30bfd5
Updated spotify collection docs
pSpitzner Apr 7, 2026
e60e1ea
Renaming: Removed `Collection` Suffix from Tidal Library and Playlist
pSpitzner Apr 7, 2026
25f8457
Fix: tidal faster lookup of len(playlist), same as for spotify earlier
pSpitzner Apr 7, 2026
9ba6876
Updated tidal collection docs
pSpitzner Apr 7, 2026
4da4df0
fix playlist len for plex
pSpitzner Apr 7, 2026
9b4d738
Updated plex collection docs
pSpitzner Apr 7, 2026
f812605
Renaming: Removed `Collection` Suffix from Plex Library and Playlist,
pSpitzner Apr 7, 2026
4dede81
Updated traktor collection docs
pSpitzner Apr 7, 2026
bc9db09
Renaming: Removed `Collection` Suffix from Traktor Library and Playlist,
pSpitzner Apr 7, 2026
02c116c
Updated remaining (community) examples
pSpitzner Apr 7, 2026
4261d8d
Ruff
pSpitzner Apr 7, 2026
68cc186
stripout and fixed doc formatting
semohr Apr 8, 2026
0e6a99a
Removed now unused PlaylistAssociationError.
semohr Apr 8, 2026
e21d5f4
Enhanced changelog
semohr Apr 8, 2026
c50f8c5
Fixed some more renaming leftovers and typos.
pSpitzner Apr 8, 2026
6f04aeb
ignore renaming commits in blame
pSpitzner Apr 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@
# Nbstripout
12c56d5dcdd2695d3155720ebcc74c177cb78ece
# Split collection into library and playlist
9bfa3ae3cfd898b30b5f4266dab05e036d8922f8
9bfa3ae3cfd898b30b5f4266dab05e036d8922f8
# Large rename, removing collection suffix from playlist and library
c50f8c5f3e990cf7411da67ef9836795ade1cbcf
4261d8dee78e9148707480d4be77b697fe811e02
bc9db09be00eb6afeb6317038be9a7e2db9d6e5f
f81260544937fbfabe2f7ca7a8f6f6efe5378244
e60e1ea0c23fa6bdd60452739403f1f6660bbc1c
e1ffbee2263c377d1c410c891a8261d22db16f2b
56 changes: 53 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,65 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Upcoming

### Breaking Changes

#### Playlist Class Hierarchy Refactor

The playlist class hierarchy has been redesigned for clearer separation of concerns:

**Renamed Classes:**
- `PlaylistCollection` → `Playlist` (base protocol)
- `SpotifyPlaylistCollection` → `SpotifyPlaylist`
- `TidalPlaylistCollection` → `TidalPlaylist`
- `PlexPlaylistCollection` → `PlexPlaylist`
- `NMLPlaylistCollection` → `NMLPlaylist`

**Library Classes Renamed:**
- `SpotifyLibraryCollection` → `SpotifyLibrary`
- `TidalLibraryCollection` → `TidalLibrary`
- `PlexLibrarySectionCollection` → `PlexLibrary`
- `NMLLibraryCollection` → `NMLLibrary`

**New Abstractions:**
- `OfflinePlaylist` — In-memory playlist with no service synchronization
- `ServicePlaylist` — Base for playlists synchronized with music services
- `MultiRequestServicePlaylist` — For APIs requiring multi-request modifications
- `PlaylistIDs` — Unified TypedDict for cross-service playlist identification

**Method Changes:**
| Old | New | Notes |
|-----|-----|-------|
| `remote_edit()` | `edit()` | Context manager for transactional edits |
| `remote_delete()` | `delete()` | Returns `OfflinePlaylist` with last state |
| `remote_create()` | `library.create_playlist()` | Factory method on library |
| `remote_upsert()` | `update()` | Bulk sync to remote |
| `remote_associated` | Removed | Service playlists always correspond to remote |

**Migration:**
```python
# Old
pl = SpotifyPlaylistCollection(library, "Name", "desc")
pl.remote_create()
with pl.remote_edit():
pl.tracks.append(track)

# New
pl = library.create_playlist("Name", "desc")
with pl.edit():
pl.tracks.append(track)
```

- Auth commands are now available via `plistsync auth [service]` instead of `plistsync [service] auth`
- Added `plistsync --version` command to show the currently installed version of the library
- Renamed `_apply_diff` -> `_remote_commit` for clarity

### Added

- Split Playlist ABC into two classes: one for simple services, like filesystems, where states can be pushed via a single API call (`PlaylistCollection`) and one where multiple API calls are required (`MultiRequestPlaylistCollection`), e.g. when a playlists description cannot be pushed in the same call as track changes.
- Added `PlaylistAssociationError` for playlist remote association checks, replacing `ValueError` with clearer messages and an `already_associated` attribute for programmatic inspection.
- Added `allservices` dependency group to allow a loaded pip install with batteries included.
- Added `plistsync --version` command to show the currently installed version of the library

### Fixed

- Fixed lazy track loading when playlist has 0 tracks (`force=True` logic in `_load_tracks`)
- In rare cases, spotify playlists can contain invalid items, which do not appear in the web interface (but through the api). We now filter and remove them.

## [0.5.1] - 2026-03-16
Expand Down
4 changes: 2 additions & 2 deletions docs/details/advanced/matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ Imagine you have a track file on your local computer that you've recently bought

```python
from plistsync.services.local import LocalTrack
from plistsync.services.spotify import SpotifyLibraryCollection
from plistsync.services.spotify import SpotifyLibrary

# This represents a single track on your local filesystem
source_track = LocalTrack("./path_to_source_track.mp3")

# Access to spotify
target_collection = SpotifyLibraryCollection()
target_collection = SpotifyLibrary()

# Perform the match operation to find the source_track in the target_collection
matches = target_collection.match(source_track)
Expand Down
2 changes: 1 addition & 1 deletion docs/details/core-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,4 @@ Each service manages the platform-specific details so you don't have to:
- **Data import/export** - Converting between platform formats and plistsync's standard Tracks/Collections
- **Write-back** - Creating playlists, adding tracks, updating metadata on the target platform

**Example**: Sync a Spotify "Road Trip" playlist → Tidal by letting services handle authentication → data extraction → track matching → playlist recreation automaticall
**Example**: Sync a Spotify "Road Trip" playlist → Tidal by letting services handle authentication → data extraction → track matching → playlist recreation automatically
Loading
Loading