New provider system. Only for people right now

This commit is contained in:
Luke Pulverenti
2014-01-28 13:37:01 -05:00
parent d748967c5d
commit ad82c9f5e9
83 changed files with 3094 additions and 1746 deletions

View File

@@ -23,7 +23,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Class BaseItem
/// </summary>
public abstract class BaseItem : IHasProviderIds, ILibraryItem, IHasImages, IHasUserData
public abstract class BaseItem : IHasProviderIds, ILibraryItem, IHasImages, IHasUserData, IHasMetadata
{
protected BaseItem()
{
@@ -767,25 +767,35 @@ namespace MediaBrowser.Controller.Entities
}).ToList();
}
public Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool resetResolveArgs = true)
{
return RefreshMetadata(new MetadataRefreshOptions { ResetResolveArgs = resetResolveArgs }, cancellationToken);
}
/// <summary>
/// Overrides the base implementation to refresh metadata for local trailers
/// </summary>
/// <param name="options">The options.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="forceSave">if set to <c>true</c> [is new item].</param>
/// <param name="forceRefresh">if set to <c>true</c> [force].</param>
/// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
/// <param name="resetResolveArgs">if set to <c>true</c> [reset resolve args].</param>
/// <returns>true if a provider reports we changed</returns>
public virtual async Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true)
public async Task<bool> RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken)
{
if (resetResolveArgs)
if (options.ResetResolveArgs)
{
// Reload this
ResetResolveArgs();
}
await ProviderManager.RefreshMetadata(this, options, cancellationToken).ConfigureAwait(false);
return false;
}
[Obsolete]
public virtual async Task<bool> RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
{
// Refresh for the item
var itemRefreshTask = ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh, allowSlowProviders);
var itemRefreshTask = ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh);
cancellationToken.ThrowIfCancellationRequested();
@@ -800,15 +810,15 @@ namespace MediaBrowser.Controller.Entities
var hasThemeMedia = this as IHasThemeMedia;
if (hasThemeMedia != null)
{
themeSongsChanged = await RefreshThemeSongs(hasThemeMedia, cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
themeSongsChanged = await RefreshThemeSongs(hasThemeMedia, cancellationToken, forceSave, forceRefresh).ConfigureAwait(false);
themeVideosChanged = await RefreshThemeVideos(hasThemeMedia, cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
themeVideosChanged = await RefreshThemeVideos(hasThemeMedia, cancellationToken, forceSave, forceRefresh).ConfigureAwait(false);
}
var hasTrailers = this as IHasTrailers;
if (hasTrailers != null)
{
localTrailersChanged = await RefreshLocalTrailers(hasTrailers, cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
localTrailersChanged = await RefreshLocalTrailers(hasTrailers, cancellationToken, forceSave, forceRefresh).ConfigureAwait(false);
}
}
@@ -829,14 +839,20 @@ namespace MediaBrowser.Controller.Entities
return changed;
}
private async Task<bool> RefreshLocalTrailers(IHasTrailers item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true)
private async Task<bool> RefreshLocalTrailers(IHasTrailers item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
{
var newItems = LoadLocalTrailers().ToList();
var newItemIds = newItems.Select(i => i.Id).ToList();
var itemsChanged = !item.LocalTrailerIds.SequenceEqual(newItemIds);
var tasks = newItems.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false));
var tasks = newItems.Select(i => i.RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = forceSave,
ReplaceAllMetadata = forceRefresh,
ResetResolveArgs = false
}, cancellationToken));
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
@@ -845,14 +861,20 @@ namespace MediaBrowser.Controller.Entities
return itemsChanged || results.Contains(true);
}
private async Task<bool> RefreshThemeVideos(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true)
private async Task<bool> RefreshThemeVideos(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
{
var newThemeVideos = LoadThemeVideos().ToList();
var newThemeVideoIds = newThemeVideos.Select(i => i.Id).ToList();
var themeVideosChanged = !item.ThemeVideoIds.SequenceEqual(newThemeVideoIds);
var tasks = newThemeVideos.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false));
var tasks = newThemeVideos.Select(i => i.RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = forceSave,
ReplaceAllMetadata = forceRefresh,
ResetResolveArgs = false
}, cancellationToken));
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
@@ -864,14 +886,20 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Refreshes the theme songs.
/// </summary>
private async Task<bool> RefreshThemeSongs(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true)
private async Task<bool> RefreshThemeSongs(IHasThemeMedia item, CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
{
var newThemeSongs = LoadThemeSongs().ToList();
var newThemeSongIds = newThemeSongs.Select(i => i.Id).ToList();
var themeSongsChanged = !item.ThemeSongIds.SequenceEqual(newThemeSongIds);
var tasks = newThemeSongs.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false));
var tasks = newThemeSongs.Select(i => i.RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = forceSave,
ReplaceAllMetadata = forceRefresh,
ResetResolveArgs = false
}, cancellationToken));
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
@@ -1456,7 +1484,13 @@ namespace MediaBrowser.Controller.Entities
// Refresh metadata
// Need to disable slow providers or the image might get re-downloaded
return RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false);
return RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = true,
ImageRefreshMode = MetadataRefreshMode.None,
MetadataRefreshMode = MetadataRefreshMode.None
}, CancellationToken.None);
}
/// <summary>
@@ -1482,8 +1516,10 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Validates that images within the item are still on the file system
/// </summary>
public void ValidateImages()
public bool ValidateImages()
{
var changed = false;
// Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below
var deletedKeys = Images
.Where(image => !File.Exists(image.Value))
@@ -1494,14 +1530,28 @@ namespace MediaBrowser.Controller.Entities
foreach (var key in deletedKeys)
{
Images.Remove(key);
changed = true;
}
if (ValidateBackdrops())
{
changed = true;
}
if (ValidateScreenshots())
{
changed = true;
}
return changed;
}
/// <summary>
/// Validates that backdrops within the item are still on the file system
/// </summary>
public void ValidateBackdrops()
private bool ValidateBackdrops()
{
var changed = false;
// Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below
var deletedImages = BackdropImagePaths
.Where(path => !File.Exists(path))
@@ -1513,7 +1563,11 @@ namespace MediaBrowser.Controller.Entities
BackdropImagePaths.Remove(path);
RemoveImageSourceForPath(path);
changed = true;
}
return changed;
}
/// <summary>
@@ -1593,9 +1647,16 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Validates the screenshots.
/// </summary>
public void ValidateScreenshots()
private bool ValidateScreenshots()
{
var hasScreenshots = (IHasScreenshots)this;
var changed = false;
var hasScreenshots = this as IHasScreenshots;
if (hasScreenshots == null)
{
return changed;
}
// Only validate paths from the same directory - need to copy to a list because we are going to potentially modify the collection below
var deletedImages = hasScreenshots.ScreenshotImagePaths
@@ -1606,7 +1667,10 @@ namespace MediaBrowser.Controller.Entities
foreach (var path in deletedImages)
{
hasScreenshots.ScreenshotImagePaths.Remove(path);
changed = true;
}
return changed;
}
/// <summary>
@@ -1699,7 +1763,12 @@ namespace MediaBrowser.Controller.Entities
FileSystem.SwapFiles(file1, file2);
// Directory watchers should repeat this, but do a quick refresh first
return RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false);
return RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = true,
MetadataRefreshMode = MetadataRefreshMode.None
}, CancellationToken.None);
}
public virtual bool IsPlayed(User user)

