From e7ab8e1f871ae4b4cba55c83d866a916ebe0b1b3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 22 Mar 2018 13:33:53 -0400 Subject: [PATCH] support metadata settings per library --- .../Library/UserManager.cs | 14 +++ .../LiveTv/EmbyTV/EmbyTV.cs | 23 ++-- .../LiveTv/EmbyTV/EncodedRecorder.cs | 66 +++-------- .../LiveTv/EmbyTV/RecordingHelper.cs | 2 + .../LiveTv/Listings/SchedulesDirect.cs | 11 +- .../Localization/Core/cs.json | 2 +- .../Localization/Core/de.json | 4 +- .../Localization/Core/sk.json | 2 +- MediaBrowser.Api/ConfigurationService.cs | 27 ----- MediaBrowser.Api/ItemLookupService.cs | 3 +- MediaBrowser.Api/Library/LibraryService.cs | 109 ++++++++++++++++-- MediaBrowser.Api/Session/SessionsService.cs | 12 ++ MediaBrowser.Controller/Entities/BaseItem.cs | 41 ++++++- .../Library/IUserManager.cs | 2 + .../LiveTv/LiveTvProgram.cs | 5 - .../Providers/ImageRefreshOptions.cs | 1 - .../Configuration/LibraryOptions.cs | 53 ++++++++- .../Configuration/MetadataPluginType.cs | 3 +- MediaBrowser.Model/Session/TranscodingInfo.cs | 3 +- .../Manager/MetadataService.cs | 39 +------ .../Manager/ProviderManager.cs | 96 +++++++-------- .../MediaInfo/FFProbeVideoInfo.cs | 37 +++++- .../MediaInfo/SubtitleScheduledTask.cs | 77 +++++++------ .../Omdb/OmdbItemProvider.cs | 2 +- .../TV/MissingEpisodeProvider.cs | 11 +- .../TV/TheMovieDb/MovieDbSeriesProvider.cs | 4 +- .../TV/TheTVDB/TvdbPrescanTask.cs | 10 +- SharedVersion.cs | 2 +- 28 files changed, 396 insertions(+), 265 deletions(-) diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index fa3ddb8fd0..cf3e289818 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -95,6 +95,20 @@ public UserManager(ILogger logger, IServerConfigurationManager configurationMana DeletePinFile(); } + public NameIdPair[] GetAuthenticationProviders() + { + return _authenticationProviders + .Where(i => i.IsEnabled) + .OrderBy(i => i is DefaultAuthenticationProvider ? 0 : 1) + .ThenBy(i => i.Name) + .Select(i => new NameIdPair + { + Name = i.Name, + Id = GetAuthenticationProviderId(i) + }) + .ToArray(); + } + public void AddParts(IEnumerable authenticationProviders) { _authenticationProviders = authenticationProviders.ToArray(); diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 26368e195f..e376d7cd1d 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -41,6 +41,7 @@ using MediaBrowser.Model.Querying; using MediaBrowser.Model.Reflection; using MediaBrowser.Model.Providers; +using Emby.Server.Implementations.LiveTv.TunerHosts; namespace Emby.Server.Implementations.LiveTv.EmbyTV { @@ -1430,8 +1431,6 @@ private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, Acti var recordPath = GetRecordingPath(timer, remoteMetadata, out seriesPath); var recordingStatus = RecordingStatus.New; - var recorder = GetRecorder(); - string liveStreamId = null; try @@ -1445,6 +1444,8 @@ private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, Acti var mediaStreamInfo = liveStreamInfo.Item2; liveStreamId = mediaStreamInfo.Id; + var recorder = GetRecorder(liveStreamInfo.Item1, mediaStreamInfo); + recordPath = recorder.GetOutputPath(mediaStreamInfo, recordPath); recordPath = EnsureFileUnique(recordPath, timer.Id); @@ -1800,24 +1801,14 @@ private bool FileExists(string path, string timerId) return false; } - private IRecorder GetRecorder() + private IRecorder GetRecorder(ILiveStream liveStream, MediaSourceInfo mediaSource) { - var config = GetConfiguration(); - - if (config.EnableRecordingEncoding) + if (mediaSource.RequiresLooping || !(mediaSource.Container ?? string.Empty).EndsWith("ts", StringComparison.OrdinalIgnoreCase)) { - return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, config, _httpClient, _processFactory, _config, _assemblyInfo); + return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, _httpClient, _processFactory, _config, _assemblyInfo); } return new DirectRecorder(_logger, _httpClient, _fileSystem); - - //var options = new LiveTvOptions - //{ - // EnableOriginalAudioWithEncodedRecordings = true, - // RecordedVideoCodec = "copy", - // RecordingEncodingFormat = "ts" - //}; - //return new EncodedRecorder(_logger, _fileSystem, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, options, _httpClient, _processFactory, _config); } private void OnSuccessfulRecording(TimerInfo timer, string path) @@ -2422,7 +2413,7 @@ private bool ShouldCancelTimerForSeriesTimer(SeriesTimerInfo seriesTimer, TimerI if (!seriesTimer.RecordAnyTime) { - if (Math.Abs(seriesTimer.StartDate.TimeOfDay.Ticks - timer.StartDate.TimeOfDay.Ticks) >= TimeSpan.FromMinutes(5).Ticks) + if (Math.Abs(seriesTimer.StartDate.TimeOfDay.Ticks - timer.StartDate.TimeOfDay.Ticks) >= TimeSpan.FromMinutes(10).Ticks) { return true; } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index ca5df7cac7..6cdcc04aaf 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -33,7 +33,6 @@ public class EncodedRecorder : IRecorder private readonly IHttpClient _httpClient; private readonly IMediaEncoder _mediaEncoder; private readonly IServerApplicationPaths _appPaths; - private readonly LiveTvOptions _liveTvOptions; private bool _hasExited; private Stream _logFileStream; private string _targetPath; @@ -44,39 +43,19 @@ public class EncodedRecorder : IRecorder private readonly IServerConfigurationManager _config; private readonly IAssemblyInfo _assemblyInfo; - public EncodedRecorder(ILogger logger, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IServerApplicationPaths appPaths, IJsonSerializer json, LiveTvOptions liveTvOptions, IHttpClient httpClient, IProcessFactory processFactory, IServerConfigurationManager config, IAssemblyInfo assemblyInfo) + public EncodedRecorder(ILogger logger, IFileSystem fileSystem, IMediaEncoder mediaEncoder, IServerApplicationPaths appPaths, IJsonSerializer json, IHttpClient httpClient, IProcessFactory processFactory, IServerConfigurationManager config, IAssemblyInfo assemblyInfo) { _logger = logger; _fileSystem = fileSystem; _mediaEncoder = mediaEncoder; _appPaths = appPaths; _json = json; - _liveTvOptions = liveTvOptions; _httpClient = httpClient; _processFactory = processFactory; _config = config; _assemblyInfo = assemblyInfo; } - private string OutputFormat - { - get - { - var format = _liveTvOptions.RecordingEncodingFormat; - - if (string.Equals(format, "mkv", StringComparison.OrdinalIgnoreCase)) - { - return "mkv"; - } - if (string.Equals(format, "ts", StringComparison.OrdinalIgnoreCase)) - { - return "ts"; - } - - return "mkv"; - } - } - private bool CopySubtitles { get @@ -88,12 +67,7 @@ private bool CopySubtitles public string GetOutputPath(MediaSourceInfo mediaSource, string targetFile) { - var extension = OutputFormat; - - if (string.Equals(extension, "mpegts", StringComparison.OrdinalIgnoreCase)) - { - extension = "ts"; - } + var extension = "ts"; return Path.ChangeExtension(targetFile, "." + extension); } @@ -211,7 +185,7 @@ private string GetCommandLineArgs(MediaSourceInfo mediaSource, string inputTempF } var videoStream = mediaSource.VideoStream; - var videoDecoder = videoStream == null ? null : new EncodingHelper(_mediaEncoder, _fileSystem, null, _appPaths, _assemblyInfo).GetVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions()); + string videoDecoder = null; if (!string.IsNullOrEmpty(videoDecoder)) { @@ -258,39 +232,27 @@ private string GetAudioArgs(MediaSourceInfo mediaSource) var mediaStreams = mediaSource.MediaStreams ?? new List(); var inputAudioCodec = mediaStreams.Where(i => i.Type == MediaStreamType.Audio).Select(i => i.Codec).FirstOrDefault() ?? string.Empty; - // do not copy aac because many players have difficulty with aac_latm - if (_liveTvOptions.EnableOriginalAudioWithEncodedRecordings && !string.Equals(inputAudioCodec, "aac", StringComparison.OrdinalIgnoreCase)) - { - return "-codec:a:0 copy"; - } + return "-codec:a:0 copy"; - var audioChannels = 2; - var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); - if (audioStream != null) - { - audioChannels = audioStream.Channels ?? audioChannels; - } - return "-codec:a:0 aac -strict experimental -ab 320000"; + //var audioChannels = 2; + //var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio); + //if (audioStream != null) + //{ + // audioChannels = audioStream.Channels ?? audioChannels; + //} + //return "-codec:a:0 aac -strict experimental -ab 320000"; } private bool EncodeVideo(MediaSourceInfo mediaSource) { - var mediaStreams = mediaSource.MediaStreams ?? new List(); - return !mediaStreams.Any(i => i.Type == MediaStreamType.Video && string.Equals(i.Codec, "h264", StringComparison.OrdinalIgnoreCase) && !i.IsInterlaced); + return false; } protected string GetOutputSizeParam() { var filters = new List(); - - if (string.Equals(GetEncodingOptions().DeinterlaceMethod, "bobandweave", StringComparison.OrdinalIgnoreCase)) - { - filters.Add("yadif=1:-1:0"); - } - else - { - filters.Add("yadif=0:-1:0"); - } + + filters.Add("yadif=0:-1:0"); var output = string.Empty; diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs index 9c702c2369..b3a1943b81 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/RecordingHelper.cs @@ -58,6 +58,8 @@ public static string GetRecordingName(TimerInfo info) private static string GetDateString(DateTime date) { + date = date.ToLocalTime(); + return string.Format("{0}_{1}_{2}_{3}_{4}_{5}", date.Year.ToString("0000", CultureInfo.InvariantCulture), date.Month.ToString("00", CultureInfo.InvariantCulture), diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs index b900fea2bf..d4ec30dbe7 100644 --- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs +++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs @@ -382,12 +382,21 @@ private ProgramInfo GetProgram(string channelId, ScheduleDirect.Program programI } } - if (!string.IsNullOrWhiteSpace(details.originalAirDate) && (!info.IsSeries || info.IsRepeat)) + if (!string.IsNullOrWhiteSpace(details.originalAirDate)) { info.OriginalAirDate = DateTime.Parse(details.originalAirDate); info.ProductionYear = info.OriginalAirDate.Value.Year; } + if (details.movie != null) + { + int year; + if (!string.IsNullOrEmpty(details.movie.year) && int.TryParse(details.movie.year, out year)) + { + info.ProductionYear = year; + } + } + if (details.genres != null) { info.Genres = details.genres.Where(g => !string.IsNullOrWhiteSpace(g)).ToList(); diff --git a/Emby.Server.Implementations/Localization/Core/cs.json b/Emby.Server.Implementations/Localization/Core/cs.json index a02e8a963c..0250e4fadd 100644 --- a/Emby.Server.Implementations/Localization/Core/cs.json +++ b/Emby.Server.Implementations/Localization/Core/cs.json @@ -24,7 +24,7 @@ "Channels": "Kan\u00e1ly", "Movies": "Filmy", "Albums": "Alba", - "NameSeasonUnknown": "Season Unknown", + "NameSeasonUnknown": "Nezn\u00e1m\u00e1 sez\u00f3na", "Artists": "Um\u011blci", "Folders": "Slo\u017eky", "Songs": "Skladby", diff --git a/Emby.Server.Implementations/Localization/Core/de.json b/Emby.Server.Implementations/Localization/Core/de.json index 0e04a3ea42..799bb299bf 100644 --- a/Emby.Server.Implementations/Localization/Core/de.json +++ b/Emby.Server.Implementations/Localization/Core/de.json @@ -24,7 +24,7 @@ "Channels": "Kan\u00e4le", "Movies": "Filme", "Albums": "Alben", - "NameSeasonUnknown": "Season Unknown", + "NameSeasonUnknown": "Staffel unbekannt", "Artists": "Interpreten", "Folders": "Verzeichnisse", "Songs": "Songs", @@ -54,7 +54,7 @@ "UserCreatedWithName": "Benutzer {0} wurde erstellt", "UserPasswordChangedWithName": "Das Passwort f\u00fcr Benutzer {0} wurde ge\u00e4ndert", "UserDeletedWithName": "Benutzer {0} wurde gel\u00f6scht", - "UserPolicyUpdatedWithName": "User policy has been updated for {0}", + "UserPolicyUpdatedWithName": "Benutzerrichtlinie wurde f\u00fcr {0} aktualisiert", "MessageServerConfigurationUpdated": "Server Einstellungen wurden aktualisiert", "MessageNamedServerConfigurationUpdatedWithValue": "Der Server Einstellungsbereich {0} wurde aktualisiert", "MessageApplicationUpdated": "Emby Server wurde auf den neusten Stand gebracht.", diff --git a/Emby.Server.Implementations/Localization/Core/sk.json b/Emby.Server.Implementations/Localization/Core/sk.json index 925cca7191..7fa98e287f 100644 --- a/Emby.Server.Implementations/Localization/Core/sk.json +++ b/Emby.Server.Implementations/Localization/Core/sk.json @@ -49,7 +49,7 @@ "LabelIpAddressValue": "IP adresa: {0}", "DeviceOnlineWithName": "{0} je pripojen\u00fd", "UserOnlineFromDevice": "{0} je online z {1}", - "ProviderValue": "Provider: {0}", + "ProviderValue": "Poskytovate\u013e: {0}", "SubtitlesDownloadedForItem": "Titulky pre {0} stiahnut\u00e9", "UserCreatedWithName": "Pou\u017e\u00edvate\u013e {0} bol vytvoren\u00fd", "UserPasswordChangedWithName": "Heslo pou\u017e\u00edvate\u013ea {0} zmenen\u00e9", diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs index 0023c13d78..8e65f21ce0 100644 --- a/MediaBrowser.Api/ConfigurationService.cs +++ b/MediaBrowser.Api/ConfigurationService.cs @@ -4,11 +4,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Serialization; -using System.Collections.Generic; using System.IO; -using System.Threading.Tasks; - -using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Services; @@ -59,20 +55,6 @@ public class GetDefaultMetadataOptions : IReturn } - [Route("/System/Configuration/MetadataPlugins", "GET", Summary = "Gets all available metadata plugins")] - [Authenticated(Roles = "Admin")] - public class GetMetadataPlugins : IReturn - { - - } - - [Route("/System/Configuration/MetadataPlugins/Autoset", "POST")] - [Authenticated(Roles = "Admin", AllowBeforeStartupWizard = true)] - public class AutoSetMetadataOptions : IReturnVoid - { - - } - [Route("/System/MediaEncoder/Path", "POST", Summary = "Updates the path to the media encoder")] [Authenticated(Roles = "Admin", AllowBeforeStartupWizard = true)] public class UpdateMediaEncoderPath : IReturnVoid @@ -132,10 +114,6 @@ public object Get(GetNamedConfiguration request) return ToOptimizedResult(result); } - public void Post(AutoSetMetadataOptions request) - { - } - /// /// Posts the specified configuraiton. /// @@ -164,10 +142,5 @@ public object Get(GetDefaultMetadataOptions request) { return ToOptimizedSerializedResultUsingCache(new MetadataOptions()); } - - public object Get(GetMetadataPlugins request) - { - return ToOptimizedSerializedResultUsingCache(_providerManager.GetAllMetadataPlugins()); - } } } diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index c18d3017dd..456490c84b 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -238,8 +238,7 @@ public void Post(ApplySearchCriteria request) ImageRefreshMode = MetadataRefreshMode.FullRefresh, ReplaceAllMetadata = true, ReplaceAllImages = request.ReplaceAllImages, - SearchResult = request, - ForceEnableInternetMetadata = true + SearchResult = request }, CancellationToken.None); Task.WaitAll(task); diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index dacaacc0cc..c9aa8d52ee 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -291,6 +291,15 @@ public class LibraryOptionsResult { public LibraryOptionInfo[] MetadataSavers { get; set; } public LibraryOptionInfo[] MetadataReaders { get; set; } + public LibraryOptionInfo[] SubtitleFetchers { get; set; } + public LibraryTypeOptions[] TypeOptions { get; set; } + } + + public class LibraryTypeOptions + { + public string Type { get; set; } + public LibraryOptionInfo[] MetadataFetchers { get; set; } + public LibraryOptionInfo[] ImageFetchers { get; set; } } /// @@ -353,23 +362,62 @@ private string[] GetRepresentativeItemTypes(string contentType) case CollectionType.Games: return new string[] { "Game", "GameSystem" }; case CollectionType.Music: - return new string[] { "MusicAlbum", "MusicArtist", "Audio" }; + return new string[] { "MusicAlbum", "MusicArtist", "Audio", "MusicVideo" }; case CollectionType.HomeVideos: case CollectionType.Photos: return new string[] { "Video", "Photo" }; case CollectionType.MusicVideos: return new string[] { "MusicVideo" }; default: - return new string[] { "Movie", "Series" }; + return new string[] { "Series", "Season", "Episode", "Movie" }; + } + } + + private bool IsSaverEnabledByDefault(string name, string[] itemTypes) + { + var metadataOptions = _config.Configuration.MetadataOptions + .Where(i => itemTypes.Contains(i.ItemType ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + .ToArray(); + + if (metadataOptions.Length == 0) + { + return true; } + + return metadataOptions.Any(i => !i.DisabledMetadataSavers.Contains(name, StringComparer.OrdinalIgnoreCase)); } - private bool IsSaverEnabledByDefault(string name, string itemType) + private bool IsSubtitleFetcherEnabledByDefault(string name, string[] itemTypes) + { + return false; + } + + private bool IsMetadataFetcherEnabledByDefault(string name, string type) { var metadataOptions = _config.Configuration.MetadataOptions - .FirstOrDefault(i => string.Equals(i.ItemType, itemType, StringComparison.OrdinalIgnoreCase)); + .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) + .ToArray(); + + if (metadataOptions.Length == 0) + { + return true; + } - return metadataOptions == null ? true : !metadataOptions.DisabledMetadataSavers.Contains(name, StringComparer.OrdinalIgnoreCase); + return metadataOptions.Any(i => !i.DisabledMetadataFetchers.Contains(name, StringComparer.OrdinalIgnoreCase)); + } + + private bool IsImageFetcherEnabledByDefault(string name, string type) + { + var metadataOptions = _config.Configuration.MetadataOptions + .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) + .ToArray(); + + if (metadataOptions.Length == 0) + { + return true; + } + + return metadataOptions.Any(i => !i.DisabledImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase)); } public object Get(GetLibraryOptionsInfo request) @@ -377,18 +425,19 @@ public object Get(GetLibraryOptionsInfo request) var result = new LibraryOptionsResult(); var types = GetRepresentativeItemTypes(request.LibraryContentType); + var typesList = types.ToList(); + var plugins = _providerManager.GetAllMetadataPlugins() .Where(i => types.Contains(i.ItemType, StringComparer.OrdinalIgnoreCase)) + .OrderBy(i => typesList.IndexOf(i.ItemType)) .ToList(); - var itemType = types[0]; - result.MetadataSavers = plugins .SelectMany(i => i.Plugins.Where(p => p.Type == MetadataPluginType.MetadataSaver)) .Select(i => new LibraryOptionInfo { Name = i.Name, - DefaultEnabled = IsSaverEnabledByDefault(i.Name, itemType) + DefaultEnabled = IsSaverEnabledByDefault(i.Name, types) }) .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) .ToArray(); @@ -403,6 +452,50 @@ public object Get(GetLibraryOptionsInfo request) .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) .ToArray(); + result.SubtitleFetchers = plugins + .SelectMany(i => i.Plugins.Where(p => p.Type == MetadataPluginType.SubtitleFetcher)) + .Select(i => new LibraryOptionInfo + { + Name = i.Name, + DefaultEnabled = IsSubtitleFetcherEnabledByDefault(i.Name, types) + }) + .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) + .ToArray(); + + var typeOptions = new List(); + + foreach (var type in types) + { + typeOptions.Add(new LibraryTypeOptions + { + Type = type, + + MetadataFetchers = plugins + .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) + .SelectMany(i => i.Plugins.Where(p => p.Type == MetadataPluginType.MetadataFetcher)) + .Select(i => new LibraryOptionInfo + { + Name = i.Name, + DefaultEnabled = IsMetadataFetcherEnabledByDefault(i.Name, type) + }) + .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) + .ToArray(), + + ImageFetchers = plugins + .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) + .SelectMany(i => i.Plugins.Where(p => p.Type == MetadataPluginType.ImageFetcher)) + .Select(i => new LibraryOptionInfo + { + Name = i.Name, + DefaultEnabled = IsImageFetcherEnabledByDefault(i.Name, type) + }) + .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) + .ToArray() + }); + } + + result.TypeOptions = typeOptions.ToArray(); + return result; } diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs index fa6c10b028..0143fdd7f9 100644 --- a/MediaBrowser.Api/Session/SessionsService.cs +++ b/MediaBrowser.Api/Session/SessionsService.cs @@ -11,6 +11,7 @@ using System.Threading.Tasks; using MediaBrowser.Model.Services; using MediaBrowser.Controller; +using MediaBrowser.Model.Dto; namespace MediaBrowser.Api.Session { @@ -242,6 +243,12 @@ public class GetApiKeys { } + [Route("/Auth/Providers", "GET")] + [Authenticated(Roles = "Admin")] + public class GetAuthProviders : IReturn + { + } + [Route("/Auth/Keys/{Key}", "DELETE")] [Authenticated(Roles = "Admin")] public class RevokeKey @@ -286,6 +293,11 @@ public SessionsService(ISessionManager sessionManager, IServerApplicationHost ap _appHost = appHost; } + public object Get(GetAuthProviders request) + { + return ToOptimizedResult(_userManager.GetAuthenticationProviders()); + } + public void Delete(RevokeKey request) { _sessionManager.RevokeToken(request.Key); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 5052329092..caef9c64e8 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -519,7 +519,7 @@ public string PrimaryImagePath get { return this.GetImagePath(ImageType.Primary); } } - public virtual bool IsInternetMetadataEnabled() + public bool IsMetadataFetcherEnabled(LibraryOptions libraryOptions, string name) { if (SourceType == SourceType.Channel) { @@ -527,7 +527,44 @@ public virtual bool IsInternetMetadataEnabled() return !EnableMediaSourceDisplay; } - return LibraryManager.GetLibraryOptions(this).EnableInternetProviders; + var typeOptions = libraryOptions.GetTypeOptions(GetType().Name); + if (typeOptions != null) + { + return typeOptions.MetadataFetchers.Contains(name, StringComparer.OrdinalIgnoreCase); + } + + if (!libraryOptions.EnableInternetProviders) + { + return false; + } + + var itemConfig = ConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, GetType().Name, StringComparison.OrdinalIgnoreCase)); + + return itemConfig == null || !itemConfig.DisabledMetadataFetchers.Contains(name, StringComparer.OrdinalIgnoreCase); + } + + public bool IsImageFetcherEnabled(LibraryOptions libraryOptions, string name) + { + if (SourceType == SourceType.Channel) + { + // hack alert + return !EnableMediaSourceDisplay; + } + + var typeOptions = libraryOptions.GetTypeOptions(GetType().Name); + if (typeOptions != null) + { + return typeOptions.ImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase); + } + + if (!libraryOptions.EnableInternetProviders) + { + return false; + } + + var itemConfig = ConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, GetType().Name, StringComparison.OrdinalIgnoreCase)); + + return itemConfig == null || !itemConfig.DisabledImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase); } public virtual bool CanDelete() diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index 9c1a5a94f5..9280271796 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -201,5 +201,7 @@ public interface IUserManager string MakeValidUsername(string username); void AddParts(IEnumerable authenticationProviders); + + NameIdPair[] GetAuthenticationProviders(); } } diff --git a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs index 4ca662d467..691ee1cd73 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvProgram.cs @@ -261,11 +261,6 @@ public override bool CanDelete() return false; } - public override bool IsInternetMetadataEnabled() - { - return false; - } - public LiveTvProgramLookupInfo GetLookupInfo() { var info = GetItemLookupInfo(); diff --git a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs index 795d6af495..fd3d6bd9e1 100644 --- a/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs +++ b/MediaBrowser.Controller/Providers/ImageRefreshOptions.cs @@ -12,7 +12,6 @@ public class ImageRefreshOptions public List ReplaceImages { get; set; } public bool IsAutomated { get; set; } - public bool ForceEnableInternetMetadata { get; set; } public ImageRefreshOptions(IDirectoryService directoryService) { diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs index 1acbd61436..e99682b3fd 100644 --- a/MediaBrowser.Model/Configuration/LibraryOptions.cs +++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs @@ -1,4 +1,6 @@ -namespace MediaBrowser.Model.Configuration +using System; + +namespace MediaBrowser.Model.Configuration { public class LibraryOptions { @@ -31,11 +33,40 @@ public class LibraryOptions public string MetadataCountryCode { get; set; } public string SeasonZeroDisplayName { get; set; } - public string[] EnabledMetadataSavers { get; set; } + public string[] MetadataSavers { get; set; } + public string[] LocalMetadataReaders { get; set; } public string[] LocalMetadataReaderOrder { get; set; } + public string[] SubtitleFetchers { get; set; } + public string[] SubtitleFetcherOrder { get; set; } + + public bool SkipSubtitlesIfEmbeddedSubtitlesPresent { get; set; } + public bool SkipSubtitlesIfAudioTrackMatches { get; set; } + public string[] SubtitleDownloadLanguages { get; set; } + public bool RequirePerfectSubtitleMatch { get; set; } + + public TypeOptions[] TypeOptions { get; set; } + + public TypeOptions GetTypeOptions(string type) + { + foreach (var options in TypeOptions) + { + if (string.Equals(options.Type, type, StringComparison.OrdinalIgnoreCase)) + { + return options; + } + } + + return null; + } + public LibraryOptions() { + TypeOptions = new TypeOptions[] { }; + + SkipSubtitlesIfAudioTrackMatches = true; + RequirePerfectSubtitleMatch = true; + EnablePhotos = true; EnableRealtimeMonitor = true; PathInfos = new MediaPathInfo[] { }; @@ -50,4 +81,22 @@ public class MediaPathInfo public string Path { get; set; } public string NetworkPath { get; set; } } + + public class TypeOptions + { + public string Type { get; set; } + public string[] MetadataFetchers { get; set; } + public string[] MetadataFetcherOrder { get; set; } + + public string[] ImageFetchers { get; set; } + public string[] ImageFetcherOrder { get; set; } + + public TypeOptions() + { + MetadataFetchers = new string[] { }; + MetadataFetcherOrder = new string[] { }; + ImageFetchers = new string[] { }; + ImageFetcherOrder = new string[] { }; + } + } } diff --git a/MediaBrowser.Model/Configuration/MetadataPluginType.cs b/MediaBrowser.Model/Configuration/MetadataPluginType.cs index 95ca3b2e6a..5ba0b395e0 100644 --- a/MediaBrowser.Model/Configuration/MetadataPluginType.cs +++ b/MediaBrowser.Model/Configuration/MetadataPluginType.cs @@ -10,6 +10,7 @@ public enum MetadataPluginType ImageSaver, LocalMetadataProvider, MetadataFetcher, - MetadataSaver + MetadataSaver, + SubtitleFetcher } } \ No newline at end of file diff --git a/MediaBrowser.Model/Session/TranscodingInfo.cs b/MediaBrowser.Model/Session/TranscodingInfo.cs index 70c299bc25..ed86d2358a 100644 --- a/MediaBrowser.Model/Session/TranscodingInfo.cs +++ b/MediaBrowser.Model/Session/TranscodingInfo.cs @@ -49,6 +49,7 @@ public enum TranscodeReason VideoLevelNotSupported = 18, VideoProfileNotSupported = 19, AudioBitDepthNotSupported = 20, - SubtitleCodecNotSupported = 21 + SubtitleCodecNotSupported = 21, + DirectPlayError = 22 } } \ No newline at end of file diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index a51fd26274..a23499ad79 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -850,16 +850,17 @@ private async Task ExecuteRemoteProviders(MetadataResult>(); + var tmpDataMerged = false; foreach (var provider in providers) { var providerName = provider.GetType().Name; Logger.Debug("Running {0} for {1}", providerName, logName); - if (id != null) + if (id != null && !tmpDataMerged) { MergeNewData(temp.Item, id); + tmpDataMerged = true; } try @@ -870,7 +871,8 @@ private async Task ExecuteRemoteProviders(MetadataResult ExecuteRemoteProviders(MetadataResult>(); - var preferredLanguage = NormalizeLanguage(id.MetadataLanguage); - - // prioritize results with matching ResultLanguage - foreach (var result in results) - { - if (!result.QueriedById) - { - break; - } - - if (string.Equals(NormalizeLanguage(result.ResultLanguage), preferredLanguage, StringComparison.OrdinalIgnoreCase) && result.QueriedById) - { - orderedResults.Add(result); - } - } - - // add all other results - foreach (var result in results) - { - if (!orderedResults.Contains(result)) - { - orderedResults.Add(result); - } - } - - foreach (var result in results) - { - MergeData(result, temp, new MetadataFields[] { }, false, false); - } - return refreshResult; } diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 8e033d9943..8e046218ac 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -25,6 +25,7 @@ using MediaBrowser.Model.Serialization; using Priority_Queue; using MediaBrowser.Model.Extensions; +using MediaBrowser.Controller.Subtitles; namespace MediaBrowser.Providers.Manager { @@ -275,31 +276,36 @@ public IEnumerable GetRemoteImageProviderInfo(BaseItem item) public IEnumerable GetImageProviders(BaseItem item, ImageRefreshOptions refreshOptions) { - return GetImageProviders(item, GetMetadataOptions(item), refreshOptions, false); + return GetImageProviders(item, _libraryManagerFactory().GetLibraryOptions(item), GetMetadataOptions(item), refreshOptions, false); } - private IEnumerable GetImageProviders(BaseItem item, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled) + private IEnumerable GetImageProviders(BaseItem item, LibraryOptions libraryOptions, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled) { // Avoid implicitly captured closure var currentOptions = options; - return ImageProviders.Where(i => CanRefresh(i, item, options, refreshOptions, includeDisabled)) - .OrderBy(i => - { - // See if there's a user-defined order - if (!(i is ILocalImageProvider)) - { - var index = Array.IndexOf(currentOptions.ImageFetcherOrder, i.Name); + var typeOptions = libraryOptions.GetTypeOptions(item.GetType().Name); + var typeFetcherOrder = typeOptions == null ? null : typeOptions.ImageFetcherOrder; - if (index != -1) + return ImageProviders.Where(i => CanRefresh(i, item, libraryOptions, options, refreshOptions, includeDisabled)) + .OrderBy(i => + { + // See if there's a user-defined order + if (!(i is ILocalImageProvider)) { - return index; + var fetcherOrder = typeFetcherOrder ?? currentOptions.ImageFetcherOrder; + + var index = Array.IndexOf(currentOptions.ImageFetcherOrder, i.Name); + + if (index != -1) + { + return index; + } } - } - // Not configured. Just return some high number to put it at the end. - return 100; - }) + // Not configured. Just return some high number to put it at the end. + return 100; + }) .ThenBy(GetOrder); } @@ -318,19 +324,20 @@ private IEnumerable> GetMetadataProvidersInternal(BaseIt var currentOptions = globalMetadataOptions; return _metadataProviders.OfType>() - .Where(i => CanRefresh(i, item, currentOptions, includeDisabled, forceEnableInternetMetadata, checkIsOwnedItem)) - .OrderBy(i => GetConfiguredOrder(i, libraryOptions, globalMetadataOptions)) + .Where(i => CanRefresh(i, item, libraryOptions, currentOptions, includeDisabled, forceEnableInternetMetadata, checkIsOwnedItem)) + .OrderBy(i => GetConfiguredOrder(item, i, libraryOptions, globalMetadataOptions)) .ThenBy(GetDefaultOrder); } private IEnumerable GetRemoteImageProviders(BaseItem item, bool includeDisabled) { var options = GetMetadataOptions(item); + var libraryOptions = _libraryManagerFactory().GetLibraryOptions(item); - return GetImageProviders(item, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), includeDisabled).OfType(); + return GetImageProviders(item, libraryOptions, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), includeDisabled).OfType(); } - private bool CanRefresh(IMetadataProvider provider, BaseItem item, MetadataOptions options, bool includeDisabled, bool forceEnableInternetMetadata, bool checkIsOwnedItem) + private bool CanRefresh(IMetadataProvider provider, BaseItem item, LibraryOptions libraryOptions, MetadataOptions options, bool includeDisabled, bool forceEnableInternetMetadata, bool checkIsOwnedItem) { if (!includeDisabled) { @@ -342,12 +349,7 @@ private bool CanRefresh(IMetadataProvider provider, BaseItem item, MetadataOptio if (provider is IRemoteMetadataProvider) { - if (!forceEnableInternetMetadata && !item.IsInternetMetadataEnabled()) - { - return false; - } - - if (Array.IndexOf(options.DisabledMetadataFetchers, provider.Name) != -1) + if (!forceEnableInternetMetadata && !item.IsMetadataFetcherEnabled(libraryOptions, provider.Name)) { return false; } @@ -371,7 +373,7 @@ private bool CanRefresh(IMetadataProvider provider, BaseItem item, MetadataOptio return true; } - private bool CanRefresh(IImageProvider provider, BaseItem item, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled) + private bool CanRefresh(IImageProvider provider, BaseItem item, LibraryOptions libraryOptions, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled) { if (!includeDisabled) { @@ -386,18 +388,10 @@ private bool CanRefresh(IImageProvider provider, BaseItem item, MetadataOptions if (provider is IRemoteImageProvider || provider is IDynamicImageProvider) { - if (Array.IndexOf(options.DisabledImageFetchers, provider.Name) != -1) + if (!item.IsImageFetcherEnabled(libraryOptions, provider.Name)) { return false; } - - if (provider is IRemoteImageProvider) - { - if (!refreshOptions.ForceEnableInternetMetadata && !item.IsInternetMetadataEnabled()) - { - return false; - } - } } } @@ -429,7 +423,7 @@ private int GetOrder(IImageProvider provider) return hasOrder.Order; } - private int GetConfiguredOrder(IMetadataProvider provider, LibraryOptions libraryOptions, MetadataOptions globalMetadataOptions) + private int GetConfiguredOrder(BaseItem item, IMetadataProvider provider, LibraryOptions libraryOptions, MetadataOptions globalMetadataOptions) { // See if there's a user-defined order if (provider is ILocalMetadataProvider) @@ -447,7 +441,12 @@ private int GetConfiguredOrder(IMetadataProvider provider, LibraryOptions librar // See if there's a user-defined order if (provider is IRemoteMetadataProvider) { - var index = Array.IndexOf(globalMetadataOptions.MetadataFetcherOrder, provider.Name); + var typeOptions = libraryOptions.GetTypeOptions(item.GetType().Name); + var typeFetcherOrder = typeOptions == null ? null : typeOptions.MetadataFetcherOrder; + + var fetcherOrder = typeFetcherOrder ?? globalMetadataOptions.MetadataFetcherOrder; + + var index = Array.IndexOf(fetcherOrder, provider.Name); if (index != -1) { @@ -516,15 +515,24 @@ private MetadataPluginSummary GetPluginSummary() ItemType = typeof(T).Name }; - var imageProviders = GetImageProviders(dummy, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), true).ToList(); + var libraryOptions = new LibraryOptions(); - var pluginList = summary.Plugins.ToList(); + var imageProviders = GetImageProviders(dummy, libraryOptions, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), true).ToList(); - var libraryOptions = new LibraryOptions(); + var pluginList = summary.Plugins.ToList(); AddMetadataPlugins(pluginList, dummy, libraryOptions, options); AddImagePlugins(pluginList, dummy, imageProviders); + var subtitleProviders = new List(); + + // Subtitle fetchers + pluginList.AddRange(subtitleProviders.Select(i => new MetadataPlugin + { + Name = i.Name, + Type = MetadataPluginType.SubtitleFetcher + })); + summary.Plugins = pluginList.ToArray(pluginList.Count); var supportedImageTypes = imageProviders.OfType() @@ -577,10 +585,8 @@ private void AddImagePlugins(List list, T item, List i is IDynamicImageProvider || (enableInternet && i is IRemoteImageProvider)).Select(i => new MetadataPlugin + list.AddRange(imageProviders.Where(i => i is IDynamicImageProvider || (i is IRemoteImageProvider)).Select(i => new MetadataPlugin { Name = i.Name, Type = MetadataPluginType.ImageFetcher @@ -687,7 +693,7 @@ private bool IsSaverEnabledForItem(IMetadataSaver saver, BaseItem item, LibraryO if (!includeDisabled) { - if (libraryOptions.EnabledMetadataSavers == null) + if (libraryOptions.MetadataSavers == null) { if (options.DisabledMetadataSavers.Contains(saver.Name, StringComparer.OrdinalIgnoreCase)) { @@ -717,7 +723,7 @@ private bool IsSaverEnabledForItem(IMetadataSaver saver, BaseItem item, LibraryO } else { - if (!libraryOptions.EnabledMetadataSavers.Contains(saver.Name, StringComparer.OrdinalIgnoreCase)) + if (!libraryOptions.MetadataSavers.Contains(saver.Name, StringComparer.OrdinalIgnoreCase)) { return false; } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 4be37703a8..8f34190ef6 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -486,19 +486,44 @@ private async Task AddExternalSubtitles(Video video, var subtitleOptions = GetOptions(); - if (enableSubtitleDownloading && (subtitleOptions.DownloadEpisodeSubtitles && + var libraryOptions = _libraryManager.GetLibraryOptions(video); + + string[] subtitleDownloadLanguages; + bool SkipIfEmbeddedSubtitlesPresent; + bool SkipIfAudioTrackMatches; + bool RequirePerfectMatch; + bool enabled; + + if (libraryOptions.SubtitleDownloadLanguages == null) + { + subtitleDownloadLanguages = subtitleOptions.DownloadLanguages; + SkipIfEmbeddedSubtitlesPresent = subtitleOptions.SkipIfEmbeddedSubtitlesPresent; + SkipIfAudioTrackMatches = subtitleOptions.SkipIfAudioTrackMatches; + RequirePerfectMatch = subtitleOptions.RequirePerfectMatch; + enabled = (subtitleOptions.DownloadEpisodeSubtitles && video is Episode) || (subtitleOptions.DownloadMovieSubtitles && - video is Movie)) + video is Movie); + } + else + { + subtitleDownloadLanguages = libraryOptions.SubtitleDownloadLanguages; + SkipIfEmbeddedSubtitlesPresent = libraryOptions.SkipSubtitlesIfEmbeddedSubtitlesPresent; + SkipIfAudioTrackMatches = libraryOptions.SkipSubtitlesIfAudioTrackMatches; + RequirePerfectMatch = libraryOptions.RequirePerfectSubtitleMatch; + enabled = true; + } + + if (enableSubtitleDownloading && enabled) { var downloadedLanguages = await new SubtitleDownloader(_logger, _subtitleManager) .DownloadSubtitles(video, currentStreams.Concat(externalSubtitleStreams).ToList(), - subtitleOptions.SkipIfEmbeddedSubtitlesPresent, - subtitleOptions.SkipIfAudioTrackMatches, - subtitleOptions.RequirePerfectMatch, - subtitleOptions.DownloadLanguages, + SkipIfEmbeddedSubtitlesPresent, + SkipIfAudioTrackMatches, + RequirePerfectMatch, + subtitleDownloadLanguages, cancellationToken).ConfigureAwait(false); // Rescan diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs index 4d68735b94..473effb710 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs @@ -66,19 +66,8 @@ public async Task Execute(CancellationToken cancellationToken, IProgress var types = new List(); - if (options.DownloadEpisodeSubtitles) - { - types.Add("Episode"); - } - if (options.DownloadMovieSubtitles) - { - types.Add("Movie"); - } - - if (types.Count == 0) - { - return; - } + types.Add("Episode"); + types.Add("Movie"); var dict = new Dictionary(); @@ -149,34 +138,48 @@ public async Task Execute(CancellationToken cancellationToken, IProgress private async Task DownloadSubtitles(Video video, SubtitleOptions options, CancellationToken cancellationToken) { - if ((options.DownloadEpisodeSubtitles && - video is Episode) || - (options.DownloadMovieSubtitles && - video is Movie)) + var mediaStreams = _mediaSourceManager.GetStaticMediaSources(video, false).First().MediaStreams; + + var libraryOptions = _libraryManager.GetLibraryOptions(video); + + string[] subtitleDownloadLanguages; + bool SkipIfEmbeddedSubtitlesPresent; + bool SkipIfAudioTrackMatches; + bool RequirePerfectMatch; + + if (libraryOptions.SubtitleDownloadLanguages == null) { - var mediaStreams = _mediaSourceManager.GetStaticMediaSources(video, false).First().MediaStreams; - - var downloadedLanguages = await new SubtitleDownloader(_logger, - _subtitleManager) - .DownloadSubtitles(video, - mediaStreams, - options.SkipIfEmbeddedSubtitlesPresent, - options.SkipIfAudioTrackMatches, - options.RequirePerfectMatch, - options.DownloadLanguages, - cancellationToken).ConfigureAwait(false); - - // Rescan - if (downloadedLanguages.Count > 0) - { - await video.RefreshMetadata(cancellationToken).ConfigureAwait(false); - return false; - } + subtitleDownloadLanguages = options.DownloadLanguages; + SkipIfEmbeddedSubtitlesPresent = options.SkipIfEmbeddedSubtitlesPresent; + SkipIfAudioTrackMatches = options.SkipIfAudioTrackMatches; + RequirePerfectMatch = options.RequirePerfectMatch; + } + else + { + subtitleDownloadLanguages = libraryOptions.SubtitleDownloadLanguages; + SkipIfEmbeddedSubtitlesPresent = libraryOptions.SkipSubtitlesIfEmbeddedSubtitlesPresent; + SkipIfAudioTrackMatches = libraryOptions.SkipSubtitlesIfAudioTrackMatches; + RequirePerfectMatch = libraryOptions.RequirePerfectSubtitleMatch; + } - return true; + var downloadedLanguages = await new SubtitleDownloader(_logger, + _subtitleManager) + .DownloadSubtitles(video, + mediaStreams, + SkipIfEmbeddedSubtitlesPresent, + SkipIfAudioTrackMatches, + RequirePerfectMatch, + subtitleDownloadLanguages, + cancellationToken).ConfigureAwait(false); + + // Rescan + if (downloadedLanguages.Count > 0) + { + await video.RefreshMetadata(cancellationToken).ConfigureAwait(false); + return false; } - return false; + return true; } public IEnumerable GetDefaultTriggers() diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index c1b98dfbf8..89e2725de7 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -46,7 +46,7 @@ public int Order get { // After primary option - return 1; + return 2; } } diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index a2e3109e49..f53b730e4d 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -121,15 +121,10 @@ public async Task Run(Series series, bool addNewItems, CancellationToken c var hasNewEpisodes = false; - if (addNewItems && series.IsInternetMetadataEnabled()) + if (addNewItems && series.IsMetadataFetcherEnabled(_libraryManager.GetLibraryOptions(series) ,TvdbSeriesProvider.Current.Name)) { - var seriesConfig = _config.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, typeof(Series).Name, StringComparison.OrdinalIgnoreCase)); - - if (seriesConfig == null || !seriesConfig.DisabledMetadataFetchers.Contains(TvdbSeriesProvider.Current.Name, StringComparer.OrdinalIgnoreCase)) - { - hasNewEpisodes = await AddMissingEpisodes(series, allRecursiveChildren, addMissingEpisodes, seriesDataPath, episodeLookup, cancellationToken) - .ConfigureAwait(false); - } + hasNewEpisodes = await AddMissingEpisodes(series, allRecursiveChildren, addMissingEpisodes, seriesDataPath, episodeLookup, cancellationToken) + .ConfigureAwait(false); } if (hasNewEpisodes || anySeasonsRemoved || anyEpisodesRemoved) diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs index f62b690c87..c1388025ab 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs @@ -656,8 +656,8 @@ public int Order { get { - // After Omdb and Tvdb - return 2; + // After Tvdb + return 1; } } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs index cbd0641a3d..2839cb434f 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs @@ -81,14 +81,6 @@ public TvdbPrescanTask(ILogger logger, IHttpClient httpClient, IServerConfigurat /// Task. public async Task Run(IProgress progress, CancellationToken cancellationToken) { - var seriesConfig = _config.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, typeof(Series).Name, StringComparison.OrdinalIgnoreCase)); - - if (seriesConfig != null && seriesConfig.DisabledMetadataFetchers.Contains(TvdbSeriesProvider.Current.Name, StringComparer.OrdinalIgnoreCase)) - { - progress.Report(100); - return; - } - var path = TvdbSeriesProvider.GetSeriesDataPath(_config.CommonApplicationPaths); _fileSystem.CreateDirectory(path); @@ -133,7 +125,7 @@ public async Task Run(IProgress progress, CancellationToken cancellation var missingSeries = seriesIdsInLibrary.Except(existingDirectories, StringComparer.OrdinalIgnoreCase) .ToList(); - var enableInternetProviders = seriesList.Count == 0 ? false : seriesList[0].IsInternetMetadataEnabled(); + var enableInternetProviders = seriesList.Count == 0 ? false : seriesList[0].IsMetadataFetcherEnabled(_libraryManager.GetLibraryOptions(seriesList[0]), TvdbSeriesProvider.Current.Name); if (!enableInternetProviders) { progress.Report(100); diff --git a/SharedVersion.cs b/SharedVersion.cs index 80ae4e2e7f..f684adaaf2 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.3.1.6")] +[assembly: AssemblyVersion("3.3.1.7")]