using System; using System.Globalization; using System.IO; using Emby.Server.Implementations.AppBase; using Jellyfin.Data.Events; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Serialization; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Configuration { /// /// Class ServerConfigurationManager. /// public class ServerConfigurationManager : BaseConfigurationManager, IServerConfigurationManager { /// /// Initializes a new instance of the class. /// /// The application paths. /// The logger factory. /// The XML serializer. public ServerConfigurationManager( IApplicationPaths applicationPaths, ILoggerFactory loggerFactory, IXmlSerializer xmlSerializer) : base(applicationPaths, loggerFactory, xmlSerializer) { UpdateMetadataPath(); } /// /// Configuration updating event. /// public event EventHandler>? ConfigurationUpdating; /// /// Gets the type of the configuration. /// /// The type of the configuration. protected override Type ConfigurationType => typeof(ServerConfiguration); /// /// Gets the application paths. /// /// The application paths. public IServerApplicationPaths ApplicationPaths => (IServerApplicationPaths)CommonApplicationPaths; /// /// Gets the configuration. /// /// The configuration. public ServerConfiguration Configuration => (ServerConfiguration)CommonConfiguration; /// /// Called when [configuration updated]. /// protected override void OnConfigurationUpdated() { UpdateMetadataPath(); base.OnConfigurationUpdated(); } /// /// Updates the metadata path. /// /// If the directory does not exist, and the caller does not have the required permission to create it. /// If there is a custom path transcoding path specified, but it is invalid. /// If the directory does not exist, and it also could not be created. private void UpdateMetadataPath() { ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrWhiteSpace(Configuration.MetadataPath) ? ApplicationPaths.DefaultInternalMetadataPath : Configuration.MetadataPath; Directory.CreateDirectory(ApplicationPaths.InternalMetadataPath); } /// /// Replaces the configuration. /// /// The new configuration. /// If the configuration path doesn't exist. public override void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration) { var newConfig = (ServerConfiguration)newConfiguration; ValidateMetadataPath(newConfig); ConfigurationUpdating?.Invoke(this, new GenericEventArgs(newConfig)); base.ReplaceConfiguration(newConfiguration); } /// /// Validates the metadata path. /// /// The new configuration. /// The new config path doesn't exist. private void ValidateMetadataPath(ServerConfiguration newConfig) { var newPath = newConfig.MetadataPath; if (!string.IsNullOrWhiteSpace(newPath) && !string.Equals(Configuration.MetadataPath, newPath, StringComparison.Ordinal)) { if (!Directory.Exists(newPath)) { throw new DirectoryNotFoundException( string.Format( CultureInfo.InvariantCulture, "{0} does not exist.", newPath)); } EnsureWriteAccess(newPath); } } } }