feat: configuration page with default lisp forms.

This commit is contained in:
redxef 2024-11-08 03:09:17 +01:00
parent 396384fd71
commit 4537a3aee3
Signed by: redxef
GPG key ID: 7DAC3AA211CBD921
6 changed files with 42 additions and 42 deletions

View file

@ -2,8 +2,19 @@ using MediaBrowser.Model.Plugins;
namespace Jellyfin.Plugin.SmartPlaylist { namespace Jellyfin.Plugin.SmartPlaylist {
public class PluginConfiguration : BasePluginConfiguration { public class PluginConfiguration : BasePluginConfiguration {
public PluginConfiguration( public PluginConfiguration() {
) { InitialProgram = """
(begin
(define lower (lambda (s) (invoke s "ToLower" nil)))
(define is-genre (lambda (g g-list) (any (lambda (x) (invoke (lower x) "Contains" (list (lower g)))) g-list)))
(define is-genre-exact (lambda (g g-list) (find g g-list)))
(define genre-list (lambda nil (let (_g (getitems item "Genres")) (if (null _g) nil (car _g)))))
(define is-favorite (lambda nil (invoke item "IsFavoriteOrLiked" (list user)))))
(define is-favourite is-favorite)
""";
} }
public string InitialProgram { get; set; }
} }
} }

View file

