diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 4518ffad00..3074b0d5bc 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -760,145 +760,45 @@ namespace MediaBrowser.Api.Images
var bytes = Convert.FromBase64String(text);
// Validate first
- using (var memoryStream = new MemoryStream(bytes))
+ using (var validationStream = new MemoryStream(bytes))
{
- using (var image = Image.FromStream(memoryStream))
+ using (var image = Image.FromStream(validationStream))
{
Logger.Info("New image is {0}x{1}", image.Width, image.Height);
}
}
- string filename;
+ var memoryStream = new MemoryStream(bytes);
- switch (imageType)
- {
- case ImageType.Art:
- filename = "clearart";
- break;
- case ImageType.Primary:
- filename = entity is Episode ? Path.GetFileNameWithoutExtension(entity.Path) : "folder";
- break;
- case ImageType.Backdrop:
- filename = GetBackdropFilenameToSave(entity);
- break;
- case ImageType.Screenshot:
- filename = GetScreenshotFilenameToSave(entity);
- break;
- default:
- filename = imageType.ToString().ToLower();
- break;
- }
+ memoryStream.Position = 0;
-
- var extension = mimeType.Split(';').First().Split('/').Last();
-
- string oldImagePath;
- switch (imageType)
- {
- case ImageType.Backdrop:
- case ImageType.Screenshot:
- oldImagePath = null;
- break;
- default:
- oldImagePath = entity.GetImage(imageType);
- break;
- }
-
- // Don't save locally if there's no parent (special feature, trailer, etc)
- var saveLocally = !(entity is Audio) && entity.Parent != null && !string.IsNullOrEmpty(entity.MetaLocation) || entity is User;
-
- if (imageType != ImageType.Primary)
- {
- if (entity is Episode)
- {
- saveLocally = false;
- }
- }
-
- if (entity.LocationType != LocationType.FileSystem)
- {
- saveLocally = false;
- }
-
- var imagePath = _providerManager.GetSavePath(entity, filename + "." + extension, saveLocally);
-
- // Save to file system
- using (var fs = new FileStream(imagePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
- {
- await fs.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
- }
+ var imageIndex = 0;
if (imageType == ImageType.Screenshot)
{
- entity.ScreenshotImagePaths.Add(imagePath);
+ imageIndex = entity.ScreenshotImagePaths.Count;
}
else if (imageType == ImageType.Backdrop)
{
- entity.BackdropImagePaths.Add(imagePath);
+ imageIndex = entity.BackdropImagePaths.Count;
+ }
+
+ await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, imageIndex, CancellationToken.None).ConfigureAwait(false);
+
+ var user = entity as User;
+
+ if (user != null)
+ {
+ await _userManager.UpdateUser(user).ConfigureAwait(false);
}
else
{
- // Set the image
- entity.SetImage(imageType, imagePath);
+ await _libraryManager.UpdateItem(entity, ItemUpdateType.ImageUpdate, CancellationToken.None)
+ .ConfigureAwait(false);
}
- // If the new and old paths are different, delete the old one
- if (!string.IsNullOrEmpty(oldImagePath) && !oldImagePath.Equals(imagePath, StringComparison.OrdinalIgnoreCase))
- {
- File.Delete(oldImagePath);
- }
-
- // Directory watchers should repeat this, but do a quick refresh first
- await entity.RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false).ConfigureAwait(false);
+ await entity.RefreshMetadata(CancellationToken.None, allowSlowProviders: false).ConfigureAwait(false);
}
}
-
- ///
- /// Gets the backdrop filename to save.
- ///
- /// The item.
- /// System.String.
- private string GetBackdropFilenameToSave(BaseItem item)
- {
- var paths = item.BackdropImagePaths.ToList();
-
- if (!paths.Any(i => string.Equals(Path.GetFileNameWithoutExtension(i), "backdrop", StringComparison.OrdinalIgnoreCase)))
- {
- return "screenshot";
- }
-
- var index = 1;
-
- while (paths.Any(i => string.Equals(Path.GetFileNameWithoutExtension(i), "backdrop" + index, StringComparison.OrdinalIgnoreCase)))
- {
- index++;
- }
-
- return "backdrop" + index;
- }
-
- ///
- /// Gets the screenshot filename to save.
- ///
- /// The item.
- /// System.String.
- private string GetScreenshotFilenameToSave(BaseItem item)
- {
- var paths = item.ScreenshotImagePaths.ToList();
-
- if (!paths.Any(i => string.Equals(Path.GetFileNameWithoutExtension(i), "screenshot", StringComparison.OrdinalIgnoreCase)))
- {
- return "screenshot";
- }
-
- var index = 1;
-
- while (paths.Any(i => string.Equals(Path.GetFileNameWithoutExtension(i), "screenshot" + index, StringComparison.OrdinalIgnoreCase)))
- {
- index++;
- }
-
- return "screenshot" + index;
- }
}
}
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index f776cf6758..d664d0bba5 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -104,6 +104,92 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
return client;
}
+ public async Task GetResponse(HttpRequestOptions options)
+ {
+ ValidateParams(options.Url, options.CancellationToken);
+
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ var client = GetHttpClient(GetHostFromUrl(options.Url), options.EnableHttpCompression);
+
+ if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < 30)
+ {
+ throw new HttpException(string.Format("Cancelling connection to {0} due to a previous timeout.", options.Url)) { IsTimedOut = true };
+ }
+
+ using (var message = GetHttpRequestMessage(options))
+ {
+ if (options.ResourcePool != null)
+ {
+ await options.ResourcePool.WaitAsync(options.CancellationToken).ConfigureAwait(false);
+ }
+
+ if ((DateTime.UtcNow - client.LastTimeout).TotalSeconds < 30)
+ {
+ if (options.ResourcePool != null)
+ {
+ options.ResourcePool.Release();
+ }
+
+ throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
+ }
+
+ _logger.Info("HttpClientManager.Get url: {0}", options.Url);
+
+ try
+ {
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ var response = await client.HttpClient.SendAsync(message, HttpCompletionOption.ResponseContentRead, options.CancellationToken).ConfigureAwait(false);
+
+ EnsureSuccessStatusCode(response);
+
+ options.CancellationToken.ThrowIfCancellationRequested();
+
+ return new HttpResponseInfo
+ {
+ Content = await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
+
+ StatusCode = response.StatusCode,
+
+ ContentType = response.Content.Headers.ContentType.MediaType
+ };
+ }
+ catch (OperationCanceledException ex)
+ {
+ var exception = GetCancellationException(options.Url, options.CancellationToken, ex);
+
+ var httpException = exception as HttpException;
+
+ if (httpException != null && httpException.IsTimedOut)
+ {
+ client.LastTimeout = DateTime.UtcNow;
+ }
+
+ throw exception;
+ }
+ catch (HttpRequestException ex)
+ {
+ _logger.ErrorException("Error getting response from " + options.Url, ex);
+
+ throw new HttpException(ex.Message, ex);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting response from " + options.Url, ex);
+
+ throw;
+ }
+ finally
+ {
+ if (options.ResourcePool != null)
+ {
+ options.ResourcePool.Release();
+ }
+ }
+ }
+ }
+
///
/// Performs a GET request and returns the resulting stream
///
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpResponseInfo.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpResponseInfo.cs
deleted file mode 100644
index 4a4612ffb5..0000000000
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpResponseInfo.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System;
-
-namespace MediaBrowser.Common.Implementations.HttpClientManager
-{
- ///
- /// Class HttpResponseOutput
- ///
- public class HttpResponseInfo
- {
- ///
- /// Gets or sets the URL.
- ///
- /// The URL.
- public string Url { get; set; }
-
- ///
- /// Gets or sets the etag.
- ///
- /// The etag.
- public string Etag { get; set; }
-
- ///
- /// Gets or sets the last modified.
- ///
- /// The last modified.
- public DateTime? LastModified { get; set; }
-
- ///
- /// Gets or sets the expires.
- ///
- /// The expires.
- public DateTime? Expires { get; set; }
-
- ///
- /// Gets or sets a value indicating whether [must revalidate].
- ///
- /// true if [must revalidate]; otherwise, false.
- public bool MustRevalidate { get; set; }
-
- ///
- /// Gets or sets the request date.
- ///
- /// The request date.
- public DateTime RequestDate { get; set; }
- }
-}
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index d804f6f1c7..e2a56e9120 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -66,7 +66,6 @@
-
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index 69439c5733..9a81537bff 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -74,6 +74,7 @@
+
diff --git a/MediaBrowser.Common/Net/HttpResponseInfo.cs b/MediaBrowser.Common/Net/HttpResponseInfo.cs
new file mode 100644
index 0000000000..558218ed16
--- /dev/null
+++ b/MediaBrowser.Common/Net/HttpResponseInfo.cs
@@ -0,0 +1,29 @@
+using System.IO;
+using System.Net;
+
+namespace MediaBrowser.Common.Net
+{
+ ///
+ /// Class HttpResponseInfo
+ ///
+ public class HttpResponseInfo
+ {
+ ///
+ /// Gets or sets the type of the content.
+ ///
+ /// The type of the content.
+ public string ContentType { get; set; }
+
+ ///
+ /// Gets or sets the content.
+ ///
+ /// The content.
+ public Stream Content { get; set; }
+
+ ///
+ /// Gets or sets the status code.
+ ///
+ /// The status code.
+ public HttpStatusCode StatusCode { get; set; }
+ }
+}
diff --git a/MediaBrowser.Common/Net/IHttpClient.cs b/MediaBrowser.Common/Net/IHttpClient.cs
index 2998d1af9b..6068d4e8c8 100644
--- a/MediaBrowser.Common/Net/IHttpClient.cs
+++ b/MediaBrowser.Common/Net/IHttpClient.cs
@@ -11,6 +11,13 @@ namespace MediaBrowser.Common.Net
///
public interface IHttpClient : IDisposable
{
+ ///
+ /// Gets the response.
+ ///
+ /// The options.
+ /// Task{HttpResponseInfo}.
+ Task GetResponse(HttpRequestOptions options);
+
///
/// Performs a GET request and returns the resulting stream
///
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index f8ecf003bf..c6d6bf2210 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -798,6 +798,9 @@ namespace MediaBrowser.Controller.Entities
});
await ((Folder)child).ValidateChildren(innerProgress, cancellationToken, recursive, forceRefreshMetadata).ConfigureAwait(false);
+
+ // Some folder providers are unable to refresh until children have been refreshed.
+ await child.RefreshMetadata(cancellationToken, resetResolveArgs: false).ConfigureAwait(false);
}
else
{
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index 643dbe1c2c..6b8083b20e 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Entities;
using System.Collections.Generic;
using System.IO;
using System.Threading;
@@ -12,40 +13,8 @@ namespace MediaBrowser.Controller.Providers
///
public interface IProviderManager
{
- ///
- /// Downloads the and save image.
- ///
- /// The item.
- /// The source.
- /// Name of the target.
- /// if set to true [save locally].
- /// The resource pool.
- /// The cancellation token.
- /// Task{System.String}.
- /// item
- Task DownloadAndSaveImage(BaseItem item, string source, string targetName, bool saveLocally, SemaphoreSlim resourcePool, CancellationToken cancellationToken);
-
- ///
- /// Saves the image.
- ///
- /// The item.
- /// The source.
- /// Name of the target.
- /// if set to true [save locally].
- /// The cancellation token.
- /// Task{System.String}.
- Task SaveImage(BaseItem item, Stream source, string targetName, bool saveLocally, CancellationToken cancellationToken);
-
- ///
- /// Saves to library filesystem.
- ///
- /// The item.
- /// The path.
- /// The data to save.
- /// The cancellation token.
- /// Task.
- ///
- Task SaveToLibraryFilesystem(BaseItem item, string path, Stream dataToSave, CancellationToken cancellationToken);
+ Task DownloadAndSaveImage(BaseItem item, string source, string targetName, bool saveLocally,
+ SemaphoreSlim resourcePool, CancellationToken cancellationToken);
///
/// Executes the metadata providers.
@@ -57,19 +26,34 @@ namespace MediaBrowser.Controller.Providers
/// Task{System.Boolean}.
Task ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false, bool allowSlowProviders = true);
+ ///
+ /// Saves the image.
+ ///
+ /// The item.
+ /// The URL.
+ /// The resource pool.
+ /// The type.
+ /// Index of the image.
+ /// The cancellation token.
+ /// Task.
+ Task SaveImage(BaseItem item, string url, SemaphoreSlim resourcePool, ImageType type, int? imageIndex, CancellationToken cancellationToken);
+
+ ///
+ /// Saves the image.
+ ///
+ /// The item.
+ /// The source.
+ /// Type of the MIME.
+ /// The type.
+ /// Index of the image.
+ /// The cancellation token.
+ /// Task.
+ Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken);
+
///
/// Adds the metadata providers.
///
/// The providers.
void AddParts(IEnumerable providers);
-
- ///
- /// Gets the save path.
- ///
- /// The item.
- /// Name of the target file.
- /// if set to true [save locally].
- /// System.String.
- string GetSavePath(BaseItem item, string targetFileName, bool saveLocally);
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
index 1a1c34928e..f0e696a06d 100644
--- a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
@@ -303,9 +303,6 @@ namespace MediaBrowser.Providers.Movies
cancellationToken.ThrowIfCancellationRequested();
- var saveLocal = ConfigurationManager.Configuration.SaveLocalMeta &&
- item.LocationType == LocationType.FileSystem;
-
string path;
var hd = ConfigurationManager.Configuration.DownloadHDFanArt ? "hd" : "";
@@ -322,7 +319,7 @@ namespace MediaBrowser.Providers.Movies
path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Logo, await _providerManager.DownloadAndSaveImage(item, path, LogoFile, saveLocal, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Logo, null, cancellationToken).ConfigureAwait(false);
}
}
cancellationToken.ThrowIfCancellationRequested();
@@ -337,7 +334,8 @@ namespace MediaBrowser.Providers.Movies
path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Art, await _providerManager.DownloadAndSaveImage(item, path, ArtFile, saveLocal, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Art, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
cancellationToken.ThrowIfCancellationRequested();
@@ -349,7 +347,8 @@ namespace MediaBrowser.Providers.Movies
path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Disc, await _providerManager.DownloadAndSaveImage(item, path, DiscFile, saveLocal, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Disc, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
@@ -362,7 +361,8 @@ namespace MediaBrowser.Providers.Movies
path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Banner, await _providerManager.DownloadAndSaveImage(item, path, BannerFile, saveLocal, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Banner, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
@@ -375,7 +375,8 @@ namespace MediaBrowser.Providers.Movies
path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Thumb, await _providerManager.DownloadAndSaveImage(item, path, ThumbFile, saveLocal, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Thumb, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
@@ -393,7 +394,8 @@ namespace MediaBrowser.Providers.Movies
if (!string.IsNullOrEmpty(path))
{
- item.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(item, path, ("backdrop" + (numBackdrops > 0 ? numBackdrops.ToString(UsCulture) : "") + ".jpg"), saveLocal, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Backdrop, numBackdrops, cancellationToken)
+ .ConfigureAwait(false);
numBackdrops++;
diff --git a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs
index 2c9fbcec8a..feb14c3a01 100644
--- a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs
@@ -93,7 +93,7 @@ namespace MediaBrowser.Providers.Movies
return ItemUpdateType.ImageUpdate;
}
}
-
+
///
/// Gets a value indicating whether [requires internet].
///
@@ -148,7 +148,7 @@ namespace MediaBrowser.Providers.Movies
{
return false;
}
-
+
return base.NeedsRefreshInternal(item, providerInfo);
}
@@ -168,7 +168,7 @@ namespace MediaBrowser.Providers.Movies
data = new BaseProviderInfo();
item.ProviderData[Id] = data;
}
-
+
var images = await FetchImages(item, item.GetProviderId(MetadataProviders.Tmdb), cancellationToken).ConfigureAwait(false);
var status = await ProcessImages(item, images, cancellationToken).ConfigureAwait(false);
@@ -246,7 +246,9 @@ namespace MediaBrowser.Providers.Movies
}).ConfigureAwait(false);
- item.PrimaryImagePath = await _providerManager.SaveImage(item, img, "folder" + Path.GetExtension(poster.file_path), ConfigurationManager.Configuration.SaveLocalMeta && item.LocationType == LocationType.FileSystem, cancellationToken).ConfigureAwait(false);
+ await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(poster.file_path), ImageType.Primary, null, cancellationToken)
+ .ConfigureAwait(false);
+
}
}
@@ -274,7 +276,8 @@ namespace MediaBrowser.Providers.Movies
}).ConfigureAwait(false);
- item.BackdropImagePaths.Add(await _providerManager.SaveImage(item, img, bdName + Path.GetExtension(images.backdrops[i].file_path), ConfigurationManager.Configuration.SaveLocalMeta && item.LocationType == LocationType.FileSystem, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(images.backdrops[i].file_path), ImageType.Backdrop, item.BackdropImagePaths.Count, cancellationToken)
+ .ConfigureAwait(false);
}
if (item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MaxBackdrops)
diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
index 5f56ab690d..64259c4242 100644
--- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.Providers.Movies
///
/// The movie db
///
- private readonly SemaphoreSlim _movieDbResourcePool = new SemaphoreSlim(1,1);
+ private readonly SemaphoreSlim _movieDbResourcePool = new SemaphoreSlim(1, 1);
internal static MovieDbProvider Current { get; private set; }
@@ -158,7 +158,7 @@ namespace MediaBrowser.Providers.Movies
_tmdbSettingsSemaphore.Release();
return _tmdbSettings;
}
-
+
try
{
using (var json = await GetMovieDbResponse(new HttpRequestOptions
@@ -199,7 +199,13 @@ namespace MediaBrowser.Providers.Movies
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
{
if (HasAltMeta(item))
- return false;
+ return false;
+
+ // Boxsets require two passes because we need the children to be refreshed
+ if (item is BoxSet && string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.TmdbCollection)))
+ {
+ return true;
+ }
return base.NeedsRefreshInternal(item, providerInfo);
}
@@ -291,19 +297,6 @@ namespace MediaBrowser.Providers.Movies
/// Task{System.String}.
public async Task FindId(BaseItem item, int? productionYear, CancellationToken cancellationToken)
{
- string id = null;
-
- if (item.LocationType == LocationType.FileSystem)
- {
- string justName = item.Path != null ? item.Path.Substring(item.Path.LastIndexOf(Path.DirectorySeparatorChar)) : string.Empty;
- id = justName.GetAttributeValue("tmdbid");
- if (id != null)
- {
- Logger.Debug("Using tmdb id specified in path.");
- return id;
- }
- }
-
int? year;
string name = item.Name;
ParseName(name, out name, out year);
@@ -320,25 +313,14 @@ namespace MediaBrowser.Providers.Movies
var boxset = item as BoxSet;
if (boxset != null)
{
- var firstChild = boxset.Children.FirstOrDefault();
-
- if (firstChild != null)
- {
- Logger.Debug("MovieDbProvider - Attempting to find boxset ID from: " + firstChild.Name);
- string childName;
- int? childYear;
- ParseName(firstChild.Name, out childName, out childYear);
- id = await GetBoxsetIdFromMovie(childName, childYear, language, cancellationToken).ConfigureAwait(false);
- if (id != null)
- {
- Logger.Info("MovieDbProvider - Found Boxset ID: " + id);
- }
- }
-
- return id;
+ // See if any movies have a collection id already
+ return boxset.Children.OfType
/// The item.
/// The source.
- /// Name of the target.
+ /// Type of the MIME.
/// The cancellation token.
/// Task{System.String}.
- private async Task DownloadAndSaveImage(BaseItem item, string source, string targetName, CancellationToken cancellationToken)
+ private async Task DownloadAndSaveImage(BaseItem item, string source, string mimeType, CancellationToken cancellationToken)
{
- if (source == null) return null;
-
- //download and save locally (if not already there)
- var localPath = Path.Combine(item.MetaLocation, targetName);
+ if (source == null) return;
using (var sourceStream = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
{
@@ -317,12 +309,11 @@ namespace MediaBrowser.Providers.Movies
}).ConfigureAwait(false))
{
- await ProviderManager.SaveToLibraryFilesystem(item, localPath, sourceStream, cancellationToken).ConfigureAwait(false);
+ await ProviderManager.SaveImage(item, sourceStream, mimeType, ImageType.Primary, null, cancellationToken)
+ .ConfigureAwait(false);
Logger.Debug("TmdbPersonProvider downloaded and saved image for {0}", item.Name);
}
-
- return localPath;
}
#region Result Objects
diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
index d7990f4312..12539d2ba9 100644
--- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
+++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
@@ -199,7 +199,8 @@ namespace MediaBrowser.Providers.Music
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Disc, await _providerManager.DownloadAndSaveImage(item, path, DiscFile, ConfigurationManager.Configuration.SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Disc, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
@@ -217,7 +218,8 @@ namespace MediaBrowser.Providers.Music
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Primary, await _providerManager.DownloadAndSaveImage(item, path, PrimaryFile, ConfigurationManager.Configuration.SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Primary, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
}
diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
index f310934aff..2593b9838f 100644
--- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
@@ -306,7 +306,8 @@ namespace MediaBrowser.Providers.Music
path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Logo, await _providerManager.DownloadAndSaveImage(item, path, LogoFile, SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Logo, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
cancellationToken.ThrowIfCancellationRequested();
@@ -323,7 +324,8 @@ namespace MediaBrowser.Providers.Music
path = node.Value;
if (!string.IsNullOrEmpty(path))
{
- item.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(item, path, ("Backdrop" + (numBackdrops > 0 ? numBackdrops.ToString(UsCulture) : "") + ".jpg"), SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Backdrop, numBackdrops, cancellationToken)
+ .ConfigureAwait(false);
numBackdrops++;
if (numBackdrops >= ConfigurationManager.Configuration.MaxBackdrops) break;
}
@@ -343,7 +345,8 @@ namespace MediaBrowser.Providers.Music
path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Art, await _providerManager.DownloadAndSaveImage(item, path, ArtFile, SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Art, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
cancellationToken.ThrowIfCancellationRequested();
@@ -355,7 +358,8 @@ namespace MediaBrowser.Providers.Music
path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Banner, await _providerManager.DownloadAndSaveImage(item, path, BannerFile, SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Banner, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
@@ -368,7 +372,8 @@ namespace MediaBrowser.Providers.Music
path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Primary, await _providerManager.DownloadAndSaveImage(item, path, PrimaryFile, SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Primary, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
}
diff --git a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs
index b16d378f7f..e8ecea38b0 100644
--- a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs
@@ -82,13 +82,16 @@ namespace MediaBrowser.Providers.Savers
builder.Append("" + SecurityElement.Escape(series.AirTime) + "");
}
- if (series.AirDays.Count == 7)
+ if (series.AirDays != null)
{
- builder.Append("" + SecurityElement.Escape("Daily") + "");
- }
- else if (series.AirDays.Count > 0)
- {
- builder.Append("" + SecurityElement.Escape(series.AirDays[0].ToString()) + "");
+ if (series.AirDays.Count == 7)
+ {
+ builder.Append("" + SecurityElement.Escape("Daily") + "");
+ }
+ else if (series.AirDays.Count > 0)
+ {
+ builder.Append("" + SecurityElement.Escape(series.AirDays[0].ToString()) + "");
+ }
}
XmlSaverHelpers.AddCommonNodes(item, builder);
diff --git a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
index d0a0735fb9..4999a845df 100644
--- a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
@@ -149,7 +149,8 @@ namespace MediaBrowser.Providers.TV
if (!string.IsNullOrEmpty(path))
{
- season.SetImage(ImageType.Thumb, await _providerManager.DownloadAndSaveImage(season, path, ThumbFile, ConfigurationManager.Configuration.SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(season, path, FanArtResourcePool, ImageType.Thumb, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
}
diff --git a/MediaBrowser.Providers/TV/FanArtTVProvider.cs b/MediaBrowser.Providers/TV/FanArtTVProvider.cs
index 6dc61b35d2..84ac59924c 100644
--- a/MediaBrowser.Providers/TV/FanArtTVProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArtTVProvider.cs
@@ -234,7 +234,8 @@ namespace MediaBrowser.Providers.TV
var path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Logo, await _providerManager.DownloadAndSaveImage(item, path, LogoFile, ConfigurationManager.Configuration.SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Logo, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
@@ -250,7 +251,8 @@ namespace MediaBrowser.Providers.TV
var path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Art, await _providerManager.DownloadAndSaveImage(item, path, ArtFile, ConfigurationManager.Configuration.SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Art, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
@@ -263,7 +265,8 @@ namespace MediaBrowser.Providers.TV
var path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Thumb, await _providerManager.DownloadAndSaveImage(item, path, ThumbFile, ConfigurationManager.Configuration.SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Thumb, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
@@ -274,7 +277,8 @@ namespace MediaBrowser.Providers.TV
var path = node != null ? node.Value : null;
if (!string.IsNullOrEmpty(path))
{
- item.SetImage(ImageType.Banner, await _providerManager.DownloadAndSaveImage(item, path, BannerFile, ConfigurationManager.Configuration.SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Banner, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
@@ -292,7 +296,8 @@ namespace MediaBrowser.Providers.TV
if (!string.IsNullOrEmpty(path))
{
- item.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(item, path, ("backdrop" + (numBackdrops > 0 ? numBackdrops.ToString(UsCulture) : "") + ".jpg"), ConfigurationManager.Configuration.SaveLocalMeta, FanArtResourcePool, cancellationToken).ConfigureAwait(false));
+ await _providerManager.SaveImage(item, path, FanArtResourcePool, ImageType.Backdrop, numBackdrops, cancellationToken)
+ .ConfigureAwait(false);
numBackdrops++;
diff --git a/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs b/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs
index eb79075ffc..438d49507e 100644
--- a/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs
@@ -276,7 +276,10 @@ namespace MediaBrowser.Providers.TV
try
{
- episode.PrimaryImagePath = await _providerManager.DownloadAndSaveImage(episode, TVUtils.BannerUrl + p, Path.GetFileName(p), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken);
+ var url = TVUtils.BannerUrl + p;
+
+ await _providerManager.SaveImage(episode, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Primary, null, cancellationToken)
+ .ConfigureAwait(false);
}
catch (HttpException)
{
diff --git a/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs b/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs
index f8399ebdf9..1ea2c1db5f 100644
--- a/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs
@@ -188,7 +188,12 @@ namespace MediaBrowser.Providers.TV
n = n.SelectSingleNode("./BannerPath");
if (n != null)
- season.PrimaryImagePath = await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "folder" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false);
+ {
+ var url = TVUtils.BannerUrl + n.InnerText;
+
+ await _providerManager.SaveImage(season, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Primary, null, cancellationToken)
+ .ConfigureAwait(false);
+ }
}
}
@@ -203,15 +208,10 @@ namespace MediaBrowser.Providers.TV
{
try
{
- var bannerImagePath =
- await _providerManager.DownloadAndSaveImage(season,
- TVUtils.BannerUrl + n.InnerText,
- "banner" +
- Path.GetExtension(n.InnerText),
- ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).
- ConfigureAwait(false);
+ var url = TVUtils.BannerUrl + n.InnerText;
- season.SetImage(ImageType.Banner, bannerImagePath);
+ await _providerManager.SaveImage(season, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Banner, null, cancellationToken)
+ .ConfigureAwait(false);
}
catch (HttpException ex)
{
@@ -235,7 +235,11 @@ namespace MediaBrowser.Providers.TV
n = n.SelectSingleNode("./BannerPath");
if (n != null)
{
- season.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(season, TVUtils.BannerUrl + n.InnerText, "backdrop" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false));
+ var url = TVUtils.BannerUrl + n.InnerText;
+
+ await _providerManager.SaveImage(season, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, 0, cancellationToken)
+ .ConfigureAwait(false);
+
}
}
}
diff --git a/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs b/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs
index fc37912eff..3d86ebb7e1 100644
--- a/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/RemoteSeriesProvider.cs
@@ -215,13 +215,6 @@ namespace MediaBrowser.Providers.TV
await FetchSeriesData(series, seriesId, seriesDataPath, force, cancellationToken).ConfigureAwait(false);
}
- BaseProviderInfo data;
- if (!item.ProviderData.TryGetValue(Id, out data))
- {
- data = new BaseProviderInfo();
- item.ProviderData[Id] = data;
- }
-
SetLastRefreshed(item, DateTime.UtcNow);
return true;
}
diff --git a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs
index 2d8bf5ed69..776cede8ef 100644
--- a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs
+++ b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs
@@ -197,9 +197,10 @@ namespace MediaBrowser.Providers.TV
n = n.SelectSingleNode("./BannerPath");
if (n != null)
{
- var path = await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "folder" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false);
+ var url = TVUtils.BannerUrl + n.InnerText;
- series.SetImage(ImageType.Primary, path);
+ await _providerManager.SaveImage(series, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Primary, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
}
@@ -212,9 +213,10 @@ namespace MediaBrowser.Providers.TV
n = n.SelectSingleNode("./BannerPath");
if (n != null)
{
- var bannerImagePath = await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + n.InnerText, "banner" + Path.GetExtension(n.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken);
+ var url = TVUtils.BannerUrl + n.InnerText;
- series.SetImage(ImageType.Banner, bannerImagePath);
+ await _providerManager.SaveImage(series, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Banner, null, cancellationToken)
+ .ConfigureAwait(false);
}
}
}
@@ -232,8 +234,11 @@ namespace MediaBrowser.Providers.TV
if (p != null)
{
- var bdName = "backdrop" + (bdNo > 0 ? bdNo.ToString(UsCulture) : "");
- series.BackdropImagePaths.Add(await _providerManager.DownloadAndSaveImage(series, TVUtils.BannerUrl + p.InnerText, bdName + Path.GetExtension(p.InnerText), ConfigurationManager.Configuration.SaveLocalMeta, RemoteSeriesProvider.Current.TvDbResourcePool, cancellationToken).ConfigureAwait(false));
+ var url = TVUtils.BannerUrl + p.InnerText;
+
+ await _providerManager.SaveImage(series, url, RemoteSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, bdNo, cancellationToken)
+ .ConfigureAwait(false);
+
bdNo++;
}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 08fbe31c00..041c9db6b8 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -148,6 +148,7 @@
+
diff --git a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs
new file mode 100644
index 0000000000..3e5a2802cc
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs
@@ -0,0 +1,255 @@
+using System.Globalization;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.IO;
+using MediaBrowser.Model.Entities;
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Providers
+{
+ ///
+ /// Class ImageSaver
+ ///
+ public class ImageSaver
+ {
+ private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+
+ ///
+ /// The _config
+ ///
+ private readonly IServerConfigurationManager _config;
+
+ ///
+ /// The remote image cache
+ ///
+ private readonly FileSystemRepository _remoteImageCache;
+ ///
+ /// The _directory watchers
+ ///
+ private readonly IDirectoryWatchers _directoryWatchers;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The config.
+ /// The directory watchers.
+ public ImageSaver(IServerConfigurationManager config, IDirectoryWatchers directoryWatchers)
+ {
+ _config = config;
+ _directoryWatchers = directoryWatchers;
+ _remoteImageCache = new FileSystemRepository(config.ApplicationPaths.DownloadedImagesDataPath);
+ }
+
+ ///
+ /// Saves the image.
+ ///
+ /// The item.
+ /// The source.
+ /// Type of the MIME.
+ /// The type.
+ /// Index of the image.
+ /// The cancellation token.
+ /// Task.
+ public async Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken)
+ {
+ if (string.IsNullOrEmpty(mimeType))
+ {
+ throw new ArgumentNullException("mimeType");
+ }
+
+ var saveLocally = _config.Configuration.SaveLocalMeta;
+
+ if (item is IItemByName)
+ {
+ saveLocally = true;
+ }
+ else if (item is User)
+ {
+ saveLocally = true;
+ }
+ else if (item is Audio || item.Parent == null || string.IsNullOrEmpty(item.MetaLocation))
+ {
+ saveLocally = false;
+ }
+
+ if (type != ImageType.Primary)
+ {
+ if (item is Episode)
+ {
+ saveLocally = false;
+ }
+ }
+
+ if (item.LocationType != LocationType.FileSystem)
+ {
+ saveLocally = false;
+ }
+
+ var path = GetSavePath(item, type, imageIndex, mimeType, saveLocally);
+
+ var currentPath = GetCurrentImagePath(item, type, imageIndex);
+
+ try
+ {
+ _directoryWatchers.TemporarilyIgnore(path);
+
+ using (source)
+ {
+ using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
+ {
+ await source.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ SetImagePath(item, type, imageIndex, path);
+
+ if (!string.IsNullOrEmpty(currentPath) && !string.Equals(path, currentPath, StringComparison.OrdinalIgnoreCase))
+ {
+ File.Delete(currentPath);
+ }
+ }
+ finally
+ {
+ _directoryWatchers.RemoveTempIgnore(path);
+ }
+
+ }
+
+ private string GetCurrentImagePath(BaseItem item, ImageType type, int? imageIndex)
+ {
+ switch (type)
+ {
+ case ImageType.Screenshot:
+
+ if (!imageIndex.HasValue)
+ {
+ throw new ArgumentNullException("imageIndex");
+ }
+ return item.ScreenshotImagePaths.Count > imageIndex.Value ? item.ScreenshotImagePaths[imageIndex.Value] : null;
+ case ImageType.Backdrop:
+ if (!imageIndex.HasValue)
+ {
+ throw new ArgumentNullException("imageIndex");
+ }
+ return item.BackdropImagePaths.Count > imageIndex.Value ? item.BackdropImagePaths[imageIndex.Value] : null;
+ default:
+ return item.GetImage(type);
+ }
+ }
+
+ private void SetImagePath(BaseItem item, ImageType type, int? imageIndex, string path)
+ {
+ switch (type)
+ {
+ case ImageType.Screenshot:
+
+ if (!imageIndex.HasValue)
+ {
+ throw new ArgumentNullException("imageIndex");
+ }
+
+ if (item.ScreenshotImagePaths.Count > imageIndex.Value)
+ {
+ item.ScreenshotImagePaths[imageIndex.Value] = path;
+ }
+ else
+ {
+ item.ScreenshotImagePaths.Add(path);
+ }
+ break;
+ case ImageType.Backdrop:
+ if (!imageIndex.HasValue)
+ {
+ throw new ArgumentNullException("imageIndex");
+ }
+ if (item.BackdropImagePaths.Count > imageIndex.Value)
+ {
+ item.BackdropImagePaths[imageIndex.Value] = path;
+ }
+ else
+ {
+ item.BackdropImagePaths.Add(path);
+ }
+ break;
+ default:
+ item.SetImage(type, path);
+ break;
+ }
+ }
+
+ ///
+ /// Gets the save path.
+ ///
+ /// The item.
+ /// The type.
+ /// Index of the image.
+ /// Type of the MIME.
+ /// if set to true [save locally].
+ /// System.String.
+ ///
+ /// imageIndex
+ /// or
+ /// imageIndex
+ ///
+ private string GetSavePath(BaseItem item, ImageType type, int? imageIndex, string mimeType, bool saveLocally)
+ {
+ string filename;
+
+ switch (type)
+ {
+ case ImageType.Art:
+ filename = "clearart";
+ break;
+ case ImageType.Primary:
+ filename = item is Episode ? Path.GetFileNameWithoutExtension(item.Path) : "folder";
+ break;
+ case ImageType.Backdrop:
+ if (!imageIndex.HasValue)
+ {
+ throw new ArgumentNullException("imageIndex");
+ }
+ filename = imageIndex.Value == 0 ? "backdrop" : "backdrop" + imageIndex.Value.ToString(UsCulture);
+ break;
+ case ImageType.Screenshot:
+ if (!imageIndex.HasValue)
+ {
+ throw new ArgumentNullException("imageIndex");
+ }
+ filename = imageIndex.Value == 0 ? "screenshot" : "screenshot" + imageIndex.Value.ToString(UsCulture);
+ break;
+ default:
+ filename = type.ToString().ToLower();
+ break;
+ }
+
+ var extension = mimeType.Split('/').Last();
+
+ if (string.Equals(extension, "jpeg", StringComparison.OrdinalIgnoreCase))
+ {
+ extension = "jpg";
+ }
+
+ filename += "." + extension.ToLower();
+
+ var path = (saveLocally && !string.IsNullOrEmpty(item.MetaLocation)) ?
+ Path.Combine(item.MetaLocation, filename) :
+ _remoteImageCache.GetResourcePath(item.GetType().FullName + item.Id, filename);
+
+ var parentPath = Path.GetDirectoryName(path);
+
+ if (!Directory.Exists(parentPath))
+ {
+ Directory.CreateDirectory(parentPath);
+ }
+
+ return path;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
index ee8bb4c096..0af7426b10 100644
--- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
+++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
@@ -2,11 +2,14 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -22,11 +25,6 @@ namespace MediaBrowser.Server.Implementations.Providers
///
public class ProviderManager : IProviderManager
{
- ///
- /// The remote image cache
- ///
- private readonly FileSystemRepository _remoteImageCache;
-
///
/// The currently running metadata providers
///
@@ -74,7 +72,6 @@ namespace MediaBrowser.Server.Implementations.Providers
_httpClient = httpClient;
ConfigurationManager = configurationManager;
_directoryWatchers = directoryWatchers;
- _remoteImageCache = new FileSystemRepository(configurationManager.ApplicationPaths.DownloadedImagesDataPath);
configurationManager.ConfigurationUpdated += configurationManager_ConfigurationUpdated;
}
@@ -206,7 +203,7 @@ namespace MediaBrowser.Server.Implementations.Providers
try
{
var changed = await provider.FetchAsync(item, force, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token).ConfigureAwait(false);
-
+
if (changed)
{
return provider.ItemUpdateType;
@@ -315,90 +312,9 @@ namespace MediaBrowser.Server.Implementations.Providers
/// The cancellation token.
/// Task{System.String}.
/// item
- public async Task DownloadAndSaveImage(BaseItem item, string source, string targetName, bool saveLocally, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
+ public Task DownloadAndSaveImage(BaseItem item, string source, string targetName, bool saveLocally, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
{
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
- if (string.IsNullOrEmpty(source))
- {
- throw new ArgumentNullException("source");
- }
- if (string.IsNullOrEmpty(targetName))
- {
- throw new ArgumentNullException("targetName");
- }
- if (resourcePool == null)
- {
- throw new ArgumentNullException("resourcePool");
- }
-
- var img = await _httpClient.Get(source, resourcePool, cancellationToken).ConfigureAwait(false);
-
- //download and save locally
- return await SaveImage(item, img, targetName, saveLocally, cancellationToken).ConfigureAwait(false);
- }
-
- public async Task SaveImage(BaseItem item, Stream source, string targetName, bool saveLocally, CancellationToken cancellationToken)
- {
- //download and save locally
- var localPath = GetSavePath(item, targetName, saveLocally);
-
- if (saveLocally) // queue to media directories
- {
- await SaveToLibraryFilesystem(item, localPath, source, cancellationToken).ConfigureAwait(false);
- }
- else
- {
- // we can write directly here because it won't affect the watchers
-
- try
- {
- using (var fs = new FileStream(localPath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
- {
- await source.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false);
- }
- }
- catch (OperationCanceledException)
- {
- throw;
- }
- catch (Exception e)
- {
- _logger.ErrorException("Error downloading and saving image " + localPath, e);
- throw;
- }
- finally
- {
- source.Dispose();
- }
-
- }
- return localPath;
- }
-
- ///
- /// Gets the save path.
- ///
- /// The item.
- /// Name of the target file.
- /// if set to true [save locally].
- /// System.String.
- public string GetSavePath(BaseItem item, string targetFileName, bool saveLocally)
- {
- var path = (saveLocally && item.MetaLocation != null) ?
- Path.Combine(item.MetaLocation, targetFileName) :
- _remoteImageCache.GetResourcePath(item.GetType().FullName + item.Id.ToString(), targetFileName);
-
- var parentPath = Path.GetDirectoryName(path);
-
- if (!Directory.Exists(parentPath))
- {
- Directory.CreateDirectory(parentPath);
- }
-
- return path;
+ throw new HttpException(string.Empty) { IsTimedOut = true };
}
///
@@ -462,5 +378,45 @@ namespace MediaBrowser.Server.Implementations.Providers
_directoryWatchers.RemoveTempIgnore(path);
}
}
+
+
+ ///
+ /// Saves the image.
+ ///
+ /// The item.
+ /// The URL.
+ /// The resource pool.
+ /// The type.
+ /// Index of the image.
+ /// The cancellation token.
+ /// Task.
+ public async Task SaveImage(BaseItem item, string url, SemaphoreSlim resourcePool, ImageType type, int? imageIndex, CancellationToken cancellationToken)
+ {
+ var response = await _httpClient.GetResponse(new HttpRequestOptions
+ {
+ CancellationToken = cancellationToken,
+ ResourcePool = resourcePool,
+ Url = url
+
+ }).ConfigureAwait(false);
+
+ await SaveImage(item, response.Content, response.ContentType, type, imageIndex, cancellationToken)
+ .ConfigureAwait(false);
+ }
+
+ ///
+ /// Saves the image.
+ ///
+ /// The item.
+ /// The source.
+ /// Type of the MIME.
+ /// The type.
+ /// Index of the image.
+ /// The cancellation token.
+ /// Task.
+ public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken)
+ {
+ return new ImageSaver(ConfigurationManager, _directoryWatchers).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken);
+ }
}
}