diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations')
6 files changed, 117 insertions, 62 deletions
diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index a439251db..78dcf6fd0 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -3,11 +3,11 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -25,7 +25,7 @@ namespace MediaBrowser.Server.Implementations.Drawing /// <summary> /// Class ImageProcessor /// </summary> - public class ImageProcessor : IImageProcessor + public class ImageProcessor : IImageProcessor, IDisposable { /// <summary> /// The us culture @@ -35,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.Drawing /// <summary> /// The _cached imaged sizes /// </summary> - private readonly ConcurrentDictionary<string, ImageSize> _cachedImagedSizes = new ConcurrentDictionary<string, ImageSize>(); + private readonly ConcurrentDictionary<Guid, ImageSize> _cachedImagedSizes; /// <summary> /// Gets the list of currently registered image processors @@ -50,21 +50,41 @@ namespace MediaBrowser.Server.Implementations.Drawing private readonly ILogger _logger; private readonly IFileSystem _fileSystem; + private readonly IJsonSerializer _jsonSerializer; + private readonly IServerApplicationPaths _appPaths; private readonly string _imageSizeCachePath; private readonly string _croppedWhitespaceImageCachePath; private readonly string _enhancedImageCachePath; private readonly string _resizedImageCachePath; - public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem) + public ImageProcessor(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer jsonSerializer) { _logger = logger; _fileSystem = fileSystem; + _jsonSerializer = jsonSerializer; + _appPaths = appPaths; _imageSizeCachePath = Path.Combine(appPaths.ImageCachePath, "image-sizes"); _croppedWhitespaceImageCachePath = Path.Combine(appPaths.ImageCachePath, "cropped-images"); _enhancedImageCachePath = Path.Combine(appPaths.ImageCachePath, "enhanced-images"); _resizedImageCachePath = Path.Combine(appPaths.ImageCachePath, "resized-images"); + + _saveImageSizeTimer = new Timer(SaveImageSizeCallback, null, Timeout.Infinite, Timeout.Infinite); + + Dictionary<Guid, ImageSize> sizeDictionary; + + try + { + sizeDictionary = jsonSerializer.DeserializeFromFile<Dictionary<Guid, ImageSize>>(ImageSizeFile); + } + catch (IOException) + { + // No biggie + sizeDictionary = new Dictionary<Guid, ImageSize>(); + } + + _cachedImagedSizes = new ConcurrentDictionary<Guid, ImageSize>(sizeDictionary); } public void AddParts(IEnumerable<IImageEnhancer> enhancers) @@ -85,6 +105,17 @@ namespace MediaBrowser.Server.Implementations.Drawing } var originalImagePath = options.OriginalImagePath; + + if (options.HasDefaultOptions()) + { + // Just spit out the original file if all the options are default + using (var fileStream = _fileSystem.GetFileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) + { + await fileStream.CopyToAsync(toStream).ConfigureAwait(false); + return; + } + } + var dateModified = options.OriginalImageDateModified; if (options.CropWhiteSpace) @@ -106,6 +137,16 @@ namespace MediaBrowser.Server.Implementations.Drawing // Determine the output size based on incoming parameters var newSize = DrawingUtils.Resize(originalImageSize, options.Width, options.Height, options.MaxWidth, options.MaxHeight); + if (options.HasDefaultOptionsWithoutSize() && newSize.Equals(originalImageSize)) + { + // Just spit out the original file the new size equals the old + using (var fileStream = _fileSystem.GetFileStream(originalImagePath, FileMode.Open, FileAccess.Read, FileShare.Read, true)) + { + await fileStream.CopyToAsync(toStream).ConfigureAwait(false); + return; + } + } + var quality = options.Quality ?? 90; var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, options.OutputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.BackgroundColor); @@ -465,11 +506,13 @@ namespace MediaBrowser.Server.Implementations.Drawing ImageSize size; - if (!_cachedImagedSizes.TryGetValue(name, out size)) + var cacheHash = name.GetMD5(); + + if (!_cachedImagedSizes.TryGetValue(cacheHash, out size)) { - size = GetImageSizeInternal(name, path); + size = GetImageSizeInternal(path); - _cachedImagedSizes.AddOrUpdate(name, size, (keyName, oldValue) => size); + _cachedImagedSizes.AddOrUpdate(cacheHash, size, (keyName, oldValue) => size); } return size; @@ -478,62 +521,47 @@ namespace MediaBrowser.Server.Implementations.Drawing /// <summary> /// Gets the image size internal. /// </summary> - /// <param name="cacheKey">The cache key.</param> /// <param name="path">The path.</param> /// <returns>ImageSize.</returns> - private ImageSize GetImageSizeInternal(string cacheKey, string path) + private ImageSize GetImageSizeInternal(string path) { - // Now check the file system cache - var fullCachePath = GetCachePath(_imageSizeCachePath, cacheKey, ".txt"); + var size = ImageHeader.GetDimensions(path, _logger, _fileSystem); - try - { - var result = File.ReadAllText(fullCachePath).Split('|'); + StartSaveImageSizeTimer(); - return new ImageSize - { - Width = double.Parse(result[0], UsCulture), - Height = double.Parse(result[1], UsCulture) - }; - } - catch (IOException) - { - // Cache file doesn't exist or is currently being written to - } + return new ImageSize { Width = size.Width, Height = size.Height }; + } - var syncLock = GetObjectLock(fullCachePath); + private readonly Timer _saveImageSizeTimer; + private const int SaveImageSizeTimeout = 5000; + private readonly object _saveImageSizeLock = new object(); + private void StartSaveImageSizeTimer() + { + _saveImageSizeTimer.Change(SaveImageSizeTimeout, Timeout.Infinite); + } - lock (syncLock) + private void SaveImageSizeCallback(object state) + { + lock (_saveImageSizeLock) { try { - var result = File.ReadAllText(fullCachePath).Split('|'); - - return new ImageSize - { - Width = double.Parse(result[0], UsCulture), - Height = double.Parse(result[1], UsCulture) - }; - } - catch (FileNotFoundException) - { - // Cache file doesn't exist no biggie + var path = ImageSizeFile; + Directory.CreateDirectory(Path.GetDirectoryName(path)); + _jsonSerializer.SerializeToFile(_cachedImagedSizes, path); } - catch (DirectoryNotFoundException) + catch (Exception ex) { - // Cache file doesn't exist no biggie + _logger.ErrorException("Error saving image size file", ex); } + } + } - var size = ImageHeader.GetDimensions(path, _logger, _fileSystem); - - var parentPath = Path.GetDirectoryName(fullCachePath); - - Directory.CreateDirectory(parentPath); - - // Update the file system cache - File.WriteAllText(fullCachePath, size.Width.ToString(UsCulture) + @"|" + size.Height.ToString(UsCulture)); - - return new ImageSize { Width = size.Width, Height = size.Height }; + private string ImageSizeFile + { + get + { + return Path.Combine(_appPaths.DataPath, "imagesizes.json"); } } @@ -862,5 +890,10 @@ namespace MediaBrowser.Server.Implementations.Drawing }).ToList(); } + + public void Dispose() + { + _saveImageSizeTimer.Dispose(); + } } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 19e19f8ea..0104196e0 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -792,11 +792,15 @@ namespace MediaBrowser.Server.Implementations.Dto dto.MediaType = item.MediaType; dto.LocationType = item.LocationType; - dto.CriticRating = item.CriticRating; - - if (fields.Contains(ItemFields.CriticRatingSummary)) + var hasCriticRating = item as IHasCriticRating; + if (hasCriticRating != null) { - dto.CriticRatingSummary = item.CriticRatingSummary; + dto.CriticRating = hasCriticRating.CriticRating; + + if (fields.Contains(ItemFields.CriticRatingSummary)) + { + dto.CriticRatingSummary = hasCriticRating.CriticRatingSummary; + } } var localTrailerCount = item.LocalTrailerIds.Count; diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs index 5f354fb0d..7d049549b 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs @@ -181,6 +181,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// <param name="dto">The dto.</param> private void FilterResponse(IHttpRequest req, IHttpResponse res, object dto) { + // Try to prevent compatibility view + res.AddHeader("X-UA-Compatible", "IE=Edge"); + var exception = dto as Exception; if (exception != null) diff --git a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs index 9fc622c21..a8c923bb0 100644 --- a/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs +++ b/MediaBrowser.Server.Implementations/IO/DirectoryWatchers.cs @@ -363,6 +363,7 @@ namespace MediaBrowser.Server.Implementations.IO { if (string.Equals(i, e.FullPath, StringComparison.OrdinalIgnoreCase)) { + Logger.Debug("Watcher ignoring change to {0}", e.FullPath); return true; } @@ -370,6 +371,7 @@ namespace MediaBrowser.Server.Implementations.IO var parent = Path.GetDirectoryName(i); if (string.Equals(parent, e.FullPath, StringComparison.OrdinalIgnoreCase)) { + Logger.Debug("Watcher ignoring change to {0}", e.FullPath); return true; } @@ -379,10 +381,18 @@ namespace MediaBrowser.Server.Implementations.IO parent = Path.GetDirectoryName(i); if (string.Equals(parent, e.FullPath, StringComparison.OrdinalIgnoreCase)) { + Logger.Debug("Watcher ignoring change to {0}", e.FullPath); return true; } } + if (i.StartsWith(e.FullPath, StringComparison.OrdinalIgnoreCase) || + e.FullPath.StartsWith(i, StringComparison.OrdinalIgnoreCase)) + { + Logger.Debug("Watcher ignoring change to {0}", e.FullPath); + return true; + } + return false; })) @@ -390,12 +400,6 @@ namespace MediaBrowser.Server.Implementations.IO return; } - if (tempIgnorePaths.Contains(e.FullPath, StringComparer.OrdinalIgnoreCase)) - { - Logger.Debug("Watcher requested to ignore change to " + e.FullPath); - return; - } - Logger.Info("Watcher sees change of type " + e.ChangeType + " to " + e.FullPath); //Since we're watching created, deleted and renamed we always want the parent of the item to be the affected path diff --git a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs index f46498599..0ed46e761 100644 --- a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs +++ b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -8,6 +7,7 @@ using MediaBrowser.Controller.IO; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; @@ -70,6 +70,15 @@ namespace MediaBrowser.Server.Implementations.Providers throw new ArgumentNullException("mimeType"); } + if (type == ImageType.Backdrop && imageIndex == null) + { + imageIndex = item.BackdropImagePaths.Count; + } + else if (type == ImageType.Screenshot && imageIndex == null) + { + imageIndex = item.ScreenshotImagePaths.Count; + } + var saveLocally = _config.Configuration.SaveLocalMeta && item.Parent != null && !(item is Audio); if (item is IItemByName || item is User) diff --git a/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs b/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs index 9484130cb..d01f7ed1b 100644 --- a/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs @@ -22,7 +22,9 @@ namespace MediaBrowser.Server.Implementations.Sorting private float GetValue(BaseItem x) { - return x.CriticRating ?? 0; + var hasCriticRating = x as IHasCriticRating; + + return hasCriticRating == null ? 0 : hasCriticRating.CriticRating ?? 0; } /// <summary> |
