aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Providers
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Providers')
-rw-r--r--MediaBrowser.Providers/Chapters/ChapterManager.cs220
-rw-r--r--MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs4
-rw-r--r--MediaBrowser.Providers/Genres/GenreImageProvider.cs6
-rw-r--r--MediaBrowser.Providers/Manager/ImageSaver.cs30
-rw-r--r--MediaBrowser.Providers/Manager/ItemImageProvider.cs30
-rw-r--r--MediaBrowser.Providers/Manager/MetadataService.cs88
-rw-r--r--MediaBrowser.Providers/Manager/ProviderManager.cs21
-rw-r--r--MediaBrowser.Providers/Manager/ProviderUtils.cs30
-rw-r--r--MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs7
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs73
-rw-r--r--MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs2
-rw-r--r--MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs90
-rw-r--r--MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs7
-rw-r--r--MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs30
-rw-r--r--MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs36
-rw-r--r--MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs60
-rw-r--r--MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs11
-rw-r--r--MediaBrowser.Providers/Omdb/OmdbItemProvider.cs8
-rw-r--r--MediaBrowser.Providers/People/MovieDbPersonProvider.cs6
-rw-r--r--MediaBrowser.Providers/People/PersonMetadataService.cs8
-rw-r--r--MediaBrowser.Providers/Studios/StudiosImageProvider.cs4
-rw-r--r--MediaBrowser.Providers/TV/MissingEpisodeProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs3
-rw-r--r--MediaBrowser.Providers/TV/SeriesPostScanTask.cs31
-rw-r--r--MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs7
-rw-r--r--MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs25
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs12
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs17
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs29
30 files changed, 368 insertions, 531 deletions
diff --git a/MediaBrowser.Providers/Chapters/ChapterManager.cs b/MediaBrowser.Providers/Chapters/ChapterManager.cs
index 88811c850..87aaafb39 100644
--- a/MediaBrowser.Providers/Chapters/ChapterManager.cs
+++ b/MediaBrowser.Providers/Chapters/ChapterManager.cs
@@ -8,7 +8,6 @@ using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Chapters;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -22,7 +21,6 @@ namespace MediaBrowser.Providers.Chapters
{
public class ChapterManager : IChapterManager
{
- private IChapterProvider[] _providers;
private readonly ILibraryManager _libraryManager;
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
@@ -36,224 +34,6 @@ namespace MediaBrowser.Providers.Chapters
_itemRepo = itemRepo;
}
- public void AddParts(IEnumerable<IChapterProvider> chapterProviders)
- {
- _providers = chapterProviders.ToArray();
- }
-
- public Task<IEnumerable<RemoteChapterResult>> Search(Video video, CancellationToken cancellationToken)
- {
- VideoContentType mediaType;
-
- if (video is Episode)
- {
- mediaType = VideoContentType.Episode;
- }
- else if (video is Movie)
- {
- mediaType = VideoContentType.Movie;
- }
- else
- {
- // These are the only supported types
- return Task.FromResult<IEnumerable<RemoteChapterResult>>(new List<RemoteChapterResult>());
- }
-
- var request = new ChapterSearchRequest
- {
- ContentType = mediaType,
- IndexNumber = video.IndexNumber,
- Language = video.GetPreferredMetadataLanguage(),
- MediaPath = video.Path,
- Name = video.Name,
- ParentIndexNumber = video.ParentIndexNumber,
- ProductionYear = video.ProductionYear,
- ProviderIds = video.ProviderIds,
- RuntimeTicks = video.RunTimeTicks,
- SearchAllProviders = false
- };
-
- var episode = video as Episode;
-
- if (episode != null)
- {
- request.IndexNumberEnd = episode.IndexNumberEnd;
- request.SeriesName = episode.SeriesName;
- }
-
- return Search(request, cancellationToken);
- }
-
- public async Task<IEnumerable<RemoteChapterResult>> Search(ChapterSearchRequest request, CancellationToken cancellationToken)
- {
- var contentType = request.ContentType;
- var providers = GetInternalProviders(false)
- .Where(i => i.SupportedMediaTypes.Contains(contentType))
- .ToList();
-
- // If not searching all, search one at a time until something is found
- if (!request.SearchAllProviders)
- {
- foreach (var provider in providers)
- {
- try
- {
- var currentResults = await Search(request, provider, cancellationToken).ConfigureAwait(false);
-
- if (currentResults.Count > 0)
- {
- return currentResults;
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error downloading subtitles from {0}", ex, provider.Name);
- }
- }
- return new List<RemoteChapterResult>();
- }
-
- var tasks = providers.Select(async i =>
- {
- try
- {
- return await Search(request, i, cancellationToken).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error downloading subtitles from {0}", ex, i.Name);
- return new List<RemoteChapterResult>();
- }
- });
-
- var results = await Task.WhenAll(tasks).ConfigureAwait(false);
-
- return results.SelectMany(i => i);
- }
-
- private async Task<List<RemoteChapterResult>> Search(ChapterSearchRequest request,
- IChapterProvider provider,
- CancellationToken cancellationToken)
- {
- var searchResults = await provider.Search(request, cancellationToken).ConfigureAwait(false);
-
- var list = searchResults.ToList();
-
- foreach (var result in list)
- {
- result.Id = GetProviderId(provider.Name) + "_" + result.Id;
- result.ProviderName = provider.Name;
- }
-
- return list;
- }
-
- public Task<ChapterResponse> GetChapters(string id, CancellationToken cancellationToken)
- {
- var parts = id.Split(new[] { '_' }, 2);
-
- var provider = GetProvider(parts.First());
- id = parts.Last();
-
- return provider.GetChapters(id, cancellationToken);
- }
-
- public IEnumerable<ChapterProviderInfo> GetProviders(string itemId)
- {
- var video = _libraryManager.GetItemById(itemId) as Video;
- VideoContentType mediaType;
-
- if (video is Episode)
- {
- mediaType = VideoContentType.Episode;
- }
- else if (video is Movie)
- {
- mediaType = VideoContentType.Movie;
- }
- else
- {
- // These are the only supported types
- return new List<ChapterProviderInfo>();
- }
-
- var providers = GetInternalProviders(false)
- .Where(i => i.SupportedMediaTypes.Contains(mediaType));
-
- return GetInfos(providers);
- }
-
- public IEnumerable<ChapterProviderInfo> GetProviders()
- {
- return GetInfos(GetInternalProviders(true));
- }
-
- private IEnumerable<IChapterProvider> GetInternalProviders(bool includeDisabledProviders)
- {
- var providers = _providers;
-
- if (!includeDisabledProviders)
- {
- var options = GetConfiguration();
-
- providers = providers
- .Where(i => !options.DisabledFetchers.Contains(i.Name))
- .ToArray();
- }
-
- return providers
- .OrderBy(GetConfiguredOrder)
- .ThenBy(GetDefaultOrder)
- .ToArray();
- }
-
- private IEnumerable<ChapterProviderInfo> GetInfos(IEnumerable<IChapterProvider> providers)
- {
- return providers.Select(i => new ChapterProviderInfo
- {
- Name = i.Name,
- Id = GetProviderId(i.Name)
- });
- }
-
- private string GetProviderId(string name)
- {
- return name.ToLower().GetMD5().ToString("N");
- }
-
- private IChapterProvider GetProvider(string id)
- {
- return _providers.First(i => string.Equals(id, GetProviderId(i.Name)));
- }
-
- private int GetConfiguredOrder(IChapterProvider provider)
- {
- var options = GetConfiguration();
-
- // See if there's a user-defined order
- var index = Array.IndexOf(options.FetcherOrder, provider.Name);
-
- if (index != -1)
- {
- return index;
- }
-
- // Not configured. Just return some high number to put it at the end.
- return 100;
- }
-
- private int GetDefaultOrder(IChapterProvider provider)
- {
- var hasOrder = provider as IHasOrder;
-
- if (hasOrder != null)
- {
- return hasOrder.Order;
- }
-
- return 0;
- }
-
public IEnumerable<ChapterInfo> GetChapters(string itemId)
{
return _itemRepo.GetChapters(new Guid(itemId));
diff --git a/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs b/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs
index 3a532257f..b26f23715 100644
--- a/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs
+++ b/MediaBrowser.Providers/GameGenres/GameGenreImageProvider.cs
@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.GameGenres
public static string ProviderName
{
- get { return "Media Browser Designs"; }
+ get { return "Emby Designs"; }
}
public bool Supports(IHasImages item)
@@ -137,7 +137,7 @@ namespace MediaBrowser.Providers.GameGenres
{
CancellationToken = cancellationToken,
Url = url,
- ResourcePool = GenreImageProvider.ImageDownloadResourcePool
+ BufferContent = false
});
}
}
diff --git a/MediaBrowser.Providers/Genres/GenreImageProvider.cs b/MediaBrowser.Providers/Genres/GenreImageProvider.cs
index 7c2ed00a6..954cd008e 100644
--- a/MediaBrowser.Providers/Genres/GenreImageProvider.cs
+++ b/MediaBrowser.Providers/Genres/GenreImageProvider.cs
@@ -22,8 +22,6 @@ namespace MediaBrowser.Providers.Genres
private readonly SemaphoreSlim _listResourcePool = new SemaphoreSlim(1, 1);
- public static SemaphoreSlim ImageDownloadResourcePool = new SemaphoreSlim(5, 5);
-
public GenreImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
{
_config = config;
@@ -38,7 +36,7 @@ namespace MediaBrowser.Providers.Genres
public static string ProviderName
{
- get { return "Media Browser Designs"; }
+ get { return "Emby Designs"; }
}
public bool Supports(IHasImages item)
@@ -138,7 +136,7 @@ namespace MediaBrowser.Providers.Genres
{
CancellationToken = cancellationToken,
Url = url,
- ResourcePool = ImageDownloadResourcePool
+ BufferContent = false
});
}
}
diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs
index 3de330557..5203adc9d 100644
--- a/MediaBrowser.Providers/Manager/ImageSaver.cs
+++ b/MediaBrowser.Providers/Manager/ImageSaver.cs
@@ -38,6 +38,7 @@ namespace MediaBrowser.Providers.Manager
private readonly ILibraryMonitor _libraryMonitor;
private readonly IFileSystem _fileSystem;
private readonly ILogger _logger;
+ private readonly IMemoryStreamProvider _memoryStreamProvider;
/// <summary>
/// Initializes a new instance of the <see cref="ImageSaver" /> class.
@@ -46,12 +47,13 @@ namespace MediaBrowser.Providers.Manager
/// <param name="libraryMonitor">The directory watchers.</param>
/// <param name="fileSystem">The file system.</param>
/// <param name="logger">The logger.</param>
- public ImageSaver(IServerConfigurationManager config, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger)
+ public ImageSaver(IServerConfigurationManager config, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, ILogger logger, IMemoryStreamProvider memoryStreamProvider)
{
_config = config;
_libraryMonitor = libraryMonitor;
_fileSystem = fileSystem;
_logger = logger;
+ _memoryStreamProvider = memoryStreamProvider;
}
/// <summary>
@@ -124,7 +126,7 @@ namespace MediaBrowser.Providers.Manager
var retryPaths = GetSavePaths(item, type, imageIndex, mimeType, false);
// If there are more than one output paths, the stream will need to be seekable
- var memoryStream = new MemoryStream();
+ var memoryStream = _memoryStreamProvider.CreateNew();
using (source)
{
await source.CopyToAsync(memoryStream).ConfigureAwait(false);
@@ -211,6 +213,20 @@ namespace MediaBrowser.Providers.Manager
throw;
}
}
+ catch (IOException ex)
+ {
+ var retry = !string.IsNullOrWhiteSpace(retryPath) &&
+ !string.Equals(path, retryPath, StringComparison.OrdinalIgnoreCase);
+
+ if (retry)
+ {
+ _logger.Error("IOException saving to {0}. {2}. Will retry saving to {1}", path, retryPath, ex.Message);
+ }
+ else
+ {
+ throw;
+ }
+ }
source.Position = 0;
await SaveImageToLocation(source, retryPath, cancellationToken).ConfigureAwait(false);
@@ -355,7 +371,7 @@ namespace MediaBrowser.Providers.Manager
return Path.Combine(seriesFolder, imageFilename);
}
- if (item.IsInMixedFolder)
+ if (item.DetectIsInMixedFolder())
{
return GetSavePathForItemInMixedFolder(item, type, "landscape", extension);
}
@@ -431,7 +447,7 @@ namespace MediaBrowser.Providers.Manager
path = Path.Combine(Path.GetDirectoryName(item.Path), "metadata", filename + extension);
}
- else if (item.IsInMixedFolder)
+ else if (item.DetectIsInMixedFolder())
{
path = GetSavePathForItemInMixedFolder(item, type, filename, extension);
}
@@ -498,7 +514,7 @@ namespace MediaBrowser.Providers.Manager
if (imageIndex.Value == 0)
{
- if (item.IsInMixedFolder)
+ if (item.DetectIsInMixedFolder())
{
return new[] { GetSavePathForItemInMixedFolder(item, type, "fanart", extension) };
}
@@ -524,7 +540,7 @@ namespace MediaBrowser.Providers.Manager
var outputIndex = imageIndex.Value;
- if (item.IsInMixedFolder)
+ if (item.DetectIsInMixedFolder())
{
return new[] { GetSavePathForItemInMixedFolder(item, type, "fanart" + outputIndex.ToString(UsCulture), extension) };
}
@@ -567,7 +583,7 @@ namespace MediaBrowser.Providers.Manager
return new[] { Path.Combine(seasonFolder, imageFilename) };
}
- if (item.IsInMixedFolder || item is MusicVideo)
+ if (item.DetectIsInMixedFolder() || item is MusicVideo)
{
return new[] { GetSavePathForItemInMixedFolder(item, type, string.Empty, extension) };
}
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index 97dd1ed4c..87da835dc 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -56,7 +56,7 @@ namespace MediaBrowser.Providers.Manager
return hasChanges;
}
- public async Task<RefreshResult> RefreshImages(IHasImages item, IEnumerable<IImageProvider> imageProviders, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken)
+ public async Task<RefreshResult> RefreshImages(IHasImages item, LibraryOptions libraryOptions, IEnumerable<IImageProvider> imageProviders, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken)
{
if (refreshOptions.IsReplacingImage(ImageType.Backdrop))
{
@@ -84,7 +84,7 @@ namespace MediaBrowser.Providers.Manager
if (remoteProvider != null)
{
- await RefreshFromProvider(item, remoteProvider, refreshOptions, savedOptions, backdropLimit, screenshotLimit, downloadedImages, result, cancellationToken).ConfigureAwait(false);
+ await RefreshFromProvider(item, libraryOptions, remoteProvider, refreshOptions, savedOptions, backdropLimit, screenshotLimit, downloadedImages, result, cancellationToken).ConfigureAwait(false);
providerIds.Add(provider.GetType().FullName.GetMD5());
continue;
}
@@ -249,7 +249,7 @@ namespace MediaBrowser.Providers.Manager
/// <param name="result">The result.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- private async Task RefreshFromProvider(IHasImages item,
+ private async Task RefreshFromProvider(IHasImages item, LibraryOptions libraryOptions,
IRemoteImageProvider provider,
ImageRefreshOptions refreshOptions,
MetadataOptions savedOptions,
@@ -293,7 +293,7 @@ namespace MediaBrowser.Providers.Manager
if (!HasImage(item, imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType)))
{
minWidth = savedOptions.GetMinWidth(imageType);
- var downloaded = await DownloadImage(item, provider, result, list, minWidth, imageType, cancellationToken).ConfigureAwait(false);
+ var downloaded = await DownloadImage(item, libraryOptions, provider, result, list, minWidth, imageType, cancellationToken).ConfigureAwait(false);
if (downloaded)
{
@@ -305,7 +305,7 @@ namespace MediaBrowser.Providers.Manager
if (!item.LockedFields.Contains(MetadataFields.Backdrops))
{
minWidth = savedOptions.GetMinWidth(ImageType.Backdrop);
- await DownloadBackdrops(item, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
+ await DownloadBackdrops(item, libraryOptions, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
}
if (!item.LockedFields.Contains(MetadataFields.Screenshots))
@@ -314,7 +314,7 @@ namespace MediaBrowser.Providers.Manager
if (hasScreenshots != null)
{
minWidth = savedOptions.GetMinWidth(ImageType.Screenshot);
- await DownloadBackdrops(item, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
+ await DownloadBackdrops(item, libraryOptions, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
}
}
}
@@ -472,7 +472,7 @@ namespace MediaBrowser.Providers.Manager
return changed;
}
- private async Task<bool> DownloadImage(IHasImages item,
+ private async Task<bool> DownloadImage(IHasImages item, LibraryOptions libraryOptions,
IRemoteImageProvider provider,
RefreshResult result,
IEnumerable<RemoteImageInfo> images,
@@ -484,7 +484,7 @@ namespace MediaBrowser.Providers.Manager
.Where(i => i.Type == type && !(i.Width.HasValue && i.Width.Value < minWidth))
.ToList();
- if (EnableImageStub(item, type) && eligibleImages.Count > 0)
+ if (EnableImageStub(item, type, libraryOptions) && eligibleImages.Count > 0)
{
SaveImageStub(item, type, eligibleImages.Select(i => i.Url));
result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
@@ -518,14 +518,14 @@ namespace MediaBrowser.Providers.Manager
return false;
}
- private bool EnableImageStub(IHasImages item, ImageType type)
+ private bool EnableImageStub(IHasImages item, ImageType type, LibraryOptions libraryOptions)
{
if (item is LiveTvProgram)
{
return true;
}
- if (_config.Configuration.DownloadImagesInAdvance)
+ if (libraryOptions.DownloadImagesInAdvance)
{
return false;
}
@@ -555,12 +555,6 @@ namespace MediaBrowser.Providers.Manager
return false;
case ImageType.Thumb:
return false;
- case ImageType.Logo:
- return false;
- case ImageType.Backdrop:
- return false;
- case ImageType.Screenshot:
- return false;
default:
return true;
}
@@ -585,7 +579,7 @@ namespace MediaBrowser.Providers.Manager
}, newIndex);
}
- private async Task DownloadBackdrops(IHasImages item, ImageType imageType, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, int minWidth, CancellationToken cancellationToken)
+ private async Task DownloadBackdrops(IHasImages item, LibraryOptions libraryOptions, ImageType imageType, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, int minWidth, CancellationToken cancellationToken)
{
foreach (var image in images.Where(i => i.Type == imageType))
{
@@ -601,7 +595,7 @@ namespace MediaBrowser.Providers.Manager
var url = image.Url;
- if (EnableImageStub(item, imageType))
+ if (EnableImageStub(item, imageType, libraryOptions))
{
SaveImageStub(item, imageType, new[] { url });
result.UpdateType = result.UpdateType | ItemUpdateType.ImageUpdate;
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index a610df427..c470f55f2 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -11,6 +11,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Providers;
namespace MediaBrowser.Providers.Manager
@@ -120,6 +121,8 @@ namespace MediaBrowser.Providers.Manager
}
}
+ LibraryOptions libraryOptions = null;
+
// Next run remote image providers, but only if local image providers didn't throw an exception
if (!localImagesFailed && refreshOptions.ImageRefreshMode != ImageRefreshMode.ValidationOnly)
{
@@ -127,7 +130,12 @@ namespace MediaBrowser.Providers.Manager
if (providers.Count > 0)
{
- var result = await itemImageProvider.RefreshImages(itemOfType, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false);
+ if (libraryOptions == null)
+ {
+ libraryOptions = LibraryManager.GetLibraryOptions((BaseItem)item);
+ }
+
+ var result = await itemImageProvider.RefreshImages(itemOfType, libraryOptions, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false);
updateType = updateType | result.UpdateType;
if (result.Failures == 0)
@@ -180,8 +188,13 @@ namespace MediaBrowser.Providers.Manager
item.DateLastRefreshed = default(DateTime);
}
+ if (libraryOptions == null)
+ {
+ libraryOptions = LibraryManager.GetLibraryOptions((BaseItem)item);
+ }
+
// Save to database
- await SaveItem(metadataResult, updateType, cancellationToken).ConfigureAwait(false);
+ await SaveItem(metadataResult, libraryOptions, updateType, cancellationToken).ConfigureAwait(false);
}
await AfterMetadataRefresh(itemOfType, refreshOptions, cancellationToken).ConfigureAwait(false);
@@ -196,17 +209,19 @@ namespace MediaBrowser.Providers.Manager
lookupInfo.Year = result.ProductionYear;
}
- protected async Task SaveItem(MetadataResult<TItemType> result, ItemUpdateType reason, CancellationToken cancellationToken)
+ protected async Task SaveItem(MetadataResult<TItemType> result, LibraryOptions libraryOptions, ItemUpdateType reason, CancellationToken cancellationToken)
{
if (result.Item.SupportsPeople && result.People != null)
{
- await LibraryManager.UpdatePeople(result.Item as BaseItem, result.People.ToList());
- await SavePeopleMetadata(result.People, cancellationToken).ConfigureAwait(false);
+ var baseItem = result.Item as BaseItem;
+
+ await LibraryManager.UpdatePeople(baseItem, result.People.ToList());
+ await SavePeopleMetadata(result.People, libraryOptions, cancellationToken).ConfigureAwait(false);
}
await result.Item.UpdateToRepository(reason, cancellationToken).ConfigureAwait(false);
}
- private async Task SavePeopleMetadata(List<PersonInfo> people, CancellationToken cancellationToken)
+ private async Task SavePeopleMetadata(List<PersonInfo> people, LibraryOptions libraryOptions, CancellationToken cancellationToken)
{
foreach (var person in people)
{
@@ -229,7 +244,7 @@ namespace MediaBrowser.Providers.Manager
if (!string.IsNullOrWhiteSpace(person.ImageUrl) && !personEntity.HasImage(ImageType.Primary))
{
- await AddPersonImage(personEntity, person.ImageUrl, cancellationToken).ConfigureAwait(false);
+ await AddPersonImage(personEntity, libraryOptions, person.ImageUrl, cancellationToken).ConfigureAwait(false);
saveEntity = true;
updateType = updateType | ItemUpdateType.ImageUpdate;
@@ -243,9 +258,9 @@ namespace MediaBrowser.Providers.Manager
}
}
- private async Task AddPersonImage(Person personEntity, string imageUrl, CancellationToken cancellationToken)
+ private async Task AddPersonImage(Person personEntity, LibraryOptions libraryOptions, string imageUrl, CancellationToken cancellationToken)
{
- if (ServerConfigurationManager.Configuration.DownloadImagesInAdvance)
+ if (libraryOptions.DownloadImagesInAdvance)
{
try
{
@@ -301,6 +316,13 @@ namespace MediaBrowser.Providers.Manager
updateType |= ItemUpdateType.MetadataImport;
}
+ var inheritedTags = item.GetInheritedTags();
+ if (!inheritedTags.SequenceEqual(item.InheritedTags, StringComparer.Ordinal))
+ {
+ item.InheritedTags = inheritedTags;
+ updateType |= ItemUpdateType.MetadataImport;
+ }
+
return updateType;
}
@@ -517,7 +539,7 @@ namespace MediaBrowser.Providers.Manager
refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport;
// Only one local provider allowed per item
- if (IsFullLocalMetadata(localItem.Item))
+ if (item.IsLocked || IsFullLocalMetadata(localItem.Item))
{
hasLocalMetadata = true;
}
@@ -532,8 +554,6 @@ namespace MediaBrowser.Providers.Manager
}
catch (Exception ex)
{
- refreshResult.Failures++;
-
Logger.ErrorException("Error in {0}", ex, provider.Name);
// If a local provider fails, consider that a failure
@@ -631,6 +651,8 @@ namespace MediaBrowser.Providers.Manager
{
var refreshResult = new RefreshResult();
+ var results = new List<MetadataResult<TItemType>>();
+
foreach (var provider in providers)
{
var providerName = provider.GetType().Name;
@@ -647,7 +669,7 @@ namespace MediaBrowser.Providers.Manager
if (result.HasMetadata)
{
- MergeData(result, temp, new List<MetadataFields>(), false, false);
+ results.Add(result);
refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataDownload;
}
@@ -668,9 +690,49 @@ namespace MediaBrowser.Providers.Manager
}
}
+ var orderedResults = new List<MetadataResult<TItemType>>();
+ var preferredLanguage = NormalizeLanguage(id.MetadataLanguage);
+
+ // prioritize results with matching ResultLanguage
+ foreach (var result in results)
+ {
+ if (!result.QueriedById)
+ {
+ break;
+ }
+
+ if (string.Equals(NormalizeLanguage(result.ResultLanguage), preferredLanguage, StringComparison.OrdinalIgnoreCase) && result.QueriedById)
+ {
+ orderedResults.Add(result);
+ }
+ }
+
+ // add all other results
+ foreach (var result in results)
+ {
+ if (!orderedResults.Contains(result))
+ {
+ orderedResults.Add(result);
+ }
+ }
+
+ foreach (var result in results)
+ {
+ MergeData(result, temp, new List<MetadataFields>(), false, false);
+ }
+
return refreshResult;
}
+ private string NormalizeLanguage(string language)
+ {
+ if (string.IsNullOrWhiteSpace(language))
+ {
+ return "en";
+ }
+ return language;
+ }
+
private void MergeNewData(TItemType source, TIdType lookupInfo)
{
// Copy new provider id's that may have been obtained
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index 25b9b4fd5..ae1d60eb9 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -20,6 +20,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Providers.Manager
@@ -57,13 +58,13 @@ namespace MediaBrowser.Providers.Manager
private IMetadataService[] _metadataServices = { };
private IMetadataProvider[] _metadataProviders = { };
private IEnumerable<IMetadataSaver> _savers;
- private IImageSaver[] _imageSavers;
private readonly IServerApplicationPaths _appPaths;
private readonly IJsonSerializer _json;
private IExternalId[] _externalIds;
private readonly Func<ILibraryManager> _libraryManagerFactory;
+ private readonly IMemoryStreamProvider _memoryStreamProvider;
/// <summary>
/// Initializes a new instance of the <see cref="ProviderManager" /> class.
@@ -73,7 +74,7 @@ namespace MediaBrowser.Providers.Manager
/// <param name="libraryMonitor">The directory watchers.</param>
/// <param name="logManager">The log manager.</param>
/// <param name="fileSystem">The file system.</param>
- public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory, IJsonSerializer json)
+ public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory, IJsonSerializer json, IMemoryStreamProvider memoryStreamProvider)
{
_logger = logManager.GetLogger("ProviderManager");
_httpClient = httpClient;
@@ -83,26 +84,20 @@ namespace MediaBrowser.Providers.Manager
_appPaths = appPaths;
_libraryManagerFactory = libraryManagerFactory;
_json = json;
+ _memoryStreamProvider = memoryStreamProvider;
}
/// <summary>
/// Adds the metadata providers.
/// </summary>
- /// <param name="imageProviders">The image providers.</param>
- /// <param name="metadataServices">The metadata services.</param>
- /// <param name="metadataProviders">The metadata providers.</param>
- /// <param name="metadataSavers">The metadata savers.</param>
- /// <param name="imageSavers">The image savers.</param>
- /// <param name="externalIds">The external ids.</param>
public void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices,
IEnumerable<IMetadataProvider> metadataProviders, IEnumerable<IMetadataSaver> metadataSavers,
- IEnumerable<IImageSaver> imageSavers, IEnumerable<IExternalId> externalIds)
+ IEnumerable<IExternalId> externalIds)
{
ImageProviders = imageProviders.ToArray();
_metadataServices = metadataServices.OrderBy(i => i.Order).ToArray();
_metadataProviders = metadataProviders.ToArray();
- _imageSavers = imageSavers.ToArray();
_externalIds = externalIds.OrderBy(i => i.Name).ToArray();
_savers = metadataSavers.Where(i =>
@@ -142,12 +137,12 @@ namespace MediaBrowser.Providers.Manager
public Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken)
{
- return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken);
+ return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken);
}
public Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken)
{
- return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
+ return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, source, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
}
public Task SaveImage(IHasImages item, string source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken)
@@ -159,7 +154,7 @@ namespace MediaBrowser.Providers.Manager
var fileStream = _fileSystem.GetFileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true);
- return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, fileStream, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
+ return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, fileStream, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
}
public async Task<IEnumerable<RemoteImageInfo>> GetAvailableRemoteImages(IHasImages item, RemoteImageQuery query, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs
index 5f23cf69c..fabe08f33 100644
--- a/MediaBrowser.Providers/Manager/ProviderUtils.cs
+++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs
@@ -99,6 +99,11 @@ namespace MediaBrowser.Providers.Manager
target.CustomRating = source.CustomRating;
}
+ if (replaceData || string.IsNullOrEmpty(target.Tagline))
+ {
+ target.Tagline = source.Tagline;
+ }
+
if (!lockedFields.Contains(MetadataFields.Overview))
{
if (replaceData || string.IsNullOrEmpty(target.Overview))
@@ -167,15 +172,9 @@ namespace MediaBrowser.Providers.Manager
if (!lockedFields.Contains(MetadataFields.ProductionLocations))
{
- var sourceHasProductionLocations = source as IHasProductionLocations;
- var targetHasProductionLocations = target as IHasProductionLocations;
-
- if (sourceHasProductionLocations != null && targetHasProductionLocations != null)
+ if (replaceData || target.ProductionLocations.Count == 0)
{
- if (replaceData || targetHasProductionLocations.ProductionLocations.Count == 0)
- {
- targetHasProductionLocations.ProductionLocations = sourceHasProductionLocations.ProductionLocations;
- }
+ target.ProductionLocations = source.ProductionLocations;
}
}
@@ -200,7 +199,6 @@ namespace MediaBrowser.Providers.Manager
MergeMetascore(source, target, lockedFields, replaceData);
MergeCriticRating(source, target, lockedFields, replaceData);
MergeAwards(source, target, lockedFields, replaceData);
- MergeTaglines(source, target, lockedFields, replaceData);
MergeTrailers(source, target, lockedFields, replaceData);
MergeShortOverview(source, target, lockedFields, replaceData);
@@ -330,20 +328,6 @@ namespace MediaBrowser.Providers.Manager
}
}
- private static void MergeTaglines(BaseItem source, BaseItem target, List<MetadataFields> lockedFields, bool replaceData)
- {
- var sourceCast = source as IHasTaglines;
- var targetCast = target as IHasTaglines;
-
- if (sourceCast != null && targetCast != null)
- {
- if (replaceData || targetCast.Taglines.Count == 0)
- {
- targetCast.Taglines = sourceCast.Taglines;
- }
- }
- }
-
private static void MergeTrailers(BaseItem source, BaseItem target, List<MetadataFields> lockedFields, bool replaceData)
{
var sourceCast = source as IHasTrailers;
diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
index 027341ee6..68fc80371 100644
--- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
@@ -162,7 +162,7 @@ namespace MediaBrowser.Providers.MediaInfo
{
var audio = item as Audio;
- return item.LocationType == LocationType.FileSystem && audio != null && !audio.IsArchive;
+ return item.LocationType == LocationType.FileSystem && audio != null;
}
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService)
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
index baa561487..afcf4b226 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
@@ -38,13 +38,6 @@ namespace MediaBrowser.Providers.MediaInfo
public async Task<ItemUpdateType> Probe<T>(T item, CancellationToken cancellationToken)
where T : Audio
{
- if (item.IsArchive)
- {
- var ext = Path.GetExtension(item.Path) ?? string.Empty;
- item.Container = ext.TrimStart('.');
- return ItemUpdateType.MetadataImport;
- }
-
var result = await GetMediaInfo(item, cancellationToken).ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
index 0f8cf93fb..be0b2ca6d 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
@@ -72,13 +72,6 @@ namespace MediaBrowser.Providers.MediaInfo
CancellationToken cancellationToken)
where T : Video
{
- if (item.IsArchive)
- {
- var ext = Path.GetExtension(item.Path) ?? string.Empty;
- item.Container = ext.TrimStart('.');
- return ItemUpdateType.MetadataImport;
- }
-
var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false);
BlurayDiscInfo blurayDiscInfo = null;
@@ -238,22 +231,6 @@ namespace MediaBrowser.Providers.MediaInfo
if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh ||
options.MetadataRefreshMode == MetadataRefreshMode.Default)
{
- var chapterOptions = _chapterManager.GetConfiguration();
-
- try
- {
- var remoteChapters = await DownloadChapters(video, chapters, chapterOptions, cancellationToken).ConfigureAwait(false);
-
- if (remoteChapters.Count > 0)
- {
- chapters = remoteChapters;
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error downloading chapters", ex);
- }
-
if (chapters.Count == 0 && mediaStreams.Any(i => i.Type == MediaStreamType.Video))
{
AddDummyChapters(video, chapters);
@@ -262,8 +239,8 @@ namespace MediaBrowser.Providers.MediaInfo
NormalizeChapterNames(chapters);
var libraryOptions = _libraryManager.GetLibraryOptions(video);
- var extractDuringScan = chapterOptions.ExtractDuringLibraryScan;
- if (libraryOptions != null && libraryOptions.SchemaVersion >= 2)
+ var extractDuringScan = false;
+ if (libraryOptions != null)
{
extractDuringScan = libraryOptions.ExtractChapterImagesDuringLibraryScan;
}
@@ -561,52 +538,6 @@ namespace MediaBrowser.Providers.MediaInfo
currentStreams.AddRange(externalSubtitleStreams);
}
- private async Task<List<ChapterInfo>> DownloadChapters(Video video, List<ChapterInfo> currentChapters, ChapterOptions options, CancellationToken cancellationToken)
- {
- if ((options.DownloadEpisodeChapters &&
- video is Episode) ||
- (options.DownloadMovieChapters &&
- video is Movie))
- {
- var results = await _chapterManager.Search(video, cancellationToken).ConfigureAwait(false);
-
- var result = results.FirstOrDefault();
-
- if (result != null)
- {
- var chapters = await _chapterManager.GetChapters(result.Id, cancellationToken).ConfigureAwait(false);
-
- var chapterInfos = chapters.Chapters.Select(i => new ChapterInfo
- {
- Name = i.Name,
- StartPositionTicks = i.StartPositionTicks
-
- }).ToList();
-
- if (chapterInfos.All(i => i.StartPositionTicks == 0))
- {
- if (currentChapters.Count >= chapterInfos.Count)
- {
- var index = 0;
- foreach (var info in chapterInfos)
- {
- info.StartPositionTicks = currentChapters[index].StartPositionTicks;
- index++;
- }
- }
- else
- {
- chapterInfos.Clear();
- }
- }
-
- return chapterInfos;
- }
- }
-
- return new List<ChapterInfo>();
- }
-
/// <summary>
/// The dummy chapter duration
/// </summary>
diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs
index f64b7b792..024171f40 100644
--- a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs
+++ b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs
@@ -117,7 +117,7 @@ namespace MediaBrowser.Providers.MediaInfo
{
get
{
- return new[] { ".srt", ".ssa", ".ass", ".sub" };
+ return new[] { ".srt", ".ssa", ".ass", ".sub", ".smi", ".sami" };
}
}
diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs
index 79da291b7..2490f7145 100644
--- a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs
+++ b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs
@@ -14,6 +14,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using System.IO;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Providers.MediaInfo
{
@@ -24,14 +26,16 @@ namespace MediaBrowser.Providers.MediaInfo
private readonly ISubtitleManager _subtitleManager;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly ILogger _logger;
+ private IJsonSerializer _json;
- public SubtitleScheduledTask(ILibraryManager libraryManager, IServerConfigurationManager config, ISubtitleManager subtitleManager, ILogger logger, IMediaSourceManager mediaSourceManager)
+ public SubtitleScheduledTask(ILibraryManager libraryManager, IJsonSerializer json, IServerConfigurationManager config, ISubtitleManager subtitleManager, ILogger logger, IMediaSourceManager mediaSourceManager)
{
_libraryManager = libraryManager;
_config = config;
_subtitleManager = subtitleManager;
_logger = logger;
_mediaSourceManager = mediaSourceManager;
+ _json = json;
}
public string Name
@@ -58,38 +62,65 @@ namespace MediaBrowser.Providers.MediaInfo
{
var options = GetOptions();
- var videos = _libraryManager.RootFolder
- .GetRecursiveChildren(i =>
- {
- if (!(i is Video))
- {
- return false;
- }
+ var types = new List<string>();
- if (i.LocationType == LocationType.Remote || i.LocationType == LocationType.Virtual)
- {
- return false;
- }
+ if (options.DownloadEpisodeSubtitles)
+ {
+ types.Add("Episode");
+ }
+ if (options.DownloadMovieSubtitles)
+ {
+ types.Add("Movie");
+ }
- return (options.DownloadEpisodeSubtitles &&
- i is Episode) ||
- (options.DownloadMovieSubtitles &&
- i is Movie);
- })
- .Cast<Video>()
+ if (types.Count == 0)
+ {
+ return;
+ }
+
+ var videos = _libraryManager.GetItemList(new InternalItemsQuery
+ {
+ MediaTypes = new string[] { MediaType.Video },
+ IsVirtualItem = false,
+ ExcludeLocationTypes = new LocationType[] { LocationType.Remote, LocationType.Virtual },
+ IncludeItemTypes = types.ToArray()
+
+ }).OfType<Video>()
.ToList();
+ var failHistoryPath = Path.Combine(_config.ApplicationPaths.CachePath, "subtitlehistory.json");
+ var history = GetHistory(failHistoryPath);
+
var numComplete = 0;
foreach (var video in videos)
{
+ DateTime lastAttempt;
+ if (history.TryGetValue(video.Id.ToString("N"), out lastAttempt))
+ {
+ if ((DateTime.UtcNow - lastAttempt).TotalDays <= 7)
+ {
+ continue;
+ }
+ }
+
try
{
- await DownloadSubtitles(video, options, cancellationToken).ConfigureAwait(false);
+ var shouldRetry = await DownloadSubtitles(video, options, cancellationToken).ConfigureAwait(false);
+
+ if (shouldRetry)
+ {
+ history[video.Id.ToString("N")] = DateTime.UtcNow;
+ }
+ else
+ {
+ history.Remove(video.Id.ToString("N"));
+ }
}
catch (Exception ex)
{
_logger.ErrorException("Error downloading subtitles for {0}", ex, video.Path);
+ history[video.Id.ToString("N")] = DateTime.UtcNow;
}
// Update progress
@@ -99,9 +130,23 @@ namespace MediaBrowser.Providers.MediaInfo
progress.Report(100 * percent);
}
+
+ _json.SerializeToFile(history, failHistoryPath);
}
- private async Task DownloadSubtitles(Video video, SubtitleOptions options, CancellationToken cancellationToken)
+ private Dictionary<string,DateTime> GetHistory(string path)
+ {
+ try
+ {
+ return _json.DeserializeFromFile<Dictionary<string, DateTime>>(path);
+ }
+ catch
+ {
+ return new Dictionary<string, DateTime>();
+ }
+ }
+
+ private async Task<bool> DownloadSubtitles(Video video, SubtitleOptions options, CancellationToken cancellationToken)
{
if ((options.DownloadEpisodeSubtitles &&
video is Episode) ||
@@ -124,8 +169,13 @@ namespace MediaBrowser.Providers.MediaInfo
if (downloadedLanguages.Count > 0)
{
await video.RefreshMetadata(cancellationToken).ConfigureAwait(false);
+ return false;
}
+
+ return true;
}
+
+ return false;
}
public IEnumerable<ITaskTrigger> GetDefaultTriggers()
diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
index 2ad02da2e..45d1c3d80 100644
--- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
@@ -134,7 +134,7 @@ namespace MediaBrowser.Providers.MediaInfo
}
}
- extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, protocol, videoIndex, cancellationToken).ConfigureAwait(false);
+ extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, videoIndex, cancellationToken).ConfigureAwait(false);
}
else
{
@@ -145,7 +145,7 @@ namespace MediaBrowser.Providers.MediaInfo
? TimeSpan.FromTicks(Convert.ToInt64(item.RunTimeTicks.Value * .1))
: TimeSpan.FromSeconds(10);
- extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, protocol, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
+ extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
}
return new DynamicImageResponse
@@ -174,8 +174,7 @@ namespace MediaBrowser.Providers.MediaInfo
{
var video = item as Video;
- if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder &&
- !video.IsShortcut && !video.IsArchive)
+ if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut)
{
return true;
}
diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
index 18f177932..2a40e4d85 100644
--- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
@@ -20,6 +20,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Providers.TV;
namespace MediaBrowser.Providers.Movies
@@ -59,30 +60,13 @@ namespace MediaBrowser.Providers.Movies
public bool Supports(IHasImages item)
{
- //var channelItem = item as IChannelMediaItem;
-
- //if (channelItem != null)
- //{
- // if (channelItem.ContentType == ChannelMediaContentType.Movie)
- // {
- // return true;
- // }
- // if (channelItem.ContentType == ChannelMediaContentType.MovieExtra)
- // {
- // if (channelItem.ExtraType == ExtraType.Trailer)
- // {
- // return true;
- // }
- // }
- //}
-
// Supports images for tv movies
- //var tvProgram = item as LiveTvProgram;
- //if (tvProgram != null && tvProgram.IsMovie)
- //{
- // return true;
- //}
-
+ var tvProgram = item as LiveTvProgram;
+ if (tvProgram != null && tvProgram.IsMovie)
+ {
+ return true;
+ }
+
return item is Movie || item is BoxSet || item is MusicVideo;
}
diff --git a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
index 1bf4ed6c0..82a2dfbe9 100644
--- a/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
+++ b/MediaBrowser.Providers/Movies/GenericMovieDbInfo.cs
@@ -14,6 +14,7 @@ using System.Net;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Providers.Movies
{
@@ -125,11 +126,7 @@ namespace MediaBrowser.Providers.Movies
movie.Name = movieData.GetTitle() ?? movie.Name;
- var hasOriginalTitle = movie as IHasOriginalTitle;
- if (hasOriginalTitle != null)
- {
- hasOriginalTitle.OriginalTitle = movieData.GetOriginalTitle();
- }
+ movie.OriginalTitle = movieData.GetOriginalTitle();
// Bug in Mono: WebUtility.HtmlDecode should return null if the string is null but in Mono it generate an System.ArgumentNullException.
movie.Overview = movieData.overview != null ? WebUtility.HtmlDecode(movieData.overview) : null;
@@ -146,24 +143,15 @@ namespace MediaBrowser.Providers.Movies
if (!string.IsNullOrEmpty(movieData.tagline))
{
- var hasTagline = movie as IHasTaglines;
- if (hasTagline != null)
- {
- hasTagline.Taglines.Clear();
- hasTagline.AddTagline(movieData.tagline);
- }
+ movie.Tagline = movieData.tagline;
}
if (movieData.production_countries != null)
{
- var hasProductionLocations = movie as IHasProductionLocations;
- if (hasProductionLocations != null)
- {
- hasProductionLocations.ProductionLocations = movieData
- .production_countries
- .Select(i => i.name)
- .ToList();
- }
+ movie.ProductionLocations = movieData
+ .production_countries
+ .Select(i => i.name)
+ .ToList();
}
movie.SetProviderId(MetadataProviders.Tmdb, movieData.id.ToString(_usCulture));
@@ -197,13 +185,17 @@ namespace MediaBrowser.Providers.Movies
{
var releases = movieData.releases.countries.Where(i => !string.IsNullOrWhiteSpace(i.certification)).ToList();
- var ourRelease = releases.FirstOrDefault(c => c.iso_3166_1.Equals(preferredCountryCode, StringComparison.OrdinalIgnoreCase));
- var usRelease = releases.FirstOrDefault(c => c.iso_3166_1.Equals("US", StringComparison.OrdinalIgnoreCase));
+ var ourRelease = releases.FirstOrDefault(c => string.Equals(c.iso_3166_1, preferredCountryCode, StringComparison.OrdinalIgnoreCase));
+ var usRelease = releases.FirstOrDefault(c => string.Equals(c.iso_3166_1, "US", StringComparison.OrdinalIgnoreCase));
if (ourRelease != null)
{
var ratingPrefix = string.Equals(preferredCountryCode, "us", StringComparison.OrdinalIgnoreCase) ? "" : preferredCountryCode + "-";
- movie.OfficialRating = ratingPrefix + ourRelease.certification;
+ var newRating = ratingPrefix + ourRelease.certification;
+
+ newRating = newRating.Replace("de-", "FSK-", StringComparison.OrdinalIgnoreCase);
+
+ movie.OfficialRating = newRating;
}
else if (usRelease != null)
{
diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
index a0ce80610..9ed8f0a00 100644
--- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
+++ b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
@@ -85,7 +85,8 @@ namespace MediaBrowser.Providers.Music
{
var result = new RemoteSearchResult
{
- Name = i.Title
+ Name = i.Title,
+ ProductionYear = i.Year
};
if (!string.IsNullOrWhiteSpace(i.ReleaseId))
@@ -94,7 +95,7 @@ namespace MediaBrowser.Providers.Music
}
if (!string.IsNullOrWhiteSpace(i.ReleaseGroupId))
{
- result.SetProviderId(MetadataProviders.MusicBrainzAlbum, i.ReleaseGroupId);
+ result.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, i.ReleaseGroupId);
}
return result;
@@ -117,16 +118,22 @@ namespace MediaBrowser.Providers.Music
var releaseResult = await GetReleaseResult(artistMusicBrainzId, id.GetAlbumArtist(), id.Name, cancellationToken).ConfigureAwait(false);
- if (!string.IsNullOrEmpty(releaseResult.ReleaseId))
+ if (releaseResult != null)
{
- releaseId = releaseResult.ReleaseId;
- result.HasMetadata = true;
- }
+ if (!string.IsNullOrEmpty(releaseResult.ReleaseId))
+ {
+ releaseId = releaseResult.ReleaseId;
+ result.HasMetadata = true;
+ }
- if (!string.IsNullOrEmpty(releaseResult.ReleaseGroupId))
- {
- releaseGroupId = releaseResult.ReleaseGroupId;
- result.HasMetadata = true;
+ if (!string.IsNullOrEmpty(releaseResult.ReleaseGroupId))
+ {
+ releaseGroupId = releaseResult.ReleaseGroupId;
+ result.HasMetadata = true;
+ }
+
+ result.Item.ProductionYear = releaseResult.Year;
+ result.Item.Overview = releaseResult.Overview;
}
}
@@ -205,6 +212,8 @@ namespace MediaBrowser.Providers.Music
public string ReleaseId;
public string ReleaseGroupId;
public string Title;
+ public string Overview;
+ public int? Year;
public static List<ReleaseResult> Parse(XmlDocument doc, int? limit = null)
{
@@ -237,7 +246,9 @@ namespace MediaBrowser.Providers.Music
{
ReleaseId = releaseId,
ReleaseGroupId = releaseGroupId,
- Title = GetTitleFromReleaseNode(node)
+ Title = GetValueFromReleaseNode(node, "title"),
+ Overview = GetValueFromReleaseNode(node, "annotation"),
+ Year = GetYearFromReleaseNode(node, "date")
});
if (limit.HasValue && list.Count >= limit.Value)
@@ -251,14 +262,37 @@ namespace MediaBrowser.Providers.Music
return list;
}
- private static string GetTitleFromReleaseNode(XmlNode node)
+ private static int? GetYearFromReleaseNode(XmlNode node, string name)
+ {
+ var subNodes = node.ChildNodes;
+ if (subNodes != null)
+ {
+ foreach (var subNode in subNodes.Cast<XmlNode>())
+ {
+ if (string.Equals(subNode.Name, name, StringComparison.OrdinalIgnoreCase))
+ {
+ DateTime date;
+ if (DateTime.TryParse(subNode.InnerText, out date))
+ {
+ return date.Year;
+ }
+
+ return null;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static string GetValueFromReleaseNode(XmlNode node, string name)
{
var subNodes = node.ChildNodes;
if (subNodes != null)
{
foreach (var subNode in subNodes.Cast<XmlNode>())
{
- if (string.Equals(subNode.Name, "title", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(subNode.Name, name, StringComparison.OrdinalIgnoreCase))
{
return subNode.InnerText;
}
diff --git a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
index 88635bf06..88128bdc7 100644
--- a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
@@ -86,7 +86,7 @@ namespace MediaBrowser.Providers.Music
if (node.Attributes != null)
{
string name = null;
-
+ string overview = null;
string mbzId = node.Attributes["id"].Value;
foreach (var child in node.ChildNodes.Cast<XmlNode>())
@@ -94,7 +94,10 @@ namespace MediaBrowser.Providers.Music
if (string.Equals(child.Name, "name", StringComparison.OrdinalIgnoreCase))
{
name = child.InnerText;
- break;
+ }
+ if (string.Equals(child.Name, "annotation", StringComparison.OrdinalIgnoreCase))
+ {
+ overview = child.InnerText;
}
}
@@ -102,7 +105,8 @@ namespace MediaBrowser.Providers.Music
{
var result = new RemoteSearchResult
{
- Name = name
+ Name = name,
+ Overview = overview
};
result.SetProviderId(MetadataProviders.MusicBrainzArtist, mbzId);
@@ -135,6 +139,7 @@ namespace MediaBrowser.Providers.Music
{
musicBrainzId = singleResult.GetProviderId(MetadataProviders.MusicBrainzArtist);
//result.Item.Name = singleResult.Name;
+ result.Item.Overview = singleResult.Overview;
}
}
diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
index 914b775af..428bde2f2 100644
--- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
+++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
@@ -212,13 +212,15 @@ namespace MediaBrowser.Providers.Omdb
{
var result = new MetadataResult<Series>
{
- Item = new Series()
+ Item = new Series(),
+ QueriedById = true
};
var imdbId = info.GetProviderId(MetadataProviders.Imdb);
if (string.IsNullOrWhiteSpace(imdbId))
{
imdbId = await GetSeriesImdbId(info, cancellationToken).ConfigureAwait(false);
+ result.QueriedById = false;
}
if (!string.IsNullOrEmpty(imdbId))
@@ -251,13 +253,15 @@ namespace MediaBrowser.Providers.Omdb
{
var result = new MetadataResult<T>
{
- Item = new T()
+ Item = new T(),
+ QueriedById = true
};
var imdbId = info.GetProviderId(MetadataProviders.Imdb);
if (string.IsNullOrWhiteSpace(imdbId))
{
imdbId = await GetMovieImdbId(info, cancellationToken).ConfigureAwait(false);
+ result.QueriedById = false;
}
if (!string.IsNullOrEmpty(imdbId))
diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
index bb17b83ec..c954e6323 100644
--- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
+++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
@@ -179,7 +179,11 @@ namespace MediaBrowser.Providers.People
item.Name = info.name;
item.HomePageUrl = info.homepage;
- item.PlaceOfBirth = info.place_of_birth;
+
+ if (!string.IsNullOrWhiteSpace(info.place_of_birth))
+ {
+ item.ProductionLocations = new List<string> { info.place_of_birth };
+ }
item.Overview = info.biography;
DateTime date;
diff --git a/MediaBrowser.Providers/People/PersonMetadataService.cs b/MediaBrowser.Providers/People/PersonMetadataService.cs
index 0be5773db..0f8bd8b66 100644
--- a/MediaBrowser.Providers/People/PersonMetadataService.cs
+++ b/MediaBrowser.Providers/People/PersonMetadataService.cs
@@ -15,14 +15,6 @@ namespace MediaBrowser.Providers.People
protected override void MergeData(MetadataResult<Person> source, MetadataResult<Person> target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
-
- var sourceItem = source.Item;
- var targetItem = target.Item;
-
- if (replaceData || string.IsNullOrEmpty(targetItem.PlaceOfBirth))
- {
- targetItem.PlaceOfBirth = sourceItem.PlaceOfBirth;
- }
}
public PersonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
diff --git a/MediaBrowser.Providers/Studios/StudiosImageProvider.cs b/MediaBrowser.Providers/Studios/StudiosImageProvider.cs
index 62109243d..bfb7eb8fd 100644
--- a/MediaBrowser.Providers/Studios/StudiosImageProvider.cs
+++ b/MediaBrowser.Providers/Studios/StudiosImageProvider.cs
@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Studios
public static string ProviderName
{
- get { return "Media Browser Designs"; }
+ get { return "Emby Designs"; }
}
public bool Supports(IHasImages item)
@@ -137,7 +137,7 @@ namespace MediaBrowser.Providers.Studios
{
CancellationToken = cancellationToken,
Url = url,
- ResourcePool = GenreImageProvider.ImageDownloadResourcePool
+ BufferContent = false
});
}
}
diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
index a12402f4f..9c212e8a0 100644
--- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
@@ -118,7 +118,7 @@ namespace MediaBrowser.Providers.TV
var hasNewEpisodes = false;
- if (_config.Configuration.EnableInternetProviders && addNewItems)
+ if (addNewItems && !group.Any(i => !i.IsInternetMetadataEnabled()))
{
var seriesConfig = _config.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, typeof(Series).Name, StringComparison.OrdinalIgnoreCase));
diff --git a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs
index 621f66514..78bce241f 100644
--- a/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/Omdb/OmdbEpisodeProvider.cs
@@ -43,7 +43,8 @@ namespace MediaBrowser.Providers.TV
{
var result = new MetadataResult<Episode>()
{
- Item = new Episode()
+ Item = new Episode(),
+ QueriedById = true
};
// Allowing this will dramatically increase scan times
diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
index d6ae84b91..e038a3d28 100644
--- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
+++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
@@ -47,7 +47,7 @@ namespace MediaBrowser.Providers.TV
return RunInternal(progress, cancellationToken);
}
- private async Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
+ private Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken)
{
var seriesList = _libraryManager.GetItemList(new InternalItemsQuery()
{
@@ -59,34 +59,7 @@ namespace MediaBrowser.Providers.TV
var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList();
- await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem)
- .Run(seriesGroups, true, cancellationToken).ConfigureAwait(false);
-
- var numComplete = 0;
-
- foreach (var series in seriesList)
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- var episodes = series.GetRecursiveChildren(i => i is Episode)
- .Cast<Episode>()
- .ToList();
-
- var physicalEpisodes = episodes.Where(i => i.LocationType != LocationType.Virtual)
- .ToList();
-
- series.SpecialFeatureIds = physicalEpisodes
- .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
- .Select(i => i.Id)
- .ToList();
-
- numComplete++;
- double percent = numComplete;
- percent /= seriesList.Count;
- percent *= 100;
-
- progress.Report(percent);
- }
+ return new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization, _fileSystem).Run(seriesGroups, true, cancellationToken);
}
internal static IEnumerable<IGrouping<string, Series>> FindSeriesGroups(List<Series> seriesList)
diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs
index bc9842b73..748124c03 100644
--- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs
@@ -91,6 +91,13 @@ namespace MediaBrowser.Providers.TV
var response = await GetEpisodeInfo(seriesTmdbId, seasonNumber.Value, episodeNumber.Value, info.MetadataLanguage, cancellationToken).ConfigureAwait(false);
result.HasMetadata = true;
+ result.QueriedById = true;
+
+ if (!string.IsNullOrEmpty(response.overview))
+ {
+ // if overview is non-empty, we can assume that localized data was returned
+ result.ResultLanguage = info.MetadataLanguage;
+ }
var item = new Episode();
result.Item = item;
diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs
index 3245a2c85..fb0678029 100644
--- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbSeriesProvider.cs
@@ -119,6 +119,7 @@ namespace MediaBrowser.Providers.TV
public async Task<MetadataResult<Series>> GetMetadata(SeriesInfo info, CancellationToken cancellationToken)
{
var result = new MetadataResult<Series>();
+ result.QueriedById = true;
var tmdbId = info.GetProviderId(MetadataProviders.Tmdb);
@@ -154,6 +155,7 @@ namespace MediaBrowser.Providers.TV
if (string.IsNullOrEmpty(tmdbId))
{
+ result.QueriedById = false;
var searchResults = await new MovieDbSearch(_logger, _jsonSerializer, _libraryManager).GetSearchResults(info, cancellationToken).ConfigureAwait(false);
var searchResult = searchResults.FirstOrDefault();
@@ -168,7 +170,7 @@ namespace MediaBrowser.Providers.TV
{
cancellationToken.ThrowIfCancellationRequested();
- result.Item = await FetchSeriesData(tmdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
+ result = await FetchMovieData(tmdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
result.HasMetadata = result.Item != null;
}
@@ -176,7 +178,7 @@ namespace MediaBrowser.Providers.TV
return result;
}
- private async Task<Series> FetchSeriesData(string tmdbId, string language, string preferredCountryCode, CancellationToken cancellationToken)
+ private async Task<MetadataResult<Series>> FetchMovieData(string tmdbId, string language, string preferredCountryCode, CancellationToken cancellationToken)
{
string dataFilePath = null;
RootObject seriesInfo = null;
@@ -194,16 +196,18 @@ namespace MediaBrowser.Providers.TV
tmdbId = seriesInfo.id.ToString(_usCulture);
dataFilePath = GetDataFilePath(tmdbId, language);
- _fileSystem.CreateDirectory(Path.GetDirectoryName(dataFilePath));
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(dataFilePath));
_jsonSerializer.SerializeToFile(seriesInfo, dataFilePath);
await EnsureSeriesInfo(tmdbId, language, cancellationToken).ConfigureAwait(false);
- var item = new Series();
+ var result = new MetadataResult<Series>();
+ result.Item = new Series();
+ result.ResultLanguage = seriesInfo.ResultLanguage;
- ProcessMainInfo(item, seriesInfo, preferredCountryCode);
+ ProcessMainInfo(result.Item, seriesInfo, preferredCountryCode);
- return item;
+ return result;
}
private void ProcessMainInfo(Series series, RootObject seriesInfo, string preferredCountryCode)
@@ -324,7 +328,7 @@ namespace MediaBrowser.Providers.TV
var dataFilePath = GetDataFilePath(id, preferredMetadataLanguage);
- _fileSystem.CreateDirectory(Path.GetDirectoryName(dataFilePath));
+ _fileSystem.CreateDirectory(Path.GetDirectoryName(dataFilePath));
_jsonSerializer.SerializeToFile(mainResult, dataFilePath);
}
@@ -354,6 +358,11 @@ namespace MediaBrowser.Providers.TV
}).ConfigureAwait(false))
{
mainResult = _jsonSerializer.DeserializeFromStream<RootObject>(json);
+
+ if (!string.IsNullOrEmpty(language))
+ {
+ mainResult.ResultLanguage = language;
+ }
}
cancellationToken.ThrowIfCancellationRequested();
@@ -385,6 +394,7 @@ namespace MediaBrowser.Providers.TV
var englishResult = _jsonSerializer.DeserializeFromStream<RootObject>(json);
mainResult.overview = englishResult.overview;
+ mainResult.ResultLanguage = "en";
}
}
@@ -627,6 +637,7 @@ namespace MediaBrowser.Providers.TV
public ExternalIds external_ids { get; set; }
public Videos videos { get; set; }
public ContentRatings content_ratings { get; set; }
+ public string ResultLanguage { get; set; }
}
public int Order
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs
index a41a95c12..41a2282d8 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs
@@ -108,6 +108,7 @@ namespace MediaBrowser.Providers.TV
public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo searchInfo, CancellationToken cancellationToken)
{
var result = new MetadataResult<Episode>();
+ result.QueriedById = true;
if (TvdbSeriesProvider.IsValidSeries(searchInfo.SeriesProviderIds) &&
(searchInfo.IndexNumber.HasValue || searchInfo.PremiereDate.HasValue))
@@ -715,6 +716,17 @@ namespace MediaBrowser.Providers.TV
break;
}
+ case "Language":
+ {
+ var val = reader.ReadElementContentAsString();
+
+ if (!string.IsNullOrWhiteSpace(val))
+ {
+ result.ResultLanguage = val;
+ }
+
+ break;
+ }
default:
reader.Skip();
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs
index 215e0640f..d9e1037d8 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbPrescanTask.cs
@@ -74,12 +74,6 @@ namespace MediaBrowser.Providers.TV
/// <returns>Task.</returns>
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
- if (!_config.Configuration.EnableInternetProviders)
- {
- progress.Report(100);
- return;
- }
-
var seriesConfig = _config.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, typeof(Series).Name, StringComparison.OrdinalIgnoreCase));
if (seriesConfig != null && seriesConfig.DisabledMetadataFetchers.Contains(TvdbSeriesProvider.Current.Name, StringComparer.OrdinalIgnoreCase))
@@ -116,7 +110,9 @@ namespace MediaBrowser.Providers.TV
IncludeItemTypes = new[] { typeof(Series).Name },
Recursive = true,
GroupByPresentationUniqueKey = false
- }).Cast<Series>();
+
+ }).Cast<Series>()
+ .ToList();
var seriesIdsInLibrary = seriesList
.Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb)))
@@ -126,6 +122,13 @@ namespace MediaBrowser.Providers.TV
var missingSeries = seriesIdsInLibrary.Except(existingDirectories, StringComparer.OrdinalIgnoreCase)
.ToList();
+ var enableInternetProviders = seriesList.Count == 0 ? false : seriesList[0].IsInternetMetadataEnabled();
+ if (!enableInternetProviders)
+ {
+ progress.Report(100);
+ return;
+ }
+
// If this is our first time, update all series
if (string.IsNullOrEmpty(lastUpdateTime))
{
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
index 66a02eba2..2572a4f58 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
@@ -21,6 +21,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using CommonIO;
+using MediaBrowser.Common.IO;
namespace MediaBrowser.Providers.TV
{
@@ -38,8 +39,9 @@ namespace MediaBrowser.Providers.TV
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager;
+ private readonly IMemoryStreamProvider _memoryStreamProvider;
- public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager)
+ public TvdbSeriesProvider(IZipClient zipClient, IHttpClient httpClient, IFileSystem fileSystem, IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IMemoryStreamProvider memoryStreamProvider)
{
_zipClient = zipClient;
_httpClient = httpClient;
@@ -47,6 +49,7 @@ namespace MediaBrowser.Providers.TV
_config = config;
_logger = logger;
_libraryManager = libraryManager;
+ _memoryStreamProvider = memoryStreamProvider;
Current = this;
}
@@ -93,9 +96,11 @@ namespace MediaBrowser.Providers.TV
public async Task<MetadataResult<Series>> GetMetadata(SeriesInfo itemId, CancellationToken cancellationToken)
{
var result = new MetadataResult<Series>();
+ result.QueriedById = true;
if (!IsValidSeries(itemId.ProviderIds))
{
+ result.QueriedById = false;
await Identify(itemId).ConfigureAwait(false);
}
@@ -159,7 +164,7 @@ namespace MediaBrowser.Providers.TV
var seriesXmlPath = GetSeriesXmlPath(seriesProviderIds, metadataLanguage);
var actorsXmlPath = Path.Combine(seriesDataPath, "actors.xml");
- FetchSeriesInfo(series, seriesXmlPath, cancellationToken);
+ FetchSeriesInfo(result, seriesXmlPath, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
@@ -236,7 +241,7 @@ namespace MediaBrowser.Providers.TV
DeleteXmlFiles(seriesDataPath);
// Copy to memory stream because we need a seekable stream
- using (var ms = new MemoryStream())
+ using (var ms = _memoryStreamProvider.CreateNew())
{
await zipStream.CopyToAsync(ms).ConfigureAwait(false);
@@ -607,7 +612,7 @@ namespace MediaBrowser.Providers.TV
return name.Trim();
}
- private void FetchSeriesInfo(Series item, string seriesXmlPath, CancellationToken cancellationToken)
+ private void FetchSeriesInfo(MetadataResult<Series> result, string seriesXmlPath, CancellationToken cancellationToken)
{
var settings = new XmlReaderSettings
{
@@ -639,7 +644,7 @@ namespace MediaBrowser.Providers.TV
{
using (var subtree = reader.ReadSubtree())
{
- FetchDataFromSeriesNode(item, subtree, cancellationToken);
+ FetchDataFromSeriesNode(result, subtree, cancellationToken);
}
break;
}
@@ -667,9 +672,9 @@ namespace MediaBrowser.Providers.TV
}
}
- if (item.Status.HasValue && item.Status.Value == SeriesStatus.Ended && episiodeAirDates.Count > 0)
+ if (result.Item.Status.HasValue && result.Item.Status.Value == SeriesStatus.Ended && episiodeAirDates.Count > 0)
{
- item.EndDate = episiodeAirDates.Max();
+ result.Item.EndDate = episiodeAirDates.Max();
}
}
@@ -861,8 +866,10 @@ namespace MediaBrowser.Providers.TV
}
}
- private void FetchDataFromSeriesNode(Series item, XmlReader reader, CancellationToken cancellationToken)
+ private void FetchDataFromSeriesNode(MetadataResult<Series> result, XmlReader reader, CancellationToken cancellationToken)
{
+ Series item = result.Item;
+
reader.MoveToContent();
// Loop through each element
@@ -886,6 +893,12 @@ namespace MediaBrowser.Providers.TV
break;
}
+ case "Language":
+ {
+ result.ResultLanguage = (reader.ReadElementContentAsString() ?? string.Empty).Trim();
+ break;
+ }
+
case "Airs_DayOfWeek":
{
var val = reader.ReadElementContentAsString();