diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index f110f85d2e..2dcea37bdf 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -4,11 +4,11 @@ using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Users;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
-using MediaBrowser.Model.Users;
namespace MediaBrowser.Controller.Entities.Audio
{
@@ -80,6 +80,15 @@ namespace MediaBrowser.Controller.Entities.Audio
}
}
+ [IgnoreDataMember]
+ protected override bool SupportsOwnedItems
+ {
+ get
+ {
+ return false;
+ }
+ }
+
[IgnoreDataMember]
public override Folder LatestItemsIndexContainer
{
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 67be6c2ceb..1e46aa9e56 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -690,7 +690,7 @@ namespace MediaBrowser.Controller.Entities
var requiresSave = false;
- if (IsFolder || Parent != null)
+ if (SupportsOwnedItems)
{
try
{
@@ -722,6 +722,12 @@ namespace MediaBrowser.Controller.Entities
}
}
+ [IgnoreDataMember]
+ protected virtual bool SupportsOwnedItems
+ {
+ get { return IsFolder || Parent != null; }
+ }
+
///
/// Refreshes owned items such as trailers, theme videos, special features, etc.
/// Returns true or false indicating if changes were found.
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 7a902c0c54..cf85cbb0d1 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -6,7 +6,6 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
-using MoreLinq;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -106,6 +105,7 @@ namespace MediaBrowser.Controller.Entities
public virtual List LinkedChildren { get; set; }
+ [IgnoreDataMember]
protected virtual bool SupportsShortcutChildren
{
get { return true; }
@@ -1033,6 +1033,15 @@ namespace MediaBrowser.Controller.Entities
.Where(i => i.Item2 != null);
}
+ [IgnoreDataMember]
+ protected override bool SupportsOwnedItems
+ {
+ get
+ {
+ return base.SupportsOwnedItems || SupportsShortcutChildren;
+ }
+ }
+
protected override async Task RefreshedOwnedItems(MetadataRefreshOptions options, List fileSystemChildren, CancellationToken cancellationToken)
{
var changesFound = false;
diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
index b8f8dcbe18..7f74e33793 100644
--- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
+++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Progress;
-using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
@@ -138,7 +137,6 @@ namespace MediaBrowser.Controller.Entities.Movies
public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken)
{
- var b = this;
// Refresh bottom up, children first, then the boxset
// By then hopefully the movies within will have Tmdb collection values
var items = GetRecursiveChildren().ToList();
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index a2731f6dfb..c8408365d3 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -55,6 +55,15 @@ namespace MediaBrowser.Controller.Entities.TV
get { return true; }
}
+ [IgnoreDataMember]
+ protected override bool SupportsOwnedItems
+ {
+ get
+ {
+ return IsStacked || MediaSourceCount > 1;
+ }
+ }
+
[IgnoreDataMember]
public int? AiredSeasonNumber
{
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 1033df4dee..8e96786d5e 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -1,4 +1,6 @@
-using MediaBrowser.Controller.Localization;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
@@ -14,7 +16,7 @@ namespace MediaBrowser.Controller.Entities.TV
///
/// Class Series
///
- public class Series : Folder, IHasSoundtracks, IHasTrailers, IHasDisplayOrder, IHasLookupInfo, IHasSpecialFeatures
+ public class Series : Folder, IHasSoundtracks, IHasTrailers, IHasDisplayOrder, IHasLookupInfo, IHasSpecialFeatures, IMetadataContainer
{
public List SpecialFeatureIds { get; set; }
public List SoundtrackIds { get; set; }
@@ -210,6 +212,55 @@ namespace MediaBrowser.Controller.Entities.TV
return returnList;
}
+ public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken)
+ {
+ // Refresh bottom up, children first, then the boxset
+ // By then hopefully the movies within will have Tmdb collection values
+ var items = GetRecursiveChildren().ToList();
+
+ var seasons = items.OfType().ToList();
+ var otherItems = items.Except(seasons).ToList();
+
+ var totalItems = seasons.Count + otherItems.Count;
+ var numComplete = 0;
+
+ refreshOptions = new MetadataRefreshOptions(refreshOptions);
+ refreshOptions.IsPostRecursiveRefresh = true;
+
+ // Refresh songs
+ foreach (var item in seasons)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+
+ numComplete++;
+ double percent = numComplete;
+ percent /= totalItems;
+ progress.Report(percent * 100);
+ }
+
+ // Refresh current item
+ await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+
+ // Refresh all non-songs
+ foreach (var item in otherItems)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+
+ numComplete++;
+ double percent = numComplete;
+ percent /= totalItems;
+ progress.Report(percent * 100);
+ }
+
+ await ProviderManager.RefreshMetadata(this, refreshOptions, cancellationToken).ConfigureAwait(false);
+
+ progress.Report(100);
+ }
+
public IEnumerable GetEpisodes(User user, int seasonNumber)
{
var config = user.Configuration;
diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
index a9e1555098..2cd119cf51 100644
--- a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
+++ b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
@@ -11,6 +11,8 @@ namespace MediaBrowser.Controller.Providers
///
public bool ReplaceAllMetadata { get; set; }
+ public bool IsPostRecursiveRefresh { get; set; }
+
public MetadataRefreshMode MetadataRefreshMode { get; set; }
public bool ForceSave { get; set; }
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index baccfa65b3..ab6cb89a62 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -183,7 +183,14 @@ namespace MediaBrowser.Providers.Manager
await SaveProviderResult(itemOfType, refreshResult, refreshOptions.DirectoryService).ConfigureAwait(false);
}
- itemOfType.AfterMetadataRefresh();
+ await AfterMetadataRefresh(itemOfType, refreshOptions, cancellationToken).ConfigureAwait(false);
+ }
+
+ private readonly Task _cachedTask = Task.FromResult(true);
+ protected virtual Task AfterMetadataRefresh(TItemType item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
+ {
+ item.AfterMetadataRefresh();
+ return _cachedTask;
}
private void MergeIdentities(TItemType item, TIdType id)
@@ -323,11 +330,11 @@ namespace MediaBrowser.Providers.Manager
return item is TItemType;
}
- protected virtual async Task RefreshWithProviders(TItemType item,
- TIdType id,
- MetadataRefreshOptions options,
- List providers,
- ItemImageProvider imageService,
+ protected virtual async Task RefreshWithProviders(TItemType item,
+ TIdType id,
+ MetadataRefreshOptions options,
+ List providers,
+ ItemImageProvider imageService,
CancellationToken cancellationToken)
{
var refreshResult = new RefreshResult
@@ -603,10 +610,10 @@ namespace MediaBrowser.Providers.Manager
}
}
- protected abstract void MergeData(TItemType source,
- TItemType target,
- List lockedFields,
- bool replaceData,
+ protected abstract void MergeData(TItemType source,
+ TItemType target,
+ List lockedFields,
+ bool replaceData,
bool mergeMetadataSettings);
public virtual int Order
diff --git a/MediaBrowser.Providers/TV/SeriesMetadataService.cs b/MediaBrowser.Providers/TV/SeriesMetadataService.cs
index e03104a23b..df06525c1f 100644
--- a/MediaBrowser.Providers/TV/SeriesMetadataService.cs
+++ b/MediaBrowser.Providers/TV/SeriesMetadataService.cs
@@ -8,6 +8,8 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
namespace MediaBrowser.Providers.TV
{
@@ -16,7 +18,8 @@ namespace MediaBrowser.Providers.TV
private readonly ILocalizationManager _localization;
private readonly ILibraryManager _libraryManager;
- public SeriesMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILocalizationManager localization, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager)
+ public SeriesMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager, ILocalizationManager localization, ILibraryManager libraryManager)
+ : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager)
{
_localization = localization;
_libraryManager = libraryManager;
@@ -52,12 +55,24 @@ namespace MediaBrowser.Providers.TV
if (replaceData || target.AirDays.Count == 0)
{
target.AirDays = source.AirDays;
- }
-
+ }
+
if (mergeMetadataSettings)
{
target.DisplaySpecialsWithSeasons = source.DisplaySpecialsWithSeasons;
}
}
+
+ protected override async Task AfterMetadataRefresh(Series item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
+ {
+ await base.AfterMetadataRefresh(item, refreshOptions, cancellationToken).ConfigureAwait(false);
+
+ if (refreshOptions.IsPostRecursiveRefresh)
+ {
+ var provider = new DummySeasonProvider(ServerConfigurationManager, Logger, _localization, _libraryManager);
+
+ await provider.Run(item, CancellationToken.None).ConfigureAwait(false);
+ }
+ }
}
}
diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
index 8b22f45a35..874b5c92db 100644
--- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
+++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
@@ -48,13 +48,6 @@ namespace MediaBrowser.Providers.TV
.Cast()
.ToList();
- var provider = new DummySeasonProvider(_config, _logger, _localization, _libraryManager);
-
- foreach (var series in seriesList)
- {
- await provider.Run(series, cancellationToken).ConfigureAwait(false);
- }
-
var seriesGroups = FindSeriesGroups(seriesList).Where(g => !string.IsNullOrEmpty(g.Key)).ToList();
await new MissingEpisodeProvider(_logger, _config, _libraryManager, _localization).Run(seriesGroups, cancellationToken).ConfigureAwait(false);