2024-10-27 19:49:14 +01:00
|
|
|
# Jellyfin SmartPlaylist Plugin
|
|
|
|
|
2024-10-28 02:31:20 +01:00
|
|
|
Smart playlists with Lisp filter engine.
|
2024-10-27 19:49:14 +01:00
|
|
|
|
2024-11-08 22:38:46 +01:00
|
|
|
This readme contains instructions for the most recent changes in
|
|
|
|
the development branch (`main`). To view the file appropriate
|
|
|
|
for your version select the tag corresponding to your version.
|
2024-12-22 18:47:46 +01:00
|
|
|
The latest version is [v0.4.0.0](https://gitea.redxef.at/redxef/jellyfin-smart-playlist/src/tag/v0.4.0.0).
|
2024-11-08 22:38:46 +01:00
|
|
|
|
2024-10-27 19:49:14 +01:00
|
|
|
## How to use
|
|
|
|
|
2024-12-22 21:14:50 +01:00
|
|
|
After [installing](#installation) the plugin and restarting Jellyfin
|
|
|
|
go to the plugin settings and below the `Initial Program` configuration
|
|
|
|
choose the smart playlist you want to edit, or `Create new playlist ...`
|
|
|
|
to create a new one.
|
|
|
|
|
|
|
|
### Without the UI
|
|
|
|
|
2024-10-27 19:49:14 +01:00
|
|
|
After [installing](#installation) the plugin and restarting Jellyfin
|
2024-11-08 03:54:49 +01:00
|
|
|
create a empty file in `config/data/smartplaylists` like this, maybe
|
|
|
|
you want to generate a playlist of your favourite rock songs:
|
2024-10-27 19:49:14 +01:00
|
|
|
|
|
|
|
```
|
2024-11-08 03:54:49 +01:00
|
|
|
$ touch config/data/smartplaylists/Rock.yaml
|
2024-10-27 19:49:14 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
Afterwards run the Task `(re)generate Smart Playlists`, this will rename
|
2024-11-08 03:54:49 +01:00
|
|
|
the `yaml` file and populate it with some default values. You can now
|
2024-11-08 20:22:46 +01:00
|
|
|
adjust the file to your liking. [Go here](examples.md) to see more
|
2024-10-27 19:49:14 +01:00
|
|
|
examples.
|
|
|
|
|
2024-11-08 03:54:49 +01:00
|
|
|
```yaml
|
|
|
|
Id: Rock
|
|
|
|
Playlists:
|
|
|
|
- PlaylistId: 24f12e1e-3278-d6d6-0ca4-066e93296c95
|
|
|
|
UserId: 6eec632a-ff0d-4d09-aad0-bf9e90b14bc6
|
|
|
|
Name: Rock
|
2024-12-22 18:44:43 +01:00
|
|
|
Program: (begin (invoke item "IsFavoriteOrLiked" (list *user*)))
|
2024-12-22 21:14:50 +01:00
|
|
|
SortProgram: (begin *items*)
|
2024-11-08 03:54:49 +01:00
|
|
|
Filename: /config/data/smartplaylists/Rock.yaml
|
|
|
|
Enabled: true
|
2024-10-27 19:49:14 +01:00
|
|
|
```
|
|
|
|
|
2024-11-08 03:54:49 +01:00
|
|
|
This is the default configuration and will always match all your
|
|
|
|
favorite songs (and songs which are in favourited albums).
|
|
|
|
|
|
|
|
To change the filter you can append a `|` (pipe) to the Program
|
|
|
|
line and write multiline filters like this:
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
Porgram: |
|
|
|
|
(begin
|
2024-12-22 18:44:43 +01:00
|
|
|
(invoke item "IsFavoriteOrLiked" (list *user*)))
|
2024-11-08 03:54:49 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
This is equivalent to the above example (not counting the other
|
|
|
|
fields obviously).
|
|
|
|
|
|
|
|
|
2024-10-27 19:49:14 +01:00
|
|
|
### Id
|
|
|
|
|
|
|
|
Arbitrary Id assigned to this playlist, can usually be left alone.
|
|
|
|
|
|
|
|
### Playlists
|
|
|
|
|
|
|
|
A list of Playlist/User mappings. By default all users get an entry.
|
|
|
|
|
|
|
|
The ids must have the dashes in them as of now. To convert a id
|
|
|
|
from without dashes to the canonical form run this command:
|
|
|
|
|
|
|
|
`echo '<your id here>' | python3 -c 'import uuid; import sys; print(uuid.UUID(sys.stdin.read().strip()))'`
|
|
|
|
|
|
|
|
To get your user id navigate to your user profile and copy the part
|
|
|
|
after `userId` in the address bar.
|
|
|
|
|
|
|
|
#### PlaylistId
|
|
|
|
|
|
|
|
The id of the playlist that should be managed, must be owned by the
|
|
|
|
corresponding user.
|
|
|
|
|
|
|
|
#### UserId
|
|
|
|
|
|
|
|
The user associated with this playlist.
|
|
|
|
|
|
|
|
### Name
|
|
|
|
|
|
|
|
The name of the generated playlists, this is just a default value.
|
|
|
|
If the user changes the name of their playlist the plugin will
|
2024-11-08 03:54:49 +01:00
|
|
|
still work and remember the correct playlist.
|
2024-10-27 19:49:14 +01:00
|
|
|
|
|
|
|
### Program
|
|
|
|
|
|
|
|
A lisp program to decide on a per item basis if it should be included in
|
2024-11-08 03:54:49 +01:00
|
|
|
the playlist, return `nil` to not include items, return any other value
|
2024-12-22 18:44:43 +01:00
|
|
|
to include them. Global variables `*user*` and `*item*` are predefined
|
2024-11-19 21:57:51 +01:00
|
|
|
and contain a [User](https://github.com/jellyfin/jellyfin/blob/master/Jellyfin.Data/Entities/User.cs) and
|
|
|
|
[BaseItem](https://github.com/jellyfin/jellyfin/blob/master/MediaBrowser.Controller/Entities/BaseItem.cs)
|
|
|
|
respectively.
|
2024-11-08 03:54:49 +01:00
|
|
|
|
2024-11-08 22:50:38 +01:00
|
|
|
**!!! The filter expression will include all items matching, if you do
|
|
|
|
not specify the kind of item to include/exclude all of them will be
|
|
|
|
added. Should you allow a playlist to be included all of it's items
|
|
|
|
will be added to the generated playlist !!!**
|
|
|
|
|
|
|
|
It's best to be explicit and always specify the item kinds you want to
|
|
|
|
include: `(and (or (is-type "MusicAlbum") (is-type "Audio")) . rest of filter)`.
|
|
|
|
|
2024-11-08 03:54:49 +01:00
|
|
|
The configuration page defines some useful functions to make it easier
|
|
|
|
to create filters. The above filter for liked items could be simplified
|
|
|
|
to: `(is-favourite)`.
|
|
|
|
|
2024-12-17 23:08:01 +01:00
|
|
|
*Go [here](lisp.md) to get an overview of the built-in functions.*
|
2024-12-17 23:06:43 +01:00
|
|
|
|
2024-11-19 21:57:51 +01:00
|
|
|
### SortProgram
|
|
|
|
|
|
|
|
This works exactly like [Program](#program), but the input is the
|
2024-12-22 18:44:43 +01:00
|
|
|
user and a list of items (`*items*`) matched by [Program](#program).
|
|
|
|
The default is `(begin *items*)`, which doesn't sort at all. To sort
|
2024-11-19 21:57:51 +01:00
|
|
|
the items by name you could use the following program:
|
|
|
|
|
|
|
|
```lisp
|
|
|
|
(qsort
|
|
|
|
(lambda
|
|
|
|
(a b)
|
|
|
|
(string>
|
|
|
|
(car (getitems a "Name"))
|
|
|
|
(car (getitems b "Name"))))
|
2024-12-22 18:44:43 +01:00
|
|
|
*items*)
|
2024-11-19 21:57:51 +01:00
|
|
|
```
|
|
|
|
|
2024-10-27 19:49:14 +01:00
|
|
|
### Filename
|
|
|
|
|
2024-11-08 03:54:49 +01:00
|
|
|
The path to this file, only used internally and updated by the program.
|
2024-10-27 19:49:14 +01:00
|
|
|
|
|
|
|
### Enabled
|
|
|
|
|
|
|
|
Enable this playlist, currently ignored.
|
|
|
|
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
2024-10-30 03:22:19 +01:00
|
|
|
Add the [plugin repository](https://jellyfin.org/docs/general/server/plugins/#catalog)
|
|
|
|
to Jellyfin:
|
|
|
|
`https://gitea.redxef.at/redxef/jellyfin-smart-playlist/raw/branch/manifest/manifest.json`
|
|
|
|
|
|
|
|
Go to `Dashboard>Catalog>(Gear)>(Plus)` and paste the provided link into
|
|
|
|
the field labeled `Repository URL`, give the plugin a descriptive name
|
|
|
|
too.
|
2024-11-08 22:57:19 +01:00
|
|
|
|
|
|
|
## Releasing a new version
|
|
|
|
|
|
|
|
1. Write the changelog: `git log --oneline $prev_version..`
|
|
|
|
2. Update the following files to include up-to-date version numbers
|
|
|
|
and changelogs, if applicable:
|
|
|
|
- `README.md`
|
|
|
|
- `Jellyfin.Plugin.SmartPlaylist/build.yaml`
|
|
|
|
- `Jellyfin.Plugin.SmartPlaylist/jellyfin-smart-playlist.csproj`
|
|
|
|
Don't forget to also bump the ABI version of Jellyfin.
|
|
|
|
3. Push the changes
|
|
|
|
4. Create a new release with the changelog, mark as pre-release if
|
|
|
|
applicable.
|
|
|
|
5. Done! The build pipeline will do the rest.
|