store chapters in xml
This commit is contained in:
parent
d2ec5126f4
commit
d3acd04e66
|
@ -1,5 +1,6 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
|
@ -9,6 +10,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
|
@ -266,7 +268,10 @@ namespace MediaBrowser.Controller.Providers
|
|||
|
||||
case "TagLines":
|
||||
{
|
||||
FetchFromTaglinesNode(reader.ReadSubtree(), item);
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromTaglinesNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -591,28 +596,58 @@ namespace MediaBrowser.Controller.Providers
|
|||
break;
|
||||
|
||||
case "Genres":
|
||||
FetchFromGenresNode(reader.ReadSubtree(), item);
|
||||
break;
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromGenresNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "Tags":
|
||||
FetchFromTagsNode(reader.ReadSubtree(), item);
|
||||
break;
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromTagsNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "Persons":
|
||||
FetchDataFromPersonsNode(reader.ReadSubtree(), item);
|
||||
break;
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchDataFromPersonsNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "ParentalRating":
|
||||
FetchFromParentalRatingNode(reader.ReadSubtree(), item);
|
||||
break;
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromParentalRatingNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "Studios":
|
||||
FetchFromStudiosNode(reader.ReadSubtree(), item);
|
||||
break;
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromStudiosNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "MediaInfo":
|
||||
FetchFromMediaInfoNode(reader.ReadSubtree(), item);
|
||||
break;
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromMediaInfoNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
|
@ -636,8 +671,13 @@ namespace MediaBrowser.Controller.Providers
|
|||
switch (reader.Name)
|
||||
{
|
||||
case "Video":
|
||||
FetchFromMediaInfoVideoNode(reader.ReadSubtree(), item);
|
||||
break;
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
FetchFromMediaInfoVideoNode(subtree, item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
|
@ -813,9 +853,12 @@ namespace MediaBrowser.Controller.Providers
|
|||
case "Person":
|
||||
case "Actor":
|
||||
{
|
||||
foreach (var person in GetPersonsFromXmlNode(reader.ReadSubtree()))
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
item.AddPerson(person);
|
||||
foreach (var person in GetPersonsFromXmlNode(subtree))
|
||||
{
|
||||
item.AddPerson(person);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -828,6 +871,86 @@ namespace MediaBrowser.Controller.Providers
|
|||
}
|
||||
}
|
||||
|
||||
protected async Task FetchChaptersFromXmlNode(Guid itemId, XmlReader reader, IItemRepository repository, CancellationToken cancellationToken)
|
||||
{
|
||||
using (reader)
|
||||
{
|
||||
var chapters = GetChaptersFromXmlNode(reader);
|
||||
|
||||
await repository.SaveChapters(itemId, chapters, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<ChapterInfo> GetChaptersFromXmlNode(XmlReader reader)
|
||||
{
|
||||
var chapters = new List<ChapterInfo>();
|
||||
|
||||
reader.MoveToContent();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "Chapter":
|
||||
{
|
||||
using (var subtree = reader.ReadSubtree())
|
||||
{
|
||||
chapters.Add(GetChapterInfoFromXmlNode(subtree));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return chapters;
|
||||
}
|
||||
|
||||
private ChapterInfo GetChapterInfoFromXmlNode(XmlReader reader)
|
||||
{
|
||||
var chapter = new ChapterInfo();
|
||||
|
||||
reader.MoveToContent();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "StartPositionMs":
|
||||
{
|
||||
var val = reader.ReadElementContentAsString();
|
||||
|
||||
var ms = long.Parse(val, _usCulture);
|
||||
|
||||
chapter.StartPositionTicks = TimeSpan.FromMilliseconds(ms).Ticks;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "Name":
|
||||
{
|
||||
chapter.Name = reader.ReadElementContentAsString();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
reader.Skip();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return chapter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches from studios node.
|
||||
/// </summary>
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<Compile Include="MediaInfo\FFProbeAudioInfoProvider.cs" />
|
||||
<Compile Include="MediaInfo\FFProbeVideoInfoProvider.cs" />
|
||||
<Compile Include="Movies\BoxSetProviderFromXml.cs" />
|
||||
<Compile Include="Movies\MovieXmlParser.cs" />
|
||||
<Compile Include="Movies\FanArtMovieProvider.cs" />
|
||||
<Compile Include="Movies\FanArtMovieUpdatesPrescanTask.cs" />
|
||||
<Compile Include="Movies\MovieDbImagesProvider.cs" />
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Providers.Music;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
@ -17,10 +17,12 @@ namespace MediaBrowser.Providers.Movies
|
|||
public class MovieProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
internal static MovieProviderFromXml Current { get; private set; }
|
||||
|
||||
public MovieProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
private readonly IItemRepository _itemRepo;
|
||||
|
||||
public MovieProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IItemRepository itemRepo)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_itemRepo = itemRepo;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -94,30 +96,9 @@ namespace MediaBrowser.Providers.Movies
|
|||
|
||||
try
|
||||
{
|
||||
var movie = item as Movie;
|
||||
var video = (Video) item;
|
||||
|
||||
if (movie != null)
|
||||
{
|
||||
new BaseItemXmlParser<Movie>(Logger).Fetch(movie, path, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
var musicVideo = item as MusicVideo;
|
||||
|
||||
if (musicVideo != null)
|
||||
{
|
||||
new MusicVideoXmlParser(Logger).Fetch(musicVideo, path, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
var trailer = item as Trailer;
|
||||
|
||||
if (trailer != null)
|
||||
{
|
||||
new BaseItemXmlParser<Trailer>(Logger).Fetch(trailer, path, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
await new MovieXmlParser(Logger, _itemRepo).FetchAsync(video, path, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
60
MediaBrowser.Providers/Movies/MovieXmlParser.cs
Normal file
60
MediaBrowser.Providers/Movies/MovieXmlParser.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.Movies
|
||||
{
|
||||
/// <summary>
|
||||
/// Class EpisodeXmlParser
|
||||
/// </summary>
|
||||
public class MovieXmlParser : BaseItemXmlParser<Video>
|
||||
{
|
||||
private readonly IItemRepository _itemRepo;
|
||||
|
||||
private Task _chaptersTask = null;
|
||||
|
||||
public MovieXmlParser(ILogger logger, IItemRepository itemRepo)
|
||||
: base(logger)
|
||||
{
|
||||
_itemRepo = itemRepo;
|
||||
}
|
||||
|
||||
public async Task FetchAsync(Video item, string metadataFile, CancellationToken cancellationToken)
|
||||
{
|
||||
_chaptersTask = null;
|
||||
|
||||
Fetch(item, metadataFile, cancellationToken);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (_chaptersTask != null)
|
||||
{
|
||||
await _chaptersTask.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the data from XML node.
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
protected override void FetchDataFromXmlNode(XmlReader reader, Video item)
|
||||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "Chapters":
|
||||
|
||||
_chaptersTask = FetchChaptersFromXmlNode(item.Id, reader.ReadSubtree(), _itemRepo, CancellationToken.None);
|
||||
break;
|
||||
|
||||
default:
|
||||
base.FetchDataFromXmlNode(reader, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Providers.TV;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
@ -15,6 +16,7 @@ namespace MediaBrowser.Providers.Savers
|
|||
public class EpisodeXmlSaver : IMetadataSaver
|
||||
{
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IItemRepository _itemRepository;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is enabled for] [the specified item].
|
||||
|
@ -38,9 +40,10 @@ namespace MediaBrowser.Providers.Savers
|
|||
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
|
||||
public EpisodeXmlSaver(IServerConfigurationManager config)
|
||||
public EpisodeXmlSaver(IServerConfigurationManager config, IItemRepository itemRepository)
|
||||
{
|
||||
_config = config;
|
||||
_itemRepository = itemRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -79,6 +82,7 @@ namespace MediaBrowser.Providers.Savers
|
|||
|
||||
XmlSaverHelpers.AddCommonNodes(item, builder);
|
||||
XmlSaverHelpers.AddMediaInfo(episode, builder);
|
||||
XmlSaverHelpers.AddChapters((Video)item, builder, _itemRepository);
|
||||
|
||||
builder.Append("</Item>");
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Providers.Movies;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
@ -18,10 +19,12 @@ namespace MediaBrowser.Providers.Savers
|
|||
public class MovieXmlSaver : IMetadataSaver
|
||||
{
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IItemRepository _itemRepository;
|
||||
|
||||
public MovieXmlSaver(IServerConfigurationManager config)
|
||||
public MovieXmlSaver(IServerConfigurationManager config, IItemRepository itemRepository)
|
||||
{
|
||||
_config = config;
|
||||
_itemRepository = itemRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -94,6 +97,8 @@ namespace MediaBrowser.Providers.Savers
|
|||
|
||||
XmlSaverHelpers.AddMediaInfo((Video)item, builder);
|
||||
|
||||
XmlSaverHelpers.AddChapters((Video)item, builder, _itemRepository);
|
||||
|
||||
builder.Append("</Title>");
|
||||
|
||||
var xmlFilePath = GetSavePath(item);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -79,7 +80,8 @@ namespace MediaBrowser.Providers.Savers
|
|||
"GamesDbId",
|
||||
"BirthDate",
|
||||
"DeathDate",
|
||||
"LockedFields"
|
||||
"LockedFields",
|
||||
"Chapters"
|
||||
});
|
||||
|
||||
var position = xml.ToString().LastIndexOf("</", StringComparison.OrdinalIgnoreCase);
|
||||
|
@ -411,7 +413,27 @@ namespace MediaBrowser.Providers.Savers
|
|||
|
||||
builder.Append("</Persons>");
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddChapters(Video item, StringBuilder builder, IItemRepository repository)
|
||||
{
|
||||
var chapters = repository.GetChapters(item.Id);
|
||||
|
||||
builder.Append("<Chapters>");
|
||||
|
||||
foreach (var chapter in chapters)
|
||||
{
|
||||
builder.Append("<Chapter>");
|
||||
builder.Append("<Name>" + SecurityElement.Escape(chapter.Name) + "</Name>");
|
||||
|
||||
var time = TimeSpan.FromTicks(chapter.StartPositionTicks);
|
||||
var ms = Convert.ToInt64(time.TotalMilliseconds);
|
||||
|
||||
builder.Append("<StartPositionMs>" + SecurityElement.Escape(ms.ToString(UsCulture)) + "</StartPositionMs>");
|
||||
builder.Append("</Chapter>");
|
||||
}
|
||||
|
||||
builder.Append("</Chapters>");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
{
|
||||
|
@ -17,10 +18,12 @@ namespace MediaBrowser.Providers.TV
|
|||
public class EpisodeProviderFromXml : BaseMetadataProvider
|
||||
{
|
||||
internal static EpisodeProviderFromXml Current { get; private set; }
|
||||
private readonly IItemRepository _itemRepo;
|
||||
|
||||
public EpisodeProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager)
|
||||
public EpisodeProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IItemRepository itemRepo)
|
||||
: base(logManager, configurationManager)
|
||||
{
|
||||
_itemRepo = itemRepo;
|
||||
Current = this;
|
||||
}
|
||||
|
||||
|
@ -98,7 +101,7 @@ namespace MediaBrowser.Providers.TV
|
|||
|
||||
try
|
||||
{
|
||||
new EpisodeXmlParser(Logger).Fetch((Episode)item, metadataFile, cancellationToken);
|
||||
await new EpisodeXmlParser(Logger, _itemRepo).FetchAsync((Episode)item, metadataFile, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace MediaBrowser.Providers.TV
|
||||
|
@ -11,13 +14,28 @@ namespace MediaBrowser.Providers.TV
|
|||
/// </summary>
|
||||
public class EpisodeXmlParser : BaseItemXmlParser<Episode>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EpisodeXmlParser" /> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public EpisodeXmlParser(ILogger logger)
|
||||
private readonly IItemRepository _itemRepo;
|
||||
|
||||
private Task _chaptersTask = null;
|
||||
|
||||
public EpisodeXmlParser(ILogger logger, IItemRepository itemRepo)
|
||||
: base(logger)
|
||||
{
|
||||
_itemRepo = itemRepo;
|
||||
}
|
||||
|
||||
public async Task FetchAsync(Episode item, string metadataFile, CancellationToken cancellationToken)
|
||||
{
|
||||
_chaptersTask = null;
|
||||
|
||||
Fetch(item, metadataFile, cancellationToken);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (_chaptersTask != null)
|
||||
{
|
||||
await _chaptersTask.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -29,7 +47,13 @@ namespace MediaBrowser.Providers.TV
|
|||
{
|
||||
switch (reader.Name)
|
||||
{
|
||||
case "Chapters":
|
||||
|
||||
_chaptersTask = FetchChaptersFromXmlNode(item.Id, reader.ReadSubtree(), _itemRepo, CancellationToken.None);
|
||||
break;
|
||||
|
||||
case "Episode":
|
||||
|
||||
//MB generated metadata is within an "Episode" node
|
||||
using (var subTree = reader.ReadSubtree())
|
||||
{
|
||||
|
|
|
@ -2,16 +2,12 @@
|
|||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Net;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -25,12 +21,6 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
/// </summary>
|
||||
public class ProviderManager : IProviderManager
|
||||
{
|
||||
/// <summary>
|
||||
/// The currently running metadata providers
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<string, Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource>> _currentlyRunningProviders =
|
||||
new ConcurrentDictionary<string, Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource>>();
|
||||
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// </summary>
|
||||
|
@ -72,19 +62,6 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
_httpClient = httpClient;
|
||||
ConfigurationManager = configurationManager;
|
||||
_directoryWatchers = directoryWatchers;
|
||||
|
||||
configurationManager.ConfigurationUpdated += configurationManager_ConfigurationUpdated;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the ConfigurationUpdated event of the configurationManager control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
|
||||
void configurationManager_ConfigurationUpdated(object sender, EventArgs e)
|
||||
{
|
||||
// Validate currently executing providers, in the background
|
||||
Task.Run(() => ValidateCurrentlyRunningProviders());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -217,8 +194,6 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
// This provides the ability to cancel just this one provider
|
||||
var innerCancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
OnProviderRefreshBeginning(provider, item, innerCancellationTokenSource);
|
||||
|
||||
try
|
||||
{
|
||||
var changed = await provider.FetchAsync(item, force, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token).ConfigureAwait(false);
|
||||
|
@ -253,70 +228,6 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||
finally
|
||||
{
|
||||
innerCancellationTokenSource.Dispose();
|
||||
|
||||
OnProviderRefreshCompleted(provider, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the kernal that a provider has begun refreshing
|
||||
/// </summary>
|
||||
/// <param name="provider">The provider.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="cancellationTokenSource">The cancellation token source.</param>
|
||||
public void OnProviderRefreshBeginning(BaseMetadataProvider provider, BaseItem item, CancellationTokenSource cancellationTokenSource)
|
||||
{
|
||||
var key = item.Id + provider.GetType().Name;
|
||||
|
||||
Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource> current;
|
||||
|
||||
if (_currentlyRunningProviders.TryGetValue(key, out current))
|
||||
{
|
||||
try
|
||||
{
|
||||
current.Item3.Cancel();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var tuple = new Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource>(provider, item, cancellationTokenSource);
|
||||
|
||||
_currentlyRunningProviders.AddOrUpdate(key, tuple, (k, v) => tuple);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the kernal that a provider has completed refreshing
|
||||
/// </summary>
|
||||
/// <param name="provider">The provider.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
public void OnProviderRefreshCompleted(BaseMetadataProvider provider, BaseItem item)
|
||||
{
|
||||
var key = item.Id + provider.GetType().Name;
|
||||
|
||||
Tuple<BaseMetadataProvider, BaseItem, CancellationTokenSource> current;
|
||||
|
||||
if (_currentlyRunningProviders.TryRemove(key, out current))
|
||||
{
|
||||
current.Item3.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the currently running providers and cancels any that should not be run due to configuration changes
|
||||
/// </summary>
|
||||
private void ValidateCurrentlyRunningProviders()
|
||||
{
|
||||
var enableInternetProviders = ConfigurationManager.Configuration.EnableInternetProviders;
|
||||
var internetProviderExcludeTypes = ConfigurationManager.Configuration.InternetProviderExcludeTypes;
|
||||
|
||||
foreach (var tuple in _currentlyRunningProviders.Values
|
||||
.Where(p => p.Item1.RequiresInternet && (!enableInternetProviders || internetProviderExcludeTypes.Contains(p.Item2.GetType().Name, StringComparer.OrdinalIgnoreCase)))
|
||||
.ToList())
|
||||
{
|
||||
tuple.Item3.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user