View File

@@ -3,6 +3,7 @@ using MediaBrowser.Common.Progress;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using MoreLinq;
@@ -535,7 +536,13 @@ namespace MediaBrowser.Controller.Entities
try
{
//refresh it
await child.RefreshMetadata(cancellationToken, forceSave: currentTuple.Item2, forceRefresh: forceRefreshMetadata, resetResolveArgs: false).ConfigureAwait(false);
await child.RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = currentTuple.Item2,
ReplaceAllMetadata = forceRefreshMetadata,
ResetResolveArgs = false
}, cancellationToken).ConfigureAwait(false);
}
catch (IOException ex)
{
@@ -907,9 +914,9 @@ namespace MediaBrowser.Controller.Entities
return item;
}
public override async Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true)
public override async Task<bool> RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
{
var changed = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs).ConfigureAwait(false);
var changed = await base.RefreshMetadataDirect(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false);
return (SupportsShortcutChildren && LocationType == LocationType.FileSystem && RefreshLinkedChildren()) || changed;
}

View File

@@ -1,5 +1,6 @@
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Entities
@@ -10,7 +11,7 @@ namespace MediaBrowser.Controller.Entities
/// Gets the name.
/// </summary>
/// <value>The name.</value>
string Name { get; }
string Name { get; set; }
/// <summary>
/// Gets the path.
@@ -24,6 +25,12 @@ namespace MediaBrowser.Controller.Entities
/// <value>The identifier.</value>
Guid Id { get; }
/// <summary>
/// Gets the type of the location.
/// </summary>
/// <value>The type of the location.</value>
LocationType LocationType { get; }
/// <summary>
/// Gets the image path.
/// </summary>
@@ -81,6 +88,24 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <returns>System.String.</returns>
string GetPreferredMetadataLanguage();
/// <summary>
/// Validates the images and returns true or false indicating if any were removed.
/// </summary>
bool ValidateImages();
/// <summary>
/// Gets or sets the backdrop image paths.
/// </summary>
/// <value>The backdrop image paths.</value>
List<string> BackdropImagePaths { get; set; }
/// <summary>
/// Determines whether [contains image with source URL] [the specified URL].
/// </summary>
/// <param name="url">The URL.</param>
/// <returns><c>true</c> if [contains image with source URL] [the specified URL]; otherwise, <c>false</c>.</returns>
bool ContainsImageWithSourceUrl(string url);
}
public static class HasImagesExtensions

