aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Providers/Manager
diff options
context:
space:
mode:
authorcvium <clausvium@gmail.com>2022-01-07 10:23:22 +0100
committercvium <clausvium@gmail.com>2022-01-07 10:23:22 +0100
commitc658a883a2bc84b46ed73d209d2983e8a324cdce (patch)
treedabdbb5ac224e202d5433e7062e0c1b6872d1af7 /MediaBrowser.Providers/Manager
parent2899b77cd58456470b8dd4d01d3a8c525a9b5911 (diff)
parent6b4f5a86631e5bde93dae88553380c7ffd99b8e4 (diff)
Merge branch 'master' into keyframe_extraction_v1
# Conflicts: # Jellyfin.Api/Controllers/DynamicHlsController.cs # MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs # MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
Diffstat (limited to 'MediaBrowser.Providers/Manager')
-rw-r--r--MediaBrowser.Providers/Manager/ImageSaver.cs32
-rw-r--r--MediaBrowser.Providers/Manager/ItemImageProvider.cs154
-rw-r--r--MediaBrowser.Providers/Manager/MetadataService.cs20
-rw-r--r--MediaBrowser.Providers/Manager/ProviderManager.cs15
-rw-r--r--MediaBrowser.Providers/Manager/ProviderUtils.cs2
-rw-r--r--MediaBrowser.Providers/Manager/RefreshResult.cs2
6 files changed, 114 insertions, 111 deletions
diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs
index 7d259a9d3..4632e1d51 100644
--- a/MediaBrowser.Providers/Manager/ImageSaver.cs
+++ b/MediaBrowser.Providers/Manager/ImageSaver.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
#pragma warning disable CS1591
using System;
@@ -7,6 +9,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Extensions;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@@ -29,8 +32,6 @@ namespace MediaBrowser.Providers.Manager
/// </summary>
public class ImageSaver
{
- private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
/// <summary>
/// The _config.
/// </summary>
@@ -173,7 +174,7 @@ namespace MediaBrowser.Providers.Manager
// Delete the current path
if (currentImageIsLocalFile
- && !savedPaths.Contains(currentImagePath, StringComparer.OrdinalIgnoreCase)
+ && !savedPaths.Contains(currentImagePath, StringComparison.OrdinalIgnoreCase)
&& (saveLocally || currentImagePath.Contains(_config.ApplicationPaths.InternalMetadataPath, StringComparison.OrdinalIgnoreCase)))
{
var currentPath = currentImagePath;
@@ -263,8 +264,10 @@ namespace MediaBrowser.Providers.Manager
_fileSystem.SetAttributes(path, false, false);
- // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
- await using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous))
+ var fileStreamOptions = AsyncFile.WriteOptions;
+ fileStreamOptions.Mode = FileMode.Create;
+ fileStreamOptions.PreallocationSize = source.Length;
+ await using (var fs = new FileStream(path, fileStreamOptions))
{
await source.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
}
@@ -377,7 +380,7 @@ namespace MediaBrowser.Providers.Manager
var seasonMarker = season.IndexNumber.Value == 0
? "-specials"
- : season.IndexNumber.Value.ToString("00", UsCulture);
+ : season.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
var imageFilename = "season" + seasonMarker + "-landscape" + extension;
@@ -400,7 +403,7 @@ namespace MediaBrowser.Providers.Manager
var seasonMarker = season.IndexNumber.Value == 0
? "-specials"
- : season.IndexNumber.Value.ToString("00", UsCulture);
+ : season.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
var imageFilename = "season" + seasonMarker + "-banner" + extension;
@@ -437,9 +440,6 @@ namespace MediaBrowser.Providers.Manager
case ImageType.Backdrop:
filename = GetBackdropSaveFilename(item.GetImages(type), "backdrop", "backdrop", imageIndex);
break;
- case ImageType.Screenshot:
- filename = GetBackdropSaveFilename(item.GetImages(type), "screenshot", "screenshot", imageIndex);
- break;
default:
filename = type.ToString().ToLowerInvariant();
break;
@@ -495,12 +495,12 @@ namespace MediaBrowser.Providers.Manager
var filenames = images.Select(i => Path.GetFileNameWithoutExtension(i.Path)).ToList();
var current = 1;
- while (filenames.Contains(numberedIndexPrefix + current.ToString(UsCulture), StringComparer.OrdinalIgnoreCase))
+ while (filenames.Contains(numberedIndexPrefix + current.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase))
{
current++;
}
- return numberedIndexPrefix + current.ToString(UsCulture);
+ return numberedIndexPrefix + current.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
@@ -539,7 +539,7 @@ namespace MediaBrowser.Providers.Manager
var seasonMarker = season.IndexNumber.Value == 0
? "-specials"
- : season.IndexNumber.Value.ToString("00", UsCulture);
+ : season.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
var imageFilename = "season" + seasonMarker + "-fanart" + extension;
@@ -556,7 +556,7 @@ namespace MediaBrowser.Providers.Manager
if (item.IsInMixedFolder)
{
- return new[] { GetSavePathForItemInMixedFolder(item, type, "fanart" + outputIndex.ToString(UsCulture), extension) };
+ return new[] { GetSavePathForItemInMixedFolder(item, type, "fanart" + outputIndex.ToString(CultureInfo.InvariantCulture), extension) };
}
var extraFanartFilename = GetBackdropSaveFilename(item.GetImages(ImageType.Backdrop), "fanart", "fanart", outputIndex);
@@ -568,7 +568,7 @@ namespace MediaBrowser.Providers.Manager
if (EnableExtraThumbsDuplication)
{
- list.Add(Path.Combine(item.ContainingFolderPath, "extrathumbs", "thumb" + outputIndex.ToString(UsCulture) + extension));
+ list.Add(Path.Combine(item.ContainingFolderPath, "extrathumbs", "thumb" + outputIndex.ToString(CultureInfo.InvariantCulture) + extension));
}
return list.ToArray();
@@ -582,7 +582,7 @@ namespace MediaBrowser.Providers.Manager
var seasonMarker = season.IndexNumber.Value == 0
? "-specials"
- : season.IndexNumber.Value.ToString("00", UsCulture);
+ : season.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
var imageFilename = "season" + seasonMarker + "-poster" + extension;
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index 73bca5aa5..b1d73c4c4 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CA1002, CS1591
+#nullable disable
using System;
using System.Collections.Generic;
@@ -23,6 +23,9 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Providers.Manager
{
+ /// <summary>
+ /// Utilities for managing images attached to items.
+ /// </summary>
public class ItemImageProvider
{
private readonly ILogger _logger;
@@ -45,6 +48,12 @@ namespace MediaBrowser.Providers.Manager
ImageType.Thumb
};
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ItemImageProvider"/> class.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ /// <param name="providerManager">The provider manager for interacting with provider image references.</param>
+ /// <param name="fileSystem">The filesystem.</param>
public ItemImageProvider(ILogger logger, IProviderManager providerManager, IFileSystem fileSystem)
{
_logger = logger;
@@ -52,6 +61,13 @@ namespace MediaBrowser.Providers.Manager
_fileSystem = fileSystem;
}
+ /// <summary>
+ /// Verifies existing images have valid paths and adds any new local images provided.
+ /// </summary>
+ /// <param name="item">The <see cref="BaseItem"/> to validate images for.</param>
+ /// <param name="providers">The providers to use, must include <see cref="ILocalImageProvider"/>(s) for local scanning.</param>
+ /// <param name="directoryService">The directory service for <see cref="ILocalImageProvider"/>s to use.</param>
+ /// <returns><c>true</c> if changes were made to the item; otherwise <c>false</c>.</returns>
public bool ValidateImages(BaseItem item, IEnumerable<IImageProvider> providers, IDirectoryService directoryService)
{
var hasChanges = false;
@@ -71,6 +87,15 @@ namespace MediaBrowser.Providers.Manager
return hasChanges;
}
+ /// <summary>
+ /// Refreshes from the providers according to the given options.
+ /// </summary>
+ /// <param name="item">The <see cref="BaseItem"/> to gather images for.</param>
+ /// <param name="libraryOptions">The library options.</param>
+ /// <param name="providers">The providers to query for images.</param>
+ /// <param name="refreshOptions">The refresh options.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>The refresh result.</returns>
public async Task<RefreshResult> RefreshImages(
BaseItem item,
LibraryOptions libraryOptions,
@@ -78,14 +103,10 @@ namespace MediaBrowser.Providers.Manager
ImageRefreshOptions refreshOptions,
CancellationToken cancellationToken)
{
+ var oldBackdropImages = Array.Empty<ItemImageInfo>();
if (refreshOptions.IsReplacingImage(ImageType.Backdrop))
{
- ClearImages(item, ImageType.Backdrop);
- }
-
- if (refreshOptions.IsReplacingImage(ImageType.Screenshot))
- {
- ClearImages(item, ImageType.Screenshot);
+ oldBackdropImages = item.GetImages(ImageType.Backdrop).ToArray();
}
var result = new RefreshResult { UpdateType = ItemUpdateType.None };
@@ -93,16 +114,15 @@ namespace MediaBrowser.Providers.Manager
var typeName = item.GetType().Name;
var typeOptions = libraryOptions.GetTypeOptions(typeName) ?? new TypeOptions { Type = typeName };
- // In order to avoid duplicates, only download these if there are none already
- var backdropLimit = typeOptions.GetLimit(ImageType.Backdrop);
- var screenshotLimit = typeOptions.GetLimit(ImageType.Screenshot);
+ // track library limits, adding buffer to allow lazy replacing of current images
+ var backdropLimit = typeOptions.GetLimit(ImageType.Backdrop) + oldBackdropImages.Length;
var downloadedImages = new List<ImageType>();
foreach (var provider in providers)
{
if (provider is IRemoteImageProvider remoteProvider)
{
- await RefreshFromProvider(item, remoteProvider, refreshOptions, typeOptions, backdropLimit, screenshotLimit, downloadedImages, result, cancellationToken).ConfigureAwait(false);
+ await RefreshFromProvider(item, remoteProvider, refreshOptions, typeOptions, backdropLimit, downloadedImages, result, cancellationToken).ConfigureAwait(false);
continue;
}
@@ -112,11 +132,17 @@ namespace MediaBrowser.Providers.Manager
}
}
+ // only delete existing multi-images if new ones were added
+ if (oldBackdropImages.Length > 0 && oldBackdropImages.Length < item.GetImages(ImageType.Backdrop).Count())
+ {
+ PruneImages(item, oldBackdropImages);
+ }
+
return result;
}
/// <summary>
- /// Refreshes from provider.
+ /// Refreshes from a dynamic provider.
/// </summary>
private async Task RefreshFromProvider(
BaseItem item,
@@ -151,19 +177,20 @@ namespace MediaBrowser.Providers.Manager
if (response.Protocol == MediaProtocol.Http)
{
_logger.LogDebug("Setting image url into item {0}", item.Id);
+ var index = item.AllowsMultipleImages(imageType) ? item.GetImages(imageType).Count() : 0;
item.SetImage(
new ItemImageInfo
{
Path = response.Path,
Type = imageType
},
- 0);
+ index);
}
else
{
var mimeType = MimeTypes.GetMimeType(response.Path);
- var stream = new FileStream(response.Path, FileMode.Open, FileAccess.Read, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
+ var stream = AsyncFile.OpenRead(response.Path);
await _providerManager.SaveImage(item, stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false);
}
@@ -188,7 +215,7 @@ namespace MediaBrowser.Providers.Manager
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
- _logger.LogError(ex, "Error in {provider}", provider.Name);
+ _logger.LogError(ex, "Error in {Provider}", provider.Name);
}
}
@@ -204,9 +231,8 @@ namespace MediaBrowser.Providers.Manager
/// <param name="images">The images.</param>
/// <param name="savedOptions">The saved options.</param>
/// <param name="backdropLimit">The backdrop limit.</param>
- /// <param name="screenshotLimit">The screenshot limit.</param>
/// <returns><c>true</c> if the specified item contains images; otherwise, <c>false</c>.</returns>
- private bool ContainsImages(BaseItem item, List<ImageType> images, TypeOptions savedOptions, int backdropLimit, int screenshotLimit)
+ private bool ContainsImages(BaseItem item, List<ImageType> images, TypeOptions savedOptions, int backdropLimit)
{
// Using .Any causes the creation of a DisplayClass aka. variable capture
for (var i = 0; i < _singularImages.Length; i++)
@@ -223,23 +249,17 @@ namespace MediaBrowser.Providers.Manager
return false;
}
- if (images.Contains(ImageType.Screenshot) && item.GetImages(ImageType.Screenshot).Count() < screenshotLimit)
- {
- return false;
- }
-
return true;
}
/// <summary>
- /// Refreshes from provider.
+ /// Refreshes from a remote provider.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="provider">The provider.</param>
/// <param name="refreshOptions">The refresh options.</param>
/// <param name="savedOptions">The saved options.</param>
/// <param name="backdropLimit">The backdrop limit.</param>
- /// <param name="screenshotLimit">The screenshot limit.</param>
/// <param name="downloadedImages">The downloaded images.</param>
/// <param name="result">The result.</param>
/// <param name="cancellationToken">The cancellation token.</param>
@@ -250,7 +270,6 @@ namespace MediaBrowser.Providers.Manager
ImageRefreshOptions refreshOptions,
TypeOptions savedOptions,
int backdropLimit,
- int screenshotLimit,
ICollection<ImageType> downloadedImages,
RefreshResult result,
CancellationToken cancellationToken)
@@ -264,7 +283,7 @@ namespace MediaBrowser.Providers.Manager
if (!refreshOptions.ReplaceAllImages &&
refreshOptions.ReplaceImages.Length == 0 &&
- ContainsImages(item, provider.GetSupportedImages(item).ToList(), savedOptions, backdropLimit, screenshotLimit))
+ ContainsImages(item, provider.GetSupportedImages(item).ToList(), savedOptions, backdropLimit))
{
return;
}
@@ -303,13 +322,7 @@ namespace MediaBrowser.Providers.Manager
}
minWidth = savedOptions.GetMinWidth(ImageType.Backdrop);
- await DownloadBackdrops(item, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
-
- if (item is IHasScreenshots hasScreenshots)
- {
- minWidth = savedOptions.GetMinWidth(ImageType.Screenshot);
- await DownloadBackdrops(item, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
- }
+ await DownloadMultiImages(item, ImageType.Backdrop, refreshOptions, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
@@ -318,7 +331,7 @@ namespace MediaBrowser.Providers.Manager
catch (Exception ex)
{
result.ErrorMessage = ex.Message;
- _logger.LogError(ex, "Error in {provider}", provider.Name);
+ _logger.LogError(ex, "Error in {Provider}", provider.Name);
}
}
@@ -327,40 +340,36 @@ namespace MediaBrowser.Providers.Manager
return options.IsEnabled(type);
}
- private void ClearImages(BaseItem item, ImageType type)
+ private void PruneImages(BaseItem item, ItemImageInfo[] images)
{
- var deleted = false;
- var deletedImages = new List<ItemImageInfo>();
-
- foreach (var image in item.GetImages(type))
+ for (var i = 0; i < images.Length; i++)
{
- if (!image.IsLocalFile)
- {
- deletedImages.Add(image);
- continue;
- }
+ var image = images[i];
- try
- {
- _fileSystem.DeleteFile(image.Path);
- deleted = true;
- }
- catch (FileNotFoundException)
+ if (image.IsLocalFile)
{
+ try
+ {
+ _fileSystem.DeleteFile(image.Path);
+ }
+ catch (FileNotFoundException)
+ {
+ }
}
}
- item.RemoveImages(deletedImages);
-
- if (deleted)
- {
- item.ValidateImages(new DirectoryService(_fileSystem));
- }
+ item.RemoveImages(images);
}
+ /// <summary>
+ /// Merges a list of images into the provided item, validating existing images and replacing them or adding new images as necessary.
+ /// </summary>
+ /// <param name="item">The <see cref="BaseItem"/> to modify.</param>
+ /// <param name="images">The new images to place in <c>item</c>.</param>
+ /// <returns><c>true</c> if changes were made to the item; otherwise <c>false</c>.</returns>
public bool MergeImages(BaseItem item, IReadOnlyList<LocalImageInfo> images)
{
- var changed = false;
+ var changed = item.ValidateImages(new DirectoryService(_fileSystem));
for (var i = 0; i < _singularImages.Length; i++)
{
@@ -396,18 +405,6 @@ namespace MediaBrowser.Providers.Manager
currentImage.DateModified = newDateModified;
}
}
- else
- {
- var existing = item.GetImageInfo(type, 0);
- if (existing != null)
- {
- if (existing.IsLocalFile && !File.Exists(existing.Path))
- {
- item.RemoveImage(existing);
- changed = true;
- }
- }
- }
}
if (UpdateMultiImages(item, images, ImageType.Backdrop))
@@ -415,15 +412,6 @@ namespace MediaBrowser.Providers.Manager
changed = true;
}
- var hasScreenshots = item as IHasScreenshots;
- if (hasScreenshots != null)
- {
- if (UpdateMultiImages(item, images, ImageType.Screenshot))
- {
- changed = true;
- }
- }
-
return changed;
}
@@ -469,7 +457,7 @@ namespace MediaBrowser.Providers.Manager
CancellationToken cancellationToken)
{
var eligibleImages = images
- .Where(i => i.Type == type && i.Width >= minWidth)
+ .Where(i => i.Type == type && (i.Width == null || i.Width >= minWidth))
.ToList();
if (EnableImageStub(item) && eligibleImages.Count > 0)
@@ -534,7 +522,7 @@ namespace MediaBrowser.Providers.Manager
return true;
}
- if (item is IItemByName && item is not MusicArtist)
+ if (item is IItemByName and not MusicArtist)
{
var hasDualAccess = item as IHasDualAccess;
if (hasDualAccess == null || hasDualAccess.IsAccessedByName)
@@ -567,7 +555,7 @@ namespace MediaBrowser.Providers.Manager
newIndex);
}
- private async Task DownloadBackdrops(BaseItem item, ImageType imageType, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, int minWidth, CancellationToken cancellationToken)
+ private async Task DownloadMultiImages(BaseItem item, ImageType imageType, ImageRefreshOptions refreshOptions, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, int minWidth, CancellationToken cancellationToken)
{
foreach (var image in images.Where(i => i.Type == imageType))
{
@@ -607,8 +595,8 @@ namespace MediaBrowser.Providers.Manager
break;
}
- // If there's already an image of the same size, skip it
- if (response.Content.Headers.ContentLength.HasValue)
+ // If there's already an image of the same file size, skip it unless doing a full refresh
+ if (response.Content.Headers.ContentLength.HasValue && !refreshOptions.IsReplacingImage(imageType))
{
try
{
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index ab8d3a2a6..94045b38b 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -1,8 +1,11 @@
+#nullable disable
+
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Configuration;
@@ -677,8 +680,15 @@ namespace MediaBrowser.Providers.Manager
{
foreach (var remoteImage in localItem.RemoteImages)
{
- await ProviderManager.SaveImage(item, remoteImage.url, remoteImage.type, null, cancellationToken).ConfigureAwait(false);
- refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
+ try
+ {
+ await ProviderManager.SaveImage(item, remoteImage.Url, remoteImage.Type, null, cancellationToken).ConfigureAwait(false);
+ refreshResult.UpdateType |= ItemUpdateType.ImageUpdate;
+ }
+ catch (HttpRequestException ex)
+ {
+ Logger.LogError(ex, "Could not save {ImageType} image: {Url}", Enum.GetName(remoteImage.Type), remoteImage.Url);
+ }
}
if (imageService.MergeImages(item, localItem.Images))
@@ -711,7 +721,7 @@ namespace MediaBrowser.Providers.Manager
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error in {provider}", provider.Name);
+ Logger.LogError(ex, "Error in {Provider}", provider.Name);
// If a local provider fails, consider that a failure
refreshResult.ErrorMessage = ex.Message;
@@ -783,7 +793,7 @@ namespace MediaBrowser.Providers.Manager
catch (Exception ex)
{
refreshResult.ErrorMessage = ex.Message;
- Logger.LogError(ex, "Error in {provider}", provider.Name);
+ Logger.LogError(ex, "Error in {Provider}", provider.Name);
}
}
@@ -835,7 +845,7 @@ namespace MediaBrowser.Providers.Manager
{
refreshResult.Failures++;
refreshResult.ErrorMessage = ex.Message;
- Logger.LogError(ex, "Error in {provider}", provider.Name);
+ Logger.LogError(ex, "Error in {Provider}", provider.Name);
}
}
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index b51a25417..0385ce6a7 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -9,7 +11,9 @@ using System.Net.Http;
using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using Jellyfin.Data.Events;
+using Jellyfin.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Progress;
using MediaBrowser.Controller;
@@ -210,8 +214,7 @@ namespace MediaBrowser.Providers.Manager
throw new ArgumentNullException(nameof(source));
}
- var fileStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
-
+ var fileStream = AsyncFile.OpenRead(source);
return new ImageSaver(_configurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, fileStream, mimeType, type, imageIndex, saveLocallyWithMedia, cancellationToken);
}
@@ -658,7 +661,7 @@ namespace MediaBrowser.Providers.Manager
/// <inheritdoc/>
public void SaveMetadata(BaseItem item, ItemUpdateType updateType, IEnumerable<string> savers)
{
- SaveMetadata(item, updateType, _savers.Where(i => savers.Contains(i.Name, StringComparer.OrdinalIgnoreCase)));
+ SaveMetadata(item, updateType, _savers.Where(i => savers.Contains(i.Name, StringComparison.OrdinalIgnoreCase)));
}
/// <summary>
@@ -735,7 +738,7 @@ namespace MediaBrowser.Providers.Manager
{
if (libraryOptions.MetadataSavers == null)
{
- if (options.DisabledMetadataSavers.Contains(saver.Name, StringComparer.OrdinalIgnoreCase))
+ if (options.DisabledMetadataSavers.Contains(saver.Name, StringComparison.OrdinalIgnoreCase))
{
return false;
}
@@ -761,7 +764,7 @@ namespace MediaBrowser.Providers.Manager
}
else
{
- if (!libraryOptions.MetadataSavers.Contains(saver.Name, StringComparer.OrdinalIgnoreCase))
+ if (!libraryOptions.MetadataSavers.Contains(saver.Name, StringComparison.OrdinalIgnoreCase))
{
return false;
}
@@ -1132,7 +1135,7 @@ namespace MediaBrowser.Providers.Manager
var albums = _libraryManager
.GetItemList(new InternalItemsQuery
{
- IncludeItemTypes = new[] { nameof(MusicAlbum) },
+ IncludeItemTypes = new[] { BaseItemKind.MusicAlbum },
ArtistIds = new[] { item.Id },
DtoOptions = new DtoOptions(false)
{
diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs
index 6d088e6e7..b90136d50 100644
--- a/MediaBrowser.Providers/Manager/ProviderUtils.cs
+++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
#pragma warning disable CS1591
using System;
diff --git a/MediaBrowser.Providers/Manager/RefreshResult.cs b/MediaBrowser.Providers/Manager/RefreshResult.cs
index 72fc61e42..663ffc524 100644
--- a/MediaBrowser.Providers/Manager/RefreshResult.cs
+++ b/MediaBrowser.Providers/Manager/RefreshResult.cs
@@ -8,7 +8,7 @@ namespace MediaBrowser.Providers.Manager
{
public ItemUpdateType UpdateType { get; set; }
- public string ErrorMessage { get; set; }
+ public string? ErrorMessage { get; set; }
public int Failures { get; set; }
}