diff options
| -rw-r--r-- | MediaBrowser.Controller/Entities/Audio/MusicArtist.cs | 97 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Folder.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs | 32 |
3 files changed, 114 insertions, 21 deletions
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 7a67c0aa6..f7dbb43c0 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -1,9 +1,11 @@ -using MediaBrowser.Controller.Providers; +using MediaBrowser.Common.Progress; +using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; @@ -13,7 +15,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// <summary> /// Class MusicArtist /// </summary> - public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess, IHasTags, IHasProductionLocations + public class MusicArtist : Folder, IMetadataContainer, IItemByName, IHasMusicGenres, IHasDualAccess, IHasTags, IHasProductionLocations { [IgnoreDataMember] public List<ItemByNameCounts> UserItemCountList { get; set; } @@ -108,5 +110,96 @@ namespace MediaBrowser.Controller.Entities.Audio { return config.BlockUnratedMusic; } + + public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken) + { + var items = RecursiveChildren.ToList(); + + var songs = items.OfType<Audio>().ToList(); + + var others = items.Except(songs).ToList(); + + var totalItems = songs.Count + others.Count; + var percentages = new Dictionary<Guid, double>(totalItems); + + var tasks = new List<Task>(); + + // Refresh songs + foreach (var item in songs) + { + if (tasks.Count > 3) + { + await Task.WhenAll(tasks).ConfigureAwait(false); + tasks.Clear(); + } + + cancellationToken.ThrowIfCancellationRequested(); + var innerProgress = new ActionableProgress<double>(); + + // Avoid implicitly captured closure + var currentChild = item; + innerProgress.RegisterAction(p => + { + lock (percentages) + { + percentages[currentChild.Id] = p / 100; + + var percent = percentages.Values.Sum(); + percent /= totalItems; + percent *= 100; + progress.Report(percent); + } + }); + + tasks.Add(RefreshItem(item, refreshOptions, innerProgress, cancellationToken)); + } + + await Task.WhenAll(tasks).ConfigureAwait(false); + tasks.Clear(); + + // Refresh current item + await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); + + // Refresh all non-songs + foreach (var item in others) + { + if (tasks.Count > 3) + { + await Task.WhenAll(tasks).ConfigureAwait(false); + tasks.Clear(); + } + + cancellationToken.ThrowIfCancellationRequested(); + var innerProgress = new ActionableProgress<double>(); + + // Avoid implicitly captured closure + var currentChild = item; + innerProgress.RegisterAction(p => + { + lock (percentages) + { + percentages[currentChild.Id] = p / 100; + + var percent = percentages.Values.Sum(); + percent /= totalItems; + percent *= 100; + progress.Report(percent); + } + }); + + tasks.Add(RefreshItem(item, refreshOptions, innerProgress, cancellationToken)); + } + + await Task.WhenAll(tasks).ConfigureAwait(false); + + progress.Report(100); + } + + private async Task RefreshItem(BaseItem item, MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken) + { + await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); + + progress.Report(100); + } } } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 4676100f4..101244d45 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -475,10 +475,6 @@ namespace MediaBrowser.Controller.Entities await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false); } } - else - { - validChildren.AddRange(ActualChildren); - } progress.Report(10); @@ -486,7 +482,7 @@ namespace MediaBrowser.Controller.Entities if (recursive) { - await ValidateSubFolders(validChildren.OfType<Folder>().ToList(), progress, cancellationToken).ConfigureAwait(false); + await ValidateSubFolders(ActualChildren.OfType<Folder>().ToList(), progress, cancellationToken).ConfigureAwait(false); } progress.Report(20); diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index e22c94f5a..5f1299e31 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -82,26 +82,30 @@ namespace MediaBrowser.Providers.MediaInfo if (!File.Exists(path)) { - using (var stream = await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.File, true, null, null, cancellationToken).ConfigureAwait(false)) - { - var semaphore = GetLock(path); - - Directory.CreateDirectory(Path.GetDirectoryName(path)); + var semaphore = GetLock(path); - // Acquire a lock - await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + // Acquire a lock + await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - try + try + { + // Check again in case it was saved while waiting for the lock + if (!File.Exists(path)) { - using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) + Directory.CreateDirectory(Path.GetDirectoryName(path)); + + using (var stream = await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.File, true, null, null, cancellationToken).ConfigureAwait(false)) { - await stream.CopyToAsync(fileStream).ConfigureAwait(false); + using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) + { + await stream.CopyToAsync(fileStream).ConfigureAwait(false); + } } } - finally - { - semaphore.Release(); - } + } + finally + { + semaphore.Release(); } } |
