diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index 6e79e80df..acef2944b 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -32,7 +32,7 @@ namespace MediaBrowser.Api /// /// The application paths /// - private readonly IServerApplicationPaths AppPaths; + private readonly IServerApplicationPaths _appPaths; /// /// Initializes a new instance of the class. @@ -42,7 +42,7 @@ namespace MediaBrowser.Api public ApiEntryPoint(ILogger logger, IServerApplicationPaths appPaths) { Logger = logger; - AppPaths = appPaths; + _appPaths = appPaths; Instance = this; } @@ -71,7 +71,7 @@ namespace MediaBrowser.Api /// private void DeleteEncodedMediaCache() { - foreach (var file in Directory.EnumerateFiles(AppPaths.TranscodingTempPath) + foreach (var file in Directory.EnumerateFiles(_appPaths.TranscodingTempPath) .Where(i => EntityResolutionHelper.VideoFileExtensions.Contains(Path.GetExtension(i))) .ToList()) { diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index f63108048..5aa83abf4 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -176,7 +176,7 @@ namespace MediaBrowser.Common.Implementations /// /// true if this instance is running as service; otherwise, false. public abstract bool IsRunningAsService { get; } - + /// /// Initializes a new instance of the class. /// @@ -547,7 +547,7 @@ namespace MediaBrowser.Common.Implementations { Container.Register(typeInterface, typeImplementation); } - + /// /// Resolves this instance. /// @@ -709,7 +709,14 @@ namespace MediaBrowser.Common.Implementations { Logger.Info("Disposing " + part.GetType().Name); - part.Dispose(); + try + { + part.Dispose(); + } + catch (Exception ex) + { + Logger.ErrorException("Error disposing {0}", ex, part.GetType().Name); + } } } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 2b5570a80..e68790e61 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -178,7 +178,7 @@ namespace MediaBrowser.Controller.Entities.Audio // Refresh all non-songs foreach (var item in others) { - if (tasks.Count > 3) + if (tasks.Count > 4) { await Task.WhenAll(tasks).ConfigureAwait(false); tasks.Clear(); @@ -202,7 +202,9 @@ namespace MediaBrowser.Controller.Entities.Audio } }); - tasks.Add(RefreshItem(item, refreshOptions, innerProgress, cancellationToken)); + // Avoid implicitly captured closure + var taskChild = item; + tasks.Add(Task.Run(async () => await RefreshItem(taskChild, refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false), cancellationToken)); } await Task.WhenAll(tasks).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 415b49f80..41c4f0bae 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1236,7 +1236,7 @@ namespace MediaBrowser.Controller.Entities public virtual Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken) { - return LibraryManager.UpdateItem(this, ItemUpdateType.ImageUpdate, cancellationToken); + return LibraryManager.UpdateItem(this, updateReason, cancellationToken); } /// diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index b718864d2..c928a130e 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -521,7 +521,7 @@ namespace MediaBrowser.Controller.Entities foreach (var child in children) { - if (tasks.Count >= 8) + if (tasks.Count >= 4) { await Task.WhenAll(tasks).ConfigureAwait(false); tasks.Clear(); @@ -552,7 +552,10 @@ namespace MediaBrowser.Controller.Entities } else { - tasks.Add(RefreshChildMetadata(child, refreshOptions, false, innerProgress, cancellationToken)); + // Avoid implicitly captured closure + var taskChild = child; + + tasks.Add(Task.Run(async () => await RefreshChildMetadata(taskChild, refreshOptions, false, innerProgress, cancellationToken).ConfigureAwait(false), cancellationToken)); } } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index a00bda772..3fd2af091 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -99,7 +99,7 @@ namespace MediaBrowser.Controller.Entities.Movies // Refresh songs foreach (var item in items) { - if (tasks.Count >= 2) + if (tasks.Count >= 4) { await Task.WhenAll(tasks).ConfigureAwait(false); tasks.Clear(); @@ -123,7 +123,9 @@ namespace MediaBrowser.Controller.Entities.Movies } }); - tasks.Add(RefreshItem(item, refreshOptions, innerProgress, cancellationToken)); + // Avoid implicitly captured closure + var taskChild = item; + tasks.Add(Task.Run(async () => await RefreshItem(taskChild, refreshOptions, innerProgress, cancellationToken).ConfigureAwait(false), cancellationToken)); } await Task.WhenAll(tasks).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index d655c275d..50ccd060b 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -102,7 +102,11 @@ namespace MediaBrowser.Controller.Entities public TrailerInfo GetLookupInfo() { - return GetItemLookupInfo(); + var info = GetItemLookupInfo(); + + info.IsLocalTrailer = IsLocalTrailer; + + return info; } } } diff --git a/MediaBrowser.Controller/Providers/DirectoryService.cs b/MediaBrowser.Controller/Providers/DirectoryService.cs index e17ae76ff..751de9fb4 100644 --- a/MediaBrowser.Controller/Providers/DirectoryService.cs +++ b/MediaBrowser.Controller/Providers/DirectoryService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Model.Logging; +using System.Collections.Concurrent; +using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; using System.IO; @@ -19,7 +20,7 @@ namespace MediaBrowser.Controller.Providers { private readonly ILogger _logger; - private readonly Dictionary> _cache = new Dictionary>(StringComparer.OrdinalIgnoreCase); + private readonly ConcurrentDictionary> _cache = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); public DirectoryService(ILogger logger) { @@ -43,7 +44,7 @@ namespace MediaBrowser.Controller.Providers entries = new List(); } - _cache.Add(path, entries); + _cache.TryAdd(path, entries); } return entries; diff --git a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs index b43654005..665da28f4 100644 --- a/MediaBrowser.Controller/Providers/ItemLookupInfo.cs +++ b/MediaBrowser.Controller/Providers/ItemLookupInfo.cs @@ -142,7 +142,7 @@ namespace MediaBrowser.Controller.Providers public class TrailerInfo : ItemLookupInfo { - + public bool IsLocalTrailer { get; set; } } public class BookInfo : ItemLookupInfo diff --git a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs index e990ddd65..1f0f0e2e7 100644 --- a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs +++ b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Providers.BoxSets { public class MovieDbBoxSetProvider : IRemoteMetadataProvider { - private readonly CultureInfo _enUs = new CultureInfo("en-US"); + private readonly CultureInfo _enUs = new CultureInfo("en-US"); private const string GetCollectionInfo3 = @"http://api.themoviedb.org/3/collection/{0}?api_key={1}&append_to_response=images"; internal static MovieDbBoxSetProvider Current; @@ -45,7 +45,12 @@ namespace MediaBrowser.Providers.BoxSets // We don't already have an Id, need to fetch it if (string.IsNullOrEmpty(tmdbId)) { - tmdbId = await GetTmdbId(id, cancellationToken).ConfigureAwait(false); + var searchResult = await new MovieDbSearch(_logger, _json).FindCollectionId(id, cancellationToken).ConfigureAwait(false); + + if (searchResult != null) + { + tmdbId = searchResult.id.ToString(_enUs); + } } var result = new MetadataResult(); @@ -87,7 +92,7 @@ namespace MediaBrowser.Providers.BoxSets { var item = new BoxSet { - Name = obj.name, + Name = obj.name, Overview = obj.overview }; @@ -189,12 +194,7 @@ namespace MediaBrowser.Providers.BoxSets return DownloadInfo(tmdbId, preferredMetadataLanguage, cancellationToken); } - - private Task GetTmdbId(ItemLookupInfo id, CancellationToken cancellationToken) - { - return new MovieDbSearch(_logger, _json).FindCollectionId(id, cancellationToken); - } - + public string Name { get { return "TheMovieDb"; } @@ -209,7 +209,7 @@ namespace MediaBrowser.Providers.BoxSets return Path.Combine(path, filename); } - + private static string GetDataPath(IApplicationPaths appPaths, string tmdbId) { var dataPath = GetCollectionsDataPath(appPaths); diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index f64d1b152..1a28e5758 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -327,7 +327,7 @@ namespace MediaBrowser.Providers.Manager } // Local metadata is king - if any is found don't run remote providers - if ((!options.ReplaceAllMetadata && !hasLocalMetadata) || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh) + if (!options.ReplaceAllMetadata && (!hasLocalMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh)) { await ExecuteRemoteProviders(item, temp, providers.OfType>(), refreshResult, cancellationToken).ConfigureAwait(false); } diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index 44e2beb7f..abd48e37c 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -39,8 +39,12 @@ namespace MediaBrowser.Providers.Movies // Don't search for music video id's because it is very easy to misidentify. if (string.IsNullOrEmpty(tmdbId) && string.IsNullOrEmpty(imdbId) && typeof(T) != typeof(MusicVideo)) { - tmdbId = await new MovieDbSearch(_logger, _jsonSerializer) - .FindMovieId(itemId, cancellationToken).ConfigureAwait(false); + var searchResult = await new MovieDbSearch(_logger, _jsonSerializer).FindMovieId(itemId, cancellationToken).ConfigureAwait(false); + + if (searchResult != null) + { + tmdbId = searchResult.id.ToString(_usCulture); + } } if (!string.IsNullOrEmpty(tmdbId) || !string.IsNullOrEmpty(imdbId)) diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 36dfc64d2..3bfd69ef1 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Providers.Movies /// /// Class MovieDbProvider /// - public class MovieDbProvider : IRemoteMetadataProvider, IDisposable + public class MovieDbProvider : IRemoteMetadataProvider, IDisposable, IHasOrder { internal readonly SemaphoreSlim MovieDbResourcePool = new SemaphoreSlim(1, 1); @@ -529,5 +529,14 @@ namespace MediaBrowser.Providers.Movies public Keywords keywords { get; set; } public Trailers trailers { get; set; } } + + public int Order + { + get + { + // After Omdb + return 1; + } + } } } diff --git a/MediaBrowser.Providers/Movies/MovieDbSearch.cs b/MediaBrowser.Providers/Movies/MovieDbSearch.cs index fb673739c..b171a2178 100644 --- a/MediaBrowser.Providers/Movies/MovieDbSearch.cs +++ b/MediaBrowser.Providers/Movies/MovieDbSearch.cs @@ -29,22 +29,22 @@ namespace MediaBrowser.Providers.Movies _json = json; } - public Task FindSeriesId(ItemLookupInfo idInfo, CancellationToken cancellationToken) + public Task FindSeriesId(ItemLookupInfo idInfo, CancellationToken cancellationToken) { return FindId(idInfo, "tv", cancellationToken); } - public Task FindMovieId(ItemLookupInfo idInfo, CancellationToken cancellationToken) + public Task FindMovieId(ItemLookupInfo idInfo, CancellationToken cancellationToken) { return FindId(idInfo, "movie", cancellationToken); } - public Task FindCollectionId(ItemLookupInfo idInfo, CancellationToken cancellationToken) + public Task FindCollectionId(ItemLookupInfo idInfo, CancellationToken cancellationToken) { return FindId(idInfo, "collection", cancellationToken); } - private async Task FindId(ItemLookupInfo idInfo, string searchType, CancellationToken cancellationToken) + private async Task FindId(ItemLookupInfo idInfo, string searchType, CancellationToken cancellationToken) { var name = idInfo.Name; var year = idInfo.Year; @@ -101,7 +101,7 @@ namespace MediaBrowser.Providers.Movies return id; } - private async Task AttemptFindId(string name, string type, int? year, string language, CancellationToken cancellationToken) + private async Task AttemptFindId(string name, string type, int? year, string language, CancellationToken cancellationToken) { var url3 = string.Format(Search3, WebUtility.UrlEncode(name), ApiKey, language, type); @@ -114,16 +114,16 @@ namespace MediaBrowser.Providers.Movies }).ConfigureAwait(false)) { var searchResult = _json.DeserializeFromStream(json); - return FindIdOfBestResult(searchResult.results, name, year); + return FindBestResult(searchResult.results, name, year); } } - private string FindIdOfBestResult(List results, string name, int? year) + private TmdbMovieSearchResult FindBestResult(List results, string name, int? year) { if (year.HasValue) { // Take the first result from the same year - var id = results.Where(i => + var result = results.FirstOrDefault(i => { // Make sure it has a name if (!string.IsNullOrEmpty(i.title ?? i.name)) @@ -138,17 +138,15 @@ namespace MediaBrowser.Providers.Movies } return false; - }) - .Select(i => i.id.ToString(CultureInfo.InvariantCulture)) - .FirstOrDefault(); + }); - if (!string.IsNullOrEmpty(id)) + if (result != null) { - return id; + return null; } // Take the first result within one year - id = results.Where(i => + result = results.FirstOrDefault(i => { // Make sure it has a name if (!string.IsNullOrEmpty(i.title ?? i.name)) @@ -163,27 +161,23 @@ namespace MediaBrowser.Providers.Movies } return false; - }) - .Select(i => i.id.ToString(CultureInfo.InvariantCulture)) - .FirstOrDefault(); + }); - if (!string.IsNullOrEmpty(id)) + if (result != null) { - return id; + return null; } } // Just take the first one - return results.Where(i => !string.IsNullOrEmpty(i.title ?? i.name)) - .Select(i => i.id.ToString(CultureInfo.InvariantCulture)) - .FirstOrDefault(); + return results.FirstOrDefault(i => !string.IsNullOrEmpty(i.title ?? i.name)); } /// /// Class TmdbMovieSearchResult /// - private class TmdbMovieSearchResult + public class TmdbMovieSearchResult { /// /// Gets or sets a value indicating whether this is adult. diff --git a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs index ed36cb7af..0ad19840e 100644 --- a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.Movies { - public class MovieDbTrailerProvider : IRemoteMetadataProvider + public class MovieDbTrailerProvider : IRemoteMetadataProvider, IHasOrder { public Task> GetMetadata(TrailerInfo info, CancellationToken cancellationToken) { @@ -22,5 +22,14 @@ namespace MediaBrowser.Providers.Movies { return MovieDbProvider.Current.HasChanged(item, date); } + + public int Order + { + get + { + // After Omdb + return 1; + } + } } } diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index 8f870d25a..3f30626ff 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -2,24 +2,31 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; +using MediaBrowser.Providers.Movies; +using MediaBrowser.Providers.TV; +using System; +using System.Globalization; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Providers.Omdb { - public class OmdbItemProvider : ICustomMetadataProvider, - ICustomMetadataProvider, ICustomMetadataProvider + public class OmdbItemProvider : IRemoteMetadataProvider, + IRemoteMetadataProvider, IRemoteMetadataProvider { private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; + private readonly ILogger _logger; - public OmdbItemProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient) + public OmdbItemProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; + _logger = logger; } public string Name @@ -27,25 +34,110 @@ namespace MediaBrowser.Providers.Omdb get { return "IMDb via The Open Movie Database"; } } - public Task FetchAsync(Series item, IDirectoryService directoryService, CancellationToken cancellationToken) + public async Task> GetMetadata(SeriesInfo info, CancellationToken cancellationToken) { - return new OmdbProvider(_jsonSerializer, _httpClient).Fetch(item, cancellationToken); - } - - public Task FetchAsync(Movie item, IDirectoryService directoryService, CancellationToken cancellationToken) - { - return new OmdbProvider(_jsonSerializer, _httpClient).Fetch(item, cancellationToken); - } - - private readonly Task _cachedTask = Task.FromResult(ItemUpdateType.None); - public Task FetchAsync(Trailer item, IDirectoryService directoryService, CancellationToken cancellationToken) - { - if (item.IsLocalTrailer) + var result = new MetadataResult { - return _cachedTask; + Item = new Series() + }; + + var imdbId = info.GetProviderId(MetadataProviders.Imdb); + + if (string.IsNullOrEmpty(imdbId)) + { + var searchResult = await GetSeriesImdbId(info, cancellationToken).ConfigureAwait(false); + + imdbId = searchResult.Item1; + + if (!string.IsNullOrEmpty(searchResult.Item2)) + { + result.Item.SetProviderId(MetadataProviders.Tvdb, searchResult.Item2); + } + } + + if (!string.IsNullOrEmpty(imdbId)) + { + result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); + result.HasMetadata = true; + + await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, cancellationToken) + .ConfigureAwait(false); } - return new OmdbProvider(_jsonSerializer, _httpClient).Fetch(item, cancellationToken); + return result; + } + + public Task> GetMetadata(MovieInfo info, CancellationToken cancellationToken) + { + return GetMovieResult(info, cancellationToken); + } + + public Task> GetMetadata(TrailerInfo info, CancellationToken cancellationToken) + { + var result = new MetadataResult(); + + if (info.IsLocalTrailer) + { + return Task.FromResult(result); + } + + return GetMovieResult(info, cancellationToken); + } + + private async Task> GetMovieResult(ItemLookupInfo info, CancellationToken cancellationToken) + where T : Video, new() + { + var result = new MetadataResult + { + Item = new T() + }; + + var imdbId = info.GetProviderId(MetadataProviders.Imdb); + + if (string.IsNullOrEmpty(imdbId)) + { + var searchResult = await GetMovieImdbId(info, cancellationToken).ConfigureAwait(false); + + imdbId = searchResult.Item1; + + if (!string.IsNullOrEmpty(searchResult.Item2)) + { + result.Item.SetProviderId(MetadataProviders.Tmdb, searchResult.Item2); + } + } + + if (!string.IsNullOrEmpty(imdbId)) + { + result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); + result.HasMetadata = true; + + await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, cancellationToken) + .ConfigureAwait(false); + } + + return result; + } + + private async Task> GetMovieImdbId(ItemLookupInfo info, CancellationToken cancellationToken) + { + var result = await new GenericMovieDbInfo(_logger, _jsonSerializer).GetMetadata(info, cancellationToken) + .ConfigureAwait(false); + + var imdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Imdb) : null; + var tmdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tmdb) : null; + + return new Tuple(imdb, tmdb); + } + + private async Task> GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken) + { + var result = await TvdbSeriesProvider.Current.GetMetadata(info, cancellationToken) + .ConfigureAwait(false); + + var imdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Imdb) : null; + var tvdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tvdb) : null; + + return new Tuple(imdb, tvdb); } } } diff --git a/MediaBrowser.Providers/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Omdb/OmdbProvider.cs index 8eabc5164..38f555133 100644 --- a/MediaBrowser.Providers/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbProvider.cs @@ -2,7 +2,6 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Serialization; using System; @@ -16,26 +15,23 @@ namespace MediaBrowser.Providers.Omdb { public class OmdbProvider { - private readonly SemaphoreSlim _resourcePool = new SemaphoreSlim(1, 1); + internal readonly SemaphoreSlim ResourcePool = new SemaphoreSlim(1, 1); private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + public static OmdbProvider Current; + public OmdbProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; + + Current = this; } - public async Task Fetch(BaseItem item, CancellationToken cancellationToken) + public async Task Fetch(BaseItem item, string imdbId, CancellationToken cancellationToken) { - var imdbId = item.GetProviderId(MetadataProviders.Imdb); - - if (string.IsNullOrEmpty(imdbId)) - { - return ItemUpdateType.None; - } - var imdbParam = imdbId.StartsWith("tt", StringComparison.OrdinalIgnoreCase) ? imdbId : "tt" + imdbId; var url = string.Format("http://www.omdbapi.com/?i={0}&tomatoes=true", imdbParam); @@ -43,7 +39,7 @@ namespace MediaBrowser.Providers.Omdb using (var stream = await _httpClient.Get(new HttpRequestOptions { Url = url, - ResourcePool = _resourcePool, + ResourcePool = ResourcePool, CancellationToken = cancellationToken }).ConfigureAwait(false)) @@ -98,16 +94,13 @@ namespace MediaBrowser.Providers.Omdb ParseAdditionalMetadata(item, result); } - - return ItemUpdateType.MetadataDownload; } private void ParseAdditionalMetadata(BaseItem item, RootObject result) { // 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 (!item.LockedFields.Contains(MetadataFields.Genres) && - ShouldFetchGenres(item) && + if (ShouldFetchGenres(item) && !string.IsNullOrWhiteSpace(result.Genre) && !string.Equals(result.Genre, "n/a", StringComparison.OrdinalIgnoreCase)) { @@ -146,21 +139,10 @@ namespace MediaBrowser.Providers.Omdb var lang = item.GetPreferredMetadataLanguage(); // The data isn't localized and so can only be used for english users - if (!string.Equals(lang, "en", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - // Only fetch if other providers didn't get anything - if (item is Trailer) - { - return item.Genres.Count == 0; - } - - return item is Series || item is Movie; + return string.Equals(lang, "en", StringComparison.OrdinalIgnoreCase); } - protected class RootObject + public class RootObject { public string Title { get; set; } public string Year { get; set; } diff --git a/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs b/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs index 5dd8a056f..f62922f6a 100644 --- a/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/MovieDbSeriesProvider.cs @@ -73,7 +73,12 @@ namespace MediaBrowser.Providers.TV if (string.IsNullOrEmpty(tmdbId)) { - tmdbId = await new MovieDbSearch(_logger, _jsonSerializer).FindSeriesId(info, cancellationToken).ConfigureAwait(false); + var searchResult = await new MovieDbSearch(_logger, _jsonSerializer).FindSeriesId(info, cancellationToken).ConfigureAwait(false); + + if (searchResult != null) + { + tmdbId = searchResult.id.ToString(_usCulture); + } } if (!string.IsNullOrEmpty(tmdbId)) @@ -434,7 +439,7 @@ namespace MediaBrowser.Providers.TV { get { - // After Tvdb + // After Omdb and Tvdb return 2; } } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index f3909e2c6..44950c4d3 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -22,7 +22,7 @@ using System.Xml; namespace MediaBrowser.Providers.TV { - public class TvdbSeriesProvider : IRemoteMetadataProvider + public class TvdbSeriesProvider : IRemoteMetadataProvider, IHasOrder { internal readonly SemaphoreSlim TvDbResourcePool = new SemaphoreSlim(2, 2); internal static TvdbSeriesProvider Current { get; private set; } @@ -1072,5 +1072,14 @@ namespace MediaBrowser.Providers.TV { get { return "TheTVDB"; } } + + public int Order + { + get + { + // After Omdb + return 1; + } + } } } diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml.cs b/MediaBrowser.ServerApplication/MainWindow.xaml.cs index 4f328b7f5..627150d81 100644 --- a/MediaBrowser.ServerApplication/MainWindow.xaml.cs +++ b/MediaBrowser.ServerApplication/MainWindow.xaml.cs @@ -154,7 +154,9 @@ namespace MediaBrowser.ServerApplication // Add our log window if specified if (_configurationManager.Configuration.ShowLogWindow) { - Trace.Listeners.Add(new WindowTraceListener(new LogForm(_logManager))); + _logForm = new LogForm(_logManager); + + Trace.Listeners.Add(new WindowTraceListener(_logForm)); } else {