View File

@@ -14,8 +14,10 @@ namespace MediaBrowser.Controller.Entities
List<string> ScreenshotImagePaths { get; set; }
/// <summary>
/// Validates the screenshots.
/// Determines whether [contains image with source URL] [the specified URL].
/// </summary>
void ValidateScreenshots();
/// <param name="url">The URL.</param>
/// <returns><c>true</c> if [contains image with source URL] [the specified URL]; otherwise, <c>false</c>.</returns>
bool ContainsImageWithSourceUrl(string url);
}
}

View File

@@ -1,4 +1,5 @@
using MediaBrowser.Model.Configuration;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
@@ -108,13 +109,11 @@ namespace MediaBrowser.Controller.Entities.Movies
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="forceSave">if set to <c>true</c> [is new item].</param>
/// <param name="forceRefresh">if set to <c>true</c> [force].</param>
/// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
/// <param name="resetResolveArgs">The reset resolve args.</param>
/// <returns>Task{System.Boolean}.</returns>
public override async Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true)
public override async Task<bool> RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
{
// Kick off a task to refresh the main item
var result = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs).ConfigureAwait(false);
var result = await base.RefreshMetadataDirect(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false);
var specialFeaturesChanged = false;
@@ -122,7 +121,7 @@ namespace MediaBrowser.Controller.Entities.Movies
// In other words, it must be part of the Parent/Child tree
if (LocationType == LocationType.FileSystem && Parent != null && !IsInMixedFolder)
{
specialFeaturesChanged = await RefreshSpecialFeatures(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
specialFeaturesChanged = await RefreshSpecialFeatures(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false);
}
return specialFeaturesChanged || result;
@@ -135,7 +134,13 @@ namespace MediaBrowser.Controller.Entities.Movies
var itemsChanged = !SpecialFeatureIds.SequenceEqual(newItemIds);
var tasks = newItems.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs: false));
var tasks = newItems.Select(i => i.RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = forceSave,
ReplaceAllMetadata = forceRefresh,
ResetResolveArgs = false
}, cancellationToken));
var results = await Task.WhenAll(tasks).ConfigureAwait(false);

View File

@@ -1,5 +1,6 @@
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Serialization;
using System;
@@ -212,7 +213,12 @@ namespace MediaBrowser.Controller.Entities
// Kick off a task to validate the media library
Task.Run(() => ValidateMediaLibrary(new Progress<double>(), CancellationToken.None));
return RefreshMetadata(CancellationToken.None, forceSave: true, forceRefresh: true);
return RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = true,
ReplaceAllMetadata = true
}, CancellationToken.None);
}
/// <summary>
@@ -275,17 +281,13 @@ namespace MediaBrowser.Controller.Entities
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="forceSave">if set to <c>true</c> [is new item].</param>
/// <param name="forceRefresh">if set to <c>true</c> [force].</param>
/// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
/// <returns>true if a provider reports we changed</returns>
public override async Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true)
public override async Task<bool> RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
{
if (resetResolveArgs)
{
// Reload this
ResetResolveArgs();
}
// Reload this
ResetResolveArgs();
var updateReason = await ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh, allowSlowProviders).ConfigureAwait(false);
var updateReason = await ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh).ConfigureAwait(false);
var changed = updateReason.HasValue;

View File

@@ -1,4 +1,5 @@
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using System;
@@ -164,13 +165,11 @@ namespace MediaBrowser.Controller.Entities
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="forceSave">if set to <c>true</c> [is new item].</param>
/// <param name="forceRefresh">if set to <c>true</c> [force].</param>
/// <param name="allowSlowProviders">if set to <c>true</c> [allow slow providers].</param>
/// <param name="resetResolveArgs">The reset resolve args.</param>
/// <returns>true if a provider reports we changed</returns>
public override async Task<bool> RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true)
public override async Task<bool> RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
{
// Kick off a task to refresh the main item
var result = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs).ConfigureAwait(false);
var result = await base.RefreshMetadataDirect(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false);
var additionalPartsChanged = false;
@@ -181,7 +180,7 @@ namespace MediaBrowser.Controller.Entities
{
try
{
additionalPartsChanged = await RefreshAdditionalParts(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
additionalPartsChanged = await RefreshAdditionalParts(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false);
}
catch (IOException ex)
{
@@ -208,7 +207,12 @@ namespace MediaBrowser.Controller.Entities
var itemsChanged = !AdditionalPartIds.SequenceEqual(newItemIds);
var tasks = newItems.Select(i => i.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders));
var tasks = newItems.Select(i => i.RefreshMetadata(new MetadataRefreshOptions
{
ForceSave = forceSave,
ReplaceAllMetadata = forceRefresh
}, cancellationToken));
var results = await Task.WhenAll(tasks).ConfigureAwait(false);