diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index 292896856..2224d544c 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -432,17 +432,12 @@ namespace Emby.Drawing return GetResult(croppedImagePath); } - var imageProcessingLockTaken = false; - try { _fileSystem.CreateDirectory(Path.GetDirectoryName(croppedImagePath)); var tmpPath = Path.ChangeExtension(Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString("N")), Path.GetExtension(croppedImagePath)); _fileSystem.CreateDirectory(Path.GetDirectoryName(tmpPath)); - await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); - imageProcessingLockTaken = true; - _imageEncoder.CropWhiteSpace(originalImagePath, tmpPath); CopyFile(tmpPath, croppedImagePath); return GetResult(tmpPath); @@ -459,13 +454,6 @@ namespace Emby.Drawing return new Tuple(originalImagePath, dateModified); } - finally - { - if (imageProcessingLockTaken) - { - _imageProcessingSemaphore.Release(); - } - } } private Tuple GetResult(string path) @@ -904,20 +892,11 @@ namespace Emby.Drawing public async Task CreateImageCollage(ImageCollageOptions options) { - await _imageProcessingSemaphore.WaitAsync().ConfigureAwait(false); + _logger.Info("Creating image collage and saving to {0}", options.OutputPath); - try - { - _logger.Info("Creating image collage and saving to {0}", options.OutputPath); + _imageEncoder.CreateImageCollage(options); - _imageEncoder.CreateImageCollage(options); - - _logger.Info("Completed creation of image collage and saved to {0}", options.OutputPath); - } - finally - { - _imageProcessingSemaphore.Release(); - } + _logger.Info("Completed creation of image collage and saved to {0}", options.OutputPath); } public IEnumerable GetSupportedEnhancers(IHasImages item, ImageType imageType) diff --git a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs index 5a8be5a49..7a36691df 100644 --- a/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs +++ b/Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs @@ -149,6 +149,11 @@ namespace Emby.Server.Implementations.Images var mimeType = MimeTypes.GetMimeType(outputPath); + if (string.Equals(mimeType, "application/octet-stream", StringComparison.OrdinalIgnoreCase)) + { + mimeType = "image/png"; + } + await ProviderManager.SaveImage(item, outputPath, mimeType, imageType, null, false, cancellationToken).ConfigureAwait(false); return ItemUpdateType.ImageUpdate; diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 283d193dd..8fb28fb59 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1069,6 +1069,11 @@ namespace Emby.Server.Implementations.Library { _logger.Info("Validating media library"); + // Ensure these objects are lazy loaded. + // Without this there is a deadlock that will need to be investigated + var rootChildren = RootFolder.Children.ToList(); + rootChildren = GetUserRootFolder().Children.ToList(); + await RootFolder.RefreshMetadata(cancellationToken).ConfigureAwait(false); progress.Report(.5); diff --git a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs index 09b68c8ea..bef964c6f 100644 --- a/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs +++ b/Emby.Server.Implementations/UserViews/DynamicImageProvider.cs @@ -151,17 +151,7 @@ namespace Emby.Server.Implementations.UserViews string[] collectionStripViewTypes = { CollectionType.Movies, - CollectionType.TvShows, - CollectionType.Music, - CollectionType.Games, - CollectionType.Books, - CollectionType.MusicVideos, - CollectionType.HomeVideos, - CollectionType.BoxSets, - CollectionType.LiveTv, - CollectionType.Playlists, - CollectionType.Photos, - string.Empty + CollectionType.TvShows }; return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty); @@ -169,20 +159,14 @@ namespace Emby.Server.Implementations.UserViews protected override async Task CreateImage(IHasImages item, List itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { - var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); - - var view = (UserView)item; - if (imageType == ImageType.Primary && IsUsingCollectionStrip(view)) + if (itemsWithImages.Count == 0) { - if (itemsWithImages.Count == 0) - { - return null; - } - - return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); + return null; } - return await base.CreateImage(item, itemsWithImages, outputPath, imageType, imageIndex).ConfigureAwait(false); + var outputPath = Path.ChangeExtension(outputPathWithoutExtension, ".png"); + + return await CreateThumbCollage(item, itemsWithImages, outputPath, 960, 540).ConfigureAwait(false); } } } diff --git a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs index 0384ddd25..9335fca9f 100644 --- a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs +++ b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs @@ -114,9 +114,10 @@ namespace MediaBrowser.Providers.People using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -142,6 +143,10 @@ namespace MediaBrowser.Providers.People break; } } + else + { + reader.Read(); + } } } } @@ -158,12 +163,14 @@ namespace MediaBrowser.Providers.People /// System.String. private RemoteImageInfo FetchImageInfoFromActorNode(string personName, XmlReader reader) { - reader.MoveToContent(); - string name = null; string image = null; - while (reader.Read()) + reader.MoveToContent(); + reader.Read(); + + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -186,6 +193,10 @@ namespace MediaBrowser.Providers.People break; } } + else + { + reader.Read(); + } } if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(image) && diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs index 139daf9a3..ecc0f6cee 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbEpisodeProvider.cs @@ -340,9 +340,10 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -368,6 +369,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -390,16 +395,15 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { - if (reader.NodeType == XmlNodeType.Element) { switch (reader.Name) { - case "FirstAired": { var val = reader.ReadElementContentAsString(); @@ -423,6 +427,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -438,12 +446,13 @@ namespace MediaBrowser.Providers.TV // Use XmlReader for best performance using (reader) { - reader.MoveToContent(); - result.ResetPeople(); + reader.MoveToContent(); + reader.Read(); + // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -507,10 +516,10 @@ namespace MediaBrowser.Providers.TV case "EpisodeNumber": { + var val = reader.ReadElementContentAsString(); + if (!item.IndexNumber.HasValue) { - var val = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(val)) { int rval; @@ -528,10 +537,10 @@ namespace MediaBrowser.Providers.TV case "SeasonNumber": { + var val = reader.ReadElementContentAsString(); + if (!item.ParentIndexNumber.HasValue) { - var val = reader.ReadElementContentAsString(); - if (!string.IsNullOrWhiteSpace(val)) { int rval; @@ -621,9 +630,9 @@ namespace MediaBrowser.Providers.TV case "EpisodeName": { + var val = reader.ReadElementContentAsString(); if (!item.LockedFields.Contains(MetadataFields.Name)) { - var val = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(val)) { item.Name = val; @@ -634,9 +643,9 @@ namespace MediaBrowser.Providers.TV case "Overview": { + var val = reader.ReadElementContentAsString(); if (!item.LockedFields.Contains(MetadataFields.Overview)) { - var val = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(val)) { item.Overview = val; @@ -756,6 +765,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -809,9 +822,10 @@ namespace MediaBrowser.Providers.TV using (reader) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -821,9 +835,9 @@ namespace MediaBrowser.Providers.TV { case "EpisodeName": { + var val = reader.ReadElementContentAsString(); if (!item.LockedFields.Contains(MetadataFields.Name)) { - var val = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(val)) { item.Name += ", " + val; @@ -834,9 +848,9 @@ namespace MediaBrowser.Providers.TV case "Overview": { + var val = reader.ReadElementContentAsString(); if (!item.LockedFields.Contains(MetadataFields.Overview)) { - var val = reader.ReadElementContentAsString(); if (!string.IsNullOrWhiteSpace(val)) { item.Overview += Environment.NewLine + Environment.NewLine + val; @@ -892,6 +906,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs index 1a611ee9b..9454277df 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeasonImageProvider.cs @@ -126,9 +126,10 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -149,6 +150,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -195,7 +200,11 @@ namespace MediaBrowser.Providers.TV int? voteCount = null; string thumbnailUrl = null; - while (reader.Read()) + reader.MoveToContent(); + reader.Read(); + + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -296,6 +305,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } if (!string.IsNullOrEmpty(url) && bannerSeason.HasValue && bannerSeason.Value == seasonNumber) diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs index f6cdacd42..5ad96300d 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesImageProvider.cs @@ -113,9 +113,10 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -136,6 +137,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -181,7 +186,11 @@ namespace MediaBrowser.Providers.TV int? voteCount = null; string thumbnailUrl = null; - while (reader.Read()) + reader.MoveToContent(); + reader.Read(); + + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -283,6 +292,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } if (!string.IsNullOrEmpty(url) && !bannerSeason.HasValue) diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs index 5147e9d10..e574d223e 100644 --- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs @@ -303,9 +303,10 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -324,6 +325,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -541,9 +546,10 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -570,6 +576,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -594,8 +604,10 @@ namespace MediaBrowser.Providers.TV string seriesId = null; reader.MoveToContent(); + reader.Read(); - while (reader.Read()) + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -616,7 +628,7 @@ namespace MediaBrowser.Providers.TV { var val = reader.ReadElementContentAsString(); - var alias = (val ?? string.Empty).Split(new [] { '|' }, StringSplitOptions.RemoveEmptyEntries).Select(GetComparableName); + var alias = (val ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries).Select(GetComparableName); titles.AddRange(alias); break; } @@ -675,6 +687,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } foreach (var title in titles) @@ -770,9 +786,10 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -808,6 +825,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -825,9 +846,10 @@ namespace MediaBrowser.Providers.TV int? seasonNumber = null; reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -874,6 +896,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } if (seasonNumber.HasValue && seasonNumber.Value != 0) @@ -905,9 +931,10 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -926,6 +953,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -943,7 +974,11 @@ namespace MediaBrowser.Providers.TV var personInfo = new PersonInfo(); - while (reader.Read()) + reader.MoveToContent(); + reader.Read(); + + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -963,6 +998,7 @@ namespace MediaBrowser.Providers.TV case "id": { + reader.Skip(); break; } @@ -998,6 +1034,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } personInfo.Type = PersonType.Actor; @@ -1013,9 +1053,10 @@ namespace MediaBrowser.Providers.TV Series item = result.Item; reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -1241,6 +1282,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } @@ -1267,9 +1312,10 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -1288,6 +1334,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } @@ -1313,9 +1363,10 @@ namespace MediaBrowser.Providers.TV using (var reader = XmlReader.Create(streamReader, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -1374,6 +1425,10 @@ namespace MediaBrowser.Providers.TV break; } } + else + { + reader.Read(); + } } } } diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs index 2ea3309b0..548403347 100644 --- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs +++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs @@ -120,9 +120,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers item.ResetPeople(); reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -130,6 +131,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers { FetchDataFromXmlNode(reader, item); } + else + { + reader.Read(); + } } } } @@ -195,9 +200,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers using (var reader = XmlReader.Create(ms, settings)) { reader.MoveToContent(); + reader.Read(); // Loop through each element - while (reader.Read()) + while (!reader.EOF) { cancellationToken.ThrowIfCancellationRequested(); @@ -205,6 +211,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers { FetchDataFromXmlNode(reader, item); } + else + { + reader.Read(); + } } } } @@ -944,8 +954,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers private void FetchFromResumeNode(XmlReader reader, T item, UserItemData userData) { reader.MoveToContent(); + reader.Read(); - while (reader.Read()) + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -971,14 +983,20 @@ namespace MediaBrowser.XbmcMetadata.Parsers break; } } + else + { + reader.Read(); + } } } private void FetchFromFileInfoNode(XmlReader reader, T item) { reader.MoveToContent(); + reader.Read(); - while (reader.Read()) + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -998,14 +1016,20 @@ namespace MediaBrowser.XbmcMetadata.Parsers break; } } + else + { + reader.Read(); + } } } private void FetchFromStreamDetailsNode(XmlReader reader, T item) { reader.MoveToContent(); + reader.Read(); - while (reader.Read()) + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -1025,14 +1049,20 @@ namespace MediaBrowser.XbmcMetadata.Parsers break; } } + else + { + reader.Read(); + } } } private void FetchFromVideoNode(XmlReader reader, T item) { reader.MoveToContent(); + reader.Read(); - while (reader.Read()) + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -1040,12 +1070,12 @@ namespace MediaBrowser.XbmcMetadata.Parsers { case "format3d": { + var val = reader.ReadElementContentAsString(); + var video = item as Video; if (video != null) { - var val = reader.ReadElementContentAsString(); - if (string.Equals("HSBS", val, StringComparison.OrdinalIgnoreCase)) { video.Video3DFormat = Video3DFormat.HalfSideBySide; @@ -1075,6 +1105,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers break; } } + else + { + reader.Read(); + } } } @@ -1091,8 +1125,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers int? sortOrder = null; reader.MoveToContent(); + reader.Read(); - while (reader.Read()) + // Loop through each element + while (!reader.EOF) { if (reader.NodeType == XmlNodeType.Element) { @@ -1143,6 +1179,10 @@ namespace MediaBrowser.XbmcMetadata.Parsers break; } } + else + { + reader.Read(); + } } return new PersonInfo