diff options
Diffstat (limited to 'MediaBrowser.Providers')
47 files changed, 473 insertions, 181 deletions
diff --git a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs index ff3d5a5b24..b3e73740d9 100644 --- a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs +++ b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetImageProvider.cs @@ -61,7 +61,7 @@ namespace MediaBrowser.Providers.BoxSets { var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; return GetImages(mainResult, language, tmdbImageUrl); } diff --git a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs index 2cac9b0638..ab05c959e8 100644 --- a/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs +++ b/MediaBrowser.Providers/BoxSets/MovieDbBoxSetProvider.cs @@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.BoxSets { public class MovieDbBoxSetProvider : IRemoteMetadataProvider<BoxSet, BoxSetInfo> { - private const string GetCollectionInfo3 = @"http://api.themoviedb.org/3/collection/{0}?api_key={1}&append_to_response=images"; + private const string GetCollectionInfo3 = @"https://api.themoviedb.org/3/collection/{0}?api_key={1}&append_to_response=images"; internal static MovieDbBoxSetProvider Current; @@ -64,7 +64,7 @@ namespace MediaBrowser.Providers.BoxSets var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; var result = new RemoteSearchResult { diff --git a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs index afd8c583d8..08b4f64610 100644 --- a/MediaBrowser.Providers/Folders/DefaultImageProvider.cs +++ b/MediaBrowser.Providers/Folders/DefaultImageProvider.cs @@ -117,7 +117,7 @@ namespace MediaBrowser.Providers.Folders } if (string.IsNullOrWhiteSpace(viewType)) { - return urlPrefix + "generic.jpg"; + //return urlPrefix + "generic.jpg"; } return null; diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index eeec4ea56a..a0c6bd889a 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -295,22 +295,22 @@ namespace MediaBrowser.Providers.Manager return true; } - if (item is BoxSet || item is IItemByName || item is Playlist) + if (!(item is Audio) && !(item is Video)) { return true; } - if (item.SourceType != SourceType.Library) + if (item is IItemByName) { return true; } - if (item is ICollectionFolder) + if (item.SourceType != SourceType.Library) { return true; } - if (!(item is Audio) && !(item is Video)) + if (item is MusicVideo) { return true; } @@ -395,7 +395,6 @@ namespace MediaBrowser.Providers.Manager return _cachedTask; } - private readonly Task<ItemUpdateType> _cachedResult = Task.FromResult(ItemUpdateType.None); /// <summary> /// Befores the save. /// </summary> @@ -403,9 +402,60 @@ namespace MediaBrowser.Providers.Manager /// <param name="isFullRefresh">if set to <c>true</c> [is full refresh].</param> /// <param name="currentUpdateType">Type of the current update.</param> /// <returns>ItemUpdateType.</returns> - protected virtual Task<ItemUpdateType> BeforeSave(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) + protected virtual async Task<ItemUpdateType> BeforeSave(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) + { + var updateType = ItemUpdateType.None; + + updateType |= SaveCumulativeRunTimeTicks(item, isFullRefresh, currentUpdateType); + updateType |= SaveDateLastMediaAdded(item, isFullRefresh, currentUpdateType); + + return updateType; + } + + private ItemUpdateType SaveCumulativeRunTimeTicks(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) + { + var updateType = ItemUpdateType.None; + + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) + { + var folder = item as Folder; + if (folder != null && folder.SupportsCumulativeRunTimeTicks) + { + var items = folder.GetRecursiveChildren(i => !i.IsFolder).ToList(); + var ticks = items.Select(i => i.RunTimeTicks ?? 0).Sum(); + + if (!folder.RunTimeTicks.HasValue || folder.RunTimeTicks.Value != ticks) + { + folder.RunTimeTicks = ticks; + updateType = ItemUpdateType.MetadataEdit; + } + } + } + + return updateType; + } + + private ItemUpdateType SaveDateLastMediaAdded(TItemType item, bool isFullRefresh, ItemUpdateType currentUpdateType) { - return _cachedResult; + var updateType = ItemUpdateType.None; + + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) + { + var folder = item as Folder; + if (folder != null && folder.SupportsDateLastMediaAdded) + { + var items = folder.GetRecursiveChildren(i => !i.IsFolder).Select(i => i.DateCreated).ToList(); + var date = items.Count == 0 ? (DateTime?)null : items.Max(); + + if ((!folder.DateLastMediaAdded.HasValue && date.HasValue) || folder.DateLastMediaAdded != date) + { + folder.DateLastMediaAdded = date; + updateType = ItemUpdateType.MetadataEdit; + } + } + } + + return updateType; } /// <summary> @@ -425,7 +475,7 @@ namespace MediaBrowser.Providers.Manager : status.DateLastMetadataRefresh ?? default(DateTime); // Run all if either of these flags are true - var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime); + var runAllProviders = options.ReplaceAllMetadata || options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || dateLastRefresh == default(DateTime) || item.RequiresRefresh(); if (!runAllProviders) { @@ -435,18 +485,18 @@ namespace MediaBrowser.Providers.Manager var providersWithChanges = providers .Where(i => { - var hasChangeMonitor = i as IHasChangeMonitor; - if (hasChangeMonitor != null) - { - return HasChanged(item, hasChangeMonitor, currentItem.DateLastSaved, options.DirectoryService); - } - var hasFileChangeMonitor = i as IHasItemChangeMonitor; if (hasFileChangeMonitor != null) { return HasChanged(item, hasFileChangeMonitor, options.DirectoryService); } + var hasChangeMonitor = i as IHasChangeMonitor; + if (hasChangeMonitor != null) + { + return HasChanged(item, hasChangeMonitor, currentItem.DateLastSaved, options.DirectoryService); + } + return false; }) .ToList(); diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs index 278d8ed710..59a2da4603 100644 --- a/MediaBrowser.Providers/Manager/ProviderUtils.cs +++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs @@ -40,6 +40,15 @@ namespace MediaBrowser.Providers.Manager } } + if (replaceData || string.IsNullOrEmpty(target.OriginalTitle)) + { + // Safeguard against incoming data having an emtpy name + if (!string.IsNullOrWhiteSpace(source.OriginalTitle)) + { + target.OriginalTitle = source.OriginalTitle; + } + } + if (replaceData || !target.CommunityRating.HasValue) { target.CommunityRating = source.CommunityRating; diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs index 9db4ab96e9..b89b0b9256 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs @@ -30,6 +30,7 @@ namespace MediaBrowser.Providers.MediaInfo ICustomMetadataProvider<Movie>, ICustomMetadataProvider<LiveTvVideoRecording>, ICustomMetadataProvider<LiveTvAudioRecording>, + ICustomMetadataProvider<Trailer>, ICustomMetadataProvider<Video>, ICustomMetadataProvider<Audio>, IHasItemChangeMonitor, @@ -77,6 +78,11 @@ namespace MediaBrowser.Providers.MediaInfo return FetchVideoInfo(item, options, cancellationToken); } + public Task<ItemUpdateType> FetchAsync(Trailer item, MetadataRefreshOptions options, CancellationToken cancellationToken) + { + return FetchVideoInfo(item, options, cancellationToken); + } + public Task<ItemUpdateType> FetchAsync(Video item, MetadataRefreshOptions options, CancellationToken cancellationToken) { return FetchVideoInfo(item, options, cancellationToken); diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 6215100285..e1ab61cbbe 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -444,7 +444,11 @@ namespace MediaBrowser.Providers.MediaInfo { if (string.IsNullOrWhiteSpace(video.Name) || string.Equals(video.Name, Path.GetFileNameWithoutExtension(video.Path), StringComparison.OrdinalIgnoreCase)) { - video.Name = data.Name; + // Don't use the embedded name for extras because it will often be the same name as the movie + if (!video.ExtraType.HasValue && !video.IsOwnedItem) + { + video.Name = data.Name; + } } } diff --git a/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs b/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs index d207e6e7c6..5262f8e3b1 100644 --- a/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs +++ b/MediaBrowser.Providers/Movies/FanArtMovieUpdatesPostScanTask.cs @@ -20,7 +20,7 @@ namespace MediaBrowser.Providers.Movies { class FanartMovieUpdatesPostScanTask : ILibraryPostScanTask { - private const string UpdatesUrl = "http://webservice.fanart.tv/v3/movies/latest?api_key={0}&date={1}"; + private const string UpdatesUrl = "https://webservice.fanart.tv/v3/movies/latest?api_key={0}&date={1}"; /// <summary> /// The _HTTP client diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs index a1dbc19679..775e6dfb9c 100644 --- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs +++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs @@ -16,6 +16,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using CommonIO; @@ -23,7 +24,7 @@ using MediaBrowser.Providers.TV; namespace MediaBrowser.Providers.Movies { - public class FanartMovieImageProvider : IRemoteImageProvider, IHasChangeMonitor, IHasOrder + public class FanartMovieImageProvider : IRemoteImageProvider, IHasItemChangeMonitor, IHasOrder { private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly IServerConfigurationManager _config; @@ -31,7 +32,7 @@ namespace MediaBrowser.Providers.Movies private readonly IFileSystem _fileSystem; private readonly IJsonSerializer _json; - private const string FanArtBaseUrl = "http://webservice.fanart.tv/v3/movies/{1}?api_key={0}"; + private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/movies/{1}?api_key={0}"; // &client_key=52c813aa7b8c8b3bb87f4797532a2f8c internal static FanartMovieImageProvider Current; @@ -185,6 +186,7 @@ namespace MediaBrowser.Providers.Movies PopulateImages(list, obj.moviebackground, ImageType.Backdrop, 1920, 1080); } + private Regex _regex_http = new Regex("^http://"); private void PopulateImages(List<RemoteImageInfo> list, List<Image> images, ImageType type, int width, int height) { if (images == null) @@ -208,7 +210,7 @@ namespace MediaBrowser.Providers.Movies Width = width, Height = height, ProviderName = Name, - Url = url, + Url = _regex_http.Replace(url, "https://", 1), Language = i.lang }; @@ -239,7 +241,7 @@ namespace MediaBrowser.Providers.Movies }); } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { var options = FanartSeriesProvider.Current.GetFanartOptions(); if (!options.EnableAutomaticUpdates) @@ -260,7 +262,7 @@ namespace MediaBrowser.Providers.Movies var fileInfo = _fileSystem.GetFileInfo(path); - return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date; + return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed; } return false; diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs index 6c6f6f0eb0..d13716cba1 100644 --- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs +++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs @@ -249,7 +249,7 @@ namespace MediaBrowser.Providers.Movies } resultItem.ResetPeople(); - var tmdbImageUrl = settings.images.base_url + "original"; + var tmdbImageUrl = settings.images.secure_base_url + "original"; //Actors, Directors, Writers - all in People //actors come from cast @@ -329,7 +329,7 @@ namespace MediaBrowser.Providers.Movies { hasTrailers.RemoteTrailers = movieData.trailers.youtube.Select(i => new MediaUrl { - Url = string.Format("http://www.youtube.com/watch?v={0}", i.source), + Url = string.Format("https://www.youtube.com/watch?v={0}", i.source), Name = i.name, VideoSize = string.Equals("hd", i.size, StringComparison.OrdinalIgnoreCase) ? VideoSize.HighDefinition : VideoSize.StandardDefinition diff --git a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs index e091cddc63..5958c3a0ad 100644 --- a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs @@ -17,7 +17,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.Movies { - class MovieDbImageProvider : IRemoteImageProvider, IHasOrder, IHasChangeMonitor + class MovieDbImageProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor { private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; @@ -72,7 +72,7 @@ namespace MediaBrowser.Providers.Movies var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; var supportedImages = GetSupportedImages(item).ToList(); @@ -222,9 +222,9 @@ namespace MediaBrowser.Providers.Movies }); } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - return MovieDbProvider.Current.HasChanged(item, date); + return MovieDbProvider.Current.HasChanged(item); } } } diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 51051e41d6..c588a9a690 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -78,7 +78,7 @@ namespace MediaBrowser.Providers.Movies var tmdbSettings = await GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; var remoteResult = new RemoteSearchResult { @@ -172,8 +172,8 @@ namespace MediaBrowser.Providers.Movies } } - private const string TmdbConfigUrl = "http://api.themoviedb.org/3/configuration?api_key={0}"; - private const string GetMovieInfo3 = @"http://api.themoviedb.org/3/movie/{0}?api_key={1}&append_to_response=casts,releases,images,keywords,trailers"; + private const string TmdbConfigUrl = "https://api.themoviedb.org/3/configuration?api_key={0}"; + private const string GetMovieInfo3 = @"https://api.themoviedb.org/3/movie/{0}?api_key={1}&append_to_response=casts,releases,images,keywords,trailers"; internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669"; internal static string AcceptHeader = "application/json,image/*"; @@ -281,7 +281,7 @@ namespace MediaBrowser.Providers.Movies public static string NormalizeLanguage(string language) { // They require this to be uppercase - // http://emby.media/community/index.php?/topic/32454-fr-follow-tmdbs-new-language-api-update/?p=311148 + // https://emby.media/community/index.php?/topic/32454-fr-follow-tmdbs-new-language-api-update/?p=311148 var parts = language.Split('-'); if (parts.Length == 2) @@ -414,7 +414,7 @@ namespace MediaBrowser.Providers.Movies return _configurationManager.GetConfiguration<TheMovieDbOptions>("themoviedb"); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item) { if (!GetTheMovieDbOptions().EnableAutomaticUpdates) { @@ -430,7 +430,7 @@ namespace MediaBrowser.Providers.Movies var fileInfo = _fileSystem.GetFileInfo(dataFilePath); - return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date; + return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed; } return false; diff --git a/MediaBrowser.Providers/Movies/MovieDbSearch.cs b/MediaBrowser.Providers/Movies/MovieDbSearch.cs index e8eeab9c53..ceb41178e1 100644 --- a/MediaBrowser.Providers/Movies/MovieDbSearch.cs +++ b/MediaBrowser.Providers/Movies/MovieDbSearch.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Movies public class MovieDbSearch { private static readonly CultureInfo EnUs = new CultureInfo("en-US"); - private const string Search3 = @"http://api.themoviedb.org/3/search/{3}?api_key={1}&query={0}&language={2}"; + private const string Search3 = @"https://api.themoviedb.org/3/search/{3}?api_key={1}&query={0}&language={2}"; internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669"; internal static string AcceptHeader = "application/json,image/*"; @@ -56,7 +56,7 @@ namespace MediaBrowser.Providers.Movies var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; if (!string.IsNullOrWhiteSpace(name)) { diff --git a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs index 336968a840..5fb3ea3696 100644 --- a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs @@ -33,9 +33,9 @@ namespace MediaBrowser.Providers.Movies get { return MovieDbProvider.Current.Name; } } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - return MovieDbProvider.Current.HasChanged(item, date); + return MovieDbProvider.Current.HasChanged(item); } public int Order diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index 02c3302679..3bceb976e7 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Providers.Movies public string UrlFormatString { - get { return "http://www.themoviedb.org/movie/{0}"; } + get { return "https://www.themoviedb.org/movie/{0}"; } } public bool Supports(IHasProviderIds item) @@ -51,7 +51,7 @@ namespace MediaBrowser.Providers.Movies public string UrlFormatString { - get { return "http://www.themoviedb.org/tv/{0}"; } + get { return "https://www.themoviedb.org/tv/{0}"; } } public bool Supports(IHasProviderIds item) @@ -74,7 +74,7 @@ namespace MediaBrowser.Providers.Movies public string UrlFormatString { - get { return "http://www.themoviedb.org/collection/{0}"; } + get { return "https://www.themoviedb.org/collection/{0}"; } } public bool Supports(IHasProviderIds item) @@ -97,7 +97,7 @@ namespace MediaBrowser.Providers.Movies public string UrlFormatString { - get { return "http://www.themoviedb.org/person/{0}"; } + get { return "https://www.themoviedb.org/person/{0}"; } } public bool Supports(IHasProviderIds item) @@ -120,7 +120,7 @@ namespace MediaBrowser.Providers.Movies public string UrlFormatString { - get { return "http://www.themoviedb.org/collection/{0}"; } + get { return "https://www.themoviedb.org/collection/{0}"; } } public bool Supports(IHasProviderIds item) diff --git a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs b/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs index 7fa7e0d15d..70c155ad5d 100644 --- a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs +++ b/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Movies /// <summary> /// The updates URL /// </summary> - private const string UpdatesUrl = "http://api.themoviedb.org/3/movie/changes?start_date={0}&api_key={1}&page={2}"; + private const string UpdatesUrl = "https://api.themoviedb.org/3/movie/changes?start_date={0}&api_key={1}&page={2}"; /// <summary> /// The _HTTP client @@ -176,9 +176,13 @@ namespace MediaBrowser.Providers.Movies var numComplete = 0; // Gather all movies into a lookup by tmdb id - var allMovies = _libraryManager.RootFolder - .GetRecursiveChildren(i => i is Movie && !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tmdb))) - .ToLookup(i => i.GetProviderId(MetadataProviders.Tmdb)); + var allMovies = _libraryManager.GetItemList(new Controller.Entities.InternalItemsQuery + { + IncludeItemTypes = new[] {typeof (Movie).Name}, + Recursive = true + + }).Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tmdb))) + .ToLookup(i => i.GetProviderId(MetadataProviders.Tmdb)); foreach (var id in list) { diff --git a/MediaBrowser.Providers/Movies/TmdbSettings.cs b/MediaBrowser.Providers/Movies/TmdbSettings.cs index 59e8f7cef6..12bb77afc9 100644 --- a/MediaBrowser.Providers/Movies/TmdbSettings.cs +++ b/MediaBrowser.Providers/Movies/TmdbSettings.cs @@ -5,7 +5,7 @@ namespace MediaBrowser.Providers.Movies internal class TmdbImageSettings { public List<string> backdrop_sizes { get; set; } - public string base_url { get; set; } + public string secure_base_url { get; set; } public List<string> poster_sizes { get; set; } public List<string> profile_sizes { get; set; } } diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs index 0c0339e12e..21e9b006bf 100644 --- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs +++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs @@ -27,10 +27,12 @@ namespace MediaBrowser.Providers.Music { if (!item.IsLocked) { - var itemFilter = item.GetItemFilter(); - var taggedItems = item.IsAccessedByName ? - LibraryManager.RootFolder.GetRecursiveChildren(i => !i.IsFolder && itemFilter(i)).ToList() : + item.GetTaggedItems(new Controller.Entities.InternalItemsQuery() + { + Recursive = true, + IsFolder = false + }) : item.GetRecursiveChildren(i => i is IHasArtist && !i.IsFolder).ToList(); if (!item.LockedFields.Contains(MetadataFields.Genres)) diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs index 444046208e..5b3bd87db0 100644 --- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs @@ -19,7 +19,7 @@ using MediaBrowser.Model.Serialization; namespace MediaBrowser.Providers.Music { - public class FanartAlbumProvider : IRemoteImageProvider, IHasChangeMonitor, IHasOrder + public class FanartAlbumProvider : IRemoteImageProvider, IHasItemChangeMonitor, IHasOrder { private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly IServerConfigurationManager _config; @@ -213,7 +213,7 @@ namespace MediaBrowser.Providers.Music }); } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { var options = FanartSeriesProvider.Current.GetFanartOptions(); if (!options.EnableAutomaticUpdates) @@ -235,7 +235,7 @@ namespace MediaBrowser.Providers.Music var fileInfo = _fileSystem.GetFileInfo(artistJsonPath); - return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date; + return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed; } } diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs index b715803ea9..37b51da5a3 100644 --- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs @@ -22,11 +22,11 @@ using MediaBrowser.Model.Serialization; namespace MediaBrowser.Providers.Music { - public class FanartArtistProvider : IRemoteImageProvider, IHasChangeMonitor, IHasOrder + public class FanartArtistProvider : IRemoteImageProvider, IHasItemChangeMonitor, IHasOrder { internal readonly SemaphoreSlim FanArtResourcePool = new SemaphoreSlim(3, 3); internal const string ApiKey = "5c6b04c68e904cfed1e6cbc9a9e683d4"; - private const string FanArtBaseUrl = "http://webservice.fanart.tv/v3.1/music/{1}?api_key={0}"; + private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3.1/music/{1}?api_key={0}"; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly IServerConfigurationManager _config; @@ -207,7 +207,7 @@ namespace MediaBrowser.Providers.Music }); } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { var options = FanartSeriesProvider.Current.GetFanartOptions(); if (!options.EnableAutomaticUpdates) @@ -224,7 +224,7 @@ namespace MediaBrowser.Providers.Music var fileInfo = _fileSystem.GetFileInfo(artistJsonPath); - return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date; + return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed; } return false; diff --git a/MediaBrowser.Providers/Music/FanArtUpdatesPostScanTask.cs b/MediaBrowser.Providers/Music/FanArtUpdatesPostScanTask.cs index 30507b8917..3b829af9eb 100644 --- a/MediaBrowser.Providers/Music/FanArtUpdatesPostScanTask.cs +++ b/MediaBrowser.Providers/Music/FanArtUpdatesPostScanTask.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Providers.Music { class FanartUpdatesPostScanTask : ILibraryPostScanTask { - private const string UpdatesUrl = "http://api.fanart.tv/webservice/newmusic/{0}/{1}/"; + private const string UpdatesUrl = "https://api.fanart.tv/webservice/newmusic/{0}/{1}/"; /// <summary> /// The _HTTP client diff --git a/MediaBrowser.Providers/Music/MovieDbMusicVideoProvider.cs b/MediaBrowser.Providers/Music/MovieDbMusicVideoProvider.cs index 55dcc99f58..d031b3d6b2 100644 --- a/MediaBrowser.Providers/Music/MovieDbMusicVideoProvider.cs +++ b/MediaBrowser.Providers/Music/MovieDbMusicVideoProvider.cs @@ -27,9 +27,9 @@ namespace MediaBrowser.Providers.Music get { return MovieDbProvider.Current.Name; } } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - return MovieDbProvider.Current.HasChanged(item, date); + return MovieDbProvider.Current.HasChanged(item); } public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken) diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs index e73a98b6f9..e41982ef67 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs @@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.Music if (!string.IsNullOrEmpty(releaseId)) { - url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=reid:{0}", releaseId); + url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=reid:{0}", releaseId); } else { @@ -50,7 +50,7 @@ namespace MediaBrowser.Providers.Music if (!string.IsNullOrWhiteSpace(artistMusicBrainzId)) { - url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND arid:{1}", + url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND arid:{1}", WebUtility.UrlEncode(searchInfo.Name), artistMusicBrainzId); } @@ -58,7 +58,7 @@ namespace MediaBrowser.Providers.Music { isNameSearch = true; - url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"", + url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"", WebUtility.UrlEncode(searchInfo.Name), WebUtility.UrlEncode(searchInfo.GetAlbumArtist())); } @@ -77,7 +77,7 @@ namespace MediaBrowser.Providers.Music private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc) { var ns = new XmlNamespaceManager(doc.NameTable); - ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#"); + ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#"); var list = new List<RemoteSearchResult>(); @@ -197,7 +197,7 @@ namespace MediaBrowser.Providers.Music private async Task<ReleaseResult> GetReleaseResult(string albumName, string artistId, CancellationToken cancellationToken) { - var url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND arid:{1}", + var url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND arid:{1}", WebUtility.UrlEncode(albumName), artistId); @@ -208,7 +208,7 @@ namespace MediaBrowser.Providers.Music private async Task<ReleaseResult> GetReleaseResultByArtistName(string albumName, string artistName, CancellationToken cancellationToken) { - var url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"", + var url = string.Format("https://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"", WebUtility.UrlEncode(albumName), WebUtility.UrlEncode(artistName)); @@ -220,7 +220,7 @@ namespace MediaBrowser.Providers.Music private ReleaseResult GetReleaseResult(XmlDocument doc) { var ns = new XmlNamespaceManager(doc.NameTable); - ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#"); + ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#"); var result = new ReleaseResult { @@ -258,12 +258,12 @@ namespace MediaBrowser.Providers.Music /// <returns>Task{System.String}.</returns> private async Task<string> GetReleaseGroupId(string releaseEntryId, CancellationToken cancellationToken) { - var url = string.Format("http://www.musicbrainz.org/ws/2/release-group/?query=reid:{0}", releaseEntryId); + var url = string.Format("https://www.musicbrainz.org/ws/2/release-group/?query=reid:{0}", releaseEntryId); var doc = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false); var ns = new XmlNamespaceManager(doc.NameTable); - ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#"); + ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#"); var node = doc.SelectSingleNode("//mb:release-group-list/mb:release-group/@id", ns); return node != null ? node.Value : null; diff --git a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs index c04f805495..2eb65f4e57 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs +++ b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs @@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Music if (!string.IsNullOrWhiteSpace(musicBrainzId)) { - var url = string.Format("http://www.musicbrainz.org/ws/2/artist/?query=arid:{0}", musicBrainzId); + var url = string.Format("https://www.musicbrainz.org/ws/2/artist/?query=arid:{0}", musicBrainzId); var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken) .ConfigureAwait(false); @@ -35,7 +35,7 @@ namespace MediaBrowser.Providers.Music // They seem to throw bad request failures on any term with a slash var nameToSearch = searchInfo.Name.Replace('/', ' '); - var url = String.Format("http://www.musicbrainz.org/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch)); + var url = String.Format("https://www.musicbrainz.org/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch)); var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false); @@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.Music if (HasDiacritics(searchInfo.Name)) { // Try again using the search with accent characters url - url = String.Format("http://www.musicbrainz.org/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch)); + url = String.Format("https://www.musicbrainz.org/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch)); doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false); @@ -62,12 +62,25 @@ namespace MediaBrowser.Providers.Music private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc) { - var ns = new XmlNamespaceManager(doc.NameTable); - ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#"); + //var ns = new XmlNamespaceManager(doc.NameTable); + //ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#"); var list = new List<RemoteSearchResult>(); - var nodes = doc.SelectNodes("//mb:artist-list/mb:artist", ns); + var docElem = doc.DocumentElement; + + if (docElem == null) + { + return list; + } + + var artistList = docElem.FirstChild; + if (artistList == null) + { + return list; + } + + var nodes = artistList.ChildNodes; if (nodes != null) { @@ -79,11 +92,13 @@ namespace MediaBrowser.Providers.Music string mbzId = node.Attributes["id"].Value; - var nameNode = node.SelectSingleNode("//mb:name", ns); - - if (nameNode != null) + foreach (var child in node.ChildNodes.Cast<XmlNode>()) { - name = nameNode.InnerText; + if (string.Equals(child.Name, "name", StringComparison.OrdinalIgnoreCase)) + { + name = node.InnerText; + break; + } } if (!string.IsNullOrWhiteSpace(mbzId) && !string.IsNullOrWhiteSpace(name)) diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index bcafdc6f62..814488df17 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Music public string UrlFormatString { - get { return "http://musicbrainz.org/release-group/{0}"; } + get { return "https://musicbrainz.org/release-group/{0}"; } } public bool Supports(IHasProviderIds item) @@ -41,7 +41,7 @@ namespace MediaBrowser.Providers.Music public string UrlFormatString { - get { return "http://musicbrainz.org/artist/{0}"; } + get { return "https://musicbrainz.org/artist/{0}"; } } public bool Supports(IHasProviderIds item) @@ -64,7 +64,7 @@ namespace MediaBrowser.Providers.Music public string UrlFormatString { - get { return "http://musicbrainz.org/release/{0}"; } + get { return "https://musicbrainz.org/release/{0}"; } } public bool Supports(IHasProviderIds item) @@ -87,7 +87,7 @@ namespace MediaBrowser.Providers.Music public string UrlFormatString { - get { return "http://musicbrainz.org/artist/{0}"; } + get { return "https://musicbrainz.org/artist/{0}"; } } public bool Supports(IHasProviderIds item) @@ -110,7 +110,7 @@ namespace MediaBrowser.Providers.Music public string UrlFormatString { - get { return "http://musicbrainz.org/artist/{0}"; } + get { return "https://musicbrainz.org/artist/{0}"; } } public bool Supports(IHasProviderIds item) @@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.Music public string UrlFormatString { - get { return "http://musicbrainz.org/track/{0}"; } + get { return "https://musicbrainz.org/track/{0}"; } } public bool Supports(IHasProviderIds item) diff --git a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs index ae563b287e..a1e038374c 100644 --- a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs @@ -40,7 +40,7 @@ namespace MediaBrowser.Providers.Omdb list.Add(new RemoteImageInfo { ProviderName = Name, - Url = string.Format("http://img.omdbapi.com/?i={0}&apikey=82e83907", imdbId) + Url = string.Format("https://img.omdbapi.com/?i={0}&apikey=82e83907", imdbId) }); } diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index 8acaf30d5b..a0d60c1669 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Providers.Omdb var imdbId = searchInfo.GetProviderId(MetadataProviders.Imdb); - var url = "http://www.omdbapi.com/?plot=full&r=json"; + var url = "https://www.omdbapi.com/?plot=full&r=json"; if (type == "episode" && episodeSearchInfo != null) { episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out imdbId); diff --git a/MediaBrowser.Providers/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Omdb/OmdbProvider.cs index b68f93cf6b..44e250350c 100644 --- a/MediaBrowser.Providers/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbProvider.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Omdb var imdbParam = imdbId.StartsWith("tt", StringComparison.OrdinalIgnoreCase) ? imdbId : "tt" + imdbId; - var url = string.Format("http://www.omdbapi.com/?i={0}&tomatoes=true", imdbParam); + var url = string.Format("https://www.omdbapi.com/?i={0}&tomatoes=true", imdbParam); using (var stream = await _httpClient.Get(new HttpRequestOptions { diff --git a/MediaBrowser.Providers/People/MovieDbPersonImageProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonImageProvider.cs index 2ac9fdfa0a..93eee69ae7 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonImageProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonImageProvider.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.Providers.People var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; return GetImages(images, item.GetPreferredMetadataLanguage(), tmdbImageUrl); } diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs index 2b37d0462d..bb17b83ec8 100644 --- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs +++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs @@ -59,7 +59,7 @@ namespace MediaBrowser.Providers.People var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; if (!string.IsNullOrEmpty(tmdbId)) { @@ -97,7 +97,7 @@ namespace MediaBrowser.Providers.People var requestCount = _requestCount; - if (requestCount >= 30) + if (requestCount >= 40) { //_logger.Debug("Throttling Tmdb people"); @@ -109,7 +109,7 @@ namespace MediaBrowser.Providers.People } } - var url = string.Format(@"http://api.themoviedb.org/3/search/person?api_key={1}&query={0}", WebUtility.UrlEncode(searchInfo.Name), MovieDbProvider.ApiKey); + var url = string.Format(@"https://api.themoviedb.org/3/search/person?api_key={1}&query={0}", WebUtility.UrlEncode(searchInfo.Name), MovieDbProvider.ApiKey); using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions { @@ -234,7 +234,7 @@ namespace MediaBrowser.Providers.People return; } - var url = string.Format(@"http://api.themoviedb.org/3/person/{1}?api_key={0}&append_to_response=credits,images,external_ids", MovieDbProvider.ApiKey, id); + var url = string.Format(@"https://api.themoviedb.org/3/person/{1}?api_key={0}&append_to_response=credits,images,external_ids", MovieDbProvider.ApiKey, id); using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions { diff --git a/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs index e683907c46..673663d7f1 100644 --- a/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs @@ -21,7 +21,7 @@ using CommonIO; namespace MediaBrowser.Providers.TV { - public class FanArtSeasonProvider : IRemoteImageProvider, IHasOrder, IHasChangeMonitor + public class FanArtSeasonProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor { private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly IServerConfigurationManager _config; @@ -225,7 +225,7 @@ namespace MediaBrowser.Providers.TV }); } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { var options = FanartSeriesProvider.Current.GetFanartOptions(); if (!options.EnableAutomaticUpdates) @@ -250,7 +250,7 @@ namespace MediaBrowser.Providers.TV var fileInfo = _fileSystem.GetFileInfo(imagesFilePath); - return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date; + return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed; } return false; diff --git a/MediaBrowser.Providers/TV/FanArt/FanArtTvUpdatesPostScanTask.cs b/MediaBrowser.Providers/TV/FanArt/FanArtTvUpdatesPostScanTask.cs index 049ffd7d8f..37e76531b1 100644 --- a/MediaBrowser.Providers/TV/FanArt/FanArtTvUpdatesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/FanArt/FanArtTvUpdatesPostScanTask.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Providers.TV { class FanArtTvUpdatesPostScanTask : ILibraryPostScanTask { - private const string UpdatesUrl = "http://webservice.fanart.tv/v3/tv/latest?api_key={0}&date={1}"; + private const string UpdatesUrl = "https://webservice.fanart.tv/v3/tv/latest?api_key={0}&date={1}"; /// <summary> /// The _HTTP client diff --git a/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs b/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs index 517951cb8c..3c831dbbca 100644 --- a/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs @@ -23,7 +23,7 @@ using CommonIO; namespace MediaBrowser.Providers.TV { - public class FanartSeriesProvider : IRemoteImageProvider, IHasOrder, IHasChangeMonitor + public class FanartSeriesProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor { private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly IServerConfigurationManager _config; @@ -31,7 +31,7 @@ namespace MediaBrowser.Providers.TV private readonly IFileSystem _fileSystem; private readonly IJsonSerializer _json; - private const string FanArtBaseUrl = "http://webservice.fanart.tv/v3/tv/{1}?api_key={0}"; + private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/tv/{1}?api_key={0}"; // &client_key=52c813aa7b8c8b3bb87f4797532a2f8c internal static FanartSeriesProvider Current { get; private set; } @@ -341,7 +341,7 @@ namespace MediaBrowser.Providers.TV } } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { var options = GetFanartOptions(); if (!options.EnableAutomaticUpdates) @@ -358,7 +358,7 @@ namespace MediaBrowser.Providers.TV var fileInfo = _fileSystem.GetFileInfo(imagesFilePath); - return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date; + return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed; } return false; diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index efdf8ce5d0..e79ad2dfbd 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -27,6 +27,8 @@ namespace MediaBrowser.Providers.TV private readonly IFileSystem _fileSystem; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + private static readonly SemaphoreSlim _resourceLock = new SemaphoreSlim(1, 1); + public static bool IsRunning = false; public MissingEpisodeProvider(ILogger logger, IServerConfigurationManager config, ILibraryManager libraryManager, ILocalizationManager localization, IFileSystem fileSystem) { @@ -37,13 +39,16 @@ namespace MediaBrowser.Providers.TV _fileSystem = fileSystem; } - public async Task Run(IEnumerable<IGrouping<string, Series>> series, CancellationToken cancellationToken) + public async Task Run(List<IGrouping<string, Series>> series, bool addNewItems, CancellationToken cancellationToken) { + await _resourceLock.WaitAsync(cancellationToken).ConfigureAwait(false); + IsRunning = true; + foreach (var seriesGroup in series) { try { - await Run(seriesGroup, cancellationToken).ConfigureAwait(false); + await Run(seriesGroup, addNewItems, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -58,9 +63,12 @@ namespace MediaBrowser.Providers.TV _logger.ErrorException("Error in missing episode provider for series id {0}", ex, seriesGroup.Key); } } + + IsRunning = false; + _resourceLock.Release(); } - private async Task Run(IGrouping<string, Series> group, CancellationToken cancellationToken) + private async Task Run(IGrouping<string, Series> group, bool addNewItems, CancellationToken cancellationToken) { var tvdbId = group.Key; @@ -110,7 +118,7 @@ namespace MediaBrowser.Providers.TV var hasNewEpisodes = false; - if (_config.Configuration.EnableInternetProviders) + if (_config.Configuration.EnableInternetProviders && addNewItems) { var seriesConfig = _config.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, typeof(Series).Name, StringComparison.OrdinalIgnoreCase)); @@ -427,7 +435,7 @@ namespace MediaBrowser.Providers.TV await season.AddChild(episode, cancellationToken).ConfigureAwait(false); - await episode.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) + await episode.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) { }, cancellationToken).ConfigureAwait(false); } diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index 1af1162897..292923d824 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -7,6 +7,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using CommonIO; @@ -31,6 +32,13 @@ namespace MediaBrowser.Providers.TV } } + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) + { + var episodes = item.GetEpisodes().ToList(); + updateType |= SavePremiereDate(item, episodes); + updateType |= SaveIsMissing(item, episodes); + } + return updateType; } @@ -38,5 +46,38 @@ namespace MediaBrowser.Providers.TV { ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings); } + + private ItemUpdateType SavePremiereDate(Season item, List<Episode> episodes) + { + var dates = episodes.Where(i => i.PremiereDate.HasValue).Select(i => i.PremiereDate.Value).ToList(); + + DateTime? premiereDate = null; + + if (dates.Count > 0) + { + premiereDate = dates.Min(); + } + + if (item.PremiereDate != premiereDate) + { + item.PremiereDate = premiereDate; + return ItemUpdateType.MetadataEdit; + } + + return ItemUpdateType.None; + } + + private ItemUpdateType SaveIsMissing(Season item, List<Episode> episodes) + { + var isMissing = item.LocationType == LocationType.Virtual && episodes.All(i => i.IsMissingEpisode); + + if (item.IsMissingSeason != isMissing) + { + item.IsMissingSeason = isMissing; + return ItemUpdateType.MetadataEdit; + } + + return ItemUpdateType.None; + } } } diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index 5428e6c920..3c0a5fc73b 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -11,6 +11,10 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using CommonIO; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Tasks; namespace MediaBrowser.Providers.TV { @@ -46,14 +50,18 @@ namespace MediaBrowser.Providers.TV private async Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken) { - var seriesList = _libraryManager.RootFolder - .GetRecursiveChildren(i => i is Series) - .Cast<Series>() - .ToList(); + var seriesList = _libraryManager.GetItemList(new InternalItemsQuery() + { + IncludeItemTypes = new[] { typeof(Series).Name }, + Recursive = true, + GroupByPresentationUniqueKey = false + + }).Cast<Series>().ToList(); var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList(); - await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem).Run(seriesGroups, cancellationToken).ConfigureAwait(false); + await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem) + .Run(seriesGroups, true, cancellationToken).ConfigureAwait(false); var numComplete = 0; @@ -82,7 +90,7 @@ namespace MediaBrowser.Providers.TV } } - private IEnumerable<IGrouping<string, Series>> FindSeriesGroups(List<Series> seriesList) + internal static IEnumerable<IGrouping<string, Series>> FindSeriesGroups(List<Series> seriesList) { var links = seriesList.ToDictionary(s => s, s => seriesList.Where(c => c != s && ShareProviderId(s, c)).ToList()); @@ -102,7 +110,7 @@ namespace MediaBrowser.Providers.TV } } - private void FindAllLinked(Series series, HashSet<Series> visited, IDictionary<Series, List<Series>> linksMap, List<Series> results) + private static void FindAllLinked(Series series, HashSet<Series> visited, IDictionary<Series, List<Series>> linksMap, List<Series> results) { results.Add(series); visited.Add(series); @@ -118,7 +126,7 @@ namespace MediaBrowser.Providers.TV } } - private bool ShareProviderId(Series a, Series b) + private static bool ShareProviderId(Series a, Series b) { return a.ProviderIds.Any(id => { @@ -137,4 +145,109 @@ namespace MediaBrowser.Providers.TV } } + public class CleanMissingEpisodesEntryPoint : IServerEntryPoint + { + private readonly ILibraryManager _libraryManager; + private readonly IServerConfigurationManager _config; + private readonly ILogger _logger; + private readonly ILocalizationManager _localization; + private readonly IFileSystem _fileSystem; + private readonly object _libraryChangedSyncLock = new object(); + private const int LibraryUpdateDuration = 180000; + private readonly ITaskManager _taskManager; + + public CleanMissingEpisodesEntryPoint(ILibraryManager libraryManager, IServerConfigurationManager config, ILogger logger, ILocalizationManager localization, IFileSystem fileSystem, ITaskManager taskManager) + { + _libraryManager = libraryManager; + _config = config; + _logger = logger; + _localization = localization; + _fileSystem = fileSystem; + _taskManager = taskManager; + } + + private Timer LibraryUpdateTimer { get; set; } + + public void Run() + { + _libraryManager.ItemAdded += _libraryManager_ItemAdded; + } + + private void _libraryManager_ItemAdded(object sender, ItemChangeEventArgs e) + { + if (!FilterItem(e.Item)) + { + return; + } + + lock (_libraryChangedSyncLock) + { + if (LibraryUpdateTimer == null) + { + LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, Timeout.Infinite); + } + else + { + LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); + } + } + } + + private async void LibraryUpdateTimerCallback(object state) + { + if (MissingEpisodeProvider.IsRunning) + { + return; + } + + if (_libraryManager.IsScanRunning) + { + return ; + } + + var seriesList = _libraryManager.GetItemList(new InternalItemsQuery() + { + IncludeItemTypes = new[] { typeof(Series).Name }, + Recursive = true, + GroupByPresentationUniqueKey = false + + }).Cast<Series>().ToList(); + + var seriesGroups = SeriesPostScanTask.FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList(); + + await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem) + .Run(seriesGroups, false, CancellationToken.None).ConfigureAwait(false); + } + + private bool FilterItem(BaseItem item) + { + return item is Episode && item.LocationType != LocationType.Virtual; + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() + { + Dispose(true); + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources. + /// </summary> + /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + if (LibraryUpdateTimer != null) + { + LibraryUpdateTimer.Dispose(); + LibraryUpdateTimer = null; + } + + _libraryManager.ItemAdded -= _libraryManager_ItemAdded; + } + } + } } diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeImageProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeImageProvider.cs index 9d16849482..719779674b 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeImageProvider.cs @@ -62,7 +62,7 @@ namespace MediaBrowser.Providers.TV var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; list.AddRange(GetPosters(response.images).Select(i => new RemoteImageInfo { diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs index d22827c25e..36800202fd 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbProviderBase.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Providers.TV { public abstract class MovieDbProviderBase { - private const string EpisodeUrlPattern = @"http://api.themoviedb.org/3/tv/{0}/season/{1}/episode/{2}?api_key={3}&append_to_response=images,external_ids,credits,videos"; + private const string EpisodeUrlPattern = @"https://api.themoviedb.org/3/tv/{0}/season/{1}/episode/{2}?api_key={3}&append_to_response=images,external_ids,credits,videos"; private readonly IHttpClient _httpClient; private readonly IServerConfigurationManager _configurationManager; private readonly IJsonSerializer _jsonSerializer; diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs index fe0bda8288..2e51393e39 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeasonProvider.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.TV { public class MovieDbSeasonProvider : IRemoteMetadataProvider<Season, SeasonInfo> { - private const string GetTvInfo3 = @"http://api.themoviedb.org/3/tv/{0}/season/{1}?api_key={2}&append_to_response=images,keywords,external_ids,credits,videos"; + private const string GetTvInfo3 = @"https://api.themoviedb.org/3/tv/{0}/season/{1}?api_key={2}&append_to_response=images,keywords,external_ids,credits,videos"; private readonly IHttpClient _httpClient; private readonly IServerConfigurationManager _configurationManager; private readonly IJsonSerializer _jsonSerializer; diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesImageProvider.cs index f7c19988c3..65ac12adf0 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesImageProvider.cs @@ -16,7 +16,7 @@ using System.Threading.Tasks; namespace MediaBrowser.Providers.TV { - public class MovieDbSeriesImageProvider : IRemoteImageProvider, IHasOrder, IHasChangeMonitor + public class MovieDbSeriesImageProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor { private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; @@ -64,7 +64,7 @@ namespace MediaBrowser.Providers.TV var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; list.AddRange(GetPosters(results).Select(i => new RemoteImageInfo { @@ -196,9 +196,9 @@ namespace MediaBrowser.Providers.TV }); } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - return MovieDbSeriesProvider.Current.HasChanged(item, date); + return MovieDbSeriesProvider.Current.HasChanged(item); } } } diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs index 05b1ebc80c..7d0f499550 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.TV { public class MovieDbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder { - private const string GetTvInfo3 = @"http://api.themoviedb.org/3/tv/{0}?api_key={1}&append_to_response=credits,images,keywords,external_ids,videos"; + private const string GetTvInfo3 = @"https://api.themoviedb.org/3/tv/{0}?api_key={1}&append_to_response=credits,images,keywords,external_ids,videos,content_ratings"; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); internal static MovieDbSeriesProvider Current { get; private set; } @@ -69,7 +69,7 @@ namespace MediaBrowser.Providers.TV var obj = _jsonSerializer.DeserializeFromFile<RootObject>(dataFilePath); var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; var remoteResult = new RemoteSearchResult { @@ -168,7 +168,7 @@ namespace MediaBrowser.Providers.TV { cancellationToken.ThrowIfCancellationRequested(); - result.Item = await FetchMovieData(tmdbId, info.MetadataLanguage, cancellationToken).ConfigureAwait(false); + result.Item = await FetchMovieData(tmdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); result.HasMetadata = result.Item != null; } @@ -176,7 +176,7 @@ namespace MediaBrowser.Providers.TV return result; } - private async Task<Series> FetchMovieData(string tmdbId, string language, CancellationToken cancellationToken) + private async Task<Series> FetchMovieData(string tmdbId, string language, string preferredCountryCode, CancellationToken cancellationToken) { string dataFilePath = null; RootObject seriesInfo = null; @@ -201,12 +201,12 @@ namespace MediaBrowser.Providers.TV var item = new Series(); - ProcessMainInfo(item, seriesInfo); + ProcessMainInfo(item, seriesInfo, preferredCountryCode); return item; } - private void ProcessMainInfo(Series series, RootObject seriesInfo) + private void ProcessMainInfo(Series series, RootObject seriesInfo, string preferredCountryCode) { series.Name = seriesInfo.name; series.SetProviderId(MetadataProviders.Tmdb, seriesInfo.id.ToString(_usCulture)); @@ -265,6 +265,26 @@ namespace MediaBrowser.Providers.TV series.SetProviderId(MetadataProviders.Tvdb, ids.tvdb_id.ToString(_usCulture)); } } + + var contentRatings = (seriesInfo.content_ratings ?? new ContentRatings()).results ?? new List<ContentRating>(); + + var ourRelease = contentRatings.FirstOrDefault(c => string.Equals(c.iso_3166_1, preferredCountryCode, StringComparison.OrdinalIgnoreCase)); + var usRelease = contentRatings.FirstOrDefault(c => string.Equals(c.iso_3166_1, "US", StringComparison.OrdinalIgnoreCase)); + var minimumRelease = contentRatings.FirstOrDefault(); + + if (ourRelease != null) + { + series.OfficialRating = ourRelease.rating; + } + else if (usRelease != null) + { + series.OfficialRating = usRelease.rating; + } + else if (minimumRelease != null) + { + series.OfficialRating = minimumRelease.rating; + } + } internal static string GetSeriesDataPath(IApplicationPaths appPaths, string tmdbId) @@ -394,7 +414,7 @@ namespace MediaBrowser.Providers.TV return Path.Combine(path, filename); } - public bool HasChanged(IHasMetadata item, DateTime date) + public bool HasChanged(IHasMetadata item) { if (!MovieDbProvider.Current.GetTheMovieDbOptions().EnableAutomaticUpdates) { @@ -410,7 +430,7 @@ namespace MediaBrowser.Providers.TV var fileInfo = _fileSystem.GetFileInfo(dataFilePath); - return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > date; + return !fileInfo.Exists || _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed; } return false; @@ -418,7 +438,7 @@ namespace MediaBrowser.Providers.TV private async Task<RemoteSearchResult> FindByExternalId(string id, string externalSource, CancellationToken cancellationToken) { - var url = string.Format("http://api.themoviedb.org/3/tv/find/{0}?api_key={1}&external_source={2}", + var url = string.Format("https://api.themoviedb.org/3/tv/find/{0}?api_key={1}&external_source={2}", id, MovieDbProvider.ApiKey, externalSource); @@ -440,7 +460,7 @@ namespace MediaBrowser.Providers.TV if (tv != null) { var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false); - var tmdbImageUrl = tmdbSettings.images.base_url + "original"; + var tmdbImageUrl = tmdbSettings.images.secure_base_url + "original"; var remoteResult = new RemoteSearchResult { @@ -481,6 +501,7 @@ namespace MediaBrowser.Providers.TV public class Season { public string air_date { get; set; } + public int episode_count { get; set; } public int id { get; set; } public string poster_path { get; set; } public int season_number { get; set; } @@ -528,7 +549,6 @@ namespace MediaBrowser.Providers.TV public double aspect_ratio { get; set; } public string file_path { get; set; } public int height { get; set; } - public string id { get; set; } public string iso_639_1 { get; set; } public double vote_average { get; set; } public int vote_count { get; set; } @@ -560,6 +580,17 @@ namespace MediaBrowser.Providers.TV public List<object> results { get; set; } } + public class ContentRating + { + public string iso_3166_1 { get; set; } + public string rating { get; set; } + } + + public class ContentRatings + { + public List<ContentRating> results { get; set; } + } + public class RootObject { public string backdrop_path { get; set; } @@ -590,6 +621,7 @@ namespace MediaBrowser.Providers.TV public Keywords keywords { get; set; } public ExternalIds external_ids { get; set; } public Videos videos { get; set; } + public ContentRatings content_ratings { get; set; } } public int Order diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs index 49d41e06cc..7a0b2c90c6 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeImageProvider.cs @@ -17,7 +17,7 @@ using CommonIO; namespace MediaBrowser.Providers.TV { - public class TvdbEpisodeImageProvider : IRemoteImageProvider, IHasChangeMonitor + public class TvdbEpisodeImageProvider : IRemoteImageProvider, IHasItemChangeMonitor { private readonly IServerConfigurationManager _config; private readonly CultureInfo _usCulture = new CultureInfo("en-US"); @@ -174,21 +174,18 @@ namespace MediaBrowser.Providers.TV }); } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - var episode = (Episode)item; - - if (!episode.IsVirtualUnaired) + // For non-unaired items, only enable if configured + if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates) { - // For non-unaired items, only enable if configured - if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates) - { - return false; - } + return false; } if (!item.HasImage(ImageType.Primary)) { + var episode = (Episode)item; + var series = episode.Series; if (series != null && TvdbSeriesProvider.IsValidSeries(series.ProviderIds)) @@ -196,7 +193,7 @@ namespace MediaBrowser.Providers.TV // Process images var seriesXmlPath = TvdbSeriesProvider.Current.GetSeriesXmlPath(series.ProviderIds, series.GetPreferredMetadataLanguage()); - return _fileSystem.GetLastWriteTimeUtc(seriesXmlPath) > date; + return _fileSystem.GetLastWriteTimeUtc(seriesXmlPath) > item.DateLastRefreshed; } } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs index 291214fcd3..509b22ee6b 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.TV /// <summary> /// Class RemoteEpisodeProvider /// </summary> - class TvdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IItemIdentityProvider<EpisodeInfo>, IHasChangeMonitor + class TvdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IItemIdentityProvider<EpisodeInfo>, IHasItemChangeMonitor { private static readonly string FullIdKey = MetadataProviders.Tvdb + "-Full"; @@ -144,10 +144,9 @@ namespace MediaBrowser.Providers.TV return result; } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - // Only enable for virtual items - if (item.LocationType != LocationType.Virtual) + if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates) { return false; } @@ -160,7 +159,7 @@ namespace MediaBrowser.Providers.TV // Process images var seriesXmlPath = TvdbSeriesProvider.Current.GetSeriesXmlPath(series.ProviderIds, series.GetPreferredMetadataLanguage()); - return _fileSystem.GetLastWriteTimeUtc(seriesXmlPath) > date; + return _fileSystem.GetLastWriteTimeUtc(seriesXmlPath) > item.DateLastRefreshed; } return false; @@ -750,7 +749,7 @@ namespace MediaBrowser.Providers.TV private void AddPeople<T>(MetadataResult<T> result, string val, string personType) { // Sometimes tvdb actors have leading spaces - foreach (var person in val.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries) + foreach (var person in val.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Where(i => !string.IsNullOrWhiteSpace(i)) .Select(str => new PersonInfo { Type = personType, Name = str.Trim() })) { diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs index 1c83d73fb3..215e0640f2 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs @@ -15,6 +15,7 @@ using System.Threading; using System.Threading.Tasks; using System.Xml; using CommonIO; +using MediaBrowser.Controller.Entities; namespace MediaBrowser.Providers.TV { @@ -26,12 +27,12 @@ namespace MediaBrowser.Providers.TV /// <summary> /// The server time URL /// </summary> - private const string ServerTimeUrl = "http://thetvdb.com/api/Updates.php?type=none"; + private const string ServerTimeUrl = "https://thetvdb.com/api/Updates.php?type=none"; /// <summary> /// The updates URL /// </summary> - private const string UpdatesUrl = "http://thetvdb.com/api/Updates.php?type=all&time={0}"; + private const string UpdatesUrl = "https://thetvdb.com/api/Updates.php?type=all&time={0}"; /// <summary> /// The _HTTP client @@ -89,7 +90,7 @@ namespace MediaBrowser.Providers.TV var path = TvdbSeriesProvider.GetSeriesDataPath(_config.CommonApplicationPaths); - _fileSystem.CreateDirectory(path); + _fileSystem.CreateDirectory(path); var timestampFile = Path.Combine(path, "time.txt"); @@ -102,7 +103,7 @@ namespace MediaBrowser.Providers.TV } // Find out the last time we queried tvdb for updates - var lastUpdateTime = timestampFileInfo.Exists ? _fileSystem.ReadAllText(timestampFile, Encoding.UTF8) : string.Empty; + var lastUpdateTime = timestampFileInfo.Exists ? _fileSystem.ReadAllText(timestampFile, Encoding.UTF8) : string.Empty; string newUpdateTime; @@ -110,15 +111,21 @@ namespace MediaBrowser.Providers.TV .Select(Path.GetFileName) .ToList(); - var seriesIdsInLibrary = _libraryManager.RootFolder - .GetRecursiveChildren(i => i is Series && !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb))) - .Cast<Series>() + var seriesList = _libraryManager.GetItemList(new InternalItemsQuery() + { + IncludeItemTypes = new[] { typeof(Series).Name }, + Recursive = true, + GroupByPresentationUniqueKey = false + }).Cast<Series>(); + + var seriesIdsInLibrary = seriesList + .Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb))) .Select(i => i.GetProviderId(MetadataProviders.Tvdb)) .ToList(); var missingSeries = seriesIdsInLibrary.Except(existingDirectories, StringComparer.OrdinalIgnoreCase) .ToList(); - + // If this is our first time, update all series if (string.IsNullOrEmpty(lastUpdateTime)) { @@ -157,7 +164,7 @@ namespace MediaBrowser.Providers.TV await UpdateSeries(listToUpdate, path, nullableUpdateValue, progress, cancellationToken).ConfigureAwait(false); } - _fileSystem.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8); + _fileSystem.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8); progress.Report(100); } @@ -300,10 +307,17 @@ namespace MediaBrowser.Providers.TV var list = seriesIds.ToList(); var numComplete = 0; + var seriesList = _libraryManager.GetItemList(new InternalItemsQuery() + { + IncludeItemTypes = new[] { typeof(Series).Name }, + Recursive = true, + GroupByPresentationUniqueKey = false + + }).Cast<Series>(); + // Gather all series into a lookup by tvdb id - var allSeries = _libraryManager.RootFolder - .GetRecursiveChildren(i => i is Series && !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb))) - .Cast<Series>() + var allSeries = seriesList + .Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb))) .ToLookup(i => i.GetProviderId(MetadataProviders.Tvdb)); foreach (var seriesId in list) @@ -323,7 +337,7 @@ namespace MediaBrowser.Providers.TV catch (HttpException ex) { _logger.ErrorException("Error updating tvdb series id {0}, language {1}", ex, seriesId, language); - + // Already logged at lower levels, but don't fail the whole operation, unless timed out // We have to fail this to make it run again otherwise new episode data could potentially be missing if (ex.IsTimedOut) @@ -357,7 +371,7 @@ namespace MediaBrowser.Providers.TV seriesDataPath = Path.Combine(seriesDataPath, id); - _fileSystem.CreateDirectory(seriesDataPath); + _fileSystem.CreateDirectory(seriesDataPath); return TvdbSeriesProvider.Current.DownloadSeriesZip(id, MetadataProviders.Tvdb.ToString(), seriesDataPath, lastTvDbUpdateTime, preferredMetadataLanguage, cancellationToken); } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs index 5e7ce9f7ed..52d12e501b 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs @@ -20,7 +20,7 @@ using CommonIO; namespace MediaBrowser.Providers.TV { - public class TvdbSeasonImageProvider : IRemoteImageProvider, IHasOrder, IHasChangeMonitor + public class TvdbSeasonImageProvider : IRemoteImageProvider, IHasOrder, IHasItemChangeMonitor { private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); @@ -363,15 +363,11 @@ namespace MediaBrowser.Providers.TV }); } - public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date) + public bool HasChanged(IHasMetadata item, IDirectoryService directoryService) { - if (item.LocationType != LocationType.Virtual) + if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates) { - // For non-virtual items, only enable if configured - if (!TvdbSeriesProvider.Current.GetTvDbOptions().EnableAutomaticUpdates) - { - return false; - } + return false; } var season = (Season)item; @@ -384,7 +380,7 @@ namespace MediaBrowser.Providers.TV var fileInfo = _fileSystem.GetFileInfo(imagesXmlPath); - return fileInfo.Exists && _fileSystem.GetLastWriteTimeUtc(fileInfo) > date; + return fileInfo.Exists && _fileSystem.GetLastWriteTimeUtc(fileInfo) > item.DateLastRefreshed; } return false; diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs index f66e9254ef..ee1505b46c 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs @@ -53,9 +53,9 @@ namespace MediaBrowser.Providers.TV Current = this; } - private const string SeriesSearchUrl = "http://www.thetvdb.com/api/GetSeries.php?seriesname={0}&language={1}"; - private const string SeriesGetZip = "http://www.thetvdb.com/api/{0}/series/{1}/all/{2}.zip"; - private const string GetSeriesByImdbId = "http://www.thetvdb.com/api/GetSeriesByRemoteID.php?imdbid={0}&language={1}"; + private const string SeriesSearchUrl = "https://www.thetvdb.com/api/GetSeries.php?seriesname={0}&language={1}"; + private const string SeriesGetZip = "https://www.thetvdb.com/api/{0}/series/{1}/all/{2}.zip"; + private const string GetSeriesByImdbId = "https://www.thetvdb.com/api/GetSeriesByRemoteID.php?imdbid={0}&language={1}"; private string NormalizeLanguage(string language) { @@ -1465,4 +1465,4 @@ namespace MediaBrowser.Providers.TV }; } } -}
\ No newline at end of file +} diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs index 82baae2507..f5a26ba0ae 100644 --- a/MediaBrowser.Providers/TV/TvExternalIds.cs +++ b/MediaBrowser.Providers/TV/TvExternalIds.cs @@ -42,7 +42,7 @@ namespace MediaBrowser.Providers.TV public string UrlFormatString { - get { return "http://thetvdb.com/index.php?tab=series&id={0}"; } + get { return "https://thetvdb.com/index.php?tab=series&id={0}"; } } public bool Supports(IHasProviderIds item) |