@ -98,6 +98,11 @@ namespace Jellyfin.Plugin.SmartPlaylist.ScheduledTasks {
Expression expression = new Parser(StringTokenStream.generate(smartPlaylist.Program)).parse(); Expression expression = new Parser(StringTokenStream.generate(smartPlaylist.Program)).parse();
Executor executor = new Executor(new DefaultEnvironment()); Executor executor = new Executor(new DefaultEnvironment());
executor.environment.Set("user", new Lisp_Object(user)); executor.environment.Set("user", new Lisp_Object(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) { foreach (var i in items) {
executor.environment.Set("item", new Lisp_Object(i)); executor.environment.Set("item", new Lisp_Object(i));
var r = executor.eval(expression); var r = executor.eval(expression);

View file

@ -41,7 +41,7 @@ namespace Jellyfin.Plugin.SmartPlaylist {
[Serializable] [Serializable]
public class SmartPlaylistDto : ISerializable { public class SmartPlaylistDto : ISerializable {
private static string DEFAULT_PROGRAM = "(begin (invoke item 'IsFavoriteOrLiked' (user)))"; private static string DEFAULT_PROGRAM = "(begin (invoke item \"IsFavoriteOrLiked\" (list user)))";
public SmartPlaylistId Id { get; set; } public SmartPlaylistId Id { get; set; }
public SmartPlaylistLinkDto[] Playlists { get; set; } public SmartPlaylistLinkDto[] Playlists { get; set; }
public string Name { get; set; } public string Name { get; set; }

View file

@ -20,9 +20,12 @@ namespace Jellyfin.Plugin.SmartPlaylist {
{ {
throw new ApplicationException(""); throw new ApplicationException("");
} }
if (dto.Id == Path.GetFileNameWithoutExtension(filename)) { if (dto.Id != Path.GetFileNameWithoutExtension(filename)) {
dto.Id = Path.GetFileNameWithoutExtension(filename); dto.Id = Path.GetFileNameWithoutExtension(filename);
} }
if (dto.Name != Path.GetFileNameWithoutExtension(filename)) {
dto.Name = Path.GetFileNameWithoutExtension(filename);
}
if (dto.Filename != filename) { if (dto.Filename != filename) {
dto.Filename = filename; dto.Filename = filename;
} }

View file

@ -5,32 +5,14 @@
<title>Template</title> <title>Template</title>
</head> </head>
<body> <body>
<div id="TemplateConfigPage" data-role="page" class="page type-interior pluginConfigurationPage" data-require="emby-input,emby-button,emby-select,emby-checkbox"> <div id="SmartPlaylistConfigPage" data-role="page" class="page type-interior pluginConfigurationPage" data-require="emby-input,emby-button,emby-select,emby-checkbox">
<div data-role="content"> <div data-role="content">
<div class="content-primary"> <div class="content-primary">
<form id="TemplateConfigForm"> <form id="SmartPlaylistConfigForm">
<div class="selectContainer">
<label class="selectLabel" for="Options">Several Options</label>
<select is="emby-select" id="Options" name="Options" class="emby-select-withcolor emby-select">
<option id="optOneOption" value="OneOption">One Option</option>
<option id="optAnotherOption" value="AnotherOption">Another Option</option>
</select>
</div>
<div class="inputContainer"> <div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="AnInteger">An Integer</label> <label class="inputLabel inputLabelUnfocused" for="InitialProgram">Initial Program</label>
<input id="AnInteger" name="AnInteger" type="number" is="emby-input" min="0" /> <div class="fieldDescription">A program which can set up the environment</div>
<div class="fieldDescription">A Description</div> <input id="InitialProgram" name="InitialProgram" type="text" is="emby-input" />
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="TrueFalseSetting" name="TrueFalseCheckBox" type="checkbox" is="emby-checkbox" />
<span>A Checkbox</span>
</label>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="AString">A String</label>
<input id="AString" name="AString" type="text" is="emby-input" />
<div class="fieldDescription">Another Description</div>
</div> </div>
<div> <div>
<button is="emby-button" type="submit" class="raised button-submit block emby-button"> <button is="emby-button" type="submit" class="raised button-submit block emby-button">
@ -41,31 +23,25 @@
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
var TemplateConfig = { var SmartPlaylistConfig = {
pluginUniqueId: 'dd2326e3-4d3e-4bfc-80e6-28502c1131df' pluginUniqueId: 'dd2326e3-4d3e-4bfc-80e6-28502c1131df'
}; };
document.querySelector('#TemplateConfigPage') document.querySelector('#SmartPlaylistConfigPage')
.addEventListener('pageshow', function() { .addEventListener('pageshow', function() {
Dashboard.showLoadingMsg(); Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(TemplateConfig.pluginUniqueId).then(function (config) { ApiClient.getPluginConfiguration(SmartPlaylistConfig.pluginUniqueId).then(function (config) {
document.querySelector('#Options').value = config.Options; document.querySelector('#InitialProgram').value = config.InitialProgram;
document.querySelector('#AnInteger').value = config.AnInteger;
document.querySelector('#TrueFalseSetting').checked = config.TrueFalseSetting;
document.querySelector('#AString').value = config.AString;
Dashboard.hideLoadingMsg(); Dashboard.hideLoadingMsg();
}); });
}); });
document.querySelector('#TemplateConfigForm') document.querySelector('#SmartPlaylistConfigForm')
.addEventListener('submit', function(e) { .addEventListener('submit', function(e) {
Dashboard.showLoadingMsg(); Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(TemplateConfig.pluginUniqueId).then(function (config) { ApiClient.getPluginConfiguration(SmartPlaylistConfig.pluginUniqueId).then(function (config) {
config.Options = document.querySelector('#Options').value; config.InitialProgram = document.querySelector('#InitialProgram').value;
config.AnInteger = document.querySelector('#AnInteger').value; ApiClient.updatePluginConfiguration(SmartPlaylistConfig.pluginUniqueId, config).then(function (result) {
config.TrueFalseSetting = document.querySelector('#TrueFalseSetting').checked;
config.AString = document.querySelector('#AString').value;
ApiClient.updatePluginConfiguration(TemplateConfig.pluginUniqueId, config).then(function (result) {
Dashboard.processPluginConfigurationUpdateResult(result); Dashboard.processPluginConfigurationUpdateResult(result);
}); });
}); });

View file

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<RootNamespace>jellyfin_smart_playlist</RootNamespace> <RootNamespace>Jellyfin.Plugin.SmartPlaylist</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Version>0.1.1.0</Version> <Version>0.1.1.0</Version>
@ -14,4 +14,9 @@
<PackageReference Include="YamlDotNet" Version="16.1.3" /> <PackageReference Include="YamlDotNet" Version="16.1.3" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="configPage.html"/>
<EmbeddedResource Include="configPage.html"/>
</ItemGroup>
</Project> </Project>