reduce scanning overhead a bit
This commit is contained in:
parent
3d9b862430
commit
2b8b98b590
|
@ -664,22 +664,6 @@ namespace MediaBrowser.Controller.Dto
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the library update info.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="changeEvent">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
|
|
||||||
/// <returns>LibraryUpdateInfo.</returns>
|
|
||||||
public static LibraryUpdateInfo GetLibraryUpdateInfo(ChildrenChangedEventArgs changeEvent)
|
|
||||||
{
|
|
||||||
return new LibraryUpdateInfo
|
|
||||||
{
|
|
||||||
Folder = GetBaseItemInfo(changeEvent.Folder),
|
|
||||||
ItemsAdded = changeEvent.ItemsAdded.Select(GetBaseItemInfo),
|
|
||||||
ItemsRemoved = changeEvent.ItemsRemoved.Select(i => i.Id),
|
|
||||||
ItemsUpdated = changeEvent.ItemsUpdated.Select(i => i.Id)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a UserItemData to a DTOUserItemData
|
/// Converts a UserItemData to a DTOUserItemData
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -659,7 +659,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
foreach (var tuple in list)
|
foreach (var tuple in list)
|
||||||
{
|
{
|
||||||
if (tasks.Count > 50)
|
if (tasks.Count > 5)
|
||||||
{
|
{
|
||||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,17 @@ namespace MediaBrowser.Controller.Providers
|
||||||
throw new ArgumentNullException();
|
throw new ArgumentNullException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var settings = new XmlReaderSettings
|
||||||
|
{
|
||||||
|
CheckCharacters = false,
|
||||||
|
IgnoreProcessingInstructions = true,
|
||||||
|
IgnoreComments = true,
|
||||||
|
IgnoreWhitespace = true,
|
||||||
|
ValidationType = ValidationType.None
|
||||||
|
};
|
||||||
|
|
||||||
// Use XmlReader for best performance
|
// Use XmlReader for best performance
|
||||||
using (var reader = XmlReader.Create(metadataFile))
|
using (var reader = XmlReader.Create(metadataFile, settings))
|
||||||
{
|
{
|
||||||
reader.MoveToContent();
|
reader.MoveToContent();
|
||||||
|
|
||||||
|
@ -93,7 +102,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
var type = reader.ReadElementContentAsString();
|
var type = reader.ReadElementContentAsString();
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(type) && !type.Equals("none",StringComparison.OrdinalIgnoreCase))
|
if (!string.IsNullOrWhiteSpace(type) && !type.Equals("none", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
item.DisplayMediaType = type;
|
item.DisplayMediaType = type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ namespace MediaBrowser.Controller.Providers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly Guid Id;
|
protected readonly Guid Id;
|
||||||
|
|
||||||
|
protected static readonly SemaphoreSlim XmlParsingResourcePool = new SemaphoreSlim(5, 5);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Supportses the specified item.
|
/// Supportses the specified item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
/// <returns>Task{System.Boolean}.</returns>
|
/// <returns>Task{System.Boolean}.</returns>
|
||||||
public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
|
public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return Task.Run(() => Fetch(item, cancellationToken));
|
return Fetch(item, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -67,7 +67,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||||
private bool Fetch(BaseItem item, CancellationToken cancellationToken)
|
private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
@ -76,7 +76,18 @@ namespace MediaBrowser.Controller.Providers
|
||||||
if (metadataFile.HasValue)
|
if (metadataFile.HasValue)
|
||||||
{
|
{
|
||||||
var path = metadataFile.Value.Path;
|
var path = metadataFile.Value.Path;
|
||||||
|
|
||||||
|
await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
new BaseItemXmlParser<Folder>(Logger).Fetch((Folder)item, path, cancellationToken);
|
new BaseItemXmlParser<Folder>(Logger).Fetch((Folder)item, path, cancellationToken);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
XmlParsingResourcePool.Release();
|
||||||
|
}
|
||||||
|
|
||||||
SetLastRefreshed(item, DateTime.UtcNow);
|
SetLastRefreshed(item, DateTime.UtcNow);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace MediaBrowser.Controller.Providers.Movies
|
||||||
/// <returns>Task{System.Boolean}.</returns>
|
/// <returns>Task{System.Boolean}.</returns>
|
||||||
public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
|
public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return Task.Run(() => Fetch(item, cancellationToken));
|
return Fetch(item, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -67,7 +67,7 @@ namespace MediaBrowser.Controller.Providers.Movies
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||||
private bool Fetch(BaseItem item, CancellationToken cancellationToken)
|
private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
@ -77,6 +77,11 @@ namespace MediaBrowser.Controller.Providers.Movies
|
||||||
{
|
{
|
||||||
var path = metadataFile.Value.Path;
|
var path = metadataFile.Value.Path;
|
||||||
var boxset = item as BoxSet;
|
var boxset = item as BoxSet;
|
||||||
|
|
||||||
|
await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if (boxset != null)
|
if (boxset != null)
|
||||||
{
|
{
|
||||||
new BaseItemXmlParser<BoxSet>(Logger).Fetch(boxset, path, cancellationToken);
|
new BaseItemXmlParser<BoxSet>(Logger).Fetch(boxset, path, cancellationToken);
|
||||||
|
@ -85,6 +90,12 @@ namespace MediaBrowser.Controller.Providers.Movies
|
||||||
{
|
{
|
||||||
new BaseItemXmlParser<Movie>(Logger).Fetch((Movie)item, path, cancellationToken);
|
new BaseItemXmlParser<Movie>(Logger).Fetch((Movie)item, path, cancellationToken);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
XmlParsingResourcePool.Release();
|
||||||
|
}
|
||||||
|
|
||||||
SetLastRefreshed(item, DateTime.UtcNow);
|
SetLastRefreshed(item, DateTime.UtcNow);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ namespace MediaBrowser.Controller.Providers.TV
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EpisodeProviderFromXml : BaseMetadataProvider
|
public class EpisodeProviderFromXml : BaseMetadataProvider
|
||||||
{
|
{
|
||||||
public EpisodeProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager) : base(logManager, configurationManager)
|
public EpisodeProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||||
|
: base(logManager, configurationManager)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ namespace MediaBrowser.Controller.Providers.TV
|
||||||
/// <returns>Task{System.Boolean}.</returns>
|
/// <returns>Task{System.Boolean}.</returns>
|
||||||
public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
|
public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return Task.Run(() => Fetch(item, cancellationToken));
|
return Fetch(item, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -84,42 +85,31 @@ namespace MediaBrowser.Controller.Providers.TV
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||||
private bool Fetch(BaseItem item, CancellationToken cancellationToken)
|
private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var metadataFile = Path.Combine(item.MetaLocation, Path.ChangeExtension(Path.GetFileName(item.Path), ".xml"));
|
var metadataFile = Path.Combine(item.MetaLocation, Path.ChangeExtension(Path.GetFileName(item.Path), ".xml"));
|
||||||
|
|
||||||
var episode = (Episode)item;
|
var file = item.ResolveArgs.Parent.ResolveArgs.GetMetaFileByPath(metadataFile);
|
||||||
|
|
||||||
if (!FetchMetadata(episode, item.ResolveArgs.Parent, metadataFile, cancellationToken))
|
|
||||||
{
|
|
||||||
// Don't set last refreshed if we didn't do anything
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLastRefreshed(item, DateTime.UtcNow);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fetches the metadata.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The item.</param>
|
|
||||||
/// <param name="parent">The parent.</param>
|
|
||||||
/// <param name="metadataFile">The metadata file.</param>
|
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
|
||||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
|
||||||
private bool FetchMetadata(Episode item, Folder parent, string metadataFile, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var file = parent.ResolveArgs.GetMetaFileByPath(metadataFile);
|
|
||||||
|
|
||||||
if (!file.HasValue)
|
if (!file.HasValue)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
new EpisodeXmlParser(Logger).Fetch(item, metadataFile, cancellationToken);
|
await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
new EpisodeXmlParser(Logger).Fetch((Episode)item, metadataFile, cancellationToken);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
XmlParsingResourcePool.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLastRefreshed(item, DateTime.UtcNow);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace MediaBrowser.Controller.Providers.TV
|
||||||
/// <returns>Task{System.Boolean}.</returns>
|
/// <returns>Task{System.Boolean}.</returns>
|
||||||
public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
|
public override Task<bool> FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return Task.Run(() => Fetch(item, cancellationToken));
|
return Fetch(item, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -68,7 +68,7 @@ namespace MediaBrowser.Controller.Providers.TV
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||||
private bool Fetch(BaseItem item, CancellationToken cancellationToken)
|
private async Task<bool> Fetch(BaseItem item, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
@ -78,7 +78,17 @@ namespace MediaBrowser.Controller.Providers.TV
|
||||||
{
|
{
|
||||||
var path = metadataFile.Value.Path;
|
var path = metadataFile.Value.Path;
|
||||||
|
|
||||||
|
await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
new SeriesXmlParser(Logger).Fetch((Series)item, path, cancellationToken);
|
new SeriesXmlParser(Logger).Fetch((Series)item, path, cancellationToken);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
XmlParsingResourcePool.Release();
|
||||||
|
}
|
||||||
|
|
||||||
SetLastRefreshed(item, DateTime.UtcNow);
|
SetLastRefreshed(item, DateTime.UtcNow);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -9,27 +9,35 @@ namespace MediaBrowser.Model.Entities
|
||||||
public class LibraryUpdateInfo
|
public class LibraryUpdateInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the folder.
|
/// Gets or sets the folders.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The folder.</value>
|
/// <value>The folders.</value>
|
||||||
public BaseItemInfo Folder { get; set; }
|
public List<Guid> Folders { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the items added.
|
/// Gets or sets the items added.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The items added.</value>
|
/// <value>The items added.</value>
|
||||||
public IEnumerable<BaseItemInfo> ItemsAdded { get; set; }
|
public List<Guid> ItemsAdded { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the items removed.
|
/// Gets or sets the items removed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The items removed.</value>
|
/// <value>The items removed.</value>
|
||||||
public IEnumerable<Guid> ItemsRemoved { get; set; }
|
public List<Guid> ItemsRemoved { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the items updated.
|
/// Gets or sets the items updated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The items updated.</value>
|
/// <value>The items updated.</value>
|
||||||
public IEnumerable<Guid> ItemsUpdated { get; set; }
|
public List<Guid> ItemsUpdated { get; set; }
|
||||||
|
|
||||||
|
public LibraryUpdateInfo()
|
||||||
|
{
|
||||||
|
Folders = new List<Guid>();
|
||||||
|
ItemsAdded = new List<Guid>();
|
||||||
|
ItemsRemoved = new List<Guid>();
|
||||||
|
ItemsUpdated = new List<Guid>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,5 +21,13 @@ namespace MediaBrowser.Model.Weather
|
||||||
/// <value>The forecasts.</value>
|
/// <value>The forecasts.</value>
|
||||||
[ProtoMember(2)]
|
[ProtoMember(2)]
|
||||||
public WeatherForecast[] Forecasts { get; set; }
|
public WeatherForecast[] Forecasts { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="WeatherInfo"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public WeatherInfo()
|
||||||
|
{
|
||||||
|
Forecasts = new WeatherForecast[] {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The audio image resource pool
|
/// The audio image resource pool
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly SemaphoreSlim _audioImageResourcePool = new SemaphoreSlim(2, 2);
|
private readonly SemaphoreSlim _audioImageResourcePool = new SemaphoreSlim(1, 1);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _subtitle extraction resource pool
|
/// The _subtitle extraction resource pool
|
||||||
|
|
|
@ -147,6 +147,8 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
|
||||||
{
|
{
|
||||||
// Image is already in the cache
|
// Image is already in the cache
|
||||||
item.PrimaryImagePath = path;
|
item.PrimaryImagePath = path;
|
||||||
|
|
||||||
|
await _libraryManager.SaveItem(item, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -60,30 +61,21 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <param name="progress">The progress.</param>
|
/// <param name="progress">The progress.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
||||||
{
|
{
|
||||||
var videos = _libraryManager.RootFolder.RecursiveChildren.OfType<Video>().Where(v => v.Chapters != null).ToList();
|
var videos = _libraryManager.RootFolder.RecursiveChildren
|
||||||
|
.OfType<Video>()
|
||||||
|
.Where(v => v.Chapters != null && v.Chapters.Count != 0)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
var numComplete = 0;
|
var numComplete = 0;
|
||||||
|
|
||||||
var tasks = videos.Select(v => Task.Run(async () =>
|
foreach (var video in videos)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await _kernel.FFMpegManager.PopulateChapterImages(v, cancellationToken, true, true);
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.ErrorException("Error creating chapter images for {0}", ex, v.Name);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
lock (progress)
|
|
||||||
{
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
await _kernel.FFMpegManager.PopulateChapterImages(video, cancellationToken, true, true);
|
||||||
|
|
||||||
numComplete++;
|
numComplete++;
|
||||||
double percent = numComplete;
|
double percent = numComplete;
|
||||||
percent /= videos.Count;
|
percent /= videos.Count;
|
||||||
|
@ -91,10 +83,6 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
|
||||||
progress.Report(100 * percent);
|
progress.Report(100 * percent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
|
||||||
|
|
||||||
return Task.WhenAll(tasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the task
|
/// Gets the name of the task
|
||||||
|
|
|
@ -176,6 +176,8 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
|
||||||
{
|
{
|
||||||
// Image is already in the cache
|
// Image is already in the cache
|
||||||
item.PrimaryImagePath = path;
|
item.PrimaryImagePath = path;
|
||||||
|
|
||||||
|
await _libraryManager.SaveItem(item, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using MediaBrowser.Common.Events;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using MediaBrowser.Common.Events;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Common.Plugins;
|
using MediaBrowser.Common.Plugins;
|
||||||
using MediaBrowser.Common.ScheduledTasks;
|
using MediaBrowser.Common.ScheduledTasks;
|
||||||
|
@ -8,6 +10,7 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Plugins;
|
using MediaBrowser.Controller.Plugins;
|
||||||
using MediaBrowser.Controller.Updates;
|
using MediaBrowser.Controller.Updates;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using MediaBrowser.Model.Updates;
|
using MediaBrowser.Model.Updates;
|
||||||
|
@ -49,8 +52,33 @@ namespace MediaBrowser.ServerApplication.EntryPoints
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IServerApplicationHost _appHost;
|
private readonly IServerApplicationHost _appHost;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _task manager
|
||||||
|
/// </summary>
|
||||||
private readonly ITaskManager _taskManager;
|
private readonly ITaskManager _taskManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The _library changed sync lock
|
||||||
|
/// </summary>
|
||||||
|
private readonly object _libraryChangedSyncLock = new object();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the library update info.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The library update info.</value>
|
||||||
|
private LibraryUpdateInfo LibraryUpdateInfo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the library update timer.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The library update timer.</value>
|
||||||
|
private Timer LibraryUpdateTimer { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The library update duration
|
||||||
|
/// </summary>
|
||||||
|
private const int LibraryUpdateDuration = 60000;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="WebSocketEvents" /> class.
|
/// Initializes a new instance of the <see cref="WebSocketEvents" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -145,7 +173,47 @@ namespace MediaBrowser.ServerApplication.EntryPoints
|
||||||
/// <param name="e">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
|
/// <param name="e">The <see cref="ChildrenChangedEventArgs" /> instance containing the event data.</param>
|
||||||
void libraryManager_LibraryChanged(object sender, ChildrenChangedEventArgs e)
|
void libraryManager_LibraryChanged(object sender, ChildrenChangedEventArgs e)
|
||||||
{
|
{
|
||||||
_serverManager.SendWebSocketMessage("LibraryChanged", () => DtoBuilder.GetLibraryUpdateInfo(e));
|
lock (_libraryChangedSyncLock)
|
||||||
|
{
|
||||||
|
if (LibraryUpdateInfo == null)
|
||||||
|
{
|
||||||
|
LibraryUpdateInfo = new LibraryUpdateInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LibraryUpdateTimer == null)
|
||||||
|
{
|
||||||
|
LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration,
|
||||||
|
Timeout.Infinite);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
|
||||||
|
}
|
||||||
|
|
||||||
|
LibraryUpdateInfo.Folders.Add(e.Folder.Id);
|
||||||
|
|
||||||
|
LibraryUpdateInfo.ItemsAdded.AddRange(e.ItemsAdded.Select(i => i.Id));
|
||||||
|
LibraryUpdateInfo.ItemsUpdated.AddRange(e.ItemsUpdated.Select(i => i.Id));
|
||||||
|
LibraryUpdateInfo.ItemsRemoved.AddRange(e.ItemsRemoved.Select(i => i.Id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Libraries the update timer callback.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="state">The state.</param>
|
||||||
|
private void LibraryUpdateTimerCallback(object state)
|
||||||
|
{
|
||||||
|
lock (_libraryChangedSyncLock)
|
||||||
|
{
|
||||||
|
_serverManager.SendWebSocketMessage("LibraryChanged", LibraryUpdateInfo);
|
||||||
|
|
||||||
|
if (LibraryUpdateTimer != null)
|
||||||
|
{
|
||||||
|
LibraryUpdateTimer.Dispose();
|
||||||
|
LibraryUpdateTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -206,6 +274,12 @@ namespace MediaBrowser.ServerApplication.EntryPoints
|
||||||
{
|
{
|
||||||
if (dispose)
|
if (dispose)
|
||||||
{
|
{
|
||||||
|
if (LibraryUpdateTimer != null)
|
||||||
|
{
|
||||||
|
LibraryUpdateTimer.Dispose();
|
||||||
|
LibraryUpdateTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
_userManager.UserDeleted -= userManager_UserDeleted;
|
_userManager.UserDeleted -= userManager_UserDeleted;
|
||||||
_userManager.UserUpdated -= userManager_UserUpdated;
|
_userManager.UserUpdated -= userManager_UserUpdated;
|
||||||
|
|
||||||
|
|
|
@ -205,4 +205,7 @@ Global
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(Performance) = preSolution
|
||||||
|
HasPerformanceSessions = true
|
||||||
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
Loading…
Reference in New Issue
Block a user