From f775f7c1fa6455aabda6a988ec5e43b52c896a39 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 6 Nov 2013 10:45:40 -0500 Subject: try to forcefully prevent compatibility view --- MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'MediaBrowser.Server.Implementations') 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 /// The dto. 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) -- cgit v1.2.3 From a4cea5a5d326677bf74da6bf7df2203c12088d38 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 6 Nov 2013 11:06:16 -0500 Subject: added critic rating interface --- MediaBrowser.Api/ItemUpdateService.cs | 8 +++-- MediaBrowser.Api/UserLibrary/ItemsService.cs | 12 +++++++- MediaBrowser.Controller/Entities/BaseItem.cs | 12 -------- .../Entities/IHasCriticRating.cs | 20 +++++++++++++ MediaBrowser.Controller/Entities/Movies/Movie.cs | 14 ++++++++- MediaBrowser.Controller/Entities/Trailer.cs | 14 ++++++++- .../MediaBrowser.Controller.csproj | 1 + .../Providers/BaseItemXmlParser.cs | 19 +++++++++--- .../Movies/OpenMovieDatabaseProvider.cs | 34 ++++++++++++---------- MediaBrowser.Providers/Savers/XmlSaverHelpers.cs | 16 ++++++---- .../Dto/DtoService.cs | 12 +++++--- .../Sorting/CriticRatingComparer.cs | 4 ++- 12 files changed, 119 insertions(+), 47 deletions(-) create mode 100644 MediaBrowser.Controller/Entities/IHasCriticRating.cs (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index ace8c4a6e..6e1dbc08b 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -219,8 +219,12 @@ namespace MediaBrowser.Api item.Budget = request.Budget; item.Revenue = request.Revenue; - item.CriticRating = request.CriticRating; - item.CriticRatingSummary = request.CriticRatingSummary; + var hasCriticRating = item as IHasCriticRating; + if (hasCriticRating != null) + { + hasCriticRating.CriticRating = request.CriticRating; + hasCriticRating.CriticRatingSummary = request.CriticRatingSummary; + } item.DisplayMediaType = request.DisplayMediaType; item.CommunityRating = request.CommunityRating; diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 29a894b1c..9547cc0a4 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -581,7 +581,17 @@ namespace MediaBrowser.Api.UserLibrary { var val = request.MinCriticRating.Value; - items = items.Where(i => i.CriticRating.HasValue && i.CriticRating >= val); + items = items.Where(i => + { + var hasCriticRating = i as IHasCriticRating; + + if (hasCriticRating != null) + { + return hasCriticRating.CriticRating.HasValue && hasCriticRating.CriticRating >= val; + } + + return false; + }); } // Artists diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 839fe34ff..f8b2fad23 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -111,18 +111,6 @@ namespace MediaBrowser.Controller.Entities /// The revenue. public double? Revenue { get; set; } - /// - /// Gets or sets the critic rating. - /// - /// The critic rating. - public float? CriticRating { get; set; } - - /// - /// Gets or sets the critic rating summary. - /// - /// The critic rating summary. - public string CriticRatingSummary { get; set; } - /// /// Gets or sets the trailer URL. /// diff --git a/MediaBrowser.Controller/Entities/IHasCriticRating.cs b/MediaBrowser.Controller/Entities/IHasCriticRating.cs new file mode 100644 index 000000000..d2b93759d --- /dev/null +++ b/MediaBrowser.Controller/Entities/IHasCriticRating.cs @@ -0,0 +1,20 @@ +namespace MediaBrowser.Controller.Entities +{ + /// + /// Interface IHasCriticRating + /// + public interface IHasCriticRating + { + /// + /// Gets or sets the critic rating. + /// + /// The critic rating. + float? CriticRating { get; set; } + + /// + /// Gets or sets the critic rating summary. + /// + /// The critic rating summary. + string CriticRatingSummary { get; set; } + } +} diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 516ee9a8a..54ad9c1c9 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Controller.Entities.Movies /// /// Class Movie /// - public class Movie : Video + public class Movie : Video, IHasCriticRating { public List SpecialFeatureIds { get; set; } @@ -20,6 +20,18 @@ namespace MediaBrowser.Controller.Entities.Movies SpecialFeatureIds = new List(); } + /// + /// Gets or sets the critic rating. + /// + /// The critic rating. + public float? CriticRating { get; set; } + + /// + /// Gets or sets the critic rating summary. + /// + /// The critic rating summary. + public string CriticRatingSummary { get; set; } + /// /// Gets or sets the name of the TMDB collection. /// diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs index e7d47f7ec..c9fe471b3 100644 --- a/MediaBrowser.Controller/Entities/Trailer.cs +++ b/MediaBrowser.Controller/Entities/Trailer.cs @@ -7,7 +7,7 @@ namespace MediaBrowser.Controller.Entities /// /// Class Trailer /// - public class Trailer : Video + public class Trailer : Video, IHasCriticRating { public Trailer() { @@ -15,6 +15,18 @@ namespace MediaBrowser.Controller.Entities Taglines = new List(); } + /// + /// Gets or sets the critic rating. + /// + /// The critic rating. + public float? CriticRating { get; set; } + + /// + /// Gets or sets the critic rating summary. + /// + /// The critic rating summary. + public string CriticRatingSummary { get; set; } + /// /// Gets a value indicating whether this instance is local trailer. /// diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 978d56bd4..94ff5d305 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -89,6 +89,7 @@ + diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs index e9bb7f66d..9fdbbf3b7 100644 --- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs +++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs @@ -143,10 +143,16 @@ namespace MediaBrowser.Controller.Providers case "CriticRating": { var text = reader.ReadElementContentAsString(); - float value; - if (float.TryParse(text, NumberStyles.Any, _usCulture, out value)) + + var hasCriticRating = item as IHasCriticRating; + + if (hasCriticRating != null && !string.IsNullOrEmpty(text)) { - item.CriticRating = value; + float value; + if (float.TryParse(text, NumberStyles.Any, _usCulture, out value)) + { + hasCriticRating.CriticRating = value; + } } break; @@ -207,7 +213,12 @@ namespace MediaBrowser.Controller.Providers if (!string.IsNullOrWhiteSpace(val)) { - item.CriticRatingSummary = val; + var hasCriticRating = item as IHasCriticRating; + + if (hasCriticRating != null) + { + hasCriticRating.CriticRatingSummary = val; + } } break; diff --git a/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs b/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs index a6fdbdcef..6550396e5 100644 --- a/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs +++ b/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs @@ -139,22 +139,26 @@ namespace MediaBrowser.Providers.Movies { var result = JsonSerializer.DeserializeFromStream(stream); - // Seeing some bogus RT data on omdb for series, so filter it out here - // RT doesn't even have tv series - int tomatoMeter; - - if (!string.IsNullOrEmpty(result.tomatoMeter) - && int.TryParse(result.tomatoMeter, NumberStyles.Integer, UsCulture, out tomatoMeter) - && tomatoMeter >= 0) - { - item.CriticRating = tomatoMeter; - } - - if (!string.IsNullOrEmpty(result.tomatoConsensus) - && !string.Equals(result.tomatoConsensus, "n/a", StringComparison.OrdinalIgnoreCase) - && !string.Equals(result.tomatoConsensus, "No consensus yet.", StringComparison.OrdinalIgnoreCase)) + var hasCriticRating = item as IHasCriticRating; + if (hasCriticRating != null) { - item.CriticRatingSummary = result.tomatoConsensus; + // Seeing some bogus RT data on omdb for series, so filter it out here + // RT doesn't even have tv series + int tomatoMeter; + + if (!string.IsNullOrEmpty(result.tomatoMeter) + && int.TryParse(result.tomatoMeter, NumberStyles.Integer, UsCulture, out tomatoMeter) + && tomatoMeter >= 0) + { + hasCriticRating.CriticRating = tomatoMeter; + } + + if (!string.IsNullOrEmpty(result.tomatoConsensus) + && !string.Equals(result.tomatoConsensus, "n/a", StringComparison.OrdinalIgnoreCase) + && !string.Equals(result.tomatoConsensus, "No consensus yet.", StringComparison.OrdinalIgnoreCase)) + { + hasCriticRating.CriticRatingSummary = result.tomatoConsensus; + } } int voteCount; diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs index d9e0fb6e2..69276e0b8 100644 --- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs +++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs @@ -209,14 +209,18 @@ namespace MediaBrowser.Providers.Savers builder.Append("" + SecurityElement.Escape(item.DisplayMediaType) + ""); } - if (item.CriticRating.HasValue) + var hasCriticRating = item as IHasCriticRating; + if (hasCriticRating != null) { - builder.Append("" + SecurityElement.Escape(item.CriticRating.Value.ToString(UsCulture)) + ""); - } + if (hasCriticRating.CriticRating.HasValue) + { + builder.Append("" + SecurityElement.Escape(hasCriticRating.CriticRating.Value.ToString(UsCulture)) + ""); + } - if (!string.IsNullOrEmpty(item.CriticRatingSummary)) - { - builder.Append(""); + if (!string.IsNullOrEmpty(hasCriticRating.CriticRatingSummary)) + { + builder.Append(""); + } } if (!string.IsNullOrEmpty(item.Overview)) 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/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; } /// -- cgit v1.2.3 From a2cd03610fd8fedc55699f43bf4a169dc5072aa8 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 6 Nov 2013 16:32:26 -0500 Subject: Serve original image file when possible --- .../Drawing/ImageProcessingOptions.cs | 32 ++++++++++++++++++++++ MediaBrowser.Model/Drawing/DrawingUtils.cs | 5 ++++ .../Drawing/ImageProcessor.cs | 22 ++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs index 76a079c57..9222a8907 100644 --- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs +++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs @@ -40,5 +40,37 @@ namespace MediaBrowser.Controller.Drawing public int? PercentPlayed { get; set; } public string BackgroundColor { get; set; } + + public bool HasDefaultOptions() + { + return HasDefaultOptionsWithoutSize() && + !Width.HasValue && + !Height.HasValue && + !MaxWidth.HasValue && + !MaxHeight.HasValue; + } + + public bool HasDefaultOptionsWithoutSize() + { + return !CropWhiteSpace && + (!Quality.HasValue || Quality.Value == 100) && + IsOutputFormatDefault && + !AddPlayedIndicator && + !PercentPlayed.HasValue && + string.IsNullOrEmpty(BackgroundColor); + } + + private bool IsOutputFormatDefault + { + get + { + if (OutputFormat == ImageOutputFormat.Original) + { + return true; + } + + return false; + } + } } } diff --git a/MediaBrowser.Model/Drawing/DrawingUtils.cs b/MediaBrowser.Model/Drawing/DrawingUtils.cs index fabe1b24c..8f66029fe 100644 --- a/MediaBrowser.Model/Drawing/DrawingUtils.cs +++ b/MediaBrowser.Model/Drawing/DrawingUtils.cs @@ -141,5 +141,10 @@ namespace MediaBrowser.Model.Drawing /// /// The width. public double Width { get; set; } + + public bool Equals(ImageSize size) + { + return Width.Equals(size.Width) && Height.Equals(size.Height); + } } } diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index a439251db..4379c8fad 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -3,7 +3,6 @@ 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; @@ -85,6 +84,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 +116,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); -- cgit v1.2.3 From 2fc662c9e9e5bc0730c37ef88eb3ff8476b301db Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 7 Nov 2013 10:57:12 -0500 Subject: optimize image processor when gdi can be skipped --- MediaBrowser.Model/Drawing/DrawingUtils.cs | 64 +++++++++++- MediaBrowser.Providers/Movies/MovieDbProvider.cs | 15 ++- .../Music/LastFmImageProvider.cs | 7 +- .../Drawing/ImageProcessor.cs | 113 ++++++++++++--------- .../IO/DirectoryWatchers.cs | 16 +-- .../Providers/ImageSaver.cs | 4 +- MediaBrowser.ServerApplication/ApplicationHost.cs | 2 +- 7 files changed, 152 insertions(+), 69 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Model/Drawing/DrawingUtils.cs b/MediaBrowser.Model/Drawing/DrawingUtils.cs index 8f66029fe..e95b5e375 100644 --- a/MediaBrowser.Model/Drawing/DrawingUtils.cs +++ b/MediaBrowser.Model/Drawing/DrawingUtils.cs @@ -1,4 +1,5 @@ - +using System.Globalization; + namespace MediaBrowser.Model.Drawing { /// @@ -131,20 +132,77 @@ namespace MediaBrowser.Model.Drawing /// public struct ImageSize { + private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); + + private double _height; + private double _width; + /// /// Gets or sets the height. /// /// The height. - public double Height { get; set; } + public double Height + { + get + { + return _height; + } + set + { + _height = value; + } + } + /// /// Gets or sets the width. /// /// The width. - public double Width { get; set; } + public double Width + { + get { return _width; } + set { _width = value; } + } public bool Equals(ImageSize size) { return Width.Equals(size.Width) && Height.Equals(size.Height); } + + public override string ToString() + { + return string.Format("{0}-{1}", Width, Height); + } + + public ImageSize(string value) + { + _width = 0; + + _height = 0; + + ParseValue(value); + } + + private void ParseValue(string value) + { + if (!string.IsNullOrEmpty(value)) + { + var parts = value.Split('-'); + + if (parts.Length == 2) + { + double val; + + if (double.TryParse(parts[0], NumberStyles.Any, UsCulture, out val)) + { + _width = val; + } + + if (double.TryParse(parts[1], NumberStyles.Any, UsCulture, out val)) + { + _height = val; + } + } + } + } } } diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 9d71fef0a..cc6e07d62 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -822,13 +822,18 @@ namespace MediaBrowser.Providers.Movies // genres // Movies get this from imdb - if (movieData.genres != null && !movie.LockedFields.Contains(MetadataFields.Genres) && movie is BoxSet) + if (movieData.genres != null && !movie.LockedFields.Contains(MetadataFields.Genres)) { - movie.Genres.Clear(); - - foreach (var genre in movieData.genres.Select(g => g.name)) + // Only grab them if a boxset or there are no genres. + // For movies and trailers we'll use imdb via omdb + if (movie is BoxSet || movie.Genres.Count == 0) { - movie.AddGenre(genre); + movie.Genres.Clear(); + + foreach (var genre in movieData.genres.Select(g => g.name)) + { + movie.AddGenre(genre); + } } } diff --git a/MediaBrowser.Providers/Music/LastFmImageProvider.cs b/MediaBrowser.Providers/Music/LastFmImageProvider.cs index 075f68b6a..cd4005223 100644 --- a/MediaBrowser.Providers/Music/LastFmImageProvider.cs +++ b/MediaBrowser.Providers/Music/LastFmImageProvider.cs @@ -70,9 +70,12 @@ namespace MediaBrowser.Providers.Music /// Task{System.Boolean}. public override async Task FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { - var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualLastFmImageProvider.ProviderName).ConfigureAwait(false); + if (!item.HasImage(ImageType.Primary)) + { + var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualLastFmImageProvider.ProviderName).ConfigureAwait(false); - await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false); + await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false); + } SetLastRefreshed(item, DateTime.UtcNow); diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs index 4379c8fad..78dcf6fd0 100644 --- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs +++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs @@ -7,6 +7,7 @@ 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; @@ -24,7 +25,7 @@ namespace MediaBrowser.Server.Implementations.Drawing /// /// Class ImageProcessor /// - public class ImageProcessor : IImageProcessor + public class ImageProcessor : IImageProcessor, IDisposable { /// /// The us culture @@ -34,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.Drawing /// /// The _cached imaged sizes /// - private readonly ConcurrentDictionary _cachedImagedSizes = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _cachedImagedSizes; /// /// Gets the list of currently registered image processors @@ -49,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 sizeDictionary; + + try + { + sizeDictionary = jsonSerializer.DeserializeFromFile>(ImageSizeFile); + } + catch (IOException) + { + // No biggie + sizeDictionary = new Dictionary(); + } + + _cachedImagedSizes = new ConcurrentDictionary(sizeDictionary); } public void AddParts(IEnumerable enhancers) @@ -84,7 +105,7 @@ namespace MediaBrowser.Server.Implementations.Drawing } var originalImagePath = options.OriginalImagePath; - + if (options.HasDefaultOptions()) { // Just spit out the original file if all the options are default @@ -125,7 +146,7 @@ namespace MediaBrowser.Server.Implementations.Drawing return; } } - + var quality = options.Quality ?? 90; var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, options.OutputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.BackgroundColor); @@ -485,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; @@ -498,62 +521,47 @@ namespace MediaBrowser.Server.Implementations.Drawing /// /// Gets the image size internal. /// - /// The cache key. /// The path. /// ImageSize. - 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"); } } @@ -882,5 +890,10 @@ namespace MediaBrowser.Server.Implementations.Drawing }).ToList(); } + + public void Dispose() + { + _saveImageSizeTimer.Dispose(); + } } } 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..dfbf0736b 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; diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index c5c5bc7e5..03819ff91 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -288,7 +288,7 @@ namespace MediaBrowser.ServerApplication LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager); RegisterSingleInstance(LocalizationManager); - ImageProcessor = new ImageProcessor(Logger, ServerConfigurationManager.ApplicationPaths, FileSystemManager); + ImageProcessor = new ImageProcessor(Logger, ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer); RegisterSingleInstance(ImageProcessor); DtoService = new DtoService(Logger, LibraryManager, UserManager, UserDataManager, ItemRepository, ImageProcessor); -- cgit v1.2.3 From 01f1ed05b9a401939ccbd586e07951c144232608 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 7 Nov 2013 11:48:23 -0500 Subject: remove need to pass in image index when adding backdrops --- .../DefaultTheme/DefaultThemeService.cs | 73 ++++++++++++++++++++++ MediaBrowser.Api/DefaultTheme/Models.cs | 3 + MediaBrowser.Api/Images/ImageService.cs | 13 +--- MediaBrowser.Api/Images/RemoteImageService.cs | 9 +-- .../Movies/FanArtMovieProvider.cs | 6 +- .../Movies/MovieDbImagesProvider.cs | 2 +- .../Music/FanArtArtistProvider.cs | 6 +- MediaBrowser.Providers/TV/FanArtTVProvider.cs | 6 +- MediaBrowser.Providers/TV/TvdbSeasonProvider.cs | 6 +- .../TV/TvdbSeriesImageProvider.cs | 6 +- .../Providers/ImageSaver.cs | 9 +++ 11 files changed, 93 insertions(+), 46 deletions(-) (limited to 'MediaBrowser.Server.Implementations') diff --git a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs b/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs index c0992a749..bb23f7f7e 100644 --- a/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs +++ b/MediaBrowser.Api/DefaultTheme/DefaultThemeService.cs @@ -471,6 +471,76 @@ namespace MediaBrowser.Api.DefaultTheme }).Where(i => i != null).ToList(); } + private void SetFavoriteGenres(MoviesView view, IEnumerable inputItems, User user) + { + var all = inputItems.SelectMany(i => i.Genres) + .Distinct(StringComparer.OrdinalIgnoreCase); + + view.FavoriteGenres = all.Select(i => + { + try + { + var itemByName = _libraryManager.GetGenre(i); + + var counts = itemByName.GetItemByNameCounts(user); + + var count = counts == null ? 0 : counts.MovieCount; + + if (count > 0 && _userDataManager.GetUserData(user.Id, itemByName.GetUserDataKey()).IsFavorite) + { + return new ItemByNameInfo + { + Name = itemByName.Name, + ItemCount = count + }; + } + } + catch (Exception ex) + { + _logger.ErrorException("Error getting genre {0}", ex, i); + + } + + return null; + + }).Where(i => i != null).ToList(); + } + + private void SetFavoriteStudios(MoviesView view, IEnumerable inputItems, User user) + { + var all = inputItems.SelectMany(i => i.Studios) + .Distinct(StringComparer.OrdinalIgnoreCase); + + view.FavoriteStudios = all.Select(i => + { + try + { + var itemByName = _libraryManager.GetStudio(i); + + var counts = itemByName.GetItemByNameCounts(user); + + var count = counts == null ? 0 : counts.MovieCount; + + if (count > 0 && _userDataManager.GetUserData(user.Id, itemByName.GetUserDataKey()).IsFavorite) + { + return new ItemByNameInfo + { + Name = itemByName.Name, + ItemCount = count + }; + } + } + catch (Exception ex) + { + _logger.ErrorException("Error getting studio {0}", ex, i); + + } + + return null; + + }).Where(i => i != null).ToList(); + } + public object Get(GetMovieView request) { var user = _userManager.GetUserById(request.UserId); @@ -487,6 +557,9 @@ namespace MediaBrowser.Api.DefaultTheme var movies = items.OfType() .ToList(); + SetFavoriteGenres(view, movies, user); + SetFavoriteStudios(view, movies, user); + var trailers = items.OfType() .ToList(); diff --git a/MediaBrowser.Api/DefaultTheme/Models.cs b/MediaBrowser.Api/DefaultTheme/Models.cs index 6dbd6b562..bdff82de2 100644 --- a/MediaBrowser.Api/DefaultTheme/Models.cs +++ b/MediaBrowser.Api/DefaultTheme/Models.cs @@ -34,6 +34,9 @@ namespace MediaBrowser.Api.DefaultTheme public List LatestTrailers { get; set; } public List LatestMovies { get; set; } + + public List FavoriteGenres { get; set; } + public List FavoriteStudios { get; set; } } public class TvView : BaseView diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 61259a4c2..0e5f420b5 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -861,21 +861,10 @@ namespace MediaBrowser.Api.Images Position = 0 }; - var imageIndex = 0; - - if (imageType == ImageType.Screenshot) - { - imageIndex = entity.ScreenshotImagePaths.Count; - } - else if (imageType == ImageType.Backdrop) - { - imageIndex = entity.BackdropImagePaths.Count; - } - // Handle image/png; charset=utf-8 mimeType = mimeType.Split(';').FirstOrDefault(); - await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, imageIndex, null, CancellationToken.None).ConfigureAwait(false); + await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, null, null, CancellationToken.None).ConfigureAwait(false); await entity.RefreshMetadata(CancellationToken.None, forceRefresh: true, forceSave: true, allowSlowProviders: false).ConfigureAwait(false); } diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index 0cf51abac..f92d9d581 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -282,14 +282,7 @@ namespace MediaBrowser.Api.Images /// Task. private async Task DownloadRemoteImage(BaseItem item, BaseDownloadRemoteImage request) { - int? index = null; - - if (request.Type == ImageType.Backdrop) - { - index = item.BackdropImagePaths.Count; - } - - await _providerManager.SaveImage(item, request.ImageUrl, null, request.Type, index, CancellationToken.None).ConfigureAwait(false); + await _providerManager.SaveImage(item, request.ImageUrl, null, request.Type, null, CancellationToken.None).ConfigureAwait(false); await item.RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false) .ConfigureAwait(false); diff --git a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs index 24f17556b..39908c3ee 100644 --- a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs +++ b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs @@ -327,15 +327,11 @@ namespace MediaBrowser.Providers.Movies if (ConfigurationManager.Configuration.DownloadMovieImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit) { - var numBackdrops = item.BackdropImagePaths.Count; - foreach (var image in images.Where(i => i.Type == ImageType.Backdrop)) { - await _providerManager.SaveImage(item, image.Url, FanArtResourcePool, ImageType.Backdrop, numBackdrops, cancellationToken) + await _providerManager.SaveImage(item, image.Url, FanArtResourcePool, ImageType.Backdrop, null, cancellationToken) .ConfigureAwait(false); - numBackdrops++; - if (item.BackdropImagePaths.Count >= backdropLimit) break; } } diff --git a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs index ab6dbf6d4..d2a12ac21 100644 --- a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs @@ -231,7 +231,7 @@ namespace MediaBrowser.Providers.Movies }).ConfigureAwait(false); - await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(url), ImageType.Backdrop, item.BackdropImagePaths.Count, url, cancellationToken) + await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(url), ImageType.Backdrop, null, url, cancellationToken) .ConfigureAwait(false); } diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs index f3ea77584..6df21b61d 100644 --- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs +++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs @@ -320,15 +320,11 @@ namespace MediaBrowser.Providers.Music if (ConfigurationManager.Configuration.DownloadMusicArtistImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit) { - var numBackdrops = item.BackdropImagePaths.Count; - foreach (var image in images.Where(i => i.Type == ImageType.Backdrop)) { - await _providerManager.SaveImage(item, image.Url, FanArtResourcePool, ImageType.Backdrop, numBackdrops, cancellationToken) + await _providerManager.SaveImage(item, image.Url, FanArtResourcePool, ImageType.Backdrop, null, cancellationToken) .ConfigureAwait(false); - numBackdrops++; - if (item.BackdropImagePaths.Count >= backdropLimit) break; } } diff --git a/MediaBrowser.Providers/TV/FanArtTVProvider.cs b/MediaBrowser.Providers/TV/FanArtTVProvider.cs index 31f8f9cb4..1f20140c5 100644 --- a/MediaBrowser.Providers/TV/FanArtTVProvider.cs +++ b/MediaBrowser.Providers/TV/FanArtTVProvider.cs @@ -260,15 +260,11 @@ namespace MediaBrowser.Providers.TV if (ConfigurationManager.Configuration.DownloadSeriesImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit) { - var numBackdrops = item.BackdropImagePaths.Count; - foreach (var image in images.Where(i => i.Type == ImageType.Backdrop)) { - await _providerManager.SaveImage(item, image.Url, FanArtResourcePool, ImageType.Backdrop, numBackdrops, cancellationToken) + await _providerManager.SaveImage(item, image.Url, FanArtResourcePool, ImageType.Backdrop, null, cancellationToken) .ConfigureAwait(false); - numBackdrops++; - if (item.BackdropImagePaths.Count >= backdropLimit) break; } } diff --git a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs index 77a432add..05fee7861 100644 --- a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs @@ -181,8 +181,6 @@ namespace MediaBrowser.Providers.TV if (ConfigurationManager.Configuration.DownloadSeasonImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit) { - var bdNo = item.BackdropImagePaths.Count; - foreach (var backdrop in images.Where(i => i.Type == ImageType.Backdrop)) { var url = backdrop.Url; @@ -192,9 +190,7 @@ namespace MediaBrowser.Providers.TV continue; } - await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, bdNo, cancellationToken).ConfigureAwait(false); - - bdNo++; + await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, null, cancellationToken).ConfigureAwait(false); if (item.BackdropImagePaths.Count >= backdropLimit) break; } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs index 42118c063..b56b50bec 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs @@ -191,8 +191,6 @@ namespace MediaBrowser.Providers.TV if (ConfigurationManager.Configuration.DownloadSeriesImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit) { - var bdNo = item.BackdropImagePaths.Count; - foreach (var backdrop in images.Where(i => i.Type == ImageType.Backdrop && (!i.Width.HasValue || i.Width.Value >= ConfigurationManager.Configuration.MinSeriesBackdropDownloadWidth))) @@ -204,9 +202,7 @@ namespace MediaBrowser.Providers.TV continue; } - await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, bdNo, cancellationToken).ConfigureAwait(false); - - bdNo++; + await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, null, cancellationToken).ConfigureAwait(false); if (item.BackdropImagePaths.Count >= backdropLimit) break; } diff --git a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs index dfbf0736b..0ed46e761 100644 --- a/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs +++ b/MediaBrowser.Server.Implementations/Providers/ImageSaver.cs @@ -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) -- cgit v1.2.3