fixes #280 - MB3 Local metadata fetcher for Music not seeing/using Artist Folder.jpg
This commit is contained in:
parent
390f165332
commit
9a820efde3
|
@ -178,15 +178,15 @@ namespace MediaBrowser.Api
|
||||||
var items = GetItems(request.UserId).ToList();
|
var items = GetItems(request.UserId).ToList();
|
||||||
|
|
||||||
var counts = new ItemCounts
|
var counts = new ItemCounts
|
||||||
{
|
{
|
||||||
AlbumCount = items.OfType<MusicAlbum>().Count(),
|
AlbumCount = items.OfType<MusicAlbum>().Count(),
|
||||||
EpisodeCount = items.OfType<Episode>().Count(),
|
EpisodeCount = items.OfType<Episode>().Count(),
|
||||||
GameCount = items.OfType<BaseGame>().Count(),
|
GameCount = items.OfType<BaseGame>().Count(),
|
||||||
MovieCount = items.OfType<Movie>().Count(),
|
MovieCount = items.OfType<Movie>().Count(),
|
||||||
SeriesCount = items.OfType<Series>().Count(),
|
SeriesCount = items.OfType<Series>().Count(),
|
||||||
SongCount = items.OfType<Audio>().Count(),
|
SongCount = items.OfType<Audio>().Count(),
|
||||||
TrailerCount = items.OfType<Trailer>().Count()
|
TrailerCount = items.OfType<Trailer>().Count()
|
||||||
};
|
};
|
||||||
|
|
||||||
return ToOptimizedResult(counts);
|
return ToOptimizedResult(counts);
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,12 +144,14 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// <param name="introProviders">The intro providers.</param>
|
/// <param name="introProviders">The intro providers.</param>
|
||||||
/// <param name="itemComparers">The item comparers.</param>
|
/// <param name="itemComparers">The item comparers.</param>
|
||||||
/// <param name="prescanTasks">The prescan tasks.</param>
|
/// <param name="prescanTasks">The prescan tasks.</param>
|
||||||
|
/// <param name="postscanTasks">The postscan tasks.</param>
|
||||||
void AddParts(IEnumerable<IResolverIgnoreRule> rules,
|
void AddParts(IEnumerable<IResolverIgnoreRule> rules,
|
||||||
IEnumerable<IVirtualFolderCreator> pluginFolders,
|
IEnumerable<IVirtualFolderCreator> pluginFolders,
|
||||||
IEnumerable<IItemResolver> resolvers,
|
IEnumerable<IItemResolver> resolvers,
|
||||||
IEnumerable<IIntroProvider> introProviders,
|
IEnumerable<IIntroProvider> introProviders,
|
||||||
IEnumerable<IBaseItemComparer> itemComparers,
|
IEnumerable<IBaseItemComparer> itemComparers,
|
||||||
IEnumerable<ILibraryPrescanTask> prescanTasks);
|
IEnumerable<ILibraryPrescanTask> prescanTasks,
|
||||||
|
IEnumerable<ILibraryPostScanTask> postscanTasks);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sorts the specified items.
|
/// Sorts the specified items.
|
||||||
|
|
20
MediaBrowser.Controller/Library/ILibraryPostScanTask.cs
Normal file
20
MediaBrowser.Controller/Library/ILibraryPostScanTask.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.Library
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An interface for tasks that run after the media library scan
|
||||||
|
/// </summary>
|
||||||
|
public interface ILibraryPostScanTask
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the specified progress.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="progress">The progress.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
Task Run(IProgress<double> progress, CancellationToken cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
|
@ -73,8 +73,10 @@
|
||||||
<Compile Include="Configuration\IServerConfigurationManager.cs" />
|
<Compile Include="Configuration\IServerConfigurationManager.cs" />
|
||||||
<Compile Include="Dto\SessionInfoDtoBuilder.cs" />
|
<Compile Include="Dto\SessionInfoDtoBuilder.cs" />
|
||||||
<Compile Include="Entities\Audio\MusicAlbumDisc.cs" />
|
<Compile Include="Entities\Audio\MusicAlbumDisc.cs" />
|
||||||
|
<Compile Include="Library\ILibraryPostScanTask.cs" />
|
||||||
<Compile Include="Library\ILibraryPrescanTask.cs" />
|
<Compile Include="Library\ILibraryPrescanTask.cs" />
|
||||||
<Compile Include="Providers\Movies\MovieDbImagesProvider.cs" />
|
<Compile Include="Providers\Movies\MovieDbImagesProvider.cs" />
|
||||||
|
<Compile Include="Providers\Music\ArtistsPostScanTask.cs" />
|
||||||
<Compile Include="Providers\Music\FanArtUpdatesPrescanTask.cs" />
|
<Compile Include="Providers\Music\FanArtUpdatesPrescanTask.cs" />
|
||||||
<Compile Include="Providers\TV\FanArtSeasonProvider.cs" />
|
<Compile Include="Providers\TV\FanArtSeasonProvider.cs" />
|
||||||
<Compile Include="Providers\TV\TvdbPrescanTask.cs" />
|
<Compile Include="Providers\TV\TvdbPrescanTask.cs" />
|
||||||
|
|
|
@ -155,7 +155,14 @@ namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
var location = GetLocation(item);
|
var location = GetLocation(item);
|
||||||
|
|
||||||
var files = new DirectoryInfo(location).EnumerateFiles("*", SearchOption.TopDirectoryOnly).ToList();
|
var directoryInfo = new DirectoryInfo(location);
|
||||||
|
|
||||||
|
if (!directoryInfo.Exists)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var files = directoryInfo.EnumerateFiles("*", SearchOption.TopDirectoryOnly).ToList();
|
||||||
|
|
||||||
var file = files.FirstOrDefault(i => string.Equals(i.Name, filenameWithoutExtension + ".png", StringComparison.OrdinalIgnoreCase));
|
var file = files.FirstOrDefault(i => string.Equals(i.Name, filenameWithoutExtension + ".png", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
|
|
132
MediaBrowser.Controller/Providers/Music/ArtistsPostScanTask.cs
Normal file
132
MediaBrowser.Controller/Providers/Music/ArtistsPostScanTask.cs
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
using MediaBrowser.Common.Progress;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.Providers.Music
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class ArtistsPostScanTask
|
||||||
|
/// </summary>
|
||||||
|
public class ArtistsPostScanTask : ILibraryPostScanTask
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The _library manager
|
||||||
|
/// </summary>
|
||||||
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ArtistsPostScanTask"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
|
public ArtistsPostScanTask(ILibraryManager libraryManager)
|
||||||
|
{
|
||||||
|
_libraryManager = libraryManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the specified progress.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="progress">The progress.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var allItems = _libraryManager.RootFolder.RecursiveChildren.ToList();
|
||||||
|
|
||||||
|
var allArtists = await GetAllArtists(allItems).ConfigureAwait(false);
|
||||||
|
|
||||||
|
progress.Report(10);
|
||||||
|
|
||||||
|
var allMusicArtists = allItems.OfType<MusicArtist>().ToList();
|
||||||
|
|
||||||
|
var numComplete = 0;
|
||||||
|
|
||||||
|
foreach (var artist in allArtists)
|
||||||
|
{
|
||||||
|
var musicArtist = FindMusicArtist(artist, allMusicArtists);
|
||||||
|
|
||||||
|
if (musicArtist != null)
|
||||||
|
{
|
||||||
|
artist.Images = new Dictionary<ImageType, string>(musicArtist.Images);
|
||||||
|
|
||||||
|
artist.BackdropImagePaths = musicArtist.BackdropImagePaths.ToList();
|
||||||
|
artist.ScreenshotImagePaths = musicArtist.ScreenshotImagePaths.ToList();
|
||||||
|
artist.SetProviderId(MetadataProviders.Musicbrainz, musicArtist.GetProviderId(MetadataProviders.Musicbrainz));
|
||||||
|
}
|
||||||
|
|
||||||
|
numComplete++;
|
||||||
|
double percent = numComplete;
|
||||||
|
percent /= allArtists.Length;
|
||||||
|
percent *= 5;
|
||||||
|
|
||||||
|
progress.Report(10 + percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
var innerProgress = new ActionableProgress<double>();
|
||||||
|
|
||||||
|
innerProgress.RegisterAction(pct => progress.Report(15 + pct * .85));
|
||||||
|
|
||||||
|
await _libraryManager.ValidateArtists(cancellationToken, innerProgress).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all artists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="allItems">All items.</param>
|
||||||
|
/// <returns>Task{Artist[]}.</returns>
|
||||||
|
private Task<Artist[]> GetAllArtists(IEnumerable<BaseItem> allItems)
|
||||||
|
{
|
||||||
|
var itemsList = allItems.OfType<Audio>().ToList();
|
||||||
|
|
||||||
|
var tasks = itemsList
|
||||||
|
.SelectMany(i =>
|
||||||
|
{
|
||||||
|
var list = new List<string>();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(i.AlbumArtist))
|
||||||
|
{
|
||||||
|
list.Add(i.AlbumArtist);
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(i.Artist))
|
||||||
|
{
|
||||||
|
list.Add(i.Artist);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
})
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.Select(i => _libraryManager.GetArtist(i));
|
||||||
|
|
||||||
|
return Task.WhenAll(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the music artist.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="artist">The artist.</param>
|
||||||
|
/// <param name="allMusicArtists">All music artists.</param>
|
||||||
|
/// <returns>MusicArtist.</returns>
|
||||||
|
private static MusicArtist FindMusicArtist(Artist artist, IEnumerable<MusicArtist> allMusicArtists)
|
||||||
|
{
|
||||||
|
var musicBrainzId = artist.GetProviderId(MetadataProviders.Musicbrainz);
|
||||||
|
|
||||||
|
return allMusicArtists.FirstOrDefault(i =>
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(musicBrainzId) && string.Equals(musicBrainzId, i.GetProviderId(MetadataProviders.Musicbrainz), StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Compare(i.Name, artist.Name, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols) == 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,15 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LibraryManager : ILibraryManager
|
public class LibraryManager : ILibraryManager
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the postscan tasks.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The postscan tasks.</value>
|
||||||
|
private IEnumerable<ILibraryPostScanTask> PostscanTasks { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the prescan tasks.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The prescan tasks.</value>
|
||||||
private IEnumerable<ILibraryPrescanTask> PrescanTasks { get; set; }
|
private IEnumerable<ILibraryPrescanTask> PrescanTasks { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -100,6 +109,9 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _user data repository
|
||||||
|
/// </summary>
|
||||||
private readonly IUserDataRepository _userDataRepository;
|
private readonly IUserDataRepository _userDataRepository;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -113,11 +125,25 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
/// (typically, multiple user roots). We store them here and be sure they all reference a
|
/// (typically, multiple user roots). We store them here and be sure they all reference a
|
||||||
/// single instance.
|
/// single instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <value>The by reference items.</value>
|
||||||
private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; }
|
private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _library items cache
|
||||||
|
/// </summary>
|
||||||
private ConcurrentDictionary<Guid, BaseItem> _libraryItemsCache;
|
private ConcurrentDictionary<Guid, BaseItem> _libraryItemsCache;
|
||||||
|
/// <summary>
|
||||||
|
/// The _library items cache sync lock
|
||||||
|
/// </summary>
|
||||||
private object _libraryItemsCacheSyncLock = new object();
|
private object _libraryItemsCacheSyncLock = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// The _library items cache initialized
|
||||||
|
/// </summary>
|
||||||
private bool _libraryItemsCacheInitialized;
|
private bool _libraryItemsCacheInitialized;
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the library items cache.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The library items cache.</value>
|
||||||
private ConcurrentDictionary<Guid, BaseItem> LibraryItemsCache
|
private ConcurrentDictionary<Guid, BaseItem> LibraryItemsCache
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -127,6 +153,9 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _user root folders
|
||||||
|
/// </summary>
|
||||||
private readonly ConcurrentDictionary<string, UserRootFolder> _userRootFolders =
|
private readonly ConcurrentDictionary<string, UserRootFolder> _userRootFolders =
|
||||||
new ConcurrentDictionary<string, UserRootFolder>();
|
new ConcurrentDictionary<string, UserRootFolder>();
|
||||||
|
|
||||||
|
@ -161,12 +190,14 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
/// <param name="introProviders">The intro providers.</param>
|
/// <param name="introProviders">The intro providers.</param>
|
||||||
/// <param name="itemComparers">The item comparers.</param>
|
/// <param name="itemComparers">The item comparers.</param>
|
||||||
/// <param name="prescanTasks">The prescan tasks.</param>
|
/// <param name="prescanTasks">The prescan tasks.</param>
|
||||||
|
/// <param name="postscanTasks">The postscan tasks.</param>
|
||||||
public void AddParts(IEnumerable<IResolverIgnoreRule> rules,
|
public void AddParts(IEnumerable<IResolverIgnoreRule> rules,
|
||||||
IEnumerable<IVirtualFolderCreator> pluginFolders,
|
IEnumerable<IVirtualFolderCreator> pluginFolders,
|
||||||
IEnumerable<IItemResolver> resolvers,
|
IEnumerable<IItemResolver> resolvers,
|
||||||
IEnumerable<IIntroProvider> introProviders,
|
IEnumerable<IIntroProvider> introProviders,
|
||||||
IEnumerable<IBaseItemComparer> itemComparers,
|
IEnumerable<IBaseItemComparer> itemComparers,
|
||||||
IEnumerable<ILibraryPrescanTask> prescanTasks)
|
IEnumerable<ILibraryPrescanTask> prescanTasks,
|
||||||
|
IEnumerable<ILibraryPostScanTask> postscanTasks)
|
||||||
{
|
{
|
||||||
EntityResolutionIgnoreRules = rules;
|
EntityResolutionIgnoreRules = rules;
|
||||||
PluginFolderCreators = pluginFolders;
|
PluginFolderCreators = pluginFolders;
|
||||||
|
@ -174,6 +205,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
IntroProviders = introProviders;
|
IntroProviders = introProviders;
|
||||||
Comparers = itemComparers;
|
Comparers = itemComparers;
|
||||||
PrescanTasks = prescanTasks;
|
PrescanTasks = prescanTasks;
|
||||||
|
PostscanTasks = postscanTasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -210,11 +242,27 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _internet providers enabled
|
||||||
|
/// </summary>
|
||||||
private bool _internetProvidersEnabled;
|
private bool _internetProvidersEnabled;
|
||||||
|
/// <summary>
|
||||||
|
/// The _people image fetching enabled
|
||||||
|
/// </summary>
|
||||||
private bool _peopleImageFetchingEnabled;
|
private bool _peopleImageFetchingEnabled;
|
||||||
|
/// <summary>
|
||||||
|
/// The _items by name path
|
||||||
|
/// </summary>
|
||||||
private string _itemsByNamePath;
|
private string _itemsByNamePath;
|
||||||
|
/// <summary>
|
||||||
|
/// The _season zero display name
|
||||||
|
/// </summary>
|
||||||
private string _seasonZeroDisplayName;
|
private string _seasonZeroDisplayName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Records the configuration values.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="configuration">The configuration.</param>
|
||||||
private void RecordConfigurationValues(ServerConfiguration configuration)
|
private void RecordConfigurationValues(ServerConfiguration configuration)
|
||||||
{
|
{
|
||||||
_seasonZeroDisplayName = ConfigurationManager.Configuration.SeasonZeroDisplayName;
|
_seasonZeroDisplayName = ConfigurationManager.Configuration.SeasonZeroDisplayName;
|
||||||
|
@ -227,7 +275,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
/// Configurations the updated.
|
/// Configurations the updated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">The sender.</param>
|
/// <param name="sender">The sender.</param>
|
||||||
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
|
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
|
||||||
void ConfigurationUpdated(object sender, EventArgs e)
|
void ConfigurationUpdated(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var config = ConfigurationManager.Configuration;
|
var config = ConfigurationManager.Configuration;
|
||||||
|
@ -373,7 +421,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ensure supplied item has only one instance throughout
|
/// Ensure supplied item has only one instance throughout
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item"></param>
|
/// <param name="item">The item.</param>
|
||||||
/// <returns>The proper instance to the item</returns>
|
/// <returns>The proper instance to the item</returns>
|
||||||
public BaseItem GetOrAddByReferenceItem(BaseItem item)
|
public BaseItem GetOrAddByReferenceItem(BaseItem item)
|
||||||
{
|
{
|
||||||
|
@ -800,6 +848,12 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
_logger.Info("People validation complete");
|
_logger.Info("People validation complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validates the artists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <param name="progress">The progress.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
public async Task ValidateArtists(CancellationToken cancellationToken, IProgress<double> progress)
|
public async Task ValidateArtists(CancellationToken cancellationToken, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
const int maxTasks = 25;
|
const int maxTasks = 25;
|
||||||
|
@ -924,11 +978,10 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
// Now validate the entire media library
|
// Now validate the entire media library
|
||||||
await RootFolder.ValidateChildren(innerProgress, cancellationToken, recursive: true).ConfigureAwait(false);
|
await RootFolder.ValidateChildren(innerProgress, cancellationToken, recursive: true).ConfigureAwait(false);
|
||||||
|
|
||||||
innerProgress = new ActionableProgress<double>();
|
progress.Report(80);
|
||||||
|
|
||||||
innerProgress.RegisterAction(pct => progress.Report(80 + pct * .2));
|
// Run post-scan tasks
|
||||||
|
await RunPostScanTasks(progress, cancellationToken).ConfigureAwait(false);
|
||||||
await ValidateArtists(cancellationToken, innerProgress);
|
|
||||||
|
|
||||||
progress.Report(100);
|
progress.Report(100);
|
||||||
}
|
}
|
||||||
|
@ -971,7 +1024,47 @@ namespace MediaBrowser.Server.Implementations.Library
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Run prescan tasks
|
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs the post scan tasks.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="progress">The progress.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
private async Task RunPostScanTasks(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var postscanTasks = PostscanTasks.ToList();
|
||||||
|
var progressDictionary = new Dictionary<ILibraryPostScanTask, double>();
|
||||||
|
|
||||||
|
var tasks = postscanTasks.Select(i => Task.Run(async () =>
|
||||||
|
{
|
||||||
|
var innerProgress = new ActionableProgress<double>();
|
||||||
|
|
||||||
|
innerProgress.RegisterAction(pct =>
|
||||||
|
{
|
||||||
|
lock (progressDictionary)
|
||||||
|
{
|
||||||
|
progressDictionary[i] = pct;
|
||||||
|
|
||||||
|
double percent = progressDictionary.Values.Sum();
|
||||||
|
percent /= postscanTasks.Count;
|
||||||
|
|
||||||
|
progress.Report(80 + percent * .2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await i.Run(innerProgress, cancellationToken);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.ErrorException("Error running postscan task", ex);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="MediaEncoder\fonts\ARIALUNI.TTF" />
|
<EmbeddedResource Include="MediaEncoder\fonts\ARIALUNI.TTF" />
|
||||||
<EmbeddedResource Include="MediaEncoder\fonts\fonts.conf" />
|
<EmbeddedResource Include="MediaEncoder\fonts\fonts.conf" />
|
||||||
<EmbeddedResource Include="MediaEncoder\ffmpeg20130509.zip" />
|
<EmbeddedResource Include="MediaEncoder\ffmpeg20130523.zip" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
2ecea48340becd42b1a3136c8ae551c96a2de324
|
|
|
@ -0,0 +1 @@
|
||||||
|
4d70588f0da1095974027f09130938f318f865c5
|
|
@ -372,7 +372,8 @@ namespace MediaBrowser.ServerApplication
|
||||||
GetExports<IItemResolver>(),
|
GetExports<IItemResolver>(),
|
||||||
GetExports<IIntroProvider>(),
|
GetExports<IIntroProvider>(),
|
||||||
GetExports<IBaseItemComparer>(),
|
GetExports<IBaseItemComparer>(),
|
||||||
GetExports<ILibraryPrescanTask>()),
|
GetExports<ILibraryPrescanTask>(),
|
||||||
|
GetExports<ILibraryPostScanTask>()),
|
||||||
|
|
||||||
() => ProviderManager.AddMetadataProviders(GetExports<BaseMetadataProvider>().ToArray())
|
() => ProviderManager.AddMetadataProviders(GetExports<BaseMetadataProvider>().ToArray())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user