support backdrops from multiple sources
This commit is contained in:
parent
96fd6459b2
commit
32cb872b06
|
@ -699,11 +699,32 @@ namespace MediaBrowser.Api.Images
|
|||
var temp1 = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp");
|
||||
var temp2 = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + ".tmp");
|
||||
|
||||
// Copying over will fail against hidden files
|
||||
RemoveHiddenAttribute(file1);
|
||||
RemoveHiddenAttribute(file2);
|
||||
|
||||
File.Copy(file1, temp1);
|
||||
File.Copy(file2, temp2);
|
||||
|
||||
File.Copy(temp1, file2, true);
|
||||
File.Copy(temp2, file1, true);
|
||||
|
||||
File.Delete(temp1);
|
||||
File.Delete(temp2);
|
||||
}
|
||||
|
||||
private void RemoveHiddenAttribute(string path)
|
||||
{
|
||||
var currentFile = new FileInfo(path);
|
||||
|
||||
// This will fail if the file is hidden
|
||||
if (currentFile.Exists)
|
||||
{
|
||||
if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
|
||||
{
|
||||
currentFile.Attributes &= ~FileAttributes.Hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -854,7 +875,7 @@ namespace MediaBrowser.Api.Images
|
|||
// Handle image/png; charset=utf-8
|
||||
mimeType = mimeType.Split(';').FirstOrDefault();
|
||||
|
||||
await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, imageIndex, CancellationToken.None).ConfigureAwait(false);
|
||||
await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, imageIndex, null, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
await entity.RefreshMetadata(CancellationToken.None, forceRefresh: true, forceSave: true, allowSlowProviders: false).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
LockedFields = new List<MetadataFields>();
|
||||
Taglines = new List<string>();
|
||||
RemoteTrailers = new List<MediaUrl>();
|
||||
ImageSources = new List<ImageSourceInfo>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -233,23 +234,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <value>The locked fields.</value>
|
||||
public List<MetadataFields> LockedFields { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the item has a saved local image of the specified name (jpg or png).
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns><c>true</c> if [has local image] [the specified item]; otherwise, <c>false</c>.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">name</exception>
|
||||
public bool HasLocalImage(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
return ResolveArgs.ContainsMetaFileByName(name + ".jpg") ||
|
||||
ResolveArgs.ContainsMetaFileByName(name + ".png");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be overridden to return the proper folder where metadata lives
|
||||
/// </summary>
|
||||
|
@ -536,6 +520,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// <value>The backdrop image paths.</value>
|
||||
public List<string> BackdropImagePaths { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the backdrop image sources.
|
||||
/// </summary>
|
||||
/// <value>The backdrop image sources.</value>
|
||||
public List<ImageSourceInfo> ImageSources { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the screenshot image paths.
|
||||
/// </summary>
|
||||
|
@ -1508,8 +1498,10 @@ namespace MediaBrowser.Controller.Entities
|
|||
|
||||
BackdropImagePaths.Remove(file);
|
||||
|
||||
RemoveImageSourceForPath(file);
|
||||
|
||||
// Delete the source file
|
||||
File.Delete(file);
|
||||
DeleteImagePath(file);
|
||||
}
|
||||
else if (type == ImageType.Screenshot)
|
||||
{
|
||||
|
@ -1523,12 +1515,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
ScreenshotImagePaths.Remove(file);
|
||||
|
||||
// Delete the source file
|
||||
File.Delete(file);
|
||||
DeleteImagePath(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete the source file
|
||||
File.Delete(GetImage(type));
|
||||
DeleteImagePath(GetImage(type));
|
||||
|
||||
// Remove it from the item
|
||||
SetImage(type, null);
|
||||
|
@ -1538,6 +1530,26 @@ namespace MediaBrowser.Controller.Entities
|
|||
return RefreshMetadata(CancellationToken.None, forceSave: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the image path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
private void DeleteImagePath(string path)
|
||||
{
|
||||
var currentFile = new FileInfo(path);
|
||||
|
||||
// This will fail if the file is hidden
|
||||
if (currentFile.Exists)
|
||||
{
|
||||
if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
|
||||
{
|
||||
currentFile.Attributes &= ~FileAttributes.Hidden;
|
||||
}
|
||||
|
||||
currentFile.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that images within the item are still on the file system
|
||||
/// </summary>
|
||||
|
@ -1570,9 +1582,85 @@ namespace MediaBrowser.Controller.Entities
|
|||
foreach (var path in deletedImages)
|
||||
{
|
||||
BackdropImagePaths.Remove(path);
|
||||
|
||||
RemoveImageSourceForPath(path);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the image source.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="url">The URL.</param>
|
||||
public void AddImageSource(string path, string url)
|
||||
{
|
||||
RemoveImageSourceForPath(path);
|
||||
|
||||
var pathMd5 = path.ToLower().GetMD5();
|
||||
|
||||
ImageSources.Add(new ImageSourceInfo
|
||||
{
|
||||
ImagePathMD5 = pathMd5,
|
||||
ImageUrlMD5 = url.ToLower().GetMD5()
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image source info.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>ImageSourceInfo.</returns>
|
||||
public ImageSourceInfo GetImageSourceInfo(string path)
|
||||
{
|
||||
if (ImageSources.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var pathMd5 = path.ToLower().GetMD5();
|
||||
|
||||
return ImageSources.FirstOrDefault(i => i.ImagePathMD5 == pathMd5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the image source for path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
public void RemoveImageSourceForPath(string path)
|
||||
{
|
||||
if (ImageSources.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pathMd5 = path.ToLower().GetMD5();
|
||||
|
||||
// Remove existing
|
||||
foreach (var entry in ImageSources
|
||||
.Where(i => i.ImagePathMD5 == pathMd5)
|
||||
.ToList())
|
||||
{
|
||||
ImageSources.Remove(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [contains image with source URL] [the specified URL].
|
||||
/// </summary>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <returns><c>true</c> if [contains image with source URL] [the specified URL]; otherwise, <c>false</c>.</returns>
|
||||
public bool ContainsImageWithSourceUrl(string url)
|
||||
{
|
||||
if (ImageSources.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var md5 = url.ToLower().GetMD5();
|
||||
|
||||
return ImageSources.Any(i => i.ImageUrlMD5 == md5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the screenshots.
|
||||
/// </summary>
|
||||
|
|
10
MediaBrowser.Controller/Entities/ImageSourceInfo.cs
Normal file
10
MediaBrowser.Controller/Entities/ImageSourceInfo.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public class ImageSourceInfo
|
||||
{
|
||||
public Guid ImagePathMD5 { get; set; }
|
||||
public Guid ImageUrlMD5 { get; set; }
|
||||
}
|
||||
}
|
|
@ -91,6 +91,7 @@
|
|||
<Compile Include="Entities\IByReferenceItem.cs" />
|
||||
<Compile Include="Entities\IItemByName.cs" />
|
||||
<Compile Include="Entities\ILibraryItem.cs" />
|
||||
<Compile Include="Entities\ImageSourceInfo.cs" />
|
||||
<Compile Include="Entities\LinkedChild.cs" />
|
||||
<Compile Include="Entities\MusicVideo.cs" />
|
||||
<Compile Include="Library\ILibraryPostScanTask.cs" />
|
||||
|
|
|
@ -43,9 +43,10 @@ namespace MediaBrowser.Controller.Providers
|
|||
/// <param name="mimeType">Type of the MIME.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <param name="sourceUrl">The source URL.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken);
|
||||
Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, string sourceUrl, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the metadata providers.
|
||||
|
|
|
@ -233,6 +233,12 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// <value>The width of the min movie backdrop.</value>
|
||||
public int MinMovieBackdropWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width of the min series backdrop.
|
||||
/// </summary>
|
||||
/// <value>The width of the min series backdrop.</value>
|
||||
public int MinSeriesBackdropWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width of the min movie poster.
|
||||
/// </summary>
|
||||
|
@ -286,6 +292,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
SeasonZeroDisplayName = "Specials";
|
||||
|
||||
MinMovieBackdropWidth = 1920;
|
||||
MinSeriesBackdropWidth = 1920;
|
||||
MinMoviePosterWidth = 1000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
item.HasImage(ImageType.Disc) &&
|
||||
item.HasImage(ImageType.Banner) &&
|
||||
item.HasImage(ImageType.Thumb) &&
|
||||
item.BackdropImagePaths.Count > 0)
|
||||
item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -389,7 +389,8 @@ namespace MediaBrowser.Providers.Movies
|
|||
}
|
||||
}
|
||||
|
||||
if (ConfigurationManager.Configuration.DownloadMovieImages.Backdrops && item.BackdropImagePaths.Count == 0)
|
||||
var backdropLimit = ConfigurationManager.Configuration.MaxBackdrops;
|
||||
if (ConfigurationManager.Configuration.DownloadMovieImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit)
|
||||
{
|
||||
var nodes = doc.SelectNodes("//fanart/movie/moviebackgrounds//@url");
|
||||
|
||||
|
@ -401,14 +402,14 @@ namespace MediaBrowser.Providers.Movies
|
|||
{
|
||||
path = node.Value;
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
if (!string.IsNullOrEmpty(path) && !item.ContainsImageWithSourceUrl(path))
|
||||
{
|
||||
await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Backdrop, numBackdrops, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
numBackdrops++;
|
||||
|
||||
if (item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops) break;
|
||||
if (item.BackdropImagePaths.Count >= backdropLimit) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ using MediaBrowser.Model.Logging;
|
|||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -135,7 +134,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
}
|
||||
|
||||
// Don't refresh if we already have both poster and backdrop and we're not refreshing images
|
||||
if (item.HasImage(ImageType.Primary) && item.BackdropImagePaths.Count > 0)
|
||||
if (item.HasImage(ImageType.Primary) && item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -239,14 +238,16 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
if (poster != null)
|
||||
{
|
||||
var url = tmdbImageUrl + poster.file_path;
|
||||
|
||||
var img = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
|
||||
{
|
||||
Url = tmdbImageUrl + poster.file_path,
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(poster.file_path), ImageType.Primary, null, cancellationToken)
|
||||
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(poster.file_path), ImageType.Primary, null, url, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
}
|
||||
|
@ -258,8 +259,10 @@ namespace MediaBrowser.Providers.Movies
|
|||
images.backdrops.Where(i => i.width >= ConfigurationManager.Configuration.MinMovieBackdropWidth)
|
||||
.ToList();
|
||||
|
||||
var backdropLimit = ConfigurationManager.Configuration.MaxBackdrops;
|
||||
|
||||
// backdrops - only download if earlier providers didn't find any (fanart)
|
||||
if (eligibleBackdrops.Count > 0 && ConfigurationManager.Configuration.DownloadMovieImages.Backdrops && item.BackdropImagePaths.Count == 0)
|
||||
if (eligibleBackdrops.Count > 0 && ConfigurationManager.Configuration.DownloadMovieImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit)
|
||||
{
|
||||
var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -267,24 +270,22 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
for (var i = 0; i < eligibleBackdrops.Count; i++)
|
||||
{
|
||||
var bdName = "backdrop" + (i == 0 ? "" : i.ToString(CultureInfo.InvariantCulture));
|
||||
var url = tmdbImageUrl + eligibleBackdrops[i].file_path;
|
||||
|
||||
var hasLocalBackdrop = item.LocationType == LocationType.FileSystem && ConfigurationManager.Configuration.SaveLocalMeta ? item.HasLocalImage(bdName) : item.BackdropImagePaths.Count > i;
|
||||
|
||||
if (!hasLocalBackdrop)
|
||||
if (!item.ContainsImageWithSourceUrl(url))
|
||||
{
|
||||
var img = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
|
||||
{
|
||||
Url = tmdbImageUrl + eligibleBackdrops[i].file_path,
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(eligibleBackdrops[i].file_path), ImageType.Backdrop, item.BackdropImagePaths.Count, cancellationToken)
|
||||
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(eligibleBackdrops[i].file_path), ImageType.Backdrop, item.BackdropImagePaths.Count, url, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops)
|
||||
if (item.BackdropImagePaths.Count >= backdropLimit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -513,7 +513,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
{
|
||||
var isBoxSet = item is BoxSet;
|
||||
|
||||
var mainResult = await FetchMainResult(id, isBoxSet, cancellationToken).ConfigureAwait(false);
|
||||
var mainResult = await FetchMainResult(id, isBoxSet, language, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (mainResult == null) return;
|
||||
|
||||
|
@ -550,7 +550,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
{
|
||||
var language = ConfigurationManager.Configuration.PreferredMetadataLanguage;
|
||||
|
||||
var mainResult = await FetchMainResult(id, isBoxSet, cancellationToken).ConfigureAwait(false);
|
||||
var mainResult = await FetchMainResult(id, isBoxSet, language, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (mainResult == null) return;
|
||||
|
||||
|
@ -588,13 +588,14 @@ namespace MediaBrowser.Providers.Movies
|
|||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="isBoxSet">if set to <c>true</c> [is box set].</param>
|
||||
/// <param name="language">The language.</param>
|
||||
/// <param name="cancellationToken">The cancellation token</param>
|
||||
/// <returns>Task{CompleteMovieData}.</returns>
|
||||
protected async Task<CompleteMovieData> FetchMainResult(string id, bool isBoxSet, CancellationToken cancellationToken)
|
||||
protected async Task<CompleteMovieData> FetchMainResult(string id, bool isBoxSet, string language, CancellationToken cancellationToken)
|
||||
{
|
||||
var baseUrl = isBoxSet ? GetBoxSetInfo3 : GetMovieInfo3;
|
||||
|
||||
string url = string.Format(baseUrl, id, ApiKey, ConfigurationManager.Configuration.PreferredMetadataLanguage);
|
||||
string url = string.Format(baseUrl, id, ApiKey, language);
|
||||
CompleteMovieData mainResult;
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
@ -614,13 +615,13 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
if (mainResult != null && string.IsNullOrEmpty(mainResult.overview))
|
||||
{
|
||||
if (ConfigurationManager.Configuration.PreferredMetadataLanguage.ToLower() != "en")
|
||||
if (language.ToLower() != "en")
|
||||
{
|
||||
Logger.Info("MovieDbProvider couldn't find meta for language " + ConfigurationManager.Configuration.PreferredMetadataLanguage + ". Trying English...");
|
||||
Logger.Info("MovieDbProvider couldn't find meta for language " + language + ". Trying English...");
|
||||
|
||||
url = string.Format(baseUrl, id, ApiKey, "en");
|
||||
|
||||
using (Stream json = await GetMovieDbResponse(new HttpRequestOptions
|
||||
using (var json = await GetMovieDbResponse(new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken,
|
||||
|
|
|
@ -390,7 +390,7 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
}).ConfigureAwait(false))
|
||||
{
|
||||
await ProviderManager.SaveImage(item, sourceStream, mimeType, ImageType.Primary, null, cancellationToken)
|
||||
await ProviderManager.SaveImage(item, sourceStream, mimeType, ImageType.Primary, null, source, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Logger.Debug("TmdbPersonProvider downloaded and saved image for {0}", item.Name);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
|
|
|
@ -332,6 +332,8 @@ namespace MediaBrowser.Providers.Music
|
|||
}
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var backdropLimit = ConfigurationManager.Configuration.MaxBackdrops;
|
||||
|
||||
if (ConfigurationManager.Configuration.DownloadMusicArtistImages.Backdrops && item.BackdropImagePaths.Count == 0)
|
||||
{
|
||||
var nodes = doc.SelectNodes("//fanart/music/artistbackgrounds//@url");
|
||||
|
@ -342,14 +344,14 @@ namespace MediaBrowser.Providers.Music
|
|||
foreach (XmlNode node in nodes)
|
||||
{
|
||||
path = node.Value;
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
if (!string.IsNullOrEmpty(path) && !item.ContainsImageWithSourceUrl(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Backdrop, numBackdrops, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
numBackdrops++;
|
||||
if (numBackdrops >= ConfigurationManager.Configuration.MaxBackdrops) break;
|
||||
if (numBackdrops >= backdropLimit) break;
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace MediaBrowser.Providers.TV
|
|||
item.HasImage(ImageType.Logo) &&
|
||||
item.HasImage(ImageType.Banner) &&
|
||||
item.HasImage(ImageType.Thumb) &&
|
||||
item.BackdropImagePaths.Count > 0)
|
||||
item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -298,7 +298,9 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
}
|
||||
|
||||
if (ConfigurationManager.Configuration.DownloadMovieImages.Backdrops && item.BackdropImagePaths.Count == 0)
|
||||
var backdropLimit = ConfigurationManager.Configuration.MaxBackdrops;
|
||||
|
||||
if (ConfigurationManager.Configuration.DownloadMovieImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit)
|
||||
{
|
||||
var nodes = doc.SelectNodes("//fanart/series/showbackgrounds//@url");
|
||||
|
||||
|
@ -310,14 +312,14 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
var path = node.Value;
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
if (!string.IsNullOrEmpty(path) && !item.ContainsImageWithSourceUrl(path))
|
||||
{
|
||||
await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Backdrop, numBackdrops, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
numBackdrops++;
|
||||
|
||||
if (item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops) break;
|
||||
if (item.BackdropImagePaths.Count >= backdropLimit) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,15 @@ namespace MediaBrowser.Providers.TV
|
|||
return false;
|
||||
}
|
||||
|
||||
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
|
||||
{
|
||||
if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Banner) && item.BackdropImagePaths.Count > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return base.NeedsRefreshInternal(item, providerInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
|
||||
/// </summary>
|
||||
|
@ -146,7 +155,7 @@ namespace MediaBrowser.Providers.TV
|
|||
try
|
||||
{
|
||||
var fanartData = FetchFanartXmlData(imagesXmlPath, seasonNumber.Value, cancellationToken);
|
||||
await DownloadImages(item, fanartData, ConfigurationManager.Configuration.MaxBackdrops, cancellationToken).ConfigureAwait(false);
|
||||
await DownloadImages(item, fanartData, 1, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
|
@ -186,13 +195,18 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
}
|
||||
|
||||
if (ConfigurationManager.Configuration.DownloadSeasonImages.Backdrops && item.BackdropImagePaths.Count == 0)
|
||||
if (ConfigurationManager.Configuration.DownloadSeasonImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit)
|
||||
{
|
||||
var bdNo = item.BackdropImagePaths.Count;
|
||||
|
||||
foreach (var backdrop in data.Backdrops)
|
||||
{
|
||||
var url = TVUtils.BannerUrl + backdrop;
|
||||
var url = TVUtils.BannerUrl + backdrop.Url;
|
||||
|
||||
if (item.ContainsImageWithSourceUrl(url))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await _providerManager.SaveImage(item, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, bdNo, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
@ -260,6 +274,7 @@ namespace MediaBrowser.Providers.TV
|
|||
string bannerType2 = null;
|
||||
string url = null;
|
||||
int? bannerSeason = null;
|
||||
string resolution = null;
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
|
@ -319,7 +334,11 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
else if (string.Equals(bannerType, "fanart", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
data.Backdrops.Add(url);
|
||||
data.Backdrops.Add(new ImageInfo
|
||||
{
|
||||
Url = url,
|
||||
Resolution = resolution
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
|
@ -133,6 +134,15 @@ namespace MediaBrowser.Providers.TV
|
|||
return base.CompareDate(item);
|
||||
}
|
||||
|
||||
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
|
||||
{
|
||||
if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Banner) && item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return base.NeedsRefreshInternal(item, providerInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
|
||||
/// </summary>
|
||||
|
@ -154,10 +164,10 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
var imagesXmlPath = Path.Combine(seriesDataPath, "banners.xml");
|
||||
|
||||
if (!series.HasImage(ImageType.Primary) || !series.HasImage(ImageType.Banner) || series.BackdropImagePaths.Count == 0)
|
||||
{
|
||||
var backdropLimit = ConfigurationManager.Configuration.MaxBackdrops;
|
||||
var backdropLimit = ConfigurationManager.Configuration.MaxBackdrops;
|
||||
|
||||
if (!series.HasImage(ImageType.Primary) || !series.HasImage(ImageType.Banner) || series.BackdropImagePaths.Count < backdropLimit)
|
||||
{
|
||||
Directory.CreateDirectory(seriesDataPath);
|
||||
|
||||
try
|
||||
|
@ -171,13 +181,6 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
}
|
||||
|
||||
BaseProviderInfo data;
|
||||
if (!item.ProviderData.TryGetValue(Id, out data))
|
||||
{
|
||||
data = new BaseProviderInfo();
|
||||
item.ProviderData[Id] = data;
|
||||
}
|
||||
|
||||
SetLastRefreshed(item, DateTime.UtcNow);
|
||||
return true;
|
||||
}
|
||||
|
@ -213,13 +216,39 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
}
|
||||
|
||||
if (ConfigurationManager.Configuration.DownloadSeriesImages.Backdrops && item.BackdropImagePaths.Count == 0)
|
||||
if (ConfigurationManager.Configuration.DownloadSeriesImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit)
|
||||
{
|
||||
var bdNo = item.BackdropImagePaths.Count;
|
||||
|
||||
foreach (var backdrop in data.Backdrops)
|
||||
var eligibleBackdrops = data.Backdrops
|
||||
.Where(i =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(i.Resolution))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var parts = i.Resolution.Split('x');
|
||||
|
||||
int width;
|
||||
|
||||
if (int.TryParse(parts[0], NumberStyles.Any, UsCulture, out width))
|
||||
{
|
||||
return width >= ConfigurationManager.Configuration.MinSeriesBackdropWidth;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
.ToList();
|
||||
|
||||
foreach (var backdrop in eligibleBackdrops)
|
||||
{
|
||||
var url = TVUtils.BannerUrl + backdrop;
|
||||
var url = TVUtils.BannerUrl + backdrop.Url;
|
||||
|
||||
if (item.ContainsImageWithSourceUrl(url))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await _providerManager.SaveImage(item, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, bdNo, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
@ -285,6 +314,7 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
string type = null;
|
||||
string url = null;
|
||||
string resolution = null;
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
|
@ -312,13 +342,6 @@ namespace MediaBrowser.Providers.TV
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (string.Equals(type, "fanart", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (data.Backdrops.Count >= backdropLimit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
|
@ -333,6 +356,12 @@ namespace MediaBrowser.Providers.TV
|
|||
break;
|
||||
}
|
||||
|
||||
case "BannerType2":
|
||||
{
|
||||
resolution = reader.ReadElementContentAsString() ?? string.Empty;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
|
@ -352,7 +381,11 @@ namespace MediaBrowser.Providers.TV
|
|||
}
|
||||
else if (string.Equals(type, "fanart", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
data.Backdrops.Add(url);
|
||||
data.Backdrops.Add(new ImageInfo
|
||||
{
|
||||
Url = url,
|
||||
Resolution = resolution
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -364,6 +397,12 @@ namespace MediaBrowser.Providers.TV
|
|||
public string LanguageBanner { get; set; }
|
||||
public string Poster { get; set; }
|
||||
public string Banner { get; set; }
|
||||
public List<string> Backdrops = new List<string>();
|
||||
public List<ImageInfo> Backdrops = new List<ImageInfo>();
|
||||
}
|
||||
|
||||
internal class ImageInfo
|
||||
{
|
||||
public string Url { get; set; }
|
||||
public string Resolution { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,10 +90,22 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
|
|||
MergeImages(musicArtist.Images, artist.Images);
|
||||
|
||||
// Merge backdrops
|
||||
var backdrops = musicArtist.BackdropImagePaths.ToList();
|
||||
backdrops.InsertRange(0, artist.BackdropImagePaths);
|
||||
artist.BackdropImagePaths = backdrops.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
var additionalBackdrops = musicArtist
|
||||
.BackdropImagePaths
|
||||
.Except(artist.BackdropImagePaths)
|
||||
.ToList();
|
||||
|
||||
var sources = additionalBackdrops
|
||||
.Select(musicArtist.GetImageSourceInfo)
|
||||
.ToList();
|
||||
|
||||
foreach (var path in additionalBackdrops)
|
||||
{
|
||||
artist.RemoveImageSourceForPath(path);
|
||||
}
|
||||
|
||||
artist.BackdropImagePaths.AddRange(additionalBackdrops);
|
||||
artist.ImageSources.AddRange(sources);
|
||||
}
|
||||
|
||||
if (!artist.LockedFields.Contains(MetadataFields.Genres))
|
||||
|
|
|
@ -56,9 +56,11 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
/// <param name="mimeType">Type of the MIME.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <param name="sourceUrl">The source URL.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken)
|
||||
/// <exception cref="System.ArgumentNullException">mimeType</exception>
|
||||
public async Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, string sourceUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(mimeType))
|
||||
{
|
||||
|
@ -128,7 +130,7 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
}
|
||||
|
||||
// Set the path into the BaseItem
|
||||
SetImagePath(item, type, imageIndex, paths[0]);
|
||||
SetImagePath(item, type, imageIndex, paths[0], sourceUrl);
|
||||
|
||||
// Delete the current path
|
||||
if (!string.IsNullOrEmpty(currentPath) && !paths.Contains(currentPath, StringComparer.OrdinalIgnoreCase))
|
||||
|
@ -137,7 +139,18 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
|
||||
try
|
||||
{
|
||||
File.Delete(currentPath);
|
||||
var currentFile = new FileInfo(currentPath);
|
||||
|
||||
// This will fail if the file is hidden
|
||||
if (currentFile.Exists)
|
||||
{
|
||||
if ((currentFile.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
|
||||
{
|
||||
currentFile.Attributes &= ~FileAttributes.Hidden;
|
||||
}
|
||||
|
||||
currentFile.Delete();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -244,12 +257,11 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
/// <param name="type">The type.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// imageIndex
|
||||
/// <param name="sourceUrl">The source URL.</param>
|
||||
/// <exception cref="System.ArgumentNullException">imageIndex
|
||||
/// or
|
||||
/// imageIndex
|
||||
/// </exception>
|
||||
private void SetImagePath(BaseItem item, ImageType type, int? imageIndex, string path)
|
||||
/// imageIndex</exception>
|
||||
private void SetImagePath(BaseItem item, ImageType type, int? imageIndex, string path, string sourceUrl)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
@ -282,6 +294,15 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
{
|
||||
item.BackdropImagePaths.Add(path);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(sourceUrl))
|
||||
{
|
||||
item.RemoveImageSourceForPath(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.AddImageSource(path, sourceUrl);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
item.SetImage(type, path);
|
||||
|
|
|
@ -325,7 +325,7 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
await SaveImage(item, response.Content, response.ContentType, type, imageIndex, cancellationToken)
|
||||
await SaveImage(item, response.Content, response.ContentType, type, imageIndex, url, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@ -337,11 +337,12 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
/// <param name="mimeType">Type of the MIME.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <param name="sourceUrl">The source URL.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken)
|
||||
public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, string sourceUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
return new ImageSaver(ConfigurationManager, _directoryWatchers).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken);
|
||||
return new ImageSaver(ConfigurationManager, _directoryWatchers).SaveImage(item, source, mimeType, type, imageIndex, sourceUrl, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,6 +174,11 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
/// <param name="item">The item.</param>
|
||||
private void RemoveNowPlayingItem(SessionInfo session, BaseItem item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException("item");
|
||||
}
|
||||
|
||||
if (session.NowPlayingItem != null && session.NowPlayingItem.Id == item.Id)
|
||||
{
|
||||
session.NowPlayingItem = null;
|
||||
|
@ -319,6 +324,16 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
throw new ArgumentNullException("info");
|
||||
}
|
||||
|
||||
if (info.Item == null)
|
||||
{
|
||||
throw new ArgumentException("PlaybackStopInfo.Item cannot be null");
|
||||
}
|
||||
|
||||
if (info.SessionId == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentException("PlaybackStopInfo.SessionId cannot be Guid.Empty");
|
||||
}
|
||||
|
||||
if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("positionTicks");
|
||||
|
|
Loading…
Reference in New Issue
Block a user