feat: add SortProgram.
Works similar to Program, but receives the list of matched items and should return the same list but sorted. This can actually also be used for further filtering.
This commit is contained in:
parent
0844cebd88
commit
f479c93c5c
2 changed files with 31 additions and 6 deletions
|
@ -95,25 +95,42 @@ namespace Jellyfin.Plugin.SmartPlaylist.ScheduledTasks {
|
|||
}
|
||||
|
||||
private IEnumerable<Guid> FilterPlaylistItems(IEnumerable<BaseItem> items, User user, SmartPlaylistDto smartPlaylist) {
|
||||
List<Guid> results = new List<Guid>();
|
||||
Expression expression = new Parser(StringTokenStream.generate(smartPlaylist.Program)).parse();
|
||||
List<BaseItem> results = new List<BaseItem>();
|
||||
Expression expression = new Parser(StringTokenStream.generate(smartPlaylist.Program)).parse(); // parse here, so that we don't repeat the work for each item
|
||||
Executor executor = new Executor(new DefaultEnvironment());
|
||||
executor.environment.Set("user", new Lisp_Object(user));
|
||||
executor.environment.Set("user", Lisp_Object.FromBase(user));
|
||||
if (Plugin.Instance is not null) {
|
||||
executor.eval(Plugin.Instance.Configuration.InitialProgram);
|
||||
} else {
|
||||
throw new ApplicationException("Plugin Instance is not yet initialized");
|
||||
}
|
||||
foreach (var i in items) {
|
||||
executor.environment.Set("item", new Lisp_Object(i));
|
||||
executor.environment.Set("item", Lisp_Object.FromBase(i));
|
||||
var r = executor.eval(expression);
|
||||
_logger.LogTrace("Item {0} evaluated to {1}", i, r.ToString());
|
||||
if ((r is not Lisp_Boolean r_bool) || (r_bool.Value())) {
|
||||
_logger.LogDebug("Added '{0}' to Smart Playlist {1}", i, smartPlaylist.Name);
|
||||
results.Add(i.Id);
|
||||
results.Add(i);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
executor = new Executor(new DefaultEnvironment());
|
||||
executor.environment.Set("user", Lisp_Object.FromBase(user));
|
||||
executor.environment.Set("items", Lisp_Object.FromBase(results));
|
||||
results = new List<BaseItem>();
|
||||
var sort_result = executor.eval(smartPlaylist.SortProgram);
|
||||
if (sort_result is Cons sorted_items) {
|
||||
foreach (var i in sorted_items.ToList()) {
|
||||
if (i is Lisp_Object iObject && iObject.Value() is BaseItem iBaseItem) {
|
||||
results.Add(iBaseItem);
|
||||
continue;
|
||||
}
|
||||
throw new ApplicationException($"Returned sorted list does contain unexpected items, got {i}");
|
||||
}
|
||||
} else if (sort_result == Lisp_Boolean.FALSE) {
|
||||
} else {
|
||||
throw new ApplicationException($"Did not return a list of items, returned {sort_result}");
|
||||
}
|
||||
return results.Select(x => x.Id);
|
||||
}
|
||||
|
||||
private IEnumerable<BaseItem> GetAllUserMedia(User user) {
|
||||
|
|
|
@ -42,10 +42,12 @@ namespace Jellyfin.Plugin.SmartPlaylist {
|
|||
[Serializable]
|
||||
public class SmartPlaylistDto : ISerializable {
|
||||
private static string DEFAULT_PROGRAM = "(begin (invoke item \"IsFavoriteOrLiked\" (list user)))";
|
||||
private static string DEFAULT_SORT_PROGRAM = "(begin items)";
|
||||
public SmartPlaylistId Id { get; set; }
|
||||
public SmartPlaylistLinkDto[] Playlists { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Program { get; set; }
|
||||
public string SortProgram { get; set; }
|
||||
public string? Filename { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
|
@ -54,6 +56,7 @@ namespace Jellyfin.Plugin.SmartPlaylist {
|
|||
Playlists = [];
|
||||
Name = Id.ToString();
|
||||
Program = DEFAULT_PROGRAM;
|
||||
SortProgram = DEFAULT_SORT_PROGRAM;
|
||||
Filename = null;
|
||||
Enabled = true;
|
||||
}
|
||||
|
@ -79,6 +82,11 @@ namespace Jellyfin.Plugin.SmartPlaylist {
|
|||
} else {
|
||||
Program = DEFAULT_PROGRAM;
|
||||
}
|
||||
if (info.GetValue("SortProgram", typeof(string)) is string _SortProgram) {
|
||||
SortProgram = _SortProgram;
|
||||
} else {
|
||||
SortProgram = DEFAULT_SORT_PROGRAM;
|
||||
}
|
||||
if (info.GetValue("Filename", typeof(string)) is string _Filename) {
|
||||
Filename = _Filename;
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue