diff --git a/src/Jellyfin.Plugin.Dlna/Configuration/DlnaPluginConfiguration.cs b/src/Jellyfin.Plugin.Dlna/Configuration/DlnaPluginConfiguration.cs index f1747eb..1a04a15 100644 --- a/src/Jellyfin.Plugin.Dlna/Configuration/DlnaPluginConfiguration.cs +++ b/src/Jellyfin.Plugin.Dlna/Configuration/DlnaPluginConfiguration.cs @@ -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; /// - /// gets or sets a value indicating whether to send only matched host. + /// Gets or sets a value indicating whether to send only matched host. /// public bool SendOnlyMatchedHost { get; set; } = true; /// /// Gets or sets the default user account that the dlna server uses. /// - public string? DefaultUserId { get; set; } + public Guid? DefaultUserId { get; set; } } diff --git a/src/Jellyfin.Plugin.Dlna/Configuration/config.html b/src/Jellyfin.Plugin.Dlna/Configuration/config.html new file mode 100644 index 0000000..1ef63d4 --- /dev/null +++ b/src/Jellyfin.Plugin.Dlna/Configuration/config.html @@ -0,0 +1,72 @@ + + + + + DLNA + + +
+
+
+
+
+
+

DNLA Settings:

+ ${Help} +
+
+
+ +
+ +
+ +
+ The SSDP client discovery interval time in seconds. + The is the time after which the server will send a SSDP search request. +
+
+ +
+ +
+ +
+ +
+ The frequency at which SSDP alive notifications are transmitted in seconds. +
+
+ +
+ +
+ +
+ +
+
+
+ + +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/src/Jellyfin.Plugin.Dlna/Configuration/config.js b/src/Jellyfin.Plugin.Dlna/Configuration/config.js new file mode 100644 index 0000000..ed44682 --- /dev/null +++ b/src/Jellyfin.Plugin.Dlna/Configuration/config.js @@ -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 += ''; + for(let i = 0, length = users.length; i < length; i++) { + const user = users[i]; + html += ''; + } + + 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); + }); +} \ No newline at end of file diff --git a/src/Jellyfin.Plugin.Dlna/ContentDirectory/ContentDirectoryService.cs b/src/Jellyfin.Plugin.Dlna/ContentDirectory/ContentDirectoryService.cs index d30bc12..81c1234 100644 --- a/src/Jellyfin.Plugin.Dlna/ContentDirectory/ContentDirectoryService.cs +++ b/src/Jellyfin.Plugin.Dlna/ContentDirectory/ContentDirectoryService.cs @@ -143,9 +143,9 @@ public Task ProcessControlRequestAsync(ControlRequest request) 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) { diff --git a/src/Jellyfin.Plugin.Dlna/DlnaManager.cs b/src/Jellyfin.Plugin.Dlna/DlnaManager.cs index 3f65426..1bdb16c 100644 --- a/src/Jellyfin.Plugin.Dlna/DlnaManager.cs +++ b/src/Jellyfin.Plugin.Dlna/DlnaManager.cs @@ -54,9 +54,9 @@ public DlnaManager( _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 @@ private IEnumerable GetProfiles(string path, DeviceProfileType ty .Where(i => i is not null) .ToList()!; // We just filtered out all the nulls } - catch (IOException) + catch (Exception) { return Array.Empty(); } diff --git a/src/Jellyfin.Plugin.Dlna/DlnaPlugin.cs b/src/Jellyfin.Plugin.Dlna/DlnaPlugin.cs index 7466e7b..697debd 100644 --- a/src/Jellyfin.Plugin.Dlna/DlnaPlugin.cs +++ b/src/Jellyfin.Plugin.Dlna/DlnaPlugin.cs @@ -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; /// /// DLNA plugin for Jellyfin. /// -public class DlnaPlugin : BasePlugin +public class DlnaPlugin : BasePlugin, IHasWebPages { public static DlnaPlugin Instance { get; private set; } = null!; @@ -27,4 +29,23 @@ public DlnaPlugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializ /// public override string Description => "Use Jellyfin as a DLNA server."; + + /// + public IEnumerable 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" + }, + }; + } } \ No newline at end of file diff --git a/src/Jellyfin.Plugin.Dlna/Jellyfin.Plugin.Dlna.csproj b/src/Jellyfin.Plugin.Dlna/Jellyfin.Plugin.Dlna.csproj index dce81c8..ce45e45 100644 --- a/src/Jellyfin.Plugin.Dlna/Jellyfin.Plugin.Dlna.csproj +++ b/src/Jellyfin.Plugin.Dlna/Jellyfin.Plugin.Dlna.csproj @@ -14,4 +14,10 @@ + + + + + +