restored external subtitle support
This commit is contained in:
parent
44bb192ce0
commit
013d5a467e
|
@ -143,7 +143,6 @@ namespace MediaBrowser.Api
|
||||||
DisableSaversForType(typeof(Game), config);
|
DisableSaversForType(typeof(Game), config);
|
||||||
DisableSaversForType(typeof(GameSystem), config);
|
DisableSaversForType(typeof(GameSystem), config);
|
||||||
DisableSaversForType(typeof(Movie), config);
|
DisableSaversForType(typeof(Movie), config);
|
||||||
DisableSaversForType(typeof(Trailer), config);
|
|
||||||
DisableSaversForType(typeof(BoxSet), config);
|
DisableSaversForType(typeof(BoxSet), config);
|
||||||
DisableSaversForType(typeof(Book), config);
|
DisableSaversForType(typeof(Book), config);
|
||||||
DisableSaversForType(typeof(Series), config);
|
DisableSaversForType(typeof(Series), config);
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
public List<string> PhysicalLocationsList { get; set; }
|
public List<string> PhysicalLocationsList { get; set; }
|
||||||
|
|
||||||
protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(DirectoryService directoryService)
|
protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
return CreateResolveArgs().FileSystemChildren;
|
return CreateResolveArgs().FileSystemChildren;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// Get the children of this folder from the actual file system
|
/// Get the children of this folder from the actual file system
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||||
protected override IEnumerable<BaseItem> GetNonCachedChildren(DirectoryService directoryService)
|
protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
return base.GetNonCachedChildren(directoryService).Concat(_virtualChildren);
|
return base.GetNonCachedChildren(directoryService).Concat(_virtualChildren);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Task _cachedTask = Task.FromResult(true);
|
private readonly Task _cachedTask = Task.FromResult(true);
|
||||||
protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, DirectoryService directoryService)
|
protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
if (IsAccessedByName)
|
if (IsAccessedByName)
|
||||||
{
|
{
|
||||||
|
|
|
@ -563,6 +563,8 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
var locationType = LocationType;
|
var locationType = LocationType;
|
||||||
|
|
||||||
|
var requiresSave = false;
|
||||||
|
|
||||||
if (IsFolder || Parent != null)
|
if (IsFolder || Parent != null)
|
||||||
{
|
{
|
||||||
options.DirectoryService = options.DirectoryService ?? new DirectoryService(Logger);
|
options.DirectoryService = options.DirectoryService ?? new DirectoryService(Logger);
|
||||||
|
@ -571,13 +573,34 @@ namespace MediaBrowser.Controller.Entities
|
||||||
GetFileSystemChildren(options.DirectoryService).ToList() :
|
GetFileSystemChildren(options.DirectoryService).ToList() :
|
||||||
new List<FileSystemInfo>();
|
new List<FileSystemInfo>();
|
||||||
|
|
||||||
await BeforeRefreshMetadata(options, files, cancellationToken).ConfigureAwait(false);
|
var ownedItemsChanged = await RefreshedOwnedItems(options, files, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (ownedItemsChanged)
|
||||||
|
{
|
||||||
|
requiresSave = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dateLastSaved = DateLastSaved;
|
||||||
|
|
||||||
await ProviderManager.RefreshMetadata(this, options, cancellationToken).ConfigureAwait(false);
|
await ProviderManager.RefreshMetadata(this, options, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// If it wasn't saved by the provider process, save now
|
||||||
|
if (requiresSave && dateLastSaved == DateLastSaved)
|
||||||
|
{
|
||||||
|
await UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual async Task BeforeRefreshMetadata(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
/// <summary>
|
||||||
|
/// Refreshes owned items such as trailers, theme videos, special features, etc.
|
||||||
|
/// Returns true or false indicating if changes were found.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options"></param>
|
||||||
|
/// <param name="fileSystemChildren"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected virtual async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var themeSongsChanged = false;
|
var themeSongsChanged = false;
|
||||||
|
|
||||||
|
@ -605,13 +628,10 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (themeSongsChanged || themeVideosChanged || localTrailersChanged)
|
return themeSongsChanged || themeVideosChanged || localTrailersChanged;
|
||||||
{
|
|
||||||
options.ForceSave = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual IEnumerable<FileSystemInfo> GetFileSystemChildren(DirectoryService directoryService)
|
protected virtual IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var path = ContainingFolderPath;
|
var path = ContainingFolderPath;
|
||||||
|
|
||||||
|
@ -1205,7 +1225,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates that images within the item are still on the file system
|
/// Validates that images within the item are still on the file system
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ValidateImages(DirectoryService directoryService)
|
public bool ValidateImages(IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var allDirectories = ImageInfos.Select(i => System.IO.Path.GetDirectoryName(i.Path)).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
var allDirectories = ImageInfos.Select(i => System.IO.Path.GetDirectoryName(i.Path)).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||||
var allFiles = allDirectories.SelectMany(directoryService.GetFiles).Select(i => i.FullName).ToList();
|
var allFiles = allDirectories.SelectMany(directoryService.GetFiles).Select(i => i.FullName).ToList();
|
||||||
|
@ -1390,5 +1410,22 @@ namespace MediaBrowser.Controller.Entities
|
||||||
ParentIndexNumber = ParentIndexNumber
|
ParentIndexNumber = ParentIndexNumber
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is called before any metadata refresh and returns ItemUpdateType indictating if changes were made, and what.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ItemUpdateType.</returns>
|
||||||
|
public virtual ItemUpdateType BeforeMetadataRefresh()
|
||||||
|
{
|
||||||
|
var updateType = ItemUpdateType.None;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(Path))
|
||||||
|
{
|
||||||
|
Name = System.IO.Path.GetFileNameWithoutExtension(Path);
|
||||||
|
updateType = updateType | ItemUpdateType.MetadataEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
public List<string> PhysicalLocationsList { get; set; }
|
public List<string> PhysicalLocationsList { get; set; }
|
||||||
|
|
||||||
protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(DirectoryService directoryService)
|
protected override IEnumerable<FileSystemInfo> GetFileSystemChildren(IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
return CreateResolveArgs().FileSystemChildren;
|
return CreateResolveArgs().FileSystemChildren;
|
||||||
}
|
}
|
||||||
|
@ -119,8 +119,9 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <param name="recursive">if set to <c>true</c> [recursive].</param>
|
/// <param name="recursive">if set to <c>true</c> [recursive].</param>
|
||||||
/// <param name="refreshChildMetadata">if set to <c>true</c> [refresh child metadata].</param>
|
/// <param name="refreshChildMetadata">if set to <c>true</c> [refresh child metadata].</param>
|
||||||
/// <param name="refreshOptions">The refresh options.</param>
|
/// <param name="refreshOptions">The refresh options.</param>
|
||||||
|
/// <param name="directoryService">The directory service.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, DirectoryService directoryService)
|
protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
CreateResolveArgs();
|
CreateResolveArgs();
|
||||||
ResetDynamicChildren();
|
ResetDynamicChildren();
|
||||||
|
|
|
@ -319,7 +319,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return ValidateChildrenWithCancellationSupport(progress, cancellationToken, recursive, true, metadataRefreshOptions, metadataRefreshOptions.DirectoryService);
|
return ValidateChildrenWithCancellationSupport(progress, cancellationToken, recursive, true, metadataRefreshOptions, metadataRefreshOptions.DirectoryService);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ValidateChildrenWithCancellationSupport(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, DirectoryService directoryService)
|
private async Task ValidateChildrenWithCancellationSupport(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <param name="refreshOptions">The refresh options.</param>
|
/// <param name="refreshOptions">The refresh options.</param>
|
||||||
/// <param name="directoryService">The directory service.</param>
|
/// <param name="directoryService">The directory service.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
protected async virtual Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, DirectoryService directoryService)
|
protected async virtual Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var locationType = LocationType;
|
var locationType = LocationType;
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <param name="progress">The progress.</param>
|
/// <param name="progress">The progress.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
private async Task ValidateSubFolders(IList<Folder> children, DirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
|
private async Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var list = children;
|
var list = children;
|
||||||
var childCount = list.Count;
|
var childCount = list.Count;
|
||||||
|
@ -679,7 +679,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// Get the children of this folder from the actual file system
|
/// Get the children of this folder from the actual file system
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||||
protected virtual IEnumerable<BaseItem> GetNonCachedChildren(DirectoryService directoryService)
|
protected virtual IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
return LibraryManager.ResolvePaths<BaseItem>(GetFileSystemChildren(directoryService), this);
|
return LibraryManager.ResolvePaths<BaseItem>(GetFileSystemChildren(directoryService), this);
|
||||||
}
|
}
|
||||||
|
@ -927,17 +927,21 @@ namespace MediaBrowser.Controller.Entities
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task BeforeRefreshMetadata(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
var changesFound = false;
|
||||||
|
|
||||||
if (SupportsShortcutChildren && LocationType == LocationType.FileSystem)
|
if (SupportsShortcutChildren && LocationType == LocationType.FileSystem)
|
||||||
{
|
{
|
||||||
if (RefreshLinkedChildren(fileSystemChildren))
|
if (RefreshLinkedChildren(fileSystemChildren))
|
||||||
{
|
{
|
||||||
options.ForceSave = true;
|
changesFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.BeforeRefreshMetadata(options, fileSystemChildren, cancellationToken);
|
var baseHasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return baseHasChanges || changesFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
using System.IO;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Controller.Providers;
|
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities
|
namespace MediaBrowser.Controller.Entities
|
||||||
|
@ -109,7 +109,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates the images and returns true or false indicating if any were removed.
|
/// Validates the images and returns true or false indicating if any were removed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool ValidateImages(DirectoryService directoryService);
|
bool ValidateImages(IDirectoryService directoryService);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this instance is owned item.
|
/// Gets a value indicating whether this instance is owned item.
|
||||||
|
@ -166,5 +166,16 @@ namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
item.SetImagePath(imageType, 0, file);
|
item.SetImagePath(imageType, 0, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the image path.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The item.</param>
|
||||||
|
/// <param name="imageType">Type of the image.</param>
|
||||||
|
/// <param name="file">The file.</param>
|
||||||
|
public static void SetImagePath(this IHasImages item, ImageType imageType, string file)
|
||||||
|
{
|
||||||
|
item.SetImagePath(imageType, new FileInfo(file));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
using System;
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Controller.Library;
|
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Entities
|
namespace MediaBrowser.Controller.Entities
|
||||||
{
|
{
|
||||||
|
@ -49,5 +49,11 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken);
|
Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is called before any metadata refresh and returns ItemUpdateType indictating if changes were made, and what.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ItemUpdateType.</returns>
|
||||||
|
ItemUpdateType BeforeMetadataRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,9 +96,9 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||||
return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.GetUserDataKey();
|
return this.GetProviderId(MetadataProviders.Tmdb) ?? this.GetProviderId(MetadataProviders.Imdb) ?? base.GetUserDataKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task BeforeRefreshMetadata(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await base.BeforeRefreshMetadata(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
// Must have a parent to have special features
|
// Must have a parent to have special features
|
||||||
// In other words, it must be part of the Parent/Child tree
|
// In other words, it must be part of the Parent/Child tree
|
||||||
|
@ -108,9 +108,11 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||||
|
|
||||||
if (specialFeaturesChanged)
|
if (specialFeaturesChanged)
|
||||||
{
|
{
|
||||||
options.ForceSave = true;
|
hasChanges = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return hasChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> RefreshSpecialFeatures(MetadataRefreshOptions options, IEnumerable<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
private async Task<bool> RefreshSpecialFeatures(MetadataRefreshOptions options, IEnumerable<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -260,5 +262,54 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ItemUpdateType BeforeMetadataRefresh()
|
||||||
|
{
|
||||||
|
var updateType = base.BeforeMetadataRefresh();
|
||||||
|
|
||||||
|
var locationType = LocationType;
|
||||||
|
if (locationType == LocationType.FileSystem || locationType == LocationType.Offline)
|
||||||
|
{
|
||||||
|
if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
|
||||||
|
{
|
||||||
|
IndexNumber = IndexNumber ?? TVUtils.GetEpisodeNumberFromFile(Path, Parent is Season);
|
||||||
|
|
||||||
|
// If a change was made record it
|
||||||
|
if (IndexNumber.HasValue)
|
||||||
|
{
|
||||||
|
updateType = updateType | ItemUpdateType.MetadataImport;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IndexNumberEnd.HasValue && !string.IsNullOrEmpty(Path))
|
||||||
|
{
|
||||||
|
IndexNumberEnd = IndexNumberEnd ?? TVUtils.GetEndingEpisodeNumberFromFile(Path);
|
||||||
|
|
||||||
|
// If a change was made record it
|
||||||
|
if (IndexNumberEnd.HasValue)
|
||||||
|
{
|
||||||
|
updateType = updateType | ItemUpdateType.MetadataImport;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ParentIndexNumber.HasValue)
|
||||||
|
{
|
||||||
|
var season = Season;
|
||||||
|
|
||||||
|
if (season != null)
|
||||||
|
{
|
||||||
|
ParentIndexNumber = season.IndexNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a change was made record it
|
||||||
|
if (ParentIndexNumber.HasValue)
|
||||||
|
{
|
||||||
|
updateType = updateType | ItemUpdateType.MetadataImport;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MediaBrowser.Controller.Localization;
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Controller.Localization;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -243,9 +244,40 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the lookup information.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>SeasonInfo.</returns>
|
||||||
public SeasonInfo GetLookupInfo()
|
public SeasonInfo GetLookupInfo()
|
||||||
{
|
{
|
||||||
return GetItemLookupInfo<SeasonInfo>();
|
return GetItemLookupInfo<SeasonInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is called before any metadata refresh and returns ItemUpdateType indictating if changes were made, and what.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ItemUpdateType.</returns>
|
||||||
|
public override ItemUpdateType BeforeMetadataRefresh()
|
||||||
|
{
|
||||||
|
var updateType = base.BeforeMetadataRefresh();
|
||||||
|
|
||||||
|
var locationType = LocationType;
|
||||||
|
|
||||||
|
if (locationType == LocationType.FileSystem || locationType == LocationType.Offline)
|
||||||
|
{
|
||||||
|
if (!IndexNumber.HasValue && !string.IsNullOrEmpty(Path))
|
||||||
|
{
|
||||||
|
IndexNumber = IndexNumber ?? TVUtils.GetSeasonNumberFromPath(Path);
|
||||||
|
|
||||||
|
// If a change was made record it
|
||||||
|
if (IndexNumber.HasValue)
|
||||||
|
{
|
||||||
|
updateType = updateType | ItemUpdateType.MetadataImport;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// Get the children of this folder from the actual file system
|
/// Get the children of this folder from the actual file system
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||||
protected override IEnumerable<BaseItem> GetNonCachedChildren(DirectoryService directoryService)
|
protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
return base.GetNonCachedChildren(directoryService).Concat(LibraryManager.RootFolder.VirtualChildren);
|
return base.GetNonCachedChildren(directoryService).Concat(LibraryManager.RootFolder.VirtualChildren);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,15 @@ namespace MediaBrowser.Controller.Entities
|
||||||
PlayableStreamFileNames = new List<string>();
|
PlayableStreamFileNames = new List<string>();
|
||||||
AdditionalPartIds = new List<Guid>();
|
AdditionalPartIds = new List<Guid>();
|
||||||
Tags = new List<string>();
|
Tags = new List<string>();
|
||||||
|
SubtitleFiles = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the subtitle paths.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The subtitle paths.</value>
|
||||||
|
public List<string> SubtitleFiles { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether this instance has subtitles.
|
/// Gets or sets a value indicating whether this instance has subtitles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -156,9 +163,9 @@ namespace MediaBrowser.Controller.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task BeforeRefreshMetadata(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await base.BeforeRefreshMetadata(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
// Must have a parent to have additional parts
|
// Must have a parent to have additional parts
|
||||||
// In other words, it must be part of the Parent/Child tree
|
// In other words, it must be part of the Parent/Child tree
|
||||||
|
@ -169,9 +176,11 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
if (additionalPartsChanged)
|
if (additionalPartsChanged)
|
||||||
{
|
{
|
||||||
options.ForceSave = true;
|
hasChanges = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return hasChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace MediaBrowser.Controller.Library
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum ItemUpdateType
|
public enum ItemUpdateType
|
||||||
{
|
{
|
||||||
Unspecified = 1,
|
None = 1,
|
||||||
MetadataImport = 2,
|
MetadataImport = 2,
|
||||||
ImageUpdate = 4,
|
ImageUpdate = 4,
|
||||||
MetadataDownload = 8,
|
MetadataDownload = 8,
|
||||||
|
|
|
@ -6,7 +6,16 @@ using MediaBrowser.Model.Logging;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Providers
|
namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
public class DirectoryService
|
public interface IDirectoryService
|
||||||
|
{
|
||||||
|
List<FileSystemInfo> GetFileSystemEntries(string path);
|
||||||
|
IEnumerable<FileInfo> GetFiles(string path);
|
||||||
|
IEnumerable<DirectoryInfo> GetDirectories(string path);
|
||||||
|
FileInfo GetFile(string path);
|
||||||
|
DirectoryInfo GetDirectory(string path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DirectoryService : IDirectoryService
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,6 @@ namespace MediaBrowser.Controller.Providers
|
||||||
public interface ICustomMetadataProvider<TItemType> : IMetadataProvider<TItemType>, ICustomMetadataProvider
|
public interface ICustomMetadataProvider<TItemType> : IMetadataProvider<TItemType>, ICustomMetadataProvider
|
||||||
where TItemType : IHasMetadata
|
where TItemType : IHasMetadata
|
||||||
{
|
{
|
||||||
Task<ItemUpdateType> FetchAsync(TItemType item, CancellationToken cancellationToken);
|
Task<ItemUpdateType> FetchAsync(TItemType item, IDirectoryService directoryService, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,9 @@ namespace MediaBrowser.Controller.Providers
|
||||||
/// Determines whether the specified item has changed.
|
/// Determines whether the specified item has changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
/// <param name="item">The item.</param>
|
||||||
|
/// <param name="directoryService">The directory service.</param>
|
||||||
/// <param name="date">The date.</param>
|
/// <param name="date">The date.</param>
|
||||||
/// <returns><c>true</c> if the specified item has changed; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the specified item has changed; otherwise, <c>false</c>.</returns>
|
||||||
bool HasChanged(IHasMetadata item, DateTime date);
|
bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Providers
|
||||||
|
|
||||||
public interface ILocalImageFileProvider : ILocalImageProvider
|
public interface ILocalImageFileProvider : ILocalImageProvider
|
||||||
{
|
{
|
||||||
List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService);
|
List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LocalImageInfo
|
public class LocalImageInfo
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using MediaBrowser.Model.Logging;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Providers
|
namespace MediaBrowser.Controller.Providers
|
||||||
{
|
{
|
||||||
|
@ -17,13 +16,12 @@ namespace MediaBrowser.Controller.Providers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Obsolete]
|
[Obsolete]
|
||||||
public bool ForceSave { get; set; }
|
public bool ForceSave { get; set; }
|
||||||
|
|
||||||
public DirectoryService DirectoryService { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImageRefreshOptions
|
public class ImageRefreshOptions
|
||||||
{
|
{
|
||||||
public ImageRefreshMode ImageRefreshMode { get; set; }
|
public ImageRefreshMode ImageRefreshMode { get; set; }
|
||||||
|
public IDirectoryService DirectoryService { get; set; }
|
||||||
|
|
||||||
public ImageRefreshOptions()
|
public ImageRefreshOptions()
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace MediaBrowser.Model.Configuration
|
||||||
public ImageOption[] ImageOptions { get; set; }
|
public ImageOption[] ImageOptions { get; set; }
|
||||||
|
|
||||||
public string[] DisabledMetadataSavers { get; set; }
|
public string[] DisabledMetadataSavers { get; set; }
|
||||||
|
public string[] LocalMetadataReaders { get; set; }
|
||||||
|
|
||||||
public MetadataOptions()
|
public MetadataOptions()
|
||||||
: this(3, 1280)
|
: this(3, 1280)
|
||||||
|
@ -35,6 +36,7 @@ namespace MediaBrowser.Model.Configuration
|
||||||
|
|
||||||
ImageOptions = imageOptions.ToArray();
|
ImageOptions = imageOptions.ToArray();
|
||||||
DisabledMetadataSavers = new string[] { };
|
DisabledMetadataSavers = new string[] { };
|
||||||
|
LocalMetadataReaders = new string[] { };
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetLimit(ImageType type)
|
public int GetLimit(ImageType type)
|
||||||
|
|
|
@ -265,11 +265,6 @@ namespace MediaBrowser.Model.Configuration
|
||||||
|
|
||||||
MetadataOptions = options.ToArray();
|
MetadataOptions = options.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MetadataOptions GetMetadataOptions(string type)
|
|
||||||
{
|
|
||||||
return MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ImageSavingConvention
|
public enum ImageSavingConvention
|
||||||
|
|
|
@ -32,6 +32,8 @@ namespace MediaBrowser.Model.Dto
|
||||||
/// <value>The date created.</value>
|
/// <value>The date created.</value>
|
||||||
public DateTime? DateCreated { get; set; }
|
public DateTime? DateCreated { get; set; }
|
||||||
|
|
||||||
|
public DateTime? DateLastMediaAdded { get; set; }
|
||||||
|
|
||||||
public int? AirsBeforeSeasonNumber { get; set; }
|
public int? AirsBeforeSeasonNumber { get; set; }
|
||||||
public int? AirsAfterSeasonNumber { get; set; }
|
public int? AirsAfterSeasonNumber { get; set; }
|
||||||
public int? AirsBeforeEpisodeNumber { get; set; }
|
public int? AirsBeforeEpisodeNumber { get; set; }
|
||||||
|
|
|
@ -6,40 +6,40 @@ namespace MediaBrowser.Model.Entities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum MetadataProviders
|
public enum MetadataProviders
|
||||||
{
|
{
|
||||||
Gamesdb,
|
Gamesdb = 1,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The imdb
|
/// The imdb
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Imdb,
|
Imdb = 2,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The TMDB
|
/// The TMDB
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Tmdb,
|
Tmdb = 3,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The TVDB
|
/// The TVDB
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Tvdb,
|
Tvdb = 4,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The tvcom
|
/// The tvcom
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Tvcom,
|
Tvcom = 5,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The rotten tomatoes
|
/// The rotten tomatoes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
RottenTomatoes,
|
RottenTomatoes = 6,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tmdb Collection Id
|
/// Tmdb Collection Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
TmdbCollection,
|
TmdbCollection = 7,
|
||||||
MusicBrainzAlbum,
|
MusicBrainzAlbum = 8,
|
||||||
MusicBrainzAlbumArtist,
|
MusicBrainzAlbumArtist = 9,
|
||||||
MusicBrainzArtist,
|
MusicBrainzArtist = 10,
|
||||||
MusicBrainzReleaseGroup,
|
MusicBrainzReleaseGroup = 11,
|
||||||
Zap2It,
|
Zap2It = 12,
|
||||||
NesBox,
|
NesBox = 13,
|
||||||
NesBoxRom,
|
NesBoxRom = 14,
|
||||||
TvRage,
|
TvRage = 15,
|
||||||
AudioDbArtist,
|
AudioDbArtist = 16,
|
||||||
AudioDbAlbum
|
AudioDbAlbum = 17
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,5 @@
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The name.</value>
|
/// <value>The name.</value>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the order.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>The order.</value>
|
|
||||||
public int Order { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace MediaBrowser.Model.Querying
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DateCreated,
|
DateCreated,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The date last media added
|
||||||
|
/// </summary>
|
||||||
|
DateLastMediaAdded,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Item display preferences
|
/// Item display preferences
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace MediaBrowser.Providers.All
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService)
|
public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var path = _config.ApplicationPaths.GetInternalMetadataPath(item.Id);
|
var path = _config.ApplicationPaths.GetInternalMetadataPath(item.Id);
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace MediaBrowser.Providers.All
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<FileSystemInfo> GetFiles(IHasImages item, bool includeDirectories, DirectoryService directoryService)
|
private IEnumerable<FileSystemInfo> GetFiles(IHasImages item, bool includeDirectories, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
if (item.LocationType != LocationType.FileSystem)
|
if (item.LocationType != LocationType.FileSystem)
|
||||||
{
|
{
|
||||||
|
@ -77,7 +77,7 @@ namespace MediaBrowser.Providers.All
|
||||||
.Where(i => BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase));
|
.Where(i => BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService)
|
public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var files = GetFiles(item, true, directoryService).ToList();
|
var files = GetFiles(item, true, directoryService).ToList();
|
||||||
|
|
||||||
|
@ -88,12 +88,12 @@ namespace MediaBrowser.Providers.All
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LocalImageInfo> GetImages(IHasImages item, string path, DirectoryService directoryService)
|
public List<LocalImageInfo> GetImages(IHasImages item, string path, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
return GetImages(item, new[] { path }, directoryService);
|
return GetImages(item, new[] { path }, directoryService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LocalImageInfo> GetImages(IHasImages item, IEnumerable<string> paths, DirectoryService directoryService)
|
public List<LocalImageInfo> GetImages(IHasImages item, IEnumerable<string> paths, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var files = paths.SelectMany(directoryService.GetFiles)
|
var files = paths.SelectMany(directoryService.GetFiles)
|
||||||
.Where(i =>
|
.Where(i =>
|
||||||
|
@ -113,7 +113,7 @@ namespace MediaBrowser.Providers.All
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateImages(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, bool supportParentSeriesFiles, DirectoryService directoryService)
|
private void PopulateImages(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, bool supportParentSeriesFiles, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var imagePrefix = string.Empty;
|
var imagePrefix = string.Empty;
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ namespace MediaBrowser.Providers.All
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateBackdrops(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, DirectoryService directoryService)
|
private void PopulateBackdrops(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", ImageType.Backdrop);
|
PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", ImageType.Backdrop);
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ namespace MediaBrowser.Providers.All
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateBackdropsFromExtraFanart(string path, List<LocalImageInfo> images, DirectoryService directoryService)
|
private void PopulateBackdropsFromExtraFanart(string path, List<LocalImageInfo> images, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var imageFiles = directoryService.GetFiles(path)
|
var imageFiles = directoryService.GetFiles(path)
|
||||||
.Where(i =>
|
.Where(i =>
|
||||||
|
@ -262,7 +262,7 @@ namespace MediaBrowser.Providers.All
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||||
private void PopulateSeasonImagesFromSeriesFolder(Season season, List<LocalImageInfo> images, DirectoryService directoryService)
|
private void PopulateSeasonImagesFromSeriesFolder(Season season, List<LocalImageInfo> images, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var seasonNumber = season.IndexNumber;
|
var seasonNumber = season.IndexNumber;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,10 @@ namespace MediaBrowser.Providers
|
||||||
{
|
{
|
||||||
result.HasMetadata = false;
|
result.HasMetadata = false;
|
||||||
}
|
}
|
||||||
|
catch (DirectoryNotFoundException)
|
||||||
|
{
|
||||||
|
result.HasMetadata = false;
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
XmlProviderUtils.XmlParsingResourcePool.Release();
|
XmlProviderUtils.XmlParsingResourcePool.Release();
|
||||||
|
@ -56,7 +60,7 @@ namespace MediaBrowser.Providers
|
||||||
|
|
||||||
protected abstract FileInfo GetXmlFile(ItemInfo info);
|
protected abstract FileInfo GetXmlFile(ItemInfo info);
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
var file = GetXmlFile(new ItemInfo { IsInMixedFolder = item.IsInMixedFolder, Path = item.Path });
|
var file = GetXmlFile(new ItemInfo { IsInMixedFolder = item.IsInMixedFolder, Path = item.Path });
|
||||||
|
|
||||||
|
|
|
@ -85,10 +85,12 @@ namespace MediaBrowser.Providers.BoxSets
|
||||||
|
|
||||||
private BoxSet GetItem(RootObject obj)
|
private BoxSet GetItem(RootObject obj)
|
||||||
{
|
{
|
||||||
var item = new BoxSet();
|
var item = new BoxSet
|
||||||
|
{
|
||||||
|
Name = obj.name,
|
||||||
|
Overview = obj.overview
|
||||||
|
};
|
||||||
|
|
||||||
item.Name = obj.name;
|
|
||||||
item.Overview = obj.overview;
|
|
||||||
item.SetProviderId(MetadataProviders.Tmdb, obj.id.ToString(_enUs));
|
item.SetProviderId(MetadataProviders.Tmdb, obj.id.ToString(_enUs));
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace MediaBrowser.Providers.Folders
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService)
|
public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var collectionFolder = (CollectionFolder)item;
|
var collectionFolder = (CollectionFolder)item;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.Folders
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService)
|
public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var name = _fileSystem.GetValidFilename(item.Name);
|
var name = _fileSystem.GetValidFilename(item.Name);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ValidateImages(IHasImages item, IEnumerable<IImageProvider> providers, DirectoryService directoryService)
|
public bool ValidateImages(IHasImages item, IEnumerable<IImageProvider> providers, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var hasChanges = item.ValidateImages(directoryService);
|
var hasChanges = item.ValidateImages(directoryService);
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
|
|
||||||
public async Task<RefreshResult> RefreshImages(IHasImages item, IEnumerable<IImageProvider> imageProviders, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken)
|
public async Task<RefreshResult> RefreshImages(IHasImages item, IEnumerable<IImageProvider> imageProviders, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = new RefreshResult { UpdateType = ItemUpdateType.Unspecified };
|
var result = new RefreshResult { UpdateType = ItemUpdateType.None };
|
||||||
|
|
||||||
var providers = GetImageProviders(item, imageProviders).ToList();
|
var providers = GetImageProviders(item, imageProviders).ToList();
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@ using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Configuration;
|
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -73,7 +73,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
var itemOfType = (TItemType)item;
|
var itemOfType = (TItemType)item;
|
||||||
var config = ProviderManager.GetMetadataOptions(item);
|
var config = ProviderManager.GetMetadataOptions(item);
|
||||||
|
|
||||||
var updateType = ItemUpdateType.Unspecified;
|
var updateType = ItemUpdateType.None;
|
||||||
var refreshResult = GetLastResult(item.Id);
|
var refreshResult = GetLastResult(item.Id);
|
||||||
refreshResult.LastErrorMessage = string.Empty;
|
refreshResult.LastErrorMessage = string.Empty;
|
||||||
refreshResult.LastStatus = ProviderRefreshStatus.Success;
|
refreshResult.LastStatus = ProviderRefreshStatus.Success;
|
||||||
|
@ -106,7 +106,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
|
|
||||||
if (providers.Count > 0 || !refreshResult.DateLastMetadataRefresh.HasValue)
|
if (providers.Count > 0 || !refreshResult.DateLastMetadataRefresh.HasValue)
|
||||||
{
|
{
|
||||||
updateType = updateType | BeforeMetadataRefresh(itemOfType);
|
updateType = updateType | item.BeforeMetadataRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (providers.Count > 0)
|
if (providers.Count > 0)
|
||||||
|
@ -138,15 +138,10 @@ namespace MediaBrowser.Providers.Manager
|
||||||
|
|
||||||
updateType = updateType | BeforeSave(itemOfType);
|
updateType = updateType | BeforeSave(itemOfType);
|
||||||
|
|
||||||
var providersHadChanges = updateType > ItemUpdateType.Unspecified;
|
var providersHadChanges = updateType > ItemUpdateType.None;
|
||||||
|
|
||||||
if (refreshOptions.ForceSave || providersHadChanges)
|
if (refreshOptions.ForceSave || providersHadChanges)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(item.Name))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException(item.GetType().Name + " has no name: " + item.Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save to database
|
// Save to database
|
||||||
await SaveItem(itemOfType, updateType, cancellationToken);
|
await SaveItem(itemOfType, updateType, cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -157,16 +152,6 @@ namespace MediaBrowser.Providers.Manager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Befores the metadata refresh.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The item.</param>
|
|
||||||
/// <returns>ItemUpdateType.</returns>
|
|
||||||
protected virtual ItemUpdateType BeforeMetadataRefresh(TItemType item)
|
|
||||||
{
|
|
||||||
return ItemUpdateType.Unspecified;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Befores the save.
|
/// Befores the save.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -174,7 +159,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
/// <returns>ItemUpdateType.</returns>
|
/// <returns>ItemUpdateType.</returns>
|
||||||
protected virtual ItemUpdateType BeforeSave(TItemType item)
|
protected virtual ItemUpdateType BeforeSave(TItemType item)
|
||||||
{
|
{
|
||||||
return ItemUpdateType.Unspecified;
|
return ItemUpdateType.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -198,15 +183,37 @@ namespace MediaBrowser.Providers.Manager
|
||||||
var currentItem = item;
|
var currentItem = item;
|
||||||
|
|
||||||
var providersWithChanges = providers.OfType<IHasChangeMonitor>()
|
var providersWithChanges = providers.OfType<IHasChangeMonitor>()
|
||||||
.Where(i => i.HasChanged(currentItem, currentItem.DateLastSaved))
|
.Where(i => i.HasChanged(currentItem, options.DirectoryService, currentItem.DateLastSaved))
|
||||||
|
.Cast<IMetadataProvider<TItemType>>()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// If local providers are the only ones with changes, then just run those
|
if (providersWithChanges.Count == 0)
|
||||||
if (providersWithChanges.All(i => i is ILocalMetadataProvider))
|
|
||||||
{
|
{
|
||||||
providers = providersWithChanges.Count == 0 ?
|
providers = new List<IMetadataProvider<TItemType>>();
|
||||||
new List<IMetadataProvider<TItemType>>() :
|
}
|
||||||
providers.Where(i => i is ILocalMetadataProvider).ToList();
|
else
|
||||||
|
{
|
||||||
|
providers = providers.Where(i =>
|
||||||
|
{
|
||||||
|
// If any provider reports a change, always run local ones as well
|
||||||
|
if (i is ILocalMetadataProvider)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var anyRemoteProvidersChanged = providersWithChanges.OfType<IRemoteMetadataProvider>()
|
||||||
|
.Any();
|
||||||
|
|
||||||
|
// If any remote providers changed, run them all so that priorities can be honored
|
||||||
|
if (i is IRemoteMetadataProvider)
|
||||||
|
{
|
||||||
|
return anyRemoteProvidersChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run custom providers if they report a change or any remote providers change
|
||||||
|
return anyRemoteProvidersChanged || providersWithChanges.Contains(i);
|
||||||
|
|
||||||
|
}).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +234,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
var currentItem = item;
|
var currentItem = item;
|
||||||
|
|
||||||
providers = providers.OfType<IHasChangeMonitor>()
|
providers = providers.OfType<IHasChangeMonitor>()
|
||||||
.Where(i => i.HasChanged(currentItem, dateLastImageRefresh.Value))
|
.Where(i => i.HasChanged(currentItem, options.DirectoryService, dateLastImageRefresh.Value))
|
||||||
.Cast<IImageProvider>()
|
.Cast<IImageProvider>()
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
@ -249,7 +256,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
{
|
{
|
||||||
var refreshResult = new RefreshResult
|
var refreshResult = new RefreshResult
|
||||||
{
|
{
|
||||||
UpdateType = ItemUpdateType.Unspecified,
|
UpdateType = ItemUpdateType.None,
|
||||||
Providers = providers.Select(i => i.GetType().FullName.GetMD5()).ToList()
|
Providers = providers.Select(i => i.GetType().FullName.GetMD5()).ToList()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -316,26 +323,26 @@ namespace MediaBrowser.Providers.Manager
|
||||||
await ExecuteRemoteProviders(item, temp, providers.OfType<IRemoteMetadataProvider<TItemType, TIdType>>(), refreshResult, cancellationToken).ConfigureAwait(false);
|
await ExecuteRemoteProviders(item, temp, providers.OfType<IRemoteMetadataProvider<TItemType, TIdType>>(), refreshResult, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refreshResult.UpdateType > ItemUpdateType.Unspecified)
|
if (refreshResult.UpdateType > ItemUpdateType.None)
|
||||||
{
|
{
|
||||||
MergeData(temp, item, item.LockedFields, true, true);
|
MergeData(temp, item, item.LockedFields, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var provider in providers.OfType<ICustomMetadataProvider<TItemType>>())
|
foreach (var provider in providers.OfType<ICustomMetadataProvider<TItemType>>())
|
||||||
{
|
{
|
||||||
await RunCustomProvider(provider, item, refreshResult, cancellationToken).ConfigureAwait(false);
|
await RunCustomProvider(provider, item, options.DirectoryService, refreshResult, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return refreshResult;
|
return refreshResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RunCustomProvider(ICustomMetadataProvider<TItemType> provider, TItemType item, RefreshResult refreshResult, CancellationToken cancellationToken)
|
private async Task RunCustomProvider(ICustomMetadataProvider<TItemType> provider, TItemType item, IDirectoryService directoryService, RefreshResult refreshResult, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name);
|
Logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
refreshResult.UpdateType = refreshResult.UpdateType | await provider.FetchAsync(item, cancellationToken).ConfigureAwait(false);
|
refreshResult.UpdateType = refreshResult.UpdateType | await provider.FetchAsync(item, directoryService, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
|
|
@ -279,8 +279,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
{
|
{
|
||||||
return GetRemoteImageProviders(item).Select(i => new ImageProviderInfo
|
return GetRemoteImageProviders(item).Select(i => new ImageProviderInfo
|
||||||
{
|
{
|
||||||
Name = i.Name,
|
Name = i.Name
|
||||||
Order = GetOrder(item, i)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,21 +297,39 @@ namespace MediaBrowser.Providers.Manager
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}).OrderBy(i => GetOrder(item, i));
|
}).OrderBy(GetOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IMetadataProvider<T>> GetMetadataProviders<T>(IHasMetadata item)
|
public IEnumerable<IMetadataProvider<T>> GetMetadataProviders<T>(IHasMetadata item)
|
||||||
where T : IHasMetadata
|
where T : IHasMetadata
|
||||||
{
|
{
|
||||||
return GetMetadataProvidersInternal<T>(item, false);
|
var options = GetMetadataOptions(item);
|
||||||
|
|
||||||
|
return GetMetadataProvidersInternal<T>(item, options, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IMetadataProvider<T>> GetMetadataProvidersInternal<T>(IHasMetadata item, bool includeDisabled)
|
private IEnumerable<IMetadataProvider<T>> GetMetadataProvidersInternal<T>(IHasMetadata item, MetadataOptions options, bool includeDisabled)
|
||||||
where T : IHasMetadata
|
where T : IHasMetadata
|
||||||
{
|
{
|
||||||
return _metadataProviders.OfType<IMetadataProvider<T>>()
|
return _metadataProviders.OfType<IMetadataProvider<T>>()
|
||||||
.Where(i => CanRefresh(i, item, includeDisabled))
|
.Where(i => CanRefresh(i, item, includeDisabled))
|
||||||
.OrderBy(i => GetOrder(item, i));
|
.OrderBy(i =>
|
||||||
|
{
|
||||||
|
// See if there's a user-defined order
|
||||||
|
if (i is ILocalMetadataProvider)
|
||||||
|
{
|
||||||
|
var index = Array.IndexOf(options.LocalMetadataReaders, i.Name);
|
||||||
|
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not configured. Just return some high number to put it at the end.
|
||||||
|
return 100;
|
||||||
|
})
|
||||||
|
.ThenBy(GetOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IRemoteImageProvider> GetRemoteImageProviders(IHasImages item)
|
private IEnumerable<IRemoteImageProvider> GetRemoteImageProviders(IHasImages item)
|
||||||
|
@ -354,10 +371,9 @@ namespace MediaBrowser.Providers.Manager
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the order.
|
/// Gets the order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
|
||||||
/// <param name="provider">The provider.</param>
|
/// <param name="provider">The provider.</param>
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
private int GetOrder(IHasImages item, IImageProvider provider)
|
private int GetOrder(IImageProvider provider)
|
||||||
{
|
{
|
||||||
var hasOrder = provider as IHasOrder;
|
var hasOrder = provider as IHasOrder;
|
||||||
|
|
||||||
|
@ -372,19 +388,18 @@ namespace MediaBrowser.Providers.Manager
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the order.
|
/// Gets the order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The item.</param>
|
|
||||||
/// <param name="provider">The provider.</param>
|
/// <param name="provider">The provider.</param>
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
private int GetOrder(IHasMetadata item, IMetadataProvider provider)
|
private int GetOrder(IMetadataProvider provider)
|
||||||
{
|
{
|
||||||
var hasOrder = provider as IHasOrder;
|
var hasOrder = provider as IHasOrder;
|
||||||
|
|
||||||
if (hasOrder == null)
|
if (hasOrder != null)
|
||||||
{
|
{
|
||||||
return 0;
|
return hasOrder.Order;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasOrder.Order;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<MetadataPluginSummary> GetAllMetadataPlugins()
|
public IEnumerable<MetadataPluginSummary> GetAllMetadataPlugins()
|
||||||
|
@ -432,6 +447,8 @@ namespace MediaBrowser.Providers.Manager
|
||||||
Parent = new Folder()
|
Parent = new Folder()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var options = GetMetadataOptions(dummy);
|
||||||
|
|
||||||
var summary = new MetadataPluginSummary
|
var summary = new MetadataPluginSummary
|
||||||
{
|
{
|
||||||
ItemType = typeof(T).Name
|
ItemType = typeof(T).Name
|
||||||
|
@ -439,7 +456,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
|
|
||||||
var imageProviders = GetImageProviders(dummy).ToList();
|
var imageProviders = GetImageProviders(dummy).ToList();
|
||||||
|
|
||||||
AddMetadataPlugins(summary.Plugins, dummy);
|
AddMetadataPlugins(summary.Plugins, dummy, options);
|
||||||
AddImagePlugins(summary.Plugins, dummy, imageProviders);
|
AddImagePlugins(summary.Plugins, dummy, imageProviders);
|
||||||
|
|
||||||
summary.SupportedImageTypes = imageProviders.OfType<IRemoteImageProvider>()
|
summary.SupportedImageTypes = imageProviders.OfType<IRemoteImageProvider>()
|
||||||
|
@ -450,10 +467,10 @@ namespace MediaBrowser.Providers.Manager
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddMetadataPlugins<T>(List<MetadataPlugin> list, T item)
|
private void AddMetadataPlugins<T>(List<MetadataPlugin> list, T item, MetadataOptions options)
|
||||||
where T : IHasMetadata
|
where T : IHasMetadata
|
||||||
{
|
{
|
||||||
var providers = GetMetadataProvidersInternal<T>(item, true).ToList();
|
var providers = GetMetadataProvidersInternal<T>(item, options, true).ToList();
|
||||||
|
|
||||||
// Locals
|
// Locals
|
||||||
list.AddRange(providers.Where(i => (i is ILocalMetadataProvider)).Select(i => new MetadataPlugin
|
list.AddRange(providers.Where(i => (i is ILocalMetadataProvider)).Select(i => new MetadataPlugin
|
||||||
|
@ -496,16 +513,21 @@ namespace MediaBrowser.Providers.Manager
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
|
|
||||||
|
|
||||||
public MetadataOptions GetMetadataOptions(IHasMetadata item)
|
public MetadataOptions GetMetadataOptions(IHasMetadata item)
|
||||||
{
|
{
|
||||||
var type = item.GetType().Name;
|
var type = item.GetType().Name;
|
||||||
|
|
||||||
|
if (item is Trailer)
|
||||||
|
{
|
||||||
|
type = typeof(Movie).Name;
|
||||||
|
}
|
||||||
|
|
||||||
return ConfigurationManager.Configuration.MetadataOptions
|
return ConfigurationManager.Configuration.MetadataOptions
|
||||||
.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ??
|
.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ??
|
||||||
new MetadataOptions();
|
new MetadataOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the metadata.
|
/// Saves the metadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -517,7 +539,7 @@ namespace MediaBrowser.Providers.Manager
|
||||||
foreach (var saver in _savers.Where(i => IsSaverEnabledForItem(i, item, updateType, true)))
|
foreach (var saver in _savers.Where(i => IsSaverEnabledForItem(i, item, updateType, true)))
|
||||||
{
|
{
|
||||||
_logger.Debug("Saving {0} to {1}.", item.Path ?? item.Name, saver.Name);
|
_logger.Debug("Saving {0} to {1}.", item.Path ?? item.Name, saver.Name);
|
||||||
|
|
||||||
var fileSaver = saver as IMetadataFileSaver;
|
var fileSaver = saver as IMetadataFileSaver;
|
||||||
|
|
||||||
if (fileSaver != null)
|
if (fileSaver != null)
|
||||||
|
|
|
@ -159,7 +159,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
return item.LocationType == LocationType.FileSystem && item is Audio;
|
return item.LocationType == LocationType.FileSystem && item is Audio;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
return item.DateModified > date;
|
return item.DateModified > date;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,11 @@ using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using MediaBrowser.Model.MediaInfo;
|
||||||
|
using MediaBrowser.Model.Serialization;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Serialization;
|
using System.Linq;
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.MediaInfo
|
namespace MediaBrowser.Providers.MediaInfo
|
||||||
{
|
{
|
||||||
|
@ -46,47 +47,47 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
get { return "ffprobe"; }
|
get { return "ffprobe"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(Episode item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(Episode item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return FetchVideoInfo(item, cancellationToken);
|
return FetchVideoInfo(item, directoryService, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(MusicVideo item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(MusicVideo item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return FetchVideoInfo(item, cancellationToken);
|
return FetchVideoInfo(item, directoryService, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(Movie item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(Movie item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return FetchVideoInfo(item, cancellationToken);
|
return FetchVideoInfo(item, directoryService, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(AdultVideo item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(AdultVideo item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return FetchVideoInfo(item, cancellationToken);
|
return FetchVideoInfo(item, directoryService, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(LiveTvVideoRecording item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(LiveTvVideoRecording item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return FetchVideoInfo(item, cancellationToken);
|
return FetchVideoInfo(item, directoryService, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(Trailer item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(Trailer item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return FetchVideoInfo(item, cancellationToken);
|
return FetchVideoInfo(item, directoryService, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(Video item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(Video item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return FetchVideoInfo(item, cancellationToken);
|
return FetchVideoInfo(item, directoryService, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(Audio item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(Audio item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return FetchAudioInfo(item, cancellationToken);
|
return FetchAudioInfo(item, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(LiveTvAudioRecording item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(LiveTvAudioRecording item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return FetchAudioInfo(item, cancellationToken);
|
return FetchAudioInfo(item, cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -103,8 +104,8 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
_json = json;
|
_json = json;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.Unspecified);
|
private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.None);
|
||||||
public Task<ItemUpdateType> FetchVideoInfo<T>(T item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchVideoInfo<T>(T item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
where T : Video
|
where T : Video
|
||||||
{
|
{
|
||||||
if (item.LocationType != LocationType.FileSystem)
|
if (item.LocationType != LocationType.FileSystem)
|
||||||
|
@ -124,7 +125,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
|
|
||||||
var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json);
|
var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json);
|
||||||
|
|
||||||
return prober.ProbeVideo(item, cancellationToken);
|
return prober.ProbeVideo(item, directoryService, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAudioInfo<T>(T item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAudioInfo<T>(T item, CancellationToken cancellationToken)
|
||||||
|
@ -140,9 +141,26 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
return prober.Probe(item, cancellationToken);
|
return prober.Probe(item, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
return item.DateModified > date;
|
if (item.DateModified > date)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.LocationType == LocationType.FileSystem)
|
||||||
|
{
|
||||||
|
var video = item as Video;
|
||||||
|
|
||||||
|
if (video != null)
|
||||||
|
{
|
||||||
|
var prober = new FFProbeVideoInfo(_logger, _isoManager, _mediaEncoder, _itemRepo, _blurayExaminer, _localization, _appPaths, _json);
|
||||||
|
|
||||||
|
return !video.SubtitleFiles.SequenceEqual(prober.GetSubtitleFiles(video, directoryService).Select(i => i.FullName).OrderBy(i => i), StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Order
|
public int Order
|
||||||
|
|
|
@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Localization;
|
using MediaBrowser.Controller.Localization;
|
||||||
using MediaBrowser.Controller.MediaInfo;
|
using MediaBrowser.Controller.MediaInfo;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
|
@ -45,7 +46,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
_json = json;
|
_json = json;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ItemUpdateType> ProbeVideo<T>(T item, CancellationToken cancellationToken)
|
public async Task<ItemUpdateType> ProbeVideo<T>(T item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
where T : Video
|
where T : Video
|
||||||
{
|
{
|
||||||
var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false);
|
var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false);
|
||||||
|
@ -72,7 +73,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
await Fetch(item, cancellationToken, result, isoMount).ConfigureAwait(false);
|
await Fetch(item, cancellationToken, result, isoMount, directoryService).ConfigureAwait(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@ -125,7 +126,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task Fetch(Video video, CancellationToken cancellationToken, InternalMediaInfoResult data, IIsoMount isoMount)
|
protected async Task Fetch(Video video, CancellationToken cancellationToken, InternalMediaInfoResult data, IIsoMount isoMount, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
if (data.format != null)
|
if (data.format != null)
|
||||||
{
|
{
|
||||||
|
@ -148,7 +149,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
FetchBdInfo(video, chapters, mediaStreams, inputPath, cancellationToken);
|
FetchBdInfo(video, chapters, mediaStreams, inputPath, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddExternalSubtitles(video, mediaStreams);
|
AddExternalSubtitles(video, mediaStreams, directoryService);
|
||||||
|
|
||||||
FetchWtvInfo(video, data);
|
FetchWtvInfo(video, data);
|
||||||
|
|
||||||
|
@ -342,76 +343,104 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<FileInfo> GetSubtitleFiles(Video video, IDirectoryService directoryService)
|
||||||
|
{
|
||||||
|
var containingPath = video.ContainingFolderPath;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(containingPath))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(string.Format("Cannot search for items that don't have a path: {0} {1}", video.Name, video.Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
var files = directoryService.GetFiles(containingPath);
|
||||||
|
|
||||||
|
var videoFileNameWithoutExtension = Path.GetFileNameWithoutExtension(video.Path);
|
||||||
|
|
||||||
|
return files.Where(i =>
|
||||||
|
{
|
||||||
|
if (!i.Attributes.HasFlag(FileAttributes.Directory) &&
|
||||||
|
SubtitleExtensions.Contains(i.Extension, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var fullName = i.FullName;
|
||||||
|
|
||||||
|
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fullName);
|
||||||
|
|
||||||
|
if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the external subtitles.
|
/// Adds the external subtitles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="video">The video.</param>
|
/// <param name="video">The video.</param>
|
||||||
/// <param name="currentStreams">The current streams.</param>
|
/// <param name="currentStreams">The current streams.</param>
|
||||||
private void AddExternalSubtitles(Video video, List<MediaStream> currentStreams)
|
private void AddExternalSubtitles(Video video, List<MediaStream> currentStreams, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
//var useParent = !video.ResolveArgs.IsDirectory;
|
var files = GetSubtitleFiles(video, directoryService);
|
||||||
|
|
||||||
//if (useParent && video.Parent == null)
|
var startIndex = currentStreams.Count;
|
||||||
//{
|
var streams = new List<MediaStream>();
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//var fileSystemChildren = useParent
|
var videoFileNameWithoutExtension = Path.GetFileNameWithoutExtension(video.Path);
|
||||||
// ? video.Parent.ResolveArgs.FileSystemChildren
|
|
||||||
// : video.ResolveArgs.FileSystemChildren;
|
|
||||||
|
|
||||||
//var startIndex = currentStreams.Count;
|
foreach (var file in files)
|
||||||
//var streams = new List<MediaStream>();
|
{
|
||||||
|
var fullName = file.FullName;
|
||||||
|
|
||||||
//var videoFileNameWithoutExtension = Path.GetFileNameWithoutExtension(video.Path);
|
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fullName);
|
||||||
|
|
||||||
//foreach (var file in fileSystemChildren
|
// If the subtitle file matches the video file name
|
||||||
// .Where(f => !f.Attributes.HasFlag(FileAttributes.Directory) && SubtitleExtensions.Contains(Path.GetExtension(f.FullName), StringComparer.OrdinalIgnoreCase)))
|
if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
|
||||||
//{
|
{
|
||||||
// var fullName = file.FullName;
|
streams.Add(new MediaStream
|
||||||
|
{
|
||||||
|
Index = startIndex++,
|
||||||
|
Type = MediaStreamType.Subtitle,
|
||||||
|
IsExternal = true,
|
||||||
|
Path = fullName,
|
||||||
|
Codec = Path.GetExtension(fullName).ToLower().TrimStart('.')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Support xbmc naming conventions - 300.spanish.srt
|
||||||
|
var language = fileNameWithoutExtension.Split('.').LastOrDefault();
|
||||||
|
|
||||||
// var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fullName);
|
// Try to translate to three character code
|
||||||
|
// Be flexible and check against both the full and three character versions
|
||||||
|
var culture = _localization.GetCultures()
|
||||||
|
.FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.ThreeLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
// // If the subtitle file matches the video file name
|
if (culture != null)
|
||||||
// if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
|
{
|
||||||
// {
|
language = culture.ThreeLetterISOLanguageName;
|
||||||
// streams.Add(new MediaStream
|
}
|
||||||
// {
|
|
||||||
// Index = startIndex++,
|
|
||||||
// Type = MediaStreamType.Subtitle,
|
|
||||||
// IsExternal = true,
|
|
||||||
// Path = fullName,
|
|
||||||
// Codec = Path.GetExtension(fullName).ToLower().TrimStart('.')
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// else if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase))
|
|
||||||
// {
|
|
||||||
// // Support xbmc naming conventions - 300.spanish.srt
|
|
||||||
// var language = fileNameWithoutExtension.Split('.').LastOrDefault();
|
|
||||||
|
|
||||||
// // Try to translate to three character code
|
streams.Add(new MediaStream
|
||||||
// // Be flexible and check against both the full and three character versions
|
{
|
||||||
// var culture = _localization.GetCultures()
|
Index = startIndex++,
|
||||||
// .FirstOrDefault(i => string.Equals(i.DisplayName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.ThreeLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase) || string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase));
|
Type = MediaStreamType.Subtitle,
|
||||||
|
IsExternal = true,
|
||||||
|
Path = fullName,
|
||||||
|
Codec = Path.GetExtension(fullName).ToLower().TrimStart('.'),
|
||||||
|
Language = language
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if (culture != null)
|
video.SubtitleFiles = streams.Select(i => i.Path).OrderBy(i => i).ToList();
|
||||||
// {
|
|
||||||
// language = culture.ThreeLetterISOLanguageName;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// streams.Add(new MediaStream
|
currentStreams.AddRange(streams);
|
||||||
// {
|
|
||||||
// Index = startIndex++,
|
|
||||||
// Type = MediaStreamType.Subtitle,
|
|
||||||
// IsExternal = true,
|
|
||||||
// Path = fullName,
|
|
||||||
// Codec = Path.GetExtension(fullName).ToLower().TrimStart('.'),
|
|
||||||
// Language = language
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//currentStreams.AddRange(streams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -126,7 +126,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||||
return item.LocationType == LocationType.FileSystem && item is Video;
|
return item.LocationType == LocationType.FileSystem && item is Video;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
return item.DateModified > date;
|
return item.DateModified > date;
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,7 +345,7 @@ namespace MediaBrowser.Providers.Movies
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
if (!_config.Configuration.EnableFanArtUpdates)
|
if (!_config.Configuration.EnableFanArtUpdates)
|
||||||
{
|
{
|
||||||
|
|
|
@ -208,7 +208,7 @@ namespace MediaBrowser.Providers.Movies
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
return MovieDbProvider.Current.HasChanged(item, date);
|
return MovieDbProvider.Current.HasChanged(item, date);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ namespace MediaBrowser.Providers.Music
|
||||||
|
|
||||||
private ItemUpdateType SetAlbumArtistFromSongs(MusicAlbum item, IEnumerable<Audio> songs)
|
private ItemUpdateType SetAlbumArtistFromSongs(MusicAlbum item, IEnumerable<Audio> songs)
|
||||||
{
|
{
|
||||||
var updateType = ItemUpdateType.Unspecified;
|
var updateType = ItemUpdateType.None;
|
||||||
|
|
||||||
var albumArtist = songs
|
var albumArtist = songs
|
||||||
.Select(i => i.AlbumArtist)
|
.Select(i => i.AlbumArtist)
|
||||||
|
@ -119,7 +119,7 @@ namespace MediaBrowser.Providers.Music
|
||||||
|
|
||||||
private ItemUpdateType SetArtistsFromSongs(MusicAlbum item, IEnumerable<Audio> songs)
|
private ItemUpdateType SetArtistsFromSongs(MusicAlbum item, IEnumerable<Audio> songs)
|
||||||
{
|
{
|
||||||
var updateType = ItemUpdateType.Unspecified;
|
var updateType = ItemUpdateType.None;
|
||||||
|
|
||||||
var currentList = item.Artists.ToList();
|
var currentList = item.Artists.ToList();
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ namespace MediaBrowser.Providers.Music
|
||||||
|
|
||||||
private ItemUpdateType SetDateFromSongs(MusicAlbum item, List<Audio> songs)
|
private ItemUpdateType SetDateFromSongs(MusicAlbum item, List<Audio> songs)
|
||||||
{
|
{
|
||||||
var updateType = ItemUpdateType.Unspecified;
|
var updateType = ItemUpdateType.None;
|
||||||
|
|
||||||
var date = songs.Select(i => i.PremiereDate)
|
var date = songs.Select(i => i.PremiereDate)
|
||||||
.FirstOrDefault(i => i.HasValue);
|
.FirstOrDefault(i => i.HasValue);
|
||||||
|
|
|
@ -357,7 +357,7 @@ namespace MediaBrowser.Providers.Music
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
if (!_config.Configuration.EnableFanArtUpdates)
|
if (!_config.Configuration.EnableFanArtUpdates)
|
||||||
{
|
{
|
||||||
|
|
|
@ -374,7 +374,7 @@ namespace MediaBrowser.Providers.Music
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
if (!_config.Configuration.EnableFanArtUpdates)
|
if (!_config.Configuration.EnableFanArtUpdates)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,18 +27,18 @@ namespace MediaBrowser.Providers.Omdb
|
||||||
get { return "IMDb via The Open Movie Database"; }
|
get { return "IMDb via The Open Movie Database"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(Series item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(Series item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return new OmdbProvider(_jsonSerializer, _httpClient).Fetch(item, cancellationToken);
|
return new OmdbProvider(_jsonSerializer, _httpClient).Fetch(item, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<ItemUpdateType> FetchAsync(Movie item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(Movie item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return new OmdbProvider(_jsonSerializer, _httpClient).Fetch(item, cancellationToken);
|
return new OmdbProvider(_jsonSerializer, _httpClient).Fetch(item, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.Unspecified);
|
private readonly Task<ItemUpdateType> _cachedTask = Task.FromResult(ItemUpdateType.None);
|
||||||
public Task<ItemUpdateType> FetchAsync(Trailer item, CancellationToken cancellationToken)
|
public Task<ItemUpdateType> FetchAsync(Trailer item, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (item.IsLocalTrailer)
|
if (item.IsLocalTrailer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace MediaBrowser.Providers.Omdb
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(imdbId))
|
if (string.IsNullOrEmpty(imdbId))
|
||||||
{
|
{
|
||||||
return ItemUpdateType.Unspecified;
|
return ItemUpdateType.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
var imdbParam = imdbId.StartsWith("tt", StringComparison.OrdinalIgnoreCase) ? imdbId : "tt" + imdbId;
|
var imdbParam = imdbId.StartsWith("tt", StringComparison.OrdinalIgnoreCase) ? imdbId : "tt" + imdbId;
|
||||||
|
|
|
@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.People
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = string.Format(@"http://api.themoviedb.org/3/person/{1}?api_key={0}&append_to_response=credits,images", MovieDbProvider.ApiKey, id);
|
var url = string.Format(@"http://api.themoviedb.org/3/person/{1}?api_key={0}&append_to_response=credits,images,external_ids", MovieDbProvider.ApiKey, id);
|
||||||
|
|
||||||
using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
|
using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
|
||||||
{
|
{
|
||||||
|
@ -267,6 +267,14 @@ namespace MediaBrowser.Providers.People
|
||||||
public List<Profile> profiles { get; set; }
|
public List<Profile> profiles { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ExternalIds
|
||||||
|
{
|
||||||
|
public string imdb_id { get; set; }
|
||||||
|
public string freebase_mid { get; set; }
|
||||||
|
public string freebase_id { get; set; }
|
||||||
|
public int tvrage_id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class PersonResult
|
public class PersonResult
|
||||||
{
|
{
|
||||||
public bool adult { get; set; }
|
public bool adult { get; set; }
|
||||||
|
@ -283,6 +291,7 @@ namespace MediaBrowser.Providers.People
|
||||||
public string profile_path { get; set; }
|
public string profile_path { get; set; }
|
||||||
public Credits credits { get; set; }
|
public Credits credits { get; set; }
|
||||||
public Images images { get; set; }
|
public Images images { get; set; }
|
||||||
|
public ExternalIds external_ids { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -1,25 +1,16 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Savers
|
namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
class AlbumXmlSaver : IMetadataFileSaver
|
class AlbumXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
|
|
||||||
public AlbumXmlSaver(IServerConfigurationManager config)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Providers.Music;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -15,13 +11,6 @@ namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
class ArtistXmlSaver : IMetadataFileSaver
|
class ArtistXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
|
|
||||||
public ArtistXmlSaver(IServerConfigurationManager config)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -1,25 +1,16 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Controller.Providers;
|
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Savers
|
namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
public class BoxSetXmlSaver : IMetadataFileSaver
|
public class BoxSetXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
|
|
||||||
public BoxSetXmlSaver(IServerConfigurationManager config)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Savers
|
namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,24 +1,28 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Savers
|
namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
public class EpisodeXmlSaver : IMetadataFileSaver
|
public class EpisodeXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
private readonly IItemRepository _itemRepository;
|
private readonly IItemRepository _itemRepository;
|
||||||
|
|
||||||
|
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||||
|
|
||||||
|
public EpisodeXmlSaver(IItemRepository itemRepository)
|
||||||
|
{
|
||||||
|
_itemRepository = itemRepository;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether [is enabled for] [the specified item].
|
/// Determines whether [is enabled for] [the specified item].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -53,14 +57,6 @@ namespace MediaBrowser.Providers.Savers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
|
||||||
|
|
||||||
public EpisodeXmlSaver(IServerConfigurationManager config, IItemRepository itemRepository)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
_itemRepository = itemRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the specified item.
|
/// Saves the specified item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,27 +1,18 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Savers
|
namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
public class FolderXmlSaver : IMetadataFileSaver
|
public class FolderXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
|
|
||||||
public FolderXmlSaver(IServerConfigurationManager config)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -1,25 +1,16 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Savers
|
namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
public class GameSystemXmlSaver : IMetadataFileSaver
|
public class GameSystemXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
|
|
||||||
public GameSystemXmlSaver(IServerConfigurationManager config)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -16,13 +15,6 @@ namespace MediaBrowser.Providers.Savers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GameXmlSaver : IMetadataFileSaver
|
public class GameXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
|
|
||||||
public GameXmlSaver(IServerConfigurationManager config)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Persistence;
|
using MediaBrowser.Controller.Persistence;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Controller.Providers;
|
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Savers
|
namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
|
@ -21,12 +18,10 @@ namespace MediaBrowser.Providers.Savers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MovieXmlSaver : IMetadataFileSaver
|
public class MovieXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
private readonly IItemRepository _itemRepository;
|
private readonly IItemRepository _itemRepository;
|
||||||
|
|
||||||
public MovieXmlSaver(IServerConfigurationManager config, IItemRepository itemRepository)
|
public MovieXmlSaver(IItemRepository itemRepository)
|
||||||
{
|
{
|
||||||
_config = config;
|
|
||||||
_itemRepository = itemRepository;
|
_itemRepository = itemRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,16 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Model.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Savers
|
namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
public class SeasonXmlSaver : IMetadataFileSaver
|
public class SeasonXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
|
|
||||||
public SeasonXmlSaver(IServerConfigurationManager config)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -13,13 +12,6 @@ namespace MediaBrowser.Providers.Savers
|
||||||
{
|
{
|
||||||
public class SeriesXmlSaver : IMetadataFileSaver
|
public class SeriesXmlSaver : IMetadataFileSaver
|
||||||
{
|
{
|
||||||
private readonly IServerConfigurationManager _config;
|
|
||||||
|
|
||||||
public SeriesXmlSaver(IServerConfigurationManager config)
|
|
||||||
{
|
|
||||||
_config = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
return item is Episode && item.LocationType == LocationType.FileSystem;
|
return item is Episode && item.LocationType == LocationType.FileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LocalImageInfo> GetImages(IHasImages item, DirectoryService directoryService)
|
public List<LocalImageInfo> GetImages(IHasImages item, IDirectoryService directoryService)
|
||||||
{
|
{
|
||||||
var parentPath = Path.GetDirectoryName(item.Path);
|
var parentPath = Path.GetDirectoryName(item.Path);
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,19 @@
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Providers.Manager;
|
using MediaBrowser.Providers.Manager;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.TV
|
namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
public class EpisodeMetadataService : MetadataService<Episode, EpisodeInfo>
|
public class EpisodeMetadataService : MetadataService<Episode, EpisodeInfo>
|
||||||
{
|
{
|
||||||
private readonly ILibraryManager _libraryManager;
|
public EpisodeMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem)
|
||||||
|
|
||||||
public EpisodeMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
|
|
||||||
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
|
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -70,50 +63,5 @@ namespace MediaBrowser.Providers.TV
|
||||||
target.IndexNumberEnd = source.IndexNumberEnd;
|
target.IndexNumberEnd = source.IndexNumberEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override ItemUpdateType BeforeMetadataRefresh(Episode item)
|
|
||||||
{
|
|
||||||
var updateType = base.BeforeMetadataRefresh(item);
|
|
||||||
|
|
||||||
var locationType = item.LocationType;
|
|
||||||
if (locationType == LocationType.FileSystem || locationType == LocationType.Offline)
|
|
||||||
{
|
|
||||||
var currentIndexNumber = item.IndexNumber;
|
|
||||||
var currentIndexNumberEnd = item.IndexNumberEnd;
|
|
||||||
var currentParentIndexNumber = item.ParentIndexNumber;
|
|
||||||
|
|
||||||
var filename = Path.GetFileName(item.Path);
|
|
||||||
|
|
||||||
item.IndexNumber = item.IndexNumber ?? TVUtils.GetEpisodeNumberFromFile(item.Path, item.Parent is Season);
|
|
||||||
item.IndexNumberEnd = item.IndexNumberEnd ?? TVUtils.GetEndingEpisodeNumberFromFile(item.Path);
|
|
||||||
|
|
||||||
if (!item.ParentIndexNumber.HasValue)
|
|
||||||
{
|
|
||||||
var season = item.Season;
|
|
||||||
|
|
||||||
if (season != null)
|
|
||||||
{
|
|
||||||
item.ParentIndexNumber = season.IndexNumber;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((currentIndexNumber ?? -1) != (item.IndexNumber ?? -1))
|
|
||||||
{
|
|
||||||
updateType = updateType | ItemUpdateType.MetadataImport;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((currentIndexNumberEnd ?? -1) != (item.IndexNumberEnd ?? -1))
|
|
||||||
{
|
|
||||||
updateType = updateType | ItemUpdateType.MetadataImport;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((currentParentIndexNumber ?? -1) != (item.ParentIndexNumber ?? -1))
|
|
||||||
{
|
|
||||||
updateType = updateType | ItemUpdateType.MetadataImport;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return updateType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
if (!_config.Configuration.EnableFanArtUpdates)
|
if (!_config.Configuration.EnableFanArtUpdates)
|
||||||
{
|
{
|
||||||
|
|
|
@ -423,7 +423,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
if (!_config.Configuration.EnableFanArtUpdates)
|
if (!_config.Configuration.EnableFanArtUpdates)
|
||||||
{
|
{
|
||||||
|
|
|
@ -203,7 +203,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
return MovieDbSeriesProvider.Current.HasChanged(item, date);
|
return MovieDbSeriesProvider.Current.HasChanged(item, date);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,19 @@
|
||||||
using MediaBrowser.Common.IO;
|
using MediaBrowser.Common.IO;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Logging;
|
using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Providers.Manager;
|
using MediaBrowser.Providers.Manager;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.TV
|
namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
public class SeasonMetadataService : MetadataService<Season, SeasonInfo>
|
public class SeasonMetadataService : MetadataService<Season, SeasonInfo>
|
||||||
{
|
{
|
||||||
private readonly ILibraryManager _libraryManager;
|
public SeasonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem)
|
||||||
|
|
||||||
public SeasonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
|
|
||||||
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
|
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -34,20 +28,5 @@ namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override ItemUpdateType BeforeMetadataRefresh(Season item)
|
|
||||||
{
|
|
||||||
var updateType = base.BeforeMetadataRefresh(item);
|
|
||||||
|
|
||||||
var currentIndexNumber = item.IndexNumber;
|
|
||||||
|
|
||||||
item.IndexNumber = item.IndexNumber ?? TVUtils.GetSeasonNumberFromPath(item.Path);
|
|
||||||
|
|
||||||
if ((currentIndexNumber ?? -1) != (item.IndexNumber ?? -1))
|
|
||||||
{
|
|
||||||
updateType = updateType | ItemUpdateType.MetadataImport;
|
|
||||||
}
|
|
||||||
return updateType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,6 @@ using MediaBrowser.Model.Logging;
|
||||||
using MediaBrowser.Providers.Manager;
|
using MediaBrowser.Providers.Manager;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.TV
|
namespace MediaBrowser.Providers.TV
|
||||||
{
|
{
|
||||||
|
|
|
@ -192,7 +192,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
if (item.LocationType != LocationType.Virtual)
|
if (item.LocationType != LocationType.Virtual)
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
return Task.FromResult(result);
|
return Task.FromResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
// Only enable for virtual items
|
// Only enable for virtual items
|
||||||
if (item.LocationType != LocationType.Virtual)
|
if (item.LocationType != LocationType.Virtual)
|
||||||
|
|
|
@ -98,8 +98,19 @@ namespace MediaBrowser.Providers.TV
|
||||||
|
|
||||||
string newUpdateTime;
|
string newUpdateTime;
|
||||||
|
|
||||||
var existingDirectories = Directory.EnumerateDirectories(path).Select(Path.GetFileName).ToList();
|
var existingDirectories = Directory.EnumerateDirectories(path)
|
||||||
|
.Select(Path.GetFileName)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var seriesIdsInLibrary = _libraryManager.RootFolder.RecursiveChildren
|
||||||
|
.OfType<Series>()
|
||||||
|
.Select(i => i.GetProviderId(MetadataProviders.Tvdb))
|
||||||
|
.Where(i => !string.IsNullOrEmpty(i))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var missingSeries = seriesIdsInLibrary.Except(existingDirectories, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
// If this is our first time, update all series
|
// If this is our first time, update all series
|
||||||
if (string.IsNullOrEmpty(lastUpdateTime))
|
if (string.IsNullOrEmpty(lastUpdateTime))
|
||||||
{
|
{
|
||||||
|
@ -116,6 +127,8 @@ namespace MediaBrowser.Providers.TV
|
||||||
newUpdateTime = GetUpdateTime(stream);
|
newUpdateTime = GetUpdateTime(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
existingDirectories.AddRange(missingSeries);
|
||||||
|
|
||||||
await UpdateSeries(existingDirectories, path, null, progress, cancellationToken).ConfigureAwait(false);
|
await UpdateSeries(existingDirectories, path, null, progress, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -130,7 +143,10 @@ namespace MediaBrowser.Providers.TV
|
||||||
|
|
||||||
var nullableUpdateValue = lastUpdateValue == 0 ? (long?)null : lastUpdateValue;
|
var nullableUpdateValue = lastUpdateValue == 0 ? (long?)null : lastUpdateValue;
|
||||||
|
|
||||||
await UpdateSeries(seriesToUpdate.Item1, path, nullableUpdateValue, progress, cancellationToken).ConfigureAwait(false);
|
var listToUpdate = seriesToUpdate.Item1.ToList();
|
||||||
|
listToUpdate.AddRange(missingSeries);
|
||||||
|
|
||||||
|
await UpdateSeries(listToUpdate, path, nullableUpdateValue, progress, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
File.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8);
|
File.WriteAllText(timestampFile, newUpdateTime, Encoding.UTF8);
|
||||||
|
|
|
@ -340,7 +340,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
if (item.LocationType != LocationType.Virtual)
|
if (item.LocationType != LocationType.Virtual)
|
||||||
{
|
{
|
||||||
|
|
|
@ -337,7 +337,7 @@ namespace MediaBrowser.Providers.TV
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
if (!_config.Configuration.EnableTvDbUpdates)
|
if (!_config.Configuration.EnableTvDbUpdates)
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
get { return 0; }
|
get { return 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalDays >= 1;
|
return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalDays >= 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
get { return 0; }
|
get { return 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalHours >= 6;
|
return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalHours >= 6;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||||
get { return 0; }
|
get { return 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasChanged(IHasMetadata item, DateTime date)
|
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
|
||||||
{
|
{
|
||||||
return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalHours >= 3;
|
return !item.HasImage(ImageType.Primary) && (DateTime.UtcNow - date).TotalHours >= 3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Common.Internal</id>
|
<id>MediaBrowser.Common.Internal</id>
|
||||||
<version>3.0.324</version>
|
<version>3.0.325</version>
|
||||||
<title>MediaBrowser.Common.Internal</title>
|
<title>MediaBrowser.Common.Internal</title>
|
||||||
<authors>Luke</authors>
|
<authors>Luke</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
|
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
|
||||||
<copyright>Copyright © Media Browser 2013</copyright>
|
<copyright>Copyright © Media Browser 2013</copyright>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="MediaBrowser.Common" version="3.0.324" />
|
<dependency id="MediaBrowser.Common" version="3.0.325" />
|
||||||
<dependency id="NLog" version="2.1.0" />
|
<dependency id="NLog" version="2.1.0" />
|
||||||
<dependency id="SimpleInjector" version="2.4.1" />
|
<dependency id="SimpleInjector" version="2.4.1" />
|
||||||
<dependency id="sharpcompress" version="0.10.2" />
|
<dependency id="sharpcompress" version="0.10.2" />
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Common</id>
|
<id>MediaBrowser.Common</id>
|
||||||
<version>3.0.324</version>
|
<version>3.0.325</version>
|
||||||
<title>MediaBrowser.Common</title>
|
<title>MediaBrowser.Common</title>
|
||||||
<authors>Media Browser Team</authors>
|
<authors>Media Browser Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>MediaBrowser.Server.Core</id>
|
<id>MediaBrowser.Server.Core</id>
|
||||||
<version>3.0.324</version>
|
<version>3.0.325</version>
|
||||||
<title>Media Browser.Server.Core</title>
|
<title>Media Browser.Server.Core</title>
|
||||||
<authors>Media Browser Team</authors>
|
<authors>Media Browser Team</authors>
|
||||||
<owners>ebr,Luke,scottisafool</owners>
|
<owners>ebr,Luke,scottisafool</owners>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<description>Contains core components required to build plugins for Media Browser Server.</description>
|
<description>Contains core components required to build plugins for Media Browser Server.</description>
|
||||||
<copyright>Copyright © Media Browser 2013</copyright>
|
<copyright>Copyright © Media Browser 2013</copyright>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency id="MediaBrowser.Common" version="3.0.324" />
|
<dependency id="MediaBrowser.Common" version="3.0.325" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user