From c534c450330759f6595c9601e3fe8b12e6987e69 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Wed, 27 Oct 2021 19:20:14 -0600 Subject: Suggestions from review --- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index d1e999666..37dc49d7a 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -459,5 +459,10 @@ namespace MediaBrowser.Model.Configuration /// Gets or sets a value indicating whether older plugins should automatically be deleted from the plugin folder. /// public bool RemoveOldPlugins { get; set; } + + /// + /// Gets or sets a value indicating whether clients should be allowed to upload logs. + /// + public bool AllowClientLogUpload { get; set; } } } -- cgit v1.2.3 From 73201ed498ade1b2731b58f7e8fe1f0aba54a3e5 Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Fri, 29 Oct 2021 06:33:46 -0600 Subject: Default log upload to enabled --- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 37dc49d7a..b79d18abd 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -463,6 +463,6 @@ namespace MediaBrowser.Model.Configuration /// /// Gets or sets a value indicating whether clients should be allowed to upload logs. /// - public bool AllowClientLogUpload { get; set; } + public bool AllowClientLogUpload { get; set; } = true; } } -- cgit v1.2.3 From 96ea865681cf6be9dbe870974c007c668c6bc22b Mon Sep 17 00:00:00 2001 From: cvium Date: Fri, 19 Nov 2021 15:32:07 +0100 Subject: Refactor omdb providers --- .../Configuration/ServerConfiguration.cs | 2 - .../Plugins/Omdb/OmdbEpisodeProvider.cs | 37 ++-- .../Plugins/Omdb/OmdbImageProvider.cs | 50 ++--- .../Plugins/Omdb/OmdbItemProvider.cs | 220 +++++++++------------ .../Plugins/Omdb/OmdbProvider.cs | 126 ++++++------ 5 files changed, 195 insertions(+), 240 deletions(-) (limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs') diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index b79d18abd..0ab721b77 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -402,8 +402,6 @@ namespace MediaBrowser.Model.Configuration /// public bool RequireHttps { get; set; } = false; - public bool EnableNewOmdbSupport { get; set; } = true; - /// /// Gets or sets the filter for remote IP connectivity. Used in conjuntion with . /// diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs index 410217098..d8b33a799 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; @@ -17,24 +16,17 @@ namespace MediaBrowser.Providers.Plugins.Omdb { public class OmdbEpisodeProvider : IRemoteMetadataProvider, IHasOrder { - private readonly IHttpClientFactory _httpClientFactory; private readonly OmdbItemProvider _itemProvider; - private readonly IFileSystem _fileSystem; - private readonly IServerConfigurationManager _configurationManager; - private readonly IApplicationHost _appHost; + private readonly OmdbProvider _omdbProvider; public OmdbEpisodeProvider( - IApplicationHost appHost, IHttpClientFactory httpClientFactory, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager configurationManager) { - _httpClientFactory = httpClientFactory; - _fileSystem = fileSystem; - _configurationManager = configurationManager; - _appHost = appHost; - _itemProvider = new OmdbItemProvider(_appHost, httpClientFactory, libraryManager, fileSystem, configurationManager); + _itemProvider = new OmdbItemProvider(httpClientFactory, libraryManager, fileSystem, configurationManager); + _omdbProvider = new OmdbProvider(httpClientFactory, fileSystem, configurationManager); } // After TheTvDb @@ -44,12 +36,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb public Task> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken) { - return _itemProvider.GetSearchResults(searchInfo, "episode", cancellationToken); + return _itemProvider.GetSearchResults(searchInfo, cancellationToken); } public async Task> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken) { - var result = new MetadataResult() + var result = new MetadataResult { Item = new Episode(), QueriedById = true @@ -61,13 +53,20 @@ namespace MediaBrowser.Providers.Plugins.Omdb return result; } - if (info.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out string? seriesImdbId) && !string.IsNullOrEmpty(seriesImdbId)) + if (info.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out string? seriesImdbId) + && !string.IsNullOrEmpty(seriesImdbId) + && info.IndexNumber.HasValue + && info.ParentIndexNumber.HasValue) { - if (info.IndexNumber.HasValue && info.ParentIndexNumber.HasValue) - { - result.HasMetadata = await new OmdbProvider(_httpClientFactory, _fileSystem, _configurationManager) - .FetchEpisodeData(result, info.IndexNumber.Value, info.ParentIndexNumber.Value, info.GetProviderId(MetadataProvider.Imdb), seriesImdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); - } + result.HasMetadata = await _omdbProvider.FetchEpisodeData( + result, + info.IndexNumber.Value, + info.ParentIndexNumber.Value, + info.GetProviderId(MetadataProvider.Imdb), + seriesImdbId, + info.MetadataLanguage, + info.MetadataCountryCode, + cancellationToken).ConfigureAwait(false); } return result; diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs index 0a7208349..178f8ed46 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbImageProvider.cs @@ -2,8 +2,9 @@ #pragma warning disable CS1591 +using System; using System.Collections.Generic; -using System.Globalization; +using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -22,14 +23,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb public class OmdbImageProvider : IRemoteImageProvider, IHasOrder { private readonly IHttpClientFactory _httpClientFactory; - private readonly IFileSystem _fileSystem; - private readonly IServerConfigurationManager _configurationManager; + private readonly OmdbProvider _omdbProvider; public OmdbImageProvider(IHttpClientFactory httpClientFactory, IFileSystem fileSystem, IServerConfigurationManager configurationManager) { _httpClientFactory = httpClientFactory; - _fileSystem = fileSystem; - _configurationManager = configurationManager; + _omdbProvider = new OmdbProvider(_httpClientFactory, fileSystem, configurationManager); } public string Name => "The Open Movie Database"; @@ -49,38 +48,27 @@ namespace MediaBrowser.Providers.Plugins.Omdb public async Task> GetImages(BaseItem item, CancellationToken cancellationToken) { var imdbId = item.GetProviderId(MetadataProvider.Imdb); + if (string.IsNullOrWhiteSpace(imdbId)) + { + return Enumerable.Empty(); + } - var list = new List(); - - var provider = new OmdbProvider(_httpClientFactory, _fileSystem, _configurationManager); + var rootObject = await _omdbProvider.GetRootObject(imdbId, cancellationToken).ConfigureAwait(false); - if (!string.IsNullOrWhiteSpace(imdbId)) + if (string.IsNullOrEmpty(rootObject.Poster) || string.Equals("N/A", rootObject.Poster, StringComparison.OrdinalIgnoreCase)) { - var rootObject = await provider.GetRootObject(imdbId, cancellationToken).ConfigureAwait(false); + return Enumerable.Empty(); + } - if (!string.IsNullOrEmpty(rootObject.Poster)) + // the poster url is sometimes higher quality than the poster api + return new[] + { + new RemoteImageInfo { - if (item is Episode) - { - // img.omdbapi.com is returning 404's - list.Add(new RemoteImageInfo - { - ProviderName = Name, - Url = rootObject.Poster - }); - } - else - { - list.Add(new RemoteImageInfo - { - ProviderName = Name, - Url = string.Format(CultureInfo.InvariantCulture, "https://img.omdbapi.com/?i={0}&apikey=2c9d9507", imdbId) - }); - } + ProviderName = Name, + Url = rootObject.Poster } - } - - return list; + }; } public Task GetImageResponse(string url, CancellationToken cancellationToken) diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs index 35bc3ce6b..db5e52899 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs @@ -8,11 +8,11 @@ using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; +using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Jellyfin.Extensions.Json; -using MediaBrowser.Common; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -31,13 +31,10 @@ namespace MediaBrowser.Providers.Plugins.Omdb { private readonly IHttpClientFactory _httpClientFactory; private readonly ILibraryManager _libraryManager; - private readonly IFileSystem _fileSystem; - private readonly IServerConfigurationManager _configurationManager; - private readonly IApplicationHost _appHost; private readonly JsonSerializerOptions _jsonOptions; + private readonly OmdbProvider _omdbProvider; public OmdbItemProvider( - IApplicationHost appHost, IHttpClientFactory httpClientFactory, ILibraryManager libraryManager, IFileSystem fileSystem, @@ -45,9 +42,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb { _httpClientFactory = httpClientFactory; _libraryManager = libraryManager; - _fileSystem = fileSystem; - _configurationManager = configurationManager; - _appHost = appHost; + _omdbProvider = new OmdbProvider(_httpClientFactory, fileSystem, configurationManager); _jsonOptions = new JsonSerializerOptions(JsonDefaults.Options); _jsonOptions.Converters.Add(new JsonOmdbNotAvailableStringConverter()); @@ -59,185 +54,167 @@ namespace MediaBrowser.Providers.Plugins.Omdb // After primary option public int Order => 2; + public Task> GetSearchResults(TrailerInfo searchInfo, CancellationToken cancellationToken) + { + return GetSearchResultsInternal(searchInfo, true, cancellationToken); + } + public Task> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken) { - return GetSearchResults(searchInfo, "series", cancellationToken); + return GetSearchResultsInternal(searchInfo, true, cancellationToken); } public Task> GetSearchResults(MovieInfo searchInfo, CancellationToken cancellationToken) { - return GetSearchResults(searchInfo, "movie", cancellationToken); + return GetSearchResultsInternal(searchInfo, true, cancellationToken); } - public Task> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken) + public Task> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken) { - return GetSearchResultsInternal(searchInfo, type, true, cancellationToken); + return GetSearchResultsInternal(searchInfo, true, cancellationToken); } - private async Task> GetSearchResultsInternal(ItemLookupInfo searchInfo, string type, bool isSearch, CancellationToken cancellationToken) + private async Task> GetSearchResultsInternal(ItemLookupInfo searchInfo, bool isSearch, CancellationToken cancellationToken) { + var type = searchInfo switch + { + EpisodeInfo => "episode", + SeriesInfo => "series", + _ => "movie" + }; + + // This is a bit hacky? var episodeSearchInfo = searchInfo as EpisodeInfo; + var indexNumberEnd = episodeSearchInfo?.IndexNumberEnd; var imdbId = searchInfo.GetProviderId(MetadataProvider.Imdb); - var urlQuery = "plot=full&r=json"; - if (type == "episode" && episodeSearchInfo != null) + var urlQuery = new StringBuilder("plot=full&r=json"); + if (episodeSearchInfo != null) { episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out imdbId); - } - - var name = searchInfo.Name; - var year = searchInfo.Year; + if (searchInfo.IndexNumber.HasValue) + { + urlQuery.AppendFormat(CultureInfo.InvariantCulture, "&Episode={0}", searchInfo.IndexNumber); + } - if (!string.IsNullOrWhiteSpace(name)) - { - var parsedName = _libraryManager.ParseName(name); - var yearInName = parsedName.Year; - name = parsedName.Name; - year ??= yearInName; + if (searchInfo.ParentIndexNumber.HasValue) + { + urlQuery.AppendFormat(CultureInfo.InvariantCulture, "&Season={0}", searchInfo.ParentIndexNumber); + } } if (string.IsNullOrWhiteSpace(imdbId)) { - if (year.HasValue) + var name = searchInfo.Name; + var year = searchInfo.Year; + if (!string.IsNullOrWhiteSpace(name)) { - urlQuery += "&y=" + year.Value.ToString(CultureInfo.InvariantCulture); + var parsedName = _libraryManager.ParseName(name); + var yearInName = parsedName.Year; + name = parsedName.Name; + year ??= yearInName; } - // &s means search and returns a list of results as opposed to t - if (isSearch) - { - urlQuery += "&s=" + WebUtility.UrlEncode(name); - } - else + if (year.HasValue) { - urlQuery += "&t=" + WebUtility.UrlEncode(name); + urlQuery.Append("&y=") + .Append(year); } - urlQuery += "&type=" + type; + // &s means search and returns a list of results as opposed to t + urlQuery.Append(isSearch ? "&s=" : "&t="); + urlQuery.Append(WebUtility.UrlEncode(name)); + urlQuery.Append("&type=") + .Append(type); } else { - urlQuery += "&i=" + imdbId; + urlQuery.Append("&i=") + .Append(imdbId); isSearch = false; } - if (type == "episode") - { - if (searchInfo.IndexNumber.HasValue) - { - urlQuery += string.Format(CultureInfo.InvariantCulture, "&Episode={0}", searchInfo.IndexNumber); - } - - if (searchInfo.ParentIndexNumber.HasValue) - { - urlQuery += string.Format(CultureInfo.InvariantCulture, "&Season={0}", searchInfo.ParentIndexNumber); - } - } - - var url = OmdbProvider.GetOmdbUrl(urlQuery); + var url = OmdbProvider.GetOmdbUrl(urlQuery.ToString()); - using var response = await OmdbProvider.GetOmdbResponse(_httpClientFactory.CreateClient(NamedClient.Default), url, cancellationToken).ConfigureAwait(false); + using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false); await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - var resultList = new List(); if (isSearch) { var searchResultList = await JsonSerializer.DeserializeAsync(stream, _jsonOptions, cancellationToken).ConfigureAwait(false); - if (searchResultList != null && searchResultList.Search != null) + if (searchResultList?.Search != null) { - resultList.AddRange(searchResultList.Search); + var resultCount = searchResultList.Search.Count; + var result = new RemoteSearchResult[resultCount]; + for (var i = 0; i < resultCount; i++) + { + result[i] = ResultToMetadataResult(searchResultList.Search[i], searchInfo, indexNumberEnd); + } + + return result; } } else { var result = await JsonSerializer.DeserializeAsync(stream, _jsonOptions, cancellationToken).ConfigureAwait(false); - if (string.Equals(result.Response, "true", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(result?.Response, "true", StringComparison.OrdinalIgnoreCase)) { - resultList.Add(result); + return new[] { ResultToMetadataResult(result, searchInfo, indexNumberEnd) }; } } - return resultList.Select(result => - { - var item = new RemoteSearchResult - { - IndexNumber = searchInfo.IndexNumber, - Name = result.Title, - ParentIndexNumber = searchInfo.ParentIndexNumber, - SearchProviderName = Name - }; - - if (episodeSearchInfo != null && episodeSearchInfo.IndexNumberEnd.HasValue) - { - item.IndexNumberEnd = episodeSearchInfo.IndexNumberEnd.Value; - } - - item.SetProviderId(MetadataProvider.Imdb, result.imdbID); - - if (result.Year.Length > 0 - && int.TryParse(result.Year.AsSpan().Slice(0, Math.Min(result.Year.Length, 4)), NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedYear)) - { - item.ProductionYear = parsedYear; - } - - if (!string.IsNullOrEmpty(result.Released) - && DateTime.TryParse(result.Released, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out var released)) - { - item.PremiereDate = released; - } - - if (!string.IsNullOrWhiteSpace(result.Poster) && !string.Equals(result.Poster, "N/A", StringComparison.OrdinalIgnoreCase)) - { - item.ImageUrl = result.Poster; - } - - return item; - }); + return Enumerable.Empty(); } public Task> GetMetadata(TrailerInfo info, CancellationToken cancellationToken) { - return GetMovieResult(info, cancellationToken); + return GetResult(info, cancellationToken); } - public Task> GetSearchResults(TrailerInfo searchInfo, CancellationToken cancellationToken) + public Task> GetMetadata(SeriesInfo info, CancellationToken cancellationToken) { - return GetSearchResults(searchInfo, "movie", cancellationToken); + return GetResult(info, cancellationToken); } - public async Task> GetMetadata(SeriesInfo info, CancellationToken cancellationToken) + public Task> GetMetadata(MovieInfo info, CancellationToken cancellationToken) { - var result = new MetadataResult + return GetResult(info, cancellationToken); + } + + private RemoteSearchResult ResultToMetadataResult(SearchResult result, ItemLookupInfo searchInfo, int? indexNumberEnd) + { + var item = new RemoteSearchResult { - Item = new Series(), - QueriedById = true + IndexNumber = searchInfo.IndexNumber, + Name = result.Title, + ParentIndexNumber = searchInfo.ParentIndexNumber, + SearchProviderName = Name, + IndexNumberEnd = indexNumberEnd }; - var imdbId = info.GetProviderId(MetadataProvider.Imdb); - if (string.IsNullOrWhiteSpace(imdbId)) + item.SetProviderId(MetadataProvider.Imdb, result.imdbID); + + if (OmdbProvider.TryParseYear(result.Year, out var parsedYear)) { - imdbId = await GetSeriesImdbId(info, cancellationToken).ConfigureAwait(false); - result.QueriedById = false; + item.ProductionYear = parsedYear; } - if (!string.IsNullOrEmpty(imdbId)) + if (!string.IsNullOrEmpty(result.Released) + && DateTime.TryParse(result.Released, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out var released)) { - result.Item.SetProviderId(MetadataProvider.Imdb, imdbId); - result.HasMetadata = true; - - await new OmdbProvider(_httpClientFactory, _fileSystem, _configurationManager).Fetch(result, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); + item.PremiereDate = released; } - return result; - } + if (!string.IsNullOrWhiteSpace(result.Poster) && !string.Equals(result.Poster, "N/A", StringComparison.OrdinalIgnoreCase)) + { + item.ImageUrl = result.Poster; + } - public Task> GetMetadata(MovieInfo info, CancellationToken cancellationToken) - { - return GetMovieResult(info, cancellationToken); + return item; } - private async Task> GetMovieResult(ItemLookupInfo info, CancellationToken cancellationToken) + private async Task> GetResult(ItemLookupInfo info, CancellationToken cancellationToken) where T : BaseItem, new() { var result = new MetadataResult @@ -249,7 +226,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb var imdbId = info.GetProviderId(MetadataProvider.Imdb); if (string.IsNullOrWhiteSpace(imdbId)) { - imdbId = await GetMovieImdbId(info, cancellationToken).ConfigureAwait(false); + imdbId = await GetImdbId(info, cancellationToken).ConfigureAwait(false); result.QueriedById = false; } @@ -258,22 +235,15 @@ namespace MediaBrowser.Providers.Plugins.Omdb result.Item.SetProviderId(MetadataProvider.Imdb, imdbId); result.HasMetadata = true; - await new OmdbProvider(_httpClientFactory, _fileSystem, _configurationManager).Fetch(result, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); + await _omdbProvider.Fetch(result, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); } return result; } - private async Task GetMovieImdbId(ItemLookupInfo info, CancellationToken cancellationToken) - { - var results = await GetSearchResultsInternal(info, "movie", false, cancellationToken).ConfigureAwait(false); - var first = results.FirstOrDefault(); - return first?.GetProviderId(MetadataProvider.Imdb); - } - - private async Task GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken) + private async Task GetImdbId(ItemLookupInfo info, CancellationToken cancellationToken) { - var results = await GetSearchResultsInternal(info, "series", false, cancellationToken).ConfigureAwait(false); + var results = await GetSearchResultsInternal(info, false, cancellationToken).ConfigureAwait(false); var first = results.FirstOrDefault(); return first?.GetProviderId(MetadataProvider.Imdb); } diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs index 7fe9fac4f..12ea2d55b 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs @@ -4,10 +4,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; +using System.Net.Http.Json; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -40,8 +42,9 @@ namespace MediaBrowser.Providers.Plugins.Omdb _configurationManager = configurationManager; _jsonOptions = new JsonSerializerOptions(JsonDefaults.Options); - _jsonOptions.Converters.Add(new JsonOmdbNotAvailableStringConverter()); - _jsonOptions.Converters.Add(new JsonOmdbNotAvailableInt32Converter()); + // These converters need to take priority + _jsonOptions.Converters.Insert(0, new JsonOmdbNotAvailableStringConverter()); + _jsonOptions.Converters.Insert(0, new JsonOmdbNotAvailableInt32Converter()); } /// Fetches data from OMDB service. @@ -64,8 +67,9 @@ namespace MediaBrowser.Providers.Plugins.Omdb var result = await GetRootObject(imdbId, cancellationToken).ConfigureAwait(false); + var isEnglishRequested = IsConfiguredForEnglish(item, language); // Only take the name and rating if the user's language is set to English, since Omdb has no localization - if (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase) || _configurationManager.Configuration.EnableNewOmdbSupport) + if (isEnglishRequested) { item.Name = result.Title; @@ -75,9 +79,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb } } - if (!string.IsNullOrEmpty(result.Year) && result.Year.Length >= 4 - && int.TryParse(result.Year.AsSpan().Slice(0, 4), NumberStyles.Number, CultureInfo.InvariantCulture, out var year) - && year >= 0) + if (TryParseYear(result.Year, out var year)) { item.ProductionYear = year; } @@ -113,7 +115,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb item.SetProviderId(MetadataProvider.Imdb, result.imdbID); } - ParseAdditionalMetadata(itemResult, result); + ParseAdditionalMetadata(itemResult, result, isEnglishRequested); } /// Gets data about an episode. @@ -176,8 +178,9 @@ namespace MediaBrowser.Providers.Plugins.Omdb return false; } + var isEnglishRequested = IsConfiguredForEnglish(item, language); // Only take the name and rating if the user's language is set to English, since Omdb has no localization - if (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase) || _configurationManager.Configuration.EnableNewOmdbSupport) + if (isEnglishRequested) { item.Name = result.Title; @@ -187,9 +190,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb } } - if (!string.IsNullOrEmpty(result.Year) && result.Year.Length >= 4 - && int.TryParse(result.Year.AsSpan().Slice(0, 4), NumberStyles.Number, CultureInfo.InvariantCulture, out var year) - && year >= 0) + if (TryParseYear(result.Year, out var year)) { item.ProductionYear = year; } @@ -225,7 +226,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb item.SetProviderId(MetadataProvider.Imdb, result.imdbID); } - ParseAdditionalMetadata(itemResult, result); + ParseAdditionalMetadata(itemResult, result, isEnglishRequested); return true; } @@ -259,6 +260,30 @@ namespace MediaBrowser.Providers.Plugins.Omdb return Url + "&" + query; } + /// + /// Extract the year from a string. + /// + /// The input string. + /// The year. + /// A value indicating whether the input could successfully be parsed as a year. + public static bool TryParseYear(string input, [NotNullWhen(true)] out int? year) + { + if (string.IsNullOrEmpty(input)) + { + year = 0; + return false; + } + + if (int.TryParse(input.AsSpan(0, 4), NumberStyles.Number, CultureInfo.InvariantCulture, out var result)) + { + year = result; + return true; + } + + year = 0; + return false; + } + private async Task EnsureItemInfo(string imdbId, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(imdbId)) @@ -291,7 +316,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb "i={0}&plot=short&tomatoes=true&r=json", imdbParam)); - var rootObject = await GetDeserializedOmdbResponse(_httpClientFactory.CreateClient(NamedClient.Default), url, cancellationToken).ConfigureAwait(false); + var rootObject = await _httpClientFactory.CreateClient(NamedClient.Default).GetFromJsonAsync(url, _jsonOptions, cancellationToken).ConfigureAwait(false); await using FileStream jsonFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous); await JsonSerializer.SerializeAsync(jsonFileStream, rootObject, _jsonOptions, cancellationToken).ConfigureAwait(false); @@ -331,37 +356,13 @@ namespace MediaBrowser.Providers.Plugins.Omdb imdbParam, seasonId)); - var rootObject = await GetDeserializedOmdbResponse(_httpClientFactory.CreateClient(NamedClient.Default), url, cancellationToken).ConfigureAwait(false); + var rootObject = await _httpClientFactory.CreateClient(NamedClient.Default).GetFromJsonAsync(url, _jsonOptions, cancellationToken).ConfigureAwait(false); await using FileStream jsonFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous); await JsonSerializer.SerializeAsync(jsonFileStream, rootObject, _jsonOptions, cancellationToken).ConfigureAwait(false); return path; } - /// Gets response from OMDB service as type T. - /// HttpClient instance to use for service call. - /// Http URL to use for service call. - /// CancellationToken to use for service call. - /// The first generic type parameter. - /// OMDB service response as type T. - public async Task GetDeserializedOmdbResponse(HttpClient httpClient, string url, CancellationToken cancellationToken) - { - using var response = await GetOmdbResponse(httpClient, url, cancellationToken).ConfigureAwait(false); - await using Stream content = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - - return await JsonSerializer.DeserializeAsync(content, _jsonOptions, cancellationToken).ConfigureAwait(false); - } - - /// Gets response from OMDB service. - /// HttpClient instance to use for service call. - /// Http URL to use for service call. - /// CancellationToken to use for service call. - /// OMDB service response as HttpResponseMessage. - public static Task GetOmdbResponse(HttpClient httpClient, string url, CancellationToken cancellationToken) - { - return httpClient.GetAsync(url, cancellationToken); - } - internal string GetDataFilePath(string imdbId) { if (string.IsNullOrEmpty(imdbId)) @@ -390,31 +391,25 @@ namespace MediaBrowser.Providers.Plugins.Omdb return Path.Combine(dataPath, filename); } - private void ParseAdditionalMetadata(MetadataResult itemResult, RootObject result) + private static void ParseAdditionalMetadata(MetadataResult itemResult, RootObject result, bool isEnglishRequested) where T : BaseItem { var item = itemResult.Item; - var isConfiguredForEnglish = IsConfiguredForEnglish(item) || _configurationManager.Configuration.EnableNewOmdbSupport; - // Grab series genres because IMDb data is better than TVDB. Leave movies alone // But only do it if English is the preferred language because this data will not be localized - if (isConfiguredForEnglish && !string.IsNullOrWhiteSpace(result.Genre)) + if (isEnglishRequested && !string.IsNullOrWhiteSpace(result.Genre)) { item.Genres = Array.Empty(); - foreach (var genre in result.Genre - .Split(',', StringSplitOptions.RemoveEmptyEntries) - .Select(i => i.Trim()) - .Where(i => !string.IsNullOrWhiteSpace(i))) + foreach (var genre in result.Genre.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) { item.AddGenre(genre); } } - if (isConfiguredForEnglish) + if (isEnglishRequested) { - // Omdb is currently English only, so for other languages skip this and let secondary providers fill it in item.Overview = result.Plot; } @@ -427,7 +422,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb { var person = new PersonInfo { - Name = result.Director.Trim(), + Name = result.Director, Type = PersonType.Director }; @@ -438,7 +433,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb { var person = new PersonInfo { - Name = result.Writer.Trim(), + Name = result.Writer, Type = PersonType.Writer }; @@ -447,29 +442,34 @@ namespace MediaBrowser.Providers.Plugins.Omdb if (!string.IsNullOrWhiteSpace(result.Actors)) { - var actorList = result.Actors.Split(','); + var actorList = result.Actors.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); foreach (var actor in actorList) { - if (!string.IsNullOrWhiteSpace(actor)) + if (string.IsNullOrWhiteSpace(actor)) { - var person = new PersonInfo - { - Name = actor.Trim(), - Type = PersonType.Actor - }; - - itemResult.AddPerson(person); + continue; } + + var person = new PersonInfo + { + Name = actor, + Type = PersonType.Actor + }; + + itemResult.AddPerson(person); } } } - private bool IsConfiguredForEnglish(BaseItem item) + private static bool IsConfiguredForEnglish(BaseItem item, string language) { - var lang = item.GetPreferredMetadataLanguage(); + if (string.IsNullOrEmpty(language)) + { + language = item.GetPreferredMetadataLanguage(); + } // The data isn't localized and so can only be used for English users - return string.Equals(lang, "en", StringComparison.OrdinalIgnoreCase); + return string.Equals(language, "en", StringComparison.OrdinalIgnoreCase); } internal class SeasonRootObject @@ -546,7 +546,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb if (Ratings != null) { var rating = Ratings.FirstOrDefault(i => string.Equals(i.Source, "Rotten Tomatoes", StringComparison.OrdinalIgnoreCase)); - if (rating != null && rating.Value != null) + if (rating?.Value != null) { var value = rating.Value.TrimEnd('%'); if (float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var score)) -- cgit v1.2.3 From 69df004b9f62cb65986607d659fde0dcc74004ab Mon Sep 17 00:00:00 2001 From: cvium Date: Wed, 24 Nov 2021 13:00:12 +0100 Subject: Migrate network configuration safely --- Emby.Server.Implementations/ApplicationHost.cs | 18 -- Jellyfin.Api/Helpers/ClassMigrationHelper.cs | 71 ------- Jellyfin.Server/Migrations/MigrationRunner.cs | 61 +++++- .../CreateNetworkConfiguration.cs | 140 +++++++++++++ Jellyfin.Server/Program.cs | 1 + .../Configuration/ServerConfiguration.cs | 222 --------------------- 6 files changed, 195 insertions(+), 318 deletions(-) delete mode 100644 Jellyfin.Api/Helpers/ClassMigrationHelper.cs create mode 100644 Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs (limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 903c31133..8892f7f40 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -313,22 +313,6 @@ namespace Emby.Server.Implementations ? Environment.MachineName : ConfigurationManager.Configuration.ServerName; - /// - /// Temporary function to migration network settings out of system.xml and into network.xml. - /// TODO: remove at the point when a fixed migration path has been decided upon. - /// - private void MigrateNetworkConfiguration() - { - string path = Path.Combine(ConfigurationManager.CommonApplicationPaths.ConfigurationDirectoryPath, "network.xml"); - if (!File.Exists(path)) - { - var networkSettings = new NetworkConfiguration(); - ClassMigrationHelper.CopyProperties(ConfigurationManager.Configuration, networkSettings); - _xmlSerializer.SerializeToFile(networkSettings, path); - Logger.LogDebug("Successfully migrated network settings."); - } - } - public string ExpandVirtualPath(string path) { var appPaths = ApplicationPaths; @@ -513,8 +497,6 @@ namespace Emby.Server.Implementations ConfigurationManager.AddParts(GetExports()); - // Have to migrate settings here as migration subsystem not yet initialised. - MigrateNetworkConfiguration(); NetManager = new NetworkManager(ConfigurationManager, LoggerFactory.CreateLogger()); // Initialize runtime stat collection diff --git a/Jellyfin.Api/Helpers/ClassMigrationHelper.cs b/Jellyfin.Api/Helpers/ClassMigrationHelper.cs deleted file mode 100644 index 76fb27bcc..000000000 --- a/Jellyfin.Api/Helpers/ClassMigrationHelper.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Reflection; - -namespace Jellyfin.Api.Helpers -{ - /// - /// A static class for copying matching properties from one object to another. - /// TODO: remove at the point when a fixed migration path has been decided upon. - /// - public static class ClassMigrationHelper - { - /// - /// Extension for 'Object' that copies the properties to a destination object. - /// - /// The source. - /// The destination. - public static void CopyProperties(this object source, object destination) - { - // If any this null throw an exception. - if (source == null || destination == null) - { - throw new ArgumentException("Source or/and Destination Objects are null"); - } - - // Getting the Types of the objects. - Type typeDest = destination.GetType(); - Type typeSrc = source.GetType(); - - // Iterate the Properties of the source instance and populate them from their destination counterparts. - PropertyInfo[] srcProps = typeSrc.GetProperties(); - foreach (PropertyInfo srcProp in srcProps) - { - if (!srcProp.CanRead) - { - continue; - } - - var targetProperty = typeDest.GetProperty(srcProp.Name); - if (targetProperty == null) - { - continue; - } - - if (!targetProperty.CanWrite) - { - continue; - } - - var obj = targetProperty.GetSetMethod(true); - if (obj != null && obj.IsPrivate) - { - continue; - } - - var target = targetProperty.GetSetMethod(); - if (target != null && (target.Attributes & MethodAttributes.Static) != 0) - { - continue; - } - - if (!targetProperty.PropertyType.IsAssignableFrom(srcProp.PropertyType)) - { - continue; - } - - // Passed all tests, lets set the value. - targetProperty.SetValue(destination, srcProp.GetValue(source, null), null); - } - } - } -} diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs index 7365c8dbc..11b6c4912 100644 --- a/Jellyfin.Server/Migrations/MigrationRunner.cs +++ b/Jellyfin.Server/Migrations/MigrationRunner.cs @@ -1,6 +1,11 @@ using System; +using System.Collections.Generic; +using System.IO; using System.Linq; +using Emby.Server.Implementations; +using Emby.Server.Implementations.Serialization; using MediaBrowser.Common.Configuration; +using MediaBrowser.Model.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -11,6 +16,14 @@ namespace Jellyfin.Server.Migrations /// public sealed class MigrationRunner { + /// + /// The list of known pre-startup migrations, in order of applicability. + /// + private static readonly Type[] _preStartupMigrationTypes = + { + typeof(PreStartupRoutines.CreateNetworkConfiguration) + }; + /// /// The list of known migrations, in order of applicability. /// @@ -29,6 +42,7 @@ namespace Jellyfin.Server.Migrations typeof(Routines.MigrateAuthenticationDb) }; + /// /// Run all needed migrations. /// @@ -41,17 +55,50 @@ namespace Jellyfin.Server.Migrations .Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m)) .OfType() .ToArray(); + var migrationOptions = host.ConfigurationManager.GetConfiguration(MigrationsListStore.StoreKey); + HandleStartupWizardCondition(migrations, migrationOptions, host.ConfigurationManager.Configuration.IsStartupWizardCompleted, logger); + PerformMigrations(migrations, migrationOptions, options => host.ConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, options), logger); + } - if (!host.ConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0) + /// + /// Run all needed pre-startup migrations. + /// + /// Application paths. + /// Factory for making the logger. + public static void RunPreStartup(ServerApplicationPaths appPaths, ILoggerFactory loggerFactory) + { + var logger = loggerFactory.CreateLogger(); + var migrations = _preStartupMigrationTypes + .Select(m => Activator.CreateInstance(m, appPaths, loggerFactory)) + .OfType() + .ToArray(); + + var xmlSerializer = new MyXmlSerializer(); + var migrationConfigPath = Path.Join(appPaths.ConfigurationDirectoryPath, MigrationsListStore.StoreKey.ToLowerInvariant() + ".xml"); + var migrationOptions = (MigrationOptions)xmlSerializer.DeserializeFromFile(typeof(MigrationOptions), migrationConfigPath)!; + + // We have to deserialize it manually since the configuration manager may overwrite it + var serverConfig = (ServerConfiguration)xmlSerializer.DeserializeFromFile(typeof(ServerConfiguration), appPaths.SystemConfigurationFilePath)!; + HandleStartupWizardCondition(migrations, migrationOptions, serverConfig.IsStartupWizardCompleted, logger); + PerformMigrations(migrations, migrationOptions, options => xmlSerializer.SerializeToFile(options, migrationConfigPath), logger); + } + + private static void HandleStartupWizardCondition(IEnumerable migrations, MigrationOptions migrationOptions, bool isStartWizardCompleted, ILogger logger) + { + if (isStartWizardCompleted || migrationOptions.Applied.Count != 0) { - // If startup wizard is not finished, this is a fresh install. - // Don't run any migrations, just mark all of them as applied. - logger.LogInformation("Marking all known migrations as applied because this is a fresh install"); - migrationOptions.Applied.AddRange(migrations.Where(m => !m.PerformOnNewInstall).Select(m => (m.Id, m.Name))); - host.ConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions); + return; } + // If startup wizard is not finished, this is a fresh install. + var onlyOldInstalls = migrations.Where(m => !m.PerformOnNewInstall).ToArray(); + logger.LogInformation("Marking following migrations as applied because this is a fresh install: {@OnlyOldInstalls}", onlyOldInstalls.Select(m => m.Name)); + migrationOptions.Applied.AddRange(onlyOldInstalls.Select(m => (m.Id, m.Name))); + } + + private static void PerformMigrations(IMigrationRoutine[] migrations, MigrationOptions migrationOptions, Action saveConfiguration, ILogger logger) + { var appliedMigrationIds = migrationOptions.Applied.Select(m => m.Id).ToHashSet(); for (var i = 0; i < migrations.Length; i++) @@ -78,7 +125,7 @@ namespace Jellyfin.Server.Migrations // Mark the migration as completed logger.LogInformation("Migration '{Name}' applied successfully", migrationRoutine.Name); migrationOptions.Applied.Add((migrationRoutine.Id, migrationRoutine.Name)); - host.ConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions); + saveConfiguration(migrationOptions); logger.LogDebug("Migration '{Name}' marked as applied in configuration.", migrationRoutine.Name); } } diff --git a/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs b/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs new file mode 100644 index 000000000..98c845dc3 --- /dev/null +++ b/Jellyfin.Server/Migrations/PreStartupRoutines/CreateNetworkConfiguration.cs @@ -0,0 +1,140 @@ +using System; +using System.IO; +using System.Runtime.Serialization; +using System.Xml; +using System.Xml.Serialization; +using Emby.Server.Implementations; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Server.Migrations.PreStartupRoutines; + +/// +public class CreateNetworkConfiguration : IMigrationRoutine +{ + private readonly ServerApplicationPaths _applicationPaths; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// An instance of . + /// An instance of the interface. + public CreateNetworkConfiguration(ServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory) + { + _applicationPaths = applicationPaths; + _logger = loggerFactory.CreateLogger(); + } + + /// + public Guid Id => Guid.Parse("9B354818-94D5-4B68-AC49-E35CB85F9D84"); + + /// + public string Name => nameof(CreateNetworkConfiguration); + + /// + public bool PerformOnNewInstall => false; + + /// + public void Perform() + { + string path = Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "network.xml"); + if (File.Exists(path)) + { + _logger.LogDebug("Network configuration file already exists, skipping"); + return; + } + + var serverConfigSerializer = new XmlSerializer(typeof(OldNetworkConfiguration), new XmlRootAttribute("ServerConfiguration")); + using var xmlReader = XmlReader.Create(_applicationPaths.SystemConfigurationFilePath); + var networkSettings = serverConfigSerializer.Deserialize(xmlReader); + + var networkConfigSerializer = new XmlSerializer(typeof(OldNetworkConfiguration), new XmlRootAttribute("NetworkConfiguration")); + var xmlWriterSettings = new XmlWriterSettings { Indent = true }; + using var xmlWriter = XmlWriter.Create(path, xmlWriterSettings); + networkConfigSerializer.Serialize(xmlWriter, networkSettings); + } + +#pragma warning disable CS1591 + public sealed class OldNetworkConfiguration + { + public const int DefaultHttpPort = 8096; + + public const int DefaultHttpsPort = 8920; + + private string _baseUrl = string.Empty; + + public bool RequireHttps { get; set; } + + public string CertificatePath { get; set; } = string.Empty; + + public string CertificatePassword { get; set; } = string.Empty; + + public string BaseUrl + { + get => _baseUrl; + set + { + // Normalize the start of the string + if (string.IsNullOrWhiteSpace(value)) + { + // If baseUrl is empty, set an empty prefix string + _baseUrl = string.Empty; + return; + } + + if (value[0] != '/') + { + // If baseUrl was not configured with a leading slash, append one for consistency + value = "/" + value; + } + + // Normalize the end of the string + if (value[^1] == '/') + { + // If baseUrl was configured with a trailing slash, remove it for consistency + value = value.Remove(value.Length - 1); + } + + _baseUrl = value; + } + } + + public int PublicHttpsPort { get; set; } = DefaultHttpsPort; + + public int HttpServerPortNumber { get; set; } = DefaultHttpPort; + + public int HttpsPortNumber { get; set; } = DefaultHttpsPort; + + public bool EnableHttps { get; set; } + + public int PublicPort { get; set; } = DefaultHttpPort; + + public bool EnableIPV6 { get; set; } + + [DataMember(Name = "EnableIPV4")] + public bool EnableIPV4 { get; set; } = true; + + public bool IgnoreVirtualInterfaces { get; set; } = true; + + public string VirtualInterfaceNames { get; set; } = "vEthernet*"; + + public bool TrustAllIP6Interfaces { get; set; } + + public string[] PublishedServerUriBySubnet { get; set; } = Array.Empty(); + + public string[] RemoteIPFilter { get; set; } = Array.Empty(); + + public bool IsRemoteIPFilterBlacklist { get; set; } + + public bool EnableUPnP { get; set; } + + public bool EnableRemoteAccess { get; set; } = true; + + public string[] LocalNetworkSubnets { get; set; } = Array.Empty(); + + public string[] LocalNetworkAddresses { get; set; } = Array.Empty(); + + public string[] KnownProxies { get; set; } = Array.Empty(); + } +#pragma warning restore CS1591 +} diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 7f158aebb..f40526e22 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -175,6 +175,7 @@ namespace Jellyfin.Server } PerformStaticInitialization(); + Migrations.MigrationRunner.RunPreStartup(appPaths, _loggerFactory); var appHost = new CoreAppHost( appPaths, diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 0ab721b77..46e61ee1a 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -13,18 +13,6 @@ namespace MediaBrowser.Model.Configuration /// public class ServerConfiguration : BaseApplicationConfiguration { - /// - /// The default value for . - /// - public const int DefaultHttpPort = 8096; - - /// - /// The default value for and . - /// - public const int DefaultHttpsPort = 8920; - - private string _baseUrl = string.Empty; - /// /// Initializes a new instance of the class. /// @@ -75,149 +63,13 @@ namespace MediaBrowser.Model.Configuration }; } - /// - /// Gets or sets a value indicating whether to enable automatic port forwarding. - /// - public bool EnableUPnP { get; set; } = false; - /// /// Gets or sets a value indicating whether to enable prometheus metrics exporting. /// public bool EnableMetrics { get; set; } = false; - /// - /// Gets or sets the public mapped port. - /// - /// The public mapped port. - public int PublicPort { get; set; } = DefaultHttpPort; - - /// - /// Gets or sets a value indicating whether the http port should be mapped as part of UPnP automatic port forwarding. - /// - public bool UPnPCreateHttpPortMap { get; set; } = false; - - /// - /// Gets or sets client udp port range. - /// - public string UDPPortRange { get; set; } = string.Empty; - - /// - /// Gets or sets a value indicating whether IPV6 capability is enabled. - /// - public bool EnableIPV6 { get; set; } = false; - - /// - /// Gets or sets a value indicating whether IPV4 capability is enabled. - /// - public bool EnableIPV4 { get; set; } = true; - - /// - /// Gets or sets a value indicating whether detailed ssdp logs are sent to the console/log. - /// "Emby.Dlna": "Debug" must be set in logging.default.json for this property to work. - /// - public bool EnableSSDPTracing { get; set; } = false; - - /// - /// Gets or sets a value indicating whether an IP address is to be used to filter the detailed ssdp logs that are being sent to the console/log. - /// If the setting "Emby.Dlna": "Debug" msut be set in logging.default.json for this property to work. - /// - public string SSDPTracingFilter { get; set; } = string.Empty; - - /// - /// Gets or sets the number of times SSDP UDP messages are sent. - /// - public int UDPSendCount { get; set; } = 2; - - /// - /// Gets or sets the delay between each groups of SSDP messages (in ms). - /// - public int UDPSendDelay { get; set; } = 100; - - /// - /// Gets or sets a value indicating whether address names that match should be Ignore for the purposes of binding. - /// - public bool IgnoreVirtualInterfaces { get; set; } = true; - - /// - /// Gets or sets a value indicating the interfaces that should be ignored. The list can be comma separated. . - /// - public string VirtualInterfaceNames { get; set; } = "vEthernet*"; - - /// - /// Gets or sets the time (in seconds) between the pings of SSDP gateway monitor. - /// - public int GatewayMonitorPeriod { get; set; } = 60; - - /// - /// Gets a value indicating whether multi-socket binding is available. - /// - public bool EnableMultiSocketBinding { get; } = true; - - /// - /// Gets or sets a value indicating whether all IPv6 interfaces should be treated as on the internal network. - /// Depending on the address range implemented ULA ranges might not be used. - /// - public bool TrustAllIP6Interfaces { get; set; } = false; - - /// - /// Gets or sets the ports that HDHomerun uses. - /// - public string HDHomerunPortRange { get; set; } = string.Empty; - - /// - /// Gets or sets PublishedServerUri to advertise for specific subnets. - /// - public string[] PublishedServerUriBySubnet { get; set; } = Array.Empty(); - - /// - /// Gets or sets a value indicating whether Autodiscovery tracing is enabled. - /// - public bool AutoDiscoveryTracing { get; set; } = false; - - /// - /// Gets or sets a value indicating whether Autodiscovery is enabled. - /// - public bool AutoDiscovery { get; set; } = true; - - /// - /// Gets or sets the public HTTPS port. - /// - /// The public HTTPS port. - public int PublicHttpsPort { get; set; } = DefaultHttpsPort; - - /// - /// Gets or sets the HTTP server port number. - /// - /// The HTTP server port number. - public int HttpServerPortNumber { get; set; } = DefaultHttpPort; - - /// - /// Gets or sets the HTTPS server port number. - /// - /// The HTTPS server port number. - public int HttpsPortNumber { get; set; } = DefaultHttpsPort; - - /// - /// Gets or sets a value indicating whether to use HTTPS. - /// - /// - /// In order for HTTPS to be used, in addition to setting this to true, valid values must also be - /// provided for and . - /// - public bool EnableHttps { get; set; } = false; - public bool EnableNormalizedItemByNameIds { get; set; } = true; - /// - /// Gets or sets the filesystem path of an X.509 certificate to use for SSL. - /// - public string CertificatePath { get; set; } = string.Empty; - - /// - /// Gets or sets the password required to access the X.509 certificate data in the file specified by . - /// - public string CertificatePassword { get; set; } = string.Empty; - /// /// Gets or sets a value indicating whether this instance is port authorized. /// @@ -229,11 +81,6 @@ namespace MediaBrowser.Model.Configuration /// public bool QuickConnectAvailable { get; set; } = false; - /// - /// Gets or sets a value indicating whether access outside of the LAN is permitted. - /// - public bool EnableRemoteAccess { get; set; } = true; - /// /// Gets or sets a value indicating whether [enable case sensitive item ids]. /// @@ -318,13 +165,6 @@ namespace MediaBrowser.Model.Configuration /// The file watcher delay. public int LibraryMonitorDelay { get; set; } = 60; - /// - /// Gets or sets a value indicating whether [enable dashboard response caching]. - /// Allows potential contributors without visual studio to modify production dashboard code and test changes. - /// - /// true if [enable dashboard response caching]; otherwise, false. - public bool EnableDashboardResponseCaching { get; set; } = true; - /// /// Gets or sets the image saving convention. /// @@ -337,36 +177,6 @@ namespace MediaBrowser.Model.Configuration public string ServerName { get; set; } = string.Empty; - public string BaseUrl - { - get => _baseUrl; - set - { - // Normalize the start of the string - if (string.IsNullOrWhiteSpace(value)) - { - // If baseUrl is empty, set an empty prefix string - _baseUrl = string.Empty; - return; - } - - if (value[0] != '/') - { - // If baseUrl was not configured with a leading slash, append one for consistency - value = "/" + value; - } - - // Normalize the end of the string - if (value[value.Length - 1] == '/') - { - // If baseUrl was configured with a trailing slash, remove it for consistency - value = value.Remove(value.Length - 1); - } - - _baseUrl = value; - } - } - public string UICulture { get; set; } = "en-US"; public bool SaveMetadataHidden { get; set; } = false; @@ -381,43 +191,16 @@ namespace MediaBrowser.Model.Configuration public bool DisplaySpecialsWithinSeasons { get; set; } = true; - /// - /// Gets or sets the subnets that are deemed to make up the LAN. - /// - public string[] LocalNetworkSubnets { get; set; } = Array.Empty(); - - /// - /// Gets or sets the interface addresses which Jellyfin will bind to. If empty, all interfaces will be used. - /// - public string[] LocalNetworkAddresses { get; set; } = Array.Empty(); - public string[] CodecsUsed { get; set; } = Array.Empty(); public List PluginRepositories { get; set; } = new List(); public bool EnableExternalContentInSuggestions { get; set; } = true; - /// - /// Gets or sets a value indicating whether the server should force connections over HTTPS. - /// - public bool RequireHttps { get; set; } = false; - - /// - /// Gets or sets the filter for remote IP connectivity. Used in conjuntion with . - /// - public string[] RemoteIPFilter { get; set; } = Array.Empty(); - - /// - /// Gets or sets a value indicating whether contains a blacklist or a whitelist. Default is a whitelist. - /// - public bool IsRemoteIPFilterBlacklist { get; set; } = false; - public int ImageExtractionTimeoutMs { get; set; } = 0; public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty(); - public string[] UninstalledPlugins { get; set; } = Array.Empty(); - /// /// Gets or sets a value indicating whether slow server responses should be logged as a warning. /// @@ -433,11 +216,6 @@ namespace MediaBrowser.Model.Configuration /// public string[] CorsHosts { get; set; } = new[] { "*" }; - /// - /// Gets or sets the known proxies. - /// - public string[] KnownProxies { get; set; } = Array.Empty(); - /// /// Gets or sets the number of days we should retain activity logs. /// -- cgit v1.2.3