Compare commits
4 commits
Author | SHA1 | Date | |
---|---|---|---|
64ae51ba71 | |||
d8145565cd | |||
5689d0424c | |||
eef2f32e14 |
8 changed files with 106 additions and 157 deletions
|
@ -90,25 +90,50 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp {
|
|||
(lambda
|
||||
(list0)
|
||||
(car list0)))
|
||||
;(split
|
||||
; (lambda
|
||||
; (list0 pivot fc h0 h1)
|
||||
; (cond
|
||||
; ((null list0) (list list0 pivot fc h0 h1))
|
||||
; ((fc (car list0) pivot) (split (cdr list0) pivot fc h0 (cons (car list0) h1)))
|
||||
; (t (split (cdr list0) pivot fc (cons (car list0) h0) h1)))))
|
||||
(split
|
||||
(lambda
|
||||
(list0 pivot fc h0 h1)
|
||||
(list0 pivot fc h0 h1 heq)
|
||||
(cond
|
||||
((null list0) (list list0 pivot fc h0 h1))
|
||||
((fc (car list0) pivot) (split (cdr list0) pivot fc h0 (cons (car list0) h1)))
|
||||
(t (split (cdr list0) pivot fc (cons (car list0) h0) h1)))))
|
||||
((null list0) (list list0 pivot fc h0 h1 heq))
|
||||
((and
|
||||
(fc (car list0) pivot)
|
||||
(fc pivot (car list0))) (split (cdr list0) pivot fc h0 h1 (cons (car list0) heq)))
|
||||
((fc (car list0) pivot) (split (cdr list0) pivot fc h0 (cons (car list0) h1) heq))
|
||||
((fc pivot (car list0)) (split (cdr list0) pivot fc (cons (car list0) h0) h1 heq))
|
||||
((= (car list0) pivot) (split (cdr list0) pivot fc h0 h1 (cons (car list0) heq)))
|
||||
(t (split (cdr list0) pivot fc h0 h1 heq)))))
|
||||
;(sort
|
||||
; (lambda
|
||||
; (fc list0)
|
||||
; (cond
|
||||
; ((null list0) nil)
|
||||
; ((null (cdr list0)) list0)
|
||||
; (t
|
||||
; (let*
|
||||
; (halves (split list0 (getpivot list0) fc nil nil))
|
||||
; (h0 (car (cdr (cdr (cdr halves)))))
|
||||
; (h1 (car (cdr (cdr (cdr (cdr halves))))))
|
||||
; (append (sort fc h0) (sort fc h1)))))))
|
||||
(sort
|
||||
(lambda
|
||||
(fc list0)
|
||||
(cond
|
||||
(begin t (cond
|
||||
((null list0) nil)
|
||||
((null (cdr list0)) list0)
|
||||
(t
|
||||
(let*
|
||||
(halves (split list0 (getpivot list0) fc nil nil))
|
||||
(halves (split list0 (getpivot list0) fc nil nil nil))
|
||||
(h0 (car (cdr (cdr (cdr halves)))))
|
||||
(h1 (car (cdr (cdr (cdr (cdr halves))))))
|
||||
(append (sort fc h0) (sort fc h1)))))))
|
||||
(heq (car (cdr (cdr (cdr (cdr (cdr halves)))))))
|
||||
(append (append (sort fc h0) heq) (sort fc h1))))))))
|
||||
(sort fc list00)))
|
||||
"""
|
||||
);
|
||||
|
|
|
@ -21,17 +21,19 @@ function initial_load() {
|
|||
Dashboard.hideLoadingMsg();
|
||||
}
|
||||
|
||||
document.querySelector('#LispPlaygroundConfigPage')
|
||||
.addEventListener('viewshow', function() {
|
||||
initial_load();
|
||||
export default function (view, params) {
|
||||
view.addEventListener('viewshow', function() {
|
||||
initial_load(null);
|
||||
});
|
||||
view.addEventListener('viewhide', function (_e) {});
|
||||
view.addEventListener('viewdestroy', function (_e) {});
|
||||
|
||||
document.querySelector('#LispPlaygroundConfigPage')
|
||||
document.querySelector('#LispPlaygroundConfigPage')
|
||||
.addEventListener('pageshow', function() {
|
||||
initial_load();
|
||||
});
|
||||
|
||||
document.querySelector('#LispPlaygroundConfigForm')
|
||||
document.querySelector('#LispPlaygroundConfigForm')
|
||||
.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
Dashboard.showLoadingMsg();
|
||||
|
@ -41,3 +43,4 @@ document.querySelector('#LispPlaygroundConfigForm')
|
|||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -88,23 +88,21 @@ function initial_load(selectedId) {
|
|||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
}
|
||||
document.querySelector('#SmartCollectionConfigPage')
|
||||
.addEventListener('viewshow', function() {
|
||||
|
||||
export default function (view, params) {
|
||||
view.addEventListener('viewshow', function() {
|
||||
initial_load(null);
|
||||
});
|
||||
view.addEventListener('viewhide', function (_e) {});
|
||||
view.addEventListener('viewdestroy', function (_e) {});
|
||||
|
||||
document.querySelector('#SmartCollectionConfigPage')
|
||||
.addEventListener('pageshow', function() {
|
||||
initial_load(null);
|
||||
});
|
||||
|
||||
document.querySelector('#SmartcollectionSelection')
|
||||
document.querySelector('#SmartcollectionSelection')
|
||||
.addEventListener('change', function() {
|
||||
const selection = document.querySelector('#SmartcollectionSelection');
|
||||
fillForm(COLLECTIONS[selection.selectedIndex]);
|
||||
});
|
||||
|
||||
document.querySelector('#SmartCollectionConfigForm')
|
||||
document.querySelector('#SmartCollectionConfigForm')
|
||||
.addEventListener('submit', function (e) {
|
||||
Dashboard.showLoadingMsg();
|
||||
const selection = document.querySelector('#SmartcollectionSelection');
|
||||
|
@ -114,3 +112,4 @@ document.querySelector('#SmartCollectionConfigForm')
|
|||
});
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -116,22 +116,20 @@ function initial_load(selectedId) {
|
|||
});
|
||||
}
|
||||
|
||||
document.querySelector('#SmartPlaylistConfigPage')
|
||||
.addEventListener('viewshow', function() {
|
||||
initial_load(null);
|
||||
});
|
||||
document.querySelector('#SmartPlaylistConfigPage')
|
||||
.addEventListener('pageshow', function() {
|
||||
export default function (view, params) {
|
||||
view.addEventListener('viewshow', function() {
|
||||
initial_load(null);
|
||||
});
|
||||
view.addEventListener('viewhide', function (_e) {});
|
||||
view.addEventListener('viewdestroy', function (_e) {});
|
||||
|
||||
document.querySelector('#SmartplaylistSelection')
|
||||
document.querySelector('#SmartplaylistSelection')
|
||||
.addEventListener('change', function() {
|
||||
const selection = document.querySelector('#SmartplaylistSelection');
|
||||
fillForm(PLAYLISTS[selection.selectedIndex], USERS);
|
||||
});
|
||||
|
||||
document.querySelector('#SmartPlaylistConfigForm')
|
||||
document.querySelector('#SmartPlaylistConfigForm')
|
||||
.addEventListener('submit', function (e) {
|
||||
Dashboard.showLoadingMsg();
|
||||
const selection = document.querySelector('#SmartplaylistSelection');
|
||||
|
@ -141,3 +139,4 @@ document.querySelector('#SmartPlaylistConfigForm')
|
|||
});
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
name: Smart Playlist
|
||||
guid: dd2326e3-4d3e-4bfc-80e6-28502c1131df
|
||||
version: 0.5.1.0
|
||||
targetAbi: 10.10.3.0
|
||||
version: 0.5.2.0
|
||||
targetAbi: 10.10.5.0
|
||||
framework: net8.0
|
||||
owner: redxef
|
||||
overview: Smart playlists with Lisp filter engine.
|
||||
|
@ -14,89 +14,8 @@ artifacts:
|
|||
- jellyfin-smart-playlist.dll
|
||||
- YamlDotNet.dll
|
||||
changelog: |
|
||||
## v0.5.1.0
|
||||
- Add multiple new functions:
|
||||
- `length` computes the length of a list
|
||||
- `split` splits off n elements of the given list `(split '(1 2 3 4 5) 3) -> ((1 2 3) 4 5)`
|
||||
- `reverse` reverses a list
|
||||
## v0.5.2.0
|
||||
- bump Jellyfin ABI version to 10.10.5
|
||||
|
||||
**Fixes**:
|
||||
- The configuration can now be updated again.
|
||||
The relevant code got lost during the smart collection restructuring.
|
||||
|
||||
## v0.5.0.0
|
||||
- Add support for collections
|
||||
- Add a playground to test lisp code, the playground has
|
||||
two additional functions available: `print` and `println`
|
||||
to fill the output window
|
||||
- Separate the config pages
|
||||
- Enable nearly all item types
|
||||
|
||||
## v0.4.1.0
|
||||
- improve defaults for new playlists
|
||||
|
||||
**Fixes**:
|
||||
- finally get the percentage indicator of the scheduled task right
|
||||
|
||||
## v0.4.0.0
|
||||
- Add a basic UI to configure the playlists.
|
||||
- It's now possible to print log messages to the jellyfin log by calling `logd`, `logi`, `logw` or `loge`
|
||||
for the respective levels `debug`, `info`, `warning` or `error`.
|
||||
- Allow calling generic methods via `(invoke-generic object methodname args list-of-types)`.
|
||||
- Add quoting via single quote: `'`.
|
||||
- Add special case for `(quote <form>)` to be rendered as `'<form>`.
|
||||
- It is now possible to include comments in the source via a semicolon (`;`).
|
||||
- Respect the `Enabled` flag and only process the playlists that are enabled.
|
||||
- New methods have been added: `rand`, `shuf`.
|
||||
- Add `find-artist`, `get-name` and `find-parent` default definitions.
|
||||
- Update YamlDotNet to v16.2.1.
|
||||
|
||||
**Breaking changes**:
|
||||
- Rename global environment variables to be enclosed by `*`.
|
||||
|
||||
**Fixes**:
|
||||
- The initialization of the executor now contains the same default definitions for the SortProgram and the normal Program.
|
||||
- The progress report now considers the SmartPlaylists and not the individual playlists per user.
|
||||
- It is now possible to pass builtins as arguments. Previously to get `(qsort > (list 1 2 3))` one had to write
|
||||
something like this: `(qsort (lambda (a b) (> a b)) (list 1 2 3))`.
|
||||
- A program no longer has to be a list, `t` is a valid program.
|
||||
- Fix list parsing in cases where a space was before the closing parenthesis.
|
||||
|
||||
## v0.3.0.0
|
||||
- Add a second program (`SortProgram`) which is run after the filtering, this
|
||||
program should return the list of items, but in the order in which they should appear in
|
||||
the playlist. The default is `(begin items)` which returns the list as is.
|
||||
- Extend builtin lisp definitions: add `qsort` and string comparison methods
|
||||
- Extend default program definitions: add `all-genres` and `any-genres` to quickly specify a list of genres which to include (or excluding when negating)
|
||||
- Update Jellyfin to v 10.10.3
|
||||
|
||||
**Fixes**:
|
||||
- The progress report now correctly gives a percentage in the range [0, 100].
|
||||
|
||||
## v0.2.2.0
|
||||
- Update Jellyfin to v 10.10.2
|
||||
|
||||
## v0.2.1.0
|
||||
- Make default program configuration a textarea in the settings page
|
||||
- Add convinience definitions: `is-type`, `name-contains`
|
||||
- Update YamlDotNet to v 16.2.0
|
||||
|
||||
**Fixes**:
|
||||
- The default program was malformed, a closing bracket was at the wrong position
|
||||
- The `haskeys` function could only be called on Objects
|
||||
|
||||
## v0.2.0.0
|
||||
- Switch to yaml loading, old json files are still accepted
|
||||
- Rework lisp interpreter to be more conventional
|
||||
- Use arbitrary strings as ids for playlists
|
||||
- Add configuration page with some default definitions for
|
||||
the filter expressions.
|
||||
|
||||
**Breaking Changes**:
|
||||
- The lisp interpreter will now only detect strings in double quotes (`"`).
|
||||
- The interpreter will also not allow specifying lists without quoting them.
|
||||
`(1 2 3)` ... used to work but will no longer, replace by either specifying
|
||||
the list as `(list 1 2 3)` or `(quote (1 2 3))`.
|
||||
|
||||
## v0.1.1.0
|
||||
- Initial Alpha release.
|
||||
- the config pages will always load, not only the first time
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
<RootNamespace>Jellyfin.Plugin.SmartPlaylist</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>0.5.1.0</Version>
|
||||
<Version>0.5.2.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.10.3" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.10.3" />
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.10.5" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.10.5" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ 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.5.1.0](https://gitea.redxef.at/redxef/jellyfin-smart-playlist/src/tag/v0.5.1.0).
|
||||
The latest version is [v0.5.2.0](https://gitea.redxef.at/redxef/jellyfin-smart-playlist/src/tag/v0.5.2.0).
|
||||
|
||||
![configuration page](config.png)
|
||||
|
||||
|
|
|
@ -267,6 +267,10 @@ namespace Tests
|
|||
//Assert.Equal("", e.eval("(shuf (list 0 1 2 3 4 5 6))").ToString());
|
||||
Assert.Equal("(1 2 3 4 5 6 7)", e.eval("(qsort (lambda (a b) (> a b)) '(5 4 7 3 2 6 1))").ToString());
|
||||
Assert.Equal("(1 2 3 4 5 6 7)", e.eval("(qsort > (list 5 4 7 3 2 6 1))").ToString());
|
||||
Assert.Equal("(0 1 2 4 5 5)", e.eval("(qsort > '(2 4 1 5 5 0))").ToString());
|
||||
Assert.Equal("(5 5 4 2 1 0)", e.eval("(qsort < '(2 4 1 5 5 0))").ToString());
|
||||
Assert.Equal("(5 5 4 2 1 0)", e.eval("(qsort <= '(2 4 1 5 5 0))").ToString());
|
||||
Assert.Equal("(0 1 2 4 5 5)", e.eval("(qsort >= '(2 4 1 5 5 0))").ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue