using System.Collections.Generic; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Events; using MediaBrowser.Common.Implementations.Configuration; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Events; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; using System.IO; using System.Linq; using MediaBrowser.Common.IO; namespace MediaBrowser.Server.Implementations.Configuration { /// /// Class ServerConfigurationManager /// public class ServerConfigurationManager : BaseConfigurationManager, IServerConfigurationManager { private readonly IFileSystem _fileSystem; /// /// Initializes a new instance of the class. /// /// The application paths. /// The log manager. /// The XML serializer. public ServerConfigurationManager(IApplicationPaths applicationPaths, ILogManager logManager, IXmlSerializer xmlSerializer, IFileSystem fileSystem) : base(applicationPaths, logManager, xmlSerializer) { _fileSystem = fileSystem; UpdateItemsByNamePath(); UpdateMetadataPath(); } public event EventHandler> ConfigurationUpdating; /// /// Gets the type of the configuration. /// /// The type of the configuration. protected override Type ConfigurationType { get { return typeof(ServerConfiguration); } } /// /// Gets the application paths. /// /// The application paths. public IServerApplicationPaths ApplicationPaths { get { return (IServerApplicationPaths)CommonApplicationPaths; } } /// /// Gets the configuration. /// /// The configuration. public ServerConfiguration Configuration { get { return (ServerConfiguration)CommonConfiguration; } } /// /// Called when [configuration updated]. /// protected override void OnConfigurationUpdated() { UpdateItemsByNamePath(); UpdateMetadataPath(); base.OnConfigurationUpdated(); } public override void AddParts(IEnumerable factories) { base.AddParts(factories); UpdateTranscodingTempPath(); } /// /// Updates the items by name path. /// private void UpdateItemsByNamePath() { if (!Configuration.MergeMetadataAndImagesByName) { ((ServerApplicationPaths)ApplicationPaths).ItemsByNamePath = string.IsNullOrEmpty(Configuration.ItemsByNamePath) ? null : Configuration.ItemsByNamePath; } } /// /// Updates the metadata path. /// private void UpdateMetadataPath() { string metadataPath; if (string.IsNullOrWhiteSpace(Configuration.MetadataPath)) { metadataPath = GetInternalMetadataPath(); } else if (Configuration.EnableCustomPathSubFolders) { metadataPath = Path.Combine(Configuration.MetadataPath, "metadata"); } else { metadataPath = Configuration.MetadataPath; } ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = metadataPath; if (Configuration.MergeMetadataAndImagesByName) { ((ServerApplicationPaths)ApplicationPaths).ItemsByNamePath = ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath; } } private string GetInternalMetadataPath() { if (Configuration.EnableStandaloneMetadata) { return Path.Combine(ApplicationPaths.ProgramDataPath, "metadata"); } return null; } /// /// Updates the transcoding temporary path. /// private void UpdateTranscodingTempPath() { var encodingConfig = this.GetConfiguration("encoding"); ((ServerApplicationPaths)ApplicationPaths).TranscodingTempPath = string.IsNullOrEmpty(encodingConfig.TranscodingTempPath) ? null : Path.Combine(encodingConfig.TranscodingTempPath, "transcoding-temp"); } protected override void OnNamedConfigurationUpdated(string key, object configuration) { base.OnNamedConfigurationUpdated(key, configuration); if (string.Equals(key, "encoding", StringComparison.OrdinalIgnoreCase)) { UpdateTranscodingTempPath(); } } /// /// Replaces the configuration. /// /// The new configuration. /// public override void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration) { var newConfig = (ServerConfiguration)newConfiguration; ValidateItemByNamePath(newConfig); ValidatePathSubstitutions(newConfig); ValidateMetadataPath(newConfig); EventHelper.FireEventIfNotNull(ConfigurationUpdating, this, new GenericEventArgs { Argument = newConfig }, Logger); base.ReplaceConfiguration(newConfiguration); } private void ValidatePathSubstitutions(ServerConfiguration newConfig) { foreach (var map in newConfig.PathSubstitutions) { if (string.IsNullOrWhiteSpace(map.From) || string.IsNullOrWhiteSpace(map.To)) { throw new ArgumentException("Invalid path substitution"); } } } /// /// Replaces the item by name path. /// /// The new configuration. /// private void ValidateItemByNamePath(ServerConfiguration newConfig) { var newPath = newConfig.ItemsByNamePath; if (!string.IsNullOrWhiteSpace(newPath) && !string.Equals(Configuration.ItemsByNamePath ?? string.Empty, newPath)) { // Validate if (!_fileSystem.DirectoryExists(newPath)) { throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath)); } } } /// /// Validates the metadata path. /// /// The new configuration. /// private void ValidateMetadataPath(ServerConfiguration newConfig) { var newPath = newConfig.MetadataPath; if (!string.IsNullOrWhiteSpace(newPath) && !string.Equals(Configuration.MetadataPath ?? string.Empty, newPath)) { // Validate if (!_fileSystem.DirectoryExists(newPath)) { throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath)); } } } public void DisableMetadataService(string service) { DisableMetadataService(typeof(Movie), Configuration, service); DisableMetadataService(typeof(Episode), Configuration, service); DisableMetadataService(typeof(Series), Configuration, service); DisableMetadataService(typeof(Season), Configuration, service); DisableMetadataService(typeof(MusicArtist), Configuration, service); DisableMetadataService(typeof(MusicAlbum), Configuration, service); DisableMetadataService(typeof(MusicVideo), Configuration, service); DisableMetadataService(typeof(Video), Configuration, service); } private void DisableMetadataService(Type type, ServerConfiguration config, string service) { var options = GetMetadataOptions(type, config); if (!options.DisabledMetadataSavers.Contains(service, StringComparer.OrdinalIgnoreCase)) { var list = options.DisabledMetadataSavers.ToList(); list.Add(service); options.DisabledMetadataSavers = list.ToArray(); } } private MetadataOptions GetMetadataOptions(Type type, ServerConfiguration config) { var options = config.MetadataOptions .FirstOrDefault(i => string.Equals(i.ItemType, type.Name, StringComparison.OrdinalIgnoreCase)); if (options == null) { var list = config.MetadataOptions.ToList(); options = new MetadataOptions { ItemType = type.Name }; list.Add(options); config.MetadataOptions = list.ToArray(); } return options; } } }