aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2013-06-24 21:22:21 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2013-06-24 21:22:21 -0400
commit92cd71143daa2d49abb0421a9cb641e9bf4489ae (patch)
treeb76e22c51681e90d85235fa06f51c76d3f2f9d06
parent12c6bc27f291fda668faaceba2fdc0920c446445 (diff)
Only fire metadata savers when appropriate
-rw-r--r--MediaBrowser.Api/LibraryService.cs22
-rw-r--r--MediaBrowser.Controller/Dto/DtoBuilder.cs5
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs7
-rw-r--r--MediaBrowser.Controller/Entities/User.cs4
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs7
-rw-r--r--MediaBrowser.Controller/Library/ItemUpdateType.cs13
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj1
-rw-r--r--MediaBrowser.Controller/Providers/BaseItemXmlParser.cs23
-rw-r--r--MediaBrowser.Controller/Providers/BaseMetadataProvider.cs5
-rw-r--r--MediaBrowser.Controller/Providers/IProviderManager.cs6
-rw-r--r--MediaBrowser.Model/Querying/ItemFields.cs5
-rw-r--r--MediaBrowser.Providers/ImageFromMediaLocationProvider.cs9
-rw-r--r--MediaBrowser.Providers/ImagesByNameProvider.cs9
-rw-r--r--MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs14
-rw-r--r--MediaBrowser.Providers/Movies/FanArtMovieProvider.cs9
-rw-r--r--MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs9
-rw-r--r--MediaBrowser.Providers/Movies/MovieDbProvider.cs2
-rw-r--r--MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs14
-rw-r--r--MediaBrowser.Providers/Movies/TmdbPersonProvider.cs9
-rw-r--r--MediaBrowser.Providers/Music/FanArtAlbumProvider.cs9
-rw-r--r--MediaBrowser.Providers/Music/FanArtArtistProvider.cs9
-rw-r--r--MediaBrowser.Providers/Savers/MovieXmlSaver.cs1
-rw-r--r--MediaBrowser.Providers/Savers/XmlSaverHelpers.cs106
-rw-r--r--MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs9
-rw-r--r--MediaBrowser.Providers/TV/FanArtSeasonProvider.cs9
-rw-r--r--MediaBrowser.Providers/TV/FanArtTVProvider.cs9
-rw-r--r--MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs8
-rw-r--r--MediaBrowser.Providers/TV/RemoteSeasonProvider.cs8
-rw-r--r--MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs8
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs89
-rw-r--r--MediaBrowser.Server.Implementations/Providers/ProviderManager.cs97
-rw-r--r--MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs2
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs8
33 files changed, 385 insertions, 160 deletions
diff --git a/MediaBrowser.Api/LibraryService.cs b/MediaBrowser.Api/LibraryService.cs
index 151f7016c..dd15dbc30 100644
--- a/MediaBrowser.Api/LibraryService.cs
+++ b/MediaBrowser.Api/LibraryService.cs
@@ -283,8 +283,8 @@ namespace MediaBrowser.Api
var item = DtoBuilder.GetItemByClientId(request.ItemId, _userManager, _libraryManager);
UpdateItem(request, item);
-
- return _libraryManager.UpdateItem(item, CancellationToken.None);
+
+ return _libraryManager.UpdateItem(item, ItemUpdateType.MetadataEdit, CancellationToken.None);
}
public void Post(UpdatePerson request)
@@ -300,7 +300,7 @@ namespace MediaBrowser.Api
UpdateItem(request, item);
- await _libraryManager.UpdateItem(item, CancellationToken.None).ConfigureAwait(false);
+ await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
}
public void Post(UpdateArtist request)
@@ -316,7 +316,7 @@ namespace MediaBrowser.Api
UpdateItem(request, item);
- await _libraryManager.UpdateItem(item, CancellationToken.None).ConfigureAwait(false);
+ await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
}
public void Post(UpdateStudio request)
@@ -332,7 +332,7 @@ namespace MediaBrowser.Api
UpdateItem(request, item);
- await _libraryManager.UpdateItem(item, CancellationToken.None).ConfigureAwait(false);
+ await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
}
public void Post(UpdateMusicGenre request)
@@ -348,7 +348,7 @@ namespace MediaBrowser.Api
UpdateItem(request, item);
- await _libraryManager.UpdateItem(item, CancellationToken.None).ConfigureAwait(false);
+ await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
}
public void Post(UpdateGenre request)
@@ -364,13 +364,19 @@ namespace MediaBrowser.Api
UpdateItem(request, item);
- await _libraryManager.UpdateItem(item, CancellationToken.None).ConfigureAwait(false);
+ await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
}
private void UpdateItem(BaseItemDto request, BaseItem item)
{
item.Name = request.Name;
- item.ForcedSortName = request.SortName;
+
+ // Only set the forced value if they changed it, or there's already one
+ if (!string.Equals(item.SortName, request.SortName) || !string.IsNullOrEmpty(item.ForcedSortName))
+ {
+ item.ForcedSortName = request.SortName;
+ }
+
item.DisplayMediaType = request.DisplayMediaType;
item.CommunityRating = request.CommunityRating;
item.HomePageUrl = request.HomePageUrl;
diff --git a/MediaBrowser.Controller/Dto/DtoBuilder.cs b/MediaBrowser.Controller/Dto/DtoBuilder.cs
index 2e28d7ad6..2bd338431 100644
--- a/MediaBrowser.Controller/Dto/DtoBuilder.cs
+++ b/MediaBrowser.Controller/Dto/DtoBuilder.cs
@@ -389,6 +389,11 @@ namespace MediaBrowser.Controller.Dto
dto.SortName = item.SortName;
}
+ if (fields.Contains(ItemFields.CustomRating))
+ {
+ dto.CustomRating = item.CustomRating;
+ }
+
if (fields.Contains(ItemFields.Taglines))
{
dto.Taglines = item.Taglines;
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index dbfeff747..695ea2583 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -834,12 +834,15 @@ namespace MediaBrowser.Controller.Entities
cancellationToken.ThrowIfCancellationRequested();
// Get the result from the item task
- var changed = await itemRefreshTask.ConfigureAwait(false);
+ var updateReason = await itemRefreshTask.ConfigureAwait(false);
+
+ var changed = updateReason.HasValue;
if (changed || forceSave || themeSongsChanged || themeVideosChanged || localTrailersChanged)
{
cancellationToken.ThrowIfCancellationRequested();
- await LibraryManager.UpdateItem(this, cancellationToken).ConfigureAwait(false);
+
+ await LibraryManager.UpdateItem(this, updateReason ?? ItemUpdateType.Unspecified, cancellationToken).ConfigureAwait(false);
}
return changed;
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index a2c5f98b8..79a813bb5 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -315,7 +315,9 @@ namespace MediaBrowser.Controller.Entities
ResolveArgs = null;
}
- var changed = await ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh, allowSlowProviders).ConfigureAwait(false);
+ var updateReason = await ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh, allowSlowProviders).ConfigureAwait(false);
+
+ var changed = updateReason.HasValue;
if (changed || forceSave)
{
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 46a6d38df..f1d5dce89 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -152,13 +152,15 @@ namespace MediaBrowser.Controller.Library
/// <param name="itemComparers">The item comparers.</param>
/// <param name="prescanTasks">The prescan tasks.</param>
/// <param name="postscanTasks">The postscan tasks.</param>
+ /// <param name="savers">The savers.</param>
void AddParts(IEnumerable<IResolverIgnoreRule> rules,
IEnumerable<IVirtualFolderCreator> pluginFolders,
IEnumerable<IItemResolver> resolvers,
IEnumerable<IIntroProvider> introProviders,
IEnumerable<IBaseItemComparer> itemComparers,
IEnumerable<ILibraryPrescanTask> prescanTasks,
- IEnumerable<ILibraryPostScanTask> postscanTasks);
+ IEnumerable<ILibraryPostScanTask> postscanTasks,
+ IEnumerable<IMetadataSaver> savers);
/// <summary>
/// Sorts the specified items.
@@ -205,9 +207,10 @@ namespace MediaBrowser.Controller.Library
/// Updates the item.
/// </summary>
/// <param name="item">The item.</param>
+ /// <param name="updateReason">The update reason.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- Task UpdateItem(BaseItem item, CancellationToken cancellationToken);
+ Task UpdateItem(BaseItem item, ItemUpdateType updateReason, CancellationToken cancellationToken);
/// <summary>
/// Retrieves the item.
diff --git a/MediaBrowser.Controller/Library/ItemUpdateType.cs b/MediaBrowser.Controller/Library/ItemUpdateType.cs
new file mode 100644
index 000000000..56ae2cbbd
--- /dev/null
+++ b/MediaBrowser.Controller/Library/ItemUpdateType.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace MediaBrowser.Controller.Library
+{
+ [Flags]
+ public enum ItemUpdateType
+ {
+ Unspecified = 1,
+ MetadataImport = 2,
+ ImageUpdate = 4,
+ MetadataEdit = 16
+ }
+}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 0bd82eaa7..2c6a6df08 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -81,6 +81,7 @@
<Compile Include="Library\ILibraryPostScanTask.cs" />
<Compile Include="Library\ILibraryPrescanTask.cs" />
<Compile Include="Library\IMetadataSaver.cs" />
+ <Compile Include="Library\ItemUpdateType.cs" />
<Compile Include="Localization\ILocalizationManager.cs" />
<Compile Include="Reflection\TypeMapper.cs" />
<Compile Include="Session\ISessionManager.cs" />
diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
index 29cf43f28..6c3d08a14 100644
--- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
+++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
@@ -124,6 +124,17 @@ namespace MediaBrowser.Controller.Providers
break;
}
+ case "CriticRating":
+ {
+ var text = reader.ReadElementContentAsString();
+ float value;
+ if (float.TryParse(text, NumberStyles.Any, _usCulture, out value))
+ {
+ item.CriticRating = value;
+ }
+
+ break;
+ }
case "Budget":
{
var text = reader.ReadElementContentAsString();
@@ -163,6 +174,18 @@ namespace MediaBrowser.Controller.Providers
break;
}
+ case "CriticRatingSummary":
+ {
+ var val = reader.ReadElementContentAsString();
+
+ if (!string.IsNullOrWhiteSpace(val))
+ {
+ item.CriticRatingSummary = val;
+ }
+
+ break;
+ }
+
case "TagLine":
{
var tagline = reader.ReadElementContentAsString();
diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
index 625910c0b..e415c6859 100644
--- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
@@ -75,6 +75,11 @@ namespace MediaBrowser.Controller.Providers
}
}
+ public virtual ItemUpdateType ItemUpdateType
+ {
+ get { return RequiresInternet ? ItemUpdateType.MetadataEdit : ItemUpdateType.MetadataImport; }
+ }
+
/// <summary>
/// Gets a value indicating whether [refresh on version change].
/// </summary>
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index 7f80973e9..643dbe1c2 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -55,15 +55,13 @@ namespace MediaBrowser.Controller.Providers
/// <param name="force">if set to <c>true</c> [force].</param>
/// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
/// <returns>Task{System.Boolean}.</returns>
- Task<bool> ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false, bool allowSlowProviders = true);
+ Task<ItemUpdateType?> ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false, bool allowSlowProviders = true);
/// <summary>
/// Adds the metadata providers.
/// </summary>
/// <param name="providers">The providers.</param>
- /// <param name="savers">The savers.</param>
- void AddParts(IEnumerable<BaseMetadataProvider> providers,
- IEnumerable<IMetadataSaver> savers);
+ void AddParts(IEnumerable<BaseMetadataProvider> providers);
/// <summary>
/// Gets the save path.
diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs
index d136af8f0..a8a58d6a6 100644
--- a/MediaBrowser.Model/Querying/ItemFields.cs
+++ b/MediaBrowser.Model/Querying/ItemFields.cs
@@ -27,6 +27,11 @@ namespace MediaBrowser.Model.Querying
CriticRatingSummary,
/// <summary>
+ /// The custom rating
+ /// </summary>
+ CustomRating,
+
+ /// <summary>
/// The date created of the item
/// </summary>
DateCreated,
diff --git a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs
index 87c450d55..883461cd0 100644
--- a/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs
+++ b/MediaBrowser.Providers/ImageFromMediaLocationProvider.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -22,6 +23,14 @@ namespace MediaBrowser.Providers
{
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Supportses the specified item.
/// </summary>
diff --git a/MediaBrowser.Providers/ImagesByNameProvider.cs b/MediaBrowser.Providers/ImagesByNameProvider.cs
index dad3a25f3..228ca94c5 100644
--- a/MediaBrowser.Providers/ImagesByNameProvider.cs
+++ b/MediaBrowser.Providers/ImagesByNameProvider.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
using System;
@@ -22,6 +23,14 @@ namespace MediaBrowser.Providers
{
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Supportses the specified item.
/// </summary>
diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
index c20a31b7e..ab3fbff55 100644
--- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
@@ -1,5 +1,4 @@
-using System.IO;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Common.MediaInfo;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
@@ -11,6 +10,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Concurrent;
+using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -113,6 +113,14 @@ namespace MediaBrowser.Providers.MediaInfo
get { return MetadataProviderPriority.Last; }
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
/// </summary>
@@ -193,8 +201,6 @@ namespace MediaBrowser.Providers.MediaInfo
// Image is already in the cache
item.PrimaryImagePath = path;
-
- await _libraryManager.UpdateItem(item, cancellationToken).ConfigureAwait(false);
}
/// <summary>
diff --git a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
index be105b63a..1a1c34928 100644
--- a/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanArtMovieProvider.cs
@@ -5,6 +5,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -61,6 +62,14 @@ namespace MediaBrowser.Providers.Movies
Current = this;
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Gets a value indicating whether [refresh on version change].
/// </summary>
diff --git a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs
index f092decdf..2c9fbcec8 100644
--- a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -85,6 +86,14 @@ namespace MediaBrowser.Providers.Movies
return item is Movie || item is BoxSet || item is MusicVideo;
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Gets a value indicating whether [requires internet].
/// </summary>
diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
index 8fecf6f44..43eae7ca2 100644
--- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs
@@ -226,7 +226,7 @@ namespace MediaBrowser.Providers.Movies
/// </summary>
/// <param name="item">The item.</param>
/// <returns><c>true</c> if [has alt meta] [the specified item]; otherwise, <c>false</c>.</returns>
- private bool HasAltMeta(BaseItem item)
+ internal static bool HasAltMeta(BaseItem item)
{
return item.LocationType == LocationType.FileSystem && item.ResolveArgs.ContainsMetaFileByName(AltMetaFileName);
}
diff --git a/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs b/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs
index c88169c80..3e12b2d87 100644
--- a/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs
+++ b/MediaBrowser.Providers/Movies/OpenMovieDatabaseProvider.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
@@ -73,6 +72,17 @@ namespace MediaBrowser.Providers.Movies
}
}
+ protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
+ {
+ // These values are now saved in movie.xml, so don't refresh if they're present
+ if (MovieDbProvider.HasAltMeta(item) && item.CriticRating.HasValue && !string.IsNullOrEmpty(item.CriticRatingSummary))
+ {
+ return false;
+ }
+
+ return base.NeedsRefreshInternal(item, providerInfo);
+ }
+
/// <summary>
/// Supports the specified item.
/// </summary>
diff --git a/MediaBrowser.Providers/Movies/TmdbPersonProvider.cs b/MediaBrowser.Providers/Movies/TmdbPersonProvider.cs
index fbf084218..b5c11acb1 100644
--- a/MediaBrowser.Providers/Movies/TmdbPersonProvider.cs
+++ b/MediaBrowser.Providers/Movies/TmdbPersonProvider.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -66,6 +67,14 @@ namespace MediaBrowser.Providers.Movies
}
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate | ItemUpdateType.MetadataEdit;
+ }
+ }
+
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
{
if (HasAltMeta(item))
diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
index 299ae2d06..d7990f431 100644
--- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
+++ b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -64,6 +65,14 @@ namespace MediaBrowser.Providers.Music
return item is MusicAlbum;
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Gets a value indicating whether [refresh on version change].
/// </summary>
diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
index 1685846d6..f310934af 100644
--- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs
@@ -5,6 +5,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -63,6 +64,14 @@ namespace MediaBrowser.Providers.Music
/// </summary>
protected string FanArtBaseUrl = "http://api.fanart.tv/webservice/artist/{0}/{1}/xml/all/1/1";
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Supportses the specified item.
/// </summary>
diff --git a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
index 32ec765b0..c180c2267 100644
--- a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
@@ -59,6 +59,7 @@ namespace MediaBrowser.Providers.Savers
builder.Append("<Title>");
XmlSaverHelpers.AddCommonNodes(item, builder);
+ XmlSaverHelpers.AppendMediaInfo((Video)item, builder);
builder.Append("</Title>");
diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
index 88d6ebec0..2ceb82d71 100644
--- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
@@ -89,9 +89,35 @@ namespace MediaBrowser.Providers.Savers
Directory.CreateDirectory(parentPath);
}
- using (var streamWriter = new StreamWriter(path, false, Encoding.UTF8))
+ var wasHidden = false;
+
+ var file = new FileInfo(path);
+
+ // This will fail if the file is hidden
+ if (file.Exists)
+ {
+ if ((file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
+ {
+ file.Attributes &= ~FileAttributes.Hidden;
+
+ wasHidden = true;
+ }
+ }
+
+ using (var filestream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
+ {
+ using (var streamWriter = new StreamWriter(filestream, Encoding.UTF8))
+ {
+ xmlDocument.Save(streamWriter);
+ }
+ }
+
+ if (wasHidden)
{
- xmlDocument.Save(streamWriter);
+ file.Refresh();
+
+ // Add back the attribute
+ file.Attributes |= FileAttributes.Hidden;
}
}
@@ -128,25 +154,21 @@ namespace MediaBrowser.Providers.Savers
builder.Append("<certification>" + SecurityElement.Escape(item.OfficialRating) + "</certification>");
}
- if (item.People.Count > 0)
- {
- builder.Append("<Persons>");
+ builder.Append("<Added>" + SecurityElement.Escape(item.DateCreated.ToString(UsCulture)) + "</Added>");
- foreach (var person in item.People)
- {
- builder.Append("<Person>");
- builder.Append("<Name>" + SecurityElement.Escape(person.Name) + "</Name>");
- builder.Append("<Type>" + SecurityElement.Escape(person.Type) + "</Type>");
- builder.Append("<Role>" + SecurityElement.Escape(person.Role) + "</Role>");
- builder.Append("</Person>");
- }
+ if (!string.IsNullOrEmpty(item.DisplayMediaType))
+ {
+ builder.Append("<Type>" + SecurityElement.Escape(item.DisplayMediaType) + "</Type>");
+ }
- builder.Append("</Persons>");
+ if (item.CriticRating.HasValue)
+ {
+ builder.Append("<CriticRating>" + SecurityElement.Escape(item.CriticRating.Value.ToString(UsCulture)) + "</CriticRating>");
}
- if (!string.IsNullOrEmpty(item.DisplayMediaType))
+ if (!string.IsNullOrEmpty(item.CriticRatingSummary))
{
- builder.Append("<Type>" + SecurityElement.Escape(item.DisplayMediaType) + "</Type>");
+ builder.Append("<CriticRatingSummary><![CDATA[" + item.Overview + "]]></CriticRatingSummary>");
}
if (!string.IsNullOrEmpty(item.Overview))
@@ -209,28 +231,17 @@ namespace MediaBrowser.Providers.Savers
builder.Append("<Language>" + SecurityElement.Escape(item.Language) + "</Language>");
}
- if (item.RunTimeTicks.HasValue)
+ // Use original runtime here, actual file runtime later in MediaInfo
+ var runTimeTicks = item.OriginalRunTimeTicks ?? item.RunTimeTicks;
+
+ if (runTimeTicks.HasValue)
{
- var timespan = TimeSpan.FromTicks(item.RunTimeTicks.Value);
+ var timespan = TimeSpan.FromTicks(runTimeTicks.Value);
builder.Append("<RunningTime>" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "</RunningTime>");
builder.Append("<Runtime>" + Convert.ToInt32(timespan.TotalMinutes).ToString(UsCulture) + "</Runtime>");
}
- if (item.Taglines.Count > 0)
- {
- builder.Append("<TagLine>" + SecurityElement.Escape(item.Taglines[0]) + "</TagLine>");
-
- builder.Append("<TagLines>");
-
- foreach (var tagline in item.Taglines)
- {
- builder.Append("<Tagline>" + SecurityElement.Escape(tagline) + "</Tagline>");
- }
-
- builder.Append("</TagLines>");
- }
-
var imdb = item.GetProviderId(MetadataProviders.Imdb);
if (!string.IsNullOrEmpty(imdb))
@@ -275,6 +286,20 @@ namespace MediaBrowser.Providers.Savers
builder.Append("<CollectionNumber>" + SecurityElement.Escape(tmdbCollection) + "</CollectionNumber>");
}
+ if (item.Taglines.Count > 0)
+ {
+ builder.Append("<TagLine>" + SecurityElement.Escape(item.Taglines[0]) + "</TagLine>");
+
+ builder.Append("<TagLines>");
+
+ foreach (var tagline in item.Taglines)
+ {
+ builder.Append("<Tagline>" + SecurityElement.Escape(tagline) + "</Tagline>");
+ }
+
+ builder.Append("</TagLines>");
+ }
+
if (item.Genres.Count > 0)
{
builder.Append("<Genres>");
@@ -311,7 +336,22 @@ namespace MediaBrowser.Providers.Savers
builder.Append("</Tags>");
}
- builder.Append("<Added>" + SecurityElement.Escape(item.DateCreated.ToString(UsCulture)) + "</Added>");
+ if (item.People.Count > 0)
+ {
+ builder.Append("<Persons>");
+
+ foreach (var person in item.People)
+ {
+ builder.Append("<Person>");
+ builder.Append("<Name>" + SecurityElement.Escape(person.Name) + "</Name>");
+ builder.Append("<Type>" + SecurityElement.Escape(person.Type) + "</Type>");
+ builder.Append("<Role>" + SecurityElement.Escape(person.Role) + "</Role>");
+ builder.Append("</Person>");
+ }
+
+ builder.Append("</Persons>");
+ }
+
}
/// <summary>
diff --git a/MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs b/MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs
index 5b1490750..8eb01a143 100644
--- a/MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs
+++ b/MediaBrowser.Providers/TV/EpisodeImageFromMediaLocationProvider.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using System;
@@ -21,6 +22,14 @@ namespace MediaBrowser.Providers.TV
{
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Supportses the specified item.
/// </summary>
diff --git a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
index ccdfc2a81..d0a0735fb 100644
--- a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -35,6 +36,14 @@ namespace MediaBrowser.Providers.TV
_providerManager = providerManager;
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Supportses the specified item.
/// </summary>
diff --git a/MediaBrowser.Providers/TV/FanArtTVProvider.cs b/MediaBrowser.Providers/TV/FanArtTVProvider.cs
index 878cd26e2..6dc61b35d 100644
--- a/MediaBrowser.Providers/TV/FanArtTVProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArtTVProvider.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -48,6 +49,14 @@ namespace MediaBrowser.Providers.TV
return item is Series;
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Needses the refresh internal.
/// </summary>
diff --git a/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs b/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs
index 32345cd09..a3d44a032 100644
--- a/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/RemoteEpisodeProvider.cs
@@ -61,6 +61,14 @@ namespace MediaBrowser.Providers.TV
return item is Episode;
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate | ItemUpdateType.MetadataEdit;
+ }
+ }
+
/// <summary>
/// Gets the priority.
/// </summary>
diff --git a/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs b/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs
index 179354c08..f8399ebdf 100644
--- a/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/RemoteSeasonProvider.cs
@@ -70,6 +70,14 @@ namespace MediaBrowser.Providers.TV
}
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Gets a value indicating whether [refresh on version change].
/// </summary>
diff --git a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs
index bf57d3c8c..2d8bf5ed6 100644
--- a/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs
+++ b/MediaBrowser.Providers/TV/TvdbSeriesImageProvider.cs
@@ -80,6 +80,14 @@ namespace MediaBrowser.Providers.TV
}
}
+ public override ItemUpdateType ItemUpdateType
+ {
+ get
+ {
+ return ItemUpdateType.ImageUpdate;
+ }
+ }
+
/// <summary>
/// Gets a value indicating whether [refresh on version change].
/// </summary>
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index d1b7634fb..0465cb5c3 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -128,6 +128,10 @@ namespace MediaBrowser.Server.Implementations.Library
/// <value>The by reference items.</value>
private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; }
+ private IEnumerable<IMetadataSaver> _savers;
+
+ private readonly Func<IDirectoryWatchers> _directoryWatchersFactory;
+
/// <summary>
/// The _library items cache
/// </summary>
@@ -167,13 +171,14 @@ namespace MediaBrowser.Server.Implementations.Library
/// <param name="userManager">The user manager.</param>
/// <param name="configurationManager">The configuration manager.</param>
/// <param name="userDataRepository">The user data repository.</param>
- public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataRepository userDataRepository)
+ public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataRepository userDataRepository, Func<IDirectoryWatchers> directoryWatchersFactory)
{
_logger = logger;
_taskManager = taskManager;
_userManager = userManager;
ConfigurationManager = configurationManager;
_userDataRepository = userDataRepository;
+ _directoryWatchersFactory = directoryWatchersFactory;
ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>();
ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated;
@@ -191,13 +196,15 @@ namespace MediaBrowser.Server.Implementations.Library
/// <param name="itemComparers">The item comparers.</param>
/// <param name="prescanTasks">The prescan tasks.</param>
/// <param name="postscanTasks">The postscan tasks.</param>
+ /// <param name="savers">The savers.</param>
public void AddParts(IEnumerable<IResolverIgnoreRule> rules,
IEnumerable<IVirtualFolderCreator> pluginFolders,
IEnumerable<IItemResolver> resolvers,
IEnumerable<IIntroProvider> introProviders,
IEnumerable<IBaseItemComparer> itemComparers,
IEnumerable<ILibraryPrescanTask> prescanTasks,
- IEnumerable<ILibraryPostScanTask> postscanTasks)
+ IEnumerable<ILibraryPostScanTask> postscanTasks,
+ IEnumerable<IMetadataSaver> savers)
{
EntityResolutionIgnoreRules = rules;
PluginFolderCreators = pluginFolders;
@@ -206,6 +213,7 @@ namespace MediaBrowser.Server.Implementations.Library
Comparers = itemComparers;
PrescanTasks = prescanTasks;
PostscanTasks = postscanTasks;
+ _savers = savers;
}
/// <summary>
@@ -326,7 +334,7 @@ namespace MediaBrowser.Server.Implementations.Library
/// <param name="newName">The new name.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- private Task UpdateSeasonZeroNames(string newName, CancellationToken cancellationToken)
+ private async Task UpdateSeasonZeroNames(string newName, CancellationToken cancellationToken)
{
var seasons = RootFolder.RecursiveChildren
.OfType<Season>()
@@ -336,9 +344,16 @@ namespace MediaBrowser.Server.Implementations.Library
foreach (var season in seasons)
{
season.Name = newName;
- }
- return UpdateItems(seasons, cancellationToken);
+ try
+ {
+ await UpdateItem(season, ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error saving {0}", ex, season.Path);
+ }
+ }
}
/// <summary>
@@ -1278,33 +1293,35 @@ namespace MediaBrowser.Server.Implementations.Library
}
/// <summary>
- /// Updates the items.
+ /// Updates the item.
/// </summary>
- /// <param name="items">The items.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="updateReason">The update reason.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- private async Task UpdateItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken)
+ public async Task UpdateItem(BaseItem item, ItemUpdateType updateReason, CancellationToken cancellationToken)
{
- var list = items.ToList();
+ await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false);
- await ItemRepository.SaveItems(list, cancellationToken).ConfigureAwait(false);
+ UpdateItemInLibraryCache(item);
- foreach (var item in list)
+ // If metadata was downloaded or edited, save external metadata
+ if ((updateReason & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit)
{
- UpdateItemInLibraryCache(item);
- OnItemUpdated(item);
+ await SaveMetadata(item).ConfigureAwait(false);
}
- }
- /// <summary>
- /// Updates the item.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- public Task UpdateItem(BaseItem item, CancellationToken cancellationToken)
- {
- return UpdateItems(new[] { item }, cancellationToken);
+ if (ItemUpdated != null)
+ {
+ try
+ {
+ ItemUpdated(this, new ItemChangeEventArgs { Item = item });
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in ItemUpdated event handler", ex);
+ }
+ }
}
/// <summary>
@@ -1337,22 +1354,38 @@ namespace MediaBrowser.Server.Implementations.Library
return ItemRepository.RetrieveItem(id, type);
}
+ private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
+
/// <summary>
- /// Called when [item updated].
+ /// Saves the metadata.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>Task.</returns>
- private void OnItemUpdated(BaseItem item)
+ private async Task SaveMetadata(BaseItem item)
{
- if (ItemUpdated != null)
+ foreach (var saver in _savers.Where(i => i.Supports(item)))
{
+ var path = saver.GetSavePath(item);
+
+ var semaphore = _fileLocks.GetOrAdd(path, key => new SemaphoreSlim(1, 1));
+
+ var directoryWatchers = _directoryWatchersFactory();
+
+ await semaphore.WaitAsync().ConfigureAwait(false);
+
try
{
- ItemUpdated(this, new ItemChangeEventArgs { Item = item });
+ directoryWatchers.TemporarilyIgnore(path);
+ saver.Save(item, CancellationToken.None);
}
catch (Exception ex)
{
- _logger.ErrorException("Error in ItemUpdated event handler", ex);
+ _logger.ErrorException("Error in metadata saver", ex);
+ }
+ finally
+ {
+ directoryWatchers.RemoveTempIgnore(path);
+ semaphore.Release();
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
index 01c0659b6..ee8bb4c09 100644
--- a/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
+++ b/MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
@@ -60,8 +60,6 @@ namespace MediaBrowser.Server.Implementations.Providers
/// <value>The metadata providers enumerable.</value>
private BaseMetadataProvider[] MetadataProviders { get; set; }
- private IEnumerable<IMetadataSaver> _savers;
-
/// <summary>
/// Initializes a new instance of the <see cref="ProviderManager" /> class.
/// </summary>
@@ -79,44 +77,6 @@ namespace MediaBrowser.Server.Implementations.Providers
_remoteImageCache = new FileSystemRepository(configurationManager.ApplicationPaths.DownloadedImagesDataPath);
configurationManager.ConfigurationUpdated += configurationManager_ConfigurationUpdated;
-
- libraryManager.ItemUpdated += libraryManager_ItemUpdated;
- }
-
- private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
-
- /// <summary>
- /// Handles the ItemUpdated event of the libraryManager control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="ItemChangeEventArgs"/> instance containing the event data.</param>
- async void libraryManager_ItemUpdated(object sender, ItemChangeEventArgs e)
- {
- var item = e.Item;
-
- foreach (var saver in _savers.Where(i => i.Supports(item)))
- {
- var path = saver.GetSavePath(item);
-
- var semaphore = _fileLocks.GetOrAdd(path, key => new SemaphoreSlim(1, 1));
-
- await semaphore.WaitAsync().ConfigureAwait(false);
-
- try
- {
- _directoryWatchers.TemporarilyIgnore(path);
- saver.Save(item, CancellationToken.None);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in metadata saver", ex);
- }
- finally
- {
- _directoryWatchers.RemoveTempIgnore(path);
- semaphore.Release();
- }
- }
}
/// <summary>
@@ -134,12 +94,9 @@ namespace MediaBrowser.Server.Implementations.Providers
/// Adds the metadata providers.
/// </summary>
/// <param name="providers">The providers.</param>
- /// <param name="savers">The savers.</param>
- public void AddParts(IEnumerable<BaseMetadataProvider> providers,
- IEnumerable<IMetadataSaver> savers)
+ public void AddParts(IEnumerable<BaseMetadataProvider> providers)
{
MetadataProviders = providers.OrderBy(e => e.Priority).ToArray();
- _savers = savers;
}
/// <summary>
@@ -150,18 +107,14 @@ namespace MediaBrowser.Server.Implementations.Providers
/// <param name="force">if set to <c>true</c> [force].</param>
/// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
/// <returns>Task{System.Boolean}.</returns>
- public async Task<bool> ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false, bool allowSlowProviders = true)
+ public async Task<ItemUpdateType?> ExecuteMetadataProviders(BaseItem item, CancellationToken cancellationToken, bool force = false, bool allowSlowProviders = true)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
- // Allow providers of the same priority to execute in parallel
- MetadataProviderPriority? currentPriority = null;
- var currentTasks = new List<Task<bool>>();
-
- var result = false;
+ ItemUpdateType? result = null;
cancellationToken.ThrowIfCancellationRequested();
@@ -188,15 +141,6 @@ namespace MediaBrowser.Server.Implementations.Providers
continue;
}
- // When a new priority is reached, await the ones that are currently running and clear the list
- if (currentPriority.HasValue && currentPriority.Value != provider.Priority && currentTasks.Count > 0)
- {
- var results = await Task.WhenAll(currentTasks).ConfigureAwait(false);
- result |= results.Contains(true);
-
- currentTasks.Clear();
- }
-
// Put this check below the await because the needs refresh of the next tier of providers may depend on the previous ones running
// This is the case for the fan art provider which depends on the movie and tv providers having run before them
if (provider.RequiresInternet && item.DontFetchMeta)
@@ -216,14 +160,19 @@ namespace MediaBrowser.Server.Implementations.Providers
_logger.Error("Error determining NeedsRefresh for {0}", ex, item.Path);
}
- currentTasks.Add(FetchAsync(provider, item, force, cancellationToken));
- currentPriority = provider.Priority;
- }
+ var updateType = await FetchAsync(provider, item, force, cancellationToken).ConfigureAwait(false);
- if (currentTasks.Count > 0)
- {
- var results = await Task.WhenAll(currentTasks).ConfigureAwait(false);
- result |= results.Contains(true);
+ if (updateType.HasValue)
+ {
+ if (result.HasValue)
+ {
+ result = result.Value | updateType.Value;
+ }
+ else
+ {
+ result = updateType;
+ }
+ }
}
return result;
@@ -238,7 +187,7 @@ namespace MediaBrowser.Server.Implementations.Providers
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{System.Boolean}.</returns>
/// <exception cref="System.ArgumentNullException"></exception>
- private async Task<bool> FetchAsync(BaseMetadataProvider provider, BaseItem item, bool force, CancellationToken cancellationToken)
+ private async Task<ItemUpdateType?> FetchAsync(BaseMetadataProvider provider, BaseItem item, bool force, CancellationToken cancellationToken)
{
if (item == null)
{
@@ -256,7 +205,14 @@ namespace MediaBrowser.Server.Implementations.Providers
try
{
- return await provider.FetchAsync(item, force, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token).ConfigureAwait(false);
+ var changed = await provider.FetchAsync(item, force, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token).ConfigureAwait(false);
+
+ if (changed)
+ {
+ return provider.ItemUpdateType;
+ }
+
+ return null;
}
catch (OperationCanceledException ex)
{
@@ -268,14 +224,15 @@ namespace MediaBrowser.Server.Implementations.Providers
throw;
}
- return false;
+ return null;
}
catch (Exception ex)
{
_logger.ErrorException("{0} failed refreshing {1}", ex, provider.GetType().Name, item.Name);
provider.SetLastRefreshed(item, DateTime.UtcNow, ProviderRefreshStatus.Failure);
- return true;
+
+ return ItemUpdateType.Unspecified;
}
finally
{
diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs
index d63494c1e..dc8425ac8 100644
--- a/MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs
+++ b/MediaBrowser.Server.Implementations/ScheduledTasks/VideoImagesTask.cs
@@ -294,7 +294,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
// Image is already in the cache
item.PrimaryImagePath = path;
- await _libraryManager.UpdateItem(item, cancellationToken).ConfigureAwait(false);
+ await _libraryManager.UpdateItem(item, ItemUpdateType.ImageUpdate, cancellationToken).ConfigureAwait(false);
}
else
{
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 09e33d7fd..70cd319ca 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -262,7 +262,7 @@ namespace MediaBrowser.ServerApplication
UserManager = new UserManager(Logger, ServerConfigurationManager);
RegisterSingleInstance(UserManager);
- LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataRepository);
+ LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataRepository, () => DirectoryWatchers);
RegisterSingleInstance(LibraryManager);
InstallationManager = new InstallationManager(HttpClient, PackageManager, JsonSerializer, Logger, this);
@@ -397,10 +397,10 @@ namespace MediaBrowser.ServerApplication
GetExports<IIntroProvider>(),
GetExports<IBaseItemComparer>(),
GetExports<ILibraryPrescanTask>(),
- GetExports<ILibraryPostScanTask>());
-
- ProviderManager.AddParts(GetExports<BaseMetadataProvider>().ToArray(),
+ GetExports<ILibraryPostScanTask>(),
GetExports<IMetadataSaver>());
+
+ ProviderManager.AddParts(GetExports<BaseMetadataProvider>().ToArray());
}
/// <summary>