No description
Find a file
2024-11-19 21:57:51 +01:00
ci ci: add initial pipeline for releasing. 2024-10-30 03:22:39 +01:00
Jellyfin.Plugin.SmartPlaylist feat(lisp): add string comparison methods. 2024-11-19 21:57:34 +01:00
Test fix: always pull newest jellyfin version. 2024-10-27 20:07:25 +01:00
Tests feat(lisp): add quicksort implementation. 2024-11-19 21:15:41 +01:00
.gitignore ci: add build script. 2024-10-28 01:44:23 +01:00
examples.md docs: itemkind behavior and filtering warning, also extend examples. 2024-11-08 22:50:38 +01:00
LICENSE chore: add license. 2024-10-27 19:58:32 +01:00
README.md docs: document SortProgram and give a simple example. 2024-11-19 21:57:51 +01:00
release.sh ci: change artifact to zipfile. 2024-10-30 03:14:13 +01:00

Jellyfin SmartPlaylist Plugin

Smart playlists with Lisp filter engine.

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. The latest version is v0.2.2.0.

How to use

After installing the plugin and restarting Jellyfin create a empty file in config/data/smartplaylists like this, maybe you want to generate a playlist of your favourite rock songs:

$ touch config/data/smartplaylists/Rock.yaml

Afterwards run the Task (re)generate Smart Playlists, this will rename the yaml file and populate it with some default values. You can now adjust the file to your liking. Go here to see more examples.

Id: Rock
Playlists:
- PlaylistId: 24f12e1e-3278-d6d6-0ca4-066e93296c95
  UserId: 6eec632a-ff0d-4d09-aad0-bf9e90b14bc6
Name: Rock
Program: (begin (invoke item "IsFavoriteOrLiked" (user)))
SortProgram: (begin items)
Filename: /config/data/smartplaylists/Rock.yaml
Enabled: true

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:

Porgram: |
  (begin
    (invoke item "IsFavoriteOrLiked" (list user)))  

This is equivalent to the above example (not counting the other fields obviously).

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 still work and remember the correct playlist.

Program

A lisp program to decide on a per item basis if it should be included in the playlist, return nil to not include items, return any other value to include them. Global variables user and item are predefined and contain a User and BaseItem respectively.

!!! 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).

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).

SortProgram

This works exactly like Program, but the input is the user and a list of items (items) matched by Program. The default is (begin items), which doesn't sort at all. To sort the items by name you could use the following program:

(qsort
  (lambda
    (a b)
    (string>
      (car (getitems a "Name"))
      (car (getitems b "Name"))))
  items)

Available definitions

  • lower: lowercases a string ((eq (lower "SomeString") "somestring"))
  • is-genre: check if the item is of this genre, partial matches allowed, the example filter would match the genre "Nu-Metal" ((is-genre "metal" (genre-list)))
  • is-genre-exact: the same as is-genre, but does not match paritally
  • is-favorite: matches a favorite item ((is-favorite))
  • is-type: matches the type of item look at BaseItemKind.cs for a list of items. The plugin has enabled support for Audio, MusicAlbum, Playlist ((is-type "Audio"))

Filename

The path to this file, only used internally and updated by the program.

Enabled

Enable this playlist, currently ignored.

Installation

Add the plugin repository 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.

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.