Add ability to configure plugin

This commit is contained in:
Cody Robibero 2023-11-23 12:31:38 -07:00
parent 5bf4941539
commit 8eaba98093
7 changed files with 173 additions and 8 deletions

View File

@ -1,3 +1,4 @@
using System;
using MediaBrowser.Model.Plugins;
namespace Jellyfin.Plugin.Dlna.Configuration;
@ -26,12 +27,12 @@ public class DlnaPluginConfiguration : BasePluginConfiguration
public int AliveMessageIntervalSeconds { get; set; } = 180;
/// <summary>
/// gets or sets a value indicating whether to send only matched host.
/// Gets or sets a value indicating whether to send only matched host.
/// </summary>
public bool SendOnlyMatchedHost { get; set; } = true;
/// <summary>
/// Gets or sets the default user account that the dlna server uses.
/// </summary>
public string? DefaultUserId { get; set; }
public Guid? DefaultUserId { get; set; }
}

View File

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DLNA</title>
</head>
<body>
<div data-role="page" class="page type-interior pluginConfigurationPage esqConfigurationPage" data-controller="__plugin/dlnajs">
<div data-role="content">
<div class="content-primary">
<form id="dlnaForm" class="esqConfigurationForm">
<div class="verticalSection verticalSection-extrabottompadding">
<div class="sectionTitleContainer flex align-items-center">
<h2 class="sectionTitle">DNLA Settings:</h2>
<a is="emby-button" class="raised button-alt headerHelpButton" target="_blank" href="https://github.com/jellyfin/jellyfin-plugin-dlna">${Help}</a>
</div>
<div class="verticalSection verticalSection-extrabottompadding">
<div class="checkboxContainer">
<label>
<input type="checkbox" is="emby-checkbox" id="dlnaPlayTo" />
<span>Enable Play To</span>
</label>
</div>
<div class="inputContainer">
<input is="emby-input" type="text" id="dlnaDiscoveryInterval" label="Client Discovery Interval:" />
<div class="fieldDescription">
The SSDP client discovery interval time in seconds.
The is the time after which the server will send a SSDP search request.
</div>
</div>
<div class="checkboxContainer">
<label>
<input type="checkbox" is="emby-checkbox" id="dlnaBlastAlive" />
<span>Blast Alive Messages</span>
</label>
</div>
<div class="inputContainer">
<input is="emby-input" type="text" id="dlnaAliveInterval" label="Alive Message Interval:" />
<div class="fieldDescription">
The frequency at which SSDP alive notifications are transmitted in seconds.
</div>
</div>
<div class="checkboxContainer">
<label>
<input type="checkbox" is="emby-checkbox" id="dlnaMatchedHost" />
<span>Send only to matched host</span>
</label>
</div>
<div class="selectContainer">
<select is="emby-select" id="dlnaSelectUser" label="Default User:"></select>
</div>
</div>
<div>
<button is="emby-button" type="submit" data-theme="b" class="raised button-submit block">
<span>${Save}</span>
</button>
<button is="emby-button" type="button" class="raised button-cancel block btnCancel" onclick="history.back();">
<span>${ButtonCancel}</span>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,65 @@
const DlnaConfigurationPage = {
pluginUniqueId: '33EBA9CD-7DA1-4720-967F-DD7DAE7B74A1',
defaultDiscoveryInterval: 60,
defaultAliveInterval: 100,
loadConfiguration: function (page) {
ApiClient.getPluginConfiguration(this.pluginUniqueId)
.then(function(config) {
page.querySelector('#dlnaPlayTo').checked = config.EnablePlayTo;
page.querySelector('#dlnaDiscoveryInterval').value = parseInt(config.ClientDiscoveryIntervalSeconds) || this.defaultDiscoveryInterval;
page.querySelector('#dlnaBlastAlive').checked = config.BlastAliveMessages;
page.querySelector('#dlnaAliveInterval').value = parseInt(config.AliveMessageIntervalSeconds) || this.defaultAliveInterval;
page.querySelector('#dlnaMatchedHost').checked = config.SendOnlyMatchedHost;
ApiClient.getUsers()
.then(function(users){
DlnaConfigurationPage.populateUsers(page, users, config.DefaultUserId);
})
.finally(function (){
Dashboard.hideLoadingMsg();
});
});
},
populateUsers: function(page, users, selectedId){
let html = '';
html += '<option value="">None</option>';
for(let i = 0, length = users.length; i < length; i++) {
const user = users[i];
html += '<option value="' + user.Id + '">' + user.Name + '</option>';
}
page.querySelector('#dlnaSelectUser').innerHTML = html;
page.querySelector('#dlnaSelectUser').value = selectedId;
},
save: function(page) {
Dashboard.showLoadingMsg();
return new Promise((_) => {
ApiClient.getPluginConfiguration(this.pluginUniqueId)
.then(function(config) {
config.EnablePlayTo = page.querySelector('#dlnaPlayTo').checked;
config.ClientDiscoveryIntervalSeconds = parseInt(page.querySelector('#dlnaDiscoveryInterval').value) || this.defaultDiscoveryInterval;
config.BlastAliveMessages = page.querySelector('#dlnaBlastAlive').checked;
config.AliveMessageIntervalSeconds = parseInt(page.querySelector('#dlnaAliveInterval').value) || this.defaultAliveInterval;
config.SendOnlyMatchedHost = page.querySelector('#dlnaMatchedHost').checked;
let selectedUser = page.querySelector('#dlnaSelectUser').value;
config.DefaultUserId = selectedUser.length > 0 ? selectedUser : null;
ApiClient.updatePluginConfiguration(DlnaConfigurationPage.pluginUniqueId, config).then(Dashboard.processPluginConfigurationUpdateResult);
});
})
}
}
export default function(view) {
view.querySelector('#dlnaForm').addEventListener('submit', function(e) {
DlnaConfigurationPage.save(view);
e.preventDefault();
return false;
});
window.addEventListener('pageshow', function(_) {
Dashboard.showLoadingMsg();
DlnaConfigurationPage.loadConfiguration(view);
});
}

