Browse Source

Added OmdbEpisodeProvider as an alternative source for series episodes

This new episode provider implementation does not bulk-download or cache
episode data. It is only meant to be a backup source for situations
where media is not recognized by the default provider (TheTvDb).
softworkz 9 năm trước cách đây
mục cha
commit
182f1da03e

+ 2 - 1
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -565,7 +565,7 @@ namespace MediaBrowser.Model.Configuration
                             Type = ImageType.Thumb
                         }
                     },
-                    DisabledMetadataFetchers = new []{ "TheMovieDb" }
+                    DisabledMetadataFetchers = new []{ "The Open Movie Database", "TheMovieDb" }
                 },
 
                 new MetadataOptions(0, 1280)
@@ -586,6 +586,7 @@ namespace MediaBrowser.Model.Configuration
                             Type = ImageType.Primary
                         }
                     },
+                    DisabledMetadataFetchers = new []{ "The Open Movie Database" },
                     DisabledImageFetchers = new []{ "TheMovieDb" }
                 }
             };

+ 1 - 0
MediaBrowser.Providers/MediaBrowser.Providers.csproj

@@ -177,6 +177,7 @@
     <Compile Include="TV\MovieDbSeasonProvider.cs" />
     <Compile Include="TV\MovieDbSeriesImageProvider.cs" />
     <Compile Include="TV\MovieDbSeriesProvider.cs" />
+    <Compile Include="TV\OmdbEpisodeProvider.cs" />
     <Compile Include="TV\SeriesMetadataService.cs" />
     <Compile Include="TV\TvdbEpisodeImageProvider.cs" />
     <Compile Include="People\TvdbPersonImageProvider.cs" />

+ 42 - 4
MediaBrowser.Providers/Omdb/OmdbItemProvider.cs

@@ -60,12 +60,18 @@ namespace MediaBrowser.Providers.Omdb
         public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken)
         {
             bool isSearch = false;
+            var episodeSearchInfo = searchInfo as EpisodeInfo;
 
             var list = new List<RemoteSearchResult>();
 
             var imdbId = searchInfo.GetProviderId(MetadataProviders.Imdb);
 
-            var url = "http://www.omdbapi.com/?plot=short&r=json";
+            var url = "http://www.omdbapi.com/?plot=full&r=json";
+            if (type == "episode" && episodeSearchInfo != null)
+            {
+                episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out imdbId);
+            }
+
 
             var name = searchInfo.Name;
             var year = searchInfo.Year;
@@ -95,6 +101,18 @@ namespace MediaBrowser.Providers.Omdb
                 url += "&i=" + imdbId;
             }
 
+            if (type == "episode")
+            {
+                if (searchInfo.IndexNumber.HasValue)
+                {
+                    url += string.Format(CultureInfo.InvariantCulture, "&Episode={0}", searchInfo.IndexNumber);
+                }
+                if (searchInfo.ParentIndexNumber.HasValue)
+                {
+                    url += string.Format(CultureInfo.InvariantCulture, "&Season={0}", searchInfo.ParentIndexNumber);
+                }
+            }
+
             using (var stream = await _httpClient.Get(new HttpRequestOptions
             {
                 Url = url,
@@ -124,10 +142,20 @@ namespace MediaBrowser.Providers.Omdb
 
                 foreach (var result in resultList)
                 {
-                    var item = new RemoteSearchResult();
+                    var item = new RemoteSearchResult
+                    {
+                        IndexNumber = searchInfo.IndexNumber,
+                        Name = result.Title,
+                        ParentIndexNumber = searchInfo.ParentIndexNumber,
+                        ProviderIds = searchInfo.ProviderIds,
+                        SearchProviderName = Name
+                    };
+
+                    if (episodeSearchInfo != null && episodeSearchInfo.IndexNumberEnd.HasValue)
+                    {
+                        item.IndexNumberEnd = episodeSearchInfo.IndexNumberEnd.Value;
+                    }
 
-                    item.SearchProviderName = Name;
-                    item.Name = result.Title;
                     item.SetProviderId(MetadataProviders.Imdb, result.imdbID);
 
                     int parsedYear;
@@ -137,6 +165,13 @@ namespace MediaBrowser.Providers.Omdb
                         item.ProductionYear = parsedYear;
                     }
 
+                    DateTime released;
+                    if (!string.IsNullOrEmpty(result.Released)
+                        && DateTime.TryParse(result.Released, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out released))
+                    {
+                        item.PremiereDate = released;
+                    }
+
                     if (!string.IsNullOrWhiteSpace(result.Poster) && !string.Equals(result.Poster, "N/A", StringComparison.OrdinalIgnoreCase))
                     {
                         item.ImageUrl = result.Poster;
@@ -267,6 +302,8 @@ namespace MediaBrowser.Providers.Omdb
             public string Year { get; set; }
             public string Rated { get; set; }
             public string Released { get; set; }
+            public string Season { get; set; }
+            public string Episode { get; set; }
             public string Runtime { get; set; }
             public string Genre { get; set; }
             public string Director { get; set; }
@@ -281,6 +318,7 @@ namespace MediaBrowser.Providers.Omdb
             public string imdbRating { get; set; }
             public string imdbVotes { get; set; }
             public string imdbID { get; set; }
+            public string seriesID { get; set; }
             public string Type { get; set; }
             public string Response { get; set; }
         }

+ 89 - 0
MediaBrowser.Providers/TV/OmdbEpisodeProvider.cs

@@ -0,0 +1,89 @@
+using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Providers;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Providers.Omdb;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.TV
+{
+    class OmdbEpisodeProvider :
+            IRemoteMetadataProvider<Episode, EpisodeInfo>,
+            IHasOrder
+    {
+        private readonly IJsonSerializer _jsonSerializer;
+        private readonly IHttpClient _httpClient;
+        private OmdbItemProvider _itemProvider;
+
+        public OmdbEpisodeProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager)
+        {
+            _jsonSerializer = jsonSerializer;
+            _httpClient = httpClient;
+            _itemProvider = new OmdbItemProvider(jsonSerializer, httpClient, logger, libraryManager);
+        }
+
+        public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken)
+        {
+            return _itemProvider.GetSearchResults(searchInfo, "episode", cancellationToken);
+        }
+
+        public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken)
+        {
+            var result = new MetadataResult<Episode>
+            {
+                Item = new Episode()
+            };
+
+            var imdbId = info.GetProviderId(MetadataProviders.Imdb);
+            if (string.IsNullOrWhiteSpace(imdbId))
+            {
+                imdbId = await GetEpisodeImdbId(info, cancellationToken).ConfigureAwait(false);
+            }
+
+            if (!string.IsNullOrEmpty(imdbId))
+            {
+                result.Item.SetProviderId(MetadataProviders.Imdb, imdbId);
+                result.HasMetadata = true;
+
+                await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
+            }
+
+            return result;
+        }
+
+        private async Task<string> GetEpisodeImdbId(EpisodeInfo info, CancellationToken cancellationToken)
+        {
+            var results = await GetSearchResults(info, cancellationToken).ConfigureAwait(false);
+            var first = results.FirstOrDefault();
+            return first == null ? null : first.GetProviderId(MetadataProviders.Imdb);
+        }
+
+        public int Order
+        {
+            get
+            {
+                // After TheTvDb
+                return 1;
+            }
+        }
+
+        public string Name
+        {
+            get { return "The Open Movie Database"; }
+        }
+
+        public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
+        {
+            return _itemProvider.GetImageResponse(url, cancellationToken);
+        }
+    }
+}

+ 10 - 3
MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs

@@ -427,11 +427,18 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
             }, cancellationToken).ConfigureAwait(false);
 
             var episode = searchResults.FirstOrDefault();
+            
+            string episodeName = string.Empty;
 
             if (episode == null)
             {
-                _logger.Warn("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber);
-                return null;
+                var msg = string.Format("No provider metadata found for {0} season {1} episode {2}", series.Name, seasonNumber, episodeNumber);
+                _logger.Warn(msg);
+                //throw new Exception(msg);
+            }
+            else
+            {
+                episodeName = episode.Name;
             }
 
             var newPath = GetSeasonFolderPath(series, seasonNumber, options);
@@ -449,7 +456,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
             // Remove additional 4 chars to prevent PathTooLongException for downloaded subtitles (eg. filename.ext.eng.srt)
             maxFilenameLength -= 4;
 
-            var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber, episodeNumber, endingEpisodeNumber, episode.Name, options, maxFilenameLength);
+            var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber, episodeNumber, endingEpisodeNumber, episodeName, options, maxFilenameLength);
 
             if (string.IsNullOrEmpty(episodeFileName))
             {