mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-21 17:44:43 +01:00
re-factored some file system access
This commit is contained in:
@@ -31,7 +31,7 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// </summary>
|
||||
/// <value>The image enhancers.</value>
|
||||
public IEnumerable<IImageEnhancer> ImageEnhancers { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image size cache.
|
||||
/// </summary>
|
||||
@@ -106,9 +106,10 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <param name="maxWidth">Use if a max width is required. Aspect ratio will be preserved.</param>
|
||||
/// <param name="maxHeight">Use if a max height is required. Aspect ratio will be preserved.</param>
|
||||
/// <param name="quality">Quality level, from 0-100. Currently only applies to JPG. The default value should suffice.</param>
|
||||
/// <param name="enhancers">The enhancers.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">entity</exception>
|
||||
public async Task ProcessImage(BaseItem entity, ImageType imageType, int imageIndex, bool cropWhitespace, DateTime dateModified, Stream toStream, int? width, int? height, int? maxWidth, int? maxHeight, int? quality)
|
||||
public async Task ProcessImage(BaseItem entity, ImageType imageType, int imageIndex, bool cropWhitespace, DateTime dateModified, Stream toStream, int? width, int? height, int? maxWidth, int? maxHeight, int? quality, List<IImageEnhancer> enhancers)
|
||||
{
|
||||
if (entity == null)
|
||||
{
|
||||
@@ -127,28 +128,13 @@ namespace MediaBrowser.Controller.Drawing
|
||||
originalImagePath = await GetCroppedImage(originalImagePath, dateModified).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var supportedEnhancers = ImageEnhancers.Where(i =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return i.Supports(entity, imageType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error in image enhancer: {0}", ex, i.GetType().Name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}).ToList();
|
||||
|
||||
// No enhancement - don't cache
|
||||
if (supportedEnhancers.Count > 0)
|
||||
if (enhancers.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Enhance if we have enhancers
|
||||
var ehnancedImagePath = await GetEnhancedImage(originalImagePath, dateModified, entity, imageType, imageIndex, supportedEnhancers).ConfigureAwait(false);
|
||||
var ehnancedImagePath = await GetEnhancedImage(originalImagePath, dateModified, entity, imageType, imageIndex, enhancers).ConfigureAwait(false);
|
||||
|
||||
// If the path changed update dateModified
|
||||
if (!ehnancedImagePath.Equals(originalImagePath, StringComparison.OrdinalIgnoreCase))
|
||||
@@ -175,6 +161,19 @@ namespace MediaBrowser.Controller.Drawing
|
||||
|
||||
var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality.Value, dateModified);
|
||||
|
||||
try
|
||||
{
|
||||
using (var fileStream = new FileStream(cacheFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
|
||||
{
|
||||
await fileStream.CopyToAsync(toStream).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Cache file doesn't exist or is currently being written ro
|
||||
}
|
||||
|
||||
var semaphore = GetLock(cacheFilePath);
|
||||
|
||||
await semaphore.WaitAsync().ConfigureAwait(false);
|
||||
@@ -262,6 +261,13 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <param name="bytes">The bytes.</param>
|
||||
private async Task CacheResizedImage(string cacheFilePath, byte[] bytes)
|
||||
{
|
||||
var parentPath = Path.GetDirectoryName(cacheFilePath);
|
||||
|
||||
if (!Directory.Exists(parentPath))
|
||||
{
|
||||
Directory.CreateDirectory(parentPath);
|
||||
}
|
||||
|
||||
// Save to the cache location
|
||||
using (var cacheFileStream = new FileStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous))
|
||||
{
|
||||
@@ -323,7 +329,7 @@ namespace MediaBrowser.Controller.Drawing
|
||||
}
|
||||
|
||||
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the image.
|
||||
/// </summary>
|
||||
@@ -335,25 +341,53 @@ namespace MediaBrowser.Controller.Drawing
|
||||
// Now check the file system cache
|
||||
var fullCachePath = ImageSizeCache.GetResourcePath(keyName, ".txt");
|
||||
|
||||
try
|
||||
{
|
||||
var result = File.ReadAllText(fullCachePath).Split('|').Select(i => double.Parse(i, UsCulture)).ToArray();
|
||||
|
||||
return new ImageSize { Width = result[0], Height = result[1] };
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Cache file doesn't exist or is currently being written to
|
||||
}
|
||||
|
||||
var semaphore = GetLock(fullCachePath);
|
||||
|
||||
await semaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = File.ReadAllText(fullCachePath).Split('|').Select(i => double.Parse(i, UsCulture)).ToArray();
|
||||
var result = File.ReadAllText(fullCachePath).Split('|').Select(i => double.Parse(i, UsCulture)).ToArray();
|
||||
|
||||
return new ImageSize { Width = result[0], Height = result[1] };
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
// Cache file doesn't exist no biggie
|
||||
}
|
||||
return new ImageSize { Width = result[0], Height = result[1] };
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
// Cache file doesn't exist no biggie
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
// Cache file doesn't exist no biggie
|
||||
}
|
||||
catch
|
||||
{
|
||||
semaphore.Release();
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var size = await ImageHeader.GetDimensions(imagePath, _logger).ConfigureAwait(false);
|
||||
|
||||
var parentPath = Path.GetDirectoryName(fullCachePath);
|
||||
|
||||
if (!Directory.Exists(parentPath))
|
||||
{
|
||||
Directory.CreateDirectory(parentPath);
|
||||
}
|
||||
|
||||
// Update the file system cache
|
||||
File.WriteAllText(fullCachePath, size.Width.ToString(UsCulture) + @"|" + size.Height.ToString(UsCulture));
|
||||
|
||||
@@ -490,12 +524,12 @@ namespace MediaBrowser.Controller.Drawing
|
||||
await semaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
// Check again in case of contention
|
||||
if (CroppedImageCache.ContainsFilePath(croppedImagePath))
|
||||
if (File.Exists(croppedImagePath))
|
||||
{
|
||||
semaphore.Release();
|
||||
return croppedImagePath;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var fileStream = new FileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
|
||||
@@ -511,6 +545,13 @@ namespace MediaBrowser.Controller.Drawing
|
||||
|
||||
using (var croppedImage = originalImage.CropWhitespace())
|
||||
{
|
||||
var parentPath = Path.GetDirectoryName(croppedImagePath);
|
||||
|
||||
if (!Directory.Exists(parentPath))
|
||||
{
|
||||
Directory.CreateDirectory(parentPath);
|
||||
}
|
||||
|
||||
using (var outputStream = new FileStream(croppedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
croppedImage.Save(outputFormat, outputStream, 100);
|
||||
@@ -568,7 +609,7 @@ namespace MediaBrowser.Controller.Drawing
|
||||
await semaphore.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
// Check again in case of contention
|
||||
if (EnhancedImageCache.ContainsFilePath(enhancedImagePath))
|
||||
if (File.Exists(enhancedImagePath))
|
||||
{
|
||||
semaphore.Release();
|
||||
return enhancedImagePath;
|
||||
@@ -588,6 +629,13 @@ namespace MediaBrowser.Controller.Drawing
|
||||
//Pass the image through registered enhancers
|
||||
using (var newImage = await ExecuteImageEnhancers(supportedEnhancers, originalImage, item, imageType, imageIndex).ConfigureAwait(false))
|
||||
{
|
||||
var parentDirectory = Path.GetDirectoryName(enhancedImagePath);
|
||||
|
||||
if (!Directory.Exists(parentDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(parentDirectory);
|
||||
}
|
||||
|
||||
//And then save it in the cache
|
||||
using (var outputStream = new FileStream(enhancedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
|
||||
@@ -304,7 +304,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <summary>
|
||||
/// We attach these to the item so that we only ever have to hit the file system once
|
||||
/// (this includes the children of the containing folder)
|
||||
/// Use ResolveArgs.FileSystemDictionary to check for the existence of files instead of File.Exists
|
||||
/// </summary>
|
||||
/// <value>The resolve args.</value>
|
||||
[IgnoreDataMember]
|
||||
|
||||
@@ -19,10 +19,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
public static IUserManager UserManager { get; set; }
|
||||
public static IXmlSerializer XmlSerializer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The _root folder path
|
||||
/// </summary>
|
||||
private string _rootFolderPath;
|
||||
/// <summary>
|
||||
/// Gets the root folder path.
|
||||
/// </summary>
|
||||
@@ -32,23 +28,19 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_rootFolderPath == null)
|
||||
if (Configuration.UseCustomLibrary)
|
||||
{
|
||||
if (Configuration.UseCustomLibrary)
|
||||
{
|
||||
_rootFolderPath = GetRootFolderPath(Name);
|
||||
var rootFolderPath = GetRootFolderPath(Name);
|
||||
|
||||
if (!Directory.Exists(_rootFolderPath))
|
||||
{
|
||||
Directory.CreateDirectory(_rootFolderPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!Directory.Exists(rootFolderPath))
|
||||
{
|
||||
_rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
Directory.CreateDirectory(rootFolderPath);
|
||||
}
|
||||
|
||||
return rootFolderPath;
|
||||
}
|
||||
return _rootFolderPath;
|
||||
|
||||
return ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +253,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
// Force these to be lazy loaded again
|
||||
_configurationDirectoryPath = null;
|
||||
_rootFolderPath = null;
|
||||
RootFolder = null;
|
||||
|
||||
// Kick off a task to validate the media library
|
||||
@@ -378,7 +369,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
// Force these to be lazy loaded again
|
||||
if (customLibraryChanged)
|
||||
{
|
||||
_rootFolderPath = null;
|
||||
RootFolder = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,10 +55,6 @@ namespace MediaBrowser.Controller.MediaInfo
|
||||
SubtitleCache = new FileSystemRepository(SubtitleCachePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The _video images data path
|
||||
/// </summary>
|
||||
private string _videoImagesDataPath;
|
||||
/// <summary>
|
||||
/// Gets the video images data path.
|
||||
/// </summary>
|
||||
@@ -67,24 +63,10 @@ namespace MediaBrowser.Controller.MediaInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_videoImagesDataPath == null)
|
||||
{
|
||||
_videoImagesDataPath = Path.Combine(_appPaths.DataPath, "extracted-video-images");
|
||||
|
||||
if (!Directory.Exists(_videoImagesDataPath))
|
||||
{
|
||||
Directory.CreateDirectory(_videoImagesDataPath);
|
||||
}
|
||||
}
|
||||
|
||||
return _videoImagesDataPath;
|
||||
return Path.Combine(_appPaths.DataPath, "extracted-video-images");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The _audio images data path
|
||||
/// </summary>
|
||||
private string _audioImagesDataPath;
|
||||
/// <summary>
|
||||
/// Gets the audio images data path.
|
||||
/// </summary>
|
||||
@@ -93,24 +75,10 @@ namespace MediaBrowser.Controller.MediaInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_audioImagesDataPath == null)
|
||||
{
|
||||
_audioImagesDataPath = Path.Combine(_appPaths.DataPath, "extracted-audio-images");
|
||||
|
||||
if (!Directory.Exists(_audioImagesDataPath))
|
||||
{
|
||||
Directory.CreateDirectory(_audioImagesDataPath);
|
||||
}
|
||||
}
|
||||
|
||||
return _audioImagesDataPath;
|
||||
return Path.Combine(_appPaths.DataPath, "extracted-audio-images");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The _subtitle cache path
|
||||
/// </summary>
|
||||
private string _subtitleCachePath;
|
||||
/// <summary>
|
||||
/// Gets the subtitle cache path.
|
||||
/// </summary>
|
||||
@@ -119,17 +87,7 @@ namespace MediaBrowser.Controller.MediaInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_subtitleCachePath == null)
|
||||
{
|
||||
_subtitleCachePath = Path.Combine(_appPaths.CachePath, "subtitles");
|
||||
|
||||
if (!Directory.Exists(_subtitleCachePath))
|
||||
{
|
||||
Directory.CreateDirectory(_subtitleCachePath);
|
||||
}
|
||||
}
|
||||
|
||||
return _subtitleCachePath;
|
||||
return Path.Combine(_appPaths.CachePath, "subtitles");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +135,7 @@ namespace MediaBrowser.Controller.MediaInfo
|
||||
|
||||
var path = VideoImageCache.GetResourcePath(filename, ".jpg");
|
||||
|
||||
if (!VideoImageCache.ContainsFilePath(path))
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
if (extractImages)
|
||||
{
|
||||
@@ -204,6 +162,13 @@ namespace MediaBrowser.Controller.MediaInfo
|
||||
|
||||
try
|
||||
{
|
||||
var parentPath = Path.GetDirectoryName(path);
|
||||
|
||||
if (!Directory.Exists(parentPath))
|
||||
{
|
||||
Directory.CreateDirectory(parentPath);
|
||||
}
|
||||
|
||||
await _encoder.ExtractImage(inputPath, type, time, path, cancellationToken).ConfigureAwait(false);
|
||||
chapter.ImagePath = path;
|
||||
changesMade = true;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using MediaBrowser.Common.IO;
|
||||
using System.IO;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.MediaInfo;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
@@ -156,7 +157,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
||||
|
||||
var path = ImageCache.GetResourcePath(filename + "_primary", ".jpg");
|
||||
|
||||
if (!ImageCache.ContainsFilePath(path))
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
var semaphore = GetLock(path);
|
||||
|
||||
@@ -164,10 +165,17 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
||||
await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Check again
|
||||
if (!ImageCache.ContainsFilePath(path))
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
var parentPath = Path.GetDirectoryName(path);
|
||||
|
||||
if (!Directory.Exists(parentPath))
|
||||
{
|
||||
Directory.CreateDirectory(parentPath);
|
||||
}
|
||||
|
||||
await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.AudioFile, null, path, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
|
||||
Reference in New Issue
Block a user