View File

@ -143,9 +143,9 @@ public class ContentDirectoryService : BaseService, IContentDirectory
var userId = DlnaPlugin.Instance.Configuration.DefaultUserId;
if (!string.IsNullOrEmpty(userId))
if (userId is not null && !userId.Equals(default))
{
var user = _userManager.GetUserById(Guid.Parse(userId));
var user = _userManager.GetUserById(userId.Value);
if (user is not null)
{

View File

@ -54,9 +54,9 @@ public class DlnaManager : IDlnaManager
_appHost = appHost;
}
private string UserProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "user");
private string UserProfilesPath => Path.Combine(_appPaths.PluginConfigurationsPath, "dlna", "user");
private string SystemProfilesPath => Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "system");
private string SystemProfilesPath => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "profiles");
public async Task InitProfilesAsync()
{
@ -234,7 +234,7 @@ public class DlnaManager : IDlnaManager
.Where(i => i is not null)
.ToList()!; // We just filtered out all the nulls
}
catch (IOException)
catch (Exception)
{
return Array.Empty<DeviceProfile>();
}

View File

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using Jellyfin.Plugin.Dlna.Configuration;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.Plugins;
using MediaBrowser.Model.Serialization;
namespace Jellyfin.Plugin.Dlna;
@ -9,7 +11,7 @@ namespace Jellyfin.Plugin.Dlna;
/// <summary>
/// DLNA plugin for Jellyfin.
/// </summary>
public class DlnaPlugin : BasePlugin<DlnaPluginConfiguration>
public class DlnaPlugin : BasePlugin<DlnaPluginConfiguration>, IHasWebPages
{
public static DlnaPlugin Instance { get; private set; } = null!;
@ -27,4 +29,23 @@ public class DlnaPlugin : BasePlugin<DlnaPluginConfiguration>
/// <inheritdoc />
public override string Description => "Use Jellyfin as a DLNA server.";
/// <inheritdoc />
public IEnumerable<PluginPageInfo> GetPages()
{
return new[]
{
new PluginPageInfo
{
Name = "dlna",
EmbeddedResourcePath = GetType().Namespace + ".Configuration.config.html",
EnableInMainMenu = true
},
new PluginPageInfo
{
Name = "dlnajs",
EmbeddedResourcePath = GetType().Namespace + ".Configuration.config.js"
},
};
}
}

View File

@ -14,4 +14,10 @@
<ProjectReference Include="..\Jellyfin.Plugin.Dlna.Playback\Jellyfin.Plugin.Dlna.Playback.csproj" />
<ProjectReference Include="..\Rssdp\Rssdp.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Configuration\config.html" />
<EmbeddedResource Include="Configuration\config.js" />
<EmbeddedResource Include="Profiles\Xml\*.xml" />
</ItemGroup>
</